aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linuxfoundation.org>2007-11-23 15:35:23 -0500
committerLinus Torvalds <torvalds@linuxfoundation.org>2007-11-23 15:35:23 -0500
commitbdd9c8e5286db0c47362e34a29fa1343fa83a4a6 (patch)
tree54317cb8991b4c47520c752e73da76a0ac5aa7cb
parent6e14d18e1c9ae7410b2df8733a4af2ac6db66d10 (diff)
downloadlinux-bdd9c8e5286db0c47362e34a29fa1343fa83a4a6.tar.gz
Import 2.4.0-test2pre2
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
-rw-r--r--Documentation/arm/README43
-rw-r--r--Documentation/arm/SA1100/LART5
-rw-r--r--Documentation/networking/8139too.txt14
-rw-r--r--Documentation/networking/shaper.txt13
-rw-r--r--Documentation/networking/sk98lin.txt37
-rw-r--r--Documentation/networking/tulip.txt18
-rw-r--r--Documentation/networking/vortex.txt5
-rw-r--r--Documentation/parport.txt33
-rw-r--r--Documentation/powerpc/SBC8260_memory_mapping.txt197
-rw-r--r--Documentation/usb/input.txt34
-rw-r--r--Documentation/usb/ov511.txt25
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/boot/bootp.c18
-rw-r--r--arch/alpha/boot/main.c17
-rw-r--r--arch/alpha/config.in44
-rw-r--r--arch/alpha/defconfig6
-rw-r--r--arch/alpha/kernel/Makefile25
-rw-r--r--arch/alpha/kernel/console.c66
-rw-r--r--arch/alpha/kernel/core_mcpcia.c83
-rw-r--r--arch/alpha/kernel/core_titan.c487
-rw-r--r--arch/alpha/kernel/core_tsunami.c26
-rw-r--r--arch/alpha/kernel/core_wildfire.c668
-rw-r--r--arch/alpha/kernel/entry.S7
-rw-r--r--arch/alpha/kernel/irq.c8
-rw-r--r--arch/alpha/kernel/irq_alpha.c12
-rw-r--r--arch/alpha/kernel/irq_i8259.c2
-rw-r--r--arch/alpha/kernel/machvec_impl.h13
-rw-r--r--arch/alpha/kernel/osf_sys.c4
-rw-r--r--arch/alpha/kernel/pci.c19
-rw-r--r--arch/alpha/kernel/pci_iommu.c17
-rw-r--r--arch/alpha/kernel/proto.h20
-rw-r--r--arch/alpha/kernel/ptrace.c45
-rw-r--r--arch/alpha/kernel/setup.c217
-rw-r--r--arch/alpha/kernel/signal.c2
-rw-r--r--arch/alpha/kernel/smc37c669.c3
-rw-r--r--arch/alpha/kernel/smp.c23
-rw-r--r--arch/alpha/kernel/sys_dp264.c11
-rw-r--r--arch/alpha/kernel/sys_mikasa.c4
-rw-r--r--arch/alpha/kernel/sys_titan.c393
-rw-r--r--arch/alpha/kernel/sys_wildfire.c361
-rw-r--r--arch/alpha/kernel/traps.c239
-rw-r--r--arch/alpha/lib/Makefile7
-rw-r--r--arch/alpha/lib/callback_init.c79
-rw-r--r--arch/alpha/lib/callback_srm.S102
-rw-r--r--arch/alpha/lib/srm_dispatch.S43
-rw-r--r--arch/alpha/lib/srm_fixup.S42
-rw-r--r--arch/alpha/lib/srm_printk.c34
-rw-r--r--arch/alpha/lib/srm_puts.c33
-rw-r--r--arch/alpha/mm/extable.c42
-rw-r--r--arch/alpha/mm/fault.c6
-rw-r--r--arch/alpha/mm/init.c67
-rw-r--r--arch/alpha/vmlinux.lds6
-rw-r--r--arch/arm/Makefile10
-rw-r--r--arch/arm/boot/compressed/Makefile2
-rw-r--r--arch/arm/boot/compressed/head-sa1100.S1
-rw-r--r--arch/arm/boot/compressed/head.S34
-rw-r--r--arch/arm/config.in256
-rw-r--r--arch/arm/def-configs/a5k4
-rw-r--r--arch/arm/def-configs/assabet320
-rw-r--r--arch/arm/def-configs/brutus11
-rw-r--r--arch/arm/def-configs/ebsa110266
-rw-r--r--arch/arm/def-configs/footbridge4
-rw-r--r--arch/arm/def-configs/graphicsclient4
-rw-r--r--arch/arm/def-configs/lart130
-rw-r--r--arch/arm/def-configs/lusl72004
-rw-r--r--arch/arm/def-configs/rpc4
-rw-r--r--arch/arm/def-configs/thinclient22
-rw-r--r--arch/arm/def-configs/victor4
-rw-r--r--arch/arm/defconfig4
-rw-r--r--arch/arm/kernel/Makefile11
-rw-r--r--arch/arm/kernel/arch.c53
-rw-r--r--arch/arm/kernel/bios32.c141
-rw-r--r--arch/arm/kernel/bios32.h5
-rw-r--r--arch/arm/kernel/calls.S2
-rw-r--r--arch/arm/kernel/debug-armv.S2
-rw-r--r--arch/arm/kernel/dec21285.c280
-rw-r--r--arch/arm/kernel/dma-a5k.c4
-rw-r--r--arch/arm/kernel/dma-rpc.c4
-rw-r--r--arch/arm/kernel/ecard.c4
-rw-r--r--arch/arm/kernel/entry-armv.S87
-rw-r--r--arch/arm/kernel/entry-common.S4
-rw-r--r--arch/arm/kernel/hw-footbridge.c26
-rw-r--r--arch/arm/kernel/hw-sa1100.c135
-rw-r--r--arch/arm/kernel/ioport.c36
-rw-r--r--arch/arm/kernel/irq.c35
-rw-r--r--arch/arm/kernel/leds-ebsa110.c2
-rw-r--r--arch/arm/kernel/leds-footbridge.c19
-rw-r--r--arch/arm/kernel/leds-sa1100.c333
-rw-r--r--arch/arm/kernel/process.c10
-rw-r--r--arch/arm/kernel/ptrace.c22
-rw-r--r--arch/arm/kernel/semaphore.c75
-rw-r--r--arch/arm/kernel/setup.c24
-rw-r--r--arch/arm/kernel/signal.c2
-rw-r--r--arch/arm/kernel/time.c34
-rw-r--r--arch/arm/lib/changebit.S15
-rw-r--r--arch/arm/lib/clearbit.S11
-rw-r--r--arch/arm/lib/findbit.S90
-rw-r--r--arch/arm/lib/getconsdata.c10
-rw-r--r--arch/arm/lib/setbit.S11
-rw-r--r--arch/arm/lib/testchangebit.S7
-rw-r--r--arch/arm/lib/testclearbit.S9
-rw-r--r--arch/arm/lib/testsetbit.S7
-rw-r--r--arch/arm/lib/uaccess.S17
-rw-r--r--arch/arm/mm/Makefile4
-rw-r--r--arch/arm/mm/consistent.c20
-rw-r--r--arch/arm/mm/fault-armv.c35
-rw-r--r--arch/arm/mm/fault-common.c202
-rw-r--r--arch/arm/mm/init.c317
-rw-r--r--arch/arm/mm/mm-armv.c57
-rw-r--r--arch/arm/mm/mm-footbridge.c2
-rw-r--r--arch/arm/mm/mm-l7200.c25
-rw-r--r--arch/arm/mm/mm-sa1100.c22
-rw-r--r--arch/arm/mm/proc-arm6,7.S80
-rw-r--r--arch/arm/mm/proc-arm720.S398
-rw-r--r--arch/arm/mm/proc-sa110.S36
-rw-r--r--arch/i386/kernel/apic.c50
-rw-r--r--arch/i386/kernel/entry.S5
-rw-r--r--arch/i386/kernel/i8259.c13
-rw-r--r--arch/i386/kernel/io_apic.c36
-rw-r--r--arch/i386/kernel/process.c2
-rw-r--r--arch/i386/kernel/ptrace.c26
-rw-r--r--arch/i386/kernel/signal.c2
-rw-r--r--arch/i386/kernel/smpboot.c38
-rw-r--r--arch/i386/kernel/time.c49
-rw-r--r--arch/i386/kernel/traps.c6
-rw-r--r--arch/i386/kernel/vm86.c2
-rw-r--r--arch/i386/math-emu/fpu_entry.c2
-rw-r--r--arch/ppc/8xx_io/Config.in17
-rw-r--r--arch/ppc/Makefile18
-rw-r--r--arch/ppc/boot/Makefile2
-rw-r--r--arch/ppc/chrpboot/Makefile35
-rw-r--r--arch/ppc/chrpboot/addnote.c163
-rw-r--r--arch/ppc/chrpboot/main.c30
-rw-r--r--arch/ppc/chrpboot/start.c23
-rw-r--r--arch/ppc/coffboot/Makefile4
-rw-r--r--arch/ppc/config.in22
-rw-r--r--arch/ppc/configs/apus_defconfig4
-rw-r--r--arch/ppc/configs/bseip_defconfig397
-rw-r--r--arch/ppc/configs/common_defconfig2
-rw-r--r--arch/ppc/configs/est8260_defconfig397
-rw-r--r--arch/ppc/configs/gemini_defconfig6
-rw-r--r--arch/ppc/configs/oak_defconfig6
-rw-r--r--arch/ppc/configs/rpxcllf_defconfig396
-rw-r--r--arch/ppc/configs/rpxlite_defconfig397
-rw-r--r--arch/ppc/configs/walnut_defconfig6
-rw-r--r--arch/ppc/defconfig2
-rw-r--r--arch/ppc/kernel/Makefile9
-rw-r--r--arch/ppc/kernel/align.c8
-rw-r--r--arch/ppc/kernel/chrp_pci.c151
-rw-r--r--arch/ppc/kernel/chrp_setup.c41
-rw-r--r--arch/ppc/kernel/entry.S38
-rw-r--r--arch/ppc/kernel/hashtable.S322
-rw-r--r--arch/ppc/kernel/head.S351
-rw-r--r--arch/ppc/kernel/head_8xx.S45
-rw-r--r--arch/ppc/kernel/i8259.c5
-rw-r--r--arch/ppc/kernel/irq.c19
-rw-r--r--arch/ppc/kernel/m8260_setup.c6
-rw-r--r--arch/ppc/kernel/misc.S119
-rw-r--r--arch/ppc/kernel/mk_defs.c3
-rw-r--r--arch/ppc/kernel/open_pic.c6
-rw-r--r--arch/ppc/kernel/pmac_time.c7
-rw-r--r--arch/ppc/kernel/ppc_asm.h28
-rw-r--r--arch/ppc/kernel/ppc_htab.c29
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c6
-rw-r--r--arch/ppc/kernel/process.c2
-rw-r--r--arch/ppc/kernel/prom.c635
-rw-r--r--arch/ppc/kernel/ptrace.c30
-rw-r--r--arch/ppc/kernel/setup.c49
-rw-r--r--arch/ppc/kernel/signal.c2
-rw-r--r--arch/ppc/kernel/smp.c39
-rw-r--r--arch/ppc/kernel/time.c19
-rw-r--r--arch/ppc/kernel/xics.c214
-rw-r--r--arch/ppc/kernel/xics.h23
-rw-r--r--arch/ppc/mbxboot/Makefile75
-rw-r--r--arch/ppc/mbxboot/embed_config.c14
-rw-r--r--arch/ppc/mbxboot/head_8260.S5
-rw-r--r--arch/ppc/mbxboot/m8260_tty.c4
-rw-r--r--arch/ppc/mbxboot/mbxtty.c201
-rw-r--r--arch/ppc/mm/fault.c10
-rw-r--r--arch/ppc/mm/init.c192
-rw-r--r--arch/ppc/mm/mem_pieces.c48
-rw-r--r--arch/ppc/mm/mem_pieces.h13
-rw-r--r--arch/ppc/xmon/start.c2
-rw-r--r--arch/ppc/xmon/xmon.c130
-rw-r--r--arch/sh/Makefile9
-rw-r--r--arch/sh/boot/Makefile43
-rw-r--r--arch/sh/boot/compressed/Makefile39
-rw-r--r--arch/sh/boot/compressed/head.S53
-rw-r--r--arch/sh/boot/compressed/install.sh56
-rw-r--r--arch/sh/boot/compressed/misc.c232
-rw-r--r--arch/sh/config.in24
-rw-r--r--arch/sh/defconfig15
-rw-r--r--arch/sh/kernel/Makefile12
-rw-r--r--arch/sh/kernel/cf-enabler.c66
-rw-r--r--arch/sh/kernel/entry.S94
-rw-r--r--arch/sh/kernel/io_hd64461.c109
-rw-r--r--arch/sh/kernel/io_se.c3
-rw-r--r--arch/sh/kernel/irq.c15
-rw-r--r--arch/sh/kernel/process.c16
-rw-r--r--arch/sh/kernel/ptrace.c39
-rw-r--r--arch/sh/kernel/setup.c25
-rw-r--r--arch/sh/kernel/setup_hd64461.c128
-rw-r--r--arch/sh/kernel/setup_od.c35
-rw-r--r--arch/sh/kernel/signal.c2
-rw-r--r--arch/sh/kernel/time.c10
-rw-r--r--arch/sh/mm/fault.c26
-rw-r--r--arch/sh/vmlinux.lds.S6
-rw-r--r--arch/sparc/config.in22
-rw-r--r--arch/sparc/defconfig23
-rw-r--r--arch/sparc/kernel/entry.S38
-rw-r--r--arch/sparc/kernel/ioport.c12
-rw-r--r--arch/sparc/kernel/ptrace.c20
-rw-r--r--arch/sparc/kernel/signal.c6
-rw-r--r--arch/sparc/kernel/sys_sparc.c6
-rw-r--r--arch/sparc/kernel/sys_sunos.c6
-rw-r--r--arch/sparc/kernel/time.c5
-rw-r--r--arch/sparc/kernel/traps.c4
-rw-r--r--arch/sparc/lib/memset.S6
-rw-r--r--arch/sparc/mm/hypersparc.S5
-rw-r--r--arch/sparc/mm/init.c14
-rw-r--r--arch/sparc/mm/srmmu.c932
-rw-r--r--arch/sparc/mm/sun4c.c65
-rw-r--r--arch/sparc/mm/swift.S7
-rw-r--r--arch/sparc/mm/tsunami.S5
-rw-r--r--arch/sparc/mm/viking.S8
-rw-r--r--arch/sparc64/config.in22
-rw-r--r--arch/sparc64/defconfig35
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c4
-rw-r--r--arch/sparc64/kernel/entry.S16
-rw-r--r--arch/sparc64/kernel/ioctl32.c12
-rw-r--r--arch/sparc64/kernel/iommu_common.c4
-rw-r--r--arch/sparc64/kernel/ptrace.c20
-rw-r--r--arch/sparc64/kernel/signal.c6
-rw-r--r--arch/sparc64/kernel/signal32.c6
-rw-r--r--arch/sparc64/kernel/sys_sparc.c6
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c7
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c6
-rw-r--r--arch/sparc64/solaris/timod.c8
-rw-r--r--drivers/cdrom/aztcd.c13
-rw-r--r--drivers/cdrom/cdrom.c159
-rw-r--r--drivers/cdrom/cm206.c7
-rw-r--r--drivers/cdrom/mcd.c18
-rw-r--r--drivers/cdrom/optcd.c13
-rw-r--r--drivers/cdrom/sjcd.c21
-rw-r--r--drivers/char/agp/agp.h16
-rw-r--r--drivers/char/agp/agpgart_be.c359
-rw-r--r--drivers/char/agp/agpgart_fe.c22
-rw-r--r--drivers/char/buz.c1
-rw-r--r--drivers/char/c-qcam.c84
-rw-r--r--drivers/char/joystick/joy-amiga.c22
-rw-r--r--drivers/char/joystick/joy-analog.c22
-rw-r--r--drivers/char/joystick/joy-assassin.c28
-rw-r--r--drivers/char/joystick/joy-console.c3
-rw-r--r--drivers/char/joystick/joy-creative.c22
-rw-r--r--drivers/char/joystick/joy-db9.c3
-rw-r--r--drivers/char/joystick/joy-gravis.c22
-rw-r--r--drivers/char/joystick/joy-lightning.c22
-rw-r--r--drivers/char/joystick/joy-logitech.c22
-rw-r--r--drivers/char/joystick/joy-magellan.c4
-rw-r--r--drivers/char/joystick/joy-pci.c25
-rw-r--r--drivers/char/joystick/joy-sidewinder.c22
-rw-r--r--drivers/char/joystick/joy-spaceball.c4
-rw-r--r--drivers/char/joystick/joy-spaceorb.c4
-rw-r--r--drivers/char/joystick/joy-thrustmaster.c22
-rw-r--r--drivers/char/joystick/joy-turbografx.c3
-rw-r--r--drivers/char/joystick/joy-warrior.c4
-rw-r--r--drivers/char/joystick/joystick.c29
-rw-r--r--drivers/char/pcmcia/serial_cb.c1
-rw-r--r--drivers/char/ppdev.c89
-rw-r--r--drivers/char/scan_keyb.c127
-rw-r--r--drivers/char/scan_keyb.h15
-rw-r--r--drivers/char/sh-sci.c500
-rw-r--r--drivers/char/sh-sci.h441
-rw-r--r--drivers/ieee1394/Makefile8
-rw-r--r--drivers/ieee1394/aic5800.c7
-rw-r--r--drivers/ieee1394/guid.c226
-rw-r--r--drivers/ieee1394/guid.h54
-rw-r--r--drivers/ieee1394/ieee1394_core.c87
-rw-r--r--drivers/ieee1394/ieee1394_syms.c6
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c32
-rw-r--r--drivers/ieee1394/ieee1394_types.h17
-rw-r--r--drivers/ieee1394/ohci1394.c1230
-rw-r--r--drivers/ieee1394/ohci1394.h63
-rw-r--r--drivers/ieee1394/pcilynx.c286
-rw-r--r--drivers/ieee1394/pcilynx.h174
-rw-r--r--drivers/ieee1394/raw1394.c13
-rw-r--r--drivers/ieee1394/video1394.h50
-rw-r--r--drivers/isdn/avmb1/b1pci.c11
-rw-r--r--drivers/isdn/avmb1/c4.c7
-rw-r--r--drivers/isdn/avmb1/capi.c1
-rw-r--r--drivers/isdn/avmb1/kcapi.c10
-rw-r--r--drivers/isdn/avmb1/t1pci.c5
-rw-r--r--drivers/isdn/eicon/eicon_pci.c12
-rw-r--r--drivers/isdn/hisax/avm_pci.c7
-rw-r--r--drivers/isdn/hisax/bkm_a4t.c5
-rw-r--r--drivers/isdn/hisax/diva.c18
-rw-r--r--drivers/isdn/hisax/elsa.c18
-rw-r--r--drivers/net/plip.c105
-rw-r--r--drivers/pcmcia/yenta.c4
-rw-r--r--drivers/sbus/audio/audio.c34
-rw-r--r--drivers/sbus/char/bpp.c1
-rw-r--r--drivers/sbus/char/envctrl.c12
-rw-r--r--drivers/sbus/char/flash.c5
-rw-r--r--drivers/sbus/char/jsflash.c5
-rw-r--r--drivers/sbus/char/openprom.c4
-rw-r--r--drivers/sbus/char/pcikbd.c10
-rw-r--r--drivers/sbus/char/rtc.c6
-rw-r--r--drivers/sbus/char/sunkbd.c3
-rw-r--r--drivers/sbus/char/sunmouse.c6
-rw-r--r--drivers/sbus/char/uctrl.c12
-rw-r--r--drivers/sbus/char/vfc_dev.c3
-rw-r--r--drivers/scsi/3w-xxxx.c12
-rw-r--r--drivers/scsi/53c7,8xx.c6
-rw-r--r--drivers/scsi/AM53C974.c16
-rw-r--r--drivers/scsi/BusLogic.c28
-rw-r--r--drivers/scsi/ChangeLog.ncr53c8xx44
-rw-r--r--drivers/scsi/ChangeLog.sym53c8xx61
-rw-r--r--drivers/scsi/NCR53C9x.c2
-rw-r--r--drivers/scsi/README.ncr53c8xx12
-rw-r--r--drivers/scsi/mac_esp.c7
-rw-r--r--drivers/scsi/mac_scsi.c5
-rw-r--r--drivers/scsi/ncr53c8xx.c502
-rw-r--r--drivers/scsi/scsi_scan.c81
-rw-r--r--drivers/scsi/sr.c20
-rw-r--r--drivers/scsi/sym53c8xx.c2229
-rw-r--r--drivers/scsi/sym53c8xx_comm.h6
-rw-r--r--drivers/scsi/sym53c8xx_defs.h106
-rw-r--r--fs/binfmt_aout.c2
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/exec.c2
-rw-r--r--fs/proc/base.c2
-rw-r--r--include/asm-alpha/console.h21
-rw-r--r--include/asm-alpha/core_titan.h525
-rw-r--r--include/asm-alpha/core_tsunami.h1
-rw-r--r--include/asm-alpha/core_wildfire.h427
-rw-r--r--include/asm-alpha/floppy.h45
-rw-r--r--include/asm-alpha/hwrpb.h4
-rw-r--r--include/asm-alpha/io.h4
-rw-r--r--include/asm-alpha/irq.h8
-rw-r--r--include/asm-alpha/mc146818rtc.h27
-rw-r--r--include/asm-alpha/pgtable.h3
-rw-r--r--include/asm-alpha/system.h18
-rw-r--r--include/asm-alpha/uaccess.h2
-rw-r--r--include/asm-alpha/unistd.h2
-rw-r--r--include/asm-arm/arch-arc/hardware.h8
-rw-r--r--include/asm-arm/arch-ebsa285/hardware.h2
-rw-r--r--include/asm-arm/arch-ebsa285/irq.h40
-rw-r--r--include/asm-arm/arch-ebsa285/irqs.h16
-rw-r--r--include/asm-arm/arch-ebsa285/memory.h4
-rw-r--r--include/asm-arm/arch-rpc/hardware.h3
-rw-r--r--include/asm-arm/arch-sa1100/assabet.h154
-rw-r--r--include/asm-arm/arch-sa1100/hardware.h97
-rw-r--r--include/asm-arm/arch-sa1100/irq.h426
-rw-r--r--include/asm-arm/arch-sa1100/irqs.h245
-rw-r--r--include/asm-arm/arch-sa1100/mmzone.h81
-rw-r--r--include/asm-arm/arch-sa1100/time.h11
-rw-r--r--include/asm-arm/arch-sa1100/uncompress.h71
-rw-r--r--include/asm-arm/arch-shark/time.h11
-rw-r--r--include/asm-arm/dec21285.h26
-rw-r--r--include/asm-arm/mc146818rtc.h27
-rw-r--r--include/asm-arm/mmzone.h12
-rw-r--r--include/asm-arm/page.h4
-rw-r--r--include/asm-arm/pgtable.h12
-rw-r--r--include/asm-arm/proc-armv/assembler.h70
-rw-r--r--include/asm-arm/proc-armv/locks.h3
-rw-r--r--include/asm-arm/setup.h1
-rw-r--r--include/asm-arm/socket.h15
-rw-r--r--include/asm-arm/system.h27
-rw-r--r--include/asm-arm/unistd.h2
-rw-r--r--include/asm-i386/processor.h2
-rw-r--r--include/asm-ppc/bitops.h127
-rw-r--r--include/asm-ppc/byteorder.h8
-rw-r--r--include/asm-ppc/cache.h4
-rw-r--r--include/asm-ppc/est8260.h10
-rw-r--r--include/asm-ppc/io.h14
-rw-r--r--include/asm-ppc/mc146818rtc.h27
-rw-r--r--include/asm-ppc/mmu.h25
-rw-r--r--include/asm-ppc/mmu_context.h10
-rw-r--r--include/asm-ppc/pgtable.h2
-rw-r--r--include/asm-ppc/posix_types.h11
-rw-r--r--include/asm-ppc/processor.h4
-rw-r--r--include/asm-ppc/prom.h4
-rw-r--r--include/asm-ppc/ptrace.h2
-rw-r--r--include/asm-ppc/rpxclassic.h21
-rw-r--r--include/asm-ppc/smp.h4
-rw-r--r--include/asm-ppc/socket.h15
-rw-r--r--include/asm-ppc/system.h1
-rw-r--r--include/asm-ppc/uaccess.h12
-rw-r--r--include/asm-s390/pgtable.h1
-rw-r--r--include/asm-s390/socket.h29
-rw-r--r--include/asm-sh/hd64461.h38
-rw-r--r--include/asm-sh/hitachi_se.h16
-rw-r--r--include/asm-sh/ide.h22
-rw-r--r--include/asm-sh/io.h3
-rw-r--r--include/asm-sh/irq.h4
-rw-r--r--include/asm-sh/keyboard.h44
-rw-r--r--include/asm-sh/linux_logo.h48
-rw-r--r--include/asm-sh/pgtable.h14
-rw-r--r--include/asm-sh/processor.h1
-rw-r--r--include/asm-sh/ptrace.h8
-rw-r--r--include/asm-sh/socket.h15
-rw-r--r--include/asm-sh/uaccess.h10
-rw-r--r--include/asm-sparc/asm_offsets.h276
-rw-r--r--include/asm-sparc/head.h4
-rw-r--r--include/asm-sparc/ide.h2
-rw-r--r--include/asm-sparc/kdebug.h10
-rw-r--r--include/asm-sparc/mc146818rtc.h27
-rw-r--r--include/asm-sparc/openprom.h7
-rw-r--r--include/asm-sparc/page.h10
-rw-r--r--include/asm-sparc/pgalloc.h18
-rw-r--r--include/asm-sparc/pgtable.h10
-rw-r--r--include/asm-sparc/pgtsrmmu.h5
-rw-r--r--include/asm-sparc/pgtsun4.h9
-rw-r--r--include/asm-sparc/pgtsun4c.h9
-rw-r--r--include/asm-sparc/siginfo.h2
-rw-r--r--include/asm-sparc/socket.h17
-rw-r--r--include/asm-sparc/vaddrs.h63
-rw-r--r--include/asm-sparc64/asm_offsets.h432
-rw-r--r--include/asm-sparc64/ide.h2
-rw-r--r--include/asm-sparc64/mc146818rtc.h27
-rw-r--r--include/asm-sparc64/string.h4
-rw-r--r--include/asm-sparc64/system.h8
-rw-r--r--include/linux/agp_backend.h1
-rw-r--r--include/linux/cdrom.h50
-rw-r--r--include/linux/fb.h1
-rw-r--r--include/linux/fs.h13
-rw-r--r--include/linux/input.h65
-rw-r--r--include/linux/joystick.h3
-rw-r--r--include/linux/notifier.h65
-rw-r--r--include/linux/sched.h12
-rw-r--r--kernel/Makefile4
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c4
-rw-r--r--kernel/ksyms.c3
-rw-r--r--kernel/signal.c4
-rw-r--r--kernel/sys.c120
437 files changed, 20495 insertions, 6663 deletions
diff --git a/Documentation/arm/README b/Documentation/arm/README
index 8e927b6f55f6a4..95e9bddd5d572b 100644
--- a/Documentation/arm/README
+++ b/Documentation/arm/README
@@ -1,9 +1,7 @@
- ARM Linux 2.2.3
- ===============
+ ARM Linux 2.4.0test1
+ ====================
- * NOTE * The ARM support in the mainstream Linux kernel sources
- is not up to date. Please check ftp.arm.uk.linux.org:/pub/armlinux
- for latest updates.
+ Please check ftp.arm.linux.org.uk:/pub/armlinux for latest updates.
Compilation of kernel
---------------------
@@ -13,10 +11,10 @@ Compilation of kernel
and EGCS are good compilers. Note that GCC-2.7.2.2 ELF is rare, and
you probably don't have it.
- To build ARM Linux natively, you shouldn't have to alter the ARCH = line in
- the top level Makefile. However, if you don't have the ARM Linux ELF tools
- installed as default, then you should change the CROSS_COMPILE line as
- detailed below.
+ To build ARM Linux natively, you shouldn't have to alter the ARCH = line
+ in the top level Makefile. However, if you don't have the ARM Linux ELF
+ tools installed as default, then you should change the CROSS_COMPILE
+ line as detailed below.
If you wish to cross-compile, then alter the following lines in the top
level make file:
@@ -41,27 +39,28 @@ Compilation of kernel
Bug reports etc
---------------
- Please send patches, bug reports and code for the ARM Linux project
- to linux@arm.linux.org.uk Patches will not be included into future
- kernels unless they come to me (or the relevant person concerned).
+ Please send patches to the patch system. For more information, see
+ http://www.arm.linux.org.uk/patches/info.html Always include some
+ explanation as to what the patch does and why it is needed.
+
+ Bug reports should be sent to linux-arm-kernel@lists.arm.linux.org.uk,
+ or submitted through the web form at
+ http://www.arm.linux.org.uk/forms/solution.shtml
When sending bug reports, please ensure that they contain all relevant
information, eg. the kernel messages that were printed before/during
the problem, what you were doing, etc.
- For patches, please include some explanation as to what the patch does
- and why (if relevant).
-
Modules
-------
Although modularisation is supported (and required for the FP emulator),
- each module on an arm2/arm250/arm3 machine when is loaded will take
- memory up to the next 32k boundary due to the size of the pages. Hence is
- modularisation on these machines really worth it?
+ each module on an ARM2/ARM250/ARM3 machine when is loaded will take
+ memory up to the next 32k boundary due to the size of the pages.
+ Therefore, modularisation on these machines really worth it?
- However, arm6 and up machines allow modules to take multiples of 4k, and
+ However, ARM6 and up machines allow modules to take multiples of 4k, and
as such Acorn RiscPCs and other architectures using these processors can
make good use of modularisation.
@@ -124,7 +123,7 @@ Kernel entry (head-armv.S)
The initial entry into the kernel made via head-armv.S uses architecture
independent code. The architecture is selected by the value of 'r1' on
entry, which must be kept unique. You can register a new architecture
- by mailing the following details to rmk@arm.uk.linux.org. Please give
+ by mailing the following details to rmk@arm.linux.org.uk Please give
the mail a subject of 'Register new architecture':
Name: <name of your architecture>
@@ -133,7 +132,7 @@ Kernel entry (head-armv.S)
<description of your architecture>
Please follow this format - it is an automated system. You should
- receive a reply the next day.
+ receive a reply within one day.
---
-Russell King (27/03/1999)
+Russell King (12/06/2000)
diff --git a/Documentation/arm/SA1100/LART b/Documentation/arm/SA1100/LART
index b7cdb8d901d5f0..2f73f513e16ace 100644
--- a/Documentation/arm/SA1100/LART
+++ b/Documentation/arm/SA1100/LART
@@ -10,6 +10,5 @@ daughterboards. A quad Ethernet / IDE / PS2 / sound daughterboard
is under development, with plenty of others in different stages of
planning.
-The designs for this board have been released under a GPL-like license;
-
-For lot more info, see the LART page at http://www.lart.tudelft.nl.
+The hardware designs for this board have been released under an open license;
+see the LART page at http://www.lart.tudelft.nl/ for more information.
diff --git a/Documentation/networking/8139too.txt b/Documentation/networking/8139too.txt
index 879bf6d2f2fcc0..f27811a2a1c749 100644
--- a/Documentation/networking/8139too.txt
+++ b/Documentation/networking/8139too.txt
@@ -181,11 +181,25 @@ User-mode (or maybe optional /proc) diagnostics program.
11) RTL8139C support untested.
+12) 10base-T support flaky or slow
+
Change History
--------------
+Version 0.9.7 - June 11, 2000
+
+* Fix support for older chips (RTL8139 early chips should now work again)
+
+
+Version 0.9.6 - May 30, 2000
+
+* Fix 4-extra-bytes bug
+ (thanks to Markus Westergren, via Santiago Garcia Mantinan)
+* Yet more improved chip recognition
+
+
Version 0.9.5 - May 17, 2000
* Improved chip version recognition
diff --git a/Documentation/networking/shaper.txt b/Documentation/networking/shaper.txt
index 53ff5aefff4d3a..1be0db8c0bc436 100644
--- a/Documentation/networking/shaper.txt
+++ b/Documentation/networking/shaper.txt
@@ -1,6 +1,6 @@
Traffic Shaper For Linux
-This is the current ALPHA release of the traffic shaper for Linux. It works
+This is the current BETA release of the traffic shaper for Linux. It works
within the following limits:
o Minimum shaping speed is currently about 9600 baud (it can only
@@ -37,13 +37,12 @@ and will treat it as such unless patched. Note that for mrouted you can run
mrouted tunnels via a traffic shaper to control bandwidth usage.
The shaper is device/route based. This makes it very easy to use
-with any setup BUT less flexible. You may well want to combine this patch
-with Mike McLagan <mmclagan@linux.org>'s patch to allow routes to be
-specified by source/destination pairs.
+with any setup BUT less flexible. You may need to use iproute2 to set up
+multiple route tables to get the flexibility.
There is no "borrowing" or "sharing" scheme. This is a simple
-traffic limiter. I'd like to implement Van Jacobson and Sally Floyd's CBQ
-architecture into Linux one day (maybe in 2.1 sometime) and do this with
-style.
+traffic limiter. We implement Van Jacobson and Sally Floyd's CBQ
+architecture into Linux 2.2. THis is the preferred solution. Shaper is
+for simple or back compatible setups.
Alan
diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
index 863090170bce24..510d2c4ef82f1c 100644
--- a/Documentation/networking/sk98lin.txt
+++ b/Documentation/networking/sk98lin.txt
@@ -3,7 +3,7 @@
sk98lin.txt created 11-Nov-1999
-Readme File for sk98lin.o v3.02
+Readme File for sk98lin.o v3.04
SK-NET Gigabit Ethernet Adapter SK-98xx Driver for Linux
This file contains
@@ -24,8 +24,8 @@ This file contains
============
The sk98lin driver supports the SysKonnect SK-NET Gigabit Ethernet
-Adapter SK-98xx family on Linux 2.2.x.
-It has been tested with Linux on Intel/x86 and ALPHA machines.
+Adapter SK-98xx family on Linux 2.2.x and above.
+It has been tested with Linux on Intel/x86, ALPHA and UltraSPARC machines.
From v3.02 on, the driver is integrated in the linux kernel source.
***
@@ -132,7 +132,8 @@ Parameters can be set at the command line while loading the
module with 'insmod'. The configuration tools of some distributions
can also give parameters to the driver module.
If you use the kernel module loader, you can set driver parameters
-in the file /etc/conf.modules. Insert a line of the form:
+in the file /etc/modules.conf (or old name: /etc/conf.modules).
+Insert a line of the form:
options sk98lin ...
@@ -281,14 +282,12 @@ The setting must be done on all adapters that can be reached by
the large frames. If one adapter is not set to receive large frames,
it will simply drop them.
-NOTE: If you look at the statistics (with netstat) in large frame
- mode while there is traffic on the net, you will see the
- RX error counter go up. This is because the adapter hardware
- counts received large frames as errors, although they are
- received correctly. So ignore this counter in that case.
-
You can switch back to the standard ethernet frame size with:
ifconfig eth0 mtu 1500
+
+To make this setting persitent, add a script with the 'ifconfig'
+line to the system startup sequence (named something like "S99sk98lin"
+in /etc/rc.d/rc2.d).
***
@@ -374,15 +373,27 @@ following information is available:
(8) HISTORY
===========
-VERSION 3.02
+VERSION 3.04 (In-Kernel version)
+Problems fixed:
+- Driver start failed on UltraSPARC
+- Rx checksum calculation for big endian machines did not work
+- Jumbo frames were counted as input-errors in netstat
+
+VERSION 3.03 (Standalone version)
+Problems fixed:
+- Compilation did not find script "printver.sh" if "." not in PATH
+Known limitations:
+- None
+
+VERSION 3.02 (In-Kernel version)
Problems fixed:
- None
New Features:
-- Integration in linux kernel source.
+- Integration in Linux kernel source (2.2.14 and 2.3.29)
Known limitations:
- None
-VERSION 3.02
+VERSION 3.01
Problems fixed:
- None
New Features:
diff --git a/Documentation/networking/tulip.txt b/Documentation/networking/tulip.txt
index be41c4031198a7..b936846afda6bb 100644
--- a/Documentation/networking/tulip.txt
+++ b/Documentation/networking/tulip.txt
@@ -142,6 +142,24 @@ tulip_core.c - Driver core (a.k.a. where "everything else" goes)
Version history
===============
+0.9.6 (May 31, 2000):
+* Revert 21143-related support flag patch
+* Add HPPA/media-table debugging printk
+
+0.9.5 (May 30, 2000):
+* HPPA support (willy@puffingroup)
+* CSR6 bits and tulip.h cleanup (Chris Smith)
+* Improve debugging messages a bit
+* Add delay after CSR13 write in t21142_start_nway
+* Remove unused ETHER_STATS code
+* Convert 'extern inline' to 'static inline' in tulip.h (Chris Smith)
+* Update DS21143 support flags in tulip_chip_info[]
+* Use spin_lock_irq, not _irqsave/restore, in tulip_start_xmit()
+* Add locking to set_rx_mode()
+* Fix race with chip setting DescOwned bit (Hal Murray)
+* Request 100% of PIO and MMIO resource space assigned to card
+* Remove error message from pci_enable_device failure
+
0.9.4.3 (April 14, 2000):
* mod_timer fix (Hal Murray)
* PNIC2 resusitation (Chris Smith)
diff --git a/Documentation/networking/vortex.txt b/Documentation/networking/vortex.txt
index 850ce4838d5446..19d30079d4caa3 100644
--- a/Documentation/networking/vortex.txt
+++ b/Documentation/networking/vortex.txt
@@ -156,7 +156,12 @@ compaq_device_id=N
"Variables to work-around the Compaq PCI BIOS32 problem"....
+watchdog=N
+ Sets the time duration (in milliseconds) after which the kernel
+ decides that the transmitter has become stuck and needs to be reset.
+ This is mainly for debugging purposes. The default value is 400 (0.4
+ seconds).
Additional resources
--------------------
diff --git a/Documentation/parport.txt b/Documentation/parport.txt
index b4d7ff89585aec..59e75b5faeb35e 100644
--- a/Documentation/parport.txt
+++ b/Documentation/parport.txt
@@ -109,7 +109,10 @@ parport
| | |-- active
| | `-- lp
| | `-- timeslice
-| |-- hardware
+| |-- base-addr
+| |-- irq
+| |-- dma
+| |-- modes
| `-- spintime
`-- parport1
|-- autoprobe
@@ -121,7 +124,10 @@ parport
| |-- active
| `-- ppa
| `-- timeslice
- |-- hardware
+ |-- base-addr
+ |-- irq
+ |-- dma
+ |-- modes
`-- spintime
@@ -133,7 +139,28 @@ devices/active A list of the device drivers using that port. A "+"
string "none" means that there are no device drivers
using that port.
-hardware Parallel port's base address, IRQ line and DMA channel.
+base-addr Parallel port's base address, or addresses if the port
+ has more than one in which case they are separated
+ with tabs. These values might not have any sensible
+ meaning for some ports.
+
+irq Parallel port's IRQ, or -1 if none is being used.
+
+dma Parallel port's DMA channel, or -1 if none is being
+ used.
+
+modes Parallel port's hardware modes, comma-separated,
+ meaning:
+
+ PCSPP PC-style SPP registers are available.
+ TRISTATE Port is bidirectional.
+ COMPAT Hardware acceleration for printers is
+ available and will be used.
+ EPP Hardware acceleration for EPP protocol
+ is available and will be used.
+ ECP Hardware acceleration for ECP protocol
+ is available and will be used.
+ DMA DMA is available and will be used.
autoprobe Any IEEE-1284 device ID information that has been
acquired from the (non-IEEE 1284.3) device.
diff --git a/Documentation/powerpc/SBC8260_memory_mapping.txt b/Documentation/powerpc/SBC8260_memory_mapping.txt
new file mode 100644
index 00000000000000..c61827c07b823c
--- /dev/null
+++ b/Documentation/powerpc/SBC8260_memory_mapping.txt
@@ -0,0 +1,197 @@
+Please mail me (Jon Diekema, diekema_jon@si.com or diekema@cideas.com)
+if you have questions, comments or corrections.
+
+ * EST SBC8260 Linux memory mapping rules
+
+ http://www.estc.com/
+ http://www.estc.com/products/boards/SBC8260-8240_ds.html
+
+ Initial conditions:
+ -------------------
+
+ Tasks that need to be perform by the boot ROM before control is
+ transferred to zImage (compressed Linux kernel):
+
+ - Define the IMMR to 0xf0000000
+
+ - Initialize the memory controller so that RAM is available at
+ physical address 0x00000000. On the SBC8260 is this 16M (64M)
+ SDRAM.
+
+ - The boot ROM should only clear the RAM that it is using.
+
+ The reason for doing this is to enhances the chances of a
+ successful post mortem on a Linux panic. One of the first
+ items to examine is the 16k (LOG_BUF_LEN) circular console
+ buffer called log_buf which is defined in kernel/printk.c.
+
+ - To enhance boot ROM performance, the I-cache can be enabled.
+
+ Date: Mon, 22 May 2000 14:21:10 -0700
+ From: Neil Russell <caret@c-side.com>
+
+ LiMon (LInux MONitor) runs with and starts Linux with MMU
+ off, I-cache enabled, D-cache disabled. The I-cache doesn't
+ need hints from the MMU to work correctly as the D-cache
+ does. No D-cache means no special code to handle devices in
+ the presence of cache (no snooping, etc). The use of the
+ I-cache means that the monitor can run acceptably fast
+ directly from ROM, rather than having to copy it to RAM.
+
+ - Build the board information structure (see
+ include/asm-ppc/est8260.h for its definition)
+
+ - The compressed Linux kernel (zImage) contains a bootstrap loader
+ that is position independent; you can load it into any RAM,
+ ROM or FLASH memory address >= 0x00500000 (above 5 MB), or
+ at its link address of 0x00400000 (4 MB).
+
+ Note: If zImage is loaded at its link address of 0x00400000 (4 MB),
+ then zImage will skip the step of moving itself to
+ its link address.
+
+ - Load R3 with the address of the board information structure
+
+ - Transfer control to zImage
+
+ - The Linux console port is SMC1, and the baud rate is controlled
+ from the bi_baudrate field of the board information structure.
+ On thing to keep in mind when picking the baud rate, is that
+ there is no flow control on the SMC ports. I would stick
+ with something safe and standard like 19200.
+
+ On the EST SBC8260, the SMC1 port is on the COM1 connector of
+ the board.
+
+
+ EST SBC8260 defaults:
+ ---------------------
+
+ Chip
+ Memory Sel Bus Use
+ --------------------- --- --- ----------------------------------
+ 0x00000000-0x03FFFFFF CS2 60x (16M or 64M)/64M SDRAM
+ 0x04000000-0x04FFFFFF CS4 local 4M/16M SDRAM (soldered to the board)
+ 0x21000000-0x21000000 CS7 60x 1B/64K Flash present detect (from the flash SIMM)
+ 0x21000001-0x21000001 CS7 60x 1B/64K Switches (read) and LEDs (write)
+ 0x22000000-0x2200FFFF CS5 60x 8K/64K EEPROM
+ 0xFC000000-0xFCFFFFFF CS6 60x 2M/16M flash (8 bits wide, soldered to the board)
+ 0xFE000000-0xFFFFFFFF CS0 60x 4M/16M flash (SIMM)
+
+ Notes:
+ ------
+
+ - The chip selects can map 32K blocks and up (powers of 2)
+
+ - The SDRAM machine can handled up to 128Mbytes per chip select
+
+ - Linux uses the 60x bus memory (the SDRAM DIMM) for the
+ communications buffers.
+
+ - BATs can map 128K-256Mbytes each. There are four data BATs and
+ four instruction BATs. Generally the data and instruction BATs
+ are mapped the same.
+
+ - The IMMR must be set above the kernel virtual memory addresses,
+ which start at 0xC0000000. Otherwise, the kernel may crash as
+ soon as you start any threads or processes due to VM collisions
+ in the kernel or user process space.
+
+
+ Details from Dan Malek <dan_malek@mvista.com> on 10/29/1999:
+
+ The user application virtual space consumes the first 2 Gbytes
+ (0x00000000 to 0x7FFFFFFF). The kernel virtual text starts at
+ 0xC0000000, with data following. There is a "protection hole"
+ between the end of kernel data and the start of the kernel
+ dynamically allocated space, but this space is still within
+ 0xCxxxxxxx.
+
+ Obviously the kernel can't map any physical addresses 1:1 in
+ these ranges.
+
+
+ Details from Dan Malek <dan_malek@mvista.com> on 5/19/2000:
+
+ During the early kernel initialization, the kernel virtual
+ memory allocator is not operational. Prior to this KVM
+ initialization, we choose to map virtual to physical addresses
+ 1:1. That is, the kernel virtual address exactly matches the
+ physical address on the bus. These mappings are typically done
+ in arch/ppc/kernel/head.S, or arch/ppc/mm/init.c. Only
+ absolutely necessary mappings should be done at this time, for
+ example board control registers or a serial uart. Normal device
+ driver initialization should map resources later when necessary.
+
+ Although platform dependent, and certainly the case for embedded
+ 8xx, traditionally memory is mapped at physical address zero,
+ and I/O devices above phsical address 0x80000000. The lowest
+ and highest (above 0xf0000000) I/O addresses are traditionally
+ used for devices or registers we need to map during kernel
+ initialization and prior to KVM operation. For this reason,
+ and since it followed prior PowerPC platform examples, I chose
+ to map the embedded 8xx kernel to the 0xc0000000 virtual address.
+ This way, we can enable the MMU to map the kernel for proper
+ operation, and still map a few windows before the KVM is operational.
+
+ On some systems, you could possibly run the kernel at the
+ 0x80000000 or any other virtual address. It just depends upon
+ mapping that must be done prior to KVM operational. You can never
+ map devices or kernel spaces that overlap with the user virtual
+ space. This is why default IMMR mapping used by most BDM tools
+ won't work. They put the IMMR at something like 0x10000000 or
+ 0x02000000 for example. You simply can't map these addresses early
+ in the kernel, and continue proper system operation.
+
+ The embedded 8xx/82xx kernel is mature enough that all you should
+ need to do is map the IMMR someplace at or above 0xf0000000 and it
+ should boot far enough to get serial console messages and KGDB
+ connected on any platform. There are lots of other subtle memory
+ management design features that you simply don't need to worry
+ about. If you are changing functions related to MMU initialization,
+ you are likely breaking things that are known to work and are
+ heading down a path of disaster and frustration. Your changes
+ should be to make the flexibility of the processor fit Linux,
+ not force arbitrary and non-workable memory mappings into Linux.
+
+ - You don't want to change KERNELLOAD or KERNELBASE, otherwise the
+ virtual memory and MMU code will get confused.
+
+ arch/ppc/Makefile:KERNELLOAD = 0xc0000000
+
+ include/asm-ppc/page.h:#define PAGE_OFFSET 0xc0000000
+ include/asm-ppc/page.h:#define KERNELBASE PAGE_OFFSET
+
+ - RAM is at physical address 0x00000000, and gets mapped to
+ virtual address 0xC0000000 for the kernel.
+
+
+ Physical addresses used by the Linux kernel:
+ --------------------------------------------
+
+ 0x00000000-0x3FFFFFFF 1GB reserved for RAM
+ 0xF0000000-0xF001FFFF 128K IMMR 64K used for dual port memory,
+ 64K for 8260 registers
+
+
+ Logical addresses used by the Linux kernel:
+ -------------------------------------------
+
+ 0xF0000000-0xFFFFFFFF 256M BAT0 (IMMR: dual port RAM, registers)
+ 0xE0000000-0xEFFFFFFF 256M BAT1 (I/O space for custom boards)
+ 0xC0000000-0xCFFFFFFF 256M BAT2 (RAM)
+ 0xD0000000-0xDFFFFFFF 256M BAT3 (if RAM > 256MByte)
+
+
+ EST SBC8260 Linux mapping:
+ --------------------------
+
+ DBAT0, IBAT0, cache inhibited:
+
+ Chip
+ Memory Sel Use
+ --------------------- --- ---------------------------------
+ 0xF0000000-0xF001FFFF n/a IMMR: dual port RAM, registers
+
+ DBAT1, IBAT1, cache inhibited:
+
diff --git a/Documentation/usb/input.txt b/Documentation/usb/input.txt
index 262c595e4ba4d7..c60bd900bad08c 100644
--- a/Documentation/usb/input.txt
+++ b/Documentation/usb/input.txt
@@ -1,6 +1,7 @@
- Linux Input drivers v0.9
- (c) 1999 Vojtech Pavlik <vojtech@suse.cz>
+ Linux Input drivers v1.0
+ (c) 1999-2000 Vojtech Pavlik <vojtech@suse.cz>
Sponsored by SuSE
+ $Id: input.txt,v 1.4 2000/05/28 17:57:22 vojtech Exp $
----------------------------------------------------------------------------
0. Disclaimer
@@ -62,27 +63,27 @@ kernel):
hid.o
After this, the USB keyboard will work straight away, and the USB mouse
-will be available as a character device on major 13, minor 32:
+will be available as a character device on major 13, minor 63:
- crw-r--r-- 1 root root 13, 32 Mar 28 22:45 mouse0
+ crw-r--r-- 1 root root 13, 63 Mar 28 22:45 mice
This device, has to be created, unless you use devfs, in which case it's
created automatically. The commands to do that are:
cd /dev
mkdir input
- mknod input/mouse0 c 13 32
+ mknod input/mice c 13 63
After that you have to point GPM (the textmode mouse cut&paste tool) and
XFree to this device to use it - GPM should be called like:
- gpm -t ps2 -m /dev/input/mouse0
+ gpm -t ps2 -m /dev/input/mice
And in X:
Section "Pointer"
Protocol "ImPS/2"
- Device "/dev/input/mouse0"
+ Device "/dev/input/mice"
ZAxisMapping 4 5
EndSection
@@ -199,10 +200,11 @@ no mice are present.
CONFIG_INPUT_MOUSEDEV_SCREEN_[XY] in the kernel configuration are the size
of your screen (in pixels) in XFree86. This is needed if you want to use
your digitizer in X, because it's movement is sent to X via a virtual PS/2
-mouse. These values won't be used if you use a mouse only.
+mouse and thus needs to be scaled accordingly. These values won't be used if
+you use a mouse only.
- Mousedev.c will generate either PS/2, ImPS/2 (microsoft intellimouse) or
-GenPS/2 (genius netmouse/netscroll) protocols, depending on what the program
+ Mousedev will generate either PS/2, ImPS/2 (Microsoft IntelliMouse) or
+GenPS/2 (Genius NetMouse/NetScroll) protocols, depending on what the program
reading the data wishes. You can set GPM and X to any of these. You'll need
ImPS/2 if you want to make use of a wheel on a USB mouse and GenPS/2 if you
want to use extra (up to 5) buttons. I'm not sure how much is GenPS/2 supported
@@ -249,8 +251,12 @@ independent.
http://www.suse.cz/development/input/
-You'll find both the latest HID driver and the complete Input driver there.
-There is also a mailing list for this:
+You'll find both the latest HID driver and the complete Input driver there
+as well as information how to access the CVS repository for latest revisions
+of the drivers.
+
+
+ There is also a mailing list for this:
majordomo@atrey.karlin.mff.cuni.cz
@@ -278,8 +284,8 @@ can. Here goes a description of the current state of things, which is going
to be extended, but not changed incompatibly as time goes:
You can use blocking and nonblocking reads, also select() on the
-/dev/inputX devices, and you'll always get a whole number of input events on
-a read. Their layout is:
+/dev/input/eventX devices, and you'll always get a whole number of input
+events on a read. Their layout is:
struct input_event {
struct timeval time;
diff --git a/Documentation/usb/ov511.txt b/Documentation/usb/ov511.txt
index 65a0c4caab3e90..a9245312959ffd 100644
--- a/Documentation/usb/ov511.txt
+++ b/Documentation/usb/ov511.txt
@@ -6,21 +6,16 @@ Author: Mark McClelland
Homepage: http://alpha.dyndns.org/ov511
NEW IN THIS VERSION:
- o 384x288 and 448x336 modes
- o better /proc/video support
+ o Race conditions and other bugs fixed
INTRODUCTION:
-This is a preliminary version of my OV511 Linux device driver. Currently, it can
-grab a frame in color (YUV420) at 640x480 or 320x240 using either vidcat or
-xawtv. Other utilities may work but have not yet been tested.
-
-Any camera using the OV511/OV511+ and the OV7610/20/20AE CCD should work. The
-driver only detects known cameras though, based on their custom id number. If
-you have a currently unsupported camera, the ID number should be reported to you
-in the kernel logs. Please send me the model, manufacturer and ID number and I
-will add it to the detection code. In the meantime, you can add to the code
-yourself in the function ov511_probe().
+This is a driver for the OV511, a USB-only chip used in many "webcam" devices.
+Any camera using the OV511/OV511+ and the OV7610/20/20AE CCD should work.It
+supports streaming and capture of color or monochrome video via the Video4Linux
+API. Most V4L apps are compatible with it, but a few videoconferencing programs
+do not work yet. The following resolutions are supported: 640x480, 448x336,
+384x288, 352x288, and 320x240.
WHAT YOU NEED:
@@ -93,7 +88,8 @@ A: The I2C code that allows the OV511 to communicate with the camera chip is a
bit flaky right now. This message means that the I2C bus never got
initialized properly, and the camera will most likely not work even if you
disable this warning. Try unloading/reloading the driver or unplugging/re-
- plugging the camera if this happens.
+ plugging the camera if this happens. Also try increasing the i2c_detect_tries
+ parameter (see below).
Q: "Why do you bother with this phony camera detection crap? It doesn't do
anything useful!"
@@ -200,9 +196,6 @@ TODO:
would like them to release their specifications to the Linux community.
o Get 160x120 working
o YUV422 (and other color modes)
- o Fix read(). It only works right now if you run an mmap() based app like xawtv
- or vidcat after loading the module and before using read(). Apparently there
- are some initialization issues.
o Get snapshot mode working with mmap().
o Fix fixFrameRGBoffset(). It is not stable yet with streaming video.
o Get hue (red/blue channel balance) adjustment working (in ov511_get_picture()
diff --git a/Makefile b/Makefile
index a2d1995469bb7b..eeced7e727cf30 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 0
-EXTRAVERSION = -test1
+EXTRAVERSION = -test2
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c
index bb892ba3c57bfb..3be5fd6b6159fd 100644
--- a/arch/alpha/boot/bootp.c
+++ b/arch/alpha/boot/bootp.c
@@ -93,7 +93,7 @@ pal_init(void)
i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
if (i) {
srm_printk("failed, code %ld\n", i);
- halt();
+ __halt();
}
percpu = (struct percpu_struct *)
@@ -171,8 +171,7 @@ start_kernel(void)
srm_printk("Initrd positioned at %#lx\n", initrd_start);
#endif
- nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
- envval, sizeof(envval));
+ nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
if (nbytes < 0 || nbytes >= sizeof(envval)) {
nbytes = 0;
}
@@ -181,18 +180,17 @@ start_kernel(void)
/* NOTE: *no* callbacks or printouts from here on out!!! */
- /*
- * This is a hack, as some consoles seem to get virtual 20000000
- * (ie where the SRM console puts the kernel bootp image) memory
- * overlapping physical 310000 memory, which causes real problems
- * when attempting to copy the former to the latter... :-(
+ /* This is a hack, as some consoles seem to get virtual 20000000 (ie
+ * where the SRM console puts the kernel bootp image) memory
+ * overlapping physical memory where the kernel wants to be put,
+ * which causes real problems when attempting to copy the former to
+ * the latter... :-(
*
* So, we first move the kernel virtual-to-physical way above where
* we physically want the kernel to end up, then copy it from there
* to its final resting place... ;-}
*
- * Sigh...
- */
+ * Sigh... */
#ifdef INITRD_SIZE
load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_SIZE);
diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c
index 07913d8998f72e..78c9b0b6eea7cd 100644
--- a/arch/alpha/boot/main.c
+++ b/arch/alpha/boot/main.c
@@ -90,7 +90,7 @@ pal_init(void)
i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
if (i) {
srm_printk("failed, code %ld\n", i);
- halt();
+ __halt();
}
percpu = (struct percpu_struct *)
@@ -107,15 +107,15 @@ static inline long openboot(void)
char bootdev[256];
long result;
- result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
+ result = callback_getenv(ENV_BOOTED_DEV, bootdev, 255);
if (result < 0)
return result;
- return srm_dispatch(CCB_OPEN, bootdev, result & 255);
+ return callback_open(bootdev, result & 255);
}
static inline long close(long dev)
{
- return srm_dispatch(CCB_CLOSE, dev);
+ return callback_close(dev);
}
static inline long load(long dev, unsigned long addr, unsigned long count)
@@ -124,7 +124,7 @@ static inline long load(long dev, unsigned long addr, unsigned long count)
extern char _end;
long result, boot_size = &_end - (char *) BOOT_ADDR;
- result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
+ result = callback_getenv(ENV_BOOTED_FILE, bootfile, 255);
if (result < 0)
return result;
result &= 255;
@@ -132,7 +132,7 @@ static inline long load(long dev, unsigned long addr, unsigned long count)
if (result)
srm_printk("Boot file specification (%s) not implemented\n",
bootfile);
- return srm_dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1);
+ return callback_read(dev, count, addr, boot_size/512 + 1);
}
/*
@@ -176,8 +176,7 @@ void start_kernel(void)
return;
}
- nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
- envval, sizeof(envval));
+ nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
if (nbytes < 0) {
nbytes = 0;
}
@@ -188,5 +187,5 @@ void start_kernel(void)
runkernel();
for (i = 0 ; i < 0x100000000 ; i++)
/* nothing */;
- halt();
+ __halt();
}
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index 6053ae25ca7098..5f344e0f57ef52 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -1,6 +1,6 @@
#
# For a description of the syntax of this configuration file,
-# see the Configure script.
+# see Documentation/kbuild/config-language.txt.
#
define_bool CONFIG_UID16 n
@@ -51,7 +51,9 @@ choice 'Alpha system type' \
RX164 CONFIG_ALPHA_RX164 \
SX164 CONFIG_ALPHA_SX164 \
Sable CONFIG_ALPHA_SABLE \
- Takara CONFIG_ALPHA_TAKARA" Generic
+ Takara CONFIG_ALPHA_TAKARA \
+ Titan CONFIG_ALPHA_TITAN \
+ Wildfire CONFIG_ALPHA_WILDFIRE" Generic
# clear all implied options (don't want default values for those):
unset CONFIG_ALPHA_EV4 CONFIG_ALPHA_EV5 CONFIG_ALPHA_EV6
@@ -131,6 +133,16 @@ then
define_bool CONFIG_ALPHA_EV6 y
define_bool CONFIG_ALPHA_TSUNAMI y
fi
+if [ "$CONFIG_ALPHA_WILDFIRE" = "y" ]
+then
+ define_bool CONFIG_PCI y
+ define_bool CONFIG_ALPHA_EV6 y
+fi
+if [ "$CONFIG_ALPHA_TITAN" = "y" ]
+then
+ define_bool CONFIG_PCI y
+ define_bool CONFIG_ALPHA_EV6 y
+fi
if [ "$CONFIG_ALPHA_RAWHIDE" = "y" ]
then
define_bool CONFIG_ALPHA_EV5 y
@@ -151,18 +163,23 @@ then
define_bool CONFIG_ALPHA_IRONGATE y
fi
+if [ "$CONFIG_ALPHA_JENSEN" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
+ -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \
+ -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
+ -o "$CONFIG_ALPHA_EIGER" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" \
+ -o "$CONFIG_ALPHA_TITAN" = "y" ]
+then
+ define_bool CONFIG_ALPHA_SRM y
+fi
if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
- -o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_JENSEN" = "y" \
+ -o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
-o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \
- -o "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_ALCOR" = "y" \
- -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
- -o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
- -o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" \
- -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
- -o "$CONFIG_ALPHA_EIGER" = "y" ]
+ -o "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
+ -o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" ]
then
bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
fi
+
if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \
-o "$CONFIG_ALPHA_RAWHIDE" = "y" ]
@@ -179,7 +196,8 @@ then
fi
if [ "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
- -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_GENERIC" = "y" ]
+ -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" \
+ -o "$CONFIG_ALPHA_TITAN" = "y" -o "$CONFIG_ALPHA_GENERIC" = "y" ]
then
bool 'Symmetric multi-processing support' CONFIG_SMP
fi
@@ -286,6 +304,12 @@ if [ "$CONFIG_VT" = "y" ]; then
mainmenu_option next_comment
comment 'Console drivers'
bool 'VGA text console' CONFIG_VGA_CONSOLE
+# if [ "$CONFIG_PCI" = "y" -a "$CONFIG_VGA_CONSOLE" = "y" ]; then
+# bool ' Allow VGA on any bus?' CONFIG_VGA_HOSE
+# if [ "$CONFIG_VGA_HOSE" = "y" ]; then
+# define_bool CONFIG_DUMMY_CONSOLE y
+# fi
+# fi
source drivers/video/Config.in
if [ "$CONFIG_FB" = "y" ]; then
define_bool CONFIG_PCI_CONSOLE y
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index 37d7a863077402..f7bf7b2a087579 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -45,6 +45,8 @@ CONFIG_ALPHA_GENERIC=y
# CONFIG_ALPHA_SX164 is not set
# CONFIG_ALPHA_SABLE is not set
# CONFIG_ALPHA_TAKARA is not set
+# CONFIG_ALPHA_TITAN is not set
+# CONFIG_ALPHA_WILDFIRE is not set
CONFIG_ISA=y
# CONFIG_SBUS is not set
CONFIG_PCI=y
@@ -83,10 +85,6 @@ CONFIG_BLK_DEV_FD=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 3a0a4ec0bf2e06..3b8d98bd29f8f6 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -26,17 +26,22 @@ O_OBJS += smp.o irq_smp.o
endif
ifdef CONFIG_PCI
-L_OBJS += pci.o pci_iommu.o
+O_OBJS += pci.o pci_iommu.o
+endif
+
+ifdef CONFIG_VGA_HOSE
+L_OBJS += console.o
endif
ifdef CONFIG_ALPHA_GENERIC
O_OBJS += core_apecs.o core_cia.o core_irongate.o core_lca.o core_mcpcia.o \
- core_polaris.o core_t2.o core_tsunami.o \
+ core_polaris.o core_t2.o core_tsunami.o core_titan.o \
sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
- sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \
+ sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o sys_titan.o \
sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
- sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o
+ sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \
+ sys_wildfire.o core_wildfire.o
else
@@ -62,9 +67,15 @@ endif
ifdef CONFIG_ALPHA_TSUNAMI
O_OBJS += core_tsunami.o
endif
+ifdef CONFIG_ALPHA_TITAN
+O_OBJS += core_titan.o
+endif
ifdef CONFIG_ALPHA_POLARIS
O_OBJS += core_polaris.o
endif
+ifdef CONFIG_ALPHA_WILDFIRE
+O_OBJS += core_wildfire.o
+endif
# Board support
ifneq ($(CONFIG_ALPHA_ALCOR)$(CONFIG_ALPHA_XLT),)
@@ -76,6 +87,9 @@ endif
ifdef CONFIG_ALPHA_DP264
O_OBJS += sys_dp264.o
endif
+ifdef CONFIG_ALPHA_TITAN
+O_OBJS += sys_titan.o
+endif
ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),)
O_OBJS += sys_eb64p.o
endif
@@ -118,6 +132,9 @@ endif
ifdef CONFIG_ALPHA_TAKARA
O_OBJS += sys_takara.o
endif
+ifdef CONFIG_ALPHA_WILDFIRE
+O_OBJS += sys_wildfire.o
+endif
endif # GENERIC
diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c
new file mode 100644
index 00000000000000..b946ce0ed4aadc
--- /dev/null
+++ b/arch/alpha/kernel/console.c
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/alpha/kernel/console.c
+ *
+ * Architecture-specific specific support for VGA device on
+ * non-0 I/O hose
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <asm/vga.h>
+#include <asm/machvec.h>
+
+#ifdef CONFIG_VGA_HOSE
+
+/*
+ * Externally-visible vga hose bases
+ */
+unsigned long __vga_hose_io_base = 0; /* base for default hose */
+unsigned long __vga_hose_mem_base = 0; /* base for default hose */
+
+static struct pci_controler * __init
+default_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2)
+{
+ if (h2->index < h1->index)
+ return h2;
+
+ return h1;
+}
+
+void __init
+set_vga_hose(struct pci_controler *hose)
+{
+ if (hose) {
+ __vga_hose_io_base = hose->io_space->start;
+ __vga_hose_mem_base = hose->mem_space->start;
+ }
+}
+
+void __init
+locate_and_init_vga(void *(*sel_func)(void *, void *))
+{
+ struct pci_controler *hose = NULL;
+ struct pci_dev *dev = NULL;
+
+ if (!sel_func) sel_func = (void *)default_vga_hose_select;
+
+ for(dev=NULL; (dev=pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) {
+ if (!hose) hose = dev->sysdata;
+ else hose = sel_func(hose, dev->sysdata);
+ }
+
+ /* Did we already inititialize the correct one? */
+ if (conswitchp == &vga_con &&
+ __vga_hose_io_base == hose->io_space->start &&
+ __vga_hose_mem_base == hose->mem_space->start)
+ return;
+
+ /* Set the VGA hose and init the new console */
+ set_vga_hose(hose);
+ take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
+}
+
+#endif
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 527c4f5eb9ce78..648090d2407e4e 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -45,6 +45,8 @@
#define MCPCIA_MAX_HOSES 4
+static int mcpcia_hose_count; /* Actual number found. */
+
/*
* Given a bus, device, and function number, compute resulting
* configuration space address and setup the MCPCIA_HAXR2 register
@@ -308,6 +310,7 @@ mcpcia_probe_hose(int h)
mb();
draina();
wrmces(7);
+
mcheck_expected(cpu) = 2; /* indicates probing */
mcheck_taken(cpu) = 0;
mcheck_extra(cpu) = mid;
@@ -410,18 +413,19 @@ mcpcia_startup_hose(struct pci_controler *hose)
* ??? We ought to scale window 1 with memory.
*/
- hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
- hose->sg_pci = iommu_arena_new(hose, 0x40000000, 0x08000000, 0);
+ /* Make sure to align the arenas. */
+ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 1);
+ hose->sg_pci = iommu_arena_new(hose, 0x40000000, 0x08000000, 1);
__direct_map_base = 0x80000000;
__direct_map_size = 0x80000000;
*(vuip)MCPCIA_W0_BASE(mid) = hose->sg_isa->dma_base | 3;
*(vuip)MCPCIA_W0_MASK(mid) = (hose->sg_isa->size - 1) & 0xfff00000;
- *(vuip)MCPCIA_T0_BASE(mid) = virt_to_phys(hose->sg_isa->ptes) >> 2;
+ *(vuip)MCPCIA_T0_BASE(mid) = virt_to_phys(hose->sg_isa->ptes) >> 8;
*(vuip)MCPCIA_W1_BASE(mid) = hose->sg_pci->dma_base | 3;
*(vuip)MCPCIA_W1_MASK(mid) = (hose->sg_pci->size - 1) & 0xfff00000;
- *(vuip)MCPCIA_T1_BASE(mid) = virt_to_phys(hose->sg_pci->ptes) >> 2;
+ *(vuip)MCPCIA_T1_BASE(mid) = virt_to_phys(hose->sg_pci->ptes) >> 8;
*(vuip)MCPCIA_W2_BASE(mid) = __direct_map_base | 1;
*(vuip)MCPCIA_W2_MASK(mid) = (__direct_map_size - 1) & 0xfff00000;
@@ -464,18 +468,20 @@ void __init
mcpcia_init_hoses(void)
{
struct pci_controler *hose;
- int h, hose_count = 0;
+ int h;
+
+ mcpcia_hose_count = 0;
/* First, find how many hoses we have. */
for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
if (mcpcia_probe_hose(h)) {
if (h != 0)
mcpcia_new_hose(h);
- hose_count++;
+ mcpcia_hose_count++;
}
}
- printk("mcpcia_init_hoses: found %d hoses\n", hose_count);
+ printk("mcpcia_init_hoses: found %d hoses\n", mcpcia_hose_count);
/* Now do init for each hose. */
for (hose = hose_head; hose; hose = hose->next)
@@ -554,6 +560,65 @@ mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
frame->ld_lock);
}
+static void
+mcpcia_print_system_area(unsigned long la_ptr)
+{
+ struct el_common *frame;
+ int i;
+
+ struct IOD_subpacket {
+ unsigned long base;
+ unsigned int whoami;
+ unsigned int rsvd1;
+ unsigned int pci_rev;
+ unsigned int cap_ctrl;
+ unsigned int hae_mem;
+ unsigned int hae_io;
+ unsigned int int_ctl;
+ unsigned int int_reg;
+ unsigned int int_mask0;
+ unsigned int int_mask1;
+ unsigned int mc_err0;
+ unsigned int mc_err1;
+ unsigned int cap_err;
+ unsigned int rsvd2;
+ unsigned int pci_err1;
+ unsigned int mdpa_stat;
+ unsigned int mdpa_syn;
+ unsigned int mdpb_stat;
+ unsigned int mdpb_syn;
+ unsigned int rsvd3;
+ unsigned int rsvd4;
+ unsigned int rsvd5;
+ } *iodpp;
+
+ frame = (struct el_common *)la_ptr;
+
+ iodpp = (struct IOD_subpacket *) (la_ptr + frame->sys_offset);
+
+ for (i = 0; i < mcpcia_hose_count; i++, iodpp++) {
+ printk("IOD %d Register Subpacket - Bridge Base Address %16lx\n",
+ i, iodpp->base);
+ printk(" WHOAMI = %8x\n", iodpp->whoami);
+ printk(" PCI_REV = %8x\n", iodpp->pci_rev);
+ printk(" CAP_CTRL = %8x\n", iodpp->cap_ctrl);
+ printk(" HAE_MEM = %8x\n", iodpp->hae_mem);
+ printk(" HAE_IO = %8x\n", iodpp->hae_io);
+ printk(" INT_CTL = %8x\n", iodpp->int_ctl);
+ printk(" INT_REG = %8x\n", iodpp->int_reg);
+ printk(" INT_MASK0 = %8x\n", iodpp->int_mask0);
+ printk(" INT_MASK1 = %8x\n", iodpp->int_mask1);
+ printk(" MC_ERR0 = %8x\n", iodpp->mc_err0);
+ printk(" MC_ERR1 = %8x\n", iodpp->mc_err1);
+ printk(" CAP_ERR = %8x\n", iodpp->cap_err);
+ printk(" PCI_ERR1 = %8x\n", iodpp->pci_err1);
+ printk(" MDPA_STAT = %8x\n", iodpp->mdpa_stat);
+ printk(" MDPA_SYN = %8x\n", iodpp->mdpa_syn);
+ printk(" MDPB_STAT = %8x\n", iodpp->mdpb_stat);
+ printk(" MDPB_SYN = %8x\n", iodpp->mdpb_syn);
+ }
+}
+
void
mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
@@ -594,6 +659,8 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
mb();
process_mcheck_info(vector, la_ptr, regs, "MCPCIA", expected != 0);
- if (!expected && vector != 0x620 && vector != 0x630)
+ if (!expected && vector != 0x620 && vector != 0x630) {
mcpcia_print_uncorrectable(mchk_logout);
+ mcpcia_print_system_area(la_ptr);
+ }
}
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
new file mode 100644
index 00000000000000..37dd8b3c382cd8
--- /dev/null
+++ b/arch/alpha/kernel/core_titan.c
@@ -0,0 +1,487 @@
+/*
+ * linux/arch/alpha/kernel/core_titan.c
+ *
+ * Code common to all TITAN core logic chips.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/smp.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_titan.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+#include "pci_impl.h"
+
+int TITAN_bootcpu;
+unsigned TITAN_agp = 0;
+
+static struct
+{
+ unsigned long wsba[4];
+ unsigned long wsm[4];
+ unsigned long tba[4];
+} saved_pachip_port[4];
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#define DEBUG_MCHECK 0 /* 0 = minimum, 1 = debug, 2 = dump+dump */
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBG_CFG(args) printk args
+#else
+# define DBG_CFG(args)
+#endif
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address
+ * accordingly. It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Note that all config space accesses use Type 1 address format.
+ *
+ * Note also that type 1 is determined by non-zero bus number.
+ *
+ * Type 1:
+ *
+ * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
+ * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 31:24 reserved
+ * 23:16 bus number (8 bits = 128 possible buses)
+ * 15:11 Device number (5 bits)
+ * 10:8 function number
+ * 7:2 register number
+ *
+ * Notes:
+ * The function number selects which function of a multi-function device
+ * (e.g., SCSI and Ethernet).
+ *
+ * The register selects a DWORD (32 bit) register offset. Hence it
+ * doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ * bits.
+ */
+
+static int
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
+ unsigned char *type1)
+{
+ struct pci_controler *hose = dev->sysdata;
+ unsigned long addr;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
+
+ DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
+ "pci_addr=0x%p, type1=0x%p)\n",
+ bus, device_fn, where, pci_addr, type1));
+
+ if (hose->first_busno == dev->bus->number)
+ bus = 0;
+ *type1 = (bus != 0);
+
+ addr = (bus << 16) | (device_fn << 8) | where;
+ addr |= hose->config_space_base;
+
+ *pci_addr = addr;
+ DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+ return 0;
+}
+
+static int
+titan_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+titan_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+titan_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+titan_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+titan_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+titan_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops titan_pci_ops =
+{
+ read_byte: titan_read_config_byte,
+ read_word: titan_read_config_word,
+ read_dword: titan_read_config_dword,
+ write_byte: titan_write_config_byte,
+ write_word: titan_write_config_word,
+ write_dword: titan_write_config_dword
+};
+
+
+void
+titan_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+{
+ titan_pachip *pachip =
+ (hose->index & 1) ? TITAN_pachip1 : TITAN_pachip0;
+ titan_pachip_port *port;
+ volatile unsigned long *csr;
+ unsigned long value;
+
+ /* Get the right hose */
+ port = &pachip->g_port;
+ if (hose->index & 2)
+ port = &pachip->a_port;
+
+ /* We can invalidate up to 8 tlb entries in a go. The flush
+ matches against <31:16> in the pci address. */
+ csr = &port->port_specific.g.gtlbia.csr;
+ if (((start ^ end) & 0xffff0000) == 0)
+ csr = &port->port_specific.g.gtlbiv.csr;
+
+ /* For TBIA, it doesn't matter what value we write. For TBI,
+ it's the shifted tag bits. */
+ value = (start & 0xffff0000) >> 12;
+
+ wmb();
+ *csr = value;
+ mb();
+ *csr;
+}
+
+#define FN __FUNCTION__
+
+static int __init
+titan_query_agp(titan_pachip_port *port)
+{
+ union TPAchipPCTL pctl;
+
+ /* set up APCTL */
+ pctl.pctl_q_whole = port->pctl.csr;
+
+ return pctl.pctl_r_bits.apctl_v_agp_present;
+
+}
+static void __init
+titan_init_agp(titan_pachip_port *port, struct pci_controler *hose)
+{
+ union TPAchipPCTL pctl;
+
+ if (!titan_query_agp(port))
+ return;
+
+ printk("AGP present on hose %d\n", hose->index);
+
+ /* get APCTL */
+ pctl.pctl_q_whole = port->pctl.csr;
+
+
+ pctl.pctl_r_bits.apctl_v_agp_en = 1; /* enable AGP */
+ pctl.pctl_r_bits.apctl_v_agp_lp_rd = 0;
+ pctl.pctl_r_bits.apctl_v_agp_hp_rd = 0;
+
+ port->pctl.csr = pctl.pctl_q_whole;
+
+ TITAN_agp |= 1 << hose->index;
+
+#ifdef CONFIG_VGA_HOSE
+ /* is a graphics card on the AGP? (always device 5) */
+ if (hose != NULL &&
+ __kernel_ldwu(*(vusp)(hose->config_space_base + 0x280a)) ==
+ PCI_CLASS_DISPLAY_VGA)
+ set_vga_hose(hose);
+#endif
+}
+
+static void __init
+titan_init_one_pachip_port(titan_pachip_port *port, int index)
+{
+ struct pci_controler *hose;
+
+ hose = alloc_pci_controler();
+ if (index == 0)
+ pci_isa_hose = hose;
+ hose->io_space = alloc_resource();
+ hose->mem_space = alloc_resource();
+
+ hose->config_space_base = TITAN_CONF(index);
+ hose->index = index;
+
+ hose->io_space->start = TITAN_IO(index) - TITAN_IO_BIAS;
+ hose->io_space->end = hose->io_space->start + TITAN_IO_SPACE - 1;
+ hose->io_space->name = pci_io_names[index];
+ hose->io_space->flags = IORESOURCE_IO;
+
+ hose->mem_space->start = TITAN_MEM(index) - TITAN_MEM_BIAS;
+ hose->mem_space->end = hose->mem_space->start + 0xffffffff;
+ hose->mem_space->name = pci_mem_names[index];
+ hose->mem_space->flags = IORESOURCE_MEM;
+
+ if (request_resource(&ioport_resource, hose->io_space) < 0)
+ printk(KERN_ERR "Failed to request IO on hose %d\n", index);
+ if (request_resource(&iomem_resource, hose->mem_space) < 0)
+ printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
+
+ /* It's safe to call this for both G-Ports and A-Ports */
+ titan_init_agp(port, hose);
+
+ /*
+ * Save the existing PCI window translations. SRM will
+ * need them when we go to reboot.
+ */
+ saved_pachip_port[index].wsba[0] = port->wsba[0].csr;
+ saved_pachip_port[index].wsm[0] = port->wsm[0].csr;
+ saved_pachip_port[index].tba[0] = port->tba[0].csr;
+
+ saved_pachip_port[index].wsba[1] = port->wsba[1].csr;
+ saved_pachip_port[index].wsm[1] = port->wsm[1].csr;
+ saved_pachip_port[index].tba[1] = port->tba[1].csr;
+
+ saved_pachip_port[index].wsba[2] = port->wsba[2].csr;
+ saved_pachip_port[index].wsm[2] = port->wsm[2].csr;
+ saved_pachip_port[index].tba[2] = port->tba[2].csr;
+
+ saved_pachip_port[index].wsba[3] = port->wsba[3].csr;
+ saved_pachip_port[index].wsm[3] = port->wsm[3].csr;
+ saved_pachip_port[index].tba[3] = port->tba[3].csr;
+
+ /*
+ * Set up the PCI to main memory translation windows.
+ *
+ * Note: Window 3 on Titan is Scatter-Gather ONLY
+ *
+ * Window 0 is scatter-gather 8MB at 8MB (for isa)
+ * Window 1 is direct access 1GB at 1GB
+ * Window 2 is direct access 1GB at 2GB
+ * Window 3 is scatter-gather 128MB at 3GB
+ * ??? We ought to scale window 3 memory.
+ *
+ * We must actually use 2 windows to direct-map the 2GB space,
+ * because of an idiot-syncrasy of the CYPRESS chip. It may
+ * respond to a PCI bus address in the last 1MB of the 4GB
+ * address range.
+ */
+ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+ hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0);
+ __direct_map_base = 0x40000000;
+ __direct_map_size = 0x80000000;
+
+ port->wsba[0].csr = hose->sg_isa->dma_base | 3;
+ port->wsm[0].csr = (hose->sg_isa->size - 1) & 0xfff00000;
+ port->tba[0].csr = virt_to_phys(hose->sg_isa->ptes);
+
+ port->wsba[1].csr = 0x40000000 | 1;
+ port->wsm[1].csr = (0x40000000 - 1) & 0xfff00000;
+ port->tba[1].csr = 0;
+
+ port->wsba[2].csr = 0x80000000 | 1;
+ port->wsm[2].csr = (0x40000000 - 1) & 0xfff00000;
+ port->tba[2].csr = 0x40000000;
+
+ port->wsba[3].csr = hose->sg_pci->dma_base | 3;
+ port->wsm[3].csr = (hose->sg_pci->size - 1) & 0xfff00000;
+ port->tba[3].csr = virt_to_phys(hose->sg_pci->ptes);
+
+ titan_pci_tbi(hose, 0, -1);
+}
+
+static void __init
+titan_init_pachips(titan_pachip *pachip0, titan_pachip *pachip1)
+{
+ int pchip1_present = TITAN_cchip->csc.csr & 1L<<14;
+
+ /* Init the ports in hose order... */
+ titan_init_one_pachip_port(&pachip0->g_port, 0); /* hose 0 */
+ if (pchip1_present)
+ titan_init_one_pachip_port(&pachip1->g_port, 1);/* hose 1 */
+ titan_init_one_pachip_port(&pachip0->a_port, 2); /* hose 2 */
+ if (pchip1_present)
+ titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */
+}
+
+void __init
+titan_init_arch(void)
+{
+#if 0
+ printk("%s: titan_init_arch()\n", FN);
+ printk("%s: CChip registers:\n", FN);
+ printk("%s: CSR_CSC 0x%lx\n", FN, TITAN_cchip->csc.csr);
+ printk("%s: CSR_MTR 0x%lx\n", FN, TITAN_cchip->mtr.csr);
+ printk("%s: CSR_MISC 0x%lx\n", FN, TITAN_cchip->misc.csr);
+ printk("%s: CSR_DIM0 0x%lx\n", FN, TITAN_cchip->dim0.csr);
+ printk("%s: CSR_DIM1 0x%lx\n", FN, TITAN_cchip->dim1.csr);
+ printk("%s: CSR_DIR0 0x%lx\n", FN, TITAN_cchip->dir0.csr);
+ printk("%s: CSR_DIR1 0x%lx\n", FN, TITAN_cchip->dir1.csr);
+ printk("%s: CSR_DRIR 0x%lx\n", FN, TITAN_cchip->drir.csr);
+
+ printk("%s: DChip registers:\n", FN);
+ printk("%s: CSR_DSC 0x%lx\n", FN, TITAN_dchip->dsc.csr);
+ printk("%s: CSR_STR 0x%lx\n", FN, TITAN_dchip->str.csr);
+ printk("%s: CSR_DREV 0x%lx\n", FN, TITAN_dchip->drev.csr);
+#endif
+
+ TITAN_bootcpu = __hard_smp_processor_id();
+
+ /* With multiple PCI busses, we play with I/O as physical addrs. */
+ ioport_resource.end = ~0UL;
+ iomem_resource.end = ~0UL;
+
+ /* Init the PA chip(s) */
+ titan_init_pachips(TITAN_pachip0, TITAN_pachip1);
+}
+
+static void
+titan_kill_one_pachip_port(titan_pachip_port *port, int index)
+{
+ port->wsba[0].csr = saved_pachip_port[index].wsba[0];
+ port->wsm[0].csr = saved_pachip_port[index].wsm[0];
+ port->tba[0].csr = saved_pachip_port[index].tba[0];
+
+ port->wsba[1].csr = saved_pachip_port[index].wsba[1];
+ port->wsm[1].csr = saved_pachip_port[index].wsm[1];
+ port->tba[1].csr = saved_pachip_port[index].tba[1];
+
+ port->wsba[2].csr = saved_pachip_port[index].wsba[2];
+ port->wsm[2].csr = saved_pachip_port[index].wsm[2];
+ port->tba[2].csr = saved_pachip_port[index].tba[2];
+
+ port->wsba[3].csr = saved_pachip_port[index].wsba[3];
+ port->wsm[3].csr = saved_pachip_port[index].wsm[3];
+ port->tba[3].csr = saved_pachip_port[index].tba[3];
+}
+
+static void
+titan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1)
+{
+ int pchip1_present = TITAN_cchip->csc.csr & 1L<<14;
+
+ if (pchip1_present) {
+ titan_kill_one_pachip_port(&pachip0->g_port, 1);
+ titan_kill_one_pachip_port(&pachip0->a_port, 3);
+ }
+ titan_kill_one_pachip_port(&pachip0->g_port, 0);
+ titan_kill_one_pachip_port(&pachip0->a_port, 2);
+}
+
+void
+titan_kill_arch(int mode)
+{
+ titan_kill_pachips(TITAN_pachip0, TITAN_pachip1);
+}
+
+static inline void
+titan_pci_clr_err_1(titan_pachip *pachip)
+{
+ unsigned int jd;
+
+ jd = pachip->g_port.port_specific.g.gperror.csr;
+ pachip->g_port.port_specific.g.gperror.csr = jd;
+ mb();
+ pachip->g_port.port_specific.g.gperror.csr;
+}
+
+static inline void
+titan_pci_clr_err(void)
+{
+ titan_pci_clr_err_1(TITAN_pachip0);
+
+ if (TITAN_cchip->csc.csr & 1L<<14)
+ titan_pci_clr_err_1(TITAN_pachip1);
+}
+
+void
+titan_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs * regs)
+{
+ /* clear error before any reporting. */
+ mb();
+ draina();
+ titan_pci_clr_err();
+ wrmces(0x7);
+ mb();
+
+ process_mcheck_info(vector, la_ptr, regs, "TITAN",
+ mcheck_expected(smp_processor_id()));
+}
+
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
index 5e3943fec80a82..45ff9bb12bba05 100644
--- a/arch/alpha/kernel/core_tsunami.c
+++ b/arch/alpha/kernel/core_tsunami.c
@@ -344,11 +344,13 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
/*
* Set up the PCI to main memory translation windows.
*
+ * Note: Window 3 is scatter-gather only
+ *
* Window 0 is scatter-gather 8MB at 8MB (for isa)
- * Window 1 is scatter-gather 128MB at 3GB
- * Window 2 is direct access 1GB at 1GB
- * Window 3 is direct access 1GB at 2GB
- * ??? We ought to scale window 1 memory.
+ * Window 1 is direct access 1GB at 1GB
+ * Window 2 is direct access 1GB at 2GB
+ * Window 3 is scatter-gather 128MB at 3GB
+ * ??? We ought to scale window 3 memory.
*
* We must actually use 2 windows to direct-map the 2GB space,
* because of an idiot-syncrasy of the CYPRESS chip. It may
@@ -364,17 +366,17 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
pchip->wsm[0].csr = (hose->sg_isa->size - 1) & 0xfff00000;
pchip->tba[0].csr = virt_to_phys(hose->sg_isa->ptes);
- pchip->wsba[1].csr = hose->sg_pci->dma_base | 3;
- pchip->wsm[1].csr = (hose->sg_pci->size - 1) & 0xfff00000;
- pchip->tba[1].csr = virt_to_phys(hose->sg_pci->ptes);
+ pchip->wsba[1].csr = 0x40000000 | 1;
+ pchip->wsm[1].csr = (0x40000000 - 1) & 0xfff00000;
+ pchip->tba[1].csr = 0;
- pchip->wsba[2].csr = 0x40000000 | 1;
+ pchip->wsba[2].csr = 0x80000000 | 1;
pchip->wsm[2].csr = (0x40000000 - 1) & 0xfff00000;
- pchip->tba[2].csr = 0;
+ pchip->tba[2].csr = 0x40000000;
- pchip->wsba[3].csr = 0x80000000 | 1;
- pchip->wsm[3].csr = (0x40000000 - 1) & 0xfff00000;
- pchip->tba[3].csr = 0x40000000;
+ pchip->wsba[3].csr = hose->sg_pci->dma_base | 3;
+ pchip->wsm[3].csr = (hose->sg_pci->size - 1) & 0xfff00000;
+ pchip->tba[3].csr = virt_to_phys(hose->sg_pci->ptes);
tsunami_pci_tbi(hose, 0, -1);
}
diff --git a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c
new file mode 100644
index 00000000000000..9b4f28c109870c
--- /dev/null
+++ b/arch/alpha/kernel/core_wildfire.c
@@ -0,0 +1,668 @@
+/*
+ * linux/arch/alpha/kernel/core_wildfire.c
+ *
+ * Wildfire support.
+ *
+ * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/smp.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_wildfire.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+#include "pci_impl.h"
+
+#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */
+#define DEBUG_CONFIG 0
+#define DEBUG_DUMP_REGS 0
+#define DEBUG_DUMP_CONFIG 1
+
+#if DEBUG_CONFIG
+# define DBG_CFG(args) printk args
+#else
+# define DBG_CFG(args)
+#endif
+
+#if DEBUG_DUMP_REGS
+static void wildfire_dump_pci_regs(int qbbno, int hoseno);
+static void wildfire_dump_pca_regs(int qbbno, int pcano);
+static void wildfire_dump_qsa_regs(int qbbno);
+static void wildfire_dump_qsd_regs(int qbbno);
+static void wildfire_dump_iop_regs(int qbbno);
+static void wildfire_dump_gp_regs(int qbbno);
+#endif
+#if DEBUG_DUMP_CONFIG
+static void wildfire_dump_hardware_config(void);
+#endif
+
+unsigned char wildfire_hard_qbb_map[WILDFIRE_MAX_QBB];
+unsigned char wildfire_soft_qbb_map[WILDFIRE_MAX_QBB];
+#define QBB_MAP_EMPTY 0xff
+
+unsigned long wildfire_hard_qbb_mask;
+unsigned long wildfire_soft_qbb_mask;
+unsigned long wildfire_gp_mask;
+unsigned long wildfire_hs_mask;
+unsigned long wildfire_iop_mask;
+unsigned long wildfire_ior_mask;
+unsigned long wildfire_pca_mask;
+unsigned long wildfire_cpu_mask;
+unsigned long wildfire_mem_mask;
+
+void __init
+wildfire_init_hose(int qbbno, int hoseno)
+{
+ struct pci_controler *hose;
+ wildfire_pci *pci;
+
+ hose = alloc_pci_controler();
+ hose->io_space = alloc_resource();
+ hose->mem_space = alloc_resource();
+
+ /* This is for userland consumption. */
+ hose->sparse_mem_base = 0;
+ hose->sparse_io_base = 0;
+ hose->dense_mem_base = WILDFIRE_MEM(qbbno, hoseno);
+ hose->dense_io_base = WILDFIRE_IO(qbbno, hoseno);
+
+ hose->config_space_base = WILDFIRE_CONF(qbbno, hoseno);
+ hose->index = (qbbno << 3) + hoseno;
+
+ hose->io_space->start = WILDFIRE_IO(qbbno, hoseno) - WILDFIRE_IO_BIAS;
+ hose->io_space->end = hose->io_space->start + WILDFIRE_IO_SPACE - 1;
+ hose->io_space->name = pci_io_names[hoseno];
+ hose->io_space->flags = IORESOURCE_IO;
+
+ hose->mem_space->start = WILDFIRE_MEM(qbbno, hoseno)-WILDFIRE_MEM_BIAS;
+ hose->mem_space->end = hose->mem_space->start + 0xffffffff;
+ hose->mem_space->name = pci_mem_names[hoseno];
+ hose->mem_space->flags = IORESOURCE_MEM;
+
+ if (request_resource(&ioport_resource, hose->io_space) < 0)
+ printk(KERN_ERR "Failed to request IO on qbb %d hose %d\n",
+ qbbno, hoseno);
+ if (request_resource(&iomem_resource, hose->mem_space) < 0)
+ printk(KERN_ERR "Failed to request MEM on qbb %d hose %d\n",
+ qbbno, hoseno);
+
+#if DEBUG_DUMP_REGS
+ wildfire_dump_pci_regs(qbbno, hoseno);
+#endif
+
+ /*
+ * Set up the PCI to main memory translation windows.
+ *
+ * Note: Window 3 is scatter-gather only
+ *
+ * Window 0 is scatter-gather 8MB at 8MB (for isa)
+ * Window 1 is direct access 1GB at 1GB
+ * Window 2 is direct access 1GB at 2GB
+ * Window 3 is scatter-gather 128MB at 3GB
+ * ??? We ought to scale window 3 memory.
+ *
+ */
+ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+ hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0);
+
+ pci = WILDFIRE_pci(qbbno, hoseno);
+
+ pci->pci_window[0].wbase.csr = hose->sg_isa->dma_base | 3;
+ pci->pci_window[0].wmask.csr = (hose->sg_isa->size - 1) & 0xfff00000;
+ pci->pci_window[0].tbase.csr = virt_to_phys(hose->sg_isa->ptes);
+
+ pci->pci_window[1].wbase.csr = 0x40000000 | 1;
+ pci->pci_window[1].wmask.csr = (0x40000000 -1) & 0xfff00000;
+ pci->pci_window[1].tbase.csr = 0;
+
+ pci->pci_window[2].wbase.csr = 0x80000000 | 1;
+ pci->pci_window[2].wmask.csr = (0x40000000 -1) & 0xfff00000;
+ pci->pci_window[2].tbase.csr = 0x40000000;
+
+ pci->pci_window[3].wbase.csr = hose->sg_pci->dma_base | 3;
+ pci->pci_window[3].wmask.csr = (hose->sg_pci->size - 1) & 0xfff00000;
+ pci->pci_window[3].tbase.csr = virt_to_phys(hose->sg_pci->ptes);
+
+ wildfire_pci_tbi(hose, 0, 0); /* Flush TLB at the end. */
+}
+
+void __init
+wildfire_init_pca(int qbbno, int pcano)
+{
+
+ /* Test for PCA existence first. */
+ if (!WILDFIRE_PCA_EXISTS(qbbno, pcano))
+ return;
+
+#if DEBUG_DUMP_REGS
+ wildfire_dump_pca_regs(qbbno, pcano);
+#endif
+
+ /* Do both hoses of the PCA. */
+ wildfire_init_hose(qbbno, (pcano << 1) + 0);
+ wildfire_init_hose(qbbno, (pcano << 1) + 1);
+}
+
+void __init
+wildfire_init_qbb(int qbbno)
+{
+ int pcano;
+
+ /* Test for QBB existence first. */
+ if (!WILDFIRE_QBB_EXISTS(qbbno))
+ return;
+
+#if DEBUG_DUMP_REGS
+ wildfire_dump_qsa_regs(qbbno);
+ wildfire_dump_qsd_regs(qbbno);
+ wildfire_dump_iop_regs(qbbno);
+ wildfire_dump_gp_regs(qbbno);
+#endif
+
+ /* Init all PCAs here. */
+ for (pcano = 0; pcano < WILDFIRE_PCA_PER_QBB; pcano++) {
+ wildfire_init_pca(qbbno, pcano);
+ }
+}
+
+void __init
+wildfire_hardware_probe(void)
+{
+ unsigned long temp;
+ unsigned int hard_qbb, soft_qbb;
+ wildfire_fast_qsd *fast = WILDFIRE_fast_qsd();
+ wildfire_qsd *qsd;
+ wildfire_qsa *qsa;
+ wildfire_iop *iop;
+ wildfire_gp *gp;
+ wildfire_ne *ne;
+ wildfire_fe *fe;
+ int i;
+
+ temp = fast->qsd_whami.csr;
+#if 0
+ printk(KERN_ERR "fast QSD_WHAMI at base %p is 0x%lx\n", fast, temp);
+#endif
+
+ hard_qbb = (temp >> 8) & 7;
+ soft_qbb = (temp >> 4) & 7;
+
+ /* Init the HW configuration variables. */
+ wildfire_hard_qbb_mask = (1 << hard_qbb);
+ wildfire_soft_qbb_mask = (1 << soft_qbb);
+
+ wildfire_gp_mask = 0;
+ wildfire_hs_mask = 0;
+ wildfire_iop_mask = 0;
+ wildfire_ior_mask = 0;
+ wildfire_pca_mask = 0;
+
+ wildfire_cpu_mask = 0;
+ wildfire_mem_mask = 0;
+
+ memset(wildfire_hard_qbb_map, QBB_MAP_EMPTY, WILDFIRE_MAX_QBB);
+ memset(wildfire_soft_qbb_map, QBB_MAP_EMPTY, WILDFIRE_MAX_QBB);
+
+ /* First, determine which QBBs are present. */
+ qsa = WILDFIRE_qsa(soft_qbb);
+
+ temp = qsa->qsa_qbb_id.csr;
+#if 0
+ printk(KERN_ERR "QSA_QBB_ID at base %p is 0x%lx\n", qsa, temp);
+#endif
+
+ if (temp & 0x40) /* Is there an HS? */
+ wildfire_hs_mask = 1;
+
+ if (temp & 0x20) { /* Is there a GP? */
+ gp = WILDFIRE_gp(soft_qbb);
+ temp = 0;
+ for (i = 0; i < 4; i++) {
+ temp |= gp->gpa_qbb_map[i].csr << (i * 8);
+#if 0
+ printk(KERN_ERR "GPA_QBB_MAP[%d] at base %p is 0x%lx\n",
+ i, gp, temp);
+#endif
+ }
+
+ for (hard_qbb = 0; hard_qbb < WILDFIRE_MAX_QBB; hard_qbb++) {
+ if (temp & 8) { /* Is there a QBB? */
+ soft_qbb = temp & 7;
+ wildfire_hard_qbb_mask |= (1 << hard_qbb);
+ wildfire_soft_qbb_mask |= (1 << soft_qbb);
+ }
+ temp >>= 4;
+ }
+ wildfire_gp_mask = wildfire_soft_qbb_mask;
+ }
+
+ /* Next determine each QBBs resources. */
+ for (soft_qbb = 0; soft_qbb < WILDFIRE_MAX_QBB; soft_qbb++) {
+ if (WILDFIRE_QBB_EXISTS(soft_qbb)) {
+ qsd = WILDFIRE_qsd(soft_qbb);
+ temp = qsd->qsd_whami.csr;
+#if 0
+ printk(KERN_ERR "QSD_WHAMI at base %p is 0x%lx\n", qsd, temp);
+#endif
+ hard_qbb = (temp >> 8) & 7;
+ wildfire_hard_qbb_map[hard_qbb] = soft_qbb;
+ wildfire_soft_qbb_map[soft_qbb] = hard_qbb;
+
+ qsa = WILDFIRE_qsa(soft_qbb);
+ temp = qsa->qsa_qbb_pop[0].csr;
+#if 0
+ printk(KERN_ERR "QSA_QBB_POP_0 at base %p is 0x%lx\n", qsa, temp);
+#endif
+ wildfire_cpu_mask |= ((temp >> 0) & 0xf) << (soft_qbb << 2);
+ wildfire_mem_mask |= ((temp >> 4) & 0xf) << (soft_qbb << 2);
+
+ temp = qsa->qsa_qbb_pop[1].csr;
+#if 0
+ printk(KERN_ERR "QSA_QBB_POP_1 at base %p is 0x%lx\n", qsa, temp);
+#endif
+ wildfire_iop_mask |= (1 << soft_qbb);
+ wildfire_ior_mask |= ((temp >> 4) & 0xf) << (soft_qbb << 2);
+
+ temp = qsa->qsa_qbb_id.csr;
+#if 0
+ printk(KERN_ERR "QSA_QBB_ID at %p is 0x%lx\n", qsa, temp);
+#endif
+ if (temp & 0x20)
+ wildfire_gp_mask |= (1 << soft_qbb);
+
+ /* Probe for PCA existence here. */
+ for (i = 0; i < WILDFIRE_PCA_PER_QBB; i++) {
+ iop = WILDFIRE_iop(soft_qbb);
+ ne = WILDFIRE_ne(soft_qbb, i);
+ fe = WILDFIRE_fe(soft_qbb, i);
+
+ if ((iop->iop_hose[i].init.csr & 1) == 1 &&
+ ((ne->ne_what_am_i.csr & 0xf00000300) == 0x100000300) &&
+ ((fe->fe_what_am_i.csr & 0xf00000300) == 0x100000200))
+ {
+ wildfire_pca_mask |= 1 << ((soft_qbb << 2) + i);
+ }
+ }
+
+ }
+ }
+#if DEBUG_DUMP_CONFIG
+ wildfire_dump_hardware_config();
+#endif
+}
+
+void __init
+wildfire_init_arch(void)
+{
+ int qbbno;
+
+ /* With multiple PCI buses, we play with I/O as physical addrs. */
+ ioport_resource.end = ~0UL;
+ iomem_resource.end = ~0UL;
+
+
+ /* Probe the hardware for info about configuration. */
+ wildfire_hardware_probe();
+
+ /* Now init all the found QBBs. */
+ for (qbbno = 0; qbbno < WILDFIRE_MAX_QBB; qbbno++) {
+ wildfire_init_qbb(qbbno);
+ }
+
+ /* Normal direct PCI DMA mapping. */
+ __direct_map_base = 0x40000000UL;
+ __direct_map_size = 0x80000000UL;
+}
+
+void
+wildfire_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs * regs)
+{
+ mb();
+ mb(); /* magic */
+ draina();
+ /* FIXME: clear pci errors */
+ wrmces(0x7);
+ mb();
+
+ process_mcheck_info(vector, la_ptr, regs, "WILDFIRE",
+ mcheck_expected(smp_processor_id()));
+}
+
+void
+wildfire_kill_arch(int mode)
+{
+}
+
+void
+wildfire_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+{
+ int qbbno = hose->index >> 3;
+ int hoseno = hose->index & 7;
+ wildfire_pci *pci = WILDFIRE_pci(qbbno, hoseno);
+
+ mb();
+ pci->pci_flush_tlb.csr; /* reading does the trick */
+}
+
+static int
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
+ unsigned char *type1)
+{
+ struct pci_controler *hose = dev->sysdata;
+ unsigned long addr;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
+
+ DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
+ "pci_addr=0x%p, type1=0x%p)\n",
+ bus, device_fn, where, pci_addr, type1));
+
+ if (hose->first_busno == dev->bus->number)
+ bus = 0;
+ *type1 = (bus != 0);
+
+ addr = (bus << 16) | (device_fn << 8) | where;
+ addr |= hose->config_space_base;
+
+ *pci_addr = addr;
+ DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+ return 0;
+}
+
+static int
+wildfire_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+wildfire_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+wildfire_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+wildfire_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+wildfire_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+wildfire_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops wildfire_pci_ops =
+{
+ read_byte: wildfire_read_config_byte,
+ read_word: wildfire_read_config_word,
+ read_dword: wildfire_read_config_dword,
+ write_byte: wildfire_write_config_byte,
+ write_word: wildfire_write_config_word,
+ write_dword: wildfire_write_config_dword
+};
+
+#if DEBUG_DUMP_REGS
+
+static void __init
+wildfire_dump_pci_regs(int qbbno, int hoseno)
+{
+ wildfire_pci *pci = WILDFIRE_pci(qbbno, hoseno);
+ int i;
+
+ printk(KERN_ERR "PCI registers for QBB %d hose %d (%p)\n",
+ qbbno, hoseno, pci);
+
+ printk(KERN_ERR " PCI_IO_ADDR_EXT: 0x%16lx\n",
+ pci->pci_io_addr_ext.csr);
+ printk(KERN_ERR " PCI_CTRL: 0x%16lx\n", pci->pci_ctrl.csr);
+ printk(KERN_ERR " PCI_ERR_SUM: 0x%16lx\n", pci->pci_err_sum.csr);
+ printk(KERN_ERR " PCI_ERR_ADDR: 0x%16lx\n", pci->pci_err_addr.csr);
+ printk(KERN_ERR " PCI_STALL_CNT: 0x%16lx\n", pci->pci_stall_cnt.csr);
+ printk(KERN_ERR " PCI_PEND_INT: 0x%16lx\n", pci->pci_pend_int.csr);
+ printk(KERN_ERR " PCI_SENT_INT: 0x%16lx\n", pci->pci_sent_int.csr);
+
+ printk(KERN_ERR " DMA window registers for QBB %d hose %d (%p)\n",
+ qbbno, hoseno, pci);
+ for (i = 0; i < 4; i++) {
+ printk(KERN_ERR " window %d: 0x%16lx 0x%16lx 0x%16lx\n", i,
+ pci->pci_window[i].wbase.csr,
+ pci->pci_window[i].wmask.csr,
+ pci->pci_window[i].tbase.csr);
+ }
+ printk(KERN_ERR "\n");
+}
+
+static void __init
+wildfire_dump_pca_regs(int qbbno, int pcano)
+{
+ wildfire_pca *pca = WILDFIRE_pca(qbbno, pcano);
+ int i;
+
+ printk(KERN_ERR "PCA registers for QBB %d PCA %d (%p)\n",
+ qbbno, pcano, pca);
+
+ printk(KERN_ERR " PCA_WHAT_AM_I: 0x%16lx\n", pca->pca_what_am_i.csr);
+ printk(KERN_ERR " PCA_ERR_SUM: 0x%16lx\n", pca->pca_err_sum.csr);
+ printk(KERN_ERR " PCA_PEND_INT: 0x%16lx\n", pca->pca_pend_int.csr);
+ printk(KERN_ERR " PCA_SENT_INT: 0x%16lx\n", pca->pca_sent_int.csr);
+ printk(KERN_ERR " PCA_STDIO_EL: 0x%16lx\n",
+ pca->pca_stdio_edge_level.csr);
+
+ printk(KERN_ERR " PCA target registers for QBB %d PCA %d (%p)\n",
+ qbbno, pcano, pca);
+ for (i = 0; i < 4; i++) {
+ printk(KERN_ERR " target %d: 0x%16lx 0x%16lx\n", i,
+ pca->pca_int[i].target.csr,
+ pca->pca_int[i].enable.csr);
+ }
+
+ printk(KERN_ERR "\n");
+}
+
+static void __init
+wildfire_dump_qsa_regs(int qbbno)
+{
+ wildfire_qsa *qsa = WILDFIRE_qsa(qbbno);
+ int i;
+
+ printk(KERN_ERR "QSA registers for QBB %d (%p)\n", qbbno, qsa);
+
+ printk(KERN_ERR " QSA_QBB_ID: 0x%16lx\n", qsa->qsa_qbb_id.csr);
+ printk(KERN_ERR " QSA_PORT_ENA: 0x%16lx\n", qsa->qsa_port_ena.csr);
+ printk(KERN_ERR " QSA_REF_INT: 0x%16lx\n", qsa->qsa_ref_int.csr);
+
+ for (i = 0; i < 5; i++)
+ printk(KERN_ERR " QSA_CONFIG_%d: 0x%16lx\n",
+ i, qsa->qsa_config[i].csr);
+
+ for (i = 0; i < 2; i++)
+ printk(KERN_ERR " QSA_QBB_POP_%d: 0x%16lx\n",
+ i, qsa->qsa_qbb_pop[0].csr);
+
+ printk(KERN_ERR "\n");
+}
+
+static void __init
+wildfire_dump_qsd_regs(int qbbno)
+{
+ wildfire_qsd *qsd = WILDFIRE_qsd(qbbno);
+
+ printk(KERN_ERR "QSD registers for QBB %d (%p)\n", qbbno, qsd);
+
+ printk(KERN_ERR " QSD_WHAMI: 0x%16lx\n", qsd->qsd_whami.csr);
+ printk(KERN_ERR " QSD_REV: 0x%16lx\n", qsd->qsd_rev.csr);
+ printk(KERN_ERR " QSD_PORT_PRESENT: 0x%16lx\n",
+ qsd->qsd_port_present.csr);
+ printk(KERN_ERR " QSD_PORT_ACTUVE: 0x%16lx\n",
+ qsd->qsd_port_active.csr);
+ printk(KERN_ERR " QSD_FAULT_ENA: 0x%16lx\n",
+ qsd->qsd_fault_ena.csr);
+ printk(KERN_ERR " QSD_CPU_INT_ENA: 0x%16lx\n",
+ qsd->qsd_cpu_int_ena.csr);
+ printk(KERN_ERR " QSD_MEM_CONFIG: 0x%16lx\n",
+ qsd->qsd_mem_config.csr);
+ printk(KERN_ERR " QSD_ERR_SUM: 0x%16lx\n",
+ qsd->qsd_err_sum.csr);
+
+ printk(KERN_ERR "\n");
+}
+
+static void __init
+wildfire_dump_iop_regs(int qbbno)
+{
+ wildfire_iop *iop = WILDFIRE_iop(qbbno);
+ int i;
+
+ printk(KERN_ERR "IOP registers for QBB %d (%p)\n", qbbno, iop);
+
+ printk(KERN_ERR " IOA_CONFIG: 0x%16lx\n", iop->ioa_config.csr);
+ printk(KERN_ERR " IOD_CONFIG: 0x%16lx\n", iop->iod_config.csr);
+ printk(KERN_ERR " IOP_SWITCH_CREDITS: 0x%16lx\n",
+ iop->iop_switch_credits.csr);
+ printk(KERN_ERR " IOP_HOSE_CREDITS: 0x%16lx\n",
+ iop->iop_hose_credits.csr);
+
+ for (i = 0; i < 4; i++)
+ printk(KERN_ERR " IOP_HOSE_%d_INIT: 0x%16lx\n",
+ i, iop->iop_hose[i].init.csr);
+ for (i = 0; i < 4; i++)
+ printk(KERN_ERR " IOP_DEV_INT_TARGET_%d: 0x%16lx\n",
+ i, iop->iop_dev_int[i].target.csr);
+
+ printk(KERN_ERR "\n");
+}
+
+static void __init
+wildfire_dump_gp_regs(int qbbno)
+{
+ wildfire_gp *gp = WILDFIRE_gp(qbbno);
+ int i;
+
+ printk(KERN_ERR "GP registers for QBB %d (%p)\n", qbbno, gp);
+ for (i = 0; i < 4; i++)
+ printk(KERN_ERR " GPA_QBB_MAP_%d: 0x%16lx\n",
+ i, gp->gpa_qbb_map[i].csr);
+
+ printk(KERN_ERR " GPA_MEM_POP_MAP: 0x%16lx\n",
+ gp->gpa_mem_pop_map.csr);
+ printk(KERN_ERR " GPA_SCRATCH: 0x%16lx\n", gp->gpa_scratch.csr);
+ printk(KERN_ERR " GPA_DIAG: 0x%16lx\n", gp->gpa_diag.csr);
+ printk(KERN_ERR " GPA_CONFIG_0: 0x%16lx\n", gp->gpa_config_0.csr);
+ printk(KERN_ERR " GPA_INIT_ID: 0x%16lx\n", gp->gpa_init_id.csr);
+ printk(KERN_ERR " GPA_CONFIG_2: 0x%16lx\n", gp->gpa_config_2.csr);
+
+ printk(KERN_ERR "\n");
+}
+#endif /* DUMP_REGS */
+
+#if DEBUG_DUMP_CONFIG
+static void __init
+wildfire_dump_hardware_config(void)
+{
+ int i;
+
+ printk(KERN_ERR "Probed Hardware Configuration\n");
+
+ printk(KERN_ERR " hard_qbb_mask: 0x%16lx\n", wildfire_hard_qbb_mask);
+ printk(KERN_ERR " soft_qbb_mask: 0x%16lx\n", wildfire_soft_qbb_mask);
+
+ printk(KERN_ERR " gp_mask: 0x%16lx\n", wildfire_gp_mask);
+ printk(KERN_ERR " hs_mask: 0x%16lx\n", wildfire_hs_mask);
+ printk(KERN_ERR " iop_mask: 0x%16lx\n", wildfire_iop_mask);
+ printk(KERN_ERR " ior_mask: 0x%16lx\n", wildfire_ior_mask);
+ printk(KERN_ERR " pca_mask: 0x%16lx\n", wildfire_pca_mask);
+
+ printk(KERN_ERR " cpu_mask: 0x%16lx\n", wildfire_cpu_mask);
+ printk(KERN_ERR " mem_mask: 0x%16lx\n", wildfire_mem_mask);
+
+ printk(" hard_qbb_map: ");
+ for (i = 0; i < WILDFIRE_MAX_QBB; i++)
+ if (wildfire_hard_qbb_map[i] == QBB_MAP_EMPTY)
+ printk("--- ");
+ else
+ printk("%3d ", wildfire_hard_qbb_map[i]);
+ printk("\n");
+
+ printk(" soft_qbb_map: ");
+ for (i = 0; i < WILDFIRE_MAX_QBB; i++)
+ if (wildfire_soft_qbb_map[i] == QBB_MAP_EMPTY)
+ printk("--- ");
+ else
+ printk("%3d ", wildfire_soft_qbb_map[i]);
+ printk("\n");
+}
+#endif /* DUMP_CONFIG */
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 33d5eead18cda2..6f73ff9f965923 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -34,11 +34,12 @@
#define TASK_EXEC_DOMAIN 32
#define TASK_NEED_RESCHED 40
#define TASK_PROCESSOR 100
+#define TASK_PTRACE 104
/*
* task flags (must match include/linux/sched.h):
*/
-#define PF_PTRACED 0x00000010
+#define PT_PTRACED 0x00000001
#define CLONE_VM 0x00000100
@@ -557,10 +558,10 @@ entSys:
lda $5,sys_call_table
lda $27,sys_ni_syscall
cmpult $0,$4,$4
- ldq $3,TASK_FLAGS($8)
+ ldq $3,TASK_PTRACE($8)
stq $17,SP_OFF+32($30)
s8addq $0,$5,$5
- and $3,PF_PTRACED,$3
+ and $3,PT_PTRACED,$3
stq $18,SP_OFF+40($30)
bne $3,strace
beq $4,1f
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index e47fcd3caa7eb7..dc665fbfbdff2b 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -233,14 +233,14 @@ static unsigned long irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
static void
select_smp_affinity(int irq)
{
- static int last_cpu;
+ static int last_cpu = 0;
int cpu = last_cpu + 1;
if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
return;
while (((cpu_present_mask >> cpu) & 1) == 0)
- cpu = (cpu < NR_CPUS ? cpu + 1 : 0);
+ cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
last_cpu = cpu;
irq_affinity[irq] = 1UL << cpu;
@@ -520,8 +520,10 @@ get_irq_list(char *buf)
p += sprintf(p, " ");
for (i = 0; i < smp_num_cpus; i++)
p += sprintf(p, "CPU%d ", i);
+#ifdef DO_BROADCAST_INTS
for (i = 0; i < smp_num_cpus; i++)
p += sprintf(p, "TRY%d ", i);
+#endif
*p++ = '\n';
#endif
@@ -536,10 +538,12 @@ get_irq_list(char *buf)
for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
+#ifdef DO_BROADCAST_INTS
for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "%10lu ",
irq_attempt(cpu_logical_map(j), i));
#endif
+#endif
p += sprintf(p, " %14s", irq_desc[i].handler->typename);
p += sprintf(p, " %c%s",
(action->flags & SA_INTERRUPT)?'+':' ',
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index 774fcf8a65eaaa..ff157040699d4f 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -105,8 +105,18 @@ common_init_isa_dma(void)
void __init
init_IRQ(void)
{
- alpha_mv.init_irq();
+ /* Uh, this really MUST come first, just in case
+ * the platform init_irq() causes interrupts/mchecks
+ * (as is the case with RAWHIDE, at least).
+ */
wrent(entInt, 0);
+
+ alpha_mv.init_irq();
+
+ /* If we had wanted SRM console printk echoing early, undo it now. */
+ if (alpha_using_srm && srmcons_output) {
+ unregister_srm_console();
+ }
}
/*
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
index 79a1c4fb5a8b01..42029b33fb66bc 100644
--- a/arch/alpha/kernel/irq_i8259.c
+++ b/arch/alpha/kernel/irq_i8259.c
@@ -126,6 +126,8 @@ init_i8259a_irqs(void)
# define IACK_SC CIA_IACK_SC
#elif defined(CONFIG_ALPHA_PYXIS)
# define IACK_SC PYXIS_IACK_SC
+#elif defined(CONFIG_ALPHA_TITAN)
+# define IACK_SC TITAN_IACK_SC
#elif defined(CONFIG_ALPHA_TSUNAMI)
# define IACK_SC TSUNAMI_IACK_SC
#elif defined(CONFIG_ALPHA_POLARIS)
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index bc9c0d3de41c6f..454950c1bd11d5 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -9,12 +9,14 @@
#include <linux/config.h>
#include <asm/pgalloc.h>
-/* Whee. IRONGATE, POLARIS and TSUNAMI don't have an HAE. Fix things up for
- the GENERIC kernel by defining the HAE address to be that of the cache.
- Now we can read and write it as we like. ;-) */
+/* Whee. IRONGATE, POLARIS, TSUNAMI, TITAN, and WILDFIRE don't have an HAE.
+ Fix things up for the GENERIC kernel by defining the HAE address
+ to be that of the cache. Now we can read and write it as we like. ;-) */
#define IRONGATE_HAE_ADDRESS (&alpha_mv.hae_cache)
#define POLARIS_HAE_ADDRESS (&alpha_mv.hae_cache)
#define TSUNAMI_HAE_ADDRESS (&alpha_mv.hae_cache)
+#define TITAN_HAE_ADDRESS (&alpha_mv.hae_cache)
+#define WILDFIRE_HAE_ADDRESS (&alpha_mv.hae_cache)
#if CIA_ONE_HAE_WINDOW
#define CIA_HAE_ADDRESS (&alpha_mv.hae_cache)
@@ -28,6 +30,7 @@
seems like such a pain. Define this to get things to compile. */
#define JENSEN_IACK_SC 1
#define T2_IACK_SC 1
+#define WILDFIRE_IACK_SC 1 /* FIXME */
/*
@@ -91,6 +94,8 @@
#define DO_POLARIS_IO IO(POLARIS,polaris)
#define DO_T2_IO IO(T2,t2)
#define DO_TSUNAMI_IO IO(TSUNAMI,tsunami)
+#define DO_TITAN_IO IO(TITAN,titan)
+#define DO_WILDFIRE_IO IO(WILDFIRE,wildfire)
#define DO_PYXIS_IO IO_LITE(CIA,cia_bwx), \
pci_ops: &CAT(cia,_pci_ops)
@@ -107,6 +112,8 @@
#define DO_POLARIS_BUS BUS(polaris)
#define DO_T2_BUS BUS(t2)
#define DO_TSUNAMI_BUS BUS(tsunami)
+#define DO_TITAN_BUS BUS(titan)
+#define DO_WILDFIRE_BUS BUS(wildfire)
/*
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 238b4004f3a659..d55af89c692106 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -230,7 +230,6 @@ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
struct file *file = NULL;
unsigned long ret = -EBADF;
- down(&current->mm->mmap_sem);
lock_kernel();
#if 0
if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
@@ -243,12 +242,13 @@ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
goto out;
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ down(&current->mm->mmap_sem);
ret = do_mmap(file, addr, len, prot, flags, off);
+ up(&current->mm->mmap_sem);
if (file)
fput(file);
out:
unlock_kernel();
- up(&current->mm->mmap_sem);
return ret;
}
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index f9a79c1d6a893e..39de164655ca0d 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -25,11 +25,13 @@
*/
const char *const pci_io_names[] = {
- "PCI IO bus 0", "PCI IO bus 1", "PCI IO bus 2", "PCI IO bus 3"
+ "PCI IO bus 0", "PCI IO bus 1", "PCI IO bus 2", "PCI IO bus 3",
+ "PCI IO bus 4", "PCI IO bus 5", "PCI IO bus 6", "PCI IO bus 7"
};
const char *const pci_mem_names[] = {
- "PCI mem bus 0", "PCI mem bus 1", "PCI mem bus 2", "PCI mem bus 3"
+ "PCI mem bus 0", "PCI mem bus 1", "PCI mem bus 2", "PCI mem bus 3",
+ "PCI mem bus 4", "PCI mem bus 5", "PCI mem bus 6", "PCI mem bus 7"
};
const char pci_hae0_name[] = "HAE0";
@@ -266,6 +268,7 @@ pcibios_fixup_bus(struct pci_bus *bus)
struct pci_controler *hose = (struct pci_controler *) bus->sysdata;
struct list_head *ln;
+ /* ???? */
bus->resource[0] = hose->io_space;
bus->resource[1] = hose->mem_space;
@@ -291,15 +294,14 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root,
u32 reg;
if (resource < PCI_ROM_RESOURCE)
- where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
else if (resource == PCI_ROM_RESOURCE)
where = dev->rom_base_reg;
else {
- /* Don't update non-standard resources here */
- return;
+ return; /* Don't update non-standard resources here. */
}
- /* Point root at the hose root */
+ /* Point root at the hose root. */
if (res->flags & IORESOURCE_IO)
root = hose->io_space;
if (res->flags & IORESOURCE_MEM)
@@ -431,6 +433,11 @@ pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
bridge->resource[0].end = bridge->resource[0].start + inner.io_end;
bridge->resource[1].end = bridge->resource[1].start + inner.mem_end;
+ bridge->resource[PCI_BRIDGE_RESOURCES].end =
+ bridge->resource[PCI_BRIDGE_RESOURCES].start + inner.io_end;
+ bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
+ bridge->resource[PCI_BRIDGE_RESOURCES+1].start + inner.mem_end;
+
/* adjust parent's resource requirements */
if (outer) {
outer->io_end = ROUND_UP(outer->io_end, 4*1024);
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 5a36aa578d770e..cadf69b58cb960 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -97,10 +97,6 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n)
}
if (i < n) {
- /* Reached the end. Flush the TLB and restart the
- search from the beginning. */
- alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
-
p = 0, i = 0;
while (i < n && p+i < nent) {
if (ptes[p+i])
@@ -139,7 +135,7 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n)
p[i] = 0;
}
-/* Map a single buffer of the indicate size for PCI DMA in streaming
+/* Map a single buffer of the indicated size for PCI DMA in streaming
mode. The 32-bit PCI bus mastering address to use is returned.
Once the device is given the dma address, the device owns this memory
until either pci_unmap_single or pci_dma_sync_single is performed. */
@@ -201,6 +197,7 @@ pci_map_single(struct pci_dev *pdev, void *cpu_addr, long size, int direction)
DBGA("pci_map_single: [%p,%lx] np %ld -> sg %x from %p\n",
cpu_addr, size, npages, ret, __builtin_return_address(0));
+ alpha_mv.mv_pci_tbi(hose, ret, ret + size - 1);
return ret;
}
@@ -250,10 +247,6 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size,
npages = calc_npages((dma_addr & ~PAGE_MASK) + size);
iommu_arena_free(arena, dma_ofs, npages);
- /* If we're freeing ptes above the `next_entry' pointer, they
- may have snuck back into the TLB since the last wrap flush.
- We need to flush the TLB before reallocating these. */
- if (dma_ofs >= arena->next_entry)
alpha_mv.mv_pci_tbi(hose, dma_addr, dma_addr + size - 1);
DBGA("pci_unmap_single: sg [%x,%lx] np %ld from %p\n",
@@ -441,6 +434,8 @@ sg_fill(struct scatterlist *leader, struct scatterlist *end,
#endif
} while (++sg < end && (int) sg->dma_address < 0);
+ alpha_mv.mv_pci_tbi(arena->hose, out->dma_address,
+ out->dma_address+out->dma_length-1);
return 1;
}
@@ -574,10 +569,6 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
if (fend < tend) fend = tend;
}
- /* If we're freeing ptes above the `next_entry' pointer, they
- may have snuck back into the TLB since the last wrap flush.
- We need to flush the TLB before reallocating these. */
- if ((fend - arena->dma_base) >> PAGE_SHIFT >= arena->next_entry)
alpha_mv.mv_pci_tbi(hose, fbeg, fend);
DBGA("pci_unmap_sg: %d entries\n", nents - (end - sg));
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index e141df202c555a..5463c9fecd8a18 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -61,6 +61,13 @@ extern void t2_init_arch(void);
extern void t2_machine_check(u64, u64, struct pt_regs *);
#define t2_pci_tbi ((void *)0)
+/* core_titan.c */
+extern struct pci_ops titan_pci_ops;
+extern void titan_init_arch(void);
+extern void titan_kill_arch(int);
+extern void titan_machine_check(u64, u64, struct pt_regs *);
+extern void titan_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+
/* core_tsunami.c */
extern struct pci_ops tsunami_pci_ops;
extern void tsunami_init_arch(void);
@@ -68,9 +75,19 @@ extern void tsunami_kill_arch(int);
extern void tsunami_machine_check(u64, u64, struct pt_regs *);
extern void tsunami_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+/* core_wildfire.c */
+extern struct pci_ops wildfire_pci_ops;
+extern void wildfire_init_arch(void);
+extern void wildfire_kill_arch(int);
+extern void wildfire_machine_check(u64, u64, struct pt_regs *);
+extern void wildfire_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+
/* setup.c */
extern unsigned long srm_hae;
extern int boot_cpuid;
+extern int srmcons_output;
+extern void register_srm_console(void);
+extern void unregister_srm_console(void);
/* smp.c */
extern void setup_smp(void);
@@ -129,7 +146,8 @@ extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15);
extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *);
/* ../mm/init.c */
-void srm_paging_stop(void);
+extern void switch_to_system_map(void);
+extern void srm_paging_stop(void);
/* irq.c */
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index b79d42257a57b4..09fcfd787610cc 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -246,18 +246,23 @@ sys_ptrace(long request, long pid, long addr, long data,
ret = -EPERM;
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->flags |= PF_PTRACED;
+ if (current->ptrace & PT_PTRACED)
+ goto out_notsk;
+ /* set the ptrace bit in the process ptrace flags. */
+ current->ptrace |= PT_PTRACED;
ret = 0;
- goto out;
+ goto out_notsk;
}
if (pid == 1) /* you may not mess with init */
- goto out;
+ goto out_notsk;
ret = -ESRCH;
- if (!(child = find_task_by_pid(pid)))
- goto out;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ goto out_notsk;
if (request == PTRACE_ATTACH) {
ret = -EPERM;
if (child == current)
@@ -273,20 +278,22 @@ sys_ptrace(long request, long pid, long addr, long data,
&& !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED)
+ if (child->ptrace & PT_PTRACED)
goto out;
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
+ write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
+ write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out;
}
ret = -ESRCH;
- if (!(child->flags & PF_PTRACED)) {
+ if (!(child->ptrace & PT_PTRACED)) {
DBG(DBG_MEM, ("child not traced\n"));
goto out;
}
@@ -343,9 +350,9 @@ sys_ptrace(long request, long pid, long addr, long data,
if ((unsigned long) data > _NSIG)
goto out;
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
wake_up_process(child);
/* make sure single-step breakpoint is gone. */
@@ -373,7 +380,7 @@ sys_ptrace(long request, long pid, long addr, long data,
if ((unsigned long) data > _NSIG)
goto out;
child->thread.bpt_nsaved = -1; /* mark single-stepping */
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
wake_up_process(child);
child->exit_code = data;
/* give it a chance to run. */
@@ -384,12 +391,14 @@ sys_ptrace(long request, long pid, long addr, long data,
ret = -EIO;
if ((unsigned long) data > _NSIG)
goto out;
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
wake_up_process(child);
child->exit_code = data;
+ write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
+ write_unlock_irq(&tasklist_lock);
/* make sure single-step breakpoint is gone. */
ptrace_cancel_bpt(child);
ret = 0;
@@ -400,6 +409,8 @@ sys_ptrace(long request, long pid, long addr, long data,
goto out;
}
out:
+ free_task_struct(child);
+ out_notsk:
unlock_kernel();
return ret;
}
@@ -407,8 +418,8 @@ sys_ptrace(long request, long pid, long addr, long data,
asmlinkage void
syscall_trace(void)
{
- if ((current->flags & (PF_PTRACED|PF_TRACESYS))
- != (PF_PTRACED|PF_TRACESYS))
+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+ != (PT_PTRACED|PT_TRACESYS))
return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 1eab8fc5b3388e..988c3cbeccb719 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -34,6 +34,15 @@
#include <linux/blk.h>
#endif
+#include <linux/notifier.h>
+extern struct notifier_block *panic_notifier_list;
+static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
+static struct notifier_block alpha_panic_block = {
+ alpha_panic_event,
+ NULL,
+ INT_MAX /* try to do it first */
+};
+
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -42,6 +51,7 @@
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/mmu_context.h>
+#include <asm/console.h>
#include "proto.h"
#include "pci_impl.h"
@@ -53,6 +63,17 @@ unsigned long srm_hae;
/* Which processor we booted from. */
int boot_cpuid;
+/* Using SRM callbacks for initial console output. This works from
+ setup_arch() time through the end of init_IRQ(), as those places
+ are under our control.
+
+ By default, OFF; set it with a bootcommand arg of "srmcons".
+*/
+int srmcons_output = 0;
+
+/* Enforce a memory size limit; useful for testing. By default, none. */
+unsigned long mem_size_limit = 0;
+
#ifdef CONFIG_ALPHA_GENERIC
struct alpha_machine_vector alpha_mv;
int alpha_using_srm;
@@ -139,6 +160,7 @@ WEAK(noritake_mv);
WEAK(noritake_primo_mv);
WEAK(p2k_mv);
WEAK(pc164_mv);
+WEAK(privateer_mv);
WEAK(rawhide_mv);
WEAK(ruffian_mv);
WEAK(rx164_mv);
@@ -147,6 +169,7 @@ WEAK(sable_gamma_mv);
WEAK(sx164_mv);
WEAK(takara_mv);
WEAK(webbrick_mv);
+WEAK(wildfire_mv);
WEAK(xl_mv);
WEAK(xlt_mv);
@@ -202,14 +225,33 @@ reserve_std_resources(void)
for ((cluster) = (memdesc)->cluster, (i) = 0; \
(i) < (memdesc)->numclusters; (i)++, (cluster)++)
+static unsigned long __init
+get_mem_size_limit(char *s)
+{
+ unsigned long end = 0;
+ char *from = s;
+
+ end = simple_strtoul(from, &from, 0);
+ if ( *from == 'K' || *from == 'k' ) {
+ end = end << 10;
+ from++;
+ } else if ( *from == 'M' || *from == 'm' ) {
+ end = end << 20;
+ from++;
+ } else if ( *from == 'G' || *from == 'g' ) {
+ end = end << 30;
+ from++;
+ }
+ return end >> PAGE_SHIFT; /* Return the PFN of the limit. */
+}
+
static void __init
-setup_memory(void)
+setup_memory(void * kernel_end)
{
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
unsigned long start_pfn, bootmap_size, bootmap_pages, bootmap_start;
unsigned long start, end;
- extern char _end[];
int i;
/* Find free clusters, and init and free the bootmem accordingly. */
@@ -232,15 +274,23 @@ setup_memory(void)
max_low_pfn = end;
}
- /* Find the end of the kernel memory. */
- start_pfn = PFN_UP(virt_to_phys(_end));
+ if (mem_size_limit && max_low_pfn >= mem_size_limit)
+ {
+ printk("setup: forcing memory size to %ldK (from %ldK).\n",
+ mem_size_limit << (PAGE_SHIFT - 10),
+ max_low_pfn << (PAGE_SHIFT - 10));
+ max_low_pfn = mem_size_limit;
+ }
+
+ /* Find the end of the memory used by the kernel. */
+ start_pfn = PFN_UP(virt_to_phys(kernel_end));
bootmap_start = -1;
try_again:
if (max_low_pfn <= start_pfn)
panic("not enough memory to boot");
- /* We need to know how many physically contigous pages
+ /* We need to know how many physically contiguous pages
we'll need for the bootmap. */
bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
@@ -307,14 +357,14 @@ setup_memory(void)
printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
(void *) initrd_start, INITRD_SIZE);
- if (initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
+ if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ "(0x%08lx > 0x%p)\ndisabling initrd\n",
initrd_end,
phys_to_virt(PFN_PHYS(max_low_pfn)));
initrd_start = initrd_end = 0;
} else {
- reserve_bootmem(virt_to_phys(initrd_start),
+ reserve_bootmem(virt_to_phys((void *)initrd_start),
INITRD_SIZE);
}
}
@@ -346,20 +396,98 @@ page_is_ram(unsigned long pfn)
#undef PFN_PHYS
#undef PFN_MAX
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
+/*
+ * Manage the SRM callbacks as a "console".
+ */
+static struct console srmcons;
+
+void __init register_srm_console(void)
+{
+ register_console(&srmcons);
+}
+
+void __init unregister_srm_console(void)
+{
+ unregister_console(&srmcons);
+}
+
+static void srm_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ srm_printk(s);
+}
+
+static kdev_t srm_console_device(struct console *c)
+{
+ /* Huh? */
+ return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static int srm_console_wait_key(struct console *co)
+{
+ /* Huh? */
+ return 1;
+}
+
+static int __init srm_console_setup(struct console *co, char *options)
+{
+ return 1;
+}
+
+static struct console srmcons = {
+ "srm0",
+ srm_console_write,
+ NULL,
+ srm_console_device,
+ srm_console_wait_key,
+ NULL,
+ srm_console_setup,
+ CON_PRINTBUFFER | CON_ENABLED, /* fake it out */
+ -1,
+ 0,
+ NULL
+};
+
+#else
+void __init register_srm_console(void)
+{
+}
+void __init unregister_srm_console(void)
+{
+}
+#endif
+
void __init
setup_arch(char **cmdline_p)
{
struct alpha_machine_vector *vec = NULL;
struct percpu_struct *cpu;
char *type_name, *var_name, *p;
+ extern char _end;
+ void * kernel_end = &_end; /* end of kernel */
hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
boot_cpuid = hard_smp_processor_id();
+ /* Register a call for panic conditions. */
+ notifier_chain_register(&panic_notifier_list, &alpha_panic_block);
+
+#ifdef CONFIG_ALPHA_GENERIC
+ /* Assume that we've booted from SRM if we havn't booted from MILO.
+ Detect the later by looking for "MILO" in the system serial nr. */
+ alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
+#endif
+
+ /* If we are using SRM, we want to allow callbacks
+ as early as possible, so do this NOW, and then
+ they should work immediately thereafter.
+ */
+ kernel_end = callback_init(kernel_end);
+
/*
* Locate the command line.
*/
-
/* Hack for Jensen... since we're restricted to 8 or 16 chars for
boot flags depending on the boot mode, we need some shorthand.
This should do for installation. */
@@ -375,7 +503,6 @@ setup_arch(char **cmdline_p)
/*
* Process command-line arguments.
*/
-
for (p = strtok(command_line, " \t"); p ; p = strtok(NULL, " \t")) {
if (strncmp(p, "alpha_mv=", 9) == 0) {
vec = get_sysvec_byname(p+9);
@@ -385,15 +512,27 @@ setup_arch(char **cmdline_p)
est_cycle_freq = simple_strtol(p+6, NULL, 0);
continue;
}
+ if (strncmp(p, "mem=", 4) == 0) {
+ mem_size_limit = get_mem_size_limit(p+4);
+ continue;
+ }
+ if (strncmp(p, "srmcons", 7) == 0) {
+ srmcons_output = 1;
+ continue;
+ }
}
- /* Replace the command line, not that we've killed it with strtok. */
+ /* Replace the command line, now that we've killed it with strtok. */
strcpy(command_line, saved_command_line);
+ /* If we want SRM console printk echoing early, do it now. */
+ if (alpha_using_srm && srmcons_output) {
+ register_srm_console();
+ }
+
/*
* Indentify and reconfigure for the current system.
*/
-
get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
&type_name, &var_name);
if (*var_name == '0')
@@ -415,12 +554,6 @@ setup_arch(char **cmdline_p)
alpha_mv = *vec;
}
-#ifdef CONFIG_ALPHA_GENERIC
- /* Assume that we've booted from SRM if we havn't booted from MILO.
- Detect the later by looking for "MILO" in the system serial nr. */
- alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
-#endif
-
printk("Booting "
#ifdef CONFIG_ALPHA_GENERIC
"GENERIC "
@@ -433,10 +566,9 @@ setup_arch(char **cmdline_p)
printk("Command line: %s\n", command_line);
/*
- * Sync with the HAE
+ * Sync up the HAE.
+ * Save the SRM's current value for restoration.
*/
-
- /* Save the SRM's current value for restoration. */
srm_hae = *alpha_mv.hae_register;
__set_hae(alpha_mv.hae_cache);
@@ -444,7 +576,7 @@ setup_arch(char **cmdline_p)
wrmces(0x7);
/* Find our memory. */
- setup_memory();
+ setup_memory(kernel_end);
/* Initialize the machine. Usually has to do with setting up
DMA windows and the like. */
@@ -499,7 +631,7 @@ static char systype_names[][16] = {
"Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
"Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
"Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
- "Tsunami", "Wildfire", "CUSCO", "Eiger"
+ "Tsunami", "Wildfire", "CUSCO", "Eiger", "Titan"
};
static char unofficial_names[][8] = {"100", "Ruffian"};
@@ -523,6 +655,11 @@ static char rawhide_names[][16] = {
};
static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
+static char titan_names[][16] = {
+ "0", "Privateer"
+};
+static int titan_indices[] = {0,1};
+
static char tsunami_names[][16] = {
"0", "DP264", "Warhol", "Windjammer", "Monet", "Clipper",
"Goldrush", "Webbrick", "Catamaran"
@@ -569,9 +706,10 @@ get_sysvec(long type, long variation, long cpu)
&takara_mv,
NULL, /* Yukon */
NULL, /* Tsunami -- see variation. */
- NULL, /* Wildfire */
+ &wildfire_mv, /* Wildfire */
NULL, /* CUSCO */
&eiger_mv, /* Eiger */
+ NULL, /* Titan */
};
static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
@@ -609,6 +747,12 @@ get_sysvec(long type, long variation, long cpu)
&eb66p_mv
};
+ static struct alpha_machine_vector *titan_vecs[] __initlocaldata =
+ {
+ NULL,
+ &privateer_mv, /* privateer */
+ };
+
static struct alpha_machine_vector *tsunami_vecs[] __initlocaldata =
{
NULL,
@@ -665,6 +809,10 @@ get_sysvec(long type, long variation, long cpu)
if (member < N(eb66_indices))
vec = eb66_vecs[eb66_indices[member]];
break;
+ case ST_DEC_TITAN:
+ if (member < N(titan_indices))
+ vec = titan_vecs[titan_indices[member]];
+ break;
case ST_DEC_TSUNAMI:
if (member < N(tsunami_indices))
vec = tsunami_vecs[tsunami_indices[member]];
@@ -723,6 +871,7 @@ get_sysvec_byname(const char *name)
&noritake_primo_mv,
&p2k_mv,
&pc164_mv,
+ &privateer_mv,
&rawhide_mv,
&ruffian_mv,
&rx164_mv,
@@ -731,6 +880,7 @@ get_sysvec_byname(const char *name)
&sx164_mv,
&takara_mv,
&webbrick_mv,
+ &wildfire_mv,
&xl_mv,
&xlt_mv
};
@@ -801,6 +951,10 @@ get_sysnames(long type, long variation,
if (member < N(rawhide_indices))
*variation_name = rawhide_names[rawhide_indices[member]];
break;
+ case ST_DEC_TITAN:
+ if (member < N(titan_indices))
+ *variation_name = titan_names[titan_indices[member]];
+ break;
case ST_DEC_TSUNAMI:
if (member < N(tsunami_indices))
*variation_name = tsunami_names[tsunami_indices[member]];
@@ -873,7 +1027,7 @@ int get_cpuinfo(char *buffer)
static char cpu_names[][8] = {
"EV3", "EV4", "Simulate", "LCA4", "EV5", "EV45", "EV56",
- "EV6", "PCA56", "PCA57", "EV67"
+ "EV6", "PCA56", "PCA57", "EV67", "EV68CB", "EV68AL"
};
struct percpu_struct *cpu;
@@ -936,3 +1090,16 @@ int get_cpuinfo(char *buffer)
return len;
}
+
+static int alpha_panic_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+#if 1
+ /* FIXME FIXME FIXME */
+ /* If we are using SRM and serial console, just hard halt here. */
+ if (alpha_using_srm && srmcons_output)
+ __halt();
+#endif
+ return NOTIFY_DONE;
+}
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 1f70c98e6b83bc..db8cacbc9e19dd 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -651,7 +651,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
if (!signr)
break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
index caab7accc292ae..0b2db18ab34c8b 100644
--- a/arch/alpha/kernel/smc37c669.c
+++ b/arch/alpha/kernel/smc37c669.c
@@ -2588,6 +2588,9 @@ void __init SMC669_Init ( int index )
);
SMC37c669_enable_device( FLOPPY_0 );
+ /* Wake up sometimes forgotten floppy, especially on DP264. */
+ outb(0xc, 0x3f2);
+
SMC37c669_disable_device( IDE_0 );
#if SMC_DEBUG
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 1ddaaf74d35a4e..b812e2c64d5608 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -212,8 +212,19 @@ smp_tune_scheduling (void)
freq = hwrpb->cycle_freq ? : est_cycle_freq;
+#if 0
/* Magic estimation stolen from x86 port. */
- cacheflush_time = freq / 1024 * on_chip_cache / 5000;
+ cacheflush_time = freq / 1024L * on_chip_cache / 5000L;
+
+ printk("Using heuristic of %d cycles.\n",
+ cacheflush_time);
+#else
+ /* Magic value to force potential preemption of other CPUs. */
+ cacheflush_time = INT_MAX;
+
+ printk("Using heuristic of %d cycles.\n",
+ cacheflush_time);
+#endif
}
/*
@@ -325,8 +336,8 @@ recv_secondary_console_msg(void)
}
}
- printk(KERN_INFO "recv_secondary_console_msg: on %d "
- "message is '%s'\n", mycpu, buf);
+ DBGS((KERN_INFO "recv_secondary_console_msg: on %d "
+ "message is '%s'\n", mycpu, buf));
}
hwrpb->txrdy = 0;
@@ -361,8 +372,10 @@ secondary_cpu_start(int cpuid, struct task_struct *idle)
hwpcb->flags = idle->thread.pal_flags;
hwpcb->res1 = hwpcb->res2 = 0;
+#if 0
DBGS(("KSP 0x%lx PTBR 0x%lx VPTBR 0x%lx UNIQUE 0x%lx\n",
hwpcb->ksp, hwpcb->ptbr, hwrpb->vptb, hwcpb->unique));
+#endif
DBGS(("Starting secondary cpu %d: state 0x%lx pal_flags 0x%lx\n",
cpuid, idle->state, idle->thread.pal_flags));
@@ -738,8 +751,10 @@ handle_ipi(struct pt_regs *regs)
unsigned long *pending_ipis = &ipi_data[this_cpu].bits;
unsigned long ops;
- DBGS(("handle_ipi: on CPU %d ops 0x%x PC 0x%lx\n",
+#if 0
+ DBGS(("handle_ipi: on CPU %d ops 0x%lx PC 0x%lx\n",
this_cpu, *pending_ipis, regs->pc));
+#endif
mb(); /* Order interrupt and bit testing. */
while ((ops = xchg(pending_ipis, 0)) != 0) {
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index c10018fffdd65b..475b477bd3d1e0 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -36,7 +36,7 @@
/* Note mask bit is true for ENABLED irqs. */
static unsigned long cached_irq_mask;
/* dp264 boards handle at max four CPUs */
-static unsigned long cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL };
+static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL };
spinlock_t dp264_irq_lock = SPIN_LOCK_UNLOCKED;
@@ -52,6 +52,7 @@ tsunami_update_irq_hw(unsigned long mask)
volatile unsigned long *dim0, *dim1, *dim2, *dim3;
unsigned long mask0, mask1, mask2, mask3, dummy;
+ mask &= ~isa_enable;
mask0 = mask & cpu_irq_affinity[0];
mask1 = mask & cpu_irq_affinity[1];
mask2 = mask & cpu_irq_affinity[2];
@@ -170,7 +171,6 @@ cpu_set_irq_affinity(unsigned int irq, unsigned long affinity)
aff &= ~(1UL << irq);
cpu_irq_affinity[cpu] = aff;
}
-
}
static void
@@ -275,7 +275,12 @@ clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
irq = (vector - 0x800) >> 4;
- /*
+#if 0
+ printk("clipper_srm_device_interrupt: vector 0x%lx IRQ %d cpu %d\n",
+ vector, irq, smp_processor_id());
+#endif
+
+/*
* The SRM console reports PCI interrupts with a vector calculated by:
*
* 0x900 + (0x10 * DRIR-bit)
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index f436b49020133a..d939b2c21b1449 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -185,8 +185,8 @@ static void
mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
{
-#define MCHK_NO_DEVSEL 0x205L
-#define MCHK_NO_TABT 0x204L
+#define MCHK_NO_DEVSEL 0x205U
+#define MCHK_NO_TABT 0x204U
struct el_common *mchk_header;
unsigned int code;
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
new file mode 100644
index 00000000000000..190b76bd9e7436
--- /dev/null
+++ b/arch/alpha/kernel/sys_titan.c
@@ -0,0 +1,393 @@
+/*
+ * linux/arch/alpha/kernel/sys_titan.c
+ *
+ * Copyright (C) 1995 David A Rusling
+ * Copyright (C) 1996, 1999 Jay A Estabrook
+ * Copyright (C) 1998, 1999 Richard Henderson
+ * Copyright (C) 1999, 2000 Jeff Wiedemeier
+ *
+ * Code supporting TITAN systems (EV6+TITAN), currently:
+ * Privateer
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_titan.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+/* Note mask bit is true for ENABLED irqs. */
+static unsigned long cached_irq_mask;
+/* Titan boards handle at most four CPUs. */
+static unsigned long cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL };
+
+spinlock_t titan_irq_lock = SPIN_LOCK_UNLOCKED;
+
+static void
+titan_update_irq_hw(unsigned long mask)
+{
+ register titan_cchip *cchip = TITAN_cchip;
+ unsigned long isa_enable = 1UL << 55;
+ register int bcpu = boot_cpuid;
+
+#ifdef CONFIG_SMP
+ register unsigned long cpm = cpu_present_mask;
+ volatile unsigned long *dim0, *dim1, *dim2, *dim3;
+ unsigned long mask0, mask1, mask2, mask3, dummy;
+
+ mask &= ~isa_enable;
+ mask0 = mask & cpu_irq_affinity[0];
+ mask1 = mask & cpu_irq_affinity[1];
+ mask2 = mask & cpu_irq_affinity[2];
+ mask3 = mask & cpu_irq_affinity[3];
+
+ if (bcpu == 0) mask0 |= isa_enable;
+ else if (bcpu == 1) mask1 |= isa_enable;
+ else if (bcpu == 2) mask2 |= isa_enable;
+ else mask3 |= isa_enable;
+
+ dim0 = &cchip->dim0.csr;
+ dim1 = &cchip->dim1.csr;
+ dim2 = &cchip->dim2.csr;
+ dim3 = &cchip->dim3.csr;
+ if ((cpm & 1) == 0) dim0 = &dummy;
+ if ((cpm & 2) == 0) dim1 = &dummy;
+ if ((cpm & 4) == 0) dim2 = &dummy;
+ if ((cpm & 8) == 0) dim3 = &dummy;
+
+ *dim0 = mask0;
+ *dim1 = mask1;
+ *dim2 = mask2;
+ *dim3 = mask3;
+ mb();
+ *dim0;
+ *dim1;
+ *dim2;
+ *dim3;
+#else
+ volatile unsigned long *dimB;
+ if (bcpu == 0) dimB = &cchip->dim0.csr;
+ else if (bcpu == 1) dimB = &cchip->dim1.csr;
+ else if (bcpu == 2) dimB = &cchip->dim2.csr;
+ else if (bcpu == 3) dimB = &cchip->dim3.csr;
+
+ *dimB = mask | isa_enable;
+ mb();
+ *dimB;
+#endif
+}
+
+static inline void
+privateer_enable_irq(unsigned int irq)
+{
+ spin_lock(&titan_irq_lock);
+ cached_irq_mask |= 1UL << (irq - 16);
+ titan_update_irq_hw(cached_irq_mask);
+ spin_unlock(&titan_irq_lock);
+}
+
+static inline void
+privateer_disable_irq(unsigned int irq)
+{
+ spin_lock(&titan_irq_lock);
+ cached_irq_mask &= ~(1UL << (irq - 16));
+ titan_update_irq_hw(cached_irq_mask);
+ spin_unlock(&titan_irq_lock);
+}
+
+static unsigned int
+privateer_startup_irq(unsigned int irq)
+{
+ privateer_enable_irq(irq);
+ return 0; /* never anything pending */
+}
+
+static void
+privateer_end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ privateer_enable_irq(irq);
+}
+
+static void
+cpu_set_irq_affinity(unsigned int irq, unsigned long affinity)
+{
+ int cpu;
+
+ for (cpu = 0; cpu < 4; cpu++) {
+ if (affinity & (1UL << cpu))
+ cpu_irq_affinity[cpu] |= 1UL << irq;
+ else
+ cpu_irq_affinity[cpu] &= ~(1UL << irq);
+ }
+
+}
+
+static void
+privateer_set_affinity(unsigned int irq, unsigned long affinity)
+{
+ spin_lock(&titan_irq_lock);
+ cpu_set_irq_affinity(irq - 16, affinity);
+ titan_update_irq_hw(cached_irq_mask);
+ spin_unlock(&titan_irq_lock);
+}
+
+static struct hw_interrupt_type privateer_irq_type = {
+ typename: "PRIVATEER",
+ startup: privateer_startup_irq,
+ shutdown: privateer_disable_irq,
+ enable: privateer_enable_irq,
+ disable: privateer_disable_irq,
+ ack: privateer_disable_irq,
+ end: privateer_end_irq,
+ set_affinity: privateer_set_affinity,
+};
+
+static void
+privateer_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ printk("privateer_device_interrupt: NOT IMPLEMENTED YET!! \n");
+}
+
+static void
+privateer_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ int irq;
+
+ irq = (vector - 0x800) >> 4;
+ handle_irq(irq, regs);
+}
+
+
+static void __init
+init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax)
+{
+ long i;
+ for(i = imin; i <= imax; ++i) {
+ irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
+ irq_desc[i].handler = ops;
+ }
+}
+
+static void __init
+privateer_init_irq(void)
+{
+ extern asmlinkage void entInt(void);
+ int cpu;
+
+ outb(0, DMA1_RESET_REG);
+ outb(0, DMA2_RESET_REG);
+ outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+ outb(0, DMA2_MASK_REG);
+
+ if (alpha_using_srm)
+ alpha_mv.device_interrupt = privateer_srm_device_interrupt;
+
+ titan_update_irq_hw(0UL);
+
+ init_i8259a_irqs();
+ init_titan_irqs(&privateer_irq_type, 16, 63 + 16);
+}
+
+/*
+ * Privateer PCI Fixup configuration.
+ *
+ * PCHIP 0 BUS 0 (Hose 0)
+ *
+ * IDSEL Dev What
+ * ----- --- ----
+ * 18 7 Embedded Southbridge
+ * 19 8 Slot 0
+ * 20 9 Slot 1
+ * 21 10 Slot 2
+ * 22 11 Slot 3
+ * 23 12 Embedded HotPlug controller
+ * 27 16 Embedded Southbridge IDE
+ * 29 18 Embedded Southbridge PMU
+ * 31 20 Embedded Southbridge USB
+ *
+ * PCHIP 1 BUS 0 (Hose 1)
+ *
+ * IDSEL Dev What
+ * ----- --- ----
+ * 12 1 Slot 0
+ * 13 2 Slot 1
+ * 17 6 Embedded hotPlug controller
+ *
+ * PCHIP 0 BUS 1 (Hose 2)
+ *
+ * IDSEL What
+ * ----- ----
+ * NONE AGP
+ *
+ * PCHIP 1 BUS 1 (Hose 3)
+ *
+ * IDSEL Dev What
+ * ----- --- ----
+ * 12 1 Slot 0
+ * 13 2 Slot 1
+ * 17 6 Embedded hotPlug controller
+ *
+ * Summary @ TITAN_CSR_DIM0:
+ * Bit Meaning
+ * 0-7 Unused
+ * 8 PCHIP 0 BUS 1 YUKON (if present)
+ * 9 PCHIP 1 BUS 1 YUKON
+ * 10 PCHIP 1 BUS 0 YUKON
+ * 11 PCHIP 0 BUS 0 YUKON
+ * 12 PCHIP 0 BUS 0 SLOT 2 INT A
+ * 13 PCHIP 0 BUS 0 SLOT 2 INT B
+ * 14 PCHIP 0 BUS 0 SLOT 2 INT C
+ * 15 PCHIP 0 BUS 0 SLOT 2 INT D
+ * 16 PCHIP 0 BUS 0 SLOT 3 INT A
+ * 17 PCHIP 0 BUS 0 SLOT 3 INT B
+ * 18 PCHIP 0 BUS 0 SLOT 3 INT C
+ * 19 PCHIP 0 BUS 0 SLOT 3 INT D
+ * 20 PCHIP 0 BUS 0 SLOT 0 INT A
+ * 21 PCHIP 0 BUS 0 SLOT 0 INT B
+ * 22 PCHIP 0 BUS 0 SLOT 0 INT C
+ * 23 PCHIP 0 BUS 0 SLOT 0 INT D
+ * 24 PCHIP 0 BUS 0 SLOT 1 INT A
+ * 25 PCHIP 0 BUS 0 SLOT 1 INT B
+ * 26 PCHIP 0 BUS 0 SLOT 1 INT C
+ * 27 PCHIP 0 BUS 0 SLOT 1 INT D
+ * 28 PCHIP 1 BUS 0 SLOT 0 INT A
+ * 29 PCHIP 1 BUS 0 SLOT 0 INT B
+ * 30 PCHIP 1 BUS 0 SLOT 0 INT C
+ * 31 PCHIP 1 BUS 0 SLOT 0 INT D
+ * 32 PCHIP 1 BUS 0 SLOT 1 INT A
+ * 33 PCHIP 1 BUS 0 SLOT 1 INT B
+ * 34 PCHIP 1 BUS 0 SLOT 1 INT C
+ * 35 PCHIP 1 BUS 0 SLOT 1 INT D
+ * 36 PCHIP 1 BUS 1 SLOT 0 INT A
+ * 37 PCHIP 1 BUS 1 SLOT 0 INT B
+ * 38 PCHIP 1 BUS 1 SLOT 0 INT C
+ * 39 PCHIP 1 BUS 1 SLOT 0 INT D
+ * 40 PCHIP 1 BUS 1 SLOT 1 INT A
+ * 41 PCHIP 1 BUS 1 SLOT 1 INT B
+ * 42 PCHIP 1 BUS 1 SLOT 1 INT C
+ * 43 PCHIP 1 BUS 1 SLOT 1 INT D
+ * 44 AGP INT A
+ * 45 AGP INT B
+ * 46-47 Unused
+ * 49 Reserved for Sleep mode
+ * 50 Temperature Warning (optional)
+ * 51 Power Warning (optional)
+ * 52 Reserved
+ * 53 South Bridge NMI
+ * 54 South Bridge SMI INT
+ * 55 South Bridge ISA Interrupt
+ * 56-58 Unused
+ * 59 PCHIP1_C_ERROR
+ * 60 PCHIP0_C_ERROR
+ * 61 PCHIP1_H_ERROR
+ * 62 PCHIP0_H_ERROR
+ * 63 Reserved
+ *
+ */
+static int __init
+privateer_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ u8 irq;
+
+ pcibios_read_config_byte(dev->bus->number,
+ dev->devfn,
+ PCI_INTERRUPT_LINE,
+ &irq);
+
+ /* is it routed through ISA? */
+ if ((irq & 0xF0) == 0xE0)
+ return (int)irq;
+
+ return (int)irq + 16; /* HACK -- this better only be called once */
+}
+
+#ifdef CONFIG_VGA_HOSE
+static struct pci_controler * __init
+privateer_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2)
+{
+ struct pci_controler *hose = h1;
+ int agp1, agp2;
+
+ /* which hose(s) are agp? */
+ agp1 = (0 != (TITAN_agp & (1 << h1->index)));
+ agp2 = (0 != (TITAN_agp & (1 << h2->index)));
+
+ hose = h1; /* default to h1 */
+ if (agp1 ^ agp2) {
+ if (agp2) hose = h2; /* take agp if only one */
+ } else if (h2->index < h1->index)
+ hose = h2; /* first hose if 2xpci or 2xagp */
+
+ return hose;
+}
+#endif
+
+static void __init
+privateer_init_pci(void)
+{
+ common_init_pci();
+ SMC669_Init(0);
+#ifdef CONFIG_VGA_HOSE
+ locate_and_init_vga(privateer_vga_hose_select);
+#endif
+}
+
+void
+privateer_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs * regs)
+{
+ /* only handle system events here */
+ if (vector != SCB_Q_SYSEVENT)
+ return titan_machine_check(vector, la_ptr, regs);
+
+ /* it's a system event, handle it here */
+ printk("PRIVATEER 680 Machine Check on CPU %d\n", smp_processor_id());
+}
+
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector privateer_mv __initmv = {
+ vector_name: "PRIVATEER",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_TITAN_IO,
+ DO_TITAN_BUS,
+ machine_check: privateer_machine_check,
+ max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
+
+ nr_irqs: 80, /* 64 + 16 */
+ device_interrupt: privateer_device_interrupt,
+
+ init_arch: titan_init_arch,
+ init_irq: privateer_init_irq,
+ init_rtc: common_init_rtc,
+ init_pci: privateer_init_pci,
+ kill_arch: titan_kill_arch,
+ pci_map_irq: privateer_map_irq,
+ pci_swizzle: common_swizzle,
+};
+ALIAS_MV(privateer)
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
new file mode 100644
index 00000000000000..276195040b4884
--- /dev/null
+++ b/arch/alpha/kernel/sys_wildfire.c
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/alpha/kernel/sys_wildfire.c
+ *
+ * Wildfire support.
+ *
+ * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_wildfire.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+static unsigned long cached_irq_mask[WILDFIRE_NR_IRQS/(sizeof(long)*8)];
+
+spinlock_t wildfire_irq_lock = SPIN_LOCK_UNLOCKED;
+
+static int doing_init_irq_hw = 0;
+
+static void
+wildfire_update_irq_hw(unsigned int irq)
+{
+ int qbbno = (irq >> 8) & (WILDFIRE_MAX_QBB - 1);
+ int pcano = (irq >> 6) & (WILDFIRE_PCA_PER_QBB - 1);
+ wildfire_pca *pca;
+ volatile unsigned long * enable0;
+
+ if (!WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
+ if (!doing_init_irq_hw) {
+ printk(KERN_ERR "wildfire_update_irq_hw:"
+ " got irq %d for non-existent PCA %d"
+ " on QBB %d.\n",
+ irq, pcano, qbbno);
+ }
+ return;
+ }
+
+ pca = WILDFIRE_pca(qbbno, pcano);
+ enable0 = (unsigned long *) &pca->pca_int[0].enable; /* ??? */
+
+ *enable0 = cached_irq_mask[qbbno * WILDFIRE_PCA_PER_QBB + pcano];
+ mb();
+ *enable0;
+}
+
+static void __init
+wildfire_init_irq_hw(void)
+{
+#if 0
+ register wildfire_pca * pca = WILDFIRE_pca(0, 0);
+ volatile unsigned long * enable0, * enable1, * enable2, *enable3;
+ volatile unsigned long * target0, * target1, * target2, *target3;
+
+ enable0 = (unsigned long *) &pca->pca_int[0].enable;
+ enable1 = (unsigned long *) &pca->pca_int[1].enable;
+ enable2 = (unsigned long *) &pca->pca_int[2].enable;
+ enable3 = (unsigned long *) &pca->pca_int[3].enable;
+
+ target0 = (unsigned long *) &pca->pca_int[0].target;
+ target1 = (unsigned long *) &pca->pca_int[1].target;
+ target2 = (unsigned long *) &pca->pca_int[2].target;
+ target3 = (unsigned long *) &pca->pca_int[3].target;
+
+ *enable0 = *enable1 = *enable2 = *enable3 = 0;
+
+ *target0 = (1UL<<8) | WILDFIRE_QBB(0);
+ *target1 = *target2 = *target3 = 0;
+
+ mb();
+
+ *enable0; *enable1; *enable2; *enable3;
+ *target0; *target1; *target2; *target3;
+
+#else
+ int i;
+
+ doing_init_irq_hw = 1;
+
+ /* Need to update only once for every possible PCA. */
+ for (i = 0; i < WILDFIRE_NR_IRQS; i+=WILDFIRE_IRQ_PER_PCA)
+ wildfire_update_irq_hw(i);
+
+ doing_init_irq_hw = 0;
+#endif
+}
+
+static void
+wildfire_enable_irq(unsigned int irq)
+{
+ if (irq < 16)
+ i8259a_enable_irq(irq);
+
+ spin_lock(&wildfire_irq_lock);
+ set_bit(irq, &cached_irq_mask);
+ wildfire_update_irq_hw(irq);
+ spin_unlock(&wildfire_irq_lock);
+}
+
+static void
+wildfire_disable_irq(unsigned int irq)
+{
+ if (irq < 16)
+ i8259a_disable_irq(irq);
+
+ spin_lock(&wildfire_irq_lock);
+ clear_bit(irq, &cached_irq_mask);
+ wildfire_update_irq_hw(irq);
+ spin_unlock(&wildfire_irq_lock);
+}
+
+static void
+wildfire_mask_and_ack_irq(unsigned int irq)
+{
+ if (irq < 16)
+ i8259a_mask_and_ack_irq(irq);
+
+ spin_lock(&wildfire_irq_lock);
+ clear_bit(irq, &cached_irq_mask);
+ wildfire_update_irq_hw(irq);
+ spin_unlock(&wildfire_irq_lock);
+}
+
+static unsigned int
+wildfire_startup_irq(unsigned int irq)
+{
+ wildfire_enable_irq(irq);
+ return 0; /* never anything pending */
+}
+
+static void
+wildfire_end_irq(unsigned int irq)
+{
+#if 0
+ if (!irq_desc[irq].action)
+ printk("got irq %d\n", irq);
+#endif
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ wildfire_enable_irq(irq);
+}
+
+static struct hw_interrupt_type wildfire_irq_type = {
+ typename: "WILDFIRE",
+ startup: wildfire_startup_irq,
+ shutdown: wildfire_disable_irq,
+ enable: wildfire_enable_irq,
+ disable: wildfire_disable_irq,
+ ack: wildfire_mask_and_ack_irq,
+ end: wildfire_end_irq,
+};
+
+static void __init
+wildfire_init_irq_per_pca(int qbbno, int pcano)
+{
+ int i, irq_bias;
+ unsigned long io_bias;
+ static struct irqaction isa_enable = {
+ handler: no_action,
+ name: "isa_enable",
+ };
+
+ irq_bias = qbbno * (WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)
+ + pcano * WILDFIRE_IRQ_PER_PCA;
+
+ /* Only need the following for first PCI bus per PCA. */
+ io_bias = WILDFIRE_IO(qbbno, pcano<<1) - WILDFIRE_IO_BIAS;
+
+#if 0
+ outb(0, DMA1_RESET_REG + io_bias);
+ outb(0, DMA2_RESET_REG + io_bias);
+ outb(DMA_MODE_CASCADE, DMA2_MODE_REG + io_bias);
+ outb(0, DMA2_MASK_REG + io_bias);
+#endif
+
+#if 0
+ /* ??? Not sure how to do this, yet... */
+ init_i8259a_irqs(); /* ??? */
+#endif
+
+ for (i = 0; i < 16; ++i) {
+ if (i == 2)
+ continue;
+ irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
+ irq_desc[i+irq_bias].handler = &wildfire_irq_type;
+ }
+
+ irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
+ irq_desc[36+irq_bias].handler = &wildfire_irq_type;
+ for (i = 40; i < 64; ++i) {
+ irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
+ irq_desc[i+irq_bias].handler = &wildfire_irq_type;
+ }
+
+ setup_irq(32+irq_bias, &isa_enable);
+}
+
+static void __init
+wildfire_init_irq(void)
+{
+ int qbbno, pcano;
+
+#if 1
+ wildfire_init_irq_hw();
+ init_i8259a_irqs();
+#endif
+
+ for (qbbno = 0; qbbno < WILDFIRE_MAX_QBB; qbbno++) {
+ if (WILDFIRE_QBB_EXISTS(qbbno)) {
+ for (pcano = 0; pcano < WILDFIRE_PCA_PER_QBB; pcano++) {
+ if (WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
+ wildfire_init_irq_per_pca(qbbno, pcano);
+ }
+ }
+ }
+ }
+}
+
+static void
+wildfire_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ int irq;
+
+ irq = (vector - 0x800) >> 4;
+
+ /*
+ * bits 10-8: source QBB ID
+ * bits 7-6: PCA
+ * bits 5-0: irq in PCA
+ */
+
+ handle_irq(irq, regs);
+ return;
+}
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary per PCA (2 PCI or HIPPI buses):
+ *
+ * Bit Meaning
+ * 0-15 ISA
+ *
+ *32 ISA summary
+ *33 SMI
+ *34 NMI
+ *36 builtin QLogic SCSI (or slot 0 if no IO module)
+ *40 Interrupt Line A from slot 2 PCI0
+ *41 Interrupt Line B from slot 2 PCI0
+ *42 Interrupt Line C from slot 2 PCI0
+ *43 Interrupt Line D from slot 2 PCI0
+ *44 Interrupt Line A from slot 3 PCI0
+ *45 Interrupt Line B from slot 3 PCI0
+ *46 Interrupt Line C from slot 3 PCI0
+ *47 Interrupt Line D from slot 3 PCI0
+ *
+ *48 Interrupt Line A from slot 4 PCI1
+ *49 Interrupt Line B from slot 4 PCI1
+ *50 Interrupt Line C from slot 4 PCI1
+ *51 Interrupt Line D from slot 4 PCI1
+ *52 Interrupt Line A from slot 5 PCI1
+ *53 Interrupt Line B from slot 5 PCI1
+ *54 Interrupt Line C from slot 5 PCI1
+ *55 Interrupt Line D from slot 5 PCI1
+ *56 Interrupt Line A from slot 6 PCI1
+ *57 Interrupt Line B from slot 6 PCI1
+ *58 Interrupt Line C from slot 6 PCI1
+ *50 Interrupt Line D from slot 6 PCI1
+ *60 Interrupt Line A from slot 7 PCI1
+ *61 Interrupt Line B from slot 7 PCI1
+ *62 Interrupt Line C from slot 7 PCI1
+ *63 Interrupt Line D from slot 7 PCI1
+ *
+ *
+ * IdSel
+ * 0 Cypress Bridge I/O (ISA summary interrupt)
+ * 1 64 bit PCI 0 option slot 1 (SCSI QLogic builtin)
+ * 2 64 bit PCI 0 option slot 2
+ * 3 64 bit PCI 0 option slot 3
+ * 4 64 bit PCI 1 option slot 4
+ * 5 64 bit PCI 1 option slot 5
+ * 6 64 bit PCI 1 option slot 6
+ * 7 64 bit PCI 1 option slot 7
+ */
+
+static int __init
+wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static char irq_tab[8][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
+ { -1, -1, -1, -1, -1}, /* IdSel 0 ISA Bridge */
+ { 36, 36, 36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */
+ { 40, 40, 40+1, 40+2, 40+3}, /* IdSel 2 PCI 0 slot 2 */
+ { 44, 44, 44+1, 44+2, 44+3}, /* IdSel 3 PCI 0 slot 3 */
+ { 48, 48, 48+1, 48+2, 48+3}, /* IdSel 4 PCI 1 slot 4 */
+ { 52, 52, 52+1, 52+2, 52+3}, /* IdSel 5 PCI 1 slot 5 */
+ { 56, 56, 56+1, 56+2, 56+3}, /* IdSel 6 PCI 1 slot 6 */
+ { 60, 60, 60+1, 60+2, 60+3}, /* IdSel 7 PCI 1 slot 7 */
+ };
+ const long min_idsel = 0, max_idsel = 7, irqs_per_slot = 5;
+
+ struct pci_controler *hose = dev->sysdata;
+ int irq = COMMON_TABLE_LOOKUP;
+
+ if (irq > 0) {
+ int qbbno = hose->index >> 3;
+ int pcano = (hose->index >> 1) & 3;
+ irq += (qbbno << 8) + (pcano << 6);
+ }
+ return irq;
+}
+
+static void __init
+wildfire_init_pci(void)
+{
+ common_init_pci();
+}
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector wildfire_mv __initmv = {
+ vector_name: "WILDFIRE",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_WILDFIRE_IO,
+ DO_WILDFIRE_BUS,
+ machine_check: wildfire_machine_check,
+ max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
+
+ nr_irqs: WILDFIRE_NR_IRQS,
+ device_interrupt: wildfire_device_interrupt,
+
+ init_arch: wildfire_init_arch,
+ init_irq: wildfire_init_irq,
+ init_rtc: common_init_rtc,
+ init_pci: wildfire_init_pci,
+ kill_arch: wildfire_kill_arch,
+ pci_map_irq: wildfire_map_irq,
+ pci_swizzle: common_swizzle,
+};
+ALIAS_MV(wildfire)
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 8edfef27db4772..7b2f8be039d674 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -27,30 +27,234 @@ dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
{
printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n",
regs->pc, regs->r26, regs->ps);
- printk("r0 = %016lx r1 = %016lx r2 = %016lx\n",
+ printk("v0 = %016lx t0 = %016lx t1 = %016lx\n",
regs->r0, regs->r1, regs->r2);
- printk("r3 = %016lx r4 = %016lx r5 = %016lx\n",
+ printk("t2 = %016lx t3 = %016lx t4 = %016lx\n",
regs->r3, regs->r4, regs->r5);
- printk("r6 = %016lx r7 = %016lx r8 = %016lx\n",
+ printk("t5 = %016lx t6 = %016lx t7 = %016lx\n",
regs->r6, regs->r7, regs->r8);
if (r9_15) {
- printk("r9 = %016lx r10= %016lx r11= %016lx\n",
+ printk("s0 = %016lx s1 = %016lx s2 = %016lx\n",
r9_15[9], r9_15[10], r9_15[11]);
- printk("r12= %016lx r13= %016lx r14= %016lx\n",
+ printk("s3 = %016lx s4 = %016lx s5 = %016lx\n",
r9_15[12], r9_15[13], r9_15[14]);
- printk("r15= %016lx\n", r9_15[15]);
+ printk("s6 = %016lx\n", r9_15[15]);
}
- printk("r16= %016lx r17= %016lx r18= %016lx\n",
+ printk("a0 = %016lx a1 = %016lx a2 = %016lx\n",
regs->r16, regs->r17, regs->r18);
- printk("r19= %016lx r20= %016lx r21= %016lx\n",
+ printk("a3 = %016lx a4 = %016lx a5 = %016lx\n",
regs->r19, regs->r20, regs->r21);
- printk("r22= %016lx r23= %016lx r24= %016lx\n",
+ printk("t8 = %016lx t9 = %016lx t10= %016lx\n",
regs->r22, regs->r23, regs->r24);
- printk("r25= %016lx r27= %016lx r28= %016lx\n",
+ printk("t11= %016lx pv = %016lx at = %016lx\n",
regs->r25, regs->r27, regs->r28);
printk("gp = %016lx sp = %p\n", regs->gp, regs+1);
+#if 0
+__halt();
+#endif
+}
+
+static char * ireg_name[] = {"v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
+ "t7", "s0", "s1", "s2", "s3", "s4", "s5", "s6",
+ "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
+ "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
+
+static char * inst_name[] = {"call_pal", "", "", "", "", "", "", "",
+ "lda", "ldah", "ldbu", "ldq_u", "ldwu", "stw", "stb", "stq_u",
+ "ALU", "ALU", "ALU", "ALU", "SQRT", "FVAX", "FIEEE", "FLOAT",
+ "MISC", "PAL19", "JMP", "PAL1B", "GRAPH", "PAL1D", "PAL1E", "PAL1F",
+ "ldf", "ldg", "lds", "ldt", "stf", "stg", "sts", "stt",
+ "ldl", "ldq", "ldl_l", "ldq_l", "stl", "stq", "stl_c", "stq_c",
+ "br", "fbeq", "fblt", "fble", "bsr", "fbne", "fbge", "fbgt"
+ "blbc", "beq", "blt", "ble", "blbs", "bne", "bge", "bgt"
+};
+
+static char * jump_name[] = {"jmp", "jsr", "ret", "jsr_coroutine"};
+
+typedef struct {int func; char * text;} alist;
+
+static alist inta_name[] = {{0, "addl"}, {2, "s4addl"}, {9, "subl"},
+ {0xb, "s4subl"}, {0xf, "cmpbge"}, {0x12, "s8addl"}, {0x1b, "s8subl"},
+ {0x1d, "cmpult"}, {0x20, "addq"}, {0x22, "s4addq"}, {0x29, "subq"},
+ {0x2b, "s4subq"}, {0x2d, "cmpeq"}, {0x32, "s8addq"}, {0x3b, "s8subq"},
+ {0x3d, "cmpule"}, {0x40, "addl/v"}, {0x49, "subl/v"}, {0x4d, "cmplt"},
+ {0x60, "addq/v"}, {0x69, "subq/v"}, {0x6d, "cmple"}, {-1, 0}};
+
+static alist intl_name[] = {{0, "and"}, {8, "andnot"}, {0x14, "cmovlbs"},
+ {0x16, "cmovlbc"}, {0x20, "or"}, {0x24, "cmoveq"}, {0x26, "cmovne"},
+ {0x28, "ornot"}, {0x40, "xor"}, {0x44, "cmovlt"}, {0x46, "cmovge"},
+ {0x48, "eqv"}, {0x61, "amask"}, {0x64, "cmovle"}, {0x66, "cmovgt"},
+ {0x6c, "implver"}, {-1, 0}};
+
+static alist ints_name[] = {{2, "mskbl"}, {6, "extbl"}, {0xb, "insbl"},
+ {0x12, "mskwl"}, {0x16, "extwl"}, {0x1b, "inswl"}, {0x22, "mskll"},
+ {0x26, "extll"}, {0x2b, "insll"}, {0x30, "zap"}, {0x31, "zapnot"},
+ {0x32, "mskql"}, {0x34, "srl"}, {0x36, "extql"}, {0x39, "sll"},
+ {0x3b, "insql"}, {0x3c, "sra"}, {0x52, "mskwh"}, {0x57, "inswh"},
+ {0x5a, "extwh"}, {0x62, "msklh"}, {0x67, "inslh"}, {0x6a, "extlh"},
+ {0x72, "mskqh"}, {0x77, "insqh"}, {0x7a, "extqh"}, {-1, 0}};
+
+static alist intm_name[] = {{0, "mull"}, {0x20, "mulq"}, {0x30, "umulh"},
+ {0x40, "mull/v"}, {0x60, "mulq/v"}, {-1, 0}};
+
+static alist * int_name[] = {inta_name, intl_name, ints_name, intm_name};
+
+static char *
+assoc(int fcode, alist * a)
+{
+ while ((fcode != a->func) && (a->func != -1))
+ ++a;
+ return a->text;
+}
+
+static char *
+iname(unsigned int instr)
+{
+ int opcode = instr >> 26;
+ char * name = inst_name[opcode];
+
+ switch (opcode) {
+ default:
+ break;
+
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13: {
+ char * specific_name
+ = assoc((instr >> 5) & 0x3f, int_name[opcode - 0x10]);
+ if (specific_name)
+ name = specific_name;
+ break;
+ }
+
+ case 0x1a:
+ name = jump_name[(instr >> 14) & 3];
+ break;
+ }
+
+ return name;
+}
+
+static enum {NOT_INST, PAL, BRANCH, MEMORY, JUMP, OPERATE, FOPERATE, MISC}
+iformat(int opcode)
+{
+ if (opcode >= 0x30)
+ return BRANCH;
+ if (opcode >= 0x20)
+ return MEMORY;
+ if (opcode == 0)
+ return PAL;
+ if (opcode < 8)
+ return NOT_INST;
+ if (opcode < 0x10)
+ return MEMORY;
+ if (opcode < 0x14)
+ return OPERATE;
+ if (opcode < 0x18)
+ return FOPERATE;
+ switch (opcode) {
+ case 0x18:
+ return MISC;
+ case 0x1A:
+ return JUMP;
+ case 0x1C:
+ return OPERATE;
+ default:
+ return NOT_INST;
+ }
+}
+
+/*
+ * The purpose here is to provide useful clues about a kernel crash, so
+ * less likely instructions, e.g. floating point, aren't fully decoded.
+ */
+static void
+disassemble(unsigned int instr)
+{
+ int optype = instr >> 26;
+ char buf[40], *s = buf;
+
+ s += sprintf(buf, "%08x %s ", instr, iname(instr));
+ switch (iformat(optype)) {
+ default:
+ case NOT_INST:
+ case MISC:
+ break;
+
+ case PAL:
+ s += sprintf(s, "%d", instr);
+ break;
+
+ case BRANCH: {
+ int reg = (instr >> 21) & 0x1f;
+ int offset = instr & 0x1fffff;
+
+ if (offset >= 0x100000)
+ offset -= 0x200000;
+ if (((optype & 3) == 0) || (optype >= 0x38)) {
+ if ((optype != 0x30) || (reg != 0x1f))
+ s += sprintf(s, "%s,", ireg_name[reg]);
+ } else
+ s += sprintf(s, "f%d,", reg);
+ s += sprintf(s, ".%+d", (offset + 1) << 2);
+ break;
+ }
+
+ case MEMORY: {
+ int addr_reg = (instr >> 16) & 0x1f;
+ int value_reg = (instr >> 21) & 0x1f;
+ int offset = instr & 0xffff;
+
+ if (offset >= 0x8000)
+ offset -= 0x10000;
+ if ((optype >= 0x20) && (optype < 0x28))
+ s += sprintf(s, "f%d", value_reg);
+ else
+ s += sprintf(s, "%s", ireg_name[value_reg]);
+
+ s += sprintf(s, ",%d(%s)", offset, ireg_name[addr_reg]);
+ break;
+ }
+
+ case JUMP: {
+ int target_reg = (instr >> 16) & 0x1f;
+ int return_reg = (instr >> 21) & 0x1f;
+
+ s += sprintf(s, "%s,", ireg_name[return_reg]);
+ s += sprintf(s, "(%s)", ireg_name[target_reg]);
+ break;
+ }
+
+ case OPERATE: {
+ int areg = (instr >> 21) & 0x1f;
+ int breg = (instr >> 16) & 0x1f;
+ int creg = instr & 0x1f;
+ int litflag = instr & (1<<12);
+ int lit = (instr >> 13) & 0xff;
+
+ s += sprintf(s, "%s,", ireg_name[areg]);
+ if (litflag)
+ s += sprintf(s, "%d", lit);
+ else
+ s += sprintf(s, "%s", ireg_name[breg]);
+ s += sprintf(s, ",%s", ireg_name[creg]);
+ break;
+ }
+
+ case FOPERATE: {
+ int areg = (instr >> 21) & 0x1f;
+ int breg = (instr >> 16) & 0x1f;
+ int creg = instr & 0x1f;
+
+ s += sprintf(s, "f%d,f%d,f%d", areg, breg, creg);
+ break;
+ }
+ }
+ buf[s-buf] = 0;
+ printk("%s\n", buf);
}
static void
@@ -59,11 +263,12 @@ dik_show_code(unsigned int *pc)
long i;
printk("Code:");
- for (i = -3; i < 6; i++) {
+ for (i = -6; i < 2; i++) {
unsigned int insn;
if (__get_user(insn, pc+i))
break;
- printk("%c%08x%c",i?' ':'<',insn,i?' ':'>');
+ printk("%c", i ? ' ' : '*');
+ disassemble(insn);
}
printk("\n");
}
@@ -81,8 +286,12 @@ dik_show_trace(unsigned long *sp)
continue;
if (tmp >= (unsigned long) &_etext)
continue;
- printk(" [<%lx>]", tmp);
- if (++i > 40) {
+ /*
+ * Assume that only the low 24-bits of a kernel text address
+ * is interesting.
+ */
+ printk("%6x%c", (int)tmp & 0xffffff, (++i % 11) ? ' ' : '\n');
+ if (i > 40) {
printk(" ...");
break;
}
@@ -450,7 +659,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
got_exception:
/* Ok, we caught the exception, but we don't want it. Is there
someone to pass it along to? */
- if ((fixup = search_exception_table(pc)) != 0) {
+ if ((fixup = search_exception_table(pc, regs.gp)) != 0) {
unsigned long newpc;
newpc = fixup_exception(una_reg, fixup, pc);
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index 52571557b50888..b6cf88e3d4f73d 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -2,13 +2,18 @@
# Makefile for alpha-specific library files..
#
+.S.s:
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $<
+.S.o:
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $<
+
OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
checksum.o csum_partial_copy.o strlen.o \
strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
strchr.o strrchr.o memchr.o \
copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
csum_ipv6_magic.o strcasecmp.o semaphore.o fpreg.o \
- srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
+ callback_srm.o callback_init.o srm_puts.o srm_printk.o
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
diff --git a/arch/alpha/lib/callback_init.c b/arch/alpha/lib/callback_init.c
new file mode 100644
index 00000000000000..fe643ccfc59fb9
--- /dev/null
+++ b/arch/alpha/lib/callback_init.c
@@ -0,0 +1,79 @@
+#include <linux/init.h>
+#include <linux/sched.h>
+
+#include <asm/page.h>
+#include <asm/hwrpb.h>
+#include <asm/console.h>
+#include <asm/pgtable.h>
+
+#include "../kernel/proto.h"
+
+extern struct hwrpb_struct *hwrpb;
+
+/* This is the SRM version. Maybe there will be a DBM version. */
+
+int callback_init_done = 0;
+
+void * __init callback_init(void * kernel_end)
+{
+ int i, j;
+ unsigned long vaddr = CONSOLE_REMAP_START;
+ struct crb_struct * crb;
+ pgd_t * pgd = pgd_offset_k(vaddr);
+ pmd_t * pmd;
+ unsigned long two_pte_pages;
+
+ if (!alpha_using_srm) {
+ switch_to_system_map();
+ return kernel_end;
+ }
+
+ /* Allocate some memory for the pages. */
+ two_pte_pages = ((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK;
+ kernel_end = (void *)(two_pte_pages + 2*PAGE_SIZE);
+ memset((void *)two_pte_pages, 0, 2*PAGE_SIZE);
+
+ /* Starting at the HWRPB, locate the CRB. */
+ crb = (struct crb_struct *)((char *)hwrpb + hwrpb->crb_offset);
+
+ /* Tell the console whither the console is to be remapped. */
+ if (srm_fixup(vaddr, (unsigned long)hwrpb))
+ __halt(); /* "We're boned." --Bender */
+
+ /* Edit the procedure descriptors for DISPATCH and FIXUP. */
+ crb->dispatch_va = (struct procdesc_struct *)
+ (vaddr + (unsigned long)crb->dispatch_va - crb->map[0].va);
+ crb->fixup_va = (struct procdesc_struct *)
+ (vaddr + (unsigned long)crb->fixup_va - crb->map[0].va);
+
+ switch_to_system_map();
+
+ /*
+ * Set up the first and second level PTEs for console callbacks.
+ * There is an assumption here that only one of each is needed,
+ * and this allows for 8MB. Currently (late 1999), big consoles
+ * are still under 4MB.
+ */
+ pgd_set(pgd, (pmd_t *)two_pte_pages);
+ pmd = pmd_offset(pgd, vaddr);
+ pmd_set(pmd, (pte_t *)(two_pte_pages + PAGE_SIZE));
+
+ /*
+ * Set up the third level PTEs and update the virtual addresses
+ * of the CRB entries.
+ */
+ for (i = 0; i < crb->map_entries; ++i) {
+ unsigned long paddr = crb->map[i].pa;
+ crb->map[i].va = vaddr;
+ for (j = 0; j < crb->map[i].count; ++j) {
+ set_pte(pte_offset(pmd, vaddr),
+ mk_pte_phys(paddr, PAGE_KERNEL));
+ paddr += PAGE_SIZE;
+ vaddr += PAGE_SIZE;
+ }
+ }
+
+ callback_init_done = 1;
+ return kernel_end;
+}
+
diff --git a/arch/alpha/lib/callback_srm.S b/arch/alpha/lib/callback_srm.S
new file mode 100644
index 00000000000000..de2edebb1b24d6
--- /dev/null
+++ b/arch/alpha/lib/callback_srm.S
@@ -0,0 +1,102 @@
+/*
+ * arch/alpha/lib/callback_srm.S
+ */
+
+#include <linux/config.h>
+#include <asm/console.h>
+
+.text
+#define HWRPB_CRB_OFFSET 0xc0
+
+#if defined(CONFIG_ALPHA_SRM) || defined(CONFIG_ALPHA_GENERIC)
+.align 4
+srm_dispatch:
+#if defined(CONFIG_ALPHA_GENERIC)
+ ldl $4,alpha_using_srm
+ beq $4,nosrm
+#endif
+ ldq $0,hwrpb # gp is set up by CALLBACK macro.
+ ldl $25,0($25) # Pick up the wrapper data.
+ mov $20,$21 # Shift arguments right.
+ mov $19,$20
+ ldq $1,HWRPB_CRB_OFFSET($0)
+ mov $18,$19
+ mov $17,$18
+ mov $16,$17
+ addq $0,$1,$2 # CRB address
+ ldq $27,0($2) # DISPATCH procedure descriptor (VMS call std)
+ extwl $25,0,$16 # SRM callback function code
+ ldq $3,8($27) # call address
+ extwl $25,2,$25 # argument information (VMS calling std)
+ jmp ($3) # Return directly to caller of wrapper.
+
+.align 4
+.globl srm_fixup
+.ent srm_fixup
+srm_fixup:
+ ldgp $29,0($27)
+#if defined(CONFIG_ALPHA_GENERIC)
+ ldl $4,alpha_using_srm
+ beq $4,nosrm
+#endif
+ ldq $0,hwrpb
+ ldq $1,HWRPB_CRB_OFFSET($0)
+ addq $0,$1,$2 # CRB address
+ ldq $27,16($2) # VA of FIXUP procedure descriptor
+ ldq $3,8($27) # call address
+ lda $25,2($31) # two integer arguments
+ jmp ($3) # Return directly to caller of srm_fixup.
+.end srm_fixup
+
+#if defined(CONFIG_ALPHA_GENERIC)
+.align 3
+nosrm:
+ lda $0,-1($31)
+ ret
+#endif
+
+#define CALLBACK(NAME, CODE, ARG_CNT) \
+.align 4; .globl callback_##NAME; .ent callback_##NAME; callback_##NAME##: \
+ldgp $29,0($27); br $25,srm_dispatch; .word CODE, ARG_CNT; .end callback_##NAME
+
+#else /* defined(CONFIG_ALPHA_SRM) || defined(CONFIG_ALPHA_GENERIC) */
+
+#define CALLBACK(NAME, CODE, ARG_CNT) \
+.align 3; .globl callback_##NAME; .ent callback_##NAME; callback_##NAME##: \
+lda $0,-1($31); ret; .end callback_##NAME
+
+.align 3
+.globl srm_fixup
+.ent srm_fixup
+srm_fixup:
+ lda $0,-1($31)
+ ret
+.end srm_fixup
+#endif /* defined(CONFIG_ALPHA_SRM) || defined(CONFIG_ALPHA_GENERIC) */
+
+CALLBACK(puts, CCB_PUTS, 4)
+CALLBACK(open, CCB_OPEN, 3)
+CALLBACK(close, CCB_CLOSE, 2)
+CALLBACK(read, CCB_READ, 5)
+CALLBACK(getenv, CCB_GET_ENV, 4)
+CALLBACK(setenv, CCB_SET_ENV, 4)
+CALLBACK(getc, CCB_GETC, 2)
+CALLBACK(reset_term, CCB_RESET_TERM, 2)
+CALLBACK(term_int, CCB_SET_TERM_INT, 3)
+CALLBACK(term_ctl, CCB_SET_TERM_CTL, 3)
+CALLBACK(process_keycode, CCB_PROCESS_KEYCODE, 3)
+CALLBACK(ioctl, CCB_IOCTL, 6)
+CALLBACK(write, CCB_WRITE, 5)
+CALLBACK(reset_env, CCB_RESET_ENV, 4)
+CALLBACK(save_env, CCB_SAVE_ENV, 1)
+CALLBACK(pswitch, CCB_PSWITCH, 3)
+CALLBACK(bios_emul, CCB_BIOS_EMUL, 5)
+
+.data
+__alpha_using_srm: # For use by bootpheader
+ .long 7 # value is not 1 for link debugging
+ .weak alpha_using_srm; alpha_using_srm = __alpha_using_srm
+__callback_init_done: # For use by bootpheader
+ .long 7 # value is not 1 for link debugging
+ .weak callback_init_done; callback_init_done = __callback_init_done
+
diff --git a/arch/alpha/lib/srm_dispatch.S b/arch/alpha/lib/srm_dispatch.S
deleted file mode 100644
index 2bcea3073aae88..00000000000000
--- a/arch/alpha/lib/srm_dispatch.S
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * arch/alpha/lib/srm_dispatch.S
- */
-
-.globl srm_dispatch
-.ent srm_dispatch
-srm_dispatch:
- .frame $30,30,$26
- subq $30,80,$30
- stq $26,0($30)
- stq $8,8($30)
- stq $9,16($30)
- stq $10,24($30)
- stq $11,32($30)
- stq $12,40($30)
- stq $13,48($30)
- stq $14,56($30)
- stq $15,64($30)
- stq $29,72($30)
- .mask 0x2400FF00, -80
- .prologue 0
-
- ldq $1,hwrpb
- ldq $2,0xc0($1) /* crb offset */
- addq $2,$1,$2 /* crb */
- ldq $27,0($2) /* dispatch procedure value */
-
- ldq $2,8($27) /* dispatch call address */
- jsr $26,($2) /* call it (weird VMS call seq) */
-
- ldq $26,0($30)
- ldq $8,8($30)
- ldq $9,16($30)
- ldq $10,24($30)
- ldq $11,32($30)
- ldq $12,40($30)
- ldq $13,48($30)
- ldq $14,56($30)
- ldq $15,64($30)
- ldq $29,72($30)
- addq $30,80,$30
- ret $31,($26),1
-.end srm_dispatch
diff --git a/arch/alpha/lib/srm_fixup.S b/arch/alpha/lib/srm_fixup.S
deleted file mode 100644
index 9cf2d78c294f71..00000000000000
--- a/arch/alpha/lib/srm_fixup.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * arch/alpha/lib/srm_fixup.S
- */
-
-.globl srm_fixup
-.ent srm_fixup
-srm_fixup:
- .frame $30,30,$26
- subq $30,80,$30
- stq $26,0($30)
- stq $8,8($30)
- stq $9,16($30)
- stq $10,24($30)
- stq $11,32($30)
- stq $12,40($30)
- stq $13,48($30)
- stq $14,56($30)
- stq $15,64($30)
- stq $29,72($30)
- .mask 0x2400FF00, -80
- .prologue 0
-
- ldq $2,0xc0($17) /* crb offset */
- addq $2,$1,$2 /* crb */
- ldq $27,16($2) /* fixup procedure value */
-
- ldq $2,8($27) /* dispatch call address */
- jsr $26,($2) /* call it (weird VMS call seq) */
-
- ldq $26,0($30)
- ldq $8,8($30)
- ldq $9,16($30)
- ldq $10,24($30)
- ldq $11,32($30)
- ldq $12,40($30)
- ldq $13,48($30)
- ldq $14,56($30)
- ldq $15,64($30)
- ldq $29,72($30)
- addq $30,80,$30
- ret $31,($26),1
-.end srm_fixup
diff --git a/arch/alpha/lib/srm_printk.c b/arch/alpha/lib/srm_printk.c
index b5baee15ffd21c..31b53c49435ec2 100644
--- a/arch/alpha/lib/srm_printk.c
+++ b/arch/alpha/lib/srm_printk.c
@@ -9,13 +9,33 @@ long
srm_printk(const char *fmt, ...)
{
static char buf[1024];
- va_list args;
- long i;
+ va_list args;
+ long len, num_lf;
+ char *src, *dst;
- va_start(args, fmt);
- i = vsprintf(buf,fmt,args);
- va_end(args);
+ va_start(args, fmt);
+ len = vsprintf(buf, fmt, args);
+ va_end(args);
- srm_puts(buf);
- return i;
+ /* count number of linefeeds in string: */
+
+ num_lf = 0;
+ for (src = buf; *src; ++src) {
+ if (*src == '\n') {
+ ++num_lf;
+ }
+ }
+
+ if (num_lf) {
+ /* expand each linefeed into carriage-return/linefeed: */
+ for (dst = src + num_lf; src >= buf; ) {
+ if (*src == '\n') {
+ *dst-- = '\r';
+ }
+ *dst-- = *src--;
+ }
+ }
+
+ srm_puts(buf, num_lf+len);
+ return len;
}
diff --git a/arch/alpha/lib/srm_puts.c b/arch/alpha/lib/srm_puts.c
index 87b1d11559a461..7b60a6f75a786a 100644
--- a/arch/alpha/lib/srm_puts.c
+++ b/arch/alpha/lib/srm_puts.c
@@ -5,30 +5,19 @@
#include <linux/string.h>
#include <asm/console.h>
-void
-srm_puts(const char *str)
+long
+srm_puts(const char *str, long len)
{
- /* Expand \n to \r\n as we go. */
+ long remaining, written;
- while (*str) {
- long len;
- const char *e = str;
+ if (!callback_init_done)
+ return len;
- if (*str == '\n') {
- if (srm_dispatch(CCB_PUTS, 0, "\r", 1) < 0)
- return;
- ++e;
- }
-
- e = strchr(e, '\n') ? : strchr(e, '\0');
- len = e - str;
-
- while (len > 0) {
- long written = srm_dispatch(CCB_PUTS, 0, str, len);
- if (written < 0)
- return;
- len -= written & 0xffffffff;
- str += written & 0xffffffff;
- }
+ for (remaining = len; remaining > 0; remaining -= written)
+ {
+ written = callback_puts(0, str, remaining);
+ written &= 0xffffffff;
+ str += written;
}
+ return len;
}
diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c
index 12a1f4803fd1f4..d3a02fe272e026 100644
--- a/arch/alpha/mm/extable.c
+++ b/arch/alpha/mm/extable.c
@@ -36,12 +36,12 @@ search_one_table(const struct exception_table_entry *first,
register unsigned long gp __asm__("$29");
-unsigned
-search_exception_table(unsigned long addr)
+static unsigned
+search_exception_table_without_gp(unsigned long addr)
{
unsigned ret;
-#ifndef CONFIG_MODULE
+#ifndef CONFIG_MODULES
/* There is only the kernel to search. */
ret = search_one_table(__start___ex_table, __stop___ex_table - 1,
addr - gp);
@@ -60,3 +60,39 @@ search_exception_table(unsigned long addr)
return 0;
}
+
+unsigned
+search_exception_table(unsigned long addr, unsigned long exc_gp)
+{
+ unsigned ret;
+
+#ifndef CONFIG_MODULES
+ ret = search_one_table(__start___ex_table, __stop___ex_table - 1,
+ addr - exc_gp);
+ if (ret) return ret;
+#else
+ /* The kernel is the last "module" -- no need to treat it special. */
+ struct module *mp;
+ for (mp = module_list; mp ; mp = mp->next) {
+ if (!mp->ex_table_start)
+ continue;
+ ret = search_one_table(mp->ex_table_start,
+ mp->ex_table_end - 1, addr - exc_gp);
+ if (ret) return ret;
+ }
+#endif
+
+ /*
+ * The search failed with the exception gp. To be safe, try the
+ * old method before giving up.
+ */
+ ret = search_exception_table_without_gp(addr);
+ if (ret) {
+ printk(KERN_ALERT, "%s: [%lx] EX_TABLE search fail with"
+ "exc frame GP, success with raw GP\n",
+ current->comm, addr);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 1639972db22e7b..bf4839b8f8c8e8 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -164,11 +164,13 @@ bad_area:
no_context:
/* Are we prepared to handle this fault as an exception? */
- if ((fixup = search_exception_table(regs->pc)) != 0) {
+ if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) {
unsigned long newpc;
newpc = fixup_exception(dpf_reg, fixup, regs->pc);
- printk("%s: Exception at [<%lx>] (%lx)\n",
+#if 1
+ printk("%s: Exception at [<%lx>] (%lx) handled successfully\n",
current->comm, regs->pc, newpc);
+#endif
regs->pc = newpc;
return;
}
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 2cbe9bb0f23f8c..84b608f4518e4d 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -182,43 +182,15 @@ load_PCB(struct thread_struct * pcb)
return __reload_thread(pcb);
}
-/*
- * paging_init() sets up the page tables: in the alpha version this actually
- * unmaps the bootup page table (as we're now in KSEG, so we don't need it).
- */
+/* switch_to_system_map() sets up some necessary page tables. */
void
-paging_init(void)
+switch_to_system_map(void)
{
unsigned long newptbr;
unsigned long original_pcb_ptr;
- unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
- unsigned long dma_pfn, high_pfn;
-
- dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- high_pfn = max_low_pfn;
-
-#define ORDER_MASK (~((1 << (MAX_ORDER-1))-1))
-#define ORDER_ALIGN(n) (((n) + ~ORDER_MASK) & ORDER_MASK)
-
- dma_pfn = ORDER_ALIGN(dma_pfn);
- high_pfn = ORDER_ALIGN(high_pfn);
-
-#undef ORDER_MASK
-#undef ORDER_ALIGN
-
- if (dma_pfn > high_pfn)
- zones_size[ZONE_DMA] = high_pfn;
- else {
- zones_size[ZONE_DMA] = dma_pfn;
- zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
- }
-
- /* Initialize mem_map[]. */
- free_area_init(zones_size);
/* Initialize the kernel's page tables. Linux puts the vptb in
the last slot of the L1 page table. */
- memset((void *)ZERO_PGE, 0, PAGE_SIZE);
memset(swapper_pg_dir, 0, PAGE_SIZE);
newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
pgd_val(swapper_pg_dir[1023]) =
@@ -253,6 +225,41 @@ paging_init(void)
original_pcb = *(struct thread_struct *) original_pcb_ptr;
}
+/*
+ * paging_init() sets up the memory map.
+ */
+void
+paging_init(void)
+{
+ unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long dma_pfn, high_pfn;
+
+ dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ high_pfn = max_low_pfn;
+
+#define ORDER_MASK (~((1L << (MAX_ORDER-1))-1))
+#define ORDER_ALIGN(n) (((n) + ~ORDER_MASK) & ORDER_MASK)
+
+ dma_pfn = ORDER_ALIGN(dma_pfn);
+ high_pfn = ORDER_ALIGN(high_pfn);
+
+#undef ORDER_MASK
+#undef ORDER_ALIGN
+
+ if (dma_pfn > high_pfn)
+ zones_size[ZONE_DMA] = high_pfn;
+ else {
+ zones_size[ZONE_DMA] = dma_pfn;
+ zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
+ }
+
+ /* Initialize mem_map[]. */
+ free_area_init(zones_size);
+
+ /* Initialize the kernel's ZERO_PGE. */
+ memset((void *)ZERO_PGE, 0, PAGE_SIZE);
+}
+
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
void
srm_paging_stop (void)
diff --git a/arch/alpha/vmlinux.lds b/arch/alpha/vmlinux.lds
index 4eaac4e42f1790..f64a926b614951 100644
--- a/arch/alpha/vmlinux.lds
+++ b/arch/alpha/vmlinux.lds
@@ -2,7 +2,7 @@ OUTPUT_FORMAT("elf64-alpha")
ENTRY(__start)
SECTIONS
{
- . = 0xfffffc0000310000;
+ . = 0xfffffc0000810000;
_text = .;
.text : { *(.text) }
_etext = .;
@@ -50,9 +50,11 @@ SECTIONS
.got : { *(.got) }
.sdata : { *(.sdata) }
_edata = .;
- _bss = .;
+
+ __bss_start = .;
.sbss : { *(.sbss) *(.scommon) }
.bss : { *(.bss) *(COMMON) }
+ __bss_stop = .;
_end = .;
.mdebug 0 : { *(.mdebug) }
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index b49cebfded6b96..9f2e5347a94426 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -19,7 +19,7 @@ ARCHCC := $(word 1,$(CC))
AFLAGS += -mno-fpu
CFLAGS_PIPE := -pipe
-CFLAGS := $(CFLAGS) $(CFLAGS_PIPE)
+CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) -msoft-float
ifdef CONFIG_FRAME_POINTER
CFLAGS := $(CFLAGS:-fomit-frame-pointer=)
@@ -29,11 +29,13 @@ ifdef CONFIG_DEBUG_INFO
CFLAGS += -g
endif
+GZFLAGS = -9
+
# Ensure this is ld "2.9.4" or later
NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi)
ifneq ($(NEW_LINKER),y)
-dummy:; @echo '*** 2.3 kernels no longer build correctly with old versions of binutils.'
+dummy:; @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.'
@echo '*** Please upgrade your binutils to 2.9.5.'
@false
endif
@@ -45,7 +47,7 @@ NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then ech
# select flags depending on the compiler
#
ifeq ($(NEW_GCC),y)
-CFLAGS += -mshort-load-bytes -msoft-float
+CFLAGS += -mshort-load-bytes
CFLAGS_PROC_CPU_26 := -mcpu=arm3 -Os
CFLAGS_PROC_CPU_32v3 := -march=armv3
CFLAGS_PROC_CPU_32v4 := -march=armv4
@@ -110,7 +112,7 @@ endif
LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
-export LIBGCC MACHINE PROCESSOR TEXTADDR
+export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
ifeq ($(CONFIG_ARCH_A5K),y)
MACHINE = a5k
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 632126213ad696..f8ff4124c52cd6 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -89,7 +89,7 @@ $(HEAD): $(HEAD:.o=.S)
piggy.o: $(SYSTEM)
$(OBJCOPY) $(SYSTEM) piggy
- gzip -9 < piggy > piggy.gz
+ gzip $(GZFLAGS) < piggy > piggy.gz
$(LD) -r -o $@ -b binary piggy.gz
rm -f piggy piggy.gz
diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S
index 411a210cfbf454..7b12ecef6d682c 100644
--- a/arch/arm/boot/compressed/head-sa1100.S
+++ b/arch/arm/boot/compressed/head-sa1100.S
@@ -133,6 +133,5 @@ UART1_BASE: .long 0x80010000
#endif
@ Restore initial r0/r1
- @ (r8 preserved)
mov r0, r8
mov r1, r9
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 2c329295d1c72e..10c2290a00fb9b 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -84,9 +84,7 @@ start:
b 1f
.word 0x016f2818 @ Magic numbers to help the loader
.word start
-1: adr r8, start @ get the start address of the code
- @ (used for locating the page tables)
-
+1:
/*
* some architecture specific code can be inserted
* by the linker here, but it should preserve r0, r1
@@ -178,9 +176,13 @@ LC0: .word __bss_start
.align 5
cache_on: ldr r1, proc_sa110_type
eor r1, r1, r6
- movs r1, r1, lsr #5
+ movs r1, r1, lsr #5 @ catch SA110 and SA1100
+ beq 1f
+ ldr r1, proc_sa1110_type
+ eor r1, r1, r6
+ movs r1, r1, lsr #4
movne pc, lr
-
+1:
sub r3, r4, #16384 @ Page directory size
bic r3, r3, #0xff @ Align the pointer
bic r3, r3, #0x3f
@@ -259,6 +261,11 @@ proc_sa110_type:
.word 0x4401a100
.size proc_sa110_type, . - proc_sa110_type
+ .type proc_sa1110_type,#object
+proc_sa1110_type:
+ .word 0x6901b110
+ .size proc_sa1110_type, . - proc_sa1110_type
+
/*
* Turn off StrongARM cache and MMU. It is safe to
* leave the I-cache on.
@@ -273,8 +280,13 @@ proc_sa110_type:
.align 5
cache_off: ldr r1, proc_sa110_type
eor r1, r1, r6
- movs r1, r1, lsr #5
+ movs r1, r1, lsr #5 @ catch SA110 and SA1100
+ beq 1f
+ ldr r1, proc_sa1110_type
+ eor r1, r1, r6
+ movs r1, r1, lsr #4
movne pc, lr
+1:
mrc p15, 0, r0, c1, c0
bic r0, r0, #0x000d
mcr p15, 0, r0, c1, c0
@@ -292,11 +304,15 @@ cache_off: ldr r1, proc_sa110_type
*/
.align 5
cache_clean_flush:
- ldr r1, proc_sa110_type @ SA-110 or SA-1100?
+ ldr r1, proc_sa110_type
+ eor r1, r1, r6
+ movs r1, r1, lsr #5 @ catch SA110 and SA1100
+ beq 1f
+ ldr r1, proc_sa1110_type
eor r1, r1, r6
- movs r1, r1, lsr #5
+ movs r1, r1, lsr #4
movne pc, lr
-
+1:
bic r1, pc, #31
add r2, r1, #32768
1: ldr r12, [r1], #32 @ s/w flush D cache
diff --git a/arch/arm/config.in b/arch/arm/config.in
index 911703fe146b30..ff683b30bfa3c3 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -1,57 +1,50 @@
#
# For a description of the syntax of this configuration file,
-# see the Configure script.
+# see Documentation/kbuild/config-language.txt.
#
mainmenu_name "Linux Kernel Configuration"
define_bool CONFIG_ARM y
-
+define_bool CONFIG_SBUS n
define_bool CONFIG_UID16 y
+
mainmenu_option next_comment
comment 'Code maturity level options'
bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
+
mainmenu_option next_comment
-comment 'System and Processor Type'
+comment 'System Type'
choice 'ARM system type' \
"Archimedes CONFIG_ARCH_ARC \
A5000 CONFIG_ARCH_A5K \
- RiscPC CONFIG_ARCH_RPC \
+ Co-EBSA285 CONFIG_ARCH_CO285 \
EBSA-110 CONFIG_ARCH_EBSA110 \
- FootBridge-based CONFIG_FOOTBRIDGE" RiscPC
+ FootBridge CONFIG_ARCH_FOOTBRIDGE \
+ RiscPC CONFIG_ARCH_RPC \
+ SA1100-based CONFIG_ARCH_SA1100" RiscPC
+
# the following are placeholders for when they are fully integrated
+# Cirrus CL-PS7500FE CONFIG_ARCH_CLPS7500 \
# LinkUp-L7200 CONFIG_ARCH_L7200
-# SA1100-based CONFIG_ARCH_SA1100
-if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
- bool 'FootBridge in HOST mode' CONFIG_HOST_FOOTBRIDGE
- if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
- define_bool CONFIG_ADDIN_FOOTBRIDGE n
- else
- define_bool CONFIG_ADDIN_FOOTBRIDGE y
- fi
-fi
-
-if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
+if [ "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then
comment 'Footbridge Implementations'
- bool ' Include support for EBSA285' CONFIG_ARCH_EBSA285
- bool ' Include support for CATS' CONFIG_ARCH_CATS
- bool ' Include support for NetWinder' CONFIG_ARCH_NETWINDER
- bool ' Include support for Compaq Personal Server' CONFIG_ARCH_PERSONAL_SERVER
-fi
-
-if [ "$CONFIG_ADDIN_FOOTBRIDGE" = "y" ]; then
- # If we get any other footbridge-based plug-in boards, then
- # add your architecture options here
- define_bool CONFIG_ARCH_CO285 y
+ bool ' CATS support' CONFIG_ARCH_CATS
+ bool ' Compaq Personal Server support' CONFIG_ARCH_PERSONAL_SERVER
+ bool ' EBSA285 (addin mode) support' CONFIG_ARCH_EBSA285_ADDIN
+ bool ' EBSA285 (host mode) support' CONFIG_ARCH_EBSA285_HOST
+ bool ' NetWinder support' CONFIG_ARCH_NETWINDER
fi
-
if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
comment 'SA11x0 Implementations'
- bool ' Include support for Assabet' CONFIG_SA110_ASSABET
+ bool ' Include support for Assabet' CONFIG_SA1100_ASSABET
+ if [ "$CONFIG_SA1100_ASSABET" = "y" ]; then
+ bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET
+ fi
bool ' Include support for Bitsy' CONFIG_SA1100_BITSY
bool ' Include support for Brutus' CONFIG_SA1100_BRUTUS
# bool ' Include support for Empeg' CONFIG_SA1100_EMPEG
@@ -62,43 +55,21 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
bool ' Include support for GraphicsClient' CONFIG_SA1100_GRAPHICSCLIENT
bool ' Include support for Victor' CONFIG_SA1100_VICTOR
# bool ' Include support for Tifon' CONFIG_SA1100_TIFON
- define_bool CONFIG_DISCONTIGMEM y
+# bool ' Include support for XP860' CONFIG_SA1100_XP860
fi
-#
-# Select various configuration options depending on the machine type
-# Easy check for Acorn-style architectures
-#
-if [ "$CONFIG_ARCH_ARC" = "y" -o \
- "$CONFIG_ARCH_A5K" = "y" -o \
- "$CONFIG_ARCH_RPC" = "y" ]; then
- define_bool CONFIG_ARCH_ACORN y
-else
- define_bool CONFIG_ARCH_ACORN n
-fi
-
-#
-# Figure out whether this system uses 26-bit or 32-bit CPUs. Nobody has
-# ever built a machine that can take both, and now that ARM3 is obsolete
-# nobody is likely to either.
-#
+# Figure out whether this system uses 26-bit or 32-bit CPUs.
if [ "$CONFIG_ARCH_ARC" = "y" -o \
"$CONFIG_ARCH_A5K" = "y" ]; then
define_bool CONFIG_CPU_32 n
define_bool CONFIG_CPU_26 y
-
- #
- # Select memory size
- #
bool '2MB physical memory' CONFIG_PAGESIZE_16
else
define_bool CONFIG_CPU_32 y
define_bool CONFIG_CPU_26 n
fi
-#
# Select CPU and optimisation dependent on architecture
-#
if [ "$CONFIG_ARCH_RPC" = "y" ]; then
define_bool CONFIG_CPU_32v3 y
bool 'Support ARM610' CONFIG_CPU_ARM6
@@ -113,6 +84,10 @@ if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
define_bool CONFIG_CPU_32v4 y
define_bool CONFIG_CPU_SA110 y
fi
+if [ "$CONFIG_ARCH_CLPS7500" = "y" ]; then
+ define_bool CONFIG_CPU_32v4 y
+ define_bool CONFIG_CPU_ARM7 y
+fi
if [ "$CONFIG_ARCH_L7200" = "y" ]; then
define_bool CONFIG_CPU_32v4 y
define_bool CONFIG_CPU_ARM720 y
@@ -122,20 +97,54 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
define_bool CONFIG_CPU_SA1100 y
fi
-#
-# These machines always have PCI
-#
+# Select various configuration options depending on the machine type
+if [ "$CONFIG_ARCH_ARC" = "y" -o \
+ "$CONFIG_ARCH_A5K" = "y" -o \
+ "$CONFIG_ARCH_RPC" = "y" ]; then
+ define_bool CONFIG_ARCH_ACORN y
+else
+ define_bool CONFIG_ARCH_ACORN n
+fi
+
+if [ "$CONFIG_ARCH_CO285" = "y" -o \
+ "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then
+ define_bool CONFIG_FOOTBRIDGE y
+else
+ define_bool CONFIG_FOOTBRIDGE n
+fi
+if [ "$CONFIG_ARCH_CATS" = "y" -o \
+ "$CONFIG_ARCH_EBSA285_HOST" = "y" -o \
+ "$CONFIG_ARCH_NETWINDER" = "y" -o \
+ "$CONFIG_ARCH_PERSONAL_SERVER" = "y" ]; then
+ define_bool CONFIG_FOOTBRIDGE_HOST y
+else
+ define_bool CONFIG_FOOTBRIDGE_HOST n
+fi
+if [ "$CONFIG_ARCH_CO285" = "y" -o \
+ "$CONFIG_ARCH_EBSA285_ADDIN" = "y" ]; then
+ define_bool CONFIG_FOOTBRIDGE_ADDIN y
+else
+ define_bool CONFIG_FOOTBRIDGE_ADDIN n
+fi
+if [ "$CONFIG_ARCH_EBSA285_HOST" = "y" -o \
+ "$CONFIG_ARCH_EBSA285_ADDIN" = "y" ]; then
+ define_bool CONFIG_ARCH_EBSA285 y
+fi
+
+if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+ define_bool CONFIG_DISCONTIGMEM y
+else
+ define_bool CONFIG_DISCONTIGMEM n
+fi
+
+# Now handle the bus types
if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \
- "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
+ "$CONFIG_FOOTBRIDGE_HOST" = "y" ]; then
define_bool CONFIG_PCI y
- source drivers/pci/Config.in
else
define_bool CONFIG_PCI n
fi
-#
-# These machines have ISA-DMA
-#
if [ "$CONFIG_ARCH_CATS" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_NETWINDER" = "y" ]; then
@@ -145,15 +154,9 @@ else
define_bool CONFIG_ISA n
define_bool CONFIG_ISA_DMA n
fi
-
-define_bool CONFIG_SBUS n
-define_bool CONFIG_PCMCIA n
-
-if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
- bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
-fi
endmenu
+
mainmenu_option next_comment
comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
@@ -163,53 +166,61 @@ if [ "$CONFIG_MODULES" = "y" ]; then
fi
endmenu
+
mainmenu_option next_comment
comment 'General setup'
+source drivers/pci/Config.in
+bool 'Support hot-pluggable devices' CONFIG_HOTPLUG
+if [ "$CONFIG_HOTPLUG" = "y" ]; then
+ source drivers/pcmcia/Config.in
+else
+ define_bool CONFIG_PCMCIA n
+fi
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
-tristate 'Math emulation' CONFIG_NWFPE
-if [ "$CONFIG_PROC_FS" = "y" ]; then
- choice 'Kernel core (/proc/kcore) format' \
+tristate 'NWFPE math emulation' CONFIG_NWFPE
+choice 'Kernel core (/proc/kcore) format' \
"ELF CONFIG_KCORE_ELF \
A.OUT CONFIG_KCORE_AOUT" ELF
-fi
tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
if [ "$CONFIG_CPU_32" = "y" ]; then
tristate 'RISC OS personality' CONFIG_ARTHUR
fi
-
-source drivers/parport/Config.in
-
if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
- "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
"$CONFIG_ARCH_CATS" = "y" ]; then
- string 'Initial kernel command string' CONFIG_CMDLINE
+ string 'Default kernel command string' CONFIG_CMDLINE ""
fi
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
- "$CONFIG_ARCH_CO285" = "y" ]; then
+ "$CONFIG_ARCH_CO285" = "y" -o \
+ "$CONFIG_ARCH_SA1100" = "y" ]; then
bool 'Timer and CPU usage LEDs' CONFIG_LEDS
if [ "$CONFIG_LEDS" = "y" ]; then
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
- "$CONFIG_ARCH_CO285" = "y" ]; then
+ "$CONFIG_ARCH_CO285" = "y" -o \
+ "$CONFIG_ARCH_SA1100" = "y" ]; then
bool ' Timer LED' CONFIG_LEDS_TIMER
bool ' CPU usage LED' CONFIG_LEDS_CPU
fi
fi
+ if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
+ define_bool CONFIG_LEDS_TIMER y
+ fi
+fi
+if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+ bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
fi
endmenu
-source drivers/ieee1394/Config.in
-
-source drivers/i2o/Config.in
+source drivers/parport/Config.in
source drivers/pnp/Config.in
@@ -219,37 +230,9 @@ if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
source drivers/acorn/block/Config.in
fi
-source drivers/char/Config.in
-if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
- if [ "$CONFIG_BUSMOUSE" = "y" ]; then
- if [ "$CONFIG_ARCH_RPC" != "y" ]; then
- define_bool CONFIG_KBDMOUSE y
- else
- define_bool CONFIG_RPCMOUSE y
- fi
- fi
-fi
-
-#source drivers/misc/Config.in
-
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
- bool 'VGA text console' CONFIG_VGA_CONSOLE
- fi
- bool 'Support Frame buffer devices' CONFIG_FB
- source drivers/video/Config.in
- endmenu
-fi
-
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
- source net/ax25/Config.in
-
- source net/irda/Config.in
-
mainmenu_option next_comment
comment 'Network device support'
@@ -258,16 +241,11 @@ if [ "$CONFIG_NET" = "y" ]; then
source drivers/net/Config.in
fi
endmenu
-fi
-# mainmenu_option next_comment
-# comment 'ISDN subsystem'
-#
-# tristate 'ISDN support' CONFIG_ISDN
-# if [ "$CONFIG_ISDN" != "n" ]; then
-# source drivers/isdn/Config.in
-# fi
-# endmenu
+ source net/ax25/Config.in
+
+ source net/irda/Config.in
+fi
mainmenu_option next_comment
comment 'ATA/IDE/MFM/RLL support'
@@ -292,6 +270,44 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
+source drivers/ieee1394/Config.in
+
+source drivers/i2o/Config.in
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+
+tristate 'ISDN support' CONFIG_ISDN
+if [ "$CONFIG_ISDN" != "n" ]; then
+ source drivers/isdn/Config.in
+fi
+endmenu
+
+source drivers/char/Config.in
+if [ "$CONFIG_ARCH_ACORN" = "y" -a \
+ "$CONFIG_BUSMOUSE" = "y" ]; then
+ if [ "$CONFIG_ARCH_RPC" != "y" ]; then
+ define_bool CONFIG_KBDMOUSE y
+ else
+ define_bool CONFIG_RPCMOUSE y
+ fi
+fi
+
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+ mainmenu_option next_comment
+ comment 'Console drivers'
+ if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+ bool 'VGA text console' CONFIG_VGA_CONSOLE
+ fi
+ bool 'Support Frame buffer devices' CONFIG_FB
+ source drivers/video/Config.in
+ endmenu
+fi
+
if [ "$CONFIG_ARCH_ACORN" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
@@ -306,10 +322,9 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -o \
endmenu
fi
-source fs/Config.in
-
source drivers/usb/Config.in
+
mainmenu_option next_comment
comment 'Kernel hacking'
@@ -317,7 +332,6 @@ bool 'Compile kernel with frame pointer (for useful debugging)' CONFIG_FRAME_POI
bool 'Verbose kernel error messages' CONFIG_DEBUG_ERRORS
bool 'Verbose user fault messages' CONFIG_DEBUG_USER
bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
if [ "$CONFIG_CPU_26" = "y" ]; then
bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE
diff --git a/arch/arm/def-configs/a5k b/arch/arm/def-configs/a5k
index 21a6488eb2f566..11a1dfd67fd16d 100644
--- a/arch/arm/def-configs/a5k
+++ b/arch/arm/def-configs/a5k
@@ -94,10 +94,6 @@ CONFIG_BLK_DEV_IDE_ICSIDE=y
# CONFIG_BLK_DEV_IDEDMA_ICS is not set
# CONFIG_BLK_DEV_IDE_RAPIDE is not set
# CONFIG_IDE_CHIPSETS is not set
-
-#
-# Additional Block Devices
-#
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
diff --git a/arch/arm/def-configs/assabet b/arch/arm/def-configs/assabet
index 0a2cb746288435..4f046fae2fdd3e 100644
--- a/arch/arm/def-configs/assabet
+++ b/arch/arm/def-configs/assabet
@@ -10,25 +10,29 @@ CONFIG_UID16=y
CONFIG_EXPERIMENTAL=y
#
-# System and processor type
+# System and Processor Type
#
# CONFIG_ARCH_ARC is not set
# CONFIG_ARCH_A5K is not set
-# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_FOOTBRIDGE is not set
+# CONFIG_ARCH_RPC is not set
CONFIG_ARCH_SA1100=y
+
+#
+# SA11x0 Implementations
+#
CONFIG_SA1100_ASSABET=y
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_EMPEG is not set
-# CONFIG_SA1100_ITSY is not set
+# CONFIG_ASSABET_NEPONSET is not set
# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_PLEB is not set
# CONFIG_SA1100_THINCLIENT is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_TIFON is not set
CONFIG_DISCONTIGMEM=y
+CONFIG_SA1100_FREQUENCY_SCALE=y
+# CONFIG_SA1100_VOLTAGE_SCALE is not set
# CONFIG_ARCH_ACORN is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
@@ -37,7 +41,8 @@ CONFIG_CPU_SA1100=y
# CONFIG_PCI is not set
# CONFIG_ISA is not set
# CONFIG_ISA_DMA is not set
-# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_SBUS is not set
+CONFIG_ALIGNMENT_TRAP=y
#
# Loadable module support
@@ -49,14 +54,14 @@ CONFIG_MODULES=y
#
# General setup
#
-# CONFIG_NET is not set
+CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
CONFIG_NWFPE=y
CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_ARTHUR is not set
@@ -69,13 +74,22 @@ CONFIG_CMDLINE=""
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
CONFIG_LEDS_CPU=y
+CONFIG_HOTPLUG=y
+
+#
+# PC Card support
+#
+CONFIG_PCMCIA=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_SA1100_PCMCIA=y
+CONFIG_VIRTUAL_BUS=y
#
# I2O device support
#
# CONFIG_I2O is not set
-# CONFIG_I2O_PCI 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
@@ -91,12 +105,15 @@ CONFIG_LEDS_CPU=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
-
-#
-# Additional Block Devices
-#
+# CONFIG_BLK_CPQ_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_LVM is not set
# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_RAID15_DANGEROUS is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_FLASH is not set
@@ -152,6 +169,7 @@ CONFIG_UNIX98_PTY_COUNT=32
# CONFIG_FTAPE is not set
# CONFIG_DRM is not set
# CONFIG_DRM_TDFX is not set
+# CONFIG_PCMCIA_SERIAL is not set
# CONFIG_AGP is not set
#
@@ -171,6 +189,7 @@ CONFIG_FB_SA1100=y
CONFIG_FBCON_CFB2=y
CONFIG_FBCON_CFB4=y
CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
CONFIG_FBCON_FONTWIDTH8_ONLY=y
CONFIG_FBCON_FONTS=y
CONFIG_FONT_8x8=y
@@ -180,11 +199,176 @@ CONFIG_FONT_8x8=y
# CONFIG_FONT_ACORN_8x8 is not set
#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# 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
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# 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_NETCARD=y
+
+#
# ATA/IDE/MFM/RLL support
#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
#
# SCSI support
@@ -192,43 +376,135 @@ CONFIG_FONT_8x8=y
# CONFIG_SCSI is not set
#
+# Sound
+#
+CONFIG_SOUND=y
+CONFIG_SOUND_UDA1341=y
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+
+#
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# 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_BFS_FS is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS 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=y
# 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 is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS 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_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
#
# Partition Types
#
-# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
#
# USB support
diff --git a/arch/arm/def-configs/brutus b/arch/arm/def-configs/brutus
index 80a38a0c3a038b..67c4eeafb4c3f3 100644
--- a/arch/arm/def-configs/brutus
+++ b/arch/arm/def-configs/brutus
@@ -95,10 +95,6 @@ CONFIG_LEDS_CPU=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_LVM is not set
@@ -216,10 +212,12 @@ CONFIG_FONT_8x8=y
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS 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
@@ -227,11 +225,16 @@ CONFIG_PROC_FS=y
# 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=y
# 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
+# CONFIG_NCPFS_NLS is not set
#
# Partition Types
diff --git a/arch/arm/def-configs/ebsa110 b/arch/arm/def-configs/ebsa110
index 42529e789a41f8..c2c7e0dcc71766 100644
--- a/arch/arm/def-configs/ebsa110
+++ b/arch/arm/def-configs/ebsa110
@@ -1,7 +1,8 @@
#
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
#
CONFIG_ARM=y
+# CONFIG_SBUS is not set
CONFIG_UID16=y
#
@@ -10,23 +11,27 @@ CONFIG_UID16=y
CONFIG_EXPERIMENTAL=y
#
-# System and Processor Type
+# System Type
#
# CONFIG_ARCH_ARC is not set
# CONFIG_ARCH_A5K is not set
-# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_CO285 is not set
CONFIG_ARCH_EBSA110=y
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_ARCH_ACORN is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
CONFIG_CPU_32v4=y
CONFIG_CPU_SA110=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+# CONFIG_DISCONTIGMEM is not set
# CONFIG_PCI is not set
# CONFIG_ISA is not set
# CONFIG_ISA_DMA is not set
-# CONFIG_SBUS is not set
-# CONFIG_PCMCIA is not set
#
# Loadable module support
@@ -38,6 +43,8 @@ CONFIG_KMOD=y
#
# General setup
#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -49,6 +56,9 @@ CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
#
# Parallel port support
@@ -64,17 +74,6 @@ CONFIG_PARPORT_PC_SUPERIO=y
# CONFIG_PARPORT_SUNBPP is not set
# CONFIG_PARPORT_OTHER is not set
CONFIG_PARPORT_1284=y
-CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
-CONFIG_LEDS=y
-
-#
-# 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
#
# Plug and Play configuration
@@ -90,12 +89,8 @@ CONFIG_LEDS=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
@@ -105,74 +100,6 @@ CONFIG_BLK_DEV_RAM=y
# CONFIG_BLK_DEV_INITRD is not set
#
-# Character devices
-#
-# 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_UNIX98_PTYS is not set
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-# CONFIG_PSMOUSE is not set
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-
-#
-# Joysticks
-#
-# CONFIG_JOYSTICK is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-CONFIG_SOFT_WATCHDOG=y
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
-# CONFIG_AGP is not set
-
-#
# Networking options
#
CONFIG_PACKET=m
@@ -194,7 +121,7 @@ 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 is not set
+CONFIG_IP_ROUTE_VERBOSE=y
# CONFIG_IP_ROUTE_LARGE_TABLES is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
@@ -206,51 +133,46 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_ALIAS=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
-
-#
-# (it is safe to leave these untouched)
-#
# CONFIG_SKB_LARGE is not set
#
# IP: Netfilter Configuration
#
-CONFIG_IP_NF_CONNTRACK=y
-CONFIG_IP_NF_FTP=y
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_LIMIT=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
# CONFIG_IP_NF_MATCH_MAC is not set
-CONFIG_IP_NF_MATCH_MARK=y
-CONFIG_IP_NF_MATCH_MULTIPORT=y
-CONFIG_IP_NF_MATCH_TOS=y
-CONFIG_IP_NF_MATCH_STATE=y
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_COMPAT_IPCHAINS=m
CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_MANGLE=y
-CONFIG_IP_NF_TARGET_TOS=y
-CONFIG_IP_NF_TARGET_MARK=y
-CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM 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_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -263,16 +185,6 @@ CONFIG_IP_NF_TARGET_LOG=y
# CONFIG_NET_SCHED is not set
#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
# Network device support
#
CONFIG_NETDEVICES=y
@@ -281,7 +193,7 @@ CONFIG_NETDEVICES=y
# ARCnet devices
#
# CONFIG_ARCNET is not set
-CONFIG_DUMMY=m
+# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_ETHERTAP is not set
@@ -317,7 +229,7 @@ CONFIG_PPP_ASYNC=y
# CONFIG_PPP_SYNC_TTY is not set
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
+# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
#
@@ -339,6 +251,16 @@ CONFIG_PPPOE=m
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ATA/IDE/MFM/RLL support
#
# CONFIG_IDE is not set
@@ -351,6 +273,85 @@ CONFIG_PPPOE=m
# CONFIG_SCSI 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
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# 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_UNIX98_PTYS is not set
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
# File systems
#
# CONFIG_QUOTA is not set
@@ -370,7 +371,7 @@ CONFIG_AUTOFS4_FS=y
# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
-# CONFIG_MINIX_FS is not set
+CONFIG_MINIX_FS=m
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
@@ -399,6 +400,7 @@ CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
diff --git a/arch/arm/def-configs/footbridge b/arch/arm/def-configs/footbridge
index ffe655f5db290d..af2ccd01aa7399 100644
--- a/arch/arm/def-configs/footbridge
+++ b/arch/arm/def-configs/footbridge
@@ -138,10 +138,6 @@ CONFIG_PARIDE_ON20=m
CONFIG_PARIDE_ON26=m
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_LVM is not set
diff --git a/arch/arm/def-configs/graphicsclient b/arch/arm/def-configs/graphicsclient
index 902495c3248802..11415b3636a70f 100644
--- a/arch/arm/def-configs/graphicsclient
+++ b/arch/arm/def-configs/graphicsclient
@@ -84,10 +84,6 @@ CONFIG_CMDLINE="ip=off"
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_ONLY is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
diff --git a/arch/arm/def-configs/lart b/arch/arm/def-configs/lart
index d101f43925123b..2e1cd07b5506a9 100644
--- a/arch/arm/def-configs/lart
+++ b/arch/arm/def-configs/lart
@@ -1,5 +1,5 @@
#
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
#
CONFIG_ARM=y
CONFIG_UID16=y
@@ -10,25 +10,24 @@ CONFIG_UID16=y
CONFIG_EXPERIMENTAL=y
#
-# System and processor type
+# System and Processor Type
#
# CONFIG_ARCH_ARC is not set
# CONFIG_ARCH_A5K is not set
-# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_FOOTBRIDGE is not set
+# CONFIG_ARCH_RPC is not set
CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_ASSABET is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_EMPEG is not set
-# CONFIG_SA1100_ITSY is not set
# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
CONFIG_SA1100_LART=y
-# CONFIG_SA1100_PLEB is not set
# CONFIG_SA1100_THINCLIENT is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_TIFON is not set
CONFIG_DISCONTIGMEM=y
+CONFIG_SA1100_FREQUENCY_SCALE=m
+CONFIG_SA1100_VOLTAGE_SCALE=y
# CONFIG_ARCH_ACORN is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
@@ -37,6 +36,7 @@ CONFIG_CPU_SA1100=y
# CONFIG_PCI is not set
# CONFIG_ISA is not set
# CONFIG_ISA_DMA is not set
+# CONFIG_SBUS is not set
CONFIG_ALIGNMENT_TRAP=y
#
@@ -69,29 +69,38 @@ CONFIG_CMDLINE="console=ttyS0,9600"
CONFIG_LEDS=y
# CONFIG_LEDS_TIMER is not set
CONFIG_LEDS_CPU=y
+# CONFIG_HOTPLUG 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
#
# Plug and Play configuration
#
# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
-
-#
-# Additional Block Devices
-#
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_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_LVM is not set
# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_RAID15_DANGEROUS is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_FLASH is not set
@@ -144,6 +153,7 @@ CONFIG_SERIAL_SA1100_CONSOLE=y
#
# CONFIG_FTAPE is not set
# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
# CONFIG_AGP is not set
#
@@ -163,18 +173,10 @@ CONFIG_INET=y
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_ALIAS is not set
# CONFIG_SYN_COOKIES is not set
-
-#
-# (it is safe to leave these untouched)
-#
# CONFIG_SKB_LARGE is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
-
-#
-#
-#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
@@ -230,10 +232,12 @@ CONFIG_NETDEVICES=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
CONFIG_PPP_ASYNC=y
# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
# CONFIG_SLIP_SMART is not set
@@ -270,42 +274,118 @@ CONFIG_SLIP_COMPRESSED=y
# CONFIG_SCSI is not set
#
+# Sound
+#
+CONFIG_SOUND=m
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+CONFIG_SOUND_OSS=m
+CONFIG_SOUND_TRACEINIT=y
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMPCI is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+CONFIG_SOUND_SA1100_SSP=m
+
+#
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# 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_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_CRAMFS is not set
+# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS 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 is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# 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_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
# CONFIG_SMB_FS 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_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
#
# Partition Types
@@ -325,6 +405,6 @@ CONFIG_MSDOS_PARTITION=y
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO is not set
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_DEBUG_LL=y
diff --git a/arch/arm/def-configs/lusl7200 b/arch/arm/def-configs/lusl7200
index 96cc49d3da7323..18010c8997b26f 100644
--- a/arch/arm/def-configs/lusl7200
+++ b/arch/arm/def-configs/lusl7200
@@ -79,10 +79,6 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_LVM is not set
diff --git a/arch/arm/def-configs/rpc b/arch/arm/def-configs/rpc
index d55bdf89f2b385..afbfda2da501b6 100644
--- a/arch/arm/def-configs/rpc
+++ b/arch/arm/def-configs/rpc
@@ -91,10 +91,6 @@ CONFIG_BLK_DEV_FD=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_LVM is not set
diff --git a/arch/arm/def-configs/thinclient b/arch/arm/def-configs/thinclient
index 32355662b1fa6d..5ad8986162b3b0 100644
--- a/arch/arm/def-configs/thinclient
+++ b/arch/arm/def-configs/thinclient
@@ -94,10 +94,6 @@ CONFIG_CMDLINE="root=nfs"
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_LVM is not set
@@ -336,10 +332,12 @@ CONFIG_SMC9194=y
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS 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
@@ -347,23 +345,39 @@ CONFIG_PROC_FS=y
# 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=y
# 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_NFSD is not set
+# CONFIG_NFSD_V3 is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS 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_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
#
# Partition Types
diff --git a/arch/arm/def-configs/victor b/arch/arm/def-configs/victor
index 569cc458df93cb..2377cc4df05b55 100644
--- a/arch/arm/def-configs/victor
+++ b/arch/arm/def-configs/victor
@@ -80,10 +80,6 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_IDE_CHIPSETS is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BLK_DEV_RAM is not set
diff --git a/arch/arm/defconfig b/arch/arm/defconfig
index af422cd83e4623..4a0c54739b1be3 100644
--- a/arch/arm/defconfig
+++ b/arch/arm/defconfig
@@ -134,10 +134,6 @@ CONFIG_PARIDE_ON20=m
CONFIG_PARIDE_ON26=m
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_MD=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index a129ca2f63a32a..7662f42efb3952 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -17,22 +17,23 @@ O_OBJS_a5k = dma-a5k.o
O_OBJS_rpc = dma-rpc.o
O_OBJS_ebsa110 = dma-dummy.o
O_OBJS_footbridge = dma.o dma-footbridge.o $(ISA_DMA_OBJS) hw-footbridge.o isa.o
+O_OBJS_clps7500 = dma-dummy.o
O_OBJS_nexuspci = dma-dummy.o
-O_OBJS_sa1100 = dma-dummy.o fiq.o
+O_OBJS_sa1100 = dma-dummy.o hw-sa1100.o
O_OBJS_l7200 = dma-dummy.o fiq.o
O_TARGET := kernel.o
# Object file lists.
-obj-y := arch.o $(ENTRY_OBJ) ioport.o irq.o process.o ptrace.o \
- semaphore.o setup.o signal.o sys_arm.o time.o traps.o \
- $(O_OBJS_$(MACHINE))
+obj-y := arch.o $(ENTRY_OBJ) irq.o process.o ptrace.o \
+ semaphore.o setup.o signal.o sys_arm.o time.o \
+ traps.o $(O_OBJS_$(MACHINE))
obj-m :=
obj-n :=
obj- :=
-export-objs := armksyms.o dma.o ecard.o hw-footbridge.o leds-$(MACHINE).o
+export-objs := armksyms.o dma.o ecard.o hw-footbridge.o hw-sa1100.o leds-$(MACHINE).o
obj-$(CONFIG_ARCH_ACORN) += dma.o ecard.o fiq.o time-acorn.o
obj-$(CONFIG_DEBUG_LL) += debug-$(PROCESSOR).o
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
index 717ba4ca9a9038..8b67943ce60979 100644
--- a/arch/arm/kernel/arch.c
+++ b/arch/arm/kernel/arch.c
@@ -55,6 +55,7 @@ fixup_acorn(struct machine_desc *desc, struct param_struct *params,
for (i = 0; i < 4; i++) {
mi->bank[i].start = PHYS_OFFSET + (i << 26);
+ mi->bank[i].node = 0;
mi->bank[i].size =
params->u1.s.pages_in_bank[i] *
params->u1.s.page_size;
@@ -122,6 +123,17 @@ static void __init
fixup_netwinder(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
{
+#ifdef CONFIG_ISAPNP
+ extern int isapnp_disable;
+
+ /*
+ * We must not use the kernels ISAPnP code
+ * on the NetWinder - it will reset the settings
+ * for the WaveArtist chip and render it inoperable.
+ */
+ isapnp_disable = 1;
+#endif
+
if (params->u1.s.nr_pages != 0x2000 &&
params->u1.s.nr_pages != 0x4000) {
printk(KERN_WARNING "Warning: bad NeTTrom parameters "
@@ -181,6 +193,7 @@ fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
mi->nr_banks = 1;
mi->bank[0].start = PHYS_OFFSET;
mi->bank[0].size = boot_memory_end;
+ mi->bank[0].node = 0;
*cmdline = boot_command_line;
}
@@ -197,7 +210,8 @@ MACHINE_END
extern void select_sa1100_io_desc(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
- mi->bank[__nr].size = (__size)
+ mi->bank[__nr].size = (__size), \
+ mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
static void __init
fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
@@ -252,7 +266,7 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
setup_initrd(0xc0400000, 4*1024*1024);
}
- else if (machine_is_thinclient()) {
+ else if (machine_is_thinclient() || machine_is_graphicsclient()) {
SET_BANK( 0, 0xc0000000, 16*1024*1024 );
mi->nr_banks = 1;
@@ -312,6 +326,12 @@ MACHINE_START(EMPEG, "empeg MP3 Car Audio Player")
FIXUP(fixup_sa1100)
MACHINE_END
#endif
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
+#endif
#ifdef CONFIG_SA1100_ITSY
MACHINE_START(ITSY, "Compaq Itsy")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
@@ -349,6 +369,35 @@ MACHINE_START(VICTOR, "VisuAide Victor")
FIXUP(fixup_sa1100)
MACHINE_END
#endif
+#ifdef CONFIG_SA1100_XP860
+MACHINE_START(XP860, "XP860")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
+#endif
+#endif
+
+#ifdef CONFIG_ARCH_L7200
+
+static void __init
+fixup_l7200(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 1;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = (32*1024*1024);
+ mi->bank[0].node = 0;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xf1000000), 0x00162b0d);
+}
+
+MACHINE_START(L7200, "LinkUp Systems L7200SDB")
+ MAINTAINER("Steve Hill")
+ BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000)
+ FIXUP(fixup_l7200)
+MACHINE_END
#endif
#ifdef CONFIG_ARCH_EBSA110
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 0d2e68846ebdee..2fbda24be57165 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -21,65 +21,94 @@ int have_isa_bridge;
extern void hw_init(void);
-void pcibios_report_device_errors(int warn)
+void pcibios_report_status(u_int status_mask, int warn)
{
struct pci_dev *dev;
pci_for_each_dev(dev) {
u16 status;
+ /*
+ * ignore host bridge - we handle
+ * that separately
+ */
+ if (dev->bus->number == 0 && dev->devfn == 0)
+ continue;
+
pci_read_config_word(dev, PCI_STATUS, &status);
- if ((status & 0xf900) == 0)
+ status &= status_mask;
+ if (status == 0)
continue;
- pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
+ /* clear the status errors */
+ pci_write_config_word(dev, PCI_STATUS, status);
if (warn)
- printk(KERN_DEBUG "PCI: %02X:%02X: status %04X "
- "on %s\n", dev->bus->number, dev->devfn,
- status, dev->name);
+ printk("(%02x:%02x.%d: %04X) ", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
+ status);
}
}
/*
* We don't use this to fix the device, but initialisation of it.
- * It's not the correct use for this, but it works. The actions we
- * take are:
- * - enable only IO
- * - set memory region to start at zero
- * - (0x48) enable all memory requests from ISA to be channeled to PCI
- * - (0x42) disable ping-pong (as per errata)
- * - (0x40) enable PCI packet retry
+ * It's not the correct use for this, but it works.
+ * Note that the arbiter/ISA bridge appears to be buggy, specifically in
+ * the following area:
+ * 1. park on CPU
+ * 2. ISA bridge ping-pong
+ * 3. ISA bridge master handling of target RETRY
+ *
+ * Bug 3 is responsible for the sound DMA grinding to a halt. We now
+ * live with bug 2.
*/
static void __init pci_fixup_83c553(struct pci_dev *dev)
{
+ /*
+ * Set memory region to start at address 0, and enable IO
+ */
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE_MEMORY);
pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO);
dev->resource[0].end -= dev->resource[0].start;
dev->resource[0].start = 0;
+ /*
+ * All memory requests from ISA to be channelled to PCI
+ */
pci_write_config_byte(dev, 0x48, 0xff);
- pci_write_config_byte(dev, 0x42, 0x00);
+
+ /*
+ * Enable ping-pong on bus master to ISA bridge transactions.
+ * This improves the sound DMA substantially. The fixed
+ * priority arbiter also helps (see below).
+ */
+ pci_write_config_byte(dev, 0x42, 0x01);
+
+ /*
+ * Enable PCI retry
+ */
pci_write_config_byte(dev, 0x40, 0x22);
/*
- * We used to set the arbiter to "park on last master"
- * (bit 1 set), but unfortunately the CyberPro does not
- * park the bus. We must therefore park on CPU.
+ * We used to set the arbiter to "park on last master" (bit
+ * 1 set), but unfortunately the CyberPro does not park the
+ * bus. We must therefore park on CPU. Unfortunately, this
+ * may trigger yet another bug in the 553.
*/
- pci_write_config_byte(dev, 0x83, 0x00);
+ pci_write_config_byte(dev, 0x83, 0x02);
/*
- * Rotate priorities of each PCI request
+ * Make the ISA DMA request lowest priority, and disable
+ * rotating priorities completely.
*/
- pci_write_config_byte(dev, 0x80, 0xe0);
- pci_write_config_byte(dev, 0x81, 0x01);
+ pci_write_config_byte(dev, 0x80, 0x11);
+ pci_write_config_byte(dev, 0x81, 0x00);
/*
- * Route INTA input to IRQ 11, and set
- * IRQ11 to be level sensitive.
+ * Route INTA input to IRQ 11, and set IRQ11 to be level
+ * sensitive.
*/
pci_write_config_word(dev, 0x44, 0xb000);
outb(0x08, 0x4d1);
@@ -193,8 +222,8 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
-/*
- * Called after each bus is probed, but before its children
+/**
+ * pcibios_fixup_bus - Called after each bus is probed, but before its children
* are examined.
*/
void __init pcibios_fixup_bus(struct pci_bus *bus)
@@ -209,6 +238,8 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
else
BUG();
+ busdata->max_lat = 255;
+
/*
* Walk the devices on this bus, working out what we can
* and can't support.
@@ -216,6 +247,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
struct pci_dev *dev = pci_dev_b(walk);
u16 status;
+ u8 max_lat, min_gnt;
pci_read_config_word(dev, PCI_STATUS, &status);
@@ -227,6 +259,17 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
busdata->features &= ~PCI_COMMAND_FAST_BACK;
/*
+ * If we encounter a CyberPro 2000, then we disable
+ * SERR and PERR reporting - this chip doesn't drive the
+ * parity line correctly.
+ */
+#if 1 /* !testing */
+ if (dev->vendor == PCI_VENDOR_ID_INTERG &&
+ dev->device == PCI_DEVICE_ID_INTERG_2000)
+ busdata->features &= ~(PCI_COMMAND_SERR |
+ PCI_COMMAND_PARITY);
+#endif
+ /*
* Calculate the maximum devsel latency.
*/
if (busdata->maxdevsel < (status & PCI_STATUS_DEVSEL_MASK))
@@ -240,6 +283,16 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA ||
dev->class >> 8 == PCI_CLASS_BRIDGE_EISA)
have_isa_bridge = !0;
+
+ /*
+ * Calculate the maximum latency on this bus. Note
+ * that we ignore any device which reports its max
+ * latency is the same as its use.
+ */
+ pci_read_config_byte(dev, PCI_MAX_LAT, &max_lat);
+ pci_read_config_byte(dev, PCI_MIN_GNT, &min_gnt);
+ if (max_lat && max_lat != min_gnt && max_lat < busdata->max_lat)
+ busdata->max_lat = max_lat;
}
/*
@@ -249,6 +302,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
struct pci_dev *dev = pci_dev_b(walk);
u16 cmd;
+ u8 min_gnt, latency;
/*
* architecture specific hacks. I don't really want
@@ -263,11 +317,27 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
pci_write_config_dword(dev, 0x40, 0x80000000);
/*
- * Set latency timer to 32, and a cache line size to 32 bytes.
+ * Calculate this masters latency timer value.
+ * This is rather primitive - it does not take
+ * account of the number of masters in a system
+ * wanting to use the bus.
+ */
+ pci_read_config_byte(dev, PCI_MIN_GNT, &min_gnt);
+ if (min_gnt) {
+ if (min_gnt > busdata->max_lat)
+ min_gnt = busdata->max_lat;
+
+ latency = (int)min_gnt * 25 / 3;
+ } else
+ latency = 32; /* 1us */
+
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
+
+ /*
+ * Set the cache line size to 32 bytes.
* Also, set system error enable, parity error enable.
* Disable ROM.
*/
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
@@ -520,15 +590,6 @@ void __init pcibios_init(void)
pci_assign_unassigned_resources();
pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
pci_set_bus_ranges();
-
-#ifdef CONFIG_FOOTBRIDGE
- /*
- * Initialise any other hardware after we've got the PCI bus
- * initialised. We may need the PCI bus to talk to this other
- * hardware.
- */
- hw_init();
-#endif
}
char * __init pcibios_setup(char *str)
@@ -544,10 +605,18 @@ void pcibios_align_resource(void *data, struct resource *res, unsigned long size
{
}
+/**
+ * pcibios_set_master - Setup device for bus mastering.
+ * @dev: PCI device to be setup
+ */
void pcibios_set_master(struct pci_dev *dev)
{
}
+/**
+ * pcibios_enable_device - Enable I/O and memory.
+ * @dev: PCI device to be enabled
+ */
int pcibios_enable_device(struct pci_dev *dev)
{
u16 cmd, old_cmd;
diff --git a/arch/arm/kernel/bios32.h b/arch/arm/kernel/bios32.h
index 525af165bb20b8..421ec6a79f88d7 100644
--- a/arch/arm/kernel/bios32.h
+++ b/arch/arm/kernel/bios32.h
@@ -10,6 +10,11 @@ struct arm_bus_sysdata {
* Maximum devsel for this bus.
*/
u16 maxdevsel;
+ /*
+ * The maximum latency that devices on this
+ * bus can withstand.
+ */
+ u8 max_lat;
};
struct arm_pci_sysdata {
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index eec058522e868b..0db6d0fde0d200 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -119,7 +119,7 @@
.long SYMBOL_NAME(sys_newlstat)
.long SYMBOL_NAME(sys_newfstat)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_uname */
-/* 110 */ .long SYMBOL_NAME(sys_iopl)
+/* 110 */ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_iopl */
.long SYMBOL_NAME(sys_vhangup)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_syscall) /* call a syscall */
diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S
index 8054f8756b25bb..da81b3b057c7a2 100644
--- a/arch/arm/kernel/debug-armv.S
+++ b/arch/arm/kernel/debug-armv.S
@@ -64,7 +64,7 @@
beq 1001b
.endm
-#elif defined(CONFIG_HOST_FOOTBRIDGE) || defined(CONFIG_ADDIN_FOOTBRIDGE)
+#elif defined(CONFIG_FOOTBRIDGE)
#ifndef CONFIG_DEBUG_DC21285_PORT
/* For NetWinder debugging */
.macro addruart,rx
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index bc8a951e2f936c..7fb43c68a99989 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -1,9 +1,8 @@
/*
* arch/arm/kernel/dec21285.c: PCI functions for DC21285
*
- * Copyright (C) 1998-1999 Russell King, Phil Blundell
+ * Copyright (C) 1998-2000 Russell King, Phil Blundell
*/
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -23,7 +22,8 @@
#define MAX_SLOTS 21
extern int setup_arm_irq(int, struct irqaction *);
-extern void pcibios_report_device_errors(int warn);
+extern void pcibios_report_status(u_int status_mask, int warn);
+extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
static unsigned long
dc21285_base_address(struct pci_dev *dev)
@@ -145,86 +145,125 @@ static struct pci_ops dc21285_ops = {
dc21285_write_config_dword,
};
+static struct timer_list serr_timer;
+static struct timer_list perr_timer;
+
+static void dc21285_enable_error(unsigned long __data)
+{
+ switch (__data) {
+ case IRQ_PCI_SERR:
+ del_timer(&serr_timer);
+ break;
+
+ case IRQ_PCI_PERR:
+ del_timer(&perr_timer);
+ break;
+ }
+
+ enable_irq(__data);
+}
+
/*
* Warn on PCI errors.
*/
-static void
-dc21285_error(int irq, void *dev_id, struct pt_regs *regs)
+static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs)
{
- static unsigned long next_warn;
- unsigned long cmd = *CSR_PCICMD & 0x0000ffff;
- unsigned long ctrl = (*CSR_SA110_CNTL) & 0xffffde07;
- unsigned long irqstatus = *CSR_IRQ_RAWSTATUS;
- int warn = time_after_eq(jiffies, next_warn);
+ unsigned int cmd;
+ unsigned int status;
- if (machine_is_netwinder())
- warn = 0;
+ cmd = *CSR_PCICMD;
+ status = cmd >> 16;
+ cmd = cmd & 0xffff;
- ctrl |= SA110_CNTL_DISCARDTIMER;
+ if (status & PCI_STATUS_REC_MASTER_ABORT) {
+ printk(KERN_DEBUG "PCI: master abort: ");
+ pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT, 1);
+ printk("\n");
- if (warn) {
- next_warn = jiffies + HZ;
- printk(KERN_DEBUG "PCI: ");
+ cmd |= PCI_STATUS_REC_MASTER_ABORT << 16;
}
- if (irqstatus & (1 << 31)) {
- if (warn)
- printk("parity error ");
- cmd |= 1 << 31;
- }
+ if (status & PCI_STATUS_REC_TARGET_ABORT) {
+ printk(KERN_DEBUG "PCI: target abort: ");
+ pcibios_report_status(PCI_STATUS_SIG_TARGET_ABORT, 1);
+ printk("\n");
- if (irqstatus & (1 << 30)) {
- if (warn)
- printk("target abort ");
- cmd |= 1 << 28;
+ cmd |= PCI_STATUS_REC_TARGET_ABORT << 16;
}
- if (irqstatus & (1 << 29)) {
- if (warn)
- printk("master abort ");
- cmd |= 1 << 29;
- }
+ *CSR_PCICMD = cmd;
+}
- if (irqstatus & (1 << 28)) {
- if (warn)
- printk("data parity error ");
- cmd |= 1 << 24;
- }
+static void dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct timer_list *timer = dev_id;
+ unsigned int cntl;
- if (irqstatus & (1 << 27)) {
- if (warn)
- printk("discard timer expired ");
- ctrl &= ~SA110_CNTL_DISCARDTIMER;
- }
+ printk(KERN_DEBUG "PCI: system error received: ");
+ pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
+ printk("\n");
- if (irqstatus & (1 << 23)) {
- if (warn)
- printk("system error ");
- ctrl |= SA110_CNTL_RXSERR;
- }
+ cntl = *CSR_SA110_CNTL & 0xffffdf07;
+ *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+
+ /*
+ * back off this interrupt
+ */
+ disable_irq(irq);
+ timer->expires = jiffies + HZ;
+ add_timer(timer);
+}
- if (warn)
- printk("pc=[<%08lX>]\n", instruction_pointer(regs));
+static void dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ printk(KERN_DEBUG "PCI: discard timer expired\n");
+ *CSR_SA110_CNTL &= 0xffffde07;
+}
+
+static void dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned int cmd;
- pcibios_report_device_errors(warn);
+ printk(KERN_DEBUG "PCI: data parity error detected: ");
+ pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
+ printk("\n");
- *CSR_PCICMD = cmd;
- *CSR_SA110_CNTL = ctrl;
+ cmd = *CSR_PCICMD & 0xffff;
+ *CSR_PCICMD = cmd | 1 << 24;
}
-static struct irqaction dc21285_error_action = {
- dc21285_error, SA_INTERRUPT, 0, "PCI error", NULL, NULL
-};
+static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct timer_list *timer = dev_id;
+ unsigned int cmd;
+
+ printk(KERN_DEBUG "PCI: parity error detected: ");
+ pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
+ printk("\n");
+
+ cmd = *CSR_PCICMD & 0xffff;
+ *CSR_PCICMD = cmd | 1 << 31;
+
+ /*
+ * back off this interrupt
+ */
+ disable_irq(irq);
+ timer->expires = jiffies + HZ;
+ add_timer(timer);
+}
void __init dc21285_init(void)
{
- static struct resource csrmem, csrio;
- struct arm_pci_sysdata sysdata;
unsigned long cntl;
- unsigned int mem_size, pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ unsigned int mem_size;
+ unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
- int i;
+ int cfn_mode;
+ /*
+ * These registers need to be set up whether we're the
+ * central function or not.
+ */
mem_size = (unsigned int)high_memory - PAGE_OFFSET;
*CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000;
*CSR_SDRAMBASEOFFSET = 0;
@@ -233,60 +272,93 @@ void __init dc21285_init(void)
*CSR_CSRBASEOFFSET = 0;
*CSR_PCIADDR_EXTN = 0;
-#ifdef CONFIG_HOST_FOOTBRIDGE
-
- csrio.flags = IORESOURCE_IO;
- csrio.name = "DC21285";
- csrmem.flags = IORESOURCE_MEM;
- csrmem.name = "DC21285";
-
- allocate_resource(&ioport_resource, &csrio, 128,
- 0xff00, 0xffff, 128, NULL, NULL);
- allocate_resource(&iomem_resource, &csrmem, 128,
- 0xf4000000, 0xf8000000, 128, NULL, NULL);
-
- /*
- * Map our SDRAM at a known address in PCI space, just in case
- * the firmware had other ideas. Using a nonzero base is
- * necessary, since some VGA cards forcefully use PCI addresses
- * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
- */
- *CSR_PCICACHELINESIZE = 0x00002008;
- *CSR_PCICSRBASE = csrmem.start;
- *CSR_PCICSRIOBASE = csrio.start;
- *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
- *CSR_PCIROMBASE = 0;
- *CSR_PCICMD = pci_cmd |
+ cfn_mode = __footbridge_cfn_mode();
+
+ printk(KERN_INFO "PCI: DC21285 footbridge, revision %02lX in "
+ "%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ?
+ "central function" : "addin");
+
+ if (cfn_mode) {
+ static struct resource csrmem, csrio;
+ struct arm_pci_sysdata sysdata;
+ int i;
+
+ csrio.flags = IORESOURCE_IO;
+ csrio.name = "DC21285";
+ csrmem.flags = IORESOURCE_MEM;
+ csrmem.name = "DC21285";
+
+ allocate_resource(&ioport_resource, &csrio, 128,
+ 0xff00, 0xffff, 128, NULL, NULL);
+ allocate_resource(&iomem_resource, &csrmem, 128,
+ 0xf4000000, 0xf8000000, 128, NULL, NULL);
+
+ /*
+ * Map our SDRAM at a known address in PCI space, just in case
+ * the firmware had other ideas. Using a nonzero base is
+ * necessary, since some VGA cards forcefully use PCI addresses
+ * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
+ */
+ *CSR_PCICACHELINESIZE = 0x00002008;
+ *CSR_PCICSRBASE = csrmem.start;
+ *CSR_PCICSRIOBASE = csrio.start;
+ *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
+ *CSR_PCIROMBASE = 0;
+ *CSR_PCICMD = pci_cmd |
(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
-#endif
- printk(KERN_DEBUG "PCI: DC21285 footbridge, revision %02lX\n",
- *CSR_CLASSREV & 0xff);
+ for (i = 0; i < MAX_NR_BUS; i++) {
+ sysdata.bus[i].features = PCI_COMMAND_FAST_BACK |
+ PCI_COMMAND_SERR |
+ PCI_COMMAND_PARITY;
+ sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
+ }
- for (i = 0; i < MAX_NR_BUS; i++) {
- sysdata.bus[i].features = PCI_COMMAND_FAST_BACK |
- PCI_COMMAND_SERR |
- PCI_COMMAND_PARITY;
- sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
+ pci_scan_bus(0, &dc21285_ops, &sysdata);
+
+ pci_cmd |= sysdata.bus[0].features;
+
+ printk("PCI: Fast back to back transfers %sabled\n",
+ (sysdata.bus[0].features & PCI_COMMAND_FAST_BACK) ?
+ "en" : "dis");
+
+ /*
+ * Clear any existing errors - we aren't
+ * interested in historical data...
+ */
+ cntl = *CSR_SA110_CNTL & 0xffffde07;
+ *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+ *CSR_PCICMD = pci_cmd | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
+ } else {
+ /*
+ * If we are not compiled to accept "add-in" mode, then
+ * we are using a constant virt_to_bus translation which
+ * can not hope to cater for the way the host BIOS has
+ * set up the machine.
+ */
+ panic("PCI: this kernel is compiled for central "
+ "function mode only");
}
- pci_scan_bus(0, &dc21285_ops, &sysdata);
+ /*
+ * Initialise PCI error IRQ after we've finished probing
+ */
+ request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT, "PCI abort", NULL);
+ request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT, "Discard timer", NULL);
+ request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT, "PCI data parity", NULL);
- pci_cmd |= sysdata.bus[0].features;
+ init_timer(&serr_timer);
+ init_timer(&perr_timer);
- printk("Fast back to back PCI transfers %sabled\n",
- (sysdata.bus[0].features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
+ serr_timer.data = IRQ_PCI_SERR;
+ serr_timer.function = dc21285_enable_error;
+ perr_timer.data = IRQ_PCI_PERR;
+ perr_timer.function = dc21285_enable_error;
- /*
- * Clear any existing errors - we aren't
- * interested in historical data...
- */
- cntl = *CSR_SA110_CNTL & 0xffffde07;
- *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
- *CSR_PCICMD = pci_cmd | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
+ request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT,
+ "PCI system error", &serr_timer);
+ request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT,
+ "PCI parity error", &perr_timer);
- /*
- * Initialise PCI error IRQ after we've finished probing
- */
- setup_arm_irq(IRQ_PCI_ERR, &dc21285_error_action);
+ register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
}
diff --git a/arch/arm/kernel/dma-a5k.c b/arch/arm/kernel/dma-a5k.c
index 84740b6d2e6351..d79013af26e457 100644
--- a/arch/arm/kernel/dma-a5k.c
+++ b/arch/arm/kernel/dma-a5k.c
@@ -15,7 +15,9 @@
#include "dma.h"
-static struct fiq_handler fh = { NULL, "floppydma", NULL, NULL };
+static struct fiq_handler fh = {
+ name: "floppydma"
+};
int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id)
{
diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c
index ad9afac3021a5f..e1b54233b97784 100644
--- a/arch/arm/kernel/dma-rpc.c
+++ b/arch/arm/kernel/dma-rpc.c
@@ -20,7 +20,9 @@
#include "dma.h"
-static struct fiq_handler fh = { NULL, "floppydma", NULL, NULL };
+static struct fiq_handler fh = {
+ name: "floppydma"
+};
#if 0
typedef enum {
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index c7d1da3e19f1ea..61eb422b21b98f 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -52,6 +52,10 @@
#define oldlatch_init()
#endif
+#ifndef CONFIG_ARCH_RPC
+#define HAVE_EXPMASK
+#endif
+
enum req {
req_readbytes,
req_reset
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bffe289ce99380..5d4f216b6737ae 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -32,7 +32,7 @@
.text
-#define PF_TRACESYS 0x20
+#define PT_TRACESYS 0x00000002
@ Bad Abort numbers
@ -----------------
@@ -233,14 +233,12 @@ irq_prio_ebsa110:
.macro irq_prio_table
.endm
-#elif defined(CONFIG_HOST_FOOTBRIDGE) || defined(CONFIG_ADDIN_FOOTBRIDGE)
+#elif defined(CONFIG_FOOTBRIDGE)
#include <asm/dec21285.h>
.macro disable_fiq
.endm
- .equ irq_mask_pci_err_high, IRQ_MASK_PCI_ERR & 0xff000000
- .equ irq_mask_pci_err_low, IRQ_MASK_PCI_ERR & 0x00ffffff
.equ dc21285_high, ARMCSR_BASE & 0xff000000
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
@@ -311,10 +309,24 @@ irq_prio_ebsa110:
movne \irqnr, #IRQ_CONTX
bne 1001f
- tst \irqstat, #irq_mask_pci_err_high
- tsteq \irqstat, #irq_mask_pci_err_low
- movne \irqnr, #IRQ_PCI_ERR
+ tst \irqstat, #IRQ_MASK_PCI_ABORT
+ movne \irqnr, #IRQ_PCI_ABORT
bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI_SERR
+ movne \irqnr, #IRQ_PCI_SERR
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_DISCARD_TIMER
+ movne \irqnr, #IRQ_DISCARD_TIMER
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI_DPERR
+ movne \irqnr, #IRQ_PCI_DPERR
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI_PERR
+ movne \irqnr, #IRQ_PCI_PERR
1001:
.endm
@@ -389,12 +401,25 @@ ENTRY(soft_irq_mask)
ldr \irqnr, [r4, #4] @ ICMR = 0xfa050004
ands \irqstat, \irqstat, \irqnr
mov \irqnr, #0
- beq 1002f
-1001: tst \irqstat, #1
- addeq \irqnr, \irqnr, #1
- moveq \irqstat, \irqstat, lsr #1
- beq 1001b
-1002:
+ beq 1001f
+ tst \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tsteq \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tsteq \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tst \irqstat, #0x0f
+ moveq \irqstat, \irqstat, lsr #4
+ addeq \irqnr, \irqnr, #4
+ tst \irqstat, #0x03
+ moveq \irqstat, \irqstat, lsr #2
+ addeq \irqnr, \irqnr, #2
+ tst \irqstat, #0x01
+ addeqs \irqnr, \irqnr, #1
+1001:
.endm
.macro irq_prio_table
@@ -441,7 +466,8 @@ ENTRY(soft_irq_mask)
.macro restore_user_regs
ldr r0, [sp, #S_PSR] @ Get calling cpsr
- msr cpsr_c, #I_BIT | MODE_SVC @ disable IRQs
+ mov ip, #I_BIT | MODE_SVC
+ msr cpsr_c, ip @ disable IRQs
msr spsr, r0 @ save in spsr_svc
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
mov r0, r0
@@ -592,9 +618,10 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
bl cpu_data_abort
#endif
msr cpsr_c, r9
- mov r3, sp
+ mov r2, sp
bl SYMBOL_NAME(do_DataAbort)
- msr cpsr_c, #I_BIT | MODE_SVC
+ mov r0, #I_BIT | MODE_SVC
+ msr cpsr_c, r0
ldr r0, [sp, #S_PSR]
msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
@@ -636,7 +663,8 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE
mov r1, sp @ struct pt_regs *regs
bl SYMBOL_NAME(do_undefinstr)
-1: msr cpsr_c, #I_BIT | MODE_SVC
+1: mov r0, #I_BIT | MODE_SVC
+ msr cpsr_c, r0
ldr lr, [sp, #S_PSR] @ Get SVC cpsr
msr spsr, lr
ldmia sp, {r0 - pc}^ @ Restore SVC registers
@@ -675,8 +703,9 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
#else
bl cpu_data_abort
#endif
- msr cpsr_c, #MODE_SVC @ Enable interrupts
- mov r3, sp
+ mov r2, #MODE_SVC
+ msr cpsr_c, r2 @ Enable interrupts
+ mov r2, sp
adrsvc al, lr, ret_from_sys_call
b SYMBOL_NAME(do_DataAbort)
@@ -720,9 +749,10 @@ call_fpe: get_current_task r10
add r10, r10, #TSS_FPESAVE @ r10 = workspace
ldr pc, [r4] @ Call FP module USR entry point
-fpundefinstr: mov r0, lr
+fpundefinstr: mov r0, #MODE_SVC
+ msr cpsr_c, r0 @ Enable interrupts
+ mov r0, lr
mov r1, sp
- msr cpsr_c, #MODE_SVC @ Enable interrupts
adrsvc al, lr, ret_from_sys_call
b SYMBOL_NAME(do_undefinstr)
@@ -736,7 +766,8 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr
alignment_trap r4, r7, __temp_abt
zero_fp
- msr cpsr_c, #MODE_SVC @ Enable interrupts
+ mov r0, #MODE_SVC
+ msr cpsr_c, r0 @ Enable interrupts
mov r0, r5 @ address (pc)
mov r1, sp @ regs
bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
@@ -816,7 +847,8 @@ vector_IRQ: @
@
@ now branch to the relevent MODE handling routine
@
- msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
+ mov r13, #I_BIT | MODE_SVC
+ msr spsr_c, r13 @ switch to SVC_32 mode
and lr, lr, #15
ldr lr, [pc, lr, lsl #2]
@@ -856,7 +888,8 @@ vector_data: @
@
@ now branch to the relevent MODE handling routine
@
- msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
+ mov r13, #I_BIT | MODE_SVC
+ msr spsr_c, r13 @ switch to SVC_32 mode
and lr, lr, #15
ldr lr, [pc, lr, lsl #2]
@@ -897,7 +930,8 @@ vector_prefetch:
@
@ now branch to the relevent MODE handling routine
@
- msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
+ mov r13, #I_BIT | MODE_SVC
+ msr spsr_c, r13 @ switch to SVC_32 mode
ands lr, lr, #15
ldreq lr, .LCtab_pabt
@@ -924,7 +958,8 @@ vector_undefinstr:
@
@ now branch to the relevent MODE handling routine
@
- msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
+ mov r13, #I_BIT | MODE_SVC
+ msr spsr_c, r13 @ switch to SVC_32 mode
and lr, lr, #15
ldr lr, [pc, lr, lsl #2]
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 97fcfc52271cf0..b4fbfe62824cad 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -94,9 +94,9 @@ vector_swi: save_user_regs
bcs 2f
get_current_task ip
- ldr ip, [ip, #TSK_FLAGS] @ check for syscall tracing
+ ldr ip, [ip, #TSK_PTRACE] @ check for syscall tracing
adr tbl, SYMBOL_NAME(sys_call_table)
- tst ip, #PF_TRACESYS
+ tst ip, #PT_TRACESYS
ldreq pc, [tbl, scno, lsl #2] @ call sys routine
ldr tip, [sp, #S_IP + S_OFF] @ save old IP
diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/kernel/hw-footbridge.c
index f47e169c5bd428..08aac078ea84b5 100644
--- a/arch/arm/kernel/hw-footbridge.c
+++ b/arch/arm/kernel/hw-footbridge.c
@@ -662,12 +662,13 @@ static void __init cats_hw_init(void)
#endif
-void __init hw_init(void)
+/*
+ * Initialise any other hardware after we've got the PCI bus
+ * initialised. We may need the PCI bus to talk to this other
+ * hardware.
+ */
+static int __init hw_init(void)
{
- extern void register_isa_ports(unsigned int, unsigned int,
- unsigned int);
- register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
-
#ifdef CONFIG_ARCH_NETWINDER
/*
* this ought to have a better home...
@@ -678,7 +679,6 @@ void __init hw_init(void)
*/
if (machine_is_netwinder()) {
unsigned long flags;
- extern int isapnp_disable;
wb977_init();
cpld_init();
@@ -687,21 +687,13 @@ void __init hw_init(void)
spin_lock_irqsave(&gpio_lock, flags);
gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS);
spin_unlock_irqrestore(&gpio_lock, flags);
-
-#ifdef CONFIG_ISAPNP
- /*
- * We must not use the kernels ISAPnP code
- * on the NetWinder - it will reset the settings
- * for the WaveArtist chip and render it inoperable.
- */
- isapnp_disable = 1;
-#endif
}
#endif
#ifdef CONFIG_ARCH_CATS
if (machine_is_cats())
cats_hw_init();
#endif
-
- leds_event(led_start);
+ return 0;
}
+
+__initcall(hw_init);
diff --git a/arch/arm/kernel/hw-sa1100.c b/arch/arm/kernel/hw-sa1100.c
new file mode 100644
index 00000000000000..539bb721baae78
--- /dev/null
+++ b/arch/arm/kernel/hw-sa1100.c
@@ -0,0 +1,135 @@
+/*
+ * arch/arm/kernel/hw-sa1100.c
+ *
+ * SA1100-dependent machine specifics
+ *
+ * Copyright (C) 2000 Nicolas Pitre <nico@cam.org>
+ *
+ * This will certainly contain more stuff with time... like power management,
+ * special hardware autodetection, etc.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+
+
+/*
+ * SA1100 GPIO edge detection for IRQs:
+ * IRQs are generated on Falling-Edge, Rising-Edge, or both.
+ * This must be called *before* the appropriate IRQ is registered.
+ * Use this instead of directly setting GRER/GFER.
+ */
+
+int GPIO_IRQ_rising_edge;
+int GPIO_IRQ_falling_edge;
+
+void set_GPIO_IRQ_edge( int gpio_mask, int edge )
+{
+ if( edge & GPIO_FALLING_EDGE )
+ GPIO_IRQ_falling_edge |= gpio_mask;
+ else
+ GPIO_IRQ_falling_edge &= ~gpio_mask;
+ if( edge & GPIO_RISING_EDGE )
+ GPIO_IRQ_rising_edge |= gpio_mask;
+ else
+ GPIO_IRQ_rising_edge &= ~gpio_mask;
+}
+
+EXPORT_SYMBOL(set_GPIO_IRQ_edge);
+
+
+#ifdef CONFIG_SA1100_ASSABET
+
+unsigned long BCR_value = BCR_DB1110;
+unsigned long SCR_value = SCR_INIT;
+EXPORT_SYMBOL(BCR_value);
+EXPORT_SYMBOL(SCR_value);
+
+/*
+ * Read System Configuration "Register"
+ * (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
+ * User's Guide", section 4.4.1)
+ *
+ * This same scan is performed in arch/arm/boot/compressed/head-sa1100.S
+ * to set up the serial port for decompression status messages. We
+ * repeat it here because the kernel may not be loaded as a zImage, and
+ * also because it's a hassle to communicate the SCR value to the kernel
+ * from the decompressor.
+ */
+
+void __init get_assabet_scr(void)
+{
+ unsigned long flags, scr, i;
+
+ save_flags_cli(flags);
+ GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
+ GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
+ GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */
+ for(i = 100; i--; scr = GPLR); /* Read GPIO 9:2 */
+ GPDR |= 0x3fc; /* restore correct pin direction */
+ restore_flags(flags);
+ scr &= 0x3fc; /* save as system configuration byte. */
+
+ SCR_value = scr;
+}
+
+#endif /* CONFIG_SA1100_ASSABET */
+
+
+#ifdef CONFIG_SA1111
+
+void __init sa1111_init(void){
+ unsigned long id=SKID;
+
+ if((id & SKID_ID_MASK) == SKID_SA1111_ID)
+ printk(KERN_INFO "SA-1111 Microprocessor Companion Chip: "
+ "silicon revision %x, metal revision %x\n",
+ (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
+ else {
+ printk(KERN_ERR "Could not detect SA-1111!\n");
+ return;
+ }
+
+ /* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
+ * (SA-1110 Developer's Manual, section 9.1.2.1)
+ */
+ GAFR |= GPIO_GPIO27;
+ GPDR |= GPIO_GPIO27;
+ TUCR = TUCR_3_6864MHz;
+
+ /* Now, set up the PLL and RCLK in the SA-1111: */
+ SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
+ udelay(100);
+ SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;
+
+ /* SA-1111 Register Access Bus should now be available. Clocks for
+ * any other SA-1111 functional blocks must be enabled separately
+ * using the SKPCR.
+ */
+}
+
+#endif
+
+
+static void __init hw_sa1100_init(void)
+{
+ if( machine_is_assabet() ){
+ if(machine_has_neponset()){
+#ifdef CONFIG_ASSABET_NEPONSET
+ LEDS = WHOAMI;
+ sa1111_init();
+#else
+ printk( "Warning: Neponset detected but full support "
+ "hasn't been configured in the kernel\n" );
+#endif
+ }
+ }
+}
+
+module_init(hw_sa1100_init);
diff --git a/arch/arm/kernel/ioport.c b/arch/arm/kernel/ioport.c
deleted file mode 100644
index 07a52ba8e4c5ef..00000000000000
--- a/arch/arm/kernel/ioport.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * linux/arch/arm/kernel/ioport.c
- *
- * IO permission support for ARM.
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_CPU_32
-asmlinkage int sys_iopl(unsigned long turn_on)
-{
- if (turn_on && !capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- /*
- * We only support an on_off approach
- */
- modify_domain(DOMAIN_IO, turn_on ? DOMAIN_MANAGER : DOMAIN_CLIENT);
-
- return 0;
-}
-#else
-asmlinkage int sys_iopl(unsigned long turn_on)
-{
- return -ENOSYS;
-}
-#endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 1b26ced9455a40..7a761b7c6b7c0a 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -15,7 +15,7 @@
* IRQ's are in fact implemented a bit like signal handlers for the kernel.
* Naturally it's not a 1:1 relation, but there are similarities.
*/
-#include <linux/config.h> /* for CONFIG_DEBUG_ERRORS */
+#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
@@ -33,13 +33,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#ifndef SMP
-#define irq_enter(cpu, irq) (++local_irq_count[cpu])
-#define irq_exit(cpu, irq) (--local_irq_count[cpu])
-#else
-#error SMP not supported
-#endif
-
#ifndef cliIF
#define cliIF()
#endif
@@ -85,6 +78,7 @@ struct irqdesc {
};
static struct irqdesc irq_desc[NR_IRQS];
+static volatile unsigned long irq_err_count;
/*
* Get architecture specific interrupt handlers
@@ -133,8 +127,8 @@ int get_irq_list(char *buf)
action = irq_desc[i].action;
if (!action)
continue;
- p += sprintf(p, "%3d: %10u %s",
- i, kstat_irqs(i), action->name);
+ p += sprintf(p, "%3d: %10u ", i, kstat_irqs(i));
+ p += sprintf(p, " %s", action->name);
for (action = action->next; action; action = action->next) {
p += sprintf(p, ", %s", action->name);
}
@@ -144,6 +138,7 @@ int get_irq_list(char *buf)
#ifdef CONFIG_ARCH_ACORN
p += get_fiq_list(p);
#endif
+ p += sprintf(p, "Err: %10lu\n", irq_err_count);
return p - buf;
}
@@ -181,10 +176,17 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
struct irqdesc * desc;
struct irqaction * action;
- int status, cpu;
+ int cpu;
irq = fixup_irq(irq);
+ /*
+ * Some hardware gives randomly wrong interrupts. Rather
+ * than crashing, do something sensible.
+ */
+ if (irq >= NR_IRQS)
+ goto bad_irq;
+
desc = irq_desc + irq;
spin_lock(&irq_controller_lock);
@@ -197,10 +199,11 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
desc->triggered = 1;
/* Return with this interrupt masked if no action */
- status = 0;
action = desc->action;
if (action) {
+ int status = 0;
+
if (desc->nomask) {
spin_lock(&irq_controller_lock);
desc->unmask(irq);
@@ -237,9 +240,15 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
if (softirq_state[cpu].active & softirq_state[cpu].mask)
do_softirq();
+ return;
+
+bad_irq:
+ irq_err_count += 1;
+ printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+ return;
}
-#if defined(CONFIG_ARCH_ACORN)
+#ifdef CONFIG_ARCH_ACORN
void do_ecard_IRQ(int irq, struct pt_regs *regs)
{
struct irqdesc * desc;
diff --git a/arch/arm/kernel/leds-ebsa110.c b/arch/arm/kernel/leds-ebsa110.c
index eb286347b1ec0f..7b2c886ef9b954 100644
--- a/arch/arm/kernel/leds-ebsa110.c
+++ b/arch/arm/kernel/leds-ebsa110.c
@@ -13,7 +13,7 @@
#include <asm/leds.h>
#include <asm/system.h>
-void ebsa110_leds_event(led_event_t ledevt)
+static void ebsa110_leds_event(led_event_t ledevt)
{
unsigned long flags;
diff --git a/arch/arm/kernel/leds-footbridge.c b/arch/arm/kernel/leds-footbridge.c
index 05f232f578148b..4fa2237ebc6184 100644
--- a/arch/arm/kernel/leds-footbridge.c
+++ b/arch/arm/kernel/leds-footbridge.c
@@ -46,7 +46,7 @@ static void ebsa285_leds_event(led_event_t evt)
switch (evt) {
case led_start:
hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN;
-#ifndef CONFIG_LEDS_IDLE
+#ifndef CONFIG_LEDS_CPU
hw_led_state |= XBUS_LED_AMBER;
#endif
led_state |= LED_STATE_ENABLED;
@@ -223,11 +223,12 @@ static void dummy_leds_event(led_event_t evt)
{
}
-static void __init
-init_leds_event(led_event_t evt)
-{
- leds_event = dummy_leds_event;
+void (*leds_event)(led_event_t) = dummy_leds_event;
+
+EXPORT_SYMBOL(leds_event);
+static int __init leds_init(void)
+{
#ifdef CONFIG_FOOTBRIDGE
if (machine_is_ebsa285() || machine_is_co285())
leds_event = ebsa285_leds_event;
@@ -237,9 +238,9 @@ init_leds_event(led_event_t evt)
leds_event = netwinder_leds_event;
#endif
- leds_event(evt);
-}
+ leds_event(led_start);
-void (*leds_event)(led_event_t) = init_leds_event;
+ return 0;
+}
-EXPORT_SYMBOL(leds_event);
+__initcall(leds_init);
diff --git a/arch/arm/kernel/leds-sa1100.c b/arch/arm/kernel/leds-sa1100.c
new file mode 100644
index 00000000000000..ef6918d7cbe90c
--- /dev/null
+++ b/arch/arm/kernel/leds-sa1100.c
@@ -0,0 +1,333 @@
+/*
+ * linux/arch/arm/kernel/leds-sa1100.c
+ *
+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * Added Brutus LEDs support
+ * Nicolas Pitre, Mar 19, 2000
+ *
+ * Added LART LED support
+ * Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
+ *
+ *
+ * Assabet uses the LEDs as follows:
+ * - Green - toggles state every 50 timer interrupts
+ * - Red - on if system is not idle
+ *
+ * Brutus uses the LEDs as follows:
+ * - D3 (Green, GPIO9) - toggles state every 50 timer interrupts
+ * - D17 (Red, GPIO20) - on if system is not idle
+ * - D4 (Green, GPIO8) - misc function
+ *
+ * LART uses the LED as follows:
+ * - GPIO23 is the LED, on if system is not idle
+ * You can use both CONFIG_LEDS_CPU and CONFIG_LEDS_TIMER at the same
+ * time, but in that case the timer events will still dictate the
+ * pace of the LED.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+
+#ifdef CONFIG_SA1100_ASSABET
+
+#define BCR_LED_MASK (BCR_LED_GREEN | BCR_LED_RED)
+
+static void assabet_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ save_flags_cli(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = BCR_LED_RED | BCR_LED_GREEN;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = BCR_LED_RED | BCR_LED_GREEN;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = BCR_LED_RED | BCR_LED_GREEN;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= BCR_LED_GREEN;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= BCR_LED_RED;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~BCR_LED_RED;
+ break;
+#endif
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~BCR_LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= BCR_LED_GREEN;
+ break;
+
+ case led_amber_on:
+ break;
+
+ case led_amber_off:
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~BCR_LED_RED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= BCR_LED_RED;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ BCR = BCR_value = (BCR_value & ~BCR_LED_MASK) | hw_led_state;
+
+ restore_flags(flags);
+}
+
+#endif /* CONFIG_SA1100_ASSABET */
+
+#ifdef CONFIG_SA1100_BRUTUS
+
+#define LED_D3 GPIO_GPIO(9)
+#define LED_D4 GPIO_GPIO(8)
+#define LED_D17 GPIO_GPIO(20)
+#define LED_MASK (LED_D3|LED_D4|LED_D17)
+
+static void brutus_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ save_flags_cli(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = LED_MASK;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_D3;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_D17;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_D17;
+ break;
+#endif
+
+ case led_green_on:
+ hw_led_state &= ~LED_D4;
+ break;
+
+ case led_green_off:
+ hw_led_state |= LED_D4;
+ break;
+
+ case led_amber_on:
+ break;
+
+ case led_amber_off:
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~LED_D17;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= LED_D17;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED) {
+ GPSR = hw_led_state;
+ GPCR = hw_led_state ^ LED_MASK;
+ }
+
+ restore_flags(flags);
+}
+
+#endif /* CONFIG_SA1100_BRUTUS */
+
+#ifdef CONFIG_SA1100_LART
+
+#define LED_23 GPIO_GPIO23
+#define LED_MASK (LED_23)
+
+
+static void lart_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ save_flags_cli(flags);
+
+ switch(evt) {
+ case led_start:
+ hw_led_state = LED_MASK;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_23;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ /* The LART people like the LED to be off when the
+ system is idle... */
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_23;
+ break;
+
+ case led_idle_end:
+ /* ... and on if the system is not idle */
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_23;
+ break;
+#endif
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~LED_23;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= LED_23;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Now set the GPIO state, or nothing will happen at all */
+ if (led_state & LED_STATE_ENABLED) {
+ GPSR = hw_led_state;
+ GPCR = hw_led_state ^ LED_MASK;
+ }
+
+ restore_flags(flags);
+}
+
+#endif /* CONFIG_SA1100_LART */
+
+static void dummy_leds_event(led_event_t evt)
+{
+}
+
+void (*leds_event)(led_event_t) = dummy_leds_event;
+
+EXPORT_SYMBOL(leds_event);
+
+static int __init
+sa1100_leds_init(void)
+{
+#ifdef CONFIG_SA1100_ASSABET
+ if (machine_is_assabet())
+ leds_event = assabet_leds_event;
+#endif
+#ifdef CONFIG_SA1100_BRUTUS
+ if (machine_is_brutus())
+ leds_event = brutus_leds_event;
+#endif
+#ifdef CONFIG_SA1100_LART
+ if (machine_is_lart())
+ leds_event = lart_leds_event;
+#endif
+
+ leds_event(led_start);
+ return 0;
+}
+
+__initcall(sa1100_leds_init);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index c7ace10b59bca6..40b3b9e7244f40 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -353,10 +353,12 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
pid_t __ret;
__asm__ __volatile__(
- "mov r0, %1 @ kernel_thread sys_clone\n"
-" mov r1, #0\n"
- __syscall(clone)"\n"
-" mov %0, r0"
+ "mov r0, %1 @ kernel_thread sys_clone
+ mov r1, #0
+ "__syscall(clone)"
+ teq r0, #0 @ if we are the child
+ moveq fp, #0 @ ensure that fp is zero
+ mov %0, r0"
: "=r" (__ret)
: "Ir" (flags | CLONE_VM) : "r0", "r1");
if (__ret == 0)
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 0ace4c898b0924..1684c5f5f925e3 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -393,10 +393,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EPERM;
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
goto out;
/* set the ptrace bit in the process flags. */
- current->flags |= PF_PTRACED;
+ current->ptrace |= PT_PTRACED;
ret = 0;
goto out;
}
@@ -419,9 +419,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED)
+ if (child->ptrace & PT_PTRACED)
goto out;
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
@@ -432,7 +432,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out;
}
ret = -ESRCH;
- if (!(child->flags & PF_PTRACED))
+ if (!(child->ptrace & PT_PTRACED))
goto out;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
@@ -486,9 +486,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data > _NSIG)
goto out;
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
wake_up_process (child);
/* make sure single-step breakpoint is gone. */
@@ -515,7 +515,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data > _NSIG)
goto out;
child->thread.debug.nsaved = -1;
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
wake_up_process(child);
child->exit_code = data;
/* give it a chance to run. */
@@ -568,7 +568,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
goto out;
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
wake_up_process (child);
child->exit_code = data;
REMOVE_LINKS(child);
@@ -590,8 +590,8 @@ out:
asmlinkage void syscall_trace(void)
{
- if ((current->flags & (PF_PTRACED|PF_TRACESYS))
- != (PF_PTRACED|PF_TRACESYS))
+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+ != (PT_PTRACED|PT_TRACESYS))
return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index a2ec71526b0e69..93a370f2dcfa3b 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -290,68 +290,95 @@ struct rw_semaphore *rwsem_wake_writer(struct rw_semaphore *sem)
* need to convert that sequence back into the C sequence when
* there is contention on the semaphore.
*
- * r0 contains the semaphore pointer on entry. Save the C-clobbered
- * registers (r0 to r3, ip and lr) except r0 in the cases where it
- * is used as a return value..
+ * ip contains the semaphore pointer on entry. Save the C-clobbered
+ * registers (r0 to r3 and lr), but not ip, as we use it as a return
+ * value in some cases..
*/
asm(" .section .text.lock, \"ax\"
.align 5
.globl __down_failed
__down_failed:
- stmfd sp!, {r0 - r3, ip, lr}
+ stmfd sp!, {r0 - r3, lr}
+ mov r0, ip
bl __down
- ldmfd sp!, {r0 - r3, ip, pc}
+ ldmfd sp!, {r0 - r3, pc}
.align 5
.globl __down_interruptible_failed
__down_interruptible_failed:
- stmfd sp!, {r1 - r3, ip, lr}
+ stmfd sp!, {r0 - r3, lr}
+ mov r0, ip
bl __down_interruptible
- ldmfd sp!, {r1 - r3, ip, pc}
+ mov ip, r0
+ ldmfd sp!, {r0 - r3, pc}
.align 5
.globl __down_trylock_failed
__down_trylock_failed:
- stmfd sp!, {r1 - r3, ip, lr}
+ stmfd sp!, {r0 - r3, lr}
+ mov r0, ip
bl __down_trylock
- ldmfd sp!, {r1 - r3, ip, pc}
+ mov ip, r0
+ ldmfd sp!, {r0 - r3, pc}
.align 5
.globl __up_wakeup
__up_wakeup:
- stmfd sp!, {r0 - r3, ip, lr}
+ stmfd sp!, {r0 - r3, lr}
+ mov r0, ip
bl __up
- ldmfd sp!, {r0 - r3, ip, pc}
+ ldmfd sp!, {r0 - r3, pc}
.align 5
.globl __down_read_failed
__down_read_failed:
- stmfd sp!, {r0 - r3, ip, lr}
+ stmfd sp!, {r0 - r3, lr}
+ mov r0, ip
bcc 1f
- bl down_read_failed_biased
- ldmfd sp!, {r0 - r3, ip, pc}
-1: bl down_read_failed
- /***/
+1: bl down_read_failed_biased
+ ldmfd sp!, {r0 - r3, pc}
+2: bl down_read_failed
+ mrs r1, cpsr
+ orr r2, r1, #128
+ msr cpsr_c, r2
+ ldr r3, [r0]
+ subs r3, r3, #1
+ str r3, [r0]
+ msr cpsr_c, r1
+ ldmplfd sp!, {r0 - r3, pc}
+ bcc 2b
+ b 1b
.align 5
.globl __down_write_failed
__down_write_failed:
- stmfd sp!, {r0 - r3, ip, lr}
+ stmfd sp!, {r0 - r3, lr}
+ mov r0, ip
bcc 1f
- bl down_write_failed_biased
- ldmfd sp!, {r0 - r3, ip, pc}
-1: bl down_write_failed
- /***/
+1: bl down_write_failed_biased
+ ldmfd sp!, {r0 - r3, pc}
+2: bl down_write_failed
+ mrs r1, cpsr
+ orr r2, r1, #128
+ msr cpsr_c, r2
+ ldr r3, [r0]
+ subs r3, r3, #"RW_LOCK_BIAS_STR"
+ str r3, [r0]
+ msr cpsr_c, r1
+ ldmeqfd sp!, {r0 - r3, pc}
+ bcc 2b
+ b 1b
.align 5
.globl __rwsem_wake
__rwsem_wake:
- stmfd sp!, {r0 - r3, ip, lr}
+ stmfd sp!, {r0 - r3, lr}
+ mov r0, ip
beq 1f
bl rwsem_wake_readers
- ldmfd sp!, {r0 - r3, ip, pc}
+ ldmfd sp!, {r0 - r3, pc}
1: bl rwsem_wake_writer
- ldmfd sp!, {r0 - r3, ip, pc}
+ ldmfd sp!, {r0 - r3, pc}
.previous
");
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ec67dcbd05afff..1f429554083796 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -124,11 +124,11 @@ static void __init setup_processor(void)
#ifdef MULTI_CPU
processor = *list->proc;
+#endif
printk("Processor: %s %s revision %d\n",
proc_info.manufacturer, proc_info.cpu_name,
(int)processor_id & 15);
-#endif
sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
@@ -164,24 +164,6 @@ static struct machine_desc * __init setup_architecture(unsigned int nr)
return list;
}
-static unsigned long __init memparse(char *ptr, char **retptr)
-{
- unsigned long ret = simple_strtoul(ptr, retptr, 0);
-
- switch (**retptr) {
- case 'M':
- case 'm':
- ret <<= 10;
- case 'K':
- case 'k':
- ret <<= 10;
- (*retptr)++;
- default:
- break;
- }
- return ret;
-}
-
/*
* Initial parsing of the command line. We need to pick out the
* memory size. We look for mem=size@start, where start and size
@@ -217,6 +199,7 @@ parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
mi->bank[mi->nr_banks].start = start;
mi->bank[mi->nr_banks].size = size;
+ mi->bank[mi->nr_banks].node = 0;
mi->nr_banks += 1;
}
c = *from++;
@@ -378,6 +361,7 @@ void __init setup_arch(char **cmdline_p)
if (meminfo.nr_banks == 0) {
meminfo.nr_banks = 1;
meminfo.bank[0].start = PHYS_OFFSET;
+ meminfo.bank[0].node = 0;
if (params)
meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
else
@@ -393,8 +377,8 @@ void __init setup_arch(char **cmdline_p)
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(&meminfo, cmdline_p, from);
bootmem_init(&meminfo);
- request_standard_resources(&meminfo, mdesc);
paging_init(&meminfo);
+ request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 15f8fb4cb2e5bc..431dd96c1153c5 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -512,7 +512,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
if (!signr)
break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index c79b323a90b08e..bdb725551dedeb 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -154,21 +154,29 @@ static inline void do_set_rtc(void)
static void do_leds(void)
{
- static unsigned int count = 50;
- static int last_pid;
-
- if (current->pid != last_pid) {
- last_pid = current->pid;
- if (last_pid)
- leds_event(led_idle_end);
- else
- leds_event(led_idle_start);
+#ifdef CONFIG_LEDS_CPU
+ {
+ static int last_pid;
+
+ if (current->pid != last_pid) {
+ last_pid = current->pid;
+ if (last_pid)
+ leds_event(led_idle_end);
+ else
+ leds_event(led_idle_start);
+ }
}
-
- if (--count == 0) {
- count = 50;
- leds_event(led_timer);
+#endif
+#ifdef CONFIG_LEDS_TIMER
+ {
+ static unsigned int count = 50;
+
+ if (--count == 0) {
+ count = 50;
+ leds_event(led_timer);
+ }
}
+#endif
}
#else
#define do_leds()
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index 8005fd49a64dc6..adb847670bc69d 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -9,18 +9,15 @@
.text
/* Purpose : Function to change a bit
- * Prototype: int change_bit(int bit,int *addr)
+ * Prototype: int change_bit(int bit, void *addr)
*/
ENTRY(change_bit)
- and r2, r0, #7
- mov r3, #1
- mov r3, r3, lsl r2
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
+ and r2, r0, #7
+ mov r3, #1
+ mov r3, r3, lsl r2
+ save_and_disable_irqs ip, r2
ldrb r2, [r1, r0, lsr #3]
eor r2, r2, r3
strb r2, [r1, r0, lsr #3]
- RESTOREIRQS(ip)
+ restore_irqs ip
RETINSTR(mov,pc,lr)
-
-
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index d936ab549ee25e..d6394752080bb0 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -8,19 +8,20 @@
#include <asm/assembler.h>
.text
-@ Purpose : Function to clear a bit
-@ Prototype: int clear_bit(int bit,int *addr)
+/*
+ * Purpose : Function to clear a bit
+ * Prototype: int clear_bit(int bit, void *addr)
+ */
ENTRY(clear_bit)
and r2, r0, #7
mov r3, #1
mov r3, r3, lsl r2
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
+ save_and_disable_irqs ip, r2
ldrb r2, [r1, r0, lsr #3]
bic r2, r2, r3
strb r2, [r1, r0, lsr #3]
- RESTOREIRQS(ip)
+ restore_irqs ip
RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 3544ac89df6976..5b570f199df374 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -1,65 +1,53 @@
/*
- * linux/arch/arm/lib/bitops.S
+ * linux/arch/arm/lib/findbit.S
*
- * Copyright (C) 1995-1996 Russell King
+ * Copyright (C) 1995-2000 Russell King
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
-@ Purpose : Find a 'zero' bit
-@ Prototype: int find_first_zero_bit(char *addr,int maxbit);
-
+/*
+ * Purpose : Find a 'zero' bit
+ * Prototype: int find_first_zero_bit(void *addr, int maxbit);
+ */
ENTRY(find_first_zero_bit)
- mov r2, #0 @ Initialise bit position
-Lfindzbit1lp: ldrb r3, [r0, r2, lsr #3] @ Check byte, if 0xFF, then all bits set
- teq r3, #0xFF
- bne Lfoundzbit
- add r2, r2, #8
- cmp r2, r1 @ Check to see if we have come to the end
- bcc Lfindzbit1lp
- add r0, r1, #1 @ Make sure that we flag an error
+ mov r2, #0
+.bytelp: ldrb r3, [r0, r2, lsr #3]
+ eors r3, r3, #0xff @ invert bits
+ bne .found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+ cmp r2, r1 @ any more?
+ bcc .bytelp
+ add r0, r1, #1 @ no free bits
RETINSTR(mov,pc,lr)
-Lfoundzbit: tst r3, #1 @ Check individual bits
- moveq r0, r2
- RETINSTR(moveq,pc,lr)
- tst r3, #2
- addeq r0, r2, #1
- RETINSTR(moveq,pc,lr)
- tst r3, #4
- addeq r0, r2, #2
- RETINSTR(moveq,pc,lr)
- tst r3, #8
- addeq r0, r2, #3
- RETINSTR(moveq,pc,lr)
- tst r3, #16
- addeq r0, r2, #4
- RETINSTR(moveq,pc,lr)
- tst r3, #32
- addeq r0, r2, #5
- RETINSTR(moveq,pc,lr)
- tst r3, #64
- addeq r0, r2, #6
- RETINSTR(moveq,pc,lr)
- add r0, r2, #7
- RETINSTR(mov,pc,lr)
-
-@ Purpose : Find next 'zero' bit
-@ Prototype: int find_next_zero_bit(char *addr,int maxbit,int offset)
+/*
+ * Purpose : Find next 'zero' bit
+ * Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset)
+ */
ENTRY(find_next_zero_bit)
- tst r2, #7
- beq Lfindzbit1lp @ If new byte, goto old routine
+ ands ip, r2, #7
+ beq .bytelp @ If new byte, goto old routine
ldrb r3, [r0, r2, lsr#3]
- orr r3, r3, #0xFF00 @ Set top bits so we wont get confused
- str r4, [sp, #-4]!
- and r4, r2, #7
- mov r3, r3, lsr r4 @ Shift right by no. of bits
- ldr r4, [sp], #4
- and r3, r3, #0xFF
- teq r3, #0xFF
- orreq r2, r2, #7
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ orreq r2, r2, #7 @ if zero, then no bits here
+ addeq r2, r2, #1 @ align bit pointer
+ beq .bytelp @ loop for next bit
+
+/*
+ * One or more bits in the LSB of r3 are assumed to be set.
+ */
+.found: tst r3, #0x0f
+ addeq r2, r2, #4
+ movne r3, r3, lsl #4
+ tst r3, #0x30
+ addeq r2, r2, #2
+ movne r3, r3, lsl #2
+ tst r3, #0x40
addeq r2, r2, #1
- beq Lfindzbit1lp @ If all bits are set, goto old routine
- b Lfoundzbit
+ mov r0, r2
+ RETINSTR(mov,pc,lr)
+
diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c
index 8b6a0affa34039..aa5efa1cda8ef1 100644
--- a/arch/arm/lib/getconsdata.c
+++ b/arch/arm/lib/getconsdata.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/lib/getconsdata.c
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-2000 Russell King
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -25,16 +25,12 @@
#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
#define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n)
-unsigned long TSK_STATE = OFF_TSK(state);
-unsigned long TSK_FLAGS = OFF_TSK(flags);
-unsigned long TSK_NEED_RESCHED = OFF_TSK(need_resched);
unsigned long TSK_SIGPENDING = OFF_TSK(sigpending);
unsigned long TSK_ADDR_LIMIT = OFF_TSK(addr_limit);
+unsigned long TSK_NEED_RESCHED = OFF_TSK(need_resched);
+unsigned long TSK_PTRACE = OFF_TSK(ptrace);
unsigned long TSK_USED_MATH = OFF_TSK(used_math);
-unsigned long MM = OFF_TSK(mm);
-unsigned long PGD = OFF_MM(pgd);
-
unsigned long TSS_SAVE = OFF_TSK(thread.save);
unsigned long TSS_FPESAVE = OFF_TSK(thread.fpstate.soft.save);
#ifdef CONFIG_CPU_32
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index b4319b4c31fbd6..745bdce4eb4fbe 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -8,19 +8,20 @@
#include <asm/assembler.h>
.text
-@ Purpose : Function to set a bit
-@ Prototype: int set_bit(int bit,int *addr)
+/*
+ * Purpose : Function to set a bit
+ * Prototype: int set_bit(int bit, void *addr)
+ */
ENTRY(set_bit)
and r2, r0, #7
mov r3, #1
mov r3, r3, lsl r2
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
+ save_and_disable_irqs ip, r2
ldrb r2, [r1, r0, lsr #3]
orr r2, r2, r3
strb r2, [r1, r0, lsr #3]
- RESTOREIRQS(ip)
+ restore_irqs ip
RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index d3dd48216535cc..c627cf99d96f43 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -12,14 +12,13 @@ ENTRY(test_and_change_bit)
add r1, r1, r0, lsr #3
and r3, r0, #7
mov r0, #1
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
+ save_and_disable_irqs ip, r2
ldrb r2, [r1]
tst r2, r0, lsl r3
eor r2, r2, r0, lsl r3
- moveq r0, #0
strb r2, [r1]
- RESTOREIRQS(ip)
+ restore_irqs ip
+ moveq r0, #0
RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 4318653027bad8..3a678e7ffc8afd 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -10,16 +10,15 @@
ENTRY(test_and_clear_bit)
add r1, r1, r0, lsr #3 @ Get byte offset
- and r3, r0, #7 @ Get bit offset
+ and r3, r0, #7 @ Get bit offset
mov r0, #1
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
+ save_and_disable_irqs ip, r2
ldrb r2, [r1]
tst r2, r0, lsl r3
bic r2, r2, r0, lsl r3
- moveq r0, #0
strb r2, [r1]
- RESTOREIRQS(ip)
+ restore_irqs ip
+ moveq r0, #0
RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 760b6649db90b7..2b59febea551f8 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -12,14 +12,13 @@ ENTRY(test_and_set_bit)
add r1, r1, r0, lsr #3 @ Get byte offset
and r3, r0, #7 @ Get bit offset
mov r0, #1
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
+ save_and_disable_irqs ip, r2
ldrb r2, [r1]
tst r2, r0, lsl r3
orr r2, r2, r0, lsl r3
- moveq r0, #0
strb r2, [r1]
- RESTOREIRQS(ip)
+ restore_irqs ip
+ moveq r0, #0
RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index 00f987b5f06feb..e95160e38b9f25 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -538,13 +538,18 @@ USER( ldrget r3, [r1], #0) @ May fault
.section .fixup,"ax"
.align 0
- /* We took an exception. Zero out the buffer and pretend no
- data was copied. */
-9001: ldr r0, [sp], #4
- ldr r1, [sp]
- teq r1, #0
+ /*
+ * We took an exception. r0 contains a pointer to
+ * the byte not copied.
+ */
+9001: ldr r2, [sp], #4 @ void *to
+ sub r2, r0, r2 @ bytes copied
+ ldr r1, [sp], #4 @ unsigned long count
+ subs r4, r1, r2 @ bytes left to copy
+ movne r1, r4
blne SYMBOL_NAME(__memzero)
- LOADREGS(fd,sp!, {r0, r4 - r7, pc})
+ mov r0, r4
+ LOADREGS(fd,sp!, {r4 - r7, pc})
.previous
/* Prototype: int __arch_clear_user(void *addr, size_t sz)
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 26d7f1058644da..faedecd2de016f 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -22,6 +22,9 @@ ifeq ($(CONFIG_CPU_32),y)
ifeq ($(CONFIG_CPU_ARM7),y)
P_OBJS += proc-arm6,7.o
endif
+ ifeq ($(CONFIG_CPU_ARM720),y)
+ P_OBJS += proc-arm720.o
+ endif
ifeq ($(CONFIG_CPU_SA110),y)
P_OBJS += proc-sa110.o
endif
@@ -41,5 +44,6 @@ fault-armv.o: fault-common.c
fault-armo.o: fault-common.c
proc-arm2,3.o: ../lib/constants.h
proc-arm6,7.o: ../lib/constants.h
+proc-arm720.o: ../lib/constants.h
proc-sa110.o: ../lib/constants.h
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 310107678c9835..b21bc1d8a14e7f 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -9,8 +9,10 @@
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/pci.h>
+#include <linux/init.h>
#include <asm/io.h>
+#include <asm/pgtable.h>
#include <asm/pgalloc.h>
/*
@@ -19,6 +21,8 @@
* whether this could be called from an interrupt context or not. For
* now, we expressly forbid it, especially as some of the stuff we do
* here is not interrupt context safe.
+ *
+ * Note that this does *not* zero the allocated area!
*/
void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
{
@@ -36,15 +40,21 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
if (!page)
goto no_page;
- memset((void *)page, 0, size);
- clean_cache_area(page, size);
-
- *dma_handle = virt_to_bus((void *)page);
-
ret = __ioremap(virt_to_phys((void *)page), size, 0);
if (ret) {
/* free wasted pages */
unsigned long end = page + (PAGE_SIZE << order);
+
+ /*
+ * we need to ensure that there are no
+ * cachelines in use, or worse dirty in
+ * this area.
+ */
+ dma_cache_inv(page, size);
+ dma_cache_inv(ret, size);
+
+ *dma_handle = virt_to_bus((void *)page);
+
page += size;
while (page < end) {
free_page(page);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 13336c0080a1fa..c3d03f251e32a5 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -250,6 +250,8 @@ do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
}
}
+if (addr != eaddr)
+printk("PC = %08lx, instr = %08x, addr = %08lx, eaddr = %08lx\n", instruction_pointer(regs), instr, addr, eaddr);
if (LDST_L_BIT(instr)) {
regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
if (rd == 15)
@@ -383,29 +385,38 @@ static const struct fsr_info {
"more information\n"
asmlinkage void
-do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
+do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
{
- const struct fsr_info *inf;
+ const struct fsr_info *inf = fsr_info + (fsr & 15);
- if (user_mode(regs) && addr == regs->ARM_pc) {
+ if (addr == regs->ARM_pc)
+ goto weirdness;
+
+ if (!inf->fn)
+ goto bad;
+
+ if (!inf->fn(addr, error_code, regs))
+ return;
+bad:
+ force_sig(inf->sig, current);
+ die_if_kernel(inf->name, regs, fsr);
+ return;
+
+weirdness:
+ if (user_mode(regs)) {
static int first = 1;
- if (first) {
+ if (first)
/*
* I want statistical information on this problem,
* but we don't want to hastle the users too much.
*/
printk(BUG_PROC_MSG, fsr);
- first = 0;
- }
+ first = 0;
return;
}
- inf = fsr_info + (fsr & 15);
-
- if (!inf->fn || inf->fn(addr, error_code, regs)) {
- force_sig(inf->sig, current);
- die_if_kernel(inf->name, regs, fsr);
- }
+ if (!inf->fn || inf->fn(addr, error_code, regs))
+ goto bad;
}
asmlinkage int
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index 14cf5a9250610a..3859377088b53e 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -16,6 +16,10 @@ static void show_pte(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
+ if (!mm)
+ mm = &init_mm;
+
+ printk(KERN_ALERT "pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr);
printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd));
@@ -52,39 +56,78 @@ static void show_pte(struct mm_struct *mm, unsigned long addr)
printk("\n");
}
-/*
- * Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice.
- */
-static void
-kernel_page_fault(unsigned long addr, int write_access, struct pt_regs *regs,
- struct task_struct *tsk, struct mm_struct *mm)
+static int __do_page_fault(struct mm_struct *mm, unsigned long addr, int mode, struct task_struct *tsk)
{
- char *reason;
+ struct vm_area_struct *vma;
+ int fault, mask;
+
+ vma = find_vma(mm, addr);
+ fault = -2; /* bad map area */
+ if (!vma)
+ goto out;
+ if (vma->vm_start > addr)
+ goto check_stack;
- if (addr < PAGE_SIZE)
- reason = "NULL pointer dereference";
+ /*
+ * Ok, we have a good vm_area for this
+ * memory access, so we can handle it.
+ */
+good_area:
+ if (READ_FAULT(mode)) /* read? */
+ mask = VM_READ|VM_EXEC;
else
- reason = "paging request";
+ mask = VM_WRITE;
- printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n",
- reason, addr);
- if (!mm)
- mm = &init_mm;
+ fault = -1; /* bad access type */
+ if (!(vma->vm_flags & mask))
+ goto out;
- printk(KERN_ALERT "pgd = %p\n", mm->pgd);
- show_pte(mm, addr);
- die("Oops", regs, write_access);
+ /*
+ * If for any reason at all we couldn't handle
+ * the fault, make sure we exit gracefully rather
+ * than endlessly redo the fault.
+ */
+survive:
+ fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(mode));
- do_exit(SIGKILL);
+ /*
+ * Handle the "normal" cases first - successful and sigbus
+ */
+ switch (fault) {
+ case 2:
+ tsk->maj_flt++;
+ return fault;
+ case 1:
+ tsk->min_flt++;
+ case 0:
+ return fault;
+ }
+
+ fault = -3; /* out of memory */
+ if (tsk->pid != 1)
+ goto out;
+
+ /*
+ * If we are out of memory for pid1,
+ * sleep for a while and retry
+ */
+ tsk->policy |= SCHED_YIELD;
+ schedule();
+ goto survive;
+
+check_stack:
+ if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
+ goto good_area;
+out:
+ return fault;
}
static int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
{
struct task_struct *tsk;
struct mm_struct *mm;
- struct vm_area_struct *vma;
unsigned long fixup;
+ int fault;
tsk = current;
mm = tsk->mm;
@@ -97,57 +140,77 @@ static int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
goto no_context;
down(&mm->mmap_sem);
- vma = find_vma(mm, addr);
- if (!vma)
- goto bad_area;
- if (vma->vm_start <= addr)
- goto good_area;
- if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack(vma, addr))
- goto bad_area;
+ fault = __do_page_fault(mm, addr, mode, tsk);
+ up(&mm->mmap_sem);
/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
+ * Handle the "normal" case first
*/
-good_area:
- if (READ_FAULT(mode)) { /* read? */
- if (!(vma->vm_flags & (VM_READ|VM_EXEC)))
- goto bad_area;
- } else {
- if (!(vma->vm_flags & VM_WRITE))
- goto bad_area;
- }
+ if (fault > 0)
+ return 0;
/*
- * If for any reason at all we couldn't handle the fault,
- * make sure we exit gracefully rather than endlessly redo
- * the fault.
+ * We had some memory, but were unable to
+ * successfully fix up this page fault.
*/
- if (!handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(mode)))
+ if (fault == 0)
goto do_sigbus;
- up(&mm->mmap_sem);
- return 0;
-
/*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
+ * If we are in kernel mode at this point, we
+ * have no context to handle this fault with.
*/
-bad_area:
- up(&mm->mmap_sem);
+ if (!user_mode(regs))
+ goto no_context;
+
+ if (fault == -3) {
+ /*
+ * We ran out of memory, or some other thing happened to
+ * us that made us unable to handle the page fault gracefully.
+ */
+ printk("VM: killing process %s\n", tsk->comm);
+ do_exit(SIGKILL);
+ } else {
+ /*
+ * Something tried to access memory that isn't in our memory map..
+ * User mode accesses just cause a SIGSEGV
+ */
+ struct siginfo si;
+
+#ifdef CONFIG_DEBUG_USER
+ printk(KERN_DEBUG "%s: unhandled page fault at pc=0x%08lx, "
+ "lr=0x%08lx (bad address=0x%08lx, code %d)\n",
+ tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
+#endif
- /* User mode accesses just cause a SIGSEGV */
- if (user_mode(regs)) {
tsk->thread.address = addr;
tsk->thread.error_code = mode;
tsk->thread.trap_no = 14;
-#ifdef CONFIG_DEBUG_USER
- printk("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
- tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
-#endif
- force_sig(SIGSEGV, tsk);
- return 0;
+ si.si_signo = SIGSEGV;
+ si.si_code = fault == -1 ? SEGV_ACCERR : SEGV_MAPERR;
+ si.si_addr = (void *)addr;
+ force_sig_info(SIGSEGV, &si, tsk);
}
+ return 0;
+
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+do_sigbus:
+ /*
+ * Send a sigbus, regardless of whether we were in kernel
+ * or user mode.
+ */
+ tsk->thread.address = addr;
+ tsk->thread.error_code = mode;
+ tsk->thread.trap_no = 14;
+ force_sig(SIGBUS, tsk);
+
+ /* Kernel mode? Handle exceptions or die */
+ if (user_mode(regs))
+ return 0;
no_context:
/* Are we prepared to handle this kernel fault? */
@@ -160,29 +223,16 @@ no_context:
return 0;
}
- kernel_page_fault(addr, mode, regs, tsk, mm);
- return 0;
-
-do_sigbus:
/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
*/
- up(&mm->mmap_sem);
+ printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n",
+ (addr < PAGE_SIZE) ? "NULL pointer dereference" : "paging request", addr);
- /*
- * Send a sigbus, regardless of whether we were in kernel
- * or user mode.
- */
- tsk->thread.address = addr;
- tsk->thread.error_code = mode;
- tsk->thread.trap_no = 14;
- force_sig(SIGBUS, tsk);
+ show_pte(mm, addr);
+ die("Oops", regs, mode);
+ do_exit(SIGKILL);
- /* Kernel mode? Handle exceptions or die */
- if (!user_mode(regs))
- goto no_context;
return 0;
}
-
-
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 61feb6a553d474..e269e146c6dd2f 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -31,16 +31,23 @@
#include "map.h"
+#ifndef CONFIG_DISCONTIGMEM
+#define NR_NODES 1
+#else
+#define NR_NODES 4
+#endif
+
#ifdef CONFIG_CPU_32
#define TABLE_OFFSET (PTRS_PER_PTE)
#else
#define TABLE_OFFSET 0
#endif
+
#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
static unsigned long totalram_pages;
pgd_t swapper_pg_dir[PTRS_PER_PGD];
-extern int _stext, _text, _etext, _edata, _end;
+extern char _stext, _text, _etext, _end, __init_begin, __init_end;
/*
* The sole use of this is to pass memory configuration
@@ -173,6 +180,12 @@ void show_mem(void)
show_buffers();
}
+struct node_info {
+ unsigned int start;
+ unsigned int end;
+ int bootmap_pages;
+};
+
#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
@@ -183,34 +196,24 @@ void show_mem(void)
#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
(((unsigned long)(s)) & PAGE_MASK))
+/*
+ * FIXME: We really want to avoid allocating the bootmap bitmap
+ * over the top of the initrd. Hopefully, this is located towards
+ * the start of a bank, so if we allocate the bootmap bitmap at
+ * the end, we won't clash.
+ */
static unsigned int __init
-find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages)
+find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
{
unsigned int start_pfn, bank, bootmap_pfn;
start_pfn = V_PFN_UP(&_end);
bootmap_pfn = 0;
- /*
- * FIXME: We really want to avoid allocating the bootmap
- * over the top of the initrd.
- */
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start) {
- if (__pa(initrd_end) > mi->end) {
- printk ("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx) - disabling initrd\n",
- __pa(initrd_end), mi->end);
- initrd_start = 0;
- initrd_end = 0;
- }
- }
-#endif
-
for (bank = 0; bank < mi->nr_banks; bank ++) {
unsigned int start, end;
- if (mi->bank[bank].size == 0)
+ if (mi->bank[bank].node != node)
continue;
start = O_PFN_UP(mi->bank[bank].start);
@@ -239,99 +242,224 @@ find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages)
}
/*
- * Initialise one node of the bootmem allocator. For now, we
- * only initialise node 0. Notice that we have a bootmem
- * bitmap per node.
+ * Scan the memory info structure and pull out:
+ * - the end of memory
+ * - the number of nodes
+ * - the pfn range of each node
+ * - the number of bootmem bitmap pages
*/
-static void __init setup_bootmem_node(int node, struct meminfo *mi)
+static unsigned int __init
+find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
{
- unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn;
- unsigned int i;
+ unsigned int i, bootmem_pages = 0, memend_pfn = 0;
- if (node != 0) /* only initialise node 0 for now */
- return;
+ for (i = 0; i < NR_NODES; i++) {
+ np[i].start = -1U;
+ np[i].end = 0;
+ np[i].bootmap_pages = 0;
+ }
- start_pfn = O_PFN_UP(PHYS_OFFSET);
- end_pfn = O_PFN_DOWN(mi->end);
- bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
- bootmap_pfn = find_bootmap_pfn(mi, bootmap_pages);
+ for (i = 0; i < mi->nr_banks; i++) {
+ unsigned long start, end;
+ int node;
+
+ if (mi->bank[i].size == 0) {
+ /*
+ * Mark this bank with an invalid node number
+ */
+ mi->bank[i].node = -1;
+ continue;
+ }
+
+ node = mi->bank[i].node;
+
+ if (node >= numnodes) {
+ numnodes = node + 1;
+
+ /*
+ * Make sure we haven't exceeded the maximum number
+ * of nodes that we have in this configuration. If
+ * we have, we're in trouble. (maybe we ought to
+ * limit, instead of bugging?)
+ */
+ if (numnodes > NR_NODES)
+ BUG();
+ }
+
+ /*
+ * Get the start and end pfns for this bank
+ */
+ start = O_PFN_UP(mi->bank[i].start);
+ end = O_PFN_DOWN(mi->bank[i].start + mi->bank[i].size);
+
+ if (np[node].start > start)
+ np[node].start = start;
+
+ if (np[node].end < end)
+ np[node].end = end;
+
+ if (memend_pfn < end)
+ memend_pfn = end;
+ }
/*
- * Initialise the boot-time allocator
+ * Calculate the number of pages we require to
+ * store the bootmem bitmaps.
*/
- init_bootmem_node(node, bootmap_pfn, start_pfn, end_pfn);
+ for (i = 0; i < numnodes; i++) {
+ if (np[i].end == 0)
+ continue;
+
+ np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end -
+ np[i].start);
+ bootmem_pages += np[i].bootmap_pages;
+ }
/*
- * Register all available RAM with the bootmem allocator.
+ * This doesn't seem to be used by the Linux memory
+ * manager any more. If we can get rid of it, we
+ * also get rid of some of the stuff above as well.
*/
- for (i = 0; i < mi->nr_banks; i++)
- if (mi->bank[i].size)
- free_bootmem_node(node, mi->bank[i].start,
- PFN_SIZE(mi->bank[i].size) << PAGE_SHIFT);
+ max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+ mi->end = memend_pfn << PAGE_SHIFT;
- reserve_bootmem_node(node, bootmap_pfn << PAGE_SHIFT,
- bootmap_pages << PAGE_SHIFT);
+ return bootmem_pages;
}
-/*
- * Initialise the bootmem allocator.
- */
-void __init bootmem_init(struct meminfo *mi)
+static int __init check_initrd(struct meminfo *mi)
{
- unsigned int i, node;
+ int initrd_node = -2;
+#ifdef CONFIG_BLK_DEV_INITRD
/*
- * Calculate the physical address of the top of memory.
- * Note that there are no guarantees assumed about the
- * ordering of the bank information.
+ * Make sure that the initrd is within a valid area of
+ * memory.
*/
- mi->end = 0;
- for (i = 0; i < mi->nr_banks; i++) {
- unsigned long end;
+ if (initrd_start) {
+ unsigned long phys_initrd_start, phys_initrd_end;
+ unsigned int i;
+
+ phys_initrd_start = __pa(initrd_start);
+ phys_initrd_end = __pa(initrd_end);
- if (mi->bank[i].size != 0) {
- end = mi->bank[i].start + mi->bank[i].size;
- if (mi->end < end)
- mi->end = end;
+ for (i = 0; i < mi->nr_banks; i++) {
+ unsigned long bank_end;
+
+ bank_end = mi->bank[i].start + mi->bank[i].size;
+
+ if (mi->bank[i].start <= phys_initrd_start &&
+ phys_initrd_end <= bank_end)
+ initrd_node = mi->bank[i].node;
}
}
- max_low_pfn = O_PFN_DOWN(mi->end - PHYS_OFFSET);
+ if (initrd_node == -1) {
+ printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
+ "physical memory - disabling initrd\n",
+ initrd_start, initrd_end);
+ initrd_start = initrd_end = 0;
+ }
+#endif
- /*
- * Setup each node
- */
- for (node = 0; node < numnodes; node++)
- setup_bootmem_node(node, mi);
+ return initrd_node;
+}
+/*
+ * Reserve the various regions of node 0
+ */
+static inline void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
+{
/*
* Register the kernel text and data with bootmem.
* Note that this can only be in node 0.
*/
- reserve_bootmem_node(0, V_PFN_DOWN(&_stext) << PAGE_SHIFT,
- PFN_RANGE(&_stext, &_end) << PAGE_SHIFT);
+ reserve_bootmem_node(0, __pa(&_stext), &_end - &_stext);
#ifdef CONFIG_CPU_32
/*
* Reserve the page tables. These are already in use,
* and can only be in node 0.
*/
- reserve_bootmem_node(0, V_PFN_DOWN(swapper_pg_dir) << PAGE_SHIFT,
- PFN_SIZE(PTRS_PER_PGD * sizeof(void *)) << PAGE_SHIFT);
+ reserve_bootmem_node(0, __pa(swapper_pg_dir),
+ PTRS_PER_PGD * sizeof(void *));
#endif
-#ifdef CONFIG_BLK_DEV_INITRD
/*
- * This may be in any bank. Currently, we assume that
- * it is in bank 0.
+ * And don't forget to reserve the allocator bitmap,
+ * which will be freed later.
*/
- if (initrd_start)
- reserve_bootmem_node(0, V_PFN_DOWN(initrd_start) << PAGE_SHIFT,
- PFN_RANGE(initrd_start, initrd_end) << PAGE_SHIFT);
+ reserve_bootmem_node(0, bootmap_pfn << PAGE_SHIFT,
+ bootmap_pages << PAGE_SHIFT);
+}
+
+/*
+ * Register all available RAM in this node with the bootmem allocator.
+ */
+static inline void free_bootmem_node_bank(int node, struct meminfo *mi)
+{
+ int bank;
+
+ for (bank = 0; bank < mi->nr_banks; bank++)
+ if (mi->bank[bank].node == node)
+ free_bootmem_node(node, mi->bank[bank].start,
+ mi->bank[bank].size);
+}
+
+/*
+ * Initialise the bootmem allocator for all nodes. This is called
+ * early during the architecture specific initialisation.
+ */
+void __init bootmem_init(struct meminfo *mi)
+{
+ struct node_info node_info[NR_NODES], *np = node_info;
+ unsigned int bootmap_pages, bootmap_pfn, map_pg;
+ int node, initrd_node;
+
+ bootmap_pages = find_memend_and_nodes(mi, np);
+ bootmap_pfn = find_bootmap_pfn(0, mi, bootmap_pages);
+ initrd_node = check_initrd(mi);
+
+ map_pg = bootmap_pfn;
+
+ for (node = 0; node < numnodes; node++, np++) {
+ /*
+ * If there are no pages in this node, ignore it.
+ * Note that node 0 must always have some pages.
+ */
+ if (np->end == 0) {
+ if (node == 0)
+ BUG();
+ continue;
+ }
+
+ /*
+ * Initialise the bootmem allocator.
+ */
+ init_bootmem_node(node, map_pg, np->start, np->end);
+ free_bootmem_node_bank(node, mi);
+ map_pg += np->bootmap_pages;
+
+ /*
+ * If this is node 0, we need to reserve some areas ASAP -
+ * we may use bootmem on node 0 to setup the other nodes.
+ */
+ if (node == 0)
+ reserve_node_zero(bootmap_pfn, bootmap_pages);
+ }
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_node >= 0)
+ reserve_bootmem_node(initrd_node, __pa(initrd_start),
+ initrd_end - initrd_start);
#endif
+
+ if (map_pg != bootmap_pfn + bootmap_pages)
+ BUG();
}
/*
- * paging_init() sets up the page tables...
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
*/
void __init paging_init(struct meminfo *mi)
{
@@ -378,11 +506,23 @@ void __init paging_init(struct meminfo *mi)
* The size of this node has already been determined.
* If we need to do anything fancy with the allocation
* of this memory to the zones, now is the time to do
- * it. For now, we don't touch zhole_size.
+ * it.
*/
zone_size[0] = bdata->node_low_pfn -
(bdata->node_boot_start >> PAGE_SHIFT);
+ /*
+ * For each bank in this node, calculate the size of the
+ * holes. holes = node_size - sum(bank_sizes_in_node)
+ */
+ zhole_size[0] = zone_size[0];
+ for (i = 0; i < mi->nr_banks; i++) {
+ if (mi->bank[i].node != node)
+ continue;
+
+ zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
+ }
+
free_area_init_node(node, pgdat, zone_size,
bdata->node_boot_start, zhole_size);
}
@@ -399,31 +539,6 @@ void __init paging_init(struct meminfo *mi)
empty_bad_pte_table = ((pte_t *)bad_table) + TABLE_OFFSET;
}
-static inline void free_unused_mem_map(void)
-{
- struct page *page, *end;
-
- end = mem_map + max_mapnr;
-
- for (page = mem_map; page < end; page++) {
- unsigned long low, high;
-
- if (!PageSkip(page))
- continue;
-
- low = PAGE_ALIGN((unsigned long)(page + 1));
- if (page->next_hash < page)
- high = ((unsigned long)end) & PAGE_MASK;
- else
- high = ((unsigned long)page->next_hash) & PAGE_MASK;
-
- while (low < high) {
- ClearPageReserved(mem_map + MAP_NR(low));
- low += PAGE_SIZE;
- }
- }
-}
-
/*
* mem_init() marks the free areas in the mem_map and tells us how much
* memory is free. This is done after various parts of the system have
@@ -431,7 +546,6 @@ static inline void free_unused_mem_map(void)
*/
void __init mem_init(void)
{
- extern char __init_begin, __init_end;
unsigned int codepages, datapages, initpages;
int i, node;
@@ -443,8 +557,7 @@ void __init mem_init(void)
max_mapnr = MAP_NR(high_memory);
/*
- * We may have non-contiguous memory. Setup the PageSkip stuff,
- * and mark the areas of mem_map which can be freed
+ * We may have non-contiguous memory.
*/
if (meminfo.nr_banks != 1)
create_memmap_holes(&meminfo);
@@ -500,8 +613,6 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s)
void free_initmem(void)
{
- extern char __init_begin, __init_end;
-
printk("Freeing unused kernel memory:");
free_area((unsigned long)(&__init_begin),
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index f58bc66f5dcec0..34bd513667d693 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -411,50 +411,41 @@ void __init pagetable_init(struct meminfo *mi)
}
/*
- * The mem_map array can get very big. Mark the end of the valid mem_map
- * banks with PG_skip, and setup the address validity bitmap.
+ * The mem_map array can get very big. Free the unused area of the memory map.
*/
-void __init create_memmap_holes(struct meminfo *mi)
+static inline void free_unused_memmap_node(int node, struct meminfo *mi)
{
- unsigned int start_pfn, end_pfn = -1;
- struct page *pg = NULL;
+ unsigned long bank_start, prev_bank_end = 0;
unsigned int i;
-#define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT)
-#define free_bootmem(s,sz) free_bootmem(((s)<<PAGE_SHIFT)+PHYS_OFFSET, (sz)<<PAGE_SHIFT)
-
+ /*
+ * [FIXME] This relies on each bank being in address order. This
+ * may not be the case, especially if the user has provided the
+ * information on the command line.
+ */
for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].size == 0)
+ if (mi->bank[i].size == 0 || mi->bank[i].node != node)
continue;
- start_pfn = PFN(mi->bank[i].start);
+ bank_start = mi->bank[i].start & PAGE_MASK;
/*
- * subtle here - if we have a full bank, then
- * start_pfn == end_pfn, and we don't want to
- * set PG_skip, or next_hash
+ * If we had a previous bank, and there is a space
+ * between the current bank and the previous, free it.
*/
- if (pg && start_pfn != end_pfn) {
- set_bit(PG_skip, &pg->flags);
- pg->next_hash = mem_map + start_pfn;
-
- start_pfn = PFN(PAGE_ALIGN(__pa(pg + 1)));
- end_pfn = PFN(__pa(pg->next_hash) & PAGE_MASK);
+ if (prev_bank_end && prev_bank_end != bank_start)
+ free_bootmem_node(node, prev_bank_end,
+ bank_start - prev_bank_end);
- if (end_pfn != start_pfn)
- free_bootmem(start_pfn, end_pfn - start_pfn);
-
- pg = NULL;
- }
-
- end_pfn = PFN(mi->bank[i].start + mi->bank[i].size);
-
- if (end_pfn != PFN(mi->end))
- pg = mem_map + end_pfn;
+ prev_bank_end = PAGE_ALIGN(mi->bank[i].start +
+ mi->bank[i].size);
}
+}
- if (pg) {
- set_bit(PG_skip, &pg->flags);
- pg->next_hash = NULL;
- }
+void __init create_memmap_holes(struct meminfo *mi)
+{
+ int node;
+
+ for (node = 0; node < numnodes; node++)
+ free_unused_memmap_node(node, mi);
}
diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c
index b67cdec330167d..b11d55a1b51d40 100644
--- a/arch/arm/mm/mm-footbridge.c
+++ b/arch/arm/mm/mm-footbridge.c
@@ -29,7 +29,7 @@
* You can then access the PCI bus at 0xe0000000 and 0xffe00000.
*/
-#ifdef CONFIG_HOST_FOOTBRIDGE
+#ifdef CONFIG_FOOTBRIDGE_HOST
/*
* The mapping when the footbridge is in host mode.
diff --git a/arch/arm/mm/mm-l7200.c b/arch/arm/mm/mm-l7200.c
new file mode 100644
index 00000000000000..14dc5c6e4ff294
--- /dev/null
+++ b/arch/arm/mm/mm-l7200.c
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mm/mm-lusl7200.c
+ *
+ * Extra MM routines for LUSL7200 architecture
+ *
+ * Copyright (C) 2000 Steven J. Hill
+ */
+
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/page.h>
+#include <asm/proc/domain.h>
+#include <asm/setup.h>
+
+#include "map.h"
+
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+struct map_desc io_desc[] __initdata = {
+ { IO_BASE, IO_START, IO_SIZE, DOMAIN_IO, 0, 1 ,0 ,0},
+ { IO_BASE_2, IO_START_2, IO_SIZE_2, DOMAIN_IO, 0, 1 ,0 ,0},
+};
+
+unsigned int __initdata io_desc_size = SIZE(io_desc);
diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c
index 9d9306dd4ecd3f..328364e5600cc0 100644
--- a/arch/arm/mm/mm-sa1100.c
+++ b/arch/arm/mm/mm-sa1100.c
@@ -11,13 +11,14 @@
* Memory is listed physically now.
*
* 2000/04/07 Nicolas Pitre <nico@cam.org>
- * Reworked for real-time selection of memory definitions
+ * Reworked for run-time selection of memory definitions
*
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -44,7 +45,9 @@
static struct map_desc assabet_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_ASSABET
{ 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */
{ 0xdc000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */
+ { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
SA1100_STD_IO_MAPPING
#endif
};
@@ -141,3 +144,20 @@ void __init select_sa1100_io_desc(void)
}
}
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Our node_data structure for discontigous memory.
+ * There is 4 possible nodes i.e. the 4 SA1100 RAM banks.
+ */
+
+static bootmem_data_t node_bootmem_data[4];
+
+pg_data_t sa1100_node_data[4] =
+{ { bdata: &node_bootmem_data[0] },
+ { bdata: &node_bootmem_data[1] },
+ { bdata: &node_bootmem_data[2] },
+ { bdata: &node_bootmem_data[3] } };
+
+#endif
+
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index c2f4f2346628c4..5d7605b851ba1c 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -93,37 +93,30 @@ ENTRY(cpu_arm7_flush_tlb_page)
* Purpose : obtain information about current aborted instruction
*
* Returns : r0 = address of abort
- * : r1 = FSR
- * : r2 != 0 if writing
+ * : r1 != 0 if writing
+ * : r3 = FSR
* : sp = pointer to registers
*/
-Lukabttxt: .ascii "Unknown data abort code %d [pc=%p, *pc=%p] LR=%p\0"
- .align
-
-msg: .ascii "DA*%p=%p\n\0"
- .align
-
ENTRY(cpu_arm6_data_abort)
ldr r4, [r0] @ read instruction causing problem
- mov r2, r4, lsr #19 @ r2 b1 = L
- and r1, r4, #14 << 24
- and r2, r2, #2 @ check read/write bit
- teq r1, #4 << 23
+ mov r1, r4, lsr #19 @ r1 b1 = L
+ and r2, r4, #14 << 24
+ and r1, r1, #2 @ check read/write bit
+ teq r2, #8 << 24 @ was it ldm/stm
bne Ldata_simple
-
Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit
beq Ldata_simple
mov r7, #0x11
orr r7, r7, r7, lsl #8
and r0, r4, r7
- and r1, r4, r7, lsl #1
- add r0, r0, r1, lsr #1
- and r1, r4, r7, lsl #2
- add r0, r0, r1, lsr #2
- and r1, r4, r7, lsl #3
- add r0, r0, r1, lsr #3
+ and r2, r4, r7, lsl #1
+ add r0, r0, r2, lsr #1
+ and r2, r4, r7, lsl #2
+ add r0, r0, r2, lsr #2
+ and r2, r4, r7, lsl #3
+ add r0, r0, r2, lsr #3
add r0, r0, r0, lsr #8
add r0, r0, r0, lsr #4
and r7, r0, #15 @ r7 = no. of registers to transfer.
@@ -134,16 +127,16 @@ Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit
addeq r7, r0, r7, lsl #2 @ Do correction (signed)
Ldata_saver7: str r7, [sp, r5, lsr #14] @ Put register
Ldata_simple: mrc p15, 0, r0, c6, c0, 0 @ get FAR
- mrc p15, 0, r1, c5, c0, 0 @ get FSR
- and r1, r1, #255
+ mrc p15, 0, r3, c5, c0, 0 @ get FSR
+ and r3, r3, #255
mov pc, lr
ENTRY(cpu_arm7_data_abort)
ldr r4, [r0] @ read instruction causing problem
- mov r2, r4, lsr #19 @ r2 b1 = L
- and r1, r4, #15 << 24
- and r2, r2, #2 @ check read/write bit
- add pc, pc, r1, lsr #22 @ Now branch to the relevent processing routine
+ mov r1, r4, lsr #19 @ r1 b1 = L
+ and r2, r4, #15 << 24
+ and r1, r1, #2 @ check read/write bit
+ add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine
movs pc, lr
b Ldata_unknown
@@ -162,7 +155,7 @@ ENTRY(cpu_arm7_data_abort)
b Ldata_simple @ ldc rd, [rn, #m]
b Ldata_unknown
Ldata_unknown: @ Part of jumptable
- mov r0, r1
+ mov r0, r2
mov r1, r4
mov r2, r3
b baddataabort
@@ -172,13 +165,13 @@ Ldata_lateldrpreconst:
tst r4, #1 << 21 @ check writeback bit
beq Ldata_simple
Ldata_lateldrpostconst:
- movs r1, r4, lsl #20 @ Get offset
+ movs r2, r4, lsl #20 @ Get offset
beq Ldata_simple
and r5, r4, #15 << 16 @ Get Rn
ldr r0, [sp, r5, lsr #14]
tst r4, #1 << 23 @ U bit
- subne r7, r0, r1, lsr #20
- addeq r7, r0, r1, lsr #20
+ subne r7, r0, r2, lsr #20
+ addeq r7, r0, r2, lsr #20
b Ldata_saver7
Ldata_lateldrprereg:
@@ -186,7 +179,7 @@ Ldata_lateldrprereg:
beq Ldata_simple
Ldata_lateldrpostreg:
and r5, r4, #15
- ldr r1, [sp, r5, lsl #2] @ Get Rm
+ ldr r2, [sp, r5, lsl #2] @ Get Rm
mov r3, r4, lsr #7
ands r3, r3, #31
and r6, r4, #0x70
@@ -194,7 +187,7 @@ Ldata_lateldrpostreg:
add pc, pc, r6
mov r0, r0
- mov r1, r1, lsl r3 @ 0: LSL #!0
+ mov r2, r2, lsl r3 @ 0: LSL #!0
b 1f
b 1f @ 1: LSL #0
mov r0, r0
@@ -202,25 +195,25 @@ Ldata_lateldrpostreg:
mov r0, r0
b 1f @ 3: MUL?
mov r0, r0
- mov r1, r1, lsr r3 @ 4: LSR #!0
+ mov r2, r2, lsr r3 @ 4: LSR #!0
b 1f
- mov r1, r1, lsr #32 @ 5: LSR #32
+ mov r2, r2, lsr #32 @ 5: LSR #32
b 1f
b 1f @ 6: MUL?
mov r0, r0
b 1f @ 7: MUL?
mov r0, r0
- mov r1, r1, asr r3 @ 8: ASR #!0
+ mov r2, r2, asr r3 @ 8: ASR #!0
b 1f
- mov r1, r1, asr #32 @ 9: ASR #32
+ mov r2, r2, asr #32 @ 9: ASR #32
b 1f
b 1f @ A: MUL?
mov r0, r0
b 1f @ B: MUL?
mov r0, r0
- mov r1, r1, ror r3 @ C: ROR #!0
+ mov r2, r2, ror r3 @ C: ROR #!0
b 1f
- mov r1, r1, rrx @ D: RRX
+ mov r2, r2, rrx @ D: RRX
b 1f
mov r0, r0 @ E: MUL?
mov r0, r0
@@ -230,8 +223,8 @@ Ldata_lateldrpostreg:
1: and r5, r4, #15 << 16 @ Get Rn
ldr r0, [sp, r5, lsr #14]
tst r4, #1 << 23 @ U bit
- subne r7, r0, r1
- addeq r7, r0, r1
+ subne r7, r0, r2
+ addeq r7, r0, r2
b Ldata_saver7
/*
@@ -254,7 +247,8 @@ ENTRY(cpu_arm7_proc_init)
ENTRY(cpu_arm6_proc_fin)
ENTRY(cpu_arm7_proc_fin)
- msr cpsr_c, #F_BIT | I_BIT | SVC_MODE
+ mov r0, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, r0
mov r0, #0x31 @ ....S..DP...M
mcr p15, 0, r0, c1, c0, 0 @ disable caches
mov pc, lr
@@ -364,7 +358,8 @@ cpu_arm710_name:
.section ".text.init", #alloc, #execinstr
-__arm6_setup: msr cpsr_c, #F_BIT | I_BIT | SVC_MODE
+__arm6_setup: mov r0, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, r0
mov r0, #0
mcr p15, 0, r0, c7, c0 @ flush caches on v3
mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
@@ -375,7 +370,8 @@ __arm6_setup: msr cpsr_c, #F_BIT | I_BIT | SVC_MODE
orr r0, r0, #0x100
mov pc, lr
-__arm7_setup: msr cpsr_c, #F_BIT | I_BIT | SVC_MODE
+__arm7_setup: mov r0, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, r0
mov r0, #0
mcr p15, 0, r0, c7, c0 @ flush caches on v3
mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
new file mode 100644
index 00000000000000..738ff9a434079e
--- /dev/null
+++ b/arch/arm/mm/proc-arm720.S
@@ -0,0 +1,398 @@
+/*
+ * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720
+ *
+ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
+ * Rob Scott (rscott@mtrob.fdns.net)
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM720T.
+ *
+ * Changelog:
+ * 05-09-2000 SJH Created by moving 720 specific functions
+ * out of 'proc-arm6,7.S' per RSK discussion
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/procinfo.h>
+#include <asm/errno.h>
+#include "../lib/constants.h"
+
+/*
+ * Function: arm720_flush_cache_all (void)
+ * : arm720_flush_cache_page (unsigned long address, int size,
+ * int flags)
+ *
+ * Params : address Area start address
+ * : size size of area
+ * : flags b0 = I cache as well
+ *
+ * Purpose : Flush all cache lines
+ */
+ENTRY(cpu_arm720_flush_cache_all)
+ENTRY(cpu_arm720_flush_cache_area)
+ENTRY(cpu_arm720_flush_cache_entry)
+ENTRY(cpu_arm720_flush_icache_area)
+ENTRY(cpu_arm720_flush_icache_page)
+ENTRY(cpu_arm720_cache_wback_area)
+ENTRY(cpu_arm720_cache_purge_area)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ flush cache
+ mov pc, lr
+
+ENTRY(cpu_arm720_clean_cache_area)
+ENTRY(cpu_arm720_flush_ram_page)
+ mov pc, lr
+
+/*
+ * Function: arm720_flush_tlb_all (void)
+ *
+ * Purpose : flush all TLB entries in all caches
+ */
+ENTRY(cpu_arm720_flush_tlb_all)
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
+ mov pc, lr
+
+/*
+ * Function: arm720_flush_tlb_page (unsigned long address, int end, int flags)
+ *
+ * Params : address Area start address
+ * : end Area end address
+ * : flags b0 = I cache as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm720_flush_tlb_area)
+1: mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4)
+ add r0, r0, #4096
+ cmp r0, r1
+ blt 1b
+ mov pc, lr
+
+/*
+ * Function: arm720_flush_tlb_page (unsigned long address, int flags)
+ *
+ * Params : address Address
+ * : flags b0 = I-TLB as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm720_flush_tlb_page)
+ mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4)
+ mov pc, lr
+
+/*
+ * Function: arm720_data_abort ()
+ *
+ * Params : r0 = address of aborted instruction
+ *
+ * Purpose : obtain information about current aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 != 0 if writing
+ * : r3 = FSR
+ * : sp = pointer to registers
+ */
+
+Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit
+ beq Ldata_simple
+ mov r7, #0x11
+ orr r7, r7, r7, lsl #8
+ and r0, r4, r7
+ and r2, r4, r7, lsl #1
+ add r0, r0, r2, lsr #1
+ and r2, r4, r7, lsl #2
+ add r0, r0, r2, lsr #2
+ and r2, r4, r7, lsl #3
+ add r0, r0, r2, lsr #3
+ add r0, r0, r0, lsr #8
+ add r0, r0, r0, lsr #4
+ and r7, r0, #15 @ r7 = no. of registers to transfer.
+ and r5, r4, #15 << 16 @ Get Rn
+ ldr r0, [sp, r5, lsr #14] @ Get register
+ tst r4, #1 << 23 @ U bit
+ subne r7, r0, r7, lsl #2
+ addeq r7, r0, r7, lsl #2 @ Do correction (signed)
+Ldata_saver7: str r7, [sp, r5, lsr #14] @ Put register
+Ldata_simple: mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ mrc p15, 0, r3, c5, c0, 0 @ get FSR
+ and r3, r3, #15
+ mov pc, lr
+
+ENTRY(cpu_arm720_data_abort)
+ ldr r4, [r0] @ read instruction causing problem
+ mov r1, r4, lsr #19 @ r1 b1 = L
+ and r2, r4, #15 << 24
+ and r1, r1, #2 @ check read/write bit
+ add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine
+ movs pc, lr
+
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_lateldrpostconst @ ldr rd, [rn], #m
+ b Ldata_lateldrpreconst @ ldr rd, [rn, #m] @ RegVal
+ b Ldata_lateldrpostreg @ ldr rd, [rn], rm
+ b Ldata_lateldrprereg @ ldr rd, [rn, rm]
+ b Ldata_ldmstm @ ldm*a rn, <rlist>
+ b Ldata_ldmstm @ ldm*b rn, <rlist>
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_simple @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
+ b Ldata_simple @ ldc rd, [rn, #m]
+ b Ldata_unknown
+Ldata_unknown: @ Part of jumptable
+ mov r0, r2
+ mov r1, r4
+ mov r2, r3
+ b baddataabort
+
+
+Ldata_lateldrpreconst:
+ tst r4, #1 << 21 @ check writeback bit
+ beq Ldata_simple
+Ldata_lateldrpostconst:
+ movs r2, r4, lsl #20 @ Get offset
+ beq Ldata_simple
+ and r5, r4, #15 << 16 @ Get Rn
+ ldr r0, [sp, r5, lsr #14]
+ tst r4, #1 << 23 @ U bit
+ subne r7, r0, r2, lsr #20
+ addeq r7, r0, r2, lsr #20
+ b Ldata_saver7
+
+Ldata_lateldrprereg:
+ tst r4, #1 << 21 @ check writeback bit
+ beq Ldata_simple
+Ldata_lateldrpostreg:
+ and r5, r4, #15
+ ldr r2, [sp, r5, lsl #2] @ Get Rm
+ mov r3, r4, lsr #7
+ ands r3, r3, #31
+ and r6, r4, #0x70
+ orreq r6, r6, #8
+ add pc, pc, r6
+ mov r0, r0
+
+ mov r2, r2, lsl r3 @ 0: LSL #!0
+ b 1f
+ b 1f @ 1: LSL #0
+ mov r0, r0
+ b 1f @ 2: MUL?
+ mov r0, r0
+ b 1f @ 3: MUL?
+ mov r0, r0
+ mov r2, r2, lsr r3 @ 4: LSR #!0
+ b 1f
+ mov r2, r2, lsr #32 @ 5: LSR #32
+ b 1f
+ b 1f @ 6: MUL?
+ mov r0, r0
+ b 1f @ 7: MUL?
+ mov r0, r0
+ mov r2, r2, asr r3 @ 8: ASR #!0
+ b 1f
+ mov r2, r2, asr #32 @ 9: ASR #32
+ b 1f
+ b 1f @ A: MUL?
+ mov r0, r0
+ b 1f @ B: MUL?
+ mov r0, r0
+ mov r2, r2, ror r3 @ C: ROR #!0
+ b 1f
+ mov r2, r2, rrx @ D: RRX
+ b 1f
+ mov r0, r0 @ E: MUL?
+ mov r0, r0
+ mov r0, r0 @ F: MUL?
+
+
+1: and r5, r4, #15 << 16 @ Get Rn
+ ldr r0, [sp, r5, lsr #14]
+ tst r4, #1 << 23 @ U bit
+ subne r7, r0, r2
+ addeq r7, r0, r2
+ b Ldata_saver7
+
+/*
+ * Function: arm720_check_bugs (void)
+ * : arm720_proc_init (void)
+ * : arm720_proc_fin (void)
+ * : arm720_proc_do_idle (void)
+ *
+ * Notes : This processor does not require these
+ */
+ENTRY(cpu_arm720_check_bugs)
+ mrs ip, cpsr
+ bic ip, ip, #F_BIT
+ msr cpsr, ip
+ mov pc, lr
+
+ENTRY(cpu_arm720_proc_init)
+ mov pc, lr
+
+ENTRY(cpu_arm720_proc_fin)
+ mrs r0, cpsr
+ orr r0, r0, #F_BIT | I_BIT
+ msr cpsr, r0
+ mov r0, #0x31 @ ....S..DP...M
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+ENTRY(cpu_arm720_do_idle)
+ mov r0, #-EINVAL
+ mov pc, lr
+
+/*
+ * Function: arm720_set_pgd(unsigned long pgd_phys)
+ * Params : pgd_phys Physical address of page table
+ * Purpose : Perform a task switch, saving the old process' state and restoring
+ * the new.
+ */
+ENTRY(cpu_arm720_set_pgd)
+ mov r1, #0
+ mcr p15, 0, r1, c7, c7, 0 @ flush cache
+ mcr p15, 0, r0, c2, c0, 0 @ update page table ptr
+ mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4)
+ mov pc, lr
+
+/*
+ * Function: arm720_set_pmd ()
+ *
+ * Params : r0 = Address to set
+ * : r1 = value to set
+ *
+ * Purpose : Set a PMD and flush it out of any WB cache
+ */
+ENTRY(cpu_arm720_set_pmd)
+ tst r1, #3
+ orrne r1, r1, #16 @ Updatable bit is
+ str r1, [r0] @ always set on ARM720
+ mov pc, lr
+
+/*
+ * Function: arm720_set_pte(pte_t *ptep, pte_t pte)
+ * Params : r0 = Address to set
+ * : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+ .align 5
+ENTRY(cpu_arm720_set_pte)
+ str r1, [r0], #-1024 @ linux version
+
+ eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+ bic r2, r1, #0xff0
+ bic r2, r2, #3
+ orr r2, r2, #HPTE_TYPE_SMALL
+
+ tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
+ orrne r2, r2, #HPTE_AP_READ
+
+ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+ orreq r2, r2, #HPTE_AP_WRITE
+
+ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young
+ movne r2, #0
+
+ str r2, [r0] @ hardware version
+
+ mcr p15, 0, r0, c7, c7, 0 @ flush cache
+ mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
+ mov pc, lr
+
+/*
+ * Function: arm720_reset
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ENTRY(cpu_arm720_reset)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ flush cache
+ mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
+ mov pc, lr
+
+
+cpu_armvlsi_name:
+ .asciz "ARM/VLSI"
+cpu_arm720_name:
+ .asciz "ARM 720"
+ .align
+
+ .section ".text.init", #alloc, #execinstr
+
+__arm720_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ flush caches on v4
+ mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
+ mcr p15, 0, r4, c2, c0 @ load page table pointer
+ mov r0, #0x1f @ Domains 0, 1 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+
+ /* Set CP15 Control reg bits (RSBLDPWCAM) */
+ mov r0, #0x7d @ ...LDPWC.M
+ orr r0, r0, #0x100 @ .S.LDPWC.M
+ mov pc, lr @ __ret (head-armv.S)
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ * come through these
+ */
+ .type arm720_processor_functions, #object
+ENTRY(arm720_processor_functions)
+ .word cpu_arm720_data_abort
+ .word cpu_arm720_check_bugs
+ .word cpu_arm720_proc_init
+ .word cpu_arm720_proc_fin
+ .word cpu_arm720_flush_cache_all
+ .word cpu_arm720_flush_cache_area
+ .word cpu_arm720_flush_cache_entry
+ .word cpu_arm720_clean_cache_area
+ .word cpu_arm720_flush_ram_page
+ .word cpu_arm720_flush_tlb_all
+ .word cpu_arm720_flush_tlb_area
+ .word cpu_arm720_set_pgd
+ .word cpu_arm720_set_pmd
+ .word cpu_arm720_set_pte
+ .word cpu_arm720_reset
+ .word cpu_arm720_flush_icache_area
+ .word cpu_arm720_cache_wback_area
+ .word cpu_arm720_cache_purge_area
+ .word cpu_arm720_flush_tlb_page
+ .word cpu_arm720_do_idle
+ .word cpu_arm720_flush_icache_page
+ .size arm720_processor_functions, . - arm720_processor_functions
+
+ .type cpu_arm720_info, #object
+cpu_arm720_info:
+ .long cpu_armvlsi_name
+ .long cpu_arm720_name
+ .size cpu_arm720_info, . - cpu_arm720_info
+
+ .type cpu_arch_name, #object
+cpu_arch_name: .asciz "armv4"
+ .size cpu_arch_name, . - cpu_arch_name
+
+ .type cpu_elf_name, #object
+cpu_elf_name: .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
+ .align
+
+/*
+ * See /include/asm-arm for a definition of this structure.
+ */
+
+ .section ".proc.info", #alloc, #execinstr
+
+ .type __arm720_proc_info, #object
+__arm720_proc_info:
+ .long 0x41807200 @ cpu_val
+ .long 0xffffff00 @ cpu_mask
+ .long 0x00000c12 @ __cpu_mmu_flags
+ b __arm720_setup @ --cpu_flush
+ .long cpu_arch_name @ arch_name
+ .long cpu_elf_name @ elf_name
+ .long HWCAP_SWP | HWCAP_26BIT @ elf_hwcap
+ .long cpu_arm720_info @ info
+ .long arm720_processor_functions
+ .size __arm720_proc_info, . - __arm720_proc_info
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index ac5d0735ec0a83..8c7a6b749847f1 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -7,6 +7,9 @@
* functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110.
*
* Note that SA1100 and SA1110 share everything but their name and CPU ID.
+ *
+ * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
+ * Flush the read buffer at context switches
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
@@ -82,6 +85,7 @@ cpu_sa1100_flush_cache_all_r2:
mov ip, #0
teq r2, #0
mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
+ mcr p15, 0, r1, c9, c0, 0 @ flush RB
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov pc, lr
@@ -300,19 +304,18 @@ ENTRY(cpu_sa1100_flush_icache_page)
* Params : r0 = address of aborted instruction
* Purpose : obtain information about current aborted instruction
* Returns : r0 = address of abort
- * : r1 = FSR
- * : r2 != 0 if writing
+ * : r1 != 0 if writing
+ * : r3 = FSR
*/
.align 5
ENTRY(cpu_sa110_data_abort)
ENTRY(cpu_sa1100_data_abort)
- ldr r2, [r0] @ read instruction causing problem
+ ldr r1, [r0] @ read instruction causing problem
mrc p15, 0, r0, c6, c0, 0 @ get FAR
- mov r2, r2, lsr #19 @ b1 = L
- and r3, r2, #0x69 << 2
- and r2, r2, #2
- mrc p15, 0, r1, c5, c0, 0 @ get FSR
- and r1, r1, #255
+ mov r1, r1, lsr #19 @ b1 = L
+ and r1, r1, #2
+ mrc p15, 0, r3, c5, c0, 0 @ get FSR
+ and r3, r3, #255
mov pc, lr
.align 5
@@ -351,6 +354,7 @@ ENTRY(cpu_sa1100_set_pgd)
flush_1100_dcache r3, ip, r1
mov r1, #0
mcr p15, 0, r1, c7, c5, 0 @ flush I cache
+ mcr p15, 0, r1, c9, c0, 0 @ flush RB
mcr p15, 0, r1, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
mcr p15, 0, r1, c8, c7, 0 @ flush TLBs
@@ -423,7 +427,8 @@ ENTRY(cpu_sa1100_proc_init)
ENTRY(cpu_sa110_proc_fin)
stmfd sp!, {r1, lr}
- msr cpsr_c, #F_BIT | I_BIT | SVC_MODE
+ mov ip, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, ip
bl cpu_sa110_flush_cache_all @ clean caches
1: mov r0, #0
mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
@@ -435,7 +440,8 @@ ENTRY(cpu_sa110_proc_fin)
ENTRY(cpu_sa1100_proc_fin)
stmfd sp!, {r1, lr}
- msr cpsr_c, #F_BIT | I_BIT | SVC_MODE
+ mov ip, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, ip
bl cpu_sa1100_flush_cache_all @ clean caches
b 1b
@@ -501,7 +507,11 @@ cpu_sa1110_name:
.section ".text.init", #alloc, #execinstr
-__sa110_setup: msr cpsr_c, #F_BIT | I_BIT | SVC_MODE
+__sa1100_setup: @ Allow read-buffer operations from userland
+ mcr p15, 0, r0, c9, c0, 5
+
+__sa110_setup: mov r0, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, r0
mov r0, #0
mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
@@ -623,7 +633,7 @@ __sa1100_proc_info:
.long 0x4401a110
.long 0xfffffff0
.long 0x00000c02
- b __sa110_setup
+ b __sa1100_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
@@ -636,7 +646,7 @@ __sa1110_proc_info:
.long 0x6901b110
.long 0xfffffff0
.long 0x00000c02
- b __sa110_setup
+ b __sa1100_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 0a19bb758be610..6a1a8aa40dc13d 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -325,18 +325,18 @@ void __init init_apic_mappings(void)
*/
static unsigned int __init get_8254_timer_count(void)
{
- extern rwlock_t xtime_lock;
+ extern spinlock_t i8253_lock;
unsigned long flags;
unsigned int count;
- write_lock_irqsave(&xtime_lock, flags);
+ spin_lock_irqsave(&i8253_lock, flags);
outb_p(0x00, 0x43);
count = inb_p(0x40);
count |= inb_p(0x40) << 8;
- write_unlock_irqrestore(&xtime_lock, flags);
+ spin_unlock_irqrestore(&i8253_lock, flags);
return count;
}
@@ -423,21 +423,21 @@ void setup_APIC_timer(void * data)
__setup_APIC_LVTT(clocks);
- t0 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
+ t0 = apic_read(APIC_TMICT)*APIC_DIVISOR;
+ /* Wait till TMCCT gets reloaded from TMICT... */
+ do {
+ t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
+ delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
+ } while (delta >= 0);
+ /* Now wait for our slice for real. */
do {
- /*
- * It looks like the 82489DX cannot handle
- * consecutive reads of the TMCCT register well;
- * this dummy read prevents it from a lockup.
- */
- apic_read(APIC_SPIV);
t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
} while (delta < 0);
__setup_APIC_LVTT(clocks);
- printk("CPU%d<C0:%d,C:%d,D:%d,S:%d,C:%d>\n",
+ printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n",
smp_processor_id(), t0, t1, delta, slice, clocks);
__restore_flags(flags);
@@ -464,7 +464,7 @@ int __init calibrate_APIC_clock(void)
int i;
const int LOOPS = HZ/10;
- printk("calibrating APIC timer ... ");
+ printk("calibrating APIC timer ...\n");
/*
* Put whatever arbitrary (but long enough) timeout
@@ -509,7 +509,7 @@ int __init calibrate_APIC_clock(void)
result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
if (cpu_has_tsc)
- printk("\n..... CPU clock speed is %ld.%04ld MHz.\n",
+ printk("..... CPU clock speed is %ld.%04ld MHz.\n",
((long)(t2-t1)/LOOPS)/(1000000/HZ),
((long)(t2-t1)/LOOPS)%(1000000/HZ));
@@ -701,7 +701,7 @@ asmlinkage void smp_spurious_interrupt(void)
ack_APIC_irq();
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
- printk("spurious APIC interrupt on CPU#%d, should never happen.\n",
+ printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
smp_processor_id());
}
@@ -718,32 +718,32 @@ asmlinkage void smp_error_interrupt(void)
spin_lock(&err_lock);
v = apic_read(APIC_ESR);
- printk("APIC error interrupt on CPU#%d, should never happen.\n",
+ printk(KERN_INFO "APIC error interrupt on CPU#%d, should never happen.\n",
smp_processor_id());
- printk("... APIC ESR0: %08lx\n", v);
+ printk(KERN_INFO "... APIC ESR0: %08lx\n", v);
apic_write(APIC_ESR, 0);
v |= apic_read(APIC_ESR);
- printk("... APIC ESR1: %08lx\n", v);
+ printk(KERN_INFO "... APIC ESR1: %08lx\n", v);
/*
* Be a bit more verbose. (multiple bits can be set)
*/
if (v & 0x01)
- printk("... bit 0: APIC Send CS Error (hw problem).\n");
+ printk(KERN_INFO "... bit 0: APIC Send CS Error (hw problem).\n");
if (v & 0x02)
- printk("... bit 1: APIC Receive CS Error (hw problem).\n");
+ printk(KERN_INFO "... bit 1: APIC Receive CS Error (hw problem).\n");
if (v & 0x04)
- printk("... bit 2: APIC Send Accept Error.\n");
+ printk(KERN_INFO "... bit 2: APIC Send Accept Error.\n");
if (v & 0x08)
- printk("... bit 3: APIC Receive Accept Error.\n");
+ printk(KERN_INFO "... bit 3: APIC Receive Accept Error.\n");
if (v & 0x10)
- printk("... bit 4: Reserved!.\n");
+ printk(KERN_INFO "... bit 4: Reserved!.\n");
if (v & 0x20)
- printk("... bit 5: Send Illegal Vector (kernel bug).\n");
+ printk(KERN_INFO "... bit 5: Send Illegal Vector (kernel bug).\n");
if (v & 0x40)
- printk("... bit 6: Received Illegal Vector.\n");
+ printk(KERN_INFO "... bit 6: Received Illegal Vector.\n");
if (v & 0x80)
- printk("... bit 7: Illegal Register Address.\n");
+ printk(KERN_INFO "... bit 7: Illegal Register Address.\n");
ack_APIC_irq();
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 26f3d505de7885..c8508aad14ac26 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -78,6 +78,7 @@ addr_limit = 12
exec_domain = 16
need_resched = 20
processor = 56
+tsk_ptrace = 60
ENOSYS = 38
@@ -180,7 +181,7 @@ ENTRY(ret_from_fork)
call SYMBOL_NAME(schedule_tail)
addl $4, %esp
GET_CURRENT(%ebx)
- testb $0x20,flags(%ebx) # PF_TRACESYS
+ testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS
jne tracesys_exit
jmp ret_from_sys_call
@@ -197,7 +198,7 @@ ENTRY(system_call)
GET_CURRENT(%ebx)
cmpl $(NR_syscalls),%eax
jae badsys
- testb $0x20,flags(%ebx) # PF_TRACESYS
+ testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS
jne tracesys
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index fff171c241a5ce..ac5de1f2f509ce 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -127,7 +127,7 @@ void (*interrupt[NR_IRQS])(void) = {
* moves to arch independent land
*/
-static spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
static void end_8259A_irq (unsigned int irq)
{
@@ -180,10 +180,6 @@ static unsigned int cached_irq_mask = 0xffff;
*/
unsigned long io_apic_irqs = 0;
-/*
- * These have to be protected by the irq controller spinlock
- * before being called.
- */
void disable_8259A_irq(unsigned int irq)
{
unsigned int mask = 1 << irq;
@@ -239,6 +235,8 @@ void make_8259A_irq(unsigned int irq)
/*
* This function assumes to be called rarely. Switching between
* 8259A registers is slow.
+ * This has to be protected by the irq controller spinlock
+ * before being called.
*/
static inline int i8259A_irq_real(unsigned int irq)
{
@@ -337,8 +335,7 @@ void __init init_8259A(int auto_eoi)
{
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&i8259A_lock, flags);
outb(0xff, 0x21); /* mask all of 8259A-1 */
outb(0xff, 0xA1); /* mask all of 8259A-2 */
@@ -372,7 +369,7 @@ void __init init_8259A(int auto_eoi)
outb(cached_21, 0x21); /* restore master IRQ mask */
outb(cached_A1, 0xA1); /* restore slave IRQ mask */
- restore_flags(flags);
+ spin_unlock_irqrestore(&i8259A_lock, flags);
}
#ifndef CONFIG_VISWS
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 7bf275c14b80c8..a9975576e0d9aa 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -175,8 +175,6 @@ int skip_ioapic_setup = 0;
static int __init ioapic_setup(char *str)
{
- extern int skip_ioapic_setup; /* defined in arch/i386/kernel/smp.c */
-
skip_ioapic_setup = 1;
return 1;
}
@@ -658,8 +656,6 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
/* mask LVT0 */
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
- init_8259A(1);
-
/*
* We use logical delivery to get the timer IRQ
* to the first CPU.
@@ -907,24 +903,27 @@ void print_all_local_APICs (void)
void /*__init*/ print_PIC(void)
{
+ extern spinlock_t i8259A_lock;
unsigned int v, flags;
printk(KERN_DEBUG "\nprinting PIC contents\n");
+ spin_lock_irqsave(&i8259A_lock, flags);
+
v = inb(0xa1) << 8 | inb(0x21);
printk(KERN_DEBUG "... PIC IMR: %04x\n", v);
v = inb(0xa0) << 8 | inb(0x20);
printk(KERN_DEBUG "... PIC IRR: %04x\n", v);
- __save_flags(flags);
- __cli();
outb(0x0b,0xa0);
outb(0x0b,0x20);
v = inb(0xa0) << 8 | inb(0x20);
outb(0x0a,0xa0);
outb(0x0a,0x20);
- __restore_flags(flags);
+
+ spin_unlock_irqrestore(&i8259A_lock, flags);
+
printk(KERN_DEBUG "... PIC ISR: %04x\n", v);
v = inb(0x4d1) << 8 | inb(0x4d0);
@@ -991,6 +990,14 @@ static void __init setup_ioapic_ids_from_mpc (void)
/* Read the register 0 value */
*(int *)&reg_00 = io_apic_read(apic, 0);
+ if (mp_ioapics[apic].mpc_apicid >= 0xf) {
+ 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",
+ reg_00.ID);
+ mp_ioapics[apic].mpc_apicid = reg_00.ID;
+ }
+
/*
* Read the right value from the MPC table and
* write it into the ID register.
@@ -1295,6 +1302,7 @@ static void setup_nmi (void)
*/
static inline void check_timer(void)
{
+ extern int timer_ack;
int pin1, pin2;
int vector;
@@ -1305,6 +1313,18 @@ static inline void check_timer(void)
vector = assign_irq_vector(0);
set_intr_gate(vector, interrupt[0]);
+ /*
+ * Subtle, code in do_timer_interrupt() expects an AEOI
+ * mode for the 8259A whenever interrupts are routed
+ * through I/O APICs. Also IRQ0 has to be enabled in
+ * the 8259A which implies the virtual wire has to be
+ * disabled in the local APIC.
+ */
+ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
+ init_8259A(1);
+ timer_ack = 1;
+ enable_8259A_irq(0);
+
pin1 = find_timer_pin(mp_INT);
pin2 = find_timer_pin(mp_ExtINT);
@@ -1318,7 +1338,6 @@ static inline void check_timer(void)
if (timer_irq_works()) {
if (nmi_watchdog) {
disable_8259A_irq(0);
- init_8259A(1);
setup_nmi();
enable_8259A_irq(0);
nmi_irq_works();
@@ -1360,7 +1379,6 @@ static inline void check_timer(void)
disable_8259A_irq(0);
irq_desc[0].handler = &lapic_irq_type;
- init_8259A(1); /* AEOI mode */
apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
enable_8259A_irq(0);
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index e3edb7c2f878ad..9c1f86e03752df 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -788,7 +788,7 @@ asmlinkage int sys_execve(struct pt_regs regs)
goto out;
error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);
if (error == 0)
- current->flags &= ~PF_DTRACE;
+ current->ptrace &= ~PT_DTRACE;
putname(filename);
out:
return error;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 01edbc37afcfa0..32ab88a4fbdbc5 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -141,10 +141,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EPERM;
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
goto out;
/* set the ptrace bit in the process flags. */
- current->flags |= PF_PTRACED;
+ current->ptrace |= PT_PTRACED;
ret = 0;
goto out;
}
@@ -174,9 +174,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED)
+ if (child->ptrace & PT_PTRACED)
goto out_tsk;
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
@@ -191,7 +191,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk;
}
ret = -ESRCH;
- if (!(child->flags & PF_PTRACED))
+ if (!(child->ptrace & PT_PTRACED))
goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
@@ -291,9 +291,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data > _NSIG)
break;
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
/* make sure the single step bit is not set. */
tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
@@ -328,10 +328,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
- child->flags &= ~PF_TRACESYS;
- if ((child->flags & PF_DTRACE) == 0) {
+ child->ptrace &= ~PT_TRACESYS;
+ if ((child->ptrace & PT_DTRACE) == 0) {
/* Spurious delayed TF traps may occur */
- child->flags |= PF_DTRACE;
+ child->ptrace |= PT_DTRACE;
}
tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG;
put_stack_long(child, EFL_OFFSET, tmp);
@@ -348,7 +348,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
@@ -447,8 +447,8 @@ out:
asmlinkage void syscall_trace(void)
{
- if ((current->flags & (PF_PTRACED|PF_TRACESYS))
- != (PF_PTRACED|PF_TRACESYS))
+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) !=
+ (PT_PTRACED|PT_TRACESYS))
return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index c35f5bae8358d3..5cf47f1426b0b9 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -662,7 +662,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!signr)
break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index e0ae38b28e42b6..084e3b963d176e 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -344,12 +344,22 @@ static void __init synchronize_tsc_ap (void)
extern void calibrate_delay(void);
+static atomic_t init_deasserted;
+
void __init smp_callin(void)
{
int cpuid, phys_id;
unsigned long timeout;
/*
+ * If waken up by an INIT in an 82489DX configuration
+ * we may get here before an INIT-deassert IPI reaches
+ * our local APIC. We have to wait for the IPI or we'll
+ * lock up on an APIC access.
+ */
+ while (!atomic_read(&init_deasserted));
+
+ /*
* (This works even if the APIC is not enabled.)
*/
phys_id = GET_APIC_ID(apic_read(APIC_ID));
@@ -573,6 +583,8 @@ static void __init do_boot_cpu (int apicid)
* the targeted processor.
*/
+ atomic_set(&init_deasserted, 0);
+
Dprintk("Setting warm reset code and vector.\n");
CMOS_WRITE(0xa, 0xf);
@@ -642,6 +654,8 @@ static void __init do_boot_cpu (int apicid)
send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
} while (send_status && (timeout++ < 1000));
+ atomic_set(&init_deasserted, 1);
+
/*
* Should we send STARTUP IPIs ?
*
@@ -869,14 +883,6 @@ void __init smp_boot_cpus(void)
phys_cpu_present_map |= (1 << hard_smp_processor_id());
}
- /*
- * If SMP should be disabled, then really disable it!
- */
- if (!max_cpus) {
- smp_found_config = 0;
- printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
- }
-
{
int reg;
@@ -912,6 +918,20 @@ void __init smp_boot_cpus(void)
Dprintk("Getting LVT1: %x\n", reg);
}
+ /*
+ * If SMP should be disabled, then really disable it!
+ */
+ if (!max_cpus) {
+ smp_found_config = 0;
+ printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
+#ifndef CONFIG_VISWS
+ io_apic_irqs = 0;
+#endif
+ cpu_online_map = phys_cpu_present_map = 1;
+ smp_num_cpus = 1;
+ goto smp_done;
+ }
+
connect_bsp_APIC();
setup_local_APIC();
@@ -998,7 +1018,6 @@ void __init smp_boot_cpus(void)
setup_IO_APIC();
#endif
-smp_done:
/*
* Set up all local APIC timers in the system:
*/
@@ -1010,6 +1029,7 @@ smp_done:
if (cpu_has_tsc && cpucount)
synchronize_tsc_bp();
+smp_done:
zap_low_mappings();
}
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index bcec04401b1e90..a009a428b04672 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -114,10 +114,12 @@ static inline unsigned long do_fast_gettimeoffset(void)
#define TICK_SIZE tick
-#ifndef CONFIG_X86_TSC
-
spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
+extern spinlock_t i8259A_lock;
+
+#ifndef CONFIG_X86_TSC
+
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
*
@@ -176,6 +178,7 @@ static unsigned long do_slow_gettimeoffset(void)
jiffies_t = jiffies;
count |= inb_p(0x40) << 8;
+ spin_unlock(&i8253_lock);
/*
* avoiding timer inconsistencies (they are rare, but they happen)...
@@ -194,10 +197,18 @@ static unsigned long do_slow_gettimeoffset(void)
if( count > count_p ) {
/* the nutcase */
- outb_p(0x0A, 0x20);
+ int i;
+
+ spin_lock(&i8259A_lock);
+ /*
+ * This is tricky when I/O APICs are used;
+ * see do_timer_interrupt().
+ */
+ i = inb(0x20);
+ spin_unlock(&i8259A_lock);
- /* assumption about timer being IRQ1 */
- if( inb(0x20) & 0x01 ) {
+ /* assumption about timer being IRQ0 */
+ if (i & 0x01) {
/*
* We cannot detect lost timer interrupts ...
* well, that's why we call them lost, don't we? :)
@@ -222,7 +233,6 @@ static unsigned long do_slow_gettimeoffset(void)
}
} else
jiffies_p = jiffies_t;
- spin_unlock(&i8253_lock);
count_p = count;
@@ -365,12 +375,30 @@ static int set_rtc_mmss(unsigned long nowtime)
/* last time the cmos clock got updated */
static long last_rtc_update = 0;
+int timer_ack = 0;
+
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
*/
static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+#ifdef CONFIG_X86_IO_APIC
+ if (timer_ack) {
+ /*
+ * Subtle, when I/O APICs are used we have to ack timer IRQ
+ * manually to reset the IRR bit for do_slow_gettimeoffset().
+ * This will also deassert NMI lines for the watchdog if run
+ * on an 82489DX-based system.
+ */
+ spin_lock(&i8259A_lock);
+ outb(0x0c, 0x20);
+ /* Ack the IRQ; AEOI will end it automatically. */
+ inb(0x20);
+ spin_unlock(&i8259A_lock);
+ }
+#endif
+
#ifdef CONFIG_VISWS
/* Clear the interrupt */
co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
@@ -459,19 +487,12 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
rdtscl(last_tsc_low);
-#if 0 /*
- * SUBTLE: this is not necessary from here because it's implicit in the
- * write xtime_lock.
- */
spin_lock(&i8253_lock);
-#endif
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
-#if 0
spin_unlock(&i8253_lock);
-#endif
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
@@ -667,7 +688,7 @@ void __init time_init(void)
dodgy_tsc();
- if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
+ if (cpu_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
if (tsc_quotient) {
fast_gettimeoffset_quotient = tsc_quotient;
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 0df54449f5dca1..84c33763cdd35f 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -136,8 +136,6 @@ out: \
unlock_kernel(); \
}
-void page_exception(void);
-
asmlinkage void divide_error(void);
asmlinkage void debug(void);
asmlinkage void nmi(void);
@@ -537,12 +535,12 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
* The TF error should be masked out only if the current
* process is not traced and if the TRAP flag has been set
* previously by a tracing process (condition detected by
- * the PF_DTRACE flag); remember that the i386 TRAP flag
+ * the PT_DTRACE flag); remember that the i386 TRAP flag
* can be modified by the process itself in user mode,
* allowing programs to debug themselves without the ptrace()
* interface.
*/
- if ((tsk->flags & (PF_DTRACE|PF_PTRACED)) == PF_DTRACE)
+ if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
goto clear_TF;
}
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 4974d5c3284036..fa803c165eafc8 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -443,7 +443,7 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno
}
if (trapno !=1)
return 1; /* we let this handle by the calling routine */
- if (current->flags & PF_PTRACED) {
+ if (current->ptrace & PT_PTRACED) {
unsigned long flags;
spin_lock_irqsave(&current->sigmask_lock, flags);
sigdelset(&current->blocked, SIGTRAP);
diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c
index 9e1484836f3aa3..2fdffe2532687d 100644
--- a/arch/i386/math-emu/fpu_entry.c
+++ b/arch/i386/math-emu/fpu_entry.c
@@ -210,7 +210,7 @@ asmlinkage void math_emulate(long arg)
}
FPU_lookahead = 1;
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
FPU_lookahead = 0;
if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP,
diff --git a/arch/ppc/8xx_io/Config.in b/arch/ppc/8xx_io/Config.in
index 7af7116fff9453..412b5033892c05 100644
--- a/arch/ppc/8xx_io/Config.in
+++ b/arch/ppc/8xx_io/Config.in
@@ -1,9 +1,10 @@
#
# MPC8xx Communication options
#
+mainmenu_option next_comment
+comment 'MPC8xx CPM Options'
+
if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
- mainmenu_option next_comment
- comment 'MPC8xx Communication Options'
bool 'CPM SCC Ethernet' CONFIG_SCC_ENET
if [ "$CONFIG_SCC_ENET" = "y" ]; then
bool 'Ethernet on SCC1' CONFIG_SCC1_ENET
@@ -12,5 +13,15 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
fi
fi
bool '860T FEC Ethernet' CONFIG_FEC_ENET
- endmenu
+ bool 'Use SMC2 for UART' CONFIG_8xxSMC2
+ bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC
fi
+
+# This doesn't really belong here, but it is convenient to ask
+# 8xx specific questions.
+
+comment 'Generic MPC8xx Options'
+bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK
+bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
+
+endmenu
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 6acdc9a65ef861..59ed9fdbdb5e54 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -34,8 +34,8 @@ ifdef CONFIG_8xx
CFLAGS := $(CFLAGS) -mcpu=860 -I../8xx_io
endif
-ifdef CONFIG_PPC64
-CFLAGS := $(CFLAGS) -Wa,-mppc64bridge #-mpowerpc64
+ifdef CONFIG_PPC64BRIDGE
+CFLAGS := $(CFLAGS) -Wa,-mppc64bridge
endif
ifdef CONFIG_4xx
@@ -128,7 +128,7 @@ $(BOOT_TARGETS): $(CHECKS) vmlinux
endif
endif
-ifdef CONFIG_PPC64
+ifdef CONFIG_PPC64BRIDGE
$(BOOT_TARGETS): $(CHECKS) vmlinux
@$(MAKECOFFBOOT) $@
@$(MAKEBOOT) $@
@@ -172,6 +172,18 @@ oak_config: clean_config
walnut_config: clean_config
cp -f arch/ppc/configs/walnut_defconfig arch/ppc/defconfig
+rpxlite_config: clean_config
+ cp -f arch/ppc/configs/rpxlite_defconfig arch/ppc/defconfig
+
+rpxcllf_config: clean_config
+ cp -f arch/ppc/configs/rpxcllf_defconfig arch/ppc/defconfig
+
+bseip_config: clean_config
+ cp -f arch/ppc/configs/bseip_defconfig arch/ppc/defconfig
+
+est8260_config: clean_config
+ cp -f arch/ppc/configs/est8260_defconfig arch/ppc/defconfig
+
archclean:
rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks}
@$(MAKECOFFBOOT) clean
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 33fa8799952450..26961e8ea5ac2d 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -41,7 +41,7 @@ else
TFTPSIMAGE=/tftpboot/sImage
endif
-ifeq ($(CONFIG_PPC64),y)
+ifeq ($(CONFIG_PPC64BRIDGE),y)
MSIZE=.64
else
MSIZE=
diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile
index e988ce9de1acdf..48750982e781ba 100644
--- a/arch/ppc/chrpboot/Makefile
+++ b/arch/ppc/chrpboot/Makefile
@@ -5,29 +5,24 @@
#
# Based on coffboot by Paul Mackerras
-.c.s:
- $(CC) $(CFLAGS) -S -o $*.s $<
-.s.o:
- $(AS) -o $*.o $<
+ifeq ($(CONFIG_PPC64BRIDGE),y)
+MSIZE=.64
+AFLAGS += -Wa,-mppc64bridge
+else
+MSIZE=
+endif
+
.c.o:
$(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $<
-.S.s:
- $(CPP) $(AFLAGS) -traditional -o $*.o $<
.S.o:
$(CC) $(AFLAGS) -traditional -c -o $*.o $<
CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS
LD_ARGS = -Ttext 0x00400000
-OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o sysmap.o
+OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o
LIBS = $(TOPDIR)/lib/lib.a
-ifeq ($(CONFIG_PPC64),y)
-MSIZE=.64
-else
-MSIZE=
-endif
-
ifeq ($(CONFIG_ALL_PPC),y)
# yes, we want to build chrp stuff
CONFIG_CHRP = y
@@ -58,8 +53,8 @@ floppy: zImage
piggyback: piggyback.c
$(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
-mknote: mknote.c
- $(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c
+addnote: addnote.c
+ $(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c
image.o: piggyback ../coffboot/vmlinux.gz
./piggyback image < ../coffboot/vmlinux.gz | $(AS) -o image.o
@@ -70,13 +65,13 @@ sysmap.o: piggyback ../../../System.map
initrd.o: ramdisk.image.gz piggyback
./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
-zImage: $(OBJS) no_initrd.o mknote
+zImage: $(OBJS) no_initrd.o addnote
$(LD) $(LD_ARGS) -o $@ $(OBJS) no_initrd.o $(LIBS)
- ./mknote > note
- $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+ ./addnote $@
-zImage.initrd: $(OBJS) initrd.o
+zImage.initrd: $(OBJS) initrd.o addnote
$(LD) $(LD_ARGS) -o $@ $(OBJS) initrd.o $(LIBS)
+ ./addnote $@
else
znetboot:
@@ -98,7 +93,7 @@ vmlinux.coff.initrd:
clean:
- rm -f piggyback note mknote $(OBJS) zImage
+ rm -f piggyback note addnote $(OBJS) zImage
fastdep:
$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff --git a/arch/ppc/chrpboot/addnote.c b/arch/ppc/chrpboot/addnote.c
new file mode 100644
index 00000000000000..5f0934f6ef60b2
--- /dev/null
+++ b/arch/ppc/chrpboot/addnote.c
@@ -0,0 +1,163 @@
+/*
+ * Program to hack in a PT_NOTE program header entry in an ELF file.
+ * This is needed for OF on RS/6000s to load an image correctly.
+ * Note that OF needs a program header entry for the note, not an
+ * ELF section.
+ *
+ * Copyright 2000 Paul Mackerras.
+ *
+ * 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.
+ *
+ * Usage: addnote zImage
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+char arch[] = "PowerPC";
+
+#define N_DESCR 6
+unsigned int descr[N_DESCR] = {
+ 0xffffffff, /* real-mode = true */
+ 0x00c00000, /* real-base, i.e. where we expect OF to be */
+ 0xffffffff, /* real-size */
+ 0xffffffff, /* virt-base */
+ 0xffffffff, /* virt-size */
+ 0x4000, /* load-base */
+};
+
+unsigned char buf[512];
+
+#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
+#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2))
+
+#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \
+ buf[(off) + 1] = (v) & 0xff)
+#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \
+ PUT_16BE((off) + 2, (v)))
+
+/* Structure of an ELF file */
+#define E_IDENT 0 /* ELF header */
+#define E_PHOFF 28
+#define E_PHENTSIZE 42
+#define E_PHNUM 44
+#define E_HSIZE 52 /* size of ELF header */
+
+#define EI_MAGIC 0 /* offsets in E_IDENT area */
+#define EI_CLASS 4
+#define EI_DATA 5
+
+#define PH_TYPE 0 /* ELF program header */
+#define PH_OFFSET 4
+#define PH_FILESZ 16
+#define PH_HSIZE 32 /* size of program header */
+
+#define PT_NOTE 4 /* Program header type = note */
+
+#define ELFCLASS32 1
+#define ELFDATA2MSB 2
+
+unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
+
+main(int ac, char **av)
+{
+ int fd, n, i;
+ int ph, ps, np;
+ int nnote, ns;
+
+ if (ac != 2) {
+ fprintf(stderr, "Usage: %s elf-file\n", av[0]);
+ exit(1);
+ }
+ fd = open(av[1], O_RDWR);
+ if (fd < 0) {
+ perror(av[1]);
+ exit(1);
+ }
+
+ nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n < 0) {
+ perror("read");
+ exit(1);
+ }
+
+ if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
+ goto notelf;
+
+ if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
+ || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
+ fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
+ av[1]);
+ exit(1);
+ }
+
+ ph = GET_32BE(E_PHOFF);
+ ps = GET_16BE(E_PHENTSIZE);
+ np = GET_16BE(E_PHNUM);
+ if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
+ goto notelf;
+ if (ph + (np + 1) * ps + nnote > n)
+ goto nospace;
+
+ for (i = 0; i < np; ++i) {
+ if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
+ fprintf(stderr, "%s already has a note entry\n",
+ av[1]);
+ exit(0);
+ }
+ ph += ps;
+ }
+
+ /* XXX check that the area we want to use is all zeroes */
+ for (i = 0; i < ps + nnote; ++i)
+ if (buf[ph + i] != 0)
+ goto nospace;
+
+ /* fill in the program header entry */
+ ns = ph + ps;
+ PUT_32BE(ph + PH_TYPE, PT_NOTE);
+ PUT_32BE(ph + PH_OFFSET, ns);
+ PUT_32BE(ph + PH_FILESZ, nnote);
+
+ /* fill in the note area we point to */
+ /* XXX we should probably make this a proper section */
+ PUT_32BE(ns, strlen(arch) + 1);
+ PUT_32BE(ns + 4, N_DESCR * 4);
+ PUT_32BE(ns + 8, 0x1275);
+ strcpy(&buf[ns + 12], arch);
+ ns += 12 + strlen(arch) + 1;
+ for (i = 0; i < N_DESCR; ++i)
+ PUT_32BE(ns + i * 4, descr[i]);
+
+ /* Update the number of program headers */
+ PUT_16BE(E_PHNUM, np + 1);
+
+ /* write back */
+ lseek(fd, (long) 0, SEEK_SET);
+ i = write(fd, buf, n);
+ if (i < 0) {
+ perror("write");
+ exit(1);
+ }
+ if (i < n) {
+ fprintf(stderr, "%s: write truncated\n", av[1]);
+ exit(1);
+ }
+
+ exit(0);
+
+ notelf:
+ fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
+ exit(1);
+
+ nospace:
+ fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
+ av[0]);
+ exit(1);
+}
diff --git a/arch/ppc/chrpboot/main.c b/arch/ppc/chrpboot/main.c
index 91bf4d8c44bedd..a080f5ac61c045 100644
--- a/arch/ppc/chrpboot/main.c
+++ b/arch/ppc/chrpboot/main.c
@@ -16,11 +16,11 @@ extern void *finddevice(const char *);
extern int getprop(void *, const char *, void *, int);
void gunzip(void *, int, unsigned char *, int *);
-#define get_16be(x) (*(unsigned short *)(x))
-#define get_32be(x) (*(unsigned *)(x))
-
#define RAM_START 0x00000000
-#define RAM_END (8<<20)
+#define RAM_END (64<<20)
+
+#define BOOT_START ((unsigned long)_start)
+#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF)
#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF)
#define PROG_START 0x00010000
@@ -36,6 +36,7 @@ extern int initrd_len;
extern char sysmap_data[];
extern int sysmap_len;
+static char scratch[1024<<10]; /* 1MB of scratch space for gunzip */
chrpboot(int a1, int a2, void *prom)
{
@@ -48,13 +49,25 @@ chrpboot(int a1, int a2, void *prom)
printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
- end_avail = (char *) RAM_END;
+ if (initrd_len) {
+ initrd_size = initrd_len;
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+ a1 = initrd_start;
+ a2 = initrd_size;
+ claim(initrd_start, RAM_END - initrd_start, 0);
+ printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r",
+ initrd_start, initrd_data, initrd_size);
+ memcpy((char *)initrd_start, initrd_data, initrd_size);
+ }
im = image_data;
len = image_len;
+ /* claim 4MB starting at PROG_START */
+ claim(PROG_START, (4<<20) - PROG_START, 0);
dst = (void *) PROG_START;
if (im[0] == 0x1f && im[1] == 0x8b) {
- avail_ram = (char *)RAM_FREE;
+ avail_ram = scratch;
+ end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
gunzip(dst, 0x400000, im, &len);
printf("done %u bytes\n\r", len);
@@ -86,17 +99,18 @@ chrpboot(int a1, int a2, void *prom)
rec->data[1] = 1;
rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
+#if 0
rec->tag = BI_SYSMAP;
rec->data[0] = (unsigned long)sysmap_data;
rec->data[1] = sysmap_len;
rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
+#endif
rec->tag = BI_LAST;
rec->size = sizeof(struct bi_record);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
}
- (*(void (*)())sa)(0, 0, prom, a1, a2);
+ (*(void (*)())sa)(a1, a2, prom);
printf("returned?\n\r");
diff --git a/arch/ppc/chrpboot/start.c b/arch/ppc/chrpboot/start.c
index 161d9a980455b8..308f4fcd349299 100644
--- a/arch/ppc/chrpboot/start.c
+++ b/arch/ppc/chrpboot/start.c
@@ -131,6 +131,29 @@ finddevice(const char *name)
return args.phandle;
}
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ unsigned int virt;
+ unsigned int size;
+ unsigned int align;
+ void *ret;
+ } args;
+
+ args.service = "claim";
+ args.nargs = 3;
+ args.nret = 1;
+ args.virt = virt;
+ args.size = size;
+ args.align = align;
+ (*prom)(&args);
+ return args.ret;
+}
+
int
getprop(void *phandle, const char *name, void *buf, int buflen)
{
diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile
index 5c46f9540c73fe..c8541965dfdc1b 100644
--- a/arch/ppc/coffboot/Makefile
+++ b/arch/ppc/coffboot/Makefile
@@ -14,7 +14,7 @@ COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o
CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o
LIBS = $(TOPDIR)/lib/lib.a
-ifeq ($(CONFIG_PPC64),y)
+ifeq ($(CONFIG_PPC64BRIDGE),y)
MSIZE=.64
else
MSIZE=
@@ -54,7 +54,7 @@ floppy: zImage
miboot.image: dummy.o vmlinux.gz
$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=vmlinux.gz dummy.o $@
-miboot.image.initrd: dummy.o vmlinux.gz
+miboot.image.initrd: miboot.image ramdisk.image.gz
$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz miboot.image $@
coffboot: $(COFFOBJS) no_initrd.o ld.script
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 7e2c47c0b18d17..f72735bc294099 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -1,6 +1,6 @@
# $Id: config.in,v 1.106 1999/09/14 19:21:18 cort Exp $
# For a description of the syntax of this configuration file,
-# see the Configure script.
+# see Documentation/kbuild/config-language.txt.
#
define_bool CONFIG_UID16 n
@@ -17,10 +17,14 @@ define_bool CONFIG_PPC y
choice 'Processor Type' \
"6xx/7xx/7400 CONFIG_6xx \
4xx CONFIG_4xx \
- 630/Power3(64-Bit) CONFIG_PPC64 \
+ POWER3/POWER4(64-Bit) CONFIG_PPC64BRIDGE \
8260 CONFIG_8260 \
8xx CONFIG_8xx" 6xx
+if [ "$CONFIG_PPC64BRIDGE" = "y" ]; then
+ bool 'Power 4 support' CONFIG_POWER4
+fi
+
if [ "$CONFIG_8260" = "y" ]; then
define_bool CONFIG_6xx y
define_bool CONFIG_SERIAL_CONSOLE y
@@ -35,14 +39,6 @@ fi
if [ "$CONFIG_8xx" = "y" ]; then
define_bool CONFIG_SERIAL_CONSOLE y
- choice 'Processor Model' \
- "821 CONFIG_MPC821 \
- 823 CONFIG_MPC823 \
- 850 CONFIG_MPC850 \
- 855 CONFIG_MPC855 \
- 860 CONFIG_MPC860 \
- 860T CONFIG_MPC860T" 860
-
choice 'Machine Type' \
"RPX-Lite CONFIG_RPXLITE \
RPX-Classic CONFIG_RPXCLASSIC \
@@ -58,7 +54,7 @@ if [ "$CONFIG_6xx" = "y" ]; then
APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP
fi
-if [ "$CONFIG_PPC64" = "y" ]; then
+if [ "$CONFIG_PPC64BRIDGE" = "y" ]; then
define_bool CONFIG_ALL_PPC y
fi
@@ -99,7 +95,7 @@ if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \
"$CONFIG_8260" = "y" ]; then
define_bool CONFIG_PCI n
else
- if [ "$CONFIG_6xx" = "y" -o "$CONFIG_PPC64" = "y" ]; then
+ if [ "$CONFIG_6xx" = "y" -o "$CONFIG_PPC64BRIDGE" = "y" ]; then
define_bool CONFIG_PCI y
else
# CONFIG_8xx
@@ -161,7 +157,7 @@ fi
if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then
bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL y
if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then
- string 'Initial kernel command string' CONFIG_CMDLINE console=ttyS0,9600 console=tty0 root=/dev/sda2
+ string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2"
fi
fi
diff --git a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig
index f86dbd55eb6920..328d5c660c99e0 100644
--- a/arch/ppc/configs/apus_defconfig
+++ b/arch/ppc/configs/apus_defconfig
@@ -78,10 +78,6 @@ CONFIG_BLK_DEV_IDEDMA_PMAC=y
CONFIG_BLK_DEV_IDEDMA=y
CONFIG_IDEDMA_PMAC_AUTO=y
# CONFIG_IDE_CHIPSETS is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
diff --git a/arch/ppc/configs/bseip_defconfig b/arch/ppc/configs/bseip_defconfig
new file mode 100644
index 00000000000000..7233997fdf1454
--- /dev/null
+++ b/arch/ppc/configs/bseip_defconfig
@@ -0,0 +1,397 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx is not set
+# CONFIG_PPC64BRIDGE is not set
+# CONFIG_8260 is not set
+CONFIG_8xx=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_RPXLITE is not set
+# CONFIG_RPXCLASSIC is not set
+CONFIG_BSEIP=y
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# 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_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_RAID15_DANGEROUS is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# 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
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_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_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS 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=y
+# 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_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS 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_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+CONFIG_SCC2_ENET=y
+# CONFIG_FEC_ENET is not set
+CONFIG_8xxSMC2=y
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
index 051e964023c2df..68e49c148fa3d4 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -14,7 +14,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_PPC=y
CONFIG_6xx=y
# CONFIG_4xx is not set
-# CONFIG_PPC64 is not set
+# CONFIG_PPC64BRIDGE is not set
# CONFIG_8260 is not set
# CONFIG_8xx is not set
CONFIG_ALL_PPC=y
diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig
new file mode 100644
index 00000000000000..972820d213df44
--- /dev/null
+++ b/arch/ppc/configs/est8260_defconfig
@@ -0,0 +1,397 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx is not set
+# CONFIG_PPC64BRIDGE is not set
+CONFIG_8260=y
+# CONFIG_8xx is not set
+CONFIG_6xx=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_GEMINI is not set
+CONFIG_EST8260=y
+# CONFIG_APUS is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+# CONFIG_ALTIVEC is not set
+CONFIG_MACH_SPECIFIC=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_FB is not set
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADB is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_MOTOROLA_HOTSWAP is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# 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_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_RAID15_DANGEROUS is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# 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
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_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_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS 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=y
+# 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_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS 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_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8260 Communication Options
+#
+CONFIG_SCC_ENET=y
+CONFIG_SCC1_ENET=y
+# CONFIG_FCC_ENET is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/gemini_defconfig
index 90cc5b71f3dc67..e141e8f54c8ec0 100644
--- a/arch/ppc/configs/gemini_defconfig
+++ b/arch/ppc/configs/gemini_defconfig
@@ -14,7 +14,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_PPC=y
CONFIG_6xx=y
# CONFIG_4xx is not set
-# CONFIG_PPC64 is not set
+# CONFIG_PPC64BRIDGE is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
# CONFIG_PMAC is not set
@@ -77,10 +77,6 @@ CONFIG_KERNEL_ELF=y
#
# CONFIG_BLK_DEV_HD_ONLY is not set
# CONFIG_BLK_CPQ_DA is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig
index deaf75f3b2552d..362c836894de34 100644
--- a/arch/ppc/configs/oak_defconfig
+++ b/arch/ppc/configs/oak_defconfig
@@ -13,7 +13,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_PPC=y
# CONFIG_6xx is not set
CONFIG_4xx=y
-# CONFIG_PPC64 is not set
+# CONFIG_PPC64BRIDGE is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
CONFIG_OAK=y
@@ -69,10 +69,6 @@ CONFIG_KERNEL_ELF=y
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_ONLY is not set
-
-#
-# Additional Block Devices
-#
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig
new file mode 100644
index 00000000000000..9aaa80530c2075
--- /dev/null
+++ b/arch/ppc/configs/rpxcllf_defconfig
@@ -0,0 +1,396 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx is not set
+# CONFIG_PPC64BRIDGE is not set
+# CONFIG_8260 is not set
+CONFIG_8xx=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_RPXLITE is not set
+CONFIG_RPXCLASSIC=y
+# CONFIG_BSEIP is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# 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_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_RAID15_DANGEROUS is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# 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
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_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_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS 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=y
+# 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_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS 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_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+CONFIG_SCC1_ENET=y
+CONFIG_FEC_ENET=y
+CONFIG_8xxSMC2=y
+CONFIG_8xxSCC=y
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/rpxlite_defconfig b/arch/ppc/configs/rpxlite_defconfig
new file mode 100644
index 00000000000000..bacefe6f7375c1
--- /dev/null
+++ b/arch/ppc/configs/rpxlite_defconfig
@@ -0,0 +1,397 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx is not set
+# CONFIG_PPC64BRIDGE is not set
+# CONFIG_8260 is not set
+CONFIG_8xx=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_RPXLITE=y
+# CONFIG_RPXCLASSIC is not set
+# CONFIG_BSEIP is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# 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_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_RAID15_DANGEROUS is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# 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
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_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_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS 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=y
+# 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_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS 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_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+CONFIG_SCC2_ENET=y
+# CONFIG_FEC_ENET is not set
+# CONFIG_8xxSMC2 is not set
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig
index ad36925f32c1d1..73bc24eea286e9 100644
--- a/arch/ppc/configs/walnut_defconfig
+++ b/arch/ppc/configs/walnut_defconfig
@@ -13,7 +13,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_PPC=y
# CONFIG_6xx is not set
CONFIG_4xx=y
-# CONFIG_PPC64 is not set
+# CONFIG_PPC64BRIDGE is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
# CONFIG_OAK is not set
@@ -69,10 +69,6 @@ CONFIG_KERNEL_ELF=y
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_ONLY is not set
-
-#
-# Additional Block Devices
-#
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index a14aa41ab7456a..e1854fad66cfcd 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -14,7 +14,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_PPC=y
CONFIG_6xx=y
# CONFIG_4xx is not set
-# CONFIG_PPC64 is not set
+# CONFIG_PPC64BRIDGE is not set
# CONFIG_8260 is not set
# CONFIG_8xx is not set
CONFIG_ALL_PPC=y
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index ed16da557d1830..501ed931a7d902 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -7,8 +7,13 @@
#
# Note 2! The CFLAGS definitions are now in the main makefile...
+ifdef CONFIG_PPC64BRIDGE
+.S.o:
+ $(CC) $(CFLAGS) -D__ASSEMBLY__ -mppc64bridge -c $< -o $*.o
+else
.S.o:
$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o
+endif
O_TARGET := kernel.o
OX_OBJS := ppc_ksyms.o setup.o
@@ -33,6 +38,10 @@ endif
O_OBJS := entry.o traps.o irq.o idle.o time.o process.o signal.o syscalls.o \
misc.o ptrace.o align.o ppc_htab.o semaphore.o bitops.o
+ifdef CONFIG_POWER4
+O_OBJS += xics.o
+endif
+
ifndef CONFIG_8xx
O_OBJS += hashtable.o
endif
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
index 5b7366adccd03a..cfa2fe0aafbb07 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -21,7 +21,7 @@ struct aligninfo {
unsigned char flags;
};
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
#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)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
int opcode, f1, f2, f3;
#endif
int i, t;
@@ -197,9 +197,11 @@ fix_alignment(struct pt_regs *regs)
unsigned char v[8];
} data;
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
/* The 4xx-family 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
*/
instr = *((unsigned int *)regs->nip);
diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c
index e609906cb7b112..0d614fba195e44 100644
--- a/arch/ppc/kernel/chrp_pci.c
+++ b/arch/ppc/kernel/chrp_pci.c
@@ -2,6 +2,7 @@
* CHRP pci routines.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/delay.h>
@@ -21,6 +22,10 @@
#include "pci.h"
+#ifdef CONFIG_POWER4
+static unsigned long pci_address_offset(int, unsigned int);
+#endif /* CONFIG_POWER4 */
+
/* LongTrail */
#define pci_config_addr(bus, dev, offset) \
(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset))
@@ -172,8 +177,11 @@ int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn
unsigned char offset, unsigned char *val)
{
unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "read-pci-config", 2, 2, (ulong *)&val, addr, 1 ) != 0 )
+ unsigned long ret;
+
+ if (call_rtas( "read-pci-config", 2, 2, &ret, addr, 1) != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
+ *val = ret;
return PCIBIOS_SUCCESSFUL;
}
@@ -181,8 +189,11 @@ int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn
unsigned char offset, unsigned short *val)
{
unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "read-pci-config", 2, 2, (ulong *)&val, addr, 2 ) != 0 )
+ unsigned long ret;
+
+ if (call_rtas("read-pci-config", 2, 2, &ret, addr, 2) != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
+ *val = ret;
return PCIBIOS_SUCCESSFUL;
}
@@ -191,8 +202,11 @@ int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_f
unsigned char offset, unsigned int *val)
{
unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "read-pci-config", 2, 2, (ulong *)&val, addr, 4 ) != 0 )
+ unsigned long ret;
+
+ if (call_rtas("read-pci-config", 2, 2, &ret, addr, 4) != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
+ *val = ret;
return PCIBIOS_SUCCESSFUL;
}
@@ -275,14 +289,33 @@ chrp_pcibios_fixup(void)
{
struct pci_dev *dev;
int i;
+ int *brp;
+ struct device_node *np;
extern struct pci_ops generic_pci_ops;
- /* Some IBM's with the python have >1 bus, this finds them */
- for ( i = 0; i < python_busnr ; i++ )
- pci_scan_bus(i+1, &generic_pci_ops, NULL);
+#ifndef CONFIG_POWER4
+ np = find_devices("device-tree");
+ if (np != 0) {
+ for (np = np->child; np != NULL; np = np->sibling) {
+ if (np->type == NULL || strcmp(np->type, "pci") != 0)
+ continue;
+ if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0)
+ continue;
+ if (brp[0] != 0) /* bus 0 is already done */
+ pci_scan_bus(brp[0], &generic_pci_ops, NULL);
+ }
+ }
+#else
+ /* XXX kludge for now because we can't properly handle
+ physical addresses > 4GB. -- paulus */
+ pci_scan_bus(0x1e, &generic_pci_ops, NULL);
+#endif /* CONFIG_POWER4 */
/* PCI interrupts are controlled by the OpenPIC */
pci_for_each_dev(dev) {
+ np = find_pci_device_OFnode(dev->bus->number, dev->devfn);
+ if ( (np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
+ dev->irq = np->intrs[0].line;
if ( dev->irq )
dev->irq = openpic_to_irq( dev->irq );
/* these need to be absolute addrs for OF and Matrox FB -- Cort */
@@ -301,10 +334,30 @@ chrp_pcibios_fixup(void)
pcibios_write_config_word(dev->bus->number,
dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
}
- if ( (dev->bus->number > 0) &&
- ((dev->vendor == PCI_VENDOR_ID_NCR) ||
- (dev->vendor == PCI_VENDOR_ID_AMD)))
- dev->resource[0].start += (dev->bus->number*0x08000000);
+#ifdef CONFIG_POWER4
+ for (i = 0; i < 6; ++i) {
+ unsigned long offset;
+ if (dev->resource[i].start == 0)
+ continue;
+ offset = pci_address_offset(dev->bus->number,
+ dev->resource[i].flags);
+ if (offset) {
+ dev->resource[i].start += offset;
+ dev->resource[i].end += offset;
+ printk("device %x.%x[%d] now [%lx..%lx]\n",
+ dev->bus->number, dev->devfn, i,
+ dev->resource[i].start,
+ dev->resource[i].end);
+ }
+ /* zap the 2nd function of the winbond chip */
+ if (dev->resource[i].flags & IORESOURCE_IO
+ && dev->bus->number == 0 && dev->devfn == 0x81)
+ dev->resource[i].flags &= ~IORESOURCE_IO;
+ }
+#else
+ if (dev->bus->number > 0 && python_busnr > 0)
+ dev->resource[0].start += dev->bus->number*0x01000000;
+#endif
}
}
@@ -316,7 +369,11 @@ void __init
chrp_setup_pci_ptrs(void)
{
struct device_node *py;
-
+
+#ifdef CONFIG_POWER4
+ set_config_access_method(rtas);
+ pci_dram_offset = 0;
+#else /* CONFIG_POWER4 */
if ( !strncmp("MOT",
get_property(find_path_device("/"), "model", NULL),3) )
{
@@ -327,23 +384,27 @@ chrp_setup_pci_ptrs(void)
}
else
{
- if ( (py = find_compatible_devices( "pci", "IBM,python" )) )
+ if ((py = find_compatible_devices("pci", "IBM,python")) != 0
+ || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0)
{
+ char *name = get_property(find_path_device("/"), "name", NULL);
+
/* find out how many pythons */
while ( (py = py->next) ) python_busnr++;
set_config_access_method(python);
+
/*
* We base these values on the machine type but should
* try to read them from the python controller itself.
* -- Cort
*/
- if ( !strncmp("IBM,7025-F50", get_property(find_path_device("/"), "name", NULL),12) )
+ if ( !strncmp("IBM,7025-F50", name, 12) )
{
pci_dram_offset = 0x80000000;
isa_mem_base = 0xa0000000;
isa_io_base = 0x88000000;
- } else if ( !strncmp("IBM,7043-260",
- get_property(find_path_device("/"), "name", NULL),12) )
+ } else if ( !strncmp("IBM,7043-260", name, 12)
+ || !strncmp("IBM,7044-270", name, 12))
{
pci_dram_offset = 0x0;
isa_mem_base = 0xc0000000;
@@ -372,6 +433,66 @@ chrp_setup_pci_ptrs(void)
}
}
}
+#endif /* CONFIG_POWER4 */
ppc_md.pcibios_fixup = chrp_pcibios_fixup;
}
+
+#ifdef CONFIG_PPC64BRIDGE
+/*
+ * Hack alert!!!
+ * 64-bit machines like POWER3 and POWER4 have > 32 bit
+ * physical addresses. For now we remap particular parts
+ * of the 32-bit physical address space that the Linux
+ * page table gives us into parts of the physical address
+ * space above 4GB so we can access the I/O devices.
+ */
+
+#ifdef CONFIG_POWER4
+static unsigned long pci_address_offset(int busnr, unsigned int flags)
+{
+ unsigned long offset = 0;
+
+ if (busnr >= 0x1e) {
+ if (flags & IORESOURCE_IO)
+ offset = -0x100000;
+ else if (flags & IORESOURCE_MEM)
+ offset = 0x38000000;
+ } else if (busnr <= 0xf) {
+ if (flags & IORESOURCE_MEM)
+ offset = -0x40000000;
+ else
+ }
+ return offset;
+}
+
+unsigned long phys_to_bus(unsigned long pa)
+{
+ if (pa >= 0xf8000000)
+ pa -= 0x38000000;
+ else if (pa >= 0x80000000 && pa < 0xc0000000)
+ pa += 0x40000000;
+ return pa;
+}
+
+unsigned long bus_to_phys(unsigned int ba, int busnr)
+{
+ return ba + pci_address_offset(busnr, IORESOURCE_MEM);
+}
+
+#else /* CONFIG_POWER4 */
+/*
+ * For now assume I/O addresses are < 4GB and PCI bridges don't
+ * remap addresses on POWER3 machines.
+ */
+unsigned long phys_to_bus(unsigned long pa)
+{
+ return pa;
+}
+
+unsigned long bus_to_phys(unsigned int ba, int busnr)
+{
+ return ba;
+}
+#endif /* CONFIG_POWER4 */
+#endif /* CONFIG_PPC64BRIDGE */
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index d8c22e1a61305d..d75ccaf5c58dc9 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -55,6 +55,7 @@
#include "local_irq.h"
#include "i8259.h"
#include "open_pic.h"
+#include "xics.h"
extern volatile unsigned char *chrp_int_ack_special;
@@ -259,6 +260,7 @@ chrp_setup_arch(void)
request_region(0x80,0x10,"dma page reg");
request_region(0xc0,0x20,"dma2");
+#ifndef CONFIG_PPC64BRIDGE
/* PCI bridge config space access area -
* appears to be not in devtree on longtrail. */
ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
@@ -267,14 +269,23 @@ chrp_setup_arch(void)
* -- Geert
*/
hydra_init(); /* Mac I/O */
+#endif /* CONFIG_PPC64BRIDGE */
+#ifndef CONFIG_POWER4
/* Some IBM machines don't have the hydra -- Cort */
if ( !OpenPIC )
{
- OpenPIC = (struct OpenPIC *)*(unsigned long *)get_property(
- find_path_device("/"), "platform-open-pic", NULL);
- OpenPIC = ioremap((unsigned long)OpenPIC, sizeof(struct OpenPIC));
+ unsigned long *opprop;
+
+ opprop = (unsigned long *)get_property(find_path_device("/"),
+ "platform-open-pic", NULL);
+ if (opprop != 0) {
+ printk("OpenPIC addrs: %lx %lx %lx\n",
+ opprop[0], opprop[1], opprop[2]);
+ OpenPIC = ioremap(opprop[0], sizeof(struct OpenPIC));
+ }
}
+#endif
/*
* Fix the Super I/O configuration
@@ -283,7 +294,10 @@ chrp_setup_arch(void)
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
#endif
+
+#ifndef CONFIG_PPC64BRIDGE
pmac_find_bridges();
+#endif /* CONFIG_PPC64BRIDGE */
/* Get the event scan rate for the rtas so we know how
* often it expects a heartbeat. -- Cort
@@ -402,15 +416,15 @@ void __init chrp_init_IRQ(void)
{
struct device_node *np;
int i;
+ unsigned long *addrp;
- if ( !(np = find_devices("pci") ) )
+ if (!(np = find_devices("pci"))
+ || !(addrp = (unsigned long *)
+ get_property(np, "8259-interrupt-acknowledge", NULL)))
printk("Cannot find pci to get ack address\n");
else
- {
chrp_int_ack_special = (volatile unsigned char *)
- (*(unsigned long *)get_property(np,
- "8259-interrupt-acknowledge", NULL));
- }
+ ioremap(*addrp, 1);
open_pic_irq_offset = 16;
for ( i = 16 ; i < NR_IRQS ; i++ )
irq_desc[i].handler = &open_pic;
@@ -435,6 +449,8 @@ chrp_init2(void)
#ifdef CONFIG_NVRAM
pmac_nvram_init();
#endif
+ if (ppc_md.progress)
+ ppc_md.progress(" Have fun! ", 0x7777);
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
@@ -560,10 +576,16 @@ void __init
ppc_md.setup_residual = NULL;
ppc_md.get_cpuinfo = chrp_get_cpuinfo;
ppc_md.irq_cannonicalize = chrp_irq_cannonicalize;
+#ifndef CONFIG_POWER4
ppc_md.init_IRQ = chrp_init_IRQ;
ppc_md.get_irq = chrp_get_irq;
ppc_md.post_irq = chrp_post_irq;
-
+#else
+ ppc_md.init_IRQ = xics_init_IRQ;
+ ppc_md.get_irq = xics_get_irq;
+ ppc_md.post_irq = NULL;
+#endif /* CONFIG_POWER4 */
+
ppc_md.init = chrp_init2;
ppc_md.restart = chrp_restart;
@@ -652,6 +674,7 @@ chrp_progress(char *s, unsigned short hex)
if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) )
{
/* assume no display-character RTAS method - use hex display */
+ call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
return;
}
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index ad467894f7aa8d..354686c2d5fe48 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -31,8 +31,8 @@
#include <linux/sys.h>
#include <linux/config.h>
-#define SHOW_SYSCALLS
-#define SHOW_SYSCALLS_TASK
+#undef SHOW_SYSCALLS
+#undef SHOW_SYSCALLS_TASK
#ifdef SHOW_SYSCALLS_TASK
.data
@@ -83,8 +83,8 @@ _GLOBAL(DoSyscall)
#endif /* SHOW_SYSCALLS */
cmpi 0,r0,0x7777 /* Special case for 'sys_sigreturn' */
beq- 10f
- lwz r10,TASK_FLAGS(r2)
- andi. r10,r10,PF_TRACESYS
+ lwz r10,TASK_PTRACE(r2)
+ andi. r10,r10,PT_TRACESYS
bne- 50f
cmpli 0,r0,NR_syscalls
bge- 66f
@@ -227,12 +227,15 @@ _GLOBAL(_switch)
stw r1,KSP(r3) /* Set old stack pointer */
sync
tophys(r0,r4)
+ CLR_TOP32(r0)
mtspr SPRG3,r0 /* Update current THREAD phys addr */
#ifdef CONFIG_8xx
/* XXX it would be nice to find a SPRGx for this on 6xx,7xx too */
lwz r9,PGDIR(r4) /* cache the page table root */
tophys(r9,r9) /* convert to phys addr */
mtspr M_TWB,r9 /* Update MMU base address */
+ tlbia
+ SYNC
#endif /* CONFIG_8xx */
lwz r1,KSP(r4) /* Load new stack pointer */
/* save the old current 'last' for return value */
@@ -244,6 +247,7 @@ _GLOBAL(_switch)
8: addi r4,r1,INT_FRAME_SIZE /* size of frame */
stw r4,THREAD+KSP(r2) /* save kernel stack pointer */
tophys(r9,r1)
+ CLR_TOP32(r9)
mtspr SPRG2,r9 /* phys exception stack pointer */
10: lwz r2,_CTR(r1)
lwz r0,_LINK(r1)
@@ -270,12 +274,13 @@ _GLOBAL(_switch)
lwz r0,_MSR(r1)
mtspr SRR0,r2
+ FIX_SRR1(r0,r2)
mtspr SRR1,r0
lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
lwz r1,GPR1(r1)
SYNC
- rfi
+ RFI
#ifdef CONFIG_SMP
.globl ret_from_smpfork
@@ -311,11 +316,7 @@ lost_irq_ret:
#ifdef CONFIG_SMP
/* get processor # */
lwz r3,PROCESSOR(r2)
-#ifndef CONFIG_PPC64
slwi r3,r3,5
-#else
-#error not 64-bit ready
-#endif
add r4,r4,r3
#endif /* CONFIG_SMP */
lwz r5,0(r4)
@@ -365,14 +366,17 @@ restore:
/* if returning to user mode, set new sprg2 and save kernel SP */
lwz r0,_MSR(r1)
- mtspr SRR1,r0
andi. r0,r0,MSR_PR
beq+ 1f
addi r0,r1,INT_FRAME_SIZE /* size of frame */
stw r0,THREAD+KSP(r2) /* save kernel stack pointer */
tophys(r2,r1)
+ CLR_TOP32(r2)
mtspr SPRG2,r2 /* phys exception stack pointer */
-1:
+1:
+ lwz r0,_MSR(r1)
+ FIX_SRR1(r0,r2)
+ mtspr SRR1,r0
lwz r2,_CCR(r1)
mtcrf 0xFF,r2
lwz r2,_NIP(r1)
@@ -381,7 +385,7 @@ restore:
lwz r2,GPR2(r1)
lwz r1,GPR1(r1)
SYNC
- rfi
+ RFI
/*
* Fake an interrupt from kernel mode.
@@ -423,7 +427,6 @@ enter_rtas:
stw r0,20(r1)
lis r4,rtas_data@ha
lwz r4,rtas_data@l(r4)
- addis r4,r4,-KERNELBASE@h
lis r6,1f@ha /* physical return address for rtas */
addi r6,r6,1f@l
addis r6,r6,-KERNELBASE@h
@@ -436,20 +439,23 @@ enter_rtas:
li r0,0
ori r0,r0,MSR_EE|MSR_SE|MSR_BE
andc r0,r9,r0
- andi. r9,r9,MSR_ME|MSR_RI
+ li r10,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
+ andc r9,r0,r10
sync /* disable interrupts so SRR0/1 */
mtmsr r0 /* don't get trashed */
mtlr r6
+ CLR_TOP32(r7)
mtspr SPRG2,r7
mtspr SRR0,r8
mtspr SRR1,r9
- rfi
+ RFI
1: addis r9,r1,-KERNELBASE@h
lwz r8,20(r9) /* get return address */
lwz r9,8(r9) /* original msr value */
+ FIX_SRR1(r9,r0)
li r0,0
mtspr SPRG2,r0
mtspr SRR0,r8
mtspr SRR1,r9
- rfi /* return to caller */
+ RFI /* return to caller */
#endif /* CONFIG_ALL_PPC */
diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S
index 58045be1d99b44..be86a1503bc1f6 100644
--- a/arch/ppc/kernel/hashtable.S
+++ b/arch/ppc/kernel/hashtable.S
@@ -52,6 +52,13 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64)
.globl hash_page
hash_page:
+#ifdef CONFIG_PPC64BRIDGE
+ mfmsr r0
+ clrldi r0,r0,1 /* make sure it's in 32-bit mode */
+ sync
+ MTMSRD(r0)
+ isync
+#endif
#ifdef CONFIG_SMP
SAVE_2GPRS(7,r21)
eieio
@@ -120,28 +127,183 @@ hash_page:
ori r4,r4,0xe04 /* clear out reserved bits */
andc r6,r6,r4 /* PP=2 or 0, when _PAGE_HWWRITE */
+#ifdef CONFIG_POWER4
+ /*
+ * XXX hack hack hack - translate 32-bit "physical" addresses
+ * in the linux page tables to 42-bit real addresses in such
+ * a fashion that we can get at the I/O we need to access.
+ * -- paulus
+ */
+ cmpwi 0,r6,0
+ rlwinm r4,r6,16,16,30
+ bge 57f
+ cmplwi 0,r4,0xfe00
+ li r5,0x3fd
+ bne 56f
+ li r5,0x3ff
+56: sldi r5,r5,32
+ or r6,r6,r5
+57:
+#endif
+
+#ifdef CONFIG_PPC64BRIDGE
/* Construct the high word of the PPC-style PTE */
mfsrin r5,r3 /* get segment reg for segment */
-#ifdef CONFIG_PPC64
+ rlwinm r5,r5,0,5,31
sldi r5,r5,12
-#else /* CONFIG_PPC64 */
- rlwinm r5,r5,7,1,24 /* put VSID in 0x7fffff80 bits */
-#endif /* CONFIG_PPC64 */
#ifndef CONFIG_SMP /* do this later for SMP */
-#ifdef CONFIG_PPC64
ori r5,r5,1 /* set V (valid) bit */
-#else /* CONFIG_PPC64 */
+#endif
+
+ rlwimi r5,r3,16,20,24 /* put in API (abbrev page index) */
+ /* Get the address of the primary PTE group in the hash table */
+ .globl hash_page_patch_A
+hash_page_patch_A:
+ lis r4,Hash_base@h /* base address of hash table */
+ rlwimi r4,r5,32-5,25-Hash_bits,24 /* (VSID & hash_mask) << 7 */
+ rlwinm r0,r3,32-5,25-Hash_bits,24 /* (PI & hash_mask) << 7 */
+ xor r4,r4,r0 /* make primary hash */
+
+ /* See whether it was a PTE not found exception or a
+ protection violation. */
+ andis. r0,r20,0x4000
+ li r2,8 /* PTEs/group */
+ bne 10f /* no PTE: go look for an empty slot */
+ tlbie r3 /* invalidate TLB entry */
+
+ /* Search the primary PTEG for a PTE whose 1st dword matches r5 */
+ mtctr r2
+ addi r3,r4,-16
+1: ldu r0,16(r3) /* get next PTE */
+ cmpd 0,r0,r5
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ found_slot
+
+ /* Search the secondary PTEG for a matching PTE */
+ ori r5,r5,0x2 /* set H (secondary hash) bit */
+ .globl hash_page_patch_B
+hash_page_patch_B:
+ xoris r3,r4,Hash_msk>>16 /* compute secondary hash */
+ xori r3,r3,0xff80
+ addi r3,r3,-16
+ mtctr r2
+2: ldu r0,16(r3)
+ cmpd 0,r0,r5
+ bdnzf 2,2b
+ beq+ found_slot
+ xori r5,r5,0x2 /* clear H bit again */
+
+ /* Search the primary PTEG for an empty slot */
+10: mtctr r2
+ addi r3,r4,-16 /* search primary PTEG */
+1: ldu r0,16(r3) /* get next PTE */
+ andi. r0,r0,1
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ found_empty
+
+ /* Search the secondary PTEG for an empty slot */
+ ori r5,r5,0x2 /* set H (secondary hash) bit */
+ .globl hash_page_patch_C
+hash_page_patch_C:
+ xoris r3,r4,Hash_msk>>16 /* compute secondary hash */
+ xori r3,r3,0xff80
+ addi r3,r3,-16
+ mtctr r2
+2: ldu r0,16(r3)
+ andi. r0,r0,1
+ bdnzf 2,2b
+ beq+ found_empty
+
+ /*
+ * Choose an arbitrary slot in the primary PTEG to overwrite.
+ * Since both the primary and secondary PTEGs are full, and we
+ * have no information that the PTEs in the primary PTEG are
+ * more important or useful than those in the secondary PTEG,
+ * and we know there is a definite (although small) speed
+ * advantage to putting the PTE in the primary PTEG, we always
+ * put the PTE in the primary PTEG.
+ */
+ xori r5,r5,0x2 /* clear H bit again */
+ lis r3,next_slot@ha
+ tophys(r3,r3)
+ lwz r2,next_slot@l(r3)
+ addi r2,r2,16
+ andi. r2,r2,0x70
+#ifdef CONFIG_POWER4
+ /*
+ * Since we don't have BATs on POWER4, we rely on always having
+ * PTEs in the hash table to map the hash table and the code
+ * that manipulates it in virtual mode, namely flush_hash_page and
+ * flush_hash_segments. Otherwise we can get a DSI inside those
+ * routines which leads to a deadlock on the hash_table_lock on
+ * SMP machines. We avoid this by never overwriting the first
+ * PTE of each PTEG if it is already valid.
+ * -- paulus.
+ */
+ bne 102f
+ li r2,0x10
+102:
+#endif /* CONFIG_POWER4 */
+ stw r2,next_slot@l(r3)
+ add r3,r4,r2
+11:
+ /* update counter of evicted pages */
+ lis r2,htab_evicts@ha
+ tophys(r2,r2)
+ lwz r4,htab_evicts@l(r2)
+ addi r4,r4,1
+ stw r4,htab_evicts@l(r2)
+
+#ifndef CONFIG_SMP
+ /* Store PTE in PTEG */
+found_empty:
+ std r5,0(r3)
+found_slot:
+ std r6,8(r3)
+ sync
+
+#else /* CONFIG_SMP */
+/*
+ * Between the tlbie above and updating the hash table entry below,
+ * another CPU could read the hash table entry and put it in its TLB.
+ * There are 3 cases:
+ * 1. using an empty slot
+ * 2. updating an earlier entry to change permissions (i.e. enable write)
+ * 3. taking over the PTE for an unrelated address
+ *
+ * In each case it doesn't really matter if the other CPUs have the old
+ * PTE in their TLB. So we don't need to bother with another tlbie here,
+ * which is convenient as we've overwritten the register that had the
+ * address. :-) The tlbie above is mainly to make sure that this CPU comes
+ * and gets the new PTE from the hash table.
+ *
+ * We do however have to make sure that the PTE is never in an invalid
+ * state with the V bit set.
+ */
+found_empty:
+found_slot:
+ std r5,0(r3) /* clear V (valid) bit in PTE */
+ sync
+ tlbsync
+ sync
+ std r6,8(r3) /* put in correct RPN, WIMG, PP bits */
+ sync
+ ori r5,r5,1
+ std r5,0(r3) /* finally set V bit in PTE */
+#endif /* CONFIG_SMP */
+
+#else /* CONFIG_PPC64BRIDGE */
+
+ /* Construct the high word of the PPC-style PTE */
+ mfsrin r5,r3 /* get segment reg for segment */
+ rlwinm r5,r5,7,1,24 /* put VSID in 0x7fffff80 bits */
+
+#ifndef CONFIG_SMP /* do this later for SMP */
oris r5,r5,0x8000 /* set V (valid) bit */
-#endif /* CONFIG_PPC64 */
#endif
-#ifdef CONFIG_PPC64
-/* XXX: does this insert the api correctly? -- Cort */
- rlwimi r5,r3,17,21,25 /* put in API (abbrev page index) */
-#else /* CONFIG_PPC64 */
rlwimi r5,r3,10,26,31 /* put in API (abbrev page index) */
-#endif /* CONFIG_PPC64 */
/* Get the address of the primary PTE group in the hash table */
.globl hash_page_patch_A
hash_page_patch_A:
@@ -160,89 +322,44 @@ hash_page_patch_A:
/* Search the primary PTEG for a PTE whose 1st word matches r5 */
mtctr r2
addi r3,r4,-8
-1:
-#ifdef CONFIG_PPC64
- lwzu r0,16(r3) /* get next PTE */
-#else
- lwzu r0,8(r3) /* get next PTE */
-#endif
+1: lwzu r0,8(r3) /* get next PTE */
cmp 0,r0,r5
bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
beq+ found_slot
/* Search the secondary PTEG for a matching PTE */
-#ifdef CONFIG_PPC64
- ori r5,r5,0x2 /* set H (secondary hash) bit */
-#else
ori r5,r5,0x40 /* set H (secondary hash) bit */
-#endif
.globl hash_page_patch_B
hash_page_patch_B:
xoris r3,r4,Hash_msk>>16 /* compute secondary hash */
xori r3,r3,0xffc0
-#ifdef CONFIG_PPC64
- addi r3,r3,-16
-#else
addi r3,r3,-8
-#endif
mtctr r2
-2:
-#ifdef CONFIG_PPC64
- lwzu r0,16(r3)
-#else
- lwzu r0,8(r3)
-#endif
+2: lwzu r0,8(r3)
cmp 0,r0,r5
bdnzf 2,2b
beq+ found_slot
-#ifdef CONFIG_PPC64
- xori r5,r5,0x2 /* clear H bit again */
-#else
xori r5,r5,0x40 /* clear H bit again */
-#endif
/* Search the primary PTEG for an empty slot */
10: mtctr r2
-#ifdef CONFIG_PPC64
- addi r3,r4,-16 /* search primary PTEG */
-#else
addi r3,r4,-8 /* search primary PTEG */
-#endif
-1:
-#ifdef CONFIG_PPC64
- lwzu r0,16(r3) /* get next PTE */
- andi. r0,r0,1
-#else
- lwzu r0,8(r3) /* get next PTE */
+1: lwzu r0,8(r3) /* get next PTE */
rlwinm. r0,r0,0,0,0 /* only want to check valid bit */
-#endif
bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
beq+ found_empty
/* Search the secondary PTEG for an empty slot */
-#ifdef CONFIG_PPC64
- ori r5,r5,0x2 /* set H (secondary hash) bit */
-#else
ori r5,r5,0x40 /* set H (secondary hash) bit */
-#endif
.globl hash_page_patch_C
hash_page_patch_C:
xoris r3,r4,Hash_msk>>16 /* compute secondary hash */
xori r3,r3,0xffc0
-#ifdef CONFIG_PPC64
- addi r3,r3,-16
-#else
addi r3,r3,-8
-#endif
mtctr r2
2:
-#ifdef CONFIG_PPC64
- lwzu r0,16(r3)
- andi. r0,r0,1
-#else
lwzu r0,8(r3)
rlwinm. r0,r0,0,0,0 /* only want to check valid bit */
-#endif
bdnzf 2,2b
beq+ found_empty
@@ -255,21 +372,12 @@ hash_page_patch_C:
* advantage to putting the PTE in the primary PTEG, we always
* put the PTE in the primary PTEG.
*/
-#ifdef CONFIG_PPC64
- xori r5,r5,0x2 /* clear H bit again */
-#else
xori r5,r5,0x40 /* clear H bit again */
-#endif
lis r3,next_slot@ha
tophys(r3,r3)
lwz r2,next_slot@l(r3)
-#ifdef CONFIG_PPC64
- addi r2,r2,16
- andi. r2,r2,0x78
-#else
addi r2,r2,8
andi. r2,r2,0x38
-#endif
stw r2,next_slot@l(r3)
add r3,r4,r2
11:
@@ -283,17 +391,9 @@ hash_page_patch_C:
#ifndef CONFIG_SMP
/* Store PTE in PTEG */
found_empty:
-#ifdef CONFIG_PPC64
- std r5,0(r3)
-#else
stw r5,0(r3)
-#endif
found_slot:
-#ifdef CONFIG_PPC64
- std r6,8(r3)
-#else
stw r6,4(r3)
-#endif
sync
#else /* CONFIG_SMP */
@@ -325,6 +425,7 @@ found_slot:
oris r5,r5,0x8000
stw r5,0(r3) /* finally set V bit in PTE */
#endif /* CONFIG_SMP */
+#endif /* CONFIG_PPC64BRIDGE */
/*
* Update the hash table miss count. We only want misses here
@@ -371,7 +472,7 @@ found_slot:
lwz r22,GPR22(r21)
lwz r23,GPR23(r21)
lwz r21,GPR21(r21)
- rfi
+ RFI
#ifdef CONFIG_SMP
hash_page_out:
@@ -410,7 +511,7 @@ _GLOBAL(flush_hash_segments)
#endif
blr
99:
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE)
/* Note - we had better not do anything which could generate
a hash table miss while we have the hash table locked,
or we'll get a deadlock. -paulus */
@@ -419,6 +520,8 @@ _GLOBAL(flush_hash_segments)
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
mtmsr r0
SYNC
+#endif
+#ifdef CONFIG_SMP
lis r9,hash_table_lock@h
ori r9,r9,hash_table_lock@l
lwz r8,PROCESSOR(r2)
@@ -430,6 +533,7 @@ _GLOBAL(flush_hash_segments)
bne- 10b
eieio
#endif
+#ifndef CONFIG_PPC64BRIDGE
rlwinm r3,r3,7,1,24 /* put VSID lower limit in position */
oris r3,r3,0x8000 /* set V bit */
rlwinm r4,r4,7,1,24 /* put VSID upper limit in position */
@@ -448,6 +552,26 @@ _GLOBAL(flush_hash_segments)
blt 2f /* branch if out of range */
stw r0,0(r5) /* invalidate entry */
2: bdnz 1b /* continue with loop */
+#else /* CONFIG_PPC64BRIDGE */
+ rldic r3,r3,12,20 /* put VSID lower limit in position */
+ ori r3,r3,1 /* set V bit */
+ rldic r4,r4,12,20 /* put VSID upper limit in position */
+ ori r4,r4,0xfff /* set V bit, API etc. */
+ lis r6,Hash_size@ha
+ lwz r6,Hash_size@l(r6) /* size in bytes */
+ srwi r6,r6,4 /* # PTEs */
+ mtctr r6
+ addi r5,r5,-16
+ li r0,0
+1: ldu r6,16(r5) /* get next tag word */
+ cmpld 0,r6,r3
+ cmpld 1,r6,r4
+ cror 0,0,5 /* set cr0.lt if out of range */
+ blt 2f /* branch if out of range */
+ std r0,0(r5) /* invalidate entry */
+2: bdnz 1b /* continue with loop */
+#endif /* CONFIG_PPC64BRIDGE */
+
sync
tlbia
sync
@@ -456,6 +580,8 @@ _GLOBAL(flush_hash_segments)
sync
lis r3,hash_table_lock@ha
stw r0,hash_table_lock@l(r3)
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE)
mtmsr r10
SYNC
#endif
@@ -479,7 +605,7 @@ _GLOBAL(flush_hash_page)
#endif
blr
99:
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE)
/* Note - we had better not do anything which could generate
a hash table miss while we have the hash table locked,
or we'll get a deadlock. -paulus */
@@ -488,6 +614,8 @@ _GLOBAL(flush_hash_page)
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
mtmsr r0
SYNC
+#endif
+#ifdef CONFIG_SMP
lis r9,hash_table_lock@h
ori r9,r9,hash_table_lock@l
lwz r8,PROCESSOR(r2)
@@ -499,6 +627,7 @@ _GLOBAL(flush_hash_page)
bne- 10b
eieio
#endif
+#ifndef CONFIG_PPC64BRIDGE
rlwinm r3,r3,11,1,20 /* put context into vsid */
rlwimi r3,r4,11,21,24 /* put top 4 bits of va into vsid */
oris r3,r3,0x8000 /* set V (valid) bit */
@@ -528,6 +657,37 @@ _GLOBAL(flush_hash_page)
bne 4f /* if we didn't find it */
3: li r0,0
stw r0,0(r7) /* invalidate entry */
+#else /* CONFIG_PPC64BRIDGE */
+ rldic r3,r3,16,16 /* put context into vsid (<< 12) */
+ rlwimi r3,r4,16,16,24 /* top 4 bits of va and API */
+ ori r3,r3,1 /* set V (valid) bit */
+ rlwinm r7,r4,32-5,9,24 /* get page index << 7 */
+ srdi r5,r3,5 /* vsid << 7 */
+ rlwinm r5,r5,0,1,24 /* vsid << 7 (limited to 24 bits) */
+ xor r7,r7,r5 /* primary hash << 7 */
+ lis r5,Hash_mask@ha
+ lwz r5,Hash_mask@l(r5) /* hash mask */
+ slwi r5,r5,7 /* << 7 */
+ and r7,r7,r5
+ add r6,r6,r7 /* address of primary PTEG */
+ li r8,8
+ mtctr r8
+ addi r7,r6,-16
+1: ldu r0,16(r7) /* get next PTE */
+ cmpd 0,r0,r3 /* see if tag matches */
+ bdnzf 2,1b /* while --ctr != 0 && !cr0.eq */
+ beq 3f /* if we found it */
+ ori r3,r3,2 /* set H (alt. hash) bit */
+ xor r6,r6,r5 /* address of secondary PTEG */
+ mtctr r8
+ addi r7,r6,-16
+2: ldu r0,16(r7) /* get next PTE */
+ cmpd 0,r0,r3 /* see if tag matches */
+ bdnzf 2,2b /* while --ctr != 0 && !cr0.eq */
+ bne 4f /* if we didn't find it */
+3: li r0,0
+ std r0,0(r7) /* invalidate entry */
+#endif /* CONFIG_PPC64BRIDGE */
4: sync
tlbie r4 /* in hw tlb too */
sync
@@ -536,6 +696,8 @@ _GLOBAL(flush_hash_page)
sync
li r0,0
stw r0,0(r9) /* clear hash_table_lock */
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE)
mtmsr r10
SYNC
#endif
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index f88c5383d2699b..8c5911d300606d 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -36,7 +36,19 @@
#include <asm/amigappc.h>
#endif
-#ifdef CONFIG_PPC64
+#ifndef CONFIG_PPC64BRIDGE
+CACHELINE_BYTES = 32
+LG_CACHELINE_BYTES = 5
+CACHELINE_MASK = 0x1f
+CACHELINE_WORDS = 8
+#else
+CACHELINE_BYTES = 128
+LG_CACHELINE_BYTES = 7
+CACHELINE_MASK = 0x7f
+CACHELINE_WORDS = 32
+#endif /* CONFIG_PPC64BRIDGE */
+
+#ifdef CONFIG_PPC64BRIDGE
#define LOAD_BAT(n, reg, RA, RB) \
ld RA,(n*32)+0(reg); \
ld RB,(n*32)+8(reg); \
@@ -47,7 +59,7 @@
mtspr DBAT##n##U,RA; \
mtspr DBAT##n##L,RB; \
-#else /* CONFIG_PPC64 */
+#else /* CONFIG_PPC64BRIDGE */
/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
#define LOAD_BAT(n, reg, RA, RB) \
@@ -65,7 +77,7 @@
mtspr DBAT##n##U,RA; \
mtspr DBAT##n##L,RB; \
1:
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64BRIDGE */
.text
.globl _stext
@@ -125,16 +137,6 @@ _start:
.globl __start
__start:
-#ifdef CONFIG_PPC64
-/*
- * Go into 32-bit mode to boot. OF should do this for
- * us already but just in case...
- * -- Cort
- */
- mfmsr r10
- clrldi r10,r10,3
- mtmsr r10
-#endif
/*
* We have to do any OF calls before we map ourselves to KERNELBASE,
* because OF may have I/O devices mapped into that area
@@ -166,67 +168,23 @@ __after_prom_start:
bl flush_tlbs
#endif
+#ifndef CONFIG_POWER4
+ /* POWER4 doesn't have BATs */
+ bl initial_bats
+#else /* CONFIG_POWER4 */
/*
- * Use the first pair of BAT registers to map the 1st 16MB
- * of RAM to KERNELBASE. From this point on we can't safely
- * call OF any more.
+ * Load up the SDR1 and segment register values now
+ * since we don't have the BATs.
*/
- lis r11,KERNELBASE@h
-#ifndef CONFIG_PPC64
- mfspr r9,PVR
- rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
- cmpi 0,r9,1
- bne 4f
- ori r11,r11,4 /* set up BAT registers for 601 */
- li r8,0x7f /* valid, block length = 8MB */
- oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */
- oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */
- mtspr IBAT0U,r11 /* N.B. 601 has valid bit in */
- mtspr IBAT0L,r8 /* lower BAT register */
- mtspr IBAT1U,r9
- mtspr IBAT1L,r10
- b 5f
-#endif /* CONFIG_PPC64 */
-
-4: tophys(r8,r11)
-#ifdef CONFIG_SMP
- ori r8,r8,0x12 /* R/W access, M=1 */
-#else
- ori r8,r8,2 /* R/W access */
-#endif /* CONFIG_SMP */
-#ifdef CONFIG_APUS
- ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
-#else
- ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
-#endif /* CONFIG_APUS */
-
-#ifdef CONFIG_PPC64
- /* clear out the high 32 bits in the BAT */
- clrldi r11,r11,32
- clrldi r8,r8,32
- /* turn off the pagetable mappings just in case */
- clrldi r16,r16,63
- mtsdr1 r16
-#else /* CONFIG_PPC64 */
- /*
- * If the MMU is off clear the bats. See clear_bat() -- Cort
- */
- mfmsr r20
- andi. r20,r20,MSR_DR
- bne 100f
- bl clear_bats
-100:
-#endif /* CONFIG_PPC64 */
- mtspr DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
- mtspr DBAT0U,r11 /* bit in upper BAT register */
- mtspr IBAT0L,r8
- mtspr IBAT0U,r11
-#if 0 /* Useful debug code, please leave in for now so I don't have to
- * look at docs when I need to setup a BAT ...
- */
- bl setup_screen_bat
-#endif
-5: isync
+ bl reloc_offset
+ addis r4,r3,_SDR1@ha /* get the value from _SDR1 */
+ lwz r4,_SDR1@l(r4) /* assume hash table below 4GB */
+ mtspr SDR1,r4
+ slbia
+ lis r5,0x2000 /* set pseudo-segment reg 12 */
+ ori r5,r5,12
+ mtsr 12,r5
+#endif /* CONFIG_POWER4 */
#ifndef CONFIG_APUS
/*
@@ -267,7 +225,21 @@ turn_on_mmu:
ori r0,r0,start_here@l
mtspr SRR0,r0
SYNC
- rfi /* enables MMU */
+ RFI /* enables MMU */
+
+#ifdef CONFIG_SMP
+ .globl __secondary_hold
+__secondary_hold:
+ /* tell the master we're here */
+ stw r3,4(0)
+100: lwz r4,0(0)
+ /* wait until we're told to start */
+ cmpw 0,r4,r3
+ bne 100b
+ /* our cpu # was at addr 0 - go */
+ mr r24,r3 /* cpu # */
+ b __secondary_start
+#endif
/*
* Exception entry code. This code runs with address translation
@@ -284,7 +256,8 @@ turn_on_mmu:
bne 1f; \
tophys(r21,r1); /* use tophys(kernel sp) otherwise */ \
subi r21,r21,INT_FRAME_SIZE; /* alloc exc. frame */\
-1: stw r20,_CCR(r21); /* save registers */ \
+1: CLR_TOP32(r21); \
+ stw r20,_CCR(r21); /* save registers */ \
stw r22,GPR22(r21); \
stw r23,GPR23(r21); \
mfspr r20,SPRG0; \
@@ -341,8 +314,13 @@ label: \
/* Data access exception. */
. = 0x300
+#ifdef CONFIG_PPC64BRIDGE
+ b DataAccess
+DataAccessCont:
+#else
DataAccess:
EXCEPTION_PROLOG
+#endif /* CONFIG_PPC64BRIDGE */
mfspr r20,DSISR
andis. r0,r20,0xa470 /* weird error? */
bne 1f /* if not, try to put a PTE */
@@ -361,10 +339,30 @@ DataAccess:
.long do_page_fault
.long ret_from_except
+#ifdef CONFIG_PPC64BRIDGE
+/* SLB fault on data access. */
+ . = 0x380
+ b DataSegment
+DataSegmentCont:
+ mfspr r4,DAR
+ stw r4,_DAR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ bl transfer_to_handler
+ .long UnknownException
+ .long ret_from_except
+#endif /* CONFIG_PPC64BRIDGE */
+
/* Instruction access exception. */
. = 0x400
+#ifdef CONFIG_PPC64BRIDGE
+ b InstructionAccess
+InstructionAccessCont:
+#else
InstructionAccess:
EXCEPTION_PROLOG
+#endif /* CONFIG_PPC64BRIDGE */
andis. r0,r23,0x4000 /* no pte found? */
beq 1f /* if so, try to put a PTE */
mr r3,r22 /* into the hash table */
@@ -380,6 +378,19 @@ InstructionAccess:
.long do_page_fault
.long ret_from_except
+#ifdef CONFIG_PPC64BRIDGE
+/* SLB fault on instruction access. */
+ . = 0x480
+ b InstructionSegment
+InstructionSegmentCont:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ bl transfer_to_handler
+ .long UnknownException
+ .long ret_from_except
+#endif /* CONFIG_PPC64BRIDGE */
+
/* External interrupt */
. = 0x500;
HardwareInterrupt:
@@ -526,7 +537,7 @@ InstructionTLBMiss:
tlbli r3
mfspr r3,SRR1 /* Need to restore CR0 */
mtcrf 0x80,r3
- rfi
+ rfi
InstructionAddressInvalid:
mfspr r3,SRR1
rlwinm r1,r3,9,6,6 /* Get load/store bit */
@@ -593,7 +604,7 @@ DataLoadTLBMiss:
tlbld r3
mfspr r3,SRR1 /* Need to restore CR0 */
mtcrf 0x80,r3
- rfi
+ rfi
DataAddressInvalid:
mfspr r3,SRR1
rlwinm r1,r3,9,6,6 /* Get load/store bit */
@@ -658,7 +669,7 @@ DataStoreTLBMiss:
tlbld r3
mfspr r3,SRR1 /* Need to restore CR0 */
mtcrf 0x80,r3
- rfi
+ rfi
STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint)
STD_EXCEPTION(0x1400, SMI, SMIException)
@@ -706,7 +717,22 @@ Trap_0f:
EXCEPTION_PROLOG
b trap_0f_cont
#endif /* CONFIG_ALTIVEC */
-
+
+#ifdef CONFIG_PPC64BRIDGE
+DataAccess:
+ EXCEPTION_PROLOG
+ b DataAccessCont
+InstructionAccess:
+ EXCEPTION_PROLOG
+ b InstructionAccessCont
+DataSegment:
+ EXCEPTION_PROLOG
+ b DataSegmentCont
+InstructionSegment:
+ EXCEPTION_PROLOG
+ b InstructionSegmentCont
+#endif /* CONFIG_PPC64BRIDGE */
+
/*
* This code finishes saving the registers to the exception frame
* and jumps to the appropriate handler for the exception, turning
@@ -741,11 +767,12 @@ transfer_to_handler:
bgt- stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
lwz r24,0(r23) /* virtual address of handler */
lwz r23,4(r23) /* where to go when done */
+ FIX_SRR1(r20,r22)
mtspr SRR0,r24
mtspr SRR1,r20
mtlr r23
SYNC
- rfi /* jump to handler, enable MMU */
+ RFI /* jump to handler, enable MMU */
/*
* On kernel stack overflow, load up an initial stack pointer
@@ -759,10 +786,11 @@ stack_ovf:
lis r24,StackOverflow@ha
addi r24,r24,StackOverflow@l
li r20,MSR_KERNEL
+ FIX_SRR1(r20,r22)
mtspr SRR0,r24
mtspr SRR1,r20
SYNC
- rfi
+ RFI
/*
* Disable FP for the task which had the FPU previously,
@@ -774,8 +802,11 @@ stack_ovf:
load_up_fpu:
mfmsr r5
ori r5,r5,MSR_FP
+#ifdef CONFIG_PPC64BRIDGE
+ clrldi r5,r5,1 /* turn off 64-bit mode */
+#endif /* CONFIG_PPC64BRIDGE */
SYNC
- mtmsr r5 /* enable use of fpu now */
+ MTMSRD(r5) /* enable use of fpu now */
SYNC
/*
* For SMP, we don't do lazy FPU switching because it just gets too
@@ -827,7 +858,7 @@ load_up_fpu:
REST_2GPRS(22, r21)
lwz r21,GPR21(r21)
SYNC
- rfi
+ RFI
/*
* FP unavailable trap from kernel - print a message, but let
@@ -919,7 +950,7 @@ load_up_altivec:
REST_2GPRS(22, r21)
lwz r21,GPR21(r21)
SYNC
- rfi
+ RFI
/*
* AltiVec unavailable trap from kernel - print a message, but let
@@ -1046,7 +1077,7 @@ relocate_kernel:
copy_and_flush:
addi r5,r5,-4
addi r6,r6,-4
-4: li r0,8
+4: li r0,CACHELINE_WORDS
mtctr r0
3: addi r6,r6,4 /* copy a cache line */
lwzx r0,r6,r4
@@ -1195,27 +1226,6 @@ apus_interrupt_entry:
#endif /* CONFIG_APUS */
#ifdef CONFIG_SMP
- .globl __secondary_hold
-__secondary_hold:
- /* tell the master we're here */
- lis r5,0x4@h
- ori r5,r5,0x4@l
- stw r3,0(r5)
- dcbf 0,r5
-100:
- lis r5,0
- dcbi 0,r5
- lwz r4,0(r5)
- /* wait until we're told to start */
- cmp 0,r4,r3
- bne 100b
- /* our cpu # was at addr 0 - go */
- lis r5,__secondary_start@h
- ori r5,r5,__secondary_start@l
- tophys(r5,r5)
- mtlr r5
- mr r24,r3 /* cpu # */
- blr
#ifdef CONFIG_GEMINI
.globl __secondary_start_gemini
__secondary_start_gemini:
@@ -1243,7 +1253,15 @@ __secondary_start_psurge:
.globl __secondary_start
__secondary_start:
+#ifdef CONFIG_PPC64BRIDGE
+ mfmsr r0
+ clrldi r0,r0,1 /* make sure it's in 32-bit mode */
+ sync
+ MTMSRD(r0)
+ isync
+#else
bl enable_caches
+#endif
/* get current */
lis r2,current_set@h
@@ -1264,6 +1282,7 @@ __secondary_start:
/* ptr to phys current thread */
tophys(r4,r2)
addi r4,r4,THREAD /* phys address of our thread_struct */
+ CLR_TOP32(r4)
mtspr SPRG3,r4
li r3,0
mtspr SPRG2,r3 /* 0 => r1 has kernel sp */
@@ -1275,7 +1294,7 @@ __secondary_start:
mtspr SRR0,r3
mtspr SRR1,r4
SYNC
- rfi
+ RFI
#endif /* CONFIG_SMP */
/*
@@ -1333,14 +1352,11 @@ load_up_mmu:
tophys(r6,r6)
lwz r6,_SDR1@l(r6)
mtspr SDR1,r6
-#ifdef CONFIG_PPC64
- /* clear the v bit in the ASR so we can
- * behave as if we have segment registers
- * -- Cort
- */
- clrldi r6,r6,63
+#ifdef CONFIG_PPC64BRIDGE
+ /* clear the ASR so we only use the pseudo-segment registers. */
+ li r6,0
mtasr r6
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64BRIDGE */
li r0,16 /* load up segment register values */
mtctr r0 /* for context 0 */
lis r3,0x2000 /* Ku = 1, VSID = 0 */
@@ -1349,6 +1365,7 @@ load_up_mmu:
addi r3,r3,1 /* increment VSID */
addis r4,r4,0x1000 /* address of next segment */
bdnz 3b
+#ifndef CONFIG_POWER4
/* Load the BAT registers with the values set up by MMU_init.
MMU_init takes care of whether we're on a 601 or not. */
mfpvr r3
@@ -1361,17 +1378,29 @@ load_up_mmu:
LOAD_BAT(1,r3,r4,r5)
LOAD_BAT(2,r3,r4,r5)
LOAD_BAT(3,r3,r4,r5)
+#endif /* CONFIG_POWER4 */
blr
/*
* This is where the main kernel code starts.
*/
start_here:
+#ifndef CONFIG_PPC64BRIDGE
bl enable_caches
+#endif
/* ptr to current */
lis r2,init_task_union@h
ori r2,r2,init_task_union@l
+ /* Set up for using our exception vectors */
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* init task's THREAD */
+ CLR_TOP32(r4)
+ mtspr SPRG3,r4
+ li r3,0
+ mtspr SPRG2,r3 /* 0 => r1 has kernel sp */
+
/* Clear out the BSS */
lis r11,_end@ha
addi r11,r11,_end@l
@@ -1424,10 +1453,11 @@ start_here:
ori r4,r4,2f@l
tophys(r4,r4)
li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ FIX_SRR1(r3,r5)
mtspr SRR0,r4
mtspr SRR1,r3
SYNC
- rfi
+ RFI
/* Load up the kernel context */
2:
SYNC /* Force all PTE updates to finish */
@@ -1439,34 +1469,30 @@ start_here:
#endif
bl load_up_mmu
-
-/* Set up for using our exception vectors */
- /* ptr to phys current thread */
- tophys(r4,r2)
- addi r4,r4,THREAD /* init task's THREAD */
- mtspr SPRG3,r4
- li r3,0
- mtspr SPRG2,r3 /* 0 => r1 has kernel sp */
/* Now turn on the MMU for real! */
li r4,MSR_KERNEL
+ FIX_SRR1(r4,r5)
lis r3,start_kernel@h
ori r3,r3,start_kernel@l
mtspr SRR0,r3
mtspr SRR1,r4
SYNC
- rfi /* enable MMU and jump to start_kernel */
+ RFI
/*
* Set up the segment registers for a new context.
*/
- .globl set_context
-set_context:
+_GLOBAL(set_context)
rlwinm r3,r3,4,8,27 /* VSID = context << 4 */
addis r3,r3,0x6000 /* Set Ks, Ku bits */
li r0,12 /* TASK_SIZE / SEGMENT_SIZE */
mtctr r0
li r4,0
-3: mtsrin r3,r4
+3:
+#ifdef CONFIG_PPC64BRIDGE
+ slbie r4
+#endif /* CONFIG_PPC64BRIDGE */
+ mtsrin r3,r4
addi r3,r3,1 /* next VSID */
addis r4,r4,0x1000 /* address of next segment */
bdnz 3b
@@ -1511,7 +1537,7 @@ clear_bats:
#ifndef CONFIG_GEMINI
flush_tlbs:
- lis r20, 0x1000
+ lis r20, 0x40
1: addic. r20, r20, -0x1000
tlbie r20
blt 1b
@@ -1522,30 +1548,79 @@ mmu_off:
addi r4, r3, __after_prom_start - _start
mfmsr r3
andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */
- beq 1f
+ beqlr
ori r3,r3,MSR_DR|MSR_IR
xori r3,r3,MSR_DR|MSR_IR
mtspr SRR0,r4
mtspr SRR1,r3
sync
- rfi
-1: blr
+ RFI
#endif
-#if 0 /* That's useful debug stuff */
+#ifndef CONFIG_POWER4
+/*
+ * Use the first pair of BAT registers to map the 1st 16MB
+ * of RAM to KERNELBASE. From this point on we can't safely
+ * call OF any more.
+ */
+initial_bats:
+ lis r11,KERNELBASE@h
+#ifndef CONFIG_PPC64BRIDGE
+ mfspr r9,PVR
+ rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
+ cmpi 0,r9,1
+ bne 4f
+ ori r11,r11,4 /* set up BAT registers for 601 */
+ li r8,0x7f /* valid, block length = 8MB */
+ oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */
+ oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */
+ mtspr IBAT0U,r11 /* N.B. 601 has valid bit in */
+ mtspr IBAT0L,r8 /* lower BAT register */
+ mtspr IBAT1U,r9
+ mtspr IBAT1L,r10
+ isync
+ blr
+#endif /* CONFIG_PPC64BRIDGE */
+
+4: tophys(r8,r11)
+#ifdef CONFIG_SMP
+ ori r8,r8,0x12 /* R/W access, M=1 */
+#else
+ ori r8,r8,2 /* R/W access */
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_APUS
+ ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
+#else
+ ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
+#endif /* CONFIG_APUS */
+
+#ifdef CONFIG_PPC64BRIDGE
+ /* clear out the high 32 bits in the BAT */
+ clrldi r11,r11,32
+ clrldi r8,r8,32
+#endif /* CONFIG_PPC64BRIDGE */
+ mtspr DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
+ mtspr DBAT0U,r11 /* bit in upper BAT register */
+ mtspr IBAT0L,r8
+ mtspr IBAT0U,r11
+#if 0 /* Useful debug code, please leave in for now so I don't have to
+ * look at docs when I need to setup a BAT ...
+ */
setup_screen_bat:
li r3,0
mtspr DBAT1U,r3
- mtspr IBAT1U,r3
- lis r3, 0x8200
- ori r4,r3,0x2a
+ lis r3,0xfa00
+ CLR_TOP32(r3)
+ lis r4,0xfa00
+ CLR_TOP32(r4)
+ ori r4,r4,0x2a
mtspr DBAT1L,r4
- mtspr IBAT1L,r4
ori r3,r3,(BL_16M<<2)|0x2 /* set up BAT registers for 604 */
mtspr DBAT1U,r3
- mtspr IBAT1U,r3
- blr
#endif
+ isync
+ blr
+#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8260
/* Jump into the system reset for the rom.
@@ -1568,7 +1643,7 @@ m8260_gorom:
mtlr r4
blr
#endif
-
+
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the data segment,
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index 59b8a49c69496c..a35f6e2a1d07a9 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -31,6 +31,13 @@
#include <asm/cache.h>
#include <asm/pgtable.h>
+/* XXX need definitions here for 16 byte cachelines on some/all 8xx
+ -- paulus */
+CACHELINE_BYTES = 32
+LG_CACHELINE_BYTES = 5
+CACHELINE_MASK = 0x1f
+CACHELINE_WORDS = 8
+
.text
.globl _stext
_stext:
@@ -90,6 +97,9 @@ __start:
li r8, 0
mtspr MI_CTR, r8 /* Set instruction control to zero */
lis r8, MD_RESETVAL@h
+#ifndef CONFIG_8xx_COPYBACK
+ oris r8, r8, MD_WTDEF@h
+#endif
mtspr MD_CTR, r8 /* Set data TLB control */
/* Now map the lower 8 Meg into the TLBs. For this quick hack,
@@ -374,6 +384,16 @@ InstructionTLBMiss:
#endif
mtspr MD_EPN, r20 /* Have to use MD_EPN for walk, MI_EPN can't */
mfspr r20, M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r21, r20, 0x0800 /* Address >= 0x80000000 */
+ beq 3f
+ lis r21, swapper_pg_dir@h
+ ori r21, r21, swapper_pg_dir@l
+ rlwimi r20, r21, 0, 2, 19
+3:
lwz r21, 0(r20) /* Get the level 1 entry */
rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */
beq 2f /* If zero, don't try to find a pte */
@@ -445,6 +465,16 @@ DataStoreTLBMiss:
stw r20, 0(r0)
stw r21, 4(r0)
mfspr r20, M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r21, r20, 0x0800
+ beq 3f
+ lis r21, swapper_pg_dir@h
+ ori r21, r21, swapper_pg_dir@l
+ rlwimi r20, r21, 0, 2, 19
+3:
lwz r21, 0(r20) /* Get the level 1 entry */
rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */
beq 2f /* If zero, don't try to find a pte */
@@ -546,6 +576,16 @@ DataTLBError:
beq 2f
mfspr r20, M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r21, r20, 0x0800
+ beq 3f
+ lis r21, swapper_pg_dir@h
+ ori r21, r21, swapper_pg_dir@l
+ rlwimi r20, r21, 0, 2, 19
+3:
lwz r21, 0(r20) /* Get the level 1 entry */
rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */
beq 2f /* If zero, bail */
@@ -717,7 +757,7 @@ relocate_kernel:
copy_and_flush:
addi r5,r5,-4
addi r6,r6,-4
-4: li r0,8
+4: li r0,CACHELINE_WORDS
mtctr r0
3: addi r6,r6,4 /* copy a cache line */
lwzx r0,r6,r4
@@ -901,6 +941,8 @@ start_here:
*/
_GLOBAL(set_context)
mtspr M_CASID,r3 /* Update context */
+ tophys (r4, r4)
+ mtspr M_TWB, r4 /* and pgd */
tlbia
SYNC
blr
@@ -948,3 +990,4 @@ swapper_pg_dir:
.globl cmd_line
cmd_line:
.space 512
+
diff --git a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c
index 5dfe902dfb73fb..bdb6ec84430dd0 100644
--- a/arch/ppc/kernel/i8259.c
+++ b/arch/ppc/kernel/i8259.c
@@ -104,11 +104,6 @@ struct hw_interrupt_type i8259_pic = {
0
};
-static void
-no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-}
-
void __init i8259_init(void)
{
/* init master interrupt controller */
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index 28be8bf46c9722..b055f23ece0663 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -286,10 +286,18 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
action = action->next;
} while ( action );
__cli();
- unmask_irq(irq);
+ if (irq_desc[irq].handler) {
+ if (irq_desc[irq].handler->end)
+ irq_desc[irq].handler->end(irq);
+ else if (irq_desc[irq].handler->enable)
+ irq_desc[irq].handler->enable(irq);
+ }
} else {
ppc_spurious_interrupts++;
- disable_irq( irq );
+ printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
+ disable_irq(irq);
+ if (irq_desc[irq].handler->end)
+ irq_desc[irq].handler->end(irq);
}
}
@@ -301,6 +309,7 @@ asmlinkage int do_IRQ(struct pt_regs *regs, int isfake)
/* every arch is required to have a get_irq -- Cort */
irq = ppc_md.get_irq( regs );
+
if ( irq < 0 )
{
/* -2 means ignore, already handled */
@@ -313,7 +322,7 @@ asmlinkage int do_IRQ(struct pt_regs *regs, int isfake)
goto out;
}
ppc_irq_dispatch_handler( regs, irq );
- if ( ppc_md.post_irq )
+ if (ppc_md.post_irq)
ppc_md.post_irq( regs, irq );
out:
@@ -770,3 +779,7 @@ void init_irq_proc (void)
register_irq_proc(i);
}
}
+
+void no_action(int irq, void *dev, struct pt_regs *regs)
+{
+}
diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c
index 65ea973d870ca0..2ce3790c37b709 100644
--- a/arch/ppc/kernel/m8260_setup.c
+++ b/arch/ppc/kernel/m8260_setup.c
@@ -167,9 +167,11 @@ int m8260_setup_residual(char *buffer)
bp = (bd_t *)__res;
- len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
- "bus clock\t: %dMHz\n",
+ len += sprintf(len+buffer,"core clock\t: %d MHz\n"
+ "CPM clock\t: %d MHz\n"
+ "bus clock\t: %d MHz\n",
bp->bi_intfreq /*/ 1000000*/,
+ bp->bi_cpmfreq /*/ 1000000*/,
bp->bi_busfreq /*/ 1000000*/);
return len;
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 96adb96cd40229..f8d230c7e31c4d 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -22,11 +22,14 @@
#include "ppc_asm.h"
#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
-CACHE_LINE_SIZE = 16
-LG_CACHE_LINE_SIZE = 4
+#define CACHE_LINE_SIZE 16
+#define LG_CACHE_LINE_SIZE 4
+#elif !defined(CONFIG_PPC64BRIDGE)
+#define CACHE_LINE_SIZE 32
+#define LG_CACHE_LINE_SIZE 5
#else
-CACHE_LINE_SIZE = 32
-LG_CACHE_LINE_SIZE = 5
+#define CACHE_LINE_SIZE 128
+#define LG_CACHE_LINE_SIZE 7
#endif /* CONFIG_4xx || CONFIG_8xx */
.text
@@ -140,12 +143,33 @@ _GLOBAL(do_lost_interrupts)
* Flush MMU TLB
*/
_GLOBAL(_tlbia)
+#if defined(CONFIG_SMP)
+ mfmsr r10
+ sync
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ mtmsr r0
+ SYNC
+ lis r9,hash_table_lock@h
+ ori r9,r9,hash_table_lock@l
+ lwz r8,PROCESSOR(r2)
+ oris r8,r8,10
+10: lwarx r7,0,r9
+ cmpi 0,r7,0
+ bne- 10b
+ stwcx. r8,0,r9
+ bne- 10b
+ eieio
+#endif /* CONFIG_SMP */
sync
tlbia
sync
#ifdef CONFIG_SMP
tlbsync
sync
+ li r0,0
+ stw r0,0(r9) /* clear hash_table_lock */
+ mtmsr r10
+ SYNC
#endif
blr
@@ -153,11 +177,32 @@ _GLOBAL(_tlbia)
* Flush MMU TLB for a particular address
*/
_GLOBAL(_tlbie)
+#if defined(CONFIG_SMP)
+ mfmsr r10
+ sync
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ mtmsr r0
+ SYNC
+ lis r9,hash_table_lock@h
+ ori r9,r9,hash_table_lock@l
+ lwz r8,PROCESSOR(r2)
+ oris r8,r8,11
+10: lwarx r7,0,r9
+ cmpi 0,r7,0
+ bne- 10b
+ stwcx. r8,0,r9
+ bne- 10b
+ eieio
+#endif /* CONFIG_SMP */
tlbie r3
sync
#ifdef CONFIG_SMP
tlbsync
sync
+ li r0,0
+ stw r0,0(r9) /* clear hash_table_lock */
+ mtmsr r10
+ SYNC
#endif
blr
@@ -305,6 +350,16 @@ _GLOBAL(clear_page)
* the destination into cache). This requires that the destination
* is cacheable.
*/
+#define COPY_16_BYTES \
+ lwz r6,4(r4); \
+ lwz r7,8(r4); \
+ lwz r8,12(r4); \
+ lwzu r9,16(r4); \
+ stw r6,4(r3); \
+ stw r7,8(r3); \
+ stw r8,12(r3); \
+ stwu r9,16(r3)
+
_GLOBAL(copy_page)
li r0,4096/CACHE_LINE_SIZE
mtctr r0
@@ -312,22 +367,20 @@ _GLOBAL(copy_page)
addi r4,r4,-4
li r5,4
1: dcbz r5,r3
- lwz r6,4(r4)
- lwz r7,8(r4)
- lwz r8,12(r4)
- lwzu r9,16(r4)
- stw r6,4(r3)
- stw r7,8(r3)
- stw r8,12(r3)
- stwu r9,16(r3)
- lwz r6,4(r4)
- lwz r7,8(r4)
- lwz r8,12(r4)
- lwzu r9,16(r4)
- stw r6,4(r3)
- stw r7,8(r3)
- stw r8,12(r3)
- stwu r9,16(r3)
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
bdnz 1b
blr
@@ -464,7 +517,7 @@ _GLOBAL(atomic_set_mask)
* The *_ns versions don't do byte-swapping.
*/
_GLOBAL(_insb)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,1
blelr-
@@ -475,7 +528,7 @@ _GLOBAL(_insb)
blr
_GLOBAL(_outsb)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,1
blelr-
@@ -486,7 +539,7 @@ _GLOBAL(_outsb)
blr
_GLOBAL(_insw)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,2
blelr-
@@ -497,7 +550,7 @@ _GLOBAL(_insw)
blr
_GLOBAL(_outsw)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,2
blelr-
@@ -508,7 +561,7 @@ _GLOBAL(_outsw)
blr
_GLOBAL(_insl)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,4
blelr-
@@ -519,7 +572,7 @@ _GLOBAL(_insl)
blr
_GLOBAL(_outsl)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,4
blelr-
@@ -531,7 +584,7 @@ _GLOBAL(_outsl)
_GLOBAL(ide_insw)
_GLOBAL(_insw_ns)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,2
blelr-
@@ -543,7 +596,7 @@ _GLOBAL(_insw_ns)
_GLOBAL(ide_outsw)
_GLOBAL(_outsw_ns)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,2
blelr-
@@ -554,7 +607,7 @@ _GLOBAL(_outsw_ns)
blr
_GLOBAL(_insl_ns)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,4
blelr-
@@ -565,7 +618,7 @@ _GLOBAL(_insl_ns)
blr
_GLOBAL(_outsl_ns)
- cmpw 0,r5,0
+ cmpwi 0,r5,0
mtctr r5
subi r4,r4,4
blelr-
@@ -650,6 +703,12 @@ _GLOBAL(_set_THRM3)
_GLOBAL(_get_PVR)
mfspr r3,PVR
blr
+
+#ifdef CONFIG_8xx
+_GLOBAL(_get_IMMR)
+ mfspr r3, 638
+ blr
+#endif
_GLOBAL(_get_HID0)
mfspr r3,HID0
diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c
index c381ea073b6ec5..0313fb1b21b946 100644
--- a/arch/ppc/kernel/mk_defs.c
+++ b/arch/ppc/kernel/mk_defs.c
@@ -44,8 +44,9 @@ main(void)
DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall));
DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
- DEFINE(PF_TRACESYS, PF_TRACESYS);
+ DEFINE(PT_TRACESYS, PT_TRACESYS);
DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+ DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
DEFINE(NEED_RESCHED, offsetof(struct task_struct, need_resched));
DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index a3c6cc4ddf96fd..21001a7ce5eedf 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -97,10 +97,6 @@ struct hw_interrupt_type open_pic = {
#define check_arg_cpu(cpu) do {} while (0)
#endif
-void no_action(int ir1, void *dev, struct pt_regs *regs)
-{
-}
-
#ifdef CONFIG_SMP
void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
{
@@ -293,7 +289,7 @@ void __init openpic_init(int main_pic)
void find_ISUs(void)
{
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
/* hardcode this for now since the IBM 260 is the only thing with
* a distributed openpic right now. -- Cort
*/
diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c
index 3b7dd283f9d5a2..ebd0037de7f59b 100644
--- a/arch/ppc/kernel/pmac_time.c
+++ b/arch/ppc/kernel/pmac_time.c
@@ -28,6 +28,8 @@
#include "time.h"
+extern rwlock_t xtime_lock;
+
/* Apparently the RTC stores seconds since 1 Jan 1904 */
#define RTC_OFFSET 2082844800
@@ -151,16 +153,21 @@ int __init via_calibrate_decr(void)
static int time_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
static unsigned long time_diff;
+ unsigned long flags;
switch (when) {
case PBOOK_SLEEP_NOW:
+ read_lock_irqsave(&xtime_lock, flags);
time_diff = xtime.tv_sec - pmac_get_rtc_time();
+ read_unlock_irqrestore(&xtime_lock, flags);
break;
case PBOOK_WAKE:
+ write_lock_irqsave(&xtime_lock, flags);
xtime.tv_sec = pmac_get_rtc_time() + time_diff;
xtime.tv_usec = 0;
set_dec(decrementer_count);
last_rtc_update = xtime.tv_sec;
+ write_unlock_irqrestore(&xtime_lock, flags);
break;
}
return PBOOK_SLEEP_OK;
diff --git a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h
index d9093c9e19905a..42b8c9c3946967 100644
--- a/arch/ppc/kernel/ppc_asm.h
+++ b/arch/ppc/kernel/ppc_asm.h
@@ -73,11 +73,13 @@
/*
* This instruction is not implemented on the PPC 603 or 601; however, on
* the 403GCX and 405GP tlbia IS defined and tlbie is not.
+ * All of these instructions exist in the 8xx, they have magical powers,
+ * and they must be used.
*/
-#if !defined(CONFIG_4xx)
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
#define tlbia \
- li r4,128; \
+ li r4,1024; \
mtctr r4; \
lis r4,KERNELBASE@h; \
0: tlbie r4; \
@@ -102,3 +104,25 @@
.align 1; \
.long 0b; \
.previous
+
+/*
+ * On 64-bit cpus, we use the rfid instruction instead of rfi, but
+ * we then have to make sure we preserve the top 32 bits except for
+ * the 64-bit mode bit, which we clear.
+ */
+#ifdef CONFIG_PPC64BRIDGE
+#define FIX_SRR1(ra, rb) \
+ mr rb,ra; \
+ mfmsr ra; \
+ clrldi ra,ra,1; /* turn off 64-bit mode */ \
+ rldimi ra,rb,0,32
+#define RFI .long 0x4c000024 /* rfid instruction */
+#define MTMSRD(r) .long (0x7c000164 + ((r) << 21)) /* mtmsrd */
+#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */
+
+#else
+#define FIX_SRR1(ra, rb)
+#define RFI rfi
+#define MTMSRD(r) mtmsr r
+#define CLR_TOP32(r)
+#endif /* CONFIG_PPC64BRIDGE */
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index 655eb4390f95a1..32f99ce0e19162 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -165,7 +165,7 @@ static ssize_t ppc_htab_read(struct file * file, char * buf,
valid = 0;
for_each_task(p)
{
- if ( (ptr->vsid >> 4) == p->mm->context )
+ if (p->mm && (ptr->vsid >> 4) == p->mm->context)
{
valid = 1;
break;
@@ -565,17 +565,22 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
if (!first)
*p++ = '\t';
val = _get_L2CR();
- p += sprintf(p, "%08x: ", val);
- p += sprintf(p, " %s",
- (val&0x80000000)?"enabled":"disabled");
- p += sprintf(p,",%sparity",(val&0x40000000)?"":"no ");
- p += sprintf(p, ",%s", sizestrings[(val >> 28) & 3]);
- p += sprintf(p, ",%s", clockstrings[(val >> 25) & 7]);
- p += sprintf(p, ",%s", typestrings[(val >> 23) & 0x2]);
- p += sprintf(p,"%s",(val>>22)&1?"":",data only");
- p += sprintf(p,"%s",(val>>20)&1?",ZZ enabled":"");
- p += sprintf(p,",%s",(val>>19)&1?"write-through":"copy-back");
- p += sprintf(p,",%sns hold", holdstrings[(val>>16)&3]);
+ p += sprintf(p, "0x%08x: ", val);
+ p += sprintf(p, " %s", (val >> 31) & 1 ? "enabled" :
+ "disabled");
+ p += sprintf(p, ", %sparity", (val>>30)&1 ? "" : "no ");
+ p += sprintf(p, ", %s", sizestrings[(val >> 28) & 3]);
+ p += sprintf(p, ", %s", clockstrings[(val >> 25) & 7]);
+ p += sprintf(p, ", %s", typestrings[(val >> 23) & 2]);
+ p += sprintf(p, "%s", (val>>22)&1 ? ", data only" : "");
+ p += sprintf(p, "%s", (val>>20)&1 ? ", ZZ enabled": "");
+ p += sprintf(p, ", %s", (val>>19)&1 ? "write-through" :
+ "copy-back");
+ p += sprintf(p, "%s", (val>>18)&1 ? ", testing" : "");
+ p += sprintf(p, ", %sns hold",holdstrings[(val>>16)&3]);
+ p += sprintf(p, "%s", (val>>15)&1 ? ", DLL slow" : "");
+ p += sprintf(p, "%s", (val>>14)&1 ? ", diff clock" :"");
+ p += sprintf(p, "%s", (val>>13)&1 ? ", DLL bypass" :"");
p += sprintf(p,"\n");
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 6d7f2aff7891f2..76809881bfceab 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -97,12 +97,14 @@ EXPORT_SYMBOL(ucSystemType);
#endif
#endif
+#if !__INLINE_BITOPS
EXPORT_SYMBOL(set_bit);
EXPORT_SYMBOL(clear_bit);
EXPORT_SYMBOL(change_bit);
EXPORT_SYMBOL(test_and_set_bit);
EXPORT_SYMBOL(test_and_clear_bit);
EXPORT_SYMBOL(test_and_change_bit);
+#endif /* __INLINE_BITOPS */
EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strncpy);
@@ -267,11 +269,13 @@ EXPORT_SYMBOL(ppc_irq_dispatch_handler);
EXPORT_SYMBOL(decrementer_count);
EXPORT_SYMBOL(get_wchan);
EXPORT_SYMBOL(console_drivers);
+EXPORT_SYMBOL(console_lock);
#ifdef CONFIG_XMON
EXPORT_SYMBOL(xmon);
#endif
EXPORT_SYMBOL(down_read_failed);
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
extern void (*debugger)(struct pt_regs *regs);
extern int (*debugger_bpt)(struct pt_regs *regs);
extern int (*debugger_sstep)(struct pt_regs *regs);
@@ -285,5 +289,7 @@ EXPORT_SYMBOL(debugger_sstep);
EXPORT_SYMBOL(debugger_iabr_match);
EXPORT_SYMBOL(debugger_dabr_match);
EXPORT_SYMBOL(debugger_fault_handler);
+#endif
EXPORT_SYMBOL(ret_to_user_hook);
+EXPORT_SYMBOL(do_softirq);
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index e1f1b498311087..7bc5cb82f6ec5b 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -501,6 +501,8 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
giveup_altivec(current);
#endif /* CONFIG_ALTIVEC */
error = do_execve(filename, (char **) a1, (char **) a2, regs);
+ if (error == 0)
+ current->ptrace &= ~PT_DTRACE;
putname(filename);
out:
return error;
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index 31fc850683fec8..7f51ca13f7a439 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -29,6 +29,9 @@
#include <asm/bootx.h>
#include <asm/system.h>
#include <asm/gemini.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/bitops.h>
#ifdef CONFIG_FB
#include <asm/linux_logo.h>
@@ -80,7 +83,8 @@ struct pci_intr_map {
unsigned intr;
};
-typedef unsigned long interpret_func(struct device_node *, unsigned long);
+typedef unsigned long interpret_func(struct device_node *, unsigned long,
+ int, int);
static interpret_func interpret_pci_props;
static interpret_func interpret_dbdma_props;
static interpret_func interpret_isa_props;
@@ -101,7 +105,7 @@ extern char *klimit;
char *bootpath = 0;
char *bootdevice = 0;
-unsigned int rtas_data = 0; /* virtual pointer */
+unsigned int rtas_data = 0; /* physical pointer */
unsigned int rtas_entry = 0; /* physical pointer */
unsigned int rtas_size = 0;
unsigned int old_rtas = 0;
@@ -145,7 +149,7 @@ static unsigned long copy_device_tree(unsigned long, unsigned long);
static unsigned long inspect_node(phandle, struct device_node *, unsigned long,
unsigned long, struct device_node ***);
static unsigned long finish_node(struct device_node *, unsigned long,
- interpret_func *);
+ interpret_func *, int, int);
static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
static unsigned long check_display(unsigned long);
static int prom_next_node(phandle *);
@@ -158,6 +162,7 @@ static void prom_welcome(boot_infos_t* bi, unsigned long phys);
extern void enter_rtas(void *);
extern unsigned long reloc_offset(void);
+void phys_call_rtas(int, int, int, ...);
extern char cmd_line[512]; /* XXX */
boot_infos_t *boot_infos = 0; /* init it so it's in data segment not bss */
@@ -279,7 +284,267 @@ prom_print(const char *msg)
}
}
-unsigned long smp_chrp_cpu_nr __initdata = 1;
+void
+prom_print_hex(unsigned int v)
+{
+ char buf[16];
+ int i, c;
+
+ for (i = 0; i < 8; ++i) {
+ c = (v >> ((7-i)*4)) & 0xf;
+ c += (c >= 10)? ('a' - 10): '0';
+ buf[i] = c;
+ }
+ buf[i] = ' ';
+ buf[i+1] = 0;
+ prom_print(buf);
+}
+
+void
+prom_print_nl(void)
+{
+ unsigned long offset = reloc_offset();
+ prom_print(RELOC("\n"));
+}
+
+unsigned long smp_chrp_cpu_nr __initdata = 0;
+
+#ifdef CONFIG_SMP
+/*
+ * With CHRP SMP we need to use the OF to start the other
+ * processors so we can't wait until smp_boot_cpus (the OF is
+ * trashed by then) so we have to put the processors into
+ * a holding pattern controlled by the kernel (not OF) before
+ * we destroy the OF.
+ *
+ * This uses a chunk of high memory, puts some holding pattern
+ * code there and sends the other processors off to there until
+ * smp_boot_cpus tells them to do something. We do that by using
+ * physical address 0x0. The holding pattern checks that address
+ * until its cpu # is there, when it is that cpu jumps to
+ * __secondary_start(). smp_boot_cpus() takes care of setting those
+ * values.
+ *
+ * We also use physical address 0x4 here to tell when a cpu
+ * is in its holding pattern code.
+ *
+ * -- Cort
+ */
+static void
+prom_hold_cpus(unsigned long mem)
+{
+ extern void __secondary_hold(void);
+ unsigned long i;
+ int cpu;
+ phandle node;
+ unsigned long offset = reloc_offset();
+ char type[16], *path;
+ unsigned int reg;
+
+ /*
+ * XXX: hack to make sure we're chrp, assume that if we're
+ * chrp we have a device_type property -- Cort
+ */
+ node = call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
+ if ( (int)call_prom(RELOC("getprop"), 4, 1, node,
+ RELOC("device_type"),type, sizeof(type)) <= 0)
+ return;
+
+ /* copy the holding pattern code to someplace safe (0) */
+ /* the holding pattern is now within the first 0x100
+ bytes of the kernel image -- paulus */
+ memcpy((void *)0, KERNELBASE + offset, 0x100);
+ flush_icache_range(0, 0x100);
+
+ /* look for cpus */
+ *(unsigned long *)(0x0) = 0;
+ asm volatile("dcbf 0,%0": : "r" (0) : "memory");
+ for (node = 0; prom_next_node(&node); ) {
+ type[0] = 0;
+ call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
+ type, sizeof(type));
+ if (strcmp(type, RELOC("cpu")) != 0)
+ continue;
+ path = (char *) mem;
+ memset(path, 0, 256);
+ if ((int) call_prom(RELOC("package-to-path"), 3, 1,
+ node, path, 255) < 0)
+ continue;
+ reg = -1;
+ call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
+ &reg, sizeof(reg));
+ cpu = RELOC(smp_chrp_cpu_nr)++;
+ RELOC(smp_hw_index)[cpu] = reg;
+ /* XXX: hack - don't start cpu 0, this cpu -- Cort */
+ if (cpu == 0)
+ continue;
+ prom_print(RELOC("starting cpu "));
+ prom_print(path);
+ *(ulong *)(0x4) = 0;
+ call_prom(RELOC("start-cpu"), 3, 0, node,
+ __pa(__secondary_hold), cpu);
+ prom_print(RELOC("..."));
+ for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
+ ;
+ if (*(ulong *)(0x4) == cpu)
+ prom_print(RELOC("ok\n"));
+ else {
+ prom_print(RELOC("failed: "));
+ prom_print_hex(*(ulong *)0x4);
+ prom_print_nl();
+ }
+ }
+}
+#endif /* CONFIG_SMP */
+
+void
+bootx_init(unsigned long r4, unsigned long phys)
+{
+ boot_infos_t *bi = (boot_infos_t *) r4;
+ unsigned long space;
+ unsigned long ptr, x;
+ char *model;
+ unsigned long offset = reloc_offset();
+
+ RELOC(boot_infos) = PTRUNRELOC(bi);
+ if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
+ bi->logicalDisplayBase = 0;
+
+#ifdef CONFIG_BOOTX_TEXT
+ RELOC(g_loc_X) = 0;
+ RELOC(g_loc_Y) = 0;
+ RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
+ RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
+ RELOC(disp_bi) = PTRUNRELOC(bi);
+
+ clearscreen();
+
+ /* Test if boot-info is compatible. Done only in config CONFIG_BOOTX_TEXT since
+ there is nothing much we can do with an incompatible version, except display
+ a message and eventually hang the processor...
+
+ I'll try to keep enough of boot-info compatible in the future to always allow
+ display of this message;
+ */
+ if (!BOOT_INFO_IS_COMPATIBLE(bi))
+ prom_print(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"));
+
+ prom_welcome(bi, phys);
+ flushscreen();
+#endif /* CONFIG_BOOTX_TEXT */
+
+ /* New BootX enters kernel with MMU off, i/os are not allowed
+ here. This hack will have been done by the boostrap anyway.
+ */
+ if (bi->version < 4) {
+ /*
+ * XXX If this is an iMac, turn off the USB controller.
+ */
+ model = (char *) early_get_property
+ (r4 + bi->deviceTreeOffset, 4, RELOC("model"));
+ if (model
+ && (strcmp(model, RELOC("iMac,1")) == 0
+ || strcmp(model, RELOC("PowerMac1,1")) == 0)) {
+ out_le32((unsigned *)0x80880008, 1); /* XXX */
+ }
+ }
+
+ /* Move klimit to enclose device tree, args, ramdisk, etc... */
+ if (bi->version < 5) {
+ space = bi->deviceTreeOffset + bi->deviceTreeSize;
+ if (bi->ramDisk)
+ space = bi->ramDisk + bi->ramDiskSize;
+ } else
+ space = bi->totalParamsSize;
+ RELOC(klimit) = PTRUNRELOC((char *) bi + space);
+
+ /* New BootX will have flushed all TLBs and enters kernel with
+ MMU switched OFF, so this should not be useful anymore.
+ */
+ if (bi->version < 4) {
+ /*
+ * Touch each page to make sure the PTEs for them
+ * are in the hash table - the aim is to try to avoid
+ * getting DSI exceptions while copying the kernel image.
+ */
+ for (ptr = (KERNELBASE + offset) & PAGE_MASK;
+ ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
+ x = *(volatile unsigned long *)ptr;
+ }
+
+#ifdef CONFIG_BOOTX_TEXT
+ prom_drawstring(RELOC("booting...\n"));
+ flushscreen();
+ RELOC(bootx_text_mapped) = 0;
+#endif
+}
+
+#ifdef CONFIG_PPC64BRIDGE
+/*
+ * Set up a hash table with a set of entries in it to map the
+ * first 64MB of RAM. This is used on 64-bit machines since
+ * some of them don't have BATs.
+ * We assume the PTE will fit in the primary PTEG.
+ */
+
+static inline void make_pte(unsigned long htab, unsigned int hsize,
+ unsigned int va, unsigned int pa, int mode)
+{
+ unsigned int *pteg;
+ unsigned int hash, i;
+
+ hash = ((va >> 5) ^ (va >> 21)) & 0x7fff80;
+ pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
+ for (i = 0; i < 8; ++i, pteg += 4) {
+ if ((pteg[1] & 1) == 0) {
+ pteg[1] = ((va >> 16) & 0xff80) | 1;
+ pteg[3] = pa | mode;
+ break;
+ }
+ }
+}
+
+extern unsigned long _SDR1;
+extern PTE *Hash;
+extern unsigned long Hash_size;
+
+void
+prom_alloc_htab(void)
+{
+ unsigned int hsize;
+ unsigned long htab;
+ unsigned int addr;
+ unsigned long offset = reloc_offset();
+
+ /*
+ * Because of OF bugs we can't use the "claim" client
+ * interface to allocate memory for the hash table.
+ * This code is only used on 64-bit PPCs, and the only
+ * 64-bit PPCs at the moment are RS/6000s, and their
+ * OF is based at 0xc00000 (the 12M point), so we just
+ * arbitrarily use the 0x800000 - 0xc00000 region for the
+ * hash table.
+ * -- paulus.
+ */
+#ifdef CONFIG_POWER4
+ hsize = 4 << 20; /* POWER4 has no BATs */
+#else
+ hsize = 2 << 20;
+#endif /* CONFIG_POWER4 */
+ htab = (8 << 20);
+ RELOC(Hash) = (void *)(htab + KERNELBASE);
+ RELOC(Hash_size) = hsize;
+ RELOC(_SDR1) = htab + __ilog2(hsize) - 18;
+
+ /*
+ * Put in PTEs for the first 64MB of RAM
+ */
+ cacheable_memzero((void *)htab, hsize);
+ for (addr = 0; addr < 0x4000000; addr += 0x1000)
+ make_pte(htab, hsize, addr + KERNELBASE, addr,
+ _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
+}
+#endif /* CONFIG_PPC64BRIDGE */
/*
* We enter here early on, when the Open Firmware prom is still
@@ -289,11 +554,6 @@ __init
unsigned long
prom_init(int r3, int r4, prom_entry pp)
{
-#ifdef CONFIG_SMP
- int i;
- phandle node;
- char type[16], *path;
-#endif
int chrp = 0;
unsigned long mem;
ihandle prom_rtas, prom_mmu, prom_op;
@@ -313,82 +573,7 @@ prom_init(int r3, int r4, prom_entry pp)
/* If we came here from BootX, clear the screen,
* set up some pointers and return. */
if (r3 == 0x426f6f58 && pp == NULL) {
- boot_infos_t *bi = (boot_infos_t *) r4;
- unsigned long space;
- unsigned long ptr, x;
- char *model;
-
- RELOC(boot_infos) = PTRUNRELOC(bi);
- if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
- bi->logicalDisplayBase = 0;
-
-#ifdef CONFIG_BOOTX_TEXT
- RELOC(g_loc_X) = 0;
- RELOC(g_loc_Y) = 0;
- RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
- RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
- RELOC(disp_bi) = PTRUNRELOC(bi);
-
- clearscreen();
-
- /* Test if boot-info is compatible. Done only in config CONFIG_BOOTX_TEXT since
- there is nothing much we can do with an incompatible version, except display
- a message and eventually hang the processor...
-
- I'll try to keep enough of boot-info compatible in the future to always allow
- display of this message;
- */
- if (!BOOT_INFO_IS_COMPATIBLE(bi))
- prom_print(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"));
-
- prom_welcome(bi, phys);
- flushscreen();
-#endif /* CONFIG_BOOTX_TEXT */
-
- /* New BootX enters kernel with MMU off, i/os are not allowed
- here. This hack will have been done by the boostrap anyway.
- */
- if (bi->version < 4) {
- /*
- * XXX If this is an iMac, turn off the USB controller.
- */
- model = (char *) early_get_property
- (r4 + bi->deviceTreeOffset, 4, RELOC("model"));
- if (model
- && (strcmp(model, RELOC("iMac,1")) == 0
- || strcmp(model, RELOC("PowerMac1,1")) == 0)) {
- out_le32((unsigned *)0x80880008, 1); /* XXX */
- }
- }
-
- /* Move klimit to enclose device tree, args, ramdisk, etc... */
- if (bi->version < 5) {
- space = bi->deviceTreeOffset + bi->deviceTreeSize;
- if (bi->ramDisk)
- space = bi->ramDisk + bi->ramDiskSize;
- } else
- space = bi->totalParamsSize;
- RELOC(klimit) = PTRUNRELOC((char *) bi + space);
-
- /* New BootX will have flushed all TLBs and enters kernel with
- MMU switched OFF, so this should not be useful anymore.
- */
- if (bi->version < 4) {
- /*
- * Touch each page to make sure the PTEs for them
- * are in the hash table - the aim is to try to avoid
- * getting DSI exceptions while copying the kernel image.
- */
- for (ptr = (KERNELBASE + offset) & PAGE_MASK;
- ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
- x = *(volatile unsigned long *)ptr;
- }
-
-#ifdef CONFIG_BOOTX_TEXT
- prom_print(RELOC("booting...\n"));
- flushscreen();
- RELOC(bootx_text_mapped) = 0;
-#endif
+ bootx_init(r4, phys);
return phys;
}
@@ -421,7 +606,8 @@ prom_init(int r3, int r4, prom_entry pp)
if (prom_op != (void*)-1) {
char model[64];
int sz;
- sz = (int)call_prom(RELOC("getprop"), 4, 1, prom_op, RELOC("model"), model, 64);
+ sz = (int)call_prom(RELOC("getprop"), 4, 1, prom_op,
+ RELOC("model"), model, 64);
if (sz > 0) {
char *c;
/* hack to skip the ibm chrp firmware # */
@@ -454,62 +640,68 @@ prom_init(int r3, int r4, prom_entry pp)
mem = ALIGN(mem + strlen(d) + 1);
}
- mem = check_display(mem);
-
- prom_print(RELOC("copying OF device tree..."));
- mem = copy_device_tree(mem, mem + (1<<20));
- prom_print(RELOC("done\n"));
-
-
- RELOC(klimit) = (char *) (mem - offset);
-
prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
if (prom_rtas != (void *) -1) {
+ int i, nargs;
+ struct prom_args prom_args;
+
RELOC(rtas_size) = 0;
call_prom(RELOC("getprop"), 4, 1, prom_rtas,
RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size));
- prom_print(RELOC("instantiating rtas..."));
+ prom_print(RELOC("instantiating rtas"));
if (RELOC(rtas_size) == 0) {
RELOC(rtas_data) = 0;
} else {
/*
- * We do _not_ want the rtas_data inside the klimit
- * boundry since it'll be squashed when we do the
- * relocate of the kernel on chrp right after prom_init()
- * in head.S. So, we just pick a spot in memory.
- * -- Cort
+ * Ask OF for some space for RTAS.
+ * Actually OF has bugs so we just arbitrarily
+ * use memory at the 6MB point.
*/
-#if 0
- mem = (mem + 4095) & -4096;
- RELOC(rtas_data) = mem + KERNELBASE;
- mem += RELOC(rtas_size);
-#endif
- RELOC(rtas_data) = (6<<20) + KERNELBASE;
+ RELOC(rtas_data) = 6 << 20;
+ prom_print(RELOC(" at "));
+ prom_print_hex(RELOC(rtas_data));
}
prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
- {
- int i, nargs;
- struct prom_args prom_args;
- nargs = 3;
- prom_args.service = RELOC("call-method");
- prom_args.nargs = nargs;
- prom_args.nret = 2;
- prom_args.args[0] = RELOC("instantiate-rtas");
- prom_args.args[1] = prom_rtas;
- prom_args.args[2] = ((void *)(RELOC(rtas_data)-KERNELBASE));
- RELOC(prom)(&prom_args);
- if (prom_args.args[nargs] != 0)
- i = 0;
- else
- i = (int)prom_args.args[nargs+1];
- RELOC(rtas_entry) = i;
- }
+ prom_print(RELOC("..."));
+ nargs = 3;
+ prom_args.service = RELOC("call-method");
+ prom_args.nargs = nargs;
+ prom_args.nret = 2;
+ prom_args.args[0] = RELOC("instantiate-rtas");
+ prom_args.args[1] = prom_rtas;
+ prom_args.args[2] = (void *) RELOC(rtas_data);
+ RELOC(prom)(&prom_args);
+ if (prom_args.args[nargs] != 0)
+ i = 0;
+ else
+ i = (int)prom_args.args[nargs+1];
+ RELOC(rtas_entry) = i;
if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0))
prom_print(RELOC(" failed\n"));
else
prom_print(RELOC(" done\n"));
}
+#ifdef CONFIG_PPC64BRIDGE
+ /*
+ * Find out how much memory we have and allocate a
+ * suitably-sized hash table.
+ */
+ prom_alloc_htab();
+#endif
+
+#ifdef CONFIG_SMP
+ prom_hold_cpus(mem);
+#endif
+
+ mem = check_display(mem);
+
+ prom_print(RELOC("copying OF device tree..."));
+ mem = copy_device_tree(mem, mem + (1<<20));
+ prom_print(RELOC("done\n"));
+
+ RELOC(klimit) = (char *) (mem - offset);
+
/* If we are already running at 0xc0000000, we assume we were loaded by
* an OF bootloader which did set a BAT for us. This breaks OF translate
* so we force phys to be 0
@@ -542,85 +734,10 @@ prom_init(int r3, int r4, prom_entry pp)
}
#ifdef CONFIG_BOOTX_TEXT
- if (!chrp && RELOC(prom_disp_node) != 0)
+ if (RELOC(prom_disp_node) != 0)
setup_disp_fake_bi(RELOC(prom_disp_node));
#endif
-#ifdef CONFIG_SMP
- /*
- * With CHRP SMP we need to use the OF to start the other
- * processors so we can't wait until smp_boot_cpus (the OF is
- * trashed by then) so we have to put the processors into
- * a holding pattern controlled by the kernel (not OF) before
- * we destroy the OF.
- *
- * This uses a chunk of high memory, puts some holding pattern
- * code there and sends the other processors off to there until
- * smp_boot_cpus tells them to do something. We do that by using
- * physical address 0x0. The holding pattern checks that address
- * until its cpu # is there, when it is that cpu jumps to
- * __secondary_start(). smp_boot_cpus() takes care of setting those
- * values.
- *
- * We also use physical address 0x4 here to tell when a cpu
- * is in its holding pattern code.
- *
- * -- Cort
- */
- {
- extern void __secondary_hold(void);
- unsigned long i;
- char type[16];
-
-
- /*
- * XXX: hack to make sure we're chrp, assume that if we're
- * chrp we have a device_type property -- Cort
- */
- node = call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
- if ( (int)call_prom(RELOC("getprop"), 4, 1, node,
- RELOC("device_type"),type, sizeof(type)) <= 0)
- return phys;
-
- /* copy the holding pattern code to someplace safe (8M) */
- memcpy( (void *)(8<<20), RELOC(__secondary_hold), 0x100 );
- for (i = 8<<20; i < ((8<<20)+0x100); i += 32)
- {
- asm volatile("dcbf 0,%0" : : "r" (i) : "memory");
- asm volatile("icbi 0,%0" : : "r" (i) : "memory");
- }
- }
-
- /* look for cpus */
- for (node = 0; prom_next_node(&node);)
- {
- type[0] = 0;
- call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
- type, sizeof(type));
- if (strcmp(type, RELOC("cpu")) != 0)
- continue;
- path = (char *) mem;
- memset(path, 0, 256);
- if ((int) call_prom(RELOC("package-to-path"), 3, 1,
- node, path, 255) < 0)
- continue;
- /* XXX: hack - don't start cpu 0, this cpu -- Cort */
- if ( smp_chrp_cpu_nr++ == 0 )
- continue;
- prom_print(RELOC("starting cpu "));
- prom_print(path);
- *(unsigned long *)(0x4) = 0;
- asm volatile("dcbf 0,%0": : "r" (0x4) : "memory");
- call_prom(RELOC("start-cpu"), 3, 0, node, 8<<20, smp_chrp_cpu_nr-1);
- for ( i = 0 ; (i < 10000) &&
- (*(ulong *)(0x4) == (ulong)0); i++ )
- ;
- if (*(ulong *)(0x4) == (ulong)smp_chrp_cpu_nr-1 )
- prom_print(RELOC("...ok\n"));
- else
- prom_print(RELOC("...failed\n"));
- }
-#endif
/* If OpenFirmware version >= 3, then use quiesce call */
if (prom_version >= 3) {
prom_print(RELOC("Calling quiesce ...\n"));
@@ -631,17 +748,41 @@ prom_init(int r3, int r4, prom_entry pp)
#ifdef CONFIG_BOOTX_TEXT
if (!chrp && RELOC(disp_bi)) {
- RELOC(prom_stdout) = 0;
clearscreen();
prom_welcome(PTRRELOC(RELOC(disp_bi)), phys);
- prom_print(RELOC("booting...\n"));
+ prom_drawstring(RELOC("booting...\n"));
}
RELOC(bootx_text_mapped) = 0;
#endif
+ prom_print(RELOC("returning from prom_init\n"));
+ RELOC(prom_stdout) = 0;
return phys;
}
+void phys_call_rtas(int service, int nargs, int nret, ...)
+{
+ va_list list;
+ union {
+ unsigned long words[16];
+ double align;
+ } u;
+ unsigned long offset = reloc_offset();
+ void (*rtas)(void *, unsigned long);
+ int i;
+
+ u.words[0] = service;
+ u.words[1] = nargs;
+ u.words[2] = nret;
+ va_start(list, nret);
+ for (i = 0; i < nargs; ++i)
+ u.words[i+3] = va_arg(list, unsigned long);
+ va_end(list);
+
+ rtas = (void (*)(void *, unsigned long)) RELOC(rtas_entry);
+ rtas(&u, RELOC(rtas_data));
+}
+
#ifdef CONFIG_BOOTX_TEXT
__init static void
prom_welcome(boot_infos_t* bi, unsigned long phys)
@@ -650,34 +791,34 @@ prom_welcome(boot_infos_t* bi, unsigned long phys)
unsigned long flags;
unsigned long pvr;
- prom_print(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
- prom_print(RELOC("\nstarted at : 0x"));
+ prom_drawstring(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
+ prom_drawstring(RELOC("\nstarted at : 0x"));
prom_drawhex(phys);
- prom_print(RELOC("\nlinked at : 0x"));
+ prom_drawstring(RELOC("\nlinked at : 0x"));
prom_drawhex(KERNELBASE);
- prom_print(RELOC("\nframe buffer at : 0x"));
+ prom_drawstring(RELOC("\nframe buffer at : 0x"));
prom_drawhex((unsigned long)bi->dispDeviceBase);
- prom_print(RELOC(" (phys), 0x"));
+ prom_drawstring(RELOC(" (phys), 0x"));
prom_drawhex((unsigned long)bi->logicalDisplayBase);
- prom_print(RELOC(" (log)"));
- prom_print(RELOC("\nklimit : 0x"));
- prom_drawhex(RELOC(klimit));
- prom_print(RELOC("\nMSR : 0x"));
+ prom_drawstring(RELOC(" (log)"));
+ prom_drawstring(RELOC("\nklimit : 0x"));
+ prom_drawhex((unsigned long)RELOC(klimit));
+ prom_drawstring(RELOC("\nMSR : 0x"));
__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
prom_drawhex(flags);
__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
pvr >>= 16;
if (pvr > 1) {
- prom_print(RELOC("\nHID0 : 0x"));
+ prom_drawstring(RELOC("\nHID0 : 0x"));
__asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
prom_drawhex(flags);
}
if (pvr == 8 || pvr == 12) {
- prom_print(RELOC("\nICTC : 0x"));
+ prom_drawstring(RELOC("\nICTC : 0x"));
__asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
prom_drawhex(flags);
}
- prom_print(RELOC("\n\n"));
+ prom_drawstring(RELOC("\n\n"));
}
#endif
@@ -822,6 +963,10 @@ setup_disp_fake_bi(ihandle dp)
call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"),
&pitch, sizeof(pitch));
address = 0;
+ if (pitch == 1) {
+ address = 0xfa000000;
+ pitch = 0x1000; /* for strange IBM display */
+ }
call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"),
&address, sizeof(address));
if (address == 0) {
@@ -987,6 +1132,7 @@ finish_device_tree(void)
/* All newworld machines now use the interrupt tree */
struct device_node *np = allnodes;
+
while(np) {
if (get_property(np, "interrupt-parent", 0)) {
pmac_newworld = 1;
@@ -997,7 +1143,7 @@ finish_device_tree(void)
if (boot_infos == 0 && pmac_newworld)
use_of_interrupt_tree = 1;
- mem = finish_node(allnodes, mem, NULL);
+ mem = finish_node(allnodes, mem, NULL, 0, 0);
dev_tree_size = mem - (unsigned long) allnodes;
klimit = (char *) mem;
}
@@ -1025,21 +1171,30 @@ early_get_property(unsigned long base, unsigned long node, char *prop)
__init
static unsigned long
finish_node(struct device_node *np, unsigned long mem_start,
- interpret_func *ifunc)
+ interpret_func *ifunc, int naddrc, int nsizec)
{
struct device_node *child;
+ int *ip;
np->name = get_property(np, "name", 0);
np->type = get_property(np, "device_type", 0);
/* get the device addresses and interrupts */
if (ifunc != NULL) {
- mem_start = ifunc(np, mem_start);
+ mem_start = ifunc(np, mem_start, naddrc, nsizec);
}
if (use_of_interrupt_tree) {
mem_start = finish_node_interrupts(np, mem_start);
}
+ /* Look for #address-cells and #size-cells properties. */
+ ip = (int *) get_property(np, "#address-cells", 0);
+ if (ip != NULL)
+ naddrc = *ip;
+ ip = (int *) get_property(np, "#size-cells", 0);
+ if (ip != NULL)
+ nsizec = *ip;
+
/* the f50 sets the name to 'display' and 'compatible' to what we
* expect for the name -- Cort
*/
@@ -1080,7 +1235,8 @@ finish_node(struct device_node *np, unsigned long mem_start,
}
for (child = np->child; child != NULL; child = child->sibling)
- mem_start = finish_node(child, mem_start, ifunc);
+ mem_start = finish_node(child, mem_start, ifunc,
+ naddrc, nsizec);
return mem_start;
}
@@ -1246,7 +1402,8 @@ void relocate_nodes(void)
__init
static unsigned long
-interpret_pci_props(struct device_node *np, unsigned long mem_start)
+interpret_pci_props(struct device_node *np, unsigned long mem_start,
+ int naddrc, int nsizec)
{
struct address_range *adr;
struct pci_reg_property *pci_addrs;
@@ -1329,7 +1486,8 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start)
__init
static unsigned long
-interpret_dbdma_props(struct device_node *np, unsigned long mem_start)
+interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
+ int naddrc, int nsizec)
{
struct reg_property *rp;
struct address_range *adr;
@@ -1381,7 +1539,8 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start)
__init
static unsigned long
-interpret_macio_props(struct device_node *np, unsigned long mem_start)
+interpret_macio_props(struct device_node *np, unsigned long mem_start,
+ int naddrc, int nsizec)
{
struct reg_property *rp;
struct address_range *adr;
@@ -1450,7 +1609,8 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start)
__init
static unsigned long
-interpret_isa_props(struct device_node *np, unsigned long mem_start)
+interpret_isa_props(struct device_node *np, unsigned long mem_start,
+ int naddrc, int nsizec)
{
struct isa_reg_property *rp;
struct address_range *adr;
@@ -1491,21 +1651,24 @@ interpret_isa_props(struct device_node *np, unsigned long mem_start)
__init
static unsigned long
-interpret_root_props(struct device_node *np, unsigned long mem_start)
+interpret_root_props(struct device_node *np, unsigned long mem_start,
+ int naddrc, int nsizec)
{
- struct reg_property *rp;
struct address_range *adr;
int i, l, *ip;
+ unsigned int *rp;
+ int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
- rp = (struct reg_property *) get_property(np, "reg", &l);
- if (rp != 0 && l >= sizeof(struct reg_property)) {
+ rp = (unsigned int *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= rpsize) {
i = 0;
adr = (struct address_range *) mem_start;
- while ((l -= sizeof(struct reg_property)) >= 0) {
+ while ((l -= rpsize) >= 0) {
adr[i].space = 0;
- adr[i].address = rp[i].address;
- adr[i].size = rp[i].size;
+ adr[i].address = rp[naddrc - 1];
+ adr[i].size = rp[naddrc + nsizec - 1];
++i;
+ rp += naddrc + nsizec;
}
np->addrs = adr;
np->n_addrs = i;
@@ -1583,9 +1746,8 @@ find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn)
int l;
for (np = allnodes; np != 0; np = np->allnext) {
- char *pname = np->parent ?
- (char *)get_property(np->parent, "name", &l) : 0;
- if (pname && strcmp(pname, "mac-io") == 0)
+ if (np->parent == NULL || np->parent->type == NULL
+ || strcmp(np->parent->type, "pci") != 0)
continue;
reg = (unsigned int *) get_property(np, "reg", &l);
if (reg == 0 || l < sizeof(struct reg_property))
@@ -1781,6 +1943,8 @@ print_properties(struct device_node *np)
}
#endif
+spinlock_t rtas_lock = SPIN_LOCK_UNLOCKED;
+
/* this can be called after setup -- Cort */
__openfirmware
int
@@ -1813,11 +1977,10 @@ call_rtas(const char *service, int nargs, int nret,
u.words[i+3] = va_arg(list, unsigned long);
va_end(list);
- save_flags(s);
- cli();
-
+ spin_lock_irqsave(&rtas_lock, s);
enter_rtas((void *)__pa(&u));
- restore_flags(s);
+ spin_unlock_irqrestore(&rtas_lock, s);
+
if (nret > 1 && outputs != NULL)
for (i = 0; i < nret-1; ++i)
outputs[i] = u.words[i+nargs+4];
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
index 3ccc8f51869e72..e618f22f643456 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/ppc/kernel/ptrace.c
@@ -89,10 +89,10 @@ int sys_ptrace(long request, long pid, long addr, long data)
lock_kernel();
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
goto out;
/* set the ptrace bit in the process flags. */
- current->flags |= PF_PTRACED;
+ current->ptrace |= PT_PTRACED;
ret = 0;
goto out;
}
@@ -123,9 +123,9 @@ int sys_ptrace(long request, long pid, long addr, long data)
&& !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED)
+ if (child->ptrace & PT_PTRACED)
goto out_tsk;
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
@@ -140,7 +140,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk;
}
ret = -ESRCH;
- if (!(child->flags & PF_PTRACED))
+ if (!(child->ptrace & PT_PTRACED))
goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
@@ -175,7 +175,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
if ((addr & 3) || index > PT_FPSCR)
break;
- if (addr < PT_FPR0) {
+ if (index < PT_FPR0) {
tmp = get_reg(child, (int) index);
} else {
if (child->thread.regs->msr & MSR_FP)
@@ -206,10 +206,10 @@ int sys_ptrace(long request, long pid, long addr, long data)
if ((addr & 3) || index > PT_FPSCR)
break;
- if (addr == PT_ORIG_R3)
+ if (index == PT_ORIG_R3)
break;
- if (addr < PT_FPR0) {
- ret = put_reg(child, addr, data);
+ if (index < PT_FPR0) {
+ ret = put_reg(child, index, data);
} else {
if (child->thread.regs->msr & MSR_FP)
giveup_fpu(child);
@@ -225,9 +225,9 @@ int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data > _NSIG)
break;
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
/* make sure the single step bit is not set. */
clear_single_step(child);
@@ -256,7 +256,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
set_single_step(child);
child->exit_code = data;
/* give it a chance to run. */
@@ -269,7 +269,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
@@ -296,8 +296,8 @@ out:
void syscall_trace(void)
{
- if ((current->flags & (PF_PTRACED|PF_TRACESYS))
- != (PF_PTRACED|PF_TRACESYS))
+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+ != (PT_PTRACED|PT_TRACESYS))
return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 67895b87dca81d..6c0c382732e6aa 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -23,6 +23,7 @@
#include <asm/setup.h>
#include <asm/amigappc.h>
#include <asm/smp.h>
+#include <asm/elf.h>
#ifdef CONFIG_8xx
#include <asm/mpc8xx.h>
#include <asm/8xx_immap.h>
@@ -130,6 +131,14 @@ struct screen_info screen_info = {
};
/*
+ * These are used in binfmt_elf.c to put aux entries on the stack
+ * for each elf executable being started.
+ */
+int dcache_bsize;
+int icache_bsize;
+int ucache_bsize;
+
+/*
* I really need to add multiple-console support... -- Cort
*/
int __init pmac_display_supported(char *name)
@@ -275,7 +284,11 @@ int get_cpuinfo(char *buffer)
}
break;
case 0x000C:
- len += sprintf(len+buffer, "7400 (G4)\n");
+ len += sprintf(len+buffer, "7400 (G4");
+#ifdef CONFIG_ALTIVEC
+ len += sprintf(len+buffer, ", altivec enabled");
+#endif /* CONFIG_ALTIVEC */
+ len += sprintf(len+buffer, ")\n");
break;
case 0x0020:
len += sprintf(len+buffer, "403G");
@@ -288,6 +301,15 @@ int get_cpuinfo(char *buffer)
break;
}
break;
+ case 0x0035:
+ len += sprintf(len+buffer, "POWER4\n");
+ break;
+ case 0x0040:
+ len += sprintf(len+buffer, "POWER3 (630)\n");
+ break;
+ case 0x0041:
+ len += sprintf(len+buffer, "POWER3 (630+)\n");
+ break;
case 0x0050:
len += sprintf(len+buffer, "8xx\n");
break;
@@ -458,7 +480,6 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
intuit_machine_type();
#endif /* CONFIG_MACH_SPECIFIC */
finish_device_tree();
-
/*
* If we were booted via quik, r3 points to the physical
* address of the command-line parameters.
@@ -494,6 +515,8 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
#ifdef CONFIG_BLK_DEV_INITRD
if (r3 && r4 && r4 != 0xdeadbeef)
{
+ if (r3 < KERNELBASE)
+ r3 += KERNELBASE;
initrd_start = r3;
initrd_end = r3 + r4;
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
@@ -574,7 +597,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
}
__max_memory = maxmem;
}
-
+
/* this is for modules since _machine can be a define -- Cort */
ppc_md.ppc_machine = _machine;
@@ -684,6 +707,24 @@ void __init setup_arch(char **cmdline_p)
breakpoint();
#endif
+ /*
+ * Set cache line size based on type of cpu as a default.
+ * Systems with OF can look in the properties on the cpu node(s)
+ * for a possibly more accurate value.
+ */
+ dcache_bsize = icache_bsize = 32; /* most common value */
+ switch (_get_PVR() >> 16) {
+ case 1: /* 601, with unified cache */
+ ucache_bsize = 32;
+ break;
+ /* XXX need definitions in here for 8xx etc. */
+ case 0x40:
+ case 0x41:
+ case 0x35: /* 64-bit POWER3, POWER3+, POWER4 */
+ dcache_bsize = icache_bsize = 128;
+ break;
+ }
+
/* reboot on panic */
panic_timeout = 180;
@@ -779,7 +820,7 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
for (i = 0; i < 26; i++)
id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
id->word156 = __le16_to_cpu(id->word156);
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 3; i++)
id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
for (i = 0; i < 96; i++)
id->words160_255[i] = __le16_to_cpu(id->words160_255[i]);
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index e5452fedbe1daf..ee7ba852c9c85b 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -411,7 +411,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if (!signr)
break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 97543348be74d5..78157554d764bc 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -53,6 +53,9 @@ unsigned int prof_multiplier[NR_CPUS];
unsigned int prof_counter[NR_CPUS];
cycles_t cacheflush_time;
+/* this has to go in the data section because it is accessed from prom_init */
+int smp_hw_index[NR_CPUS] = {0};
+
/* all cpu mappings are 1-1 -- Cort */
volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
@@ -238,6 +241,7 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
case _MACH_chrp:
case _MACH_prep:
case _MACH_gemini:
+#ifndef CONFIG_POWER4
/* make sure we're sending something that translates to an IPI */
if ( msg > 0x3 )
break;
@@ -254,6 +258,18 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
openpic_cause_IPI(smp_processor_id(), msg, 1<<target);
break;
}
+#else /* CONFIG_POWER4 */
+ /* for now, only do reschedule messages
+ since we only have one IPI */
+ if (msg != MSG_RESCHEDULE)
+ break;
+ for (i = 0; i < smp_num_cpus; ++i) {
+ if (target == MSG_ALL || target == i
+ || (target == MSG_ALL_BUT_SELF
+ && i != smp_processor_id()))
+ xics_cause_IPI(i);
+ }
+#endif /* CONFIG_POWER4 */
break;
}
}
@@ -306,8 +322,9 @@ void __init smp_boot_cpus(void)
cpu_nr = 2;
break;
case _MACH_chrp:
- for ( i = 0; i < 4 ; i++ )
- openpic_enable_IPI(i);
+ if (OpenPIC)
+ for ( i = 0; i < 4 ; i++ )
+ openpic_enable_IPI(i);
cpu_nr = smp_chrp_cpu_nr;
break;
case _MACH_gemini:
@@ -390,10 +407,10 @@ void __init smp_boot_cpus(void)
printk("Processor %d is stuck.\n", i);
}
}
-
- if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
+
+ if (OpenPIC && (_machine & (_MACH_gemini|_MACH_chrp|_MACH_prep)))
do_openpic_setup_cpu();
-
+
if ( _machine == _MACH_Pmac )
{
/* reset the entry point so if we get another intr we won't
@@ -433,19 +450,19 @@ void __init smp_callin(void)
set_dec(decrementer_count);
init_idle();
-#if 0
- current->mm->mmap->vm_page_prot = PAGE_SHARED;
- current->mm->mmap->vm_start = PAGE_OFFSET;
- current->mm->mmap->vm_end = init_mm.mmap->vm_end;
-#endif
cpu_callin_map[current->processor] = 1;
+
+#ifndef CONFIG_POWER4
/*
* Each processor has to do this and this is the best
* place to stick it for now.
* -- Cort
*/
- if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
+ if (OpenPIC && _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep))
do_openpic_setup_cpu();
+#else
+ xics_setup_cpu();
+#endif /* CONFIG_POWER4 */
#ifdef CONFIG_GEMINI
if ( _machine == _MACH_gemini )
gemini_init_l2();
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 3877d11dce291e..3303bf785482d0 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -50,6 +50,7 @@ void smp_local_timer_interrupt(struct pt_regs *);
/* keep track of when we need to update the rtc */
time_t last_rtc_update = 0;
+extern rwlock_t xtime_lock;
/* The decrementer counts down by 128 every 128ns on a 601. */
#define DECREMENTER_COUNT_601 (1000000000 / HZ)
@@ -69,6 +70,7 @@ unsigned long last_tb;
int timer_interrupt(struct pt_regs * regs)
{
int dval, d;
+ unsigned long flags;
unsigned long cpu = smp_processor_id();
hardirq_enter(cpu);
@@ -102,7 +104,6 @@ int timer_interrupt(struct pt_regs * regs)
while ((d = get_dec()) == dval)
;
asm volatile("mftb %0" : "=r" (last_tb) );
-
/*
* Don't play catchup between the call to time_init()
* and sti() in init/main.c.
@@ -122,6 +123,7 @@ int timer_interrupt(struct pt_regs * regs)
/*
* update the rtc when needed
*/
+ read_lock_irqsave(&xtime_lock, flags);
if ( (time_status & STA_UNSYNC) &&
((xtime.tv_sec > last_rtc_update + 60) ||
(xtime.tv_sec < last_rtc_update)) )
@@ -132,6 +134,7 @@ int timer_interrupt(struct pt_regs * regs)
/* do it again in 60 s */
last_rtc_update = xtime.tv_sec;
}
+ read_unlock_irqrestore(&xtime_lock, flags);
}
#ifdef CONFIG_SMP
smp_local_timer_interrupt(regs);
@@ -153,17 +156,18 @@ void do_gettimeofday(struct timeval *tv)
save_flags(flags);
cli();
+ read_lock_irqsave(&xtime_lock, flags);
*tv = xtime;
+ read_unlock_irqrestore(&xtime_lock, flags);
/* XXX we don't seem to have the decrementers synced properly yet */
#ifndef CONFIG_SMP
asm volatile("mftb %0" : "=r" (diff) );
diff -= last_tb;
-
tv->tv_usec += diff * count_period_num / count_period_den;
tv->tv_sec += tv->tv_usec / 1000000;
tv->tv_usec = tv->tv_usec % 1000000;
#endif
-
+
restore_flags(flags);
}
@@ -177,8 +181,10 @@ void do_settimeofday(struct timeval *tv)
frac_tick = tv->tv_usec % (1000000 / HZ);
save_flags(flags);
cli();
+ write_lock_irqsave(&xtime_lock, flags);
xtime.tv_sec = tv->tv_sec;
xtime.tv_usec = tv->tv_usec - frac_tick;
+ write_unlock_irqrestore(&xtime_lock, flags);
set_dec(frac_tick * count_period_den / count_period_num);
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
@@ -191,6 +197,7 @@ void do_settimeofday(struct timeval *tv)
void __init time_init(void)
{
+ unsigned long flags;
if (ppc_md.time_init != NULL)
{
ppc_md.time_init();
@@ -205,8 +212,10 @@ void __init time_init(void)
ppc_md.calibrate_decr();
}
- xtime.tv_sec = ppc_md.get_rtc_time();
- xtime.tv_usec = 0;
+ write_lock_irqsave(&xtime_lock, flags);
+ xtime.tv_sec = ppc_md.get_rtc_time();
+ xtime.tv_usec = 0;
+ write_unlock_irqrestore(&xtime_lock, flags);
set_dec(decrementer_count);
/* allow setting the time right away */
diff --git a/arch/ppc/kernel/xics.c b/arch/ppc/kernel/xics.c
new file mode 100644
index 00000000000000..a9772821bf96bb
--- /dev/null
+++ b/arch/ppc/kernel/xics.c
@@ -0,0 +1,214 @@
+/*
+ * arch/ppc/kernel/xics.c
+ *
+ * Copyright 2000 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/threads.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include "i8259.h"
+#include "xics.h"
+
+void xics_enable_irq(u_int irq);
+void xics_disable_irq(u_int irq);
+void xics_mask_and_ack_irq(u_int irq);
+void xics_end_irq(u_int irq);
+
+struct hw_interrupt_type xics_pic = {
+ " XICS ",
+ NULL,
+ NULL,
+ xics_enable_irq,
+ xics_disable_irq,
+ xics_mask_and_ack_irq,
+ xics_end_irq
+};
+
+struct hw_interrupt_type xics_8259_pic = {
+ " XICS/8259",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ xics_mask_and_ack_irq,
+ NULL
+};
+
+#define XICS_IPI 2
+#define XICS_IRQ_8259_CASCADE 0x2c
+#define XICS_IRQ_OFFSET 16
+#define XICS_IRQ_SPURIOUS 0
+
+#define DEFAULT_SERVER 0
+#define DEFAULT_PRIORITY 0
+
+struct xics_ipl {
+ union {
+ u32 word;
+ u8 bytes[4];
+ } xirr_poll;
+ union {
+ u32 word;
+ u8 bytes[4];
+ } xirr;
+ u32 dummy;
+ union {
+ u32 word;
+ u8 bytes[4];
+ } qirr;
+};
+
+struct xics_info {
+ volatile struct xics_ipl * per_cpu[NR_CPUS];
+};
+
+struct xics_info xics_info;
+
+#define xirr_info(n_cpu) (xics_info.per_cpu[n_cpu]->xirr.word)
+#define cppr_info(n_cpu) (xics_info.per_cpu[n_cpu]->xirr.bytes[0])
+#define poll_info(n_cpu) (xics_info.per_cpu[n_cpu]->xirr_poll.word)
+#define qirr_info(n_cpu) (xics_info.per_cpu[n_cpu]->qirr.bytes[0])
+
+void
+xics_enable_irq(
+ u_int irq
+ )
+{
+ int status;
+ int call_status;
+
+ irq -= XICS_IRQ_OFFSET;
+ if (irq == XICS_IPI)
+ return;
+ call_status = call_rtas("ibm,set-xive", 3, 1, (ulong*)&status,
+ irq, DEFAULT_SERVER, DEFAULT_PRIORITY);
+ if( call_status != 0 ) {
+ printk("xics_enable_irq: irq=%x: call_rtas failed; retn=%x, status=%x\n",
+ irq, call_status, status);
+ return;
+ }
+}
+
+void
+xics_disable_irq(
+ u_int irq
+ )
+{
+ int status;
+ int call_status;
+
+ irq -= XICS_IRQ_OFFSET;
+ call_status = call_rtas("ibm,int-off", 1, 1, (ulong*)&status, irq);
+ if( call_status != 0 ) {
+ printk("xics_disable_irq: irq=%x: call_rtas failed, retn=%x\n",
+ irq, call_status);
+ return;
+ }
+}
+
+void
+xics_end_irq(
+ u_int irq
+ )
+{
+ int cpu = smp_processor_id();
+
+ cppr_info(cpu) = 0; /* actually the value overwritten by ack */
+ xirr_info(cpu) = (0xff<<24) | (irq-XICS_IRQ_OFFSET);
+}
+
+void
+xics_mask_and_ack_irq(
+ u_int irq
+ )
+{
+ int cpu = smp_processor_id();
+
+ if( irq < XICS_IRQ_OFFSET ) {
+ i8259_pic.ack(irq);
+ xirr_info(cpu) = (0xff<<24) | XICS_IRQ_8259_CASCADE;
+ }
+ else {
+ cppr_info(cpu) = 0xff;
+ }
+}
+
+int
+xics_get_irq(struct pt_regs *regs)
+{
+ u_int cpu = smp_processor_id();
+ u_int vec;
+ int irq;
+
+ vec = xirr_info(cpu);
+ /* (vec >> 24) == old priority */
+ vec &= 0x00ffffff;
+ /* for sanity, this had better be < NR_IRQS - 16 */
+ if( vec == XICS_IRQ_8259_CASCADE )
+ irq = i8259_irq(cpu);
+ else if( vec == XICS_IRQ_SPURIOUS )
+ irq = -1;
+ else
+ irq = vec + XICS_IRQ_OFFSET;
+ return irq;
+}
+
+#ifdef CONFIG_SMP
+void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+{
+ qirr_info(smp_processor_id()) = 0xff;
+ smp_message_recv(MSG_RESCHEDULE);
+}
+
+void xics_cause_IPI(int cpu)
+{
+ qirr_info(cpu) = 0;
+}
+
+void xics_setup_cpu(void)
+{
+ int cpu = smp_processor_id();
+
+ cppr_info(cpu) = 0xff;
+}
+#endif /* CONFIG_SMP */
+
+void
+xics_init_IRQ( void )
+{
+ int i;
+ extern unsigned long smp_chrp_cpu_nr;
+
+#ifdef CONFIG_SMP
+ for (i = 0; i < smp_chrp_cpu_nr; ++i)
+ xics_info.per_cpu[i] =
+ ioremap(0xfe000000 + smp_hw_index[i] * 0x1000, 0x20);
+#else
+ xics_info.per_cpu[0] = ioremap(0xfe000000, 0x20);
+#endif /* CONFIG_SMP */
+ xics_8259_pic.enable = i8259_pic.enable;
+ xics_8259_pic.disable = i8259_pic.disable;
+ for (i = 0; i < 16; ++i)
+ irq_desc[i].handler = &xics_8259_pic;
+ for (; i < NR_IRQS; ++i)
+ irq_desc[i].handler = &xics_pic;
+
+ cppr_info(0) = 0xff;
+ if (request_irq(XICS_IRQ_8259_CASCADE + XICS_IRQ_OFFSET, no_action,
+ 0, "8259 cascade", 0))
+ printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
+ i8259_init();
+
+#ifdef CONFIG_SMP
+ request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0);
+#endif
+}
diff --git a/arch/ppc/kernel/xics.h b/arch/ppc/kernel/xics.h
new file mode 100644
index 00000000000000..88b4d479097133
--- /dev/null
+++ b/arch/ppc/kernel/xics.h
@@ -0,0 +1,23 @@
+/*
+ * arch/ppc/kernel/xics.h
+ *
+ * Copyright 2000 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _PPC_KERNEL_XICS_H
+#define _PPC_KERNEL_XICS_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type xics_pic;
+extern struct hw_interrupt_type xics_8259_pic;
+
+void xics_init_IRQ(void);
+int xics_get_irq(struct pt_regs *);
+
+#endif /* _PPC_KERNEL_XICS_H */
diff --git a/arch/ppc/mbxboot/Makefile b/arch/ppc/mbxboot/Makefile
index 53611aa582f4e7..9dd5d64f36cd5a 100644
--- a/arch/ppc/mbxboot/Makefile
+++ b/arch/ppc/mbxboot/Makefile
@@ -28,14 +28,14 @@ ISZ = 0
TFTPIMAGE=/tftpboot/zImage.embedded
ifdef CONFIG_8xx
-ZLINKFLAGS = -T vmlinux.lds -Ttext 0x00180000
-OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o gzimage.o rdimage.o
+ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00180000
+OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o
CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8xx
endif
ifdef CONFIG_8260
-ZLINKFLAGS = -T vmlinux.lds -Ttext 0x00400000
-OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o gzimage.o rdimage.o
+ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00400000
+OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o
CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8260
endif
@@ -61,32 +61,21 @@ endif
all: zImage
zvmlinux.initrd: zvmlinux
-#
-# Build the boot loader images
-#
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .gzimage gzimage.o
+ $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp1 $(OBJECTS)
$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section=.gzimage=../coffboot/vmlinux.gz \
- --set-section-flags=.gzimage=alloc,load,readonly,data \
- gzimage.o
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .rdimage rdimage.o
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section=.rdimage=ramdisk.image.gz \
- --set-section-flags=.rdimage=alloc,load,readonly,data \
- rdimage.o
- $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS)
-#
-# Compute the sizes/offsets for the final image, and rebuild with these values.
-#
- $(CC) $(CFLAGS) \
- -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd .rdimage` \
- -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd .rdimage` \
- -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd .gzimage` \
- -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd .gzimage` \
+ --add-section=initrd=ramdisk.image.gz \
+ --add-section=image=../coffboot/vmlinux.gz \
+ zvmlinux.initrd.tmp1 zvmlinux.initrd1
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 initrd` \
+ -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 initrd` \
+ -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 image` \
+ -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 image` \
-c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment $@
- $(OBJDUMP) -h $@
+ $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=initrd=ramdisk.image.gz \
+ --add-section=image=../coffboot/vmlinux.gz \
+ zvmlinux.initrd.tmp $@
zImage: zvmlinux
ln -sf zvmlinux zImage
@@ -96,27 +85,23 @@ zImage.initrd: zvmlinux.initrd
zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz
#
-# Build the boot loader images
+# build the boot loader image and then compute the offset into it
+# for the kernel image
#
+ $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
+ zvmlinux.tmp $@
#
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .gzimage gzimage.o
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section=.gzimage=../coffboot/vmlinux.gz \
- --set-section-flags=.gzimage=alloc,load,readonly,data \
- gzimage.o
- $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS)
-#
-# Compute the sizes/offsets for the final image, and rebuild with these values.
+# then with the offset rebuild the bootloader so we know where the kernel is
#
- $(CC) $(CFLAGS) \
- -DINITRD_OFFSET=0 \
- -DINITRD_SIZE=0 \
- -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux .gzimage` \
- -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux .gzimage` \
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
+ -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \
+ -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \
-c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment $@
- $(OBJDUMP) -h $@
+ $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
+ zvmlinux.tmp $@
+ rm zvmlinux.tmp
znetboot : zImage
cp zImage $(TFTPIMAGE)
diff --git a/arch/ppc/mbxboot/embed_config.c b/arch/ppc/mbxboot/embed_config.c
index 048f8bcfe529bb..b9a37a76cb12aa 100644
--- a/arch/ppc/mbxboot/embed_config.c
+++ b/arch/ppc/mbxboot/embed_config.c
@@ -231,17 +231,17 @@ embed_config(bd_t *bd)
u_char *cp;
int i;
-#if 1
+#if 0
/* This is actually provided by my boot rom. I have it
* here for those people that may load the kernel with
* a JTAG/COP tool and not the rom monitor.
*/
- bd->bi_baudrate = 19200;
- bd->bi_intfreq = 165;
- bd->bi_busfreq = 33;
- bd->bi_cpmfreq = 132;
- bd->bi_brgfreq = bd->bi_cpmfreq / 2; /* BRGCLK = (CPM*2/4) */
- bd->bi_memsize = 16 * 1024 * 1024;
+ bd->bi_baudrate = 115200;
+ bd->bi_intfreq = 200;
+ bd->bi_busfreq = 66;
+ bd->bi_cpmfreq = 66;
+ bd->bi_brgfreq = 33;
+ bd->bi_memsize = 16 * 1024 * 1024;
#endif
cp = (u_char *)def_enet_addr;
diff --git a/arch/ppc/mbxboot/head_8260.S b/arch/ppc/mbxboot/head_8260.S
index 0895ce025961f8..3e4bf700aade85 100644
--- a/arch/ppc/mbxboot/head_8260.S
+++ b/arch/ppc/mbxboot/head_8260.S
@@ -101,6 +101,11 @@ start_ldr:
subi r1,r1,256
li r2,0x000F /* Mask pointer to 16-byte boundary */
andc r1,r1,r2
+
+ /* Speed us up a little.
+ */
+ bl flush_instruction_cache
+
/* Run loader */
mr r3,r8 /* Load point */
mr r4,r7 /* Program length */
diff --git a/arch/ppc/mbxboot/m8260_tty.c b/arch/ppc/mbxboot/m8260_tty.c
index 1340577ab2a525..167abbdccdc256 100644
--- a/arch/ppc/mbxboot/m8260_tty.c
+++ b/arch/ppc/mbxboot/m8260_tty.c
@@ -72,8 +72,8 @@ serial_init(bd_t *bd)
*/
up->smc_rbase = dpaddr;
up->smc_tbase = dpaddr+sizeof(cbd_t);
- up->smc_rfcr = SMC_EB;
- up->smc_tfcr = SMC_EB;
+ up->smc_rfcr = CPMFCR_EB;
+ up->smc_tfcr = CPMFCR_EB;
up->smc_brklen = 0;
up->smc_brkec = 0;
up->smc_brkcr = 0;
diff --git a/arch/ppc/mbxboot/mbxtty.c b/arch/ppc/mbxboot/mbxtty.c
deleted file mode 100644
index e5566dc3225e4d..00000000000000
--- a/arch/ppc/mbxboot/mbxtty.c
+++ /dev/null
@@ -1,201 +0,0 @@
-
-
-/* Minimal serial functions needed to send messages out the serial
- * port on the MBX console.
- *
- * The MBX uxes SMC1 for the serial port. We reset the port and use
- * only the first BD that EPPC-Bug set up as a character FIFO.
- *
- * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
- * use COM1 instead of SMC1 as the console port. This kinda sucks
- * for the rest of the kernel, so here we force the use of SMC1 again.
- * I f**ked around for a day trying to figure out how to make EPPC-Bug
- * use SMC1, but gave up and decided to fix it here.
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#ifdef CONFIG_MBX
-#include <asm/mbx.h>
-#endif
-#ifdef CONFIG_FADS
-#include <asm/fads.h>
-#endif
-#include "../8xx_io/commproc.h"
-
-#ifdef CONFIG_MBX
-#define MBX_CSR1 ((volatile u_char *)0xfa100000)
-#define CSR1_COMEN (u_char)0x02
-#endif
-
-static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
-
-void
-serial_init(bd_t *bd)
-{
- volatile smc_t *sp;
- volatile smc_uart_t *up;
- volatile cbd_t *tbdf, *rbdf;
- volatile cpm8xx_t *cp;
- uint dpaddr, memaddr;
-
- cp = cpmp;
- sp = (smc_t*)&(cp->cp_smc[0]);
- up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
-
- /* Disable transmitter/receiver.
- */
- sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-
-#ifdef CONFIG_MBX
- if (*MBX_CSR1 & CSR1_COMEN) {
- /* COM1 is enabled. Initialize SMC1 and use it for
- * the console port.
- */
-
- /* Enable SDMA.
- */
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
-
- /* Use Port B for SMCs instead of other functions.
- */
- cp->cp_pbpar |= 0x00000cc0;
- cp->cp_pbdir &= ~0x00000cc0;
- cp->cp_pbodr &= ~0x00000cc0;
-
- /* Allocate space for two buffer descriptors in the DP ram.
- * For now, this address seems OK, but it may have to
- * change with newer versions of the firmware.
- */
- dpaddr = 0x0800;
-
- /* Grab a few bytes from the top of memory. EPPC-Bug isn't
- * running any more, so we can do this.
- */
- memaddr = (bd->bi_memsize - 32) & ~15;
-
- /* Set the physical address of the host memory buffers in
- * the buffer descriptors.
- */
- rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
- rbdf->cbd_bufaddr = memaddr;
- rbdf->cbd_sc = 0;
- tbdf = rbdf + 1;
- tbdf->cbd_bufaddr = memaddr+4;
- tbdf->cbd_sc = 0;
-
- /* Set up the uart parameters in the parameter ram.
- */
- up->smc_rbase = dpaddr;
- up->smc_tbase = dpaddr+sizeof(cbd_t);
- up->smc_rfcr = SMC_EB;
- up->smc_tfcr = SMC_EB;
-
- /* Set UART mode, 8 bit, no parity, one stop.
- * Enable receive and transmit.
- */
- sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
-
- /* Mask all interrupts and remove anything pending.
- */
- sp->smc_smcm = 0;
- sp->smc_smce = 0xff;
-
- /* Set up the baud rate generator.
- * See 8xx_io/commproc.c for details.
- */
- cp->cp_simode = 0x10000000;
- cp->cp_brgc1 =
- ((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN;
-
- /* Enable SMC1 for console output.
- */
- *MBX_CSR1 &= ~CSR1_COMEN;
- }
- else {
-#endif
- /* SMC1 is used as console port.
- */
- tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
- rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
-
- /* Issue a stop transmit, and wait for it.
- */
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1,
- CPM_CR_STOP_TX) | CPM_CR_FLG;
- while (cp->cp_cpcr & CPM_CR_FLG);
-#ifdef CONFIG_MBX
- }
-#endif
-
- /* Make the first buffer the only buffer.
- */
- tbdf->cbd_sc |= BD_SC_WRAP;
- rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
-
- /* Single character receive.
- */
- up->smc_mrblr = 1;
- up->smc_maxidl = 0;
-
- /* Initialize Tx/Rx parameters.
- */
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG;
- while (cp->cp_cpcr & CPM_CR_FLG);
-
- /* Enable transmitter/receiver.
- */
- sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
-}
-
-void
-serial_putchar(const char c)
-{
- volatile cbd_t *tbdf;
- volatile char *buf;
- volatile smc_uart_t *up;
-
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1];
- tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
-
- /* Wait for last character to go.
- */
- buf = (char *)tbdf->cbd_bufaddr;
- while (tbdf->cbd_sc & BD_SC_READY);
-
- *buf = c;
- tbdf->cbd_datlen = 1;
- tbdf->cbd_sc |= BD_SC_READY;
-}
-
-char
-serial_getc()
-{
- volatile cbd_t *rbdf;
- volatile char *buf;
- volatile smc_uart_t *up;
- char c;
-
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1];
- rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
-
- /* Wait for character to show up.
- */
- buf = (char *)rbdf->cbd_bufaddr;
- while (rbdf->cbd_sc & BD_SC_EMPTY);
- c = *buf;
- rbdf->cbd_sc |= BD_SC_EMPTY;
-
- return(c);
-}
-
-int
-serial_tstc()
-{
- volatile cbd_t *rbdf;
- volatile smc_uart_t *up;
-
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1];
- rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
-
- return(!(rbdf->cbd_sc & BD_SC_EMPTY));
-}
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 7a899252faf126..0b551c8032858e 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -238,11 +238,17 @@ bad_page_fault(struct pt_regs *regs, unsigned long address)
/* The pgtable.h claims some functions generically exist, but I
* can't find them......
*/
-pte_t *find_pte(struct mm_struct *mm, unsigned long address)
+pte_t *va_to_pte(unsigned long address)
{
pgd_t *dir;
pmd_t *pmd;
pte_t *pte;
+ struct mm_struct *mm;
+
+ if (address < TASK_SIZE)
+ mm = current->mm;
+ else
+ mm = &init_mm;
dir = pgd_offset(mm, address & PAGE_MASK);
if (dir) {
@@ -267,7 +273,7 @@ unsigned long va_to_phys(unsigned long address)
{
pte_t *pte;
- pte = find_pte(current->mm, address);
+ pte = va_to_pte(address);
if (pte)
return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK-1)));
return (0);
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index fc3acdd5c25dda..0cfb5916cc7226 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -94,6 +94,7 @@ unsigned long avail_start;
extern int num_memory;
extern struct mem_info memory[];
extern boot_infos_t *boot_infos;
+extern unsigned int rtas_data, rtas_size;
#ifndef CONFIG_SMP
struct pgtable_cache_struct quicklists;
#endif
@@ -116,21 +117,26 @@ unsigned long *m8260_find_end_of_memory(void);
#endif /* CONFIG_8260 */
static void mapin_ram(void);
void map_page(unsigned long va, unsigned long pa, int flags);
+void set_phys_avail(struct mem_pieces *mp);
extern void die_if_kernel(char *,struct pt_regs *,long);
-struct mem_pieces phys_mem;
-
+extern char _start[], _end[];
+extern char _stext[], etext[];
extern struct task_struct *current_set[NR_CPUS];
-PTE *Hash, *Hash_end;
-unsigned long Hash_size, Hash_mask;
+struct mem_pieces phys_mem;
+char *klimit = _end;
+struct mem_pieces phys_avail;
+
+PTE *Hash=0, *Hash_end;
+unsigned long Hash_size=0, Hash_mask;
#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-unsigned long _SDR1;
+unsigned long _SDR1=0;
static void hash_init(void);
union ubat { /* BAT register values to be loaded */
BAT bat;
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
u64 word[2];
#else
u32 word[2];
@@ -479,7 +485,8 @@ map_page(unsigned long va, unsigned long pa, int flags)
if (pmd_none(oldpd) && mem_init_done)
set_pgdir(va, *(pgd_t *)pd);
set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
- flush_hash_page(0, va);
+ if (mem_init_done)
+ flush_hash_page(0, va);
}
#ifndef CONFIG_8xx
@@ -503,11 +510,16 @@ map_page(unsigned long va, unsigned long pa, int flags)
void
local_flush_tlb_all(void)
{
+#ifdef CONFIG_PPC64BRIDGE
+ /* XXX this assumes that the vmalloc arena starts no lower than
+ * 0xd0000000 on 64-bit machines. */
+ flush_hash_segments(0xd, 0xffffff);
+#else
__clear_user(Hash, Hash_size);
- _tlbia();
#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
-#endif
+#endif /* CONFIG_SMP */
+#endif /* CONFIG_PPC64BRIDGE */
}
/*
@@ -591,7 +603,10 @@ mmu_context_overflow(void)
atomic_set(&next_mmu_context, 0);
/* make sure current always has a context */
current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context));
- set_context(current->mm->context);
+ /* The PGD is only a placeholder. It is only used on
+ * 8xx processors.
+ */
+ set_context(current->mm->context, current->mm->pgd);
}
#endif /* CONFIG_8xx */
@@ -690,7 +705,7 @@ static void __init mapin_ram(void)
int i;
unsigned long v, p, s, f;
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
if (!__map_without_bats) {
unsigned long tot, mem_base, bl, done;
unsigned long max_size = (256<<20);
@@ -725,7 +740,7 @@ static void __init mapin_ram(void)
RAM_PAGE);
}
}
-#endif /* !CONFIG_4xx && !CONFIG_8xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_POWER4 */
for (i = 0; i < phys_mem.n_regions; ++i) {
v = (ulong)__va(phys_mem.regions[i].address);
@@ -940,9 +955,7 @@ void __init MMU_init(void)
if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
hash_init();
-#ifdef CONFIG_PPC64
- _SDR1 = __pa(Hash) | (ffz(~Hash_size) - 7)-11;
-#else
+#ifndef CONFIG_PPC64BRIDGE
_SDR1 = __pa(Hash) | (Hash_mask >> 10);
#endif
@@ -952,6 +965,11 @@ void __init MMU_init(void)
/* Map in all of RAM starting at KERNELBASE */
mapin_ram();
+#ifdef CONFIG_POWER4
+ ioremap_base = ioremap_bot = 0xfffff000;
+ isa_io_base = (unsigned long) ioremap(0xffd00000, 0x200000) + 0x100000;
+
+#else /* CONFIG_POWER4 */
/*
* Setup the bat mappings we're going to load that cover
* the io areas. RAM was mapped by mapin_ram().
@@ -966,26 +984,15 @@ void __init MMU_init(void)
break;
case _MACH_chrp:
setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE);
-#ifdef CONFIG_PPC64
- /* temporary hack to get working until page tables are stable -- Cort*/
-/* setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE);*/
- setbat(3, 0xd0000000, 0xd0000000, 0x10000000, IO_PAGE);
+#ifdef CONFIG_PPC64BRIDGE
+ setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE);
#else
setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
-#endif
+#endif
break;
case _MACH_Pmac:
-#if 0
- {
- unsigned long base = 0xf3000000;
- struct device_node *macio = find_devices("mac-io");
- if (macio && macio->n_addrs)
- base = macio->addrs[0].address;
- setbat(0, base, base, 0x100000, IO_PAGE);
- }
-#endif
- ioremap_base = 0xf0000000;
+ ioremap_base = 0xf8000000;
break;
case _MACH_apus:
/* Map PPC exception vectors. */
@@ -1009,6 +1016,7 @@ void __init MMU_init(void)
break;
}
ioremap_bot = ioremap_base;
+#endif /* CONFIG_POWER4 */
#else /* CONFIG_8xx */
end_of_DRAM = m8xx_find_end_of_memory();
@@ -1080,6 +1088,7 @@ void __init do_init_bootmem(void)
/* remove the bootmem bitmap from the available memory */
mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
+
/* add everything in phys_avail into the bootmem map */
for (i = 0; i < phys_avail.n_regions; ++i)
free_bootmem(phys_avail.regions[i].address,
@@ -1159,9 +1168,6 @@ void __init mem_init(void)
int codepages = 0;
int datapages = 0;
int initpages = 0;
-#if defined(CONFIG_ALL_PPC)
- extern unsigned int rtas_data, rtas_size;
-#endif /* defined(CONFIG_ALL_PPC) */
max_mapnr = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
num_physpages = max_mapnr; /* RAM is assumed contiguous */
@@ -1223,13 +1229,7 @@ void __init mem_init(void)
unsigned long __init *pmac_find_end_of_memory(void)
{
unsigned long a, total;
- unsigned long ram_limit = 0xf0000000 - KERNELBASE;
- /* allow 0x08000000 for IO space */
- if ( _machine & (_MACH_prep|_MACH_Pmac) )
- ram_limit = 0xd8000000 - KERNELBASE;
-#ifdef CONFIG_PPC64
- ram_limit = 64<<20;
-#endif
+ unsigned long ram_limit = 0xe0000000 - KERNELBASE;
memory_node = find_devices("memory");
if (memory_node == NULL) {
@@ -1422,27 +1422,42 @@ unsigned long __init *apus_find_end_of_memory(void)
*/
static void __init hash_init(void)
{
- int Hash_bits;
- unsigned long h, ramsize;
+ int Hash_bits, mb, mb2;
+ unsigned int hmask, ramsize, h;
extern unsigned int hash_page_patch_A[], hash_page_patch_B[],
hash_page_patch_C[], hash_page[];
+ ramsize = (ulong)end_of_DRAM - KERNELBASE;
+#ifdef CONFIG_PPC64BRIDGE
+ /* The hash table has already been allocated and initialized
+ in prom.c */
+ Hash_mask = (Hash_size >> 7) - 1;
+ hmask = Hash_mask >> 9;
+ Hash_bits = __ilog2(Hash_size) - 7;
+ mb = 25 - Hash_bits;
+ if (Hash_bits > 16)
+ Hash_bits = 16;
+ mb2 = 25 - Hash_bits;
+
+#else /* CONFIG_PPC64BRIDGE */
+
if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
/*
* Allow 64k of hash table for every 16MB of memory,
* up to a maximum of 2MB.
*/
- ramsize = (ulong)end_of_DRAM - KERNELBASE;
- for (h = 64<<10; h < ramsize / 256 && h < 2<<20; h *= 2)
+ for (h = 64<<10; h < ramsize / 256 && h < (2<<20); h *= 2)
;
Hash_size = h;
-#ifdef CONFIG_PPC64
- Hash_mask = (h >> 7) - 1;
-#else
Hash_mask = (h >> 6) - 1;
-#endif
-
+ hmask = Hash_mask >> 10;
+ Hash_bits = __ilog2(h) - 6;
+ mb = 26 - Hash_bits;
+ if (Hash_bits > 16)
+ Hash_bits = 16;
+ mb2 = 26 - Hash_bits;
+
/* shrink the htab since we don't use it on 603's -- Cort */
switch (_get_PVR()>>16) {
case 3: /* 603 */
@@ -1459,50 +1474,36 @@ static void __init hash_init(void)
if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
/* Find some memory for the hash table. */
- if ( Hash_size )
+ if ( Hash_size ) {
Hash = mem_pieces_find(Hash_size, Hash_size);
- else
+ /*__clear_user(Hash, Hash_size);*/
+ } else
Hash = 0;
+#endif /* CONFIG_PPC64BRIDGE */
- printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
+ printk("Total memory = %dMB; using %ldkB for hash table (at %p)\n",
ramsize >> 20, Hash_size >> 10, Hash);
if ( Hash_size )
{
if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
- /*__clear_user(Hash, Hash_size);*/
/*
* Patch up the instructions in head.S:hash_page
*/
-#ifdef CONFIG_PPC64
- Hash_bits = ffz(~Hash_size) - 7;
-#else
- Hash_bits = ffz(~Hash_size) - 6;
-#endif
hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
| (__pa(Hash) >> 16);
hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0)
- | ((26 - Hash_bits) << 6);
- if (Hash_bits > 16)
- Hash_bits = 16;
+ | (mb << 6);
hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0)
- | ((26 - Hash_bits) << 6);
+ | (mb2 << 6);
hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff)
-#ifdef CONFIG_PPC64
- | (Hash_mask >> 11);
-#else
- | (Hash_mask >> 10);
-#endif
+ | hmask;
hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff)
-#ifdef CONFIG_PPC64
- | (Hash_mask >> 11);
-#else
- | (Hash_mask >> 10);
-#endif
+ | hmask;
#if 0 /* see hash_page in head.S, note also patch_C ref below */
hash_page_patch_D[0] = (hash_page_patch_D[0] & ~0xffff)
- | (Hash_mask >> 10);
+ | hmask;
#endif
/*
* Ensure that the locations we've patched have been written
@@ -1579,3 +1580,48 @@ oak_find_end_of_memory(void)
return (ret);
}
#endif
+
+/*
+ * Set phys_avail to phys_mem less the kernel text/data/bss.
+ */
+void __init
+set_phys_avail(struct mem_pieces *mp)
+{
+ unsigned long kstart, ksize;
+
+ /*
+ * Initially, available phyiscal memory is equivalent to all
+ * physical memory.
+ */
+
+ phys_avail = *mp;
+
+ /*
+ * Map out the kernel text/data/bss from the available physical
+ * memory.
+ */
+
+ kstart = __pa(_stext); /* should be 0 */
+ ksize = PAGE_ALIGN(klimit - _stext);
+
+ mem_pieces_remove(&phys_avail, kstart, ksize, 0);
+ mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+ /* Remove the init RAM disk from the available memory. */
+ if (initrd_start) {
+ mem_pieces_remove(&phys_avail, __pa(initrd_start),
+ initrd_end - initrd_start, 1);
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+#ifdef CONFIG_ALL_PPC
+ /* remove the RTAS pages from the available memory */
+ if (rtas_data)
+ mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
+#endif /* CONFIG_ALL_PPC */
+#ifdef CONFIG_PPC64BRIDGE
+ /* Remove the hash table from the available memory */
+ if (Hash)
+ mem_pieces_remove(&phys_avail, __pa(Hash), Hash_size, 1);
+#endif /* CONFIG_PPC64BRIDGE */
+}
diff --git a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c
index 309a526f5736cb..a329cca7a83c2d 100644
--- a/arch/ppc/mm/mem_pieces.c
+++ b/arch/ppc/mm/mem_pieces.c
@@ -18,18 +18,11 @@
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/blk.h>
-
-#include <asm/page.h>
-#include <asm/prom.h>
+#include <linux/init.h>
#include "mem_pieces.h"
-extern char _start[], _end[];
-extern char _stext[], etext[];
-
-char *klimit = _end;
-
-struct mem_pieces phys_avail;
+extern struct mem_pieces phys_avail;
static void mem_pieces_print(struct mem_pieces *);
@@ -142,7 +135,7 @@ mem_pieces_append(struct mem_pieces *mp, unsigned int start, unsigned int size)
rp->address = start;
rp->size = size;
}
-#endif
+#endif /* CONFIG_APUS || CONFIG_ALL_PPC */
void __init
mem_pieces_sort(struct mem_pieces *mp)
@@ -185,38 +178,3 @@ mem_pieces_coalesce(struct mem_pieces *mp)
}
mp->n_regions = d;
}
-
-/*
- * Set phys_avail to phys_mem less the kernel text/data/bss.
- */
-void __init
-set_phys_avail(struct mem_pieces *mp)
-{
- unsigned long kstart, ksize;
-
- /*
- * Initially, available phyiscal memory is equivalent to all
- * physical memory.
- */
-
- phys_avail = *mp;
-
- /*
- * Map out the kernel text/data/bss from the available physical
- * memory.
- */
-
- kstart = __pa(_stext); /* should be 0 */
- ksize = PAGE_ALIGN(klimit - _stext);
-
- mem_pieces_remove(&phys_avail, kstart, ksize, 0);
- mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
-
-#if defined(CONFIG_BLK_DEV_INITRD)
- /* Remove the init RAM disk from the available memory. */
- if (initrd_start) {
- mem_pieces_remove(&phys_avail, __pa(initrd_start),
- initrd_end - initrd_start, 1);
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
-}
diff --git a/arch/ppc/mm/mem_pieces.h b/arch/ppc/mm/mem_pieces.h
index 6dbe045da7dd9a..bc8e2861c4059e 100644
--- a/arch/ppc/mm/mem_pieces.h
+++ b/arch/ppc/mm/mem_pieces.h
@@ -17,8 +17,7 @@
#ifndef __MEM_PIECES_H__
#define __MEM_PIECES_H__
-#include <linux/init.h>
-
+#include <asm/prom.h>
#ifdef __cplusplus
extern "C" {
@@ -34,13 +33,6 @@ struct mem_pieces {
struct reg_property regions[MEM_PIECES_MAX];
};
-
-/* Global Variables */
-
-extern char *klimit;
-extern struct mem_pieces phys_avail;
-
-
/* Function Prototypes */
extern void *mem_pieces_find(unsigned int size, unsigned int align);
@@ -51,9 +43,6 @@ extern void mem_pieces_append(struct mem_pieces *mp, unsigned int start,
extern void mem_pieces_coalesce(struct mem_pieces *mp);
extern void mem_pieces_sort(struct mem_pieces *mp);
-extern void set_phys_avail(struct mem_pieces *mp);
-
-
#ifdef __cplusplus
}
#endif
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 77b6f3548d4187..a816f0b9d7b8e7 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -272,7 +272,7 @@ xmon_init_scc()
if ( _machine == _MACH_chrp )
{
sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
- sccd[0] = 3; eieio(); /* DLL = 38400 baud */
+ sccd[0] = 12; eieio(); /* DLL = 9600 baud */
sccd[1] = 0; eieio();
sccd[2] = 0; eieio(); /* FCR = 0 */
sccd[3] = 3; eieio(); /* LCR = 8N1 */
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 9cc30284025b0f..4abc138cffbe4d 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -19,6 +19,7 @@ static unsigned adrs;
static int size = 1;
static unsigned ndump = 64;
static unsigned nidump = 16;
+static unsigned ncsum = 4096;
static int termch;
static u_int bus_error_jmp[100];
@@ -85,6 +86,7 @@ static void bpt_cmds(void);
static void cacheflush(void);
static char *pretty_print_addr(unsigned long addr);
static char *lookup_name(unsigned long addr);
+static void csum(void);
extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
extern void printf(const char *fmt, ...);
@@ -261,7 +263,7 @@ insert_bpts()
bp->enabled = 0;
}
}
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
if (dabr.enabled)
set_dabr(dabr.address);
if (iabr.enabled)
@@ -276,7 +278,7 @@ remove_bpts()
struct bpt *bp;
unsigned instr;
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
set_dabr(0);
set_iabr(0);
#endif
@@ -379,8 +381,68 @@ cmds(struct pt_regs *excp)
case 'b':
bpt_cmds();
break;
+ case 'c':
+ csum();
+ break;
+ }
+ }
+}
+
+static unsigned short fcstab[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+ 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+ 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+ 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+ 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+ 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+ 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+ 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+ 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+ 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+ 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+ 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+ 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+ 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+ 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+ 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+ 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+ 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+ 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+ 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+ 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+ 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+ 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+ 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+ 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+ 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+ 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+ 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+ 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+ 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+ 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
+
+static void
+csum(void)
+{
+ unsigned int i;
+ unsigned short fcs;
+ unsigned char v;
+
+ scanhex(&adrs);
+ scanhex(&ncsum);
+ fcs = 0xffff;
+ for (i = 0; i < ncsum; ++i) {
+ if (mread(adrs+i, &v, 1) == 0) {
+ printf("csum stopped at %x\n", adrs+i);
+ break;
}
+ fcs = FCS(fcs, v);
}
+ printf("%x\n", fcs);
}
static void
@@ -393,7 +455,7 @@ bpt_cmds(void)
cmd = inchar();
switch (cmd) {
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
case 'd':
mode = 7;
cmd = inchar();
@@ -695,6 +757,7 @@ openforth()
}
#endif
+#ifndef CONFIG_PPC64BRIDGE
static void
dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
{
@@ -752,6 +815,67 @@ dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
if (last_found)
printf(" ... %x\n", last_va);
}
+
+#else /* CONFIG_PPC64BRIDGE */
+static void
+dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+{
+ extern void *Hash;
+ extern unsigned long Hash_size;
+ unsigned *htab = Hash;
+ unsigned hsize = Hash_size;
+ unsigned v, hmask, va, last_va;
+ int found, last_found, i;
+ unsigned *hg, w1, last_w2, last_va0;
+
+ last_found = 0;
+ hmask = hsize / 128 - 1;
+ va = start;
+ start = (start >> 12) & 0xffff;
+ end = (end >> 12) & 0xffff;
+ for (v = start; v < end; ++v) {
+ found = 0;
+ hg = htab + (((v ^ seg) & hmask) * 32);
+ w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
+ for (i = 0; i < 8; ++i, hg += 4) {
+ if (hg[1] == w1) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ w1 ^= 2;
+ hg = htab + ((~(v ^ seg) & hmask) * 32);
+ for (i = 0; i < 8; ++i, hg += 4) {
+ if (hg[1] == w1) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
+ if (last_found) {
+ if (last_va != last_va0)
+ printf(" ... %x", last_va);
+ printf("\n");
+ }
+ if (found) {
+ printf("%x to %x", va, hg[3]);
+ last_va0 = va;
+ }
+ last_found = found;
+ }
+ if (found) {
+ last_w2 = hg[3] & ~0x180;
+ last_va = va;
+ }
+ va += 4096;
+ }
+ if (last_found)
+ printf(" ... %x\n", last_va);
+}
+#endif /* CONFIG_PPC64BRIDGE */
+
static unsigned hash_ctx;
static unsigned hash_start;
static unsigned hash_end;
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 1857ef33b11637..05cc371011580a 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.4 2000/03/08 15:14:14 gniibe Exp $
+# $Id: Makefile,v 1.6 2000/06/10 03:03:52 gniibe Exp $
#
# 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
@@ -22,6 +22,11 @@ CFLAGS += -ml
AFLAGS += -ml
# LINKFLAGS += -EL
LDFLAGS := -EL
+else
+CFLAGS += -mb
+AFLAGS += -mb
+# LINKFLAGS += -EB
+LDFLAGS := -EB
endif
# ifdef CONFIG_CROSSCOMPILE
@@ -29,7 +34,7 @@ CROSS_COMPILE = $(tool-prefix)
# endif
LD =$(CROSS_COMPILE)ld $(LDFLAGS)
-OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
+OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr -S
MODFLAGS +=
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index 8c087beb1c3821..aff166e2802fc8 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -5,37 +5,30 @@
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
+# Copyright (C) 1999 Stuart Menefy
+#
-.S.s:
- $(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
- $(CC) $(CFLAGS) -c $< -o $*.o
+SYSTEM =$(TOPDIR)/vmlinux
-OBJS =
+Image: $(CONFIGURE) $(SYSTEM)
+ $(OBJCOPY) $(SYSTEM) Image
-#
-# Drop some uninteresting sections in the kernel.
-#
-drop-sections = .reginfo .mdebug
-strip-flags = $(addprefix --remove-section=,$(drop-sections))
+zImage: $(CONFIGURE) compressed/vmlinux
+ $(OBJCOPY) compressed/vmlinux zImage
-#
-# Fake compressed boot
-#
-zImage: $(CONFIGURE) mkboot $(TOPDIR)/vmlinux
- $(OBJCOPY) $(strip-flags) $(TOPDIR)/vmlinux zImage.tmp
- ./mkboot zImage.tmp zImage
- rm -f zImage.tmp
+compressed/vmlinux: $(TOPDIR)/vmlinux
+ $(MAKE) -C compressed vmlinux
+
+install: $(CONFIGURE) Image
+ sh -x ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
-mkboot: mkboot.c
- $(HOSTCC) -o $@ $^
+zinstall: $(CONFIGURE) zImage
+ sh -x ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
-# Don't build dependencies, this may die if $(CC) isn't gcc
dep:
clean:
- rm -f zImage zImage.tmp mkboot
-
-dummy:
-
-include $(TOPDIR)/Rules.make
+ rm -f tools/build
+ rm -f setup bootsect zImage compressed/vmlinux.out
+ rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
+ @$(MAKE) -C compressed clean
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
new file mode 100644
index 00000000000000..7a5b5b22f2adba
--- /dev/null
+++ b/arch/sh/boot/compressed/Makefile
@@ -0,0 +1,39 @@
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+HEAD = head.o
+SYSTEM = $(TOPDIR)/vmlinux
+
+OBJECTS = $(HEAD) misc.o
+
+ZLDFLAGS = -e startup -T $(TOPDIR)/arch/sh/vmlinux.lds
+
+#
+# ZIMAGE_OFFSET is the load offset of the compression loader
+#
+ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x200000])
+
+ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
+
+all: vmlinux
+
+vmlinux: piggy.o $(OBJECTS)
+ $(LD) $(ZLINKFLAGS) -o vmlinux $(OBJECTS) piggy.o
+
+head.o: head.S
+ $(CC) $(AFLAGS) -traditional -c head.S
+
+piggy.o: $(SYSTEM)
+ tmppiggy=_tmp_$$$$piggy; \
+ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
+ $(OBJCOPY) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \
+ gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
+ echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+ $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-shl -T $$tmppiggy.lnk; \
+ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
+
+clean:
+ rm -f vmlinux _tmp_*
diff --git a/arch/sh/boot/compressed/head.S b/arch/sh/boot/compressed/head.S
new file mode 100644
index 00000000000000..d270d1b47a90a7
--- /dev/null
+++ b/arch/sh/boot/compressed/head.S
@@ -0,0 +1,53 @@
+/*
+ * linux/arch/sh/boot/compressed/head.S
+ *
+ * Copyright (C) 1999 Stuart Menefy
+ */
+
+.text
+
+#include <linux/linkage.h>
+
+ .global startup
+startup:
+
+ /* First clear BSS */
+ mov.l end_addr, r1
+ mov.l bss_start_addr, r2
+ mov #0, r0
+l1:
+ mov.l r0, @-r1
+ cmp/eq r1,r2
+ bf l1
+
+ /* Load initial status register */
+ mov.l init_sr, r1
+ ldc r1, sr
+
+ /* Set the initial pointer. */
+ mov.l init_stack_addr, r0
+ mov.l @r0, r15
+
+ /* Decompress the kernel */
+ mov.l decompress_kernel_addr, r0
+ jsr @r0
+ nop
+
+ /* Jump to the start of the decompressed kernel */
+ mov.l kernel_start_addr, r0
+ jmp @r0
+ nop
+
+ .align 2
+bss_start_addr:
+ .long __bss_start
+end_addr:
+ .long _end
+init_sr:
+ .long 0x50000000 /* Privileged mode, Bank=0, Block=1, I3-I0=0 */
+init_stack_addr:
+ .long stack_start
+decompress_kernel_addr:
+ .long decompress_kernel
+kernel_start_addr:
+ .long _text+0x1000
diff --git a/arch/sh/boot/compressed/install.sh b/arch/sh/boot/compressed/install.sh
new file mode 100644
index 00000000000000..90589f0fec1249
--- /dev/null
+++ b/arch/sh/boot/compressed/install.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# arch/sh/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
+#
+# "make install" script for sh architecture
+#
+# Arguments:
+# $1 - kernel version
+# $2 - kernel image file
+# $3 - kernel map file
+# $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/installkernel ]; then
+ exec /sbin/installkernel "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+ echo "Installing compressed kernel"
+ if [ -f $4/vmlinuz-$1 ]; then
+ mv $4/vmlinuz-$1 $4/vmlinuz.old
+ fi
+
+ if [ -f $4/System.map-$1 ]; then
+ mv $4/System.map-$1 $4/System.old
+ fi
+
+ cat $2 > $4/vmlinuz-$1
+ cp $3 $4/System.map-$1
+else
+# Normal install
+ echo "Installing normal kernel"
+ if [ -f $4/vmlinux-$1 ]; then
+ mv $4/vmlinux-$1 $4/vmlinux.old
+ fi
+
+ if [ -f $4/System.map ]; then
+ mv $4/System.map $4/System.old
+ fi
+
+ cat $2 > $4/vmlinux-$1
+ cp $3 $4/System.map
+fi
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
new file mode 100644
index 00000000000000..aab7985053c3e2
--- /dev/null
+++ b/arch/sh/boot/compressed/misc.c
@@ -0,0 +1,232 @@
+/*
+ * arch/sh/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ */
+
+#include <linux/config.h>
+#include <asm/uaccess.h>
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args) args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset ((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000 /* Window size must be at least 32k, */
+ /* and a power of two */
+
+static uch *inbuf; /* input buffer */
+static uch window[WSIZE]; /* Sliding window buffer */
+
+static unsigned insize = 0; /* valid bytes in inbuf */
+static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0; /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
+#define RESERVED 0xC0 /* bit 6,7: reserved */
+
+#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static void puts(const char *);
+
+extern int _text; /* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#define HEAP_SIZE 0x10000
+
+#include "../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+ void *p;
+
+ if (size <0) error("Malloc error\n");
+ if (free_mem_ptr == 0) error("Memory error\n");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *)free_mem_ptr;
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+ error("\nOut of memory\n");
+
+ return p;
+}
+
+static void free(void *where)
+{ /* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+ *ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+ free_mem_ptr = (long) *ptr;
+}
+
+#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#define IN_GDB 1
+#endif
+#include <asm/io.h>
+#include "../../../../drivers/char/sh-sci.h"
+
+static int strlen(const char *s)
+{
+ int i = 0;
+
+ while (*s++)
+ i++;
+ return i;
+}
+
+void puts(const char *s)
+{
+ put_string(s, strlen(s));
+}
+
+void* memset(void* s, int c, size_t n)
+{
+ int i;
+ char *ss = (char*)s;
+
+ for (i=0;i<n;i++) ss[i] = c;
+ return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+ size_t __n)
+{
+ int i;
+ char *d = (char *)__dest, *s = (char *)__src;
+
+ for (i=0;i<__n;i++) d[i] = s[i];
+ return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+ if (insize != 0) {
+ error("ran out of input data\n");
+ }
+
+ inbuf = input_data;
+ insize = input_len;
+ inptr = 1;
+ return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out++ = *in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
+}
+
+static void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+#define STACK_SIZE (4096)
+long user_stack [STACK_SIZE];
+long* stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+ output_data = 0;
+ output_ptr = (unsigned long)&_text+0x20001000;
+ free_mem_ptr = (unsigned long)&_end;
+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+ makecrc();
+ puts("Uncompressing Linux... ");
+ gunzip();
+ puts("Ok, booting the kernel.\n");
+}
diff --git a/arch/sh/config.in b/arch/sh/config.in
index ef521e0d4ec35c..f67a029e0bee6f 100644
--- a/arch/sh/config.in
+++ b/arch/sh/config.in
@@ -1,6 +1,6 @@
#
# For a description of the syntax of this configuration file,
-# see the Configure script.
+# see Documentation/kbuild/config-language.txt.
#
mainmenu_name "Linux/SuperH Kernel Configuration"
@@ -17,7 +17,9 @@ mainmenu_option next_comment
comment 'Processor type and features'
choice 'SuperH system type' \
"Generic CONFIG_SH_GENERIC \
- SolutionEngine CONFIG_SH_SOLUTION_ENGINE" Generic
+ SolutionEngine CONFIG_SH_SOLUTION_ENGINE \
+ Overdrive CONFIG_SH_OVERDRIVE \
+ HP600 CONFIG_SH_HP600" Generic
choice 'Processor type' \
"SH7708 CONFIG_CPU_SUBTYPE_SH7708 \
@@ -36,7 +38,8 @@ if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then
define_bool CONFIG_CPU_SH4 y
fi
bool 'Little Endian' CONFIG_LITTLE_ENDIAN
-if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
+if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \
+ "$CONFIG_SH_OVERDRIVE" = "y" ]; then
define_hex CONFIG_MEMORY_START 0c000000
else
hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
@@ -61,8 +64,14 @@ define_bool CONFIG_SBUS n
bool 'Networking support' CONFIG_NET
-if [ "$CONFIG_SH_SOLUTION_ENGINE" != "y" ]; then
- bool 'Directly Connected Compact Flash support' CONFIG_CF_ENABLER
+if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
+ bool 'Compact Flash Enabler support' CONFIG_CF_ENABLER
+fi
+
+bool 'Hitachi HD64461 companion chip support' CONFIG_HD64461
+if [ "$CONFIG_HD64461" = "y" ]; then
+ int 'HD64461 IRQ' CONFIG_HD64461_IRQ 36
+ bool 'HD64461 PCMCIA enabler' CONFIG_HD64461_ENABLER
fi
bool 'PCI support' CONFIG_PCI
@@ -158,11 +167,6 @@ if [ "$CONFIG_VT" = "y" ]; then
fi
tristate 'Serial support' CONFIG_SERIAL
-if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SERIAL" = "m" ]; then
- choice 'Serial interface type' \
- "SCI CONFIG_SH_SCI_SERIAL \
- SCIF CONFIG_SH_SCIF_SERIAL"
-fi
if [ "$CONFIG_SERIAL" = "y" ]; then
bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
fi
diff --git a/arch/sh/defconfig b/arch/sh/defconfig
index 6e1a2ba2dada60..be2685bd784981 100644
--- a/arch/sh/defconfig
+++ b/arch/sh/defconfig
@@ -14,6 +14,8 @@ CONFIG_UID16=y
#
CONFIG_SH_GENERIC=y
# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_OVERDRIVE is not set
+# CONFIG_SH_HP600 is not set
CONFIG_CPU_SUBTYPE_SH7708=y
# CONFIG_CPU_SUBTYPE_SH7709 is not set
# CONFIG_CPU_SUBTYPE_SH7750 is not set
@@ -35,6 +37,7 @@ CONFIG_IOPORT_START=ba000000
# CONFIG_SBUS is not set
# CONFIG_NET is not set
CONFIG_CF_ENABLER=y
+# CONFIG_HD64461 is not set
# CONFIG_PCI is not set
# CONFIG_HOTPLUG is not set
# CONFIG_PCMCIA is not set
@@ -59,17 +62,16 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_LVM 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_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
#
@@ -96,6 +98,8 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
@@ -110,6 +114,7 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
#
@@ -122,8 +127,6 @@ CONFIG_BLK_DEV_IDEDISK=y
#
# CONFIG_VT is not set
CONFIG_SERIAL=y
-CONFIG_SH_SCI_SERIAL=y
-# CONFIG_SH_SCIF_SERIAL is not set
CONFIG_SERIAL_CONSOLE=y
#
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index cb14a2b501f4fe..95b6c5f134cf3c 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -28,10 +28,22 @@ ifdef CONFIG_SH_SOLUTION_ENGINE
O_OBJS += setup_se.o io_se.o
endif
+ifdef CONFIG_SH_OVERDRIVE
+O_OBJS += setup_od.o io_generic.o
+endif
+
+ifdef CONFIG_SH_HP600
+O_OBJS += io_hd64461.o
+endif
+
ifdef CONFIG_CPU_SH4
O_OBJS += fpu.o
endif
+ifdef CONFIG_HD64461
+O_OBJS += setup_hd64461.o
+endif
+
all: kernel.o head.o init_task.o
entry.o: entry.S
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index 80dc511b3da796..d5c7437ae8f6ed 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -1,19 +1,81 @@
-/* $Id: cf-enabler.c,v 1.2 1999/12/20 10:14:40 gniibe Exp $
+/* $Id: cf-enabler.c,v 1.2 2000/06/08 05:50:10 gniibe Exp $
*
* linux/drivers/block/cf-enabler.c
*
* Copyright (C) 1999 Niibe Yutaka
+ * Copyright (C) 2000 Toshiharu Nozawa
*
* Enable the CF configuration.
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/irq.h>
+#ifdef CONFIG_SH_SOLUTION_ENGINE
+#include <asm/hitachi_se.h>
+/*
+ * 0xB8400000 : Common Memory
+ * 0xB8500000 : Attribute
+ * 0xB8600000 : I/O
+ */
+
+int __init cf_init(void)
+{
+ if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
+ return 0; /* Not detected */
+
+ if ((ctrl_inw(MRSHPC_CSR) & 0x0080) == 0) {
+ ctrl_outw(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
+ } else {
+ ctrl_outw(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
+ }
+
+ /*
+ * PC-Card window open
+ * flag == COMMON/ATTRIBUTE/IO
+ */
+ /* common window open */
+ ctrl_outw(0x8a84, MRSHPC_MW0CR1);/* window 0xb8400000 */
+ if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
+ /* common mode & bus width 16bit SWAP = 1*/
+ ctrl_outw(0x0b00, MRSHPC_MW0CR2);
+ else
+ /* common mode & bus width 16bit SWAP = 0*/
+ ctrl_outw(0x0300, MRSHPC_MW0CR2);
+
+ /* attribute window open */
+ ctrl_outw(0x8a85, MRSHPC_MW1CR1);/* window 0xb8500000 */
+ if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
+ /* attribute mode & bus width 16bit SWAP = 1*/
+ ctrl_outw(0x0a00, MRSHPC_MW1CR2);
+ else
+ /* attribute mode & bus width 16bit SWAP = 0*/
+ ctrl_outw(0x0200, MRSHPC_MW1CR2);
+
+ /* I/O window open */
+ ctrl_outw(0x8a86, MRSHPC_IOWCR1);/* I/O window 0xb8600000 */
+ ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */
+ if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
+ ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
+ else
+ ctrl_outw(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
+
+ ctrl_outw(0x2000, MRSHPC_ICR);
+ ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206);
+ ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
+ return 0;
+}
+#else /* then generic system type */
#define CF_CIS_BASE 0xb8000000
/*
+ * You can connect Compact Flash directly to the bus of SuperH.
+ * This is the enabler for that.
+ */
+
+/*
* 0xB8000000 : Attribute
* 0xB8001000 : Common Memory
* 0xBA000000 : I/O
@@ -21,10 +83,12 @@
int __init cf_init(void)
{
+ /* Enable the card, and set the level interrupt */
outw(0x0042, CF_CIS_BASE+0x0200);
make_imask_irq(14);
disable_irq(14);
return 0;
}
+#endif
__initcall (cf_init);
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index dcb306cac0f980..e54c37b09269d6 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -52,8 +52,9 @@
flags = 4
sigpending = 8
need_resched = 20
+tsk_ptrace = 60
-PF_TRACESYS = 0x00000020
+PT_TRACESYS = 0x00000002
PF_USEDFPU = 0x00100000
ENOSYS = 38
@@ -127,7 +128,7 @@ SYSCALL_NR = (16*4+6*4)
or $r11, $r10; \
ldc $r10, $sr
- .balign 4
+ .align 2
tlb_miss_load:
mov.l 2f, $r0
mov.l @$r0, $r6
@@ -137,7 +138,7 @@ tlb_miss_load:
jmp @$r0
mov #0, $r5
- .balign 4
+ .align 2
tlb_miss_store:
mov.l 2f, $r0
mov.l @$r0, $r6
@@ -147,7 +148,7 @@ tlb_miss_store:
jmp @$r0
mov #1, $r5
- .balign 4
+ .align 2
initial_page_write:
mov.l 2f, $r0
mov.l @$r0, $r6
@@ -157,7 +158,7 @@ initial_page_write:
jmp @$r0
mov #1, $r5
- .balign 4
+ .align 2
tlb_protection_violation_load:
mov.l 2f, $r0
mov.l @$r0, $r6
@@ -167,7 +168,7 @@ tlb_protection_violation_load:
jmp @$r0
mov #0, $r5
- .balign 4
+ .align 2
tlb_protection_violation_store:
mov.l 2f, $r0
mov.l @$r0, $r6
@@ -177,14 +178,14 @@ tlb_protection_violation_store:
jmp @$r0
mov #1, $r5
- .balign 4
+ .align 2
1: .long SYMBOL_NAME(do_page_fault)
2: .long MMU_TEA
#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
- .balign 4
+ .align 2
/* Unwind the stack and jmp to the debug entry */
-debug:
+debug_kernel:
mov.l @$r15+, $r0
mov.l @$r15+, $r1
mov.l @$r15+, $r2
@@ -216,19 +217,36 @@ debug:
mov.l 2f, $k0
jmp @$k0
ldc $k1, $ssr
- .balign 4
+ .align 2
1: .long 0x300000f0
2: .long 0xa0000100
#endif
- .balign 4
+ .align 2
+debug_trap:
+#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+ mov #SR, $r0
+ mov.l @($r0,$r15), $r0 ! get status register
+ shll $r0
+ shll $r0 ! kernel space?
+ bt/s debug_kernel
+#endif
+ mov.l @$r15, $r0
+ mov.l 1f, $r8
+ jmp @$r8
+ nop
+
+ .align 2
+1: .long SYMBOL_NAME(break_point_trap_software)
+
+ .align 2
error:
!
STI()
mov.l 1f, $r0
jmp @$r0
nop
- .balign 4
+ .align 2
1: .long SYMBOL_NAME(do_exception_error)
badsys: mov #-ENOSYS, $r0
@@ -263,13 +281,11 @@ system_call:
mov.l 1f, $r9
mov.l @$r9, $r8
!
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
mov #0x20, $r9
extu.b $r9, $r9
shll2 $r9
cmp/hs $r9, $r8
- bt debug
-#endif
+ bt debug_trap
!
mov #SYSCALL_NR, $r14
add $r15, $r14
@@ -311,16 +327,34 @@ system_call:
bt 7b
#endif
0: stc $k_current, $r11
- mov.l @(flags,$r11), $r10 ! Is it trace?
- mov #PF_TRACESYS, $r11
+ mov.l @(tsk_ptrace,$r11), $r10 ! Is it trace?
+ mov #PT_TRACESYS, $r11
tst $r11, $r10
bt 5f
! Trace system call
mov #-ENOSYS, $r11
mov.l $r11, @(R0,$r15)
+ ! Push up $R0--$R2, and $R4--$R7
+ mov.l $r0, @-$r15
+ mov.l $r1, @-$r15
+ mov.l $r2, @-$r15
+ mov.l $r4, @-$r15
+ mov.l $r5, @-$r15
+ mov.l $r6, @-$r15
+ mov.l $r7, @-$r15
+ !
mov.l 2f, $r11
jsr @$r11
nop
+ ! Pop down $R0--$R2, and $R4--$R7
+ mov.l @$r15+, $r7
+ mov.l @$r15+, $r6
+ mov.l @$r15+, $r5
+ mov.l @$r15+, $r4
+ mov.l @$r15+, $r2
+ mov.l @$r15+, $r1
+ mov.l @$r15+, $r0
+ !
mov.l __syscall_ret_trace, $r10
bra 6f
lds $r10, $pr
@@ -337,7 +371,7 @@ system_call:
nop
! In case of trace
- .balign 4
+ .align 2
3:
#ifdef COMPAT_OLD_SYSCALL_ABI
add $r8, $r15 ! pop off the arguments
@@ -347,7 +381,7 @@ system_call:
mova SYMBOL_NAME(ret_from_syscall), $r0
jmp @$r1
lds $r0, $pr
- .balign 4
+ .align 2
1: .long TRA
2: .long SYMBOL_NAME(syscall_trace)
__n_sys: .long NR_syscalls
@@ -366,18 +400,18 @@ fixup_syscall_argerr:
.previous
.section __ex_table, "a"
- .balign 4
+ .align 2
.long 4b,fixup_syscall_argerr
.previous
#endif
- .balign 4
+ .align 2
reschedule:
mova SYMBOL_NAME(ret_from_syscall), $r0
mov.l 1f, $r1
jmp @$r1
lds $r0, $pr
- .balign 4
+ .align 2
1: .long SYMBOL_NAME(schedule)
ENTRY(ret_from_irq)
@@ -401,11 +435,11 @@ ENTRY(ret_from_exception)
STI()
bra ret_from_syscall
nop
- .balign 4
+ .align 2
__INV_IMASK:
.long 0xffffff0f ! ~(IMASK)
- .balign 4
+ .align 2
syscall_ret:
#ifdef COMPAT_OLD_SYSCALL_ABI
add $r8, $r15 ! pop off the arguments
@@ -438,7 +472,7 @@ signal_return:
mova restore_all, $r0
jmp @$r1
lds $r0, $pr
- .balign 4
+ .align 2
__do_signal:
.long SYMBOL_NAME(do_signal)
__softirq_state:
@@ -446,7 +480,7 @@ __softirq_state:
__do_softirq:
.long SYMBOL_NAME(do_softirq)
- .balign 4
+ .align 2
restore_all:
#if defined(__SH4__)
mov.l __fpu_prepare_fd, $r0
@@ -554,7 +588,7 @@ restore_all:
rte
nop
- .balign 4
+ .align 2
__blrb_flags: .long 0x30000000
#if defined(__SH4__)
__fpu_prepare_fd:
@@ -582,7 +616,7 @@ general_exception:
mov.l 2f, $k3
bra handle_exception
mov.l @$k2, $k2
- .balign 4
+ .align 2
2: .long SYMBOL_NAME(ret_from_exception)
1: .long EXPEVT
!
@@ -601,7 +635,7 @@ interrupt:
bra handle_exception
mov.l @$k2, $k2
- .balign 4
+ .align 2
1: .long EXPEVT
2: .long INTEVT
3: .long SYMBOL_NAME(ret_from_irq)
@@ -707,7 +741,7 @@ handle_exception:
mov.l @$r9, $r9
jmp @$r9
nop
- .balign 4
+ .align 2
1: .long SYMBOL_NAME(exception_handling_table)
2: .long 0x00008000 ! FD=1
3: .long 0x000000f0 ! FD=0, IMASK=15
diff --git a/arch/sh/kernel/io_hd64461.c b/arch/sh/kernel/io_hd64461.c
new file mode 100644
index 00000000000000..7c655942b6601e
--- /dev/null
+++ b/arch/sh/kernel/io_hd64461.c
@@ -0,0 +1,109 @@
+/*
+ * $Id: io_hd64461.c,v 1.1 2000/06/10 21:45:18 yaegashi Exp $
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * Typical I/O routines for HD64461 system.
+ */
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include <asm/hd64461.h>
+
+static __inline__ unsigned long PORT2ADDR(unsigned long port)
+{
+ /* HD64461 internal devices (0xb0000000) */
+ if (port < 0x10000) return CONFIG_HD64461_IOBASE + port;
+
+ /* PCMCIA channel 0, I/O (0xba000000) */
+ if (port < 0x20000) return 0xba000000 + port - 0x10000;
+
+ /* PCMCIA channel 1, memory (0xb5000000)
+ SH7709 cannot support I/O card attached to Area 5 */
+ if (port < 0x30000) return 0xb5000000 + port - 0x20000;
+
+ /* Whole physical address space (0xa0000000) */
+ return 0xa0000000 + (port & 0x1fffffff);
+}
+
+static inline void delay(void)
+{
+ ctrl_inw(0xa0000000);
+}
+
+unsigned long inb(unsigned int port)
+{
+ return *(volatile unsigned char*)PORT2ADDR(port);
+}
+
+unsigned long inb_p(unsigned int port)
+{
+ unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
+ delay();
+ return v;
+}
+
+unsigned long inw(unsigned int port)
+{
+ return *(volatile unsigned short*)PORT2ADDR(port);
+}
+
+unsigned long inl(unsigned int port)
+{
+ return *(volatile unsigned long*)PORT2ADDR(port);
+}
+
+void insb(unsigned int port, void *buffer, unsigned long count)
+{
+ unsigned char *buf=buffer;
+ while(count--) *buf++=inb(port);
+}
+
+void insw(unsigned int port, void *buffer, unsigned long count)
+{
+ unsigned short *buf=buffer;
+ while(count--) *buf++=inw(port);
+}
+
+void insl(unsigned int port, void *buffer, unsigned long count)
+{
+ unsigned long *buf=buffer;
+ while(count--) *buf++=inl(port);
+}
+
+void outb(unsigned long b, unsigned int port)
+{
+ *(volatile unsigned char*)PORT2ADDR(port) = b;
+}
+
+void outb_p(unsigned long b, unsigned int port)
+{
+ *(volatile unsigned char*)PORT2ADDR(port) = b;
+ delay();
+}
+
+void outw(unsigned long b, unsigned int port)
+{
+ *(volatile unsigned short*)PORT2ADDR(port) = b;
+}
+
+void outl(unsigned long b, unsigned int port)
+{
+ *(volatile unsigned long*)PORT2ADDR(port) = b;
+}
+
+void outsb(unsigned int port, const void *buffer, unsigned long count)
+{
+ const unsigned char *buf=buffer;
+ while(count--) outb(*buf++, port);
+}
+
+void outsw(unsigned int port, const void *buffer, unsigned long count)
+{
+ const unsigned short *buf=buffer;
+ while(count--) outw(*buf++, port);
+}
+
+void outsl(unsigned int port, const void *buffer, unsigned long count)
+{
+ const unsigned long *buf=buffer;
+ while(count--) outl(*buf++, port);
+}
diff --git a/arch/sh/kernel/io_se.c b/arch/sh/kernel/io_se.c
index 1726980b6eca51..a16c4738d39e5f 100644
--- a/arch/sh/kernel/io_se.c
+++ b/arch/sh/kernel/io_se.c
@@ -1,4 +1,4 @@
-/* $Id: io_se.c,v 1.4 2000/05/07 23:31:58 gniibe Exp $
+/* $Id: io_se.c,v 1.5 2000/06/08 05:50:10 gniibe Exp $
*
* linux/arch/sh/kernel/io_se.c
*
@@ -7,6 +7,7 @@
* I/O routine for Hitachi SolutionEngine.
*
*/
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index b7d01e9a25bdb7..f21d0e4517d1d5 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -37,6 +37,9 @@
#include <asm/irq.h>
#include <linux/irq.h>
+#ifdef CONFIG_HD64461
+#include <asm/hd64461.h>
+#endif
unsigned int local_bh_count[NR_CPUS];
unsigned int local_irq_count[NR_CPUS];
@@ -243,6 +246,18 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
"shlr %0\n\t"
"add #-16, %0\n\t"
:"=z" (irq));
+#if defined(CONFIG_HD64461)
+ if (irq == CONFIG_HD64461_IRQ) {
+ unsigned short bit;
+ unsigned short nirr = inw(HD64461_NIRR);
+ unsigned short nimr = inw(HD64461_NIMR);
+ nirr &= ~nimr;
+ for (bit = 1, irq = 0; irq < 16; bit <<= 1, irq++)
+ if (nirr & bit) break;
+ if (irq == 16) irq = CONFIG_HD64461_IRQ;
+ else irq += HD64461_IRQBASE;
+ }
+#endif
kstat.irqs[cpu][irq]++;
desc = irq_desc + irq;
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 2d0f5e18aebe9f..acefb5e4faecc6 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -339,7 +339,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
error = do_execve(filename, uargv, uenvp, &regs);
if (error == 0)
- current->flags &= ~PF_DTRACE;
+ current->ptrace &= ~PT_DTRACE;
putname(filename);
out:
unlock_kernel();
@@ -384,11 +384,21 @@ asmlinkage void print_syscall(int x)
restore_flags(flags);
}
-asmlinkage void break_point_trap(void)
+asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs regs)
{
- /* Clear traicng. */
+ /* Clear tracing. */
ctrl_outw(0, UBC_BBRA);
ctrl_outw(0, UBC_BBRB);
force_sig(SIGTRAP, current);
}
+
+asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs regs)
+{
+ regs.pc -= 2;
+ force_sig(SIGTRAP, current);
+}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 73601b358b56eb..7f42367e2dff60 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.5 2000/05/09 01:42:21 gniibe Exp $
+/* $Id: ptrace.c,v 1.6 2000/06/08 23:44:50 gniibe Exp $
*
* linux/arch/sh/kernel/ptrace.c
*
@@ -10,6 +10,7 @@
*
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -121,13 +122,21 @@ ubc_set_tracing(int asid, unsigned long nextpc1, unsigned nextpc2)
{
ctrl_outl(nextpc1, UBC_BARA);
ctrl_outb(asid, UBC_BASRA);
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+ ctrl_outl(0x0fff, UBC_BAMRA);
+#else
ctrl_outb(BAMR_12, UBC_BAMRA);
+#endif
ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
if (nextpc2 != (unsigned long) -1) {
ctrl_outl(nextpc2, UBC_BARB);
ctrl_outb(asid, UBC_BASRB);
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+ ctrl_outl(0x0fff, UBC_BAMRA);
+#else
ctrl_outb(BAMR_12, UBC_BAMRB);
+#endif
ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB);
}
ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR);
@@ -143,10 +152,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EPERM;
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
goto out;
/* set the ptrace bit in the process flags. */
- current->flags |= PF_PTRACED;
+ current->ptrace |= PT_PTRACED;
ret = 0;
goto out;
}
@@ -176,9 +185,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
(tsk->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED)
+ if (child->ptrace & PT_PTRACED)
goto out_tsk;
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != tsk) {
@@ -193,7 +202,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk;
}
ret = -ESRCH;
- if (!(child->flags & PF_PTRACED))
+ if (!(child->ptrace & PT_PTRACED))
goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
@@ -280,9 +289,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data > _NSIG)
break;
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
wake_up_process(child);
ret = 0;
@@ -313,16 +322,16 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
- child->flags &= ~PF_TRACESYS;
- if ((child->flags & PF_DTRACE) == 0) {
+ child->ptrace &= ~PT_TRACESYS;
+ if ((child->ptrace & PT_DTRACE) == 0) {
/* Spurious delayed TF traps may occur */
- child->flags |= PF_DTRACE;
+ child->ptrace |= PT_DTRACE;
}
/* Compute next pc. */
pc = get_stack_long(child, (long)&dummy->pc);
regs = (struct pt_regs *)((unsigned long)child + THREAD_SIZE - sizeof(struct pt_regs));
- if (access_process_vm(child, pc&~3, &tmp, sizeof(tmp), 1) != sizeof(data))
+ if (access_process_vm(child, pc&~3, &tmp, sizeof(tmp), 0) != sizeof(tmp))
break;
#ifdef __LITTLE_ENDIAN__
@@ -357,7 +366,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
@@ -384,8 +393,8 @@ asmlinkage void syscall_trace(void)
{
struct task_struct *tsk = current;
- if ((tsk->flags & (PF_PTRACED|PF_TRACESYS))
- != (PF_PTRACED|PF_TRACESYS))
+ if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYS))
+ != (PT_PTRACED|PT_TRACESYS))
return;
tsk->exit_code = SIGTRAP;
tsk->state = TASK_STOPPED;
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 49179f08fa15b3..c8c04ec1240285 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -110,23 +110,6 @@ static struct resource rom_resources[MAXROMS] = {
static unsigned long memory_start, memory_end;
-unsigned long __init memparse(char *ptr, char **retptr)
-{
- unsigned long ret;
-
- ret = simple_strtoul(ptr, retptr, 0);
-
- if (**retptr == 'K' || **retptr == 'k') {
- ret <<= 10;
- (*retptr)++;
- }
- else if (**retptr == 'M' || **retptr == 'm') {
- ret <<= 20;
- (*retptr)++;
- }
- return ret;
-} /* memparse */
-
static inline void parse_mem_cmdline (char ** cmdline_p)
{
char c = ' ', *to = command_line, *from = COMMAND_LINE;
@@ -327,5 +310,13 @@ int get_cpuinfo(char *buffer)
(loops_per_sec+2500)/500000,
((loops_per_sec+2500)/5000) % 100);
+#define PRINT_CLOCK(name, value) \
+ p += sprintf(p, name " clock: %d.%02dMHz\n", \
+ ((value) / 1000000), ((value) % 1000000)/10000)
+
+ PRINT_CLOCK("CPU", boot_cpu_data.cpu_clock);
+ PRINT_CLOCK("Bus", boot_cpu_data.bus_clock);
+ PRINT_CLOCK("Peripheral module", boot_cpu_data.module_clock);
+
return p - buffer;
}
diff --git a/arch/sh/kernel/setup_hd64461.c b/arch/sh/kernel/setup_hd64461.c
new file mode 100644
index 00000000000000..0ee07e887d84fb
--- /dev/null
+++ b/arch/sh/kernel/setup_hd64461.c
@@ -0,0 +1,128 @@
+/*
+ * $Id: setup_hd64461.c,v 1.1 2000/06/10 21:45:18 yaegashi Exp $
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * Hitachi HD64461 companion chip support
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/hd64461.h>
+
+static void disable_hd64461_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short nimr;
+ unsigned short mask = 1 << (irq - HD64461_IRQBASE);
+
+ save_and_cli(flags);
+ nimr = inw(HD64461_NIMR);
+ nimr |= mask;
+ outw(nimr, HD64461_NIMR);
+ restore_flags(flags);
+}
+
+
+static void enable_hd64461_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short nimr;
+ unsigned short mask = 1 << (irq - HD64461_IRQBASE);
+
+ save_and_cli(flags);
+ nimr = inw(HD64461_NIMR);
+ nimr &= ~mask;
+ outw(nimr, HD64461_NIMR);
+ restore_flags(flags);
+}
+
+
+static void mask_and_ack_hd64461(unsigned int irq)
+{
+ disable_hd64461_irq(irq);
+#ifdef CONFIG_HD64461_ENABLER
+ if (irq == HD64461_IRQBASE + 13)
+ outb(0x00, HD64461_PCC1CSCR);
+#endif
+}
+
+
+static void end_hd64461_irq(unsigned int irq)
+{
+ enable_hd64461_irq(irq);
+}
+
+
+static unsigned int startup_hd64461_irq(unsigned int irq)
+{
+ enable_hd64461_irq(irq);
+ return 0;
+}
+
+
+static void shutdown_hd64461_irq(unsigned int irq)
+{
+ disable_hd64461_irq(irq);
+}
+
+
+static struct hw_interrupt_type hd64461_irq_type = {
+ "HD64461-IRQ",
+ startup_hd64461_irq,
+ shutdown_hd64461_irq,
+ enable_hd64461_irq,
+ disable_hd64461_irq,
+ mask_and_ack_hd64461,
+ end_hd64461_irq
+};
+
+
+static void hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ printk(KERN_INFO
+ "HD64461: spurious interrupt, nirr: 0x%lx nimr: 0x%lx\n",
+ inw(HD64461_NIRR), inw(HD64461_NIMR));
+}
+
+
+static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL};
+
+
+int __init setup_hd64461(void)
+{
+ int i;
+
+ printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n",
+ CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ,
+ HD64461_IRQBASE, HD64461_IRQBASE+15);
+#if 1
+ /* IRQ line for HD64461 should be set level trigger mode("10"). */
+ /* And this should be done earlier than the kernel starts. */
+ ctrl_outw(0x0200, INTC_ICR1); /* when connected to IRQ4. */
+#endif
+ outw(0xffff, HD64461_NIMR);
+
+ for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
+ irq_desc[i].handler = &hd64461_irq_type;
+ }
+
+ setup_irq(CONFIG_HD64461_IRQ, &irq0);
+
+#ifdef CONFIG_HD64461_ENABLER
+ printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
+ outb(0x04, HD64461_PCC1CSCIER);
+ outb(0x00, HD64461_PCC1CSCR);
+#endif
+
+ return 0;
+}
+
+module_init(setup_hd64461);
diff --git a/arch/sh/kernel/setup_od.c b/arch/sh/kernel/setup_od.c
new file mode 100644
index 00000000000000..f605bd20e4194d
--- /dev/null
+++ b/arch/sh/kernel/setup_od.c
@@ -0,0 +1,35 @@
+/* $Id: setup_od.c,v 1.1 2000/06/14 09:35:59 stuart_menefy Exp $
+ *
+ * arch/sh/kernel/setup_od.c
+ *
+ * Copyright (C) 2000 Stuart Menefy
+ *
+ * STMicroelectronics Overdrive Support.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+/*
+ * Initialize the board
+ */
+int __init setup_od(void)
+{
+ /* Enable RS232 receive buffers */
+ volatile int* p = (volatile int*)0xa3000000;
+
+#if defined(CONFIG_SH_ORION)
+ *p=1;
+#elif defined(CONFIG_SH_OVERDRIVE)
+ *p=0x1e;
+#else
+#error Illegal configuration
+#endif
+
+ printk(KERN_INFO "STMicroelectronics Overdrive Setup...done\n");
+ return 0;
+}
+
+module_init(setup_od);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 14ce2eae950706..65469f7e19f3dd 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -595,7 +595,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!signr)
break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index de61501841efa1..3861fec7d4a174 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -8,6 +8,7 @@
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*/
+#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -421,7 +422,11 @@ void __init time_init(void)
tmp = (frqcr & 0x2000) >> 11;
tmp |= frqcr & 0x0003;
pfc = pfc_table[tmp];
+#ifdef CONFIG_SH_HP600
+ master_clock = cpu_clock/6;
+#else
master_clock = cpu_clock;
+#endif
bus_clock = master_clock/pfc;
}
#elif defined(__SH4__)
@@ -444,6 +449,11 @@ void __init time_init(void)
printk("Interval = %ld\n", interval);
+ current_cpu_data.cpu_clock = cpu_clock;
+ current_cpu_data.master_clock = master_clock;
+ current_cpu_data.bus_clock = bus_clock;
+ current_cpu_data.module_clock = module_clock;
+
/* Start TMU0 */
ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index d3a874447fe9b0..428bec21c9c798 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -82,7 +82,7 @@ bad_area:
return 0;
}
-static void handle_vmalloc_fault(struct task_struct *tsk, unsigned long address)
+static void handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
{
pgd_t *dir;
pmd_t *pmd;
@@ -107,6 +107,13 @@ static void handle_vmalloc_fault(struct task_struct *tsk, unsigned long address)
return;
}
+#if defined(__SH4__)
+ /*
+ * ITLB is not affected by "ldtlb" instruction.
+ * So, we need to flush the entry by ourselves.
+ */
+ __flush_tlb_page(mm, address&PAGE_MASK);
+#endif
update_mmu_cache(NULL, address, entry);
}
@@ -128,7 +135,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
mm = tsk->mm;
if (address >= VMALLOC_START && address < VMALLOC_END) {
- handle_vmalloc_fault(tsk, address);
+ handle_vmalloc_fault(mm, address);
return;
}
@@ -269,18 +276,13 @@ void update_mmu_cache(struct vm_area_struct * vma,
unsigned long pteaddr;
save_and_cli(flags);
-#if defined(__SH4__)
- /*
- * ITLB is not affected by "ldtlb" instruction.
- * So, we need to flush the entry by ourselves.
- */
- __flush_tlb_page(vma->vm_mm, address&PAGE_MASK);
-#endif
/* Set PTEH register */
- pteaddr = (address & MMU_VPN_MASK) |
- (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK);
- ctrl_outl(pteaddr, MMU_PTEH);
+ if (vma) {
+ pteaddr = (address & MMU_VPN_MASK) |
+ (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK);
+ ctrl_outl(pteaddr, MMU_PTEH);
+ }
/* Set PTEL register */
pteval = pte_val(pte);
diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
index 53a7fff56c193b..736e4301f0f13a 100644
--- a/arch/sh/vmlinux.lds.S
+++ b/arch/sh/vmlinux.lds.S
@@ -15,12 +15,14 @@ SECTIONS
. = 0x80000000 + CONFIG_MEMORY_START + 0x1000;
_text = .; /* Text and read-only data */
text = .; /* Text and read-only data */
- .text : {
+ .empty_zero_page : {
*(.empty_zero_page)
+ } = 0
+ .text : {
*(.text)
*(.fixup)
*(.gnu.warning)
- } = 0
+ } = 0x0009
.text.lock : { *(.text.lock) } /* out-of-line lock text */
.rodata : { *(.rodata) }
.kstrtab : { *(.kstrtab) }
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index 9faf12053f950f..6d07d32c6eb59a 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -1,6 +1,6 @@
-# $Id: config.in,v 1.93 2000/05/22 08:12:19 davem Exp $
+# $Id: config.in,v 1.94 2000/06/04 22:23:10 anton Exp $
# For a description of the syntax of this configuration file,
-# see the Configure script.
+# see Documentation/kbuild/config-language.txt.
#
mainmenu_name "Linux/SPARC Kernel Configuration"
@@ -12,6 +12,15 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_VT y
@@ -59,15 +68,6 @@ dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
endmenu
mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool ' Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
comment 'Console drivers'
bool 'PROM console' CONFIG_PROM_CONSOLE
source drivers/video/Config.in
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index b9c76ef4a89ded..8d2f5b78e1a808 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -9,6 +9,13 @@ CONFIG_UID16=y
CONFIG_EXPERIMENTAL=y
#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
# General setup
#
CONFIG_VT=y
@@ -47,13 +54,6 @@ CONFIG_SUNOS_EMUL=y
# CONFIG_PRINTER is not set
#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
# Console drivers
#
CONFIG_PROM_CONSOLE=y
@@ -149,9 +149,9 @@ CONFIG_ATALK=m
CONFIG_DECNET=m
CONFIG_DECNET_SIOCGIFCONF=y
# CONFIG_DECNET_ROUTER is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -252,6 +252,7 @@ CONFIG_UNIX98_PTY_COUNT=256
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
CONFIG_AFFS_FS=m
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
@@ -261,10 +262,12 @@ CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_EFS_FS=m
# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=m
# CONFIG_JOLIET is not set
CONFIG_MINIX_FS=m
# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
CONFIG_HPFS_FS=m
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
@@ -272,11 +275,13 @@ CONFIG_PROC_FS=y
# 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=m
CONFIG_EXT2_FS=y
CONFIG_SYSV_FS=m
# CONFIG_SYSV_FS_WRITE is not set
# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
@@ -285,9 +290,11 @@ CONFIG_UFS_FS=m
#
CONFIG_CODA_FS=m
CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
# CONFIG_ROOT_NFS is not set
CONFIG_NFSD=m
# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_SMB_FS=m
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 61518872f27cce..f701027e0027a3 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.164 2000/05/09 17:40:13 davem Exp $
+/* $Id: entry.S,v 1.166 2000/06/19 06:24:36 davem Exp $
* arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -945,7 +945,7 @@ sun4c_fault:
and %l5, %l4, %l5
/* Test for NULL pte_t * in vmalloc area. */
- sethi %hi(SUN4C_VMALLOC_START), %l4
+ sethi %hi(VMALLOC_START), %l4
cmp %l5, %l4
blu,a C_LABEL(invalid_segment_patch1)
lduXa [%l5] ASI_SEGMAP, %l4
@@ -1072,7 +1072,7 @@ C_LABEL(invalid_segment_patch2):
andn %l4, 0x1ff, %l5
1:
- sethi %hi(SUN4C_VMALLOC_START), %l4
+ sethi %hi(VMALLOC_START), %l4
cmp %l5, %l4
bgeu 1f
@@ -1233,8 +1233,8 @@ C_LABEL(sys_ptrace):
call C_LABEL(do_ptrace)
add %sp, REGWIN_SZ, %o0
- ld [%curptr + AOFF_task_flags], %l5
- andcc %l5, 0x20, %g0
+ ld [%curptr + AOFF_task_ptrace], %l5
+ andcc %l5, 0x02, %g0
be 1f
nop
@@ -1283,8 +1283,8 @@ C_LABEL(sys_sigpause):
call C_LABEL(do_sigpause)
add %sp, REGWIN_SZ, %o1
- ld [%curptr + AOFF_task_flags], %l5
- andcc %l5, 0x20, %g0
+ ld [%curptr + AOFF_task_ptrace], %l5
+ andcc %l5, 0x02, %g0
be 1f
nop
@@ -1301,8 +1301,8 @@ C_LABEL(sys_sigsuspend):
call C_LABEL(do_sigsuspend)
add %sp, REGWIN_SZ, %o0
- ld [%curptr + AOFF_task_flags], %l5
- andcc %l5, 0x20, %g0
+ ld [%curptr + AOFF_task_ptrace], %l5
+ andcc %l5, 0x02, %g0
be 1f
nop
@@ -1320,8 +1320,8 @@ C_LABEL(sys_rt_sigsuspend):
call C_LABEL(do_rt_sigsuspend)
add %sp, REGWIN_SZ, %o2
- ld [%curptr + AOFF_task_flags], %l5
- andcc %l5, 0x20, %g0
+ ld [%curptr + AOFF_task_ptrace], %l5
+ andcc %l5, 0x02, %g0
be 1f
nop
@@ -1338,8 +1338,8 @@ C_LABEL(sys_sigreturn):
call C_LABEL(do_sigreturn)
add %sp, REGWIN_SZ, %o0
- ld [%curptr + AOFF_task_flags], %l5
- andcc %l5, 0x20, %g0
+ ld [%curptr + AOFF_task_ptrace], %l5
+ andcc %l5, 0x02, %g0
be 1f
nop
@@ -1358,8 +1358,8 @@ C_LABEL(sys_rt_sigreturn):
call C_LABEL(do_rt_sigreturn)
add %sp, REGWIN_SZ, %o0
- ld [%curptr + AOFF_task_flags], %l5
- andcc %l5, 0x20, %g0
+ ld [%curptr + AOFF_task_ptrace], %l5
+ andcc %l5, 0x02, %g0
be 1f
nop
@@ -1496,9 +1496,9 @@ syscall_is_too_hard:
mov %i1, %o1
mov %i2, %o2
- ld [%curptr + AOFF_task_flags], %l5
+ ld [%curptr + AOFF_task_ptrace], %l5
mov %i3, %o3
- andcc %l5, 0x20, %g0
+ andcc %l5, 0x02, %g0
mov %i4, %o4
bne linux_syscall_trace
mov %i0, %l5
@@ -1510,12 +1510,12 @@ syscall_is_too_hard:
.globl C_LABEL(ret_sys_call)
C_LABEL(ret_sys_call):
- ld [%curptr + AOFF_task_flags], %l6
+ ld [%curptr + AOFF_task_ptrace], %l6
cmp %o0, -ENOIOCTLCMD
ld [%sp + REGWIN_SZ + PT_PSR], %g3
set PSR_C, %g2
bgeu 1f
- andcc %l6, 0x20, %l6
+ andcc %l6, 0x02, %l6
/* System call success, clear Carry condition code. */
andn %g3, %g2, %g3
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 20c141a00294ef..71f5dbc88e2ad4 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -1,4 +1,4 @@
-/* $Id: ioport.c,v 1.37 2000/03/28 06:38:19 davem Exp $
+/* $Id: ioport.c,v 1.38 2000/06/04 06:23:52 anton Exp $
* ioport.c: Simple io mapping allocator.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -52,11 +52,11 @@ static void _sparc_free_io(struct resource *res);
/* This points to the next to use virtual memory for DVMA mappings */
static struct resource _sparc_dvma = {
- "sparc_dvma", DVMA_VADDR, DVMA_VADDR + DVMA_LEN - 1
+ "sparc_dvma", DVMA_VADDR, DVMA_END - 1
};
/* This points to the start of I/O mappings, cluable from outside. */
/*ext*/ struct resource sparc_iomap = {
- "sparc_iomap", IOBASE_VADDR, IOBASE_END-1
+ "sparc_iomap", IOBASE_VADDR, IOBASE_END - 1
};
/*
@@ -453,7 +453,11 @@ void sbus_dma_sync_single(struct sbus_dev *sdev, u32 ba, long size, int directio
panic("sbus_dma_sync_single: 0x%x\n", ba);
va = (unsigned long) phys_to_virt(mmu_translate_dvma(ba));
- mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK);
+ /*
+ * XXX This bogosity will be fixed with the iommu rewrite coming soon
+ * to a kernel near you. - Anton
+ */
+ /* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */
}
void sbus_dma_sync_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction)
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 742d7db97a6b57..baed3a125ae743 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -289,12 +289,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
#endif
if(request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED) {
+ if (current->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
goto out;
}
/* set the ptrace bit in the process flags. */
- current->flags |= PF_PTRACED;
+ current->ptrace |= PT_PTRACED;
pt_succ_return(regs, 0);
goto out;
}
@@ -333,11 +333,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
goto out;
}
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED) {
+ if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
goto out;
}
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if(child->p_pptr != current) {
REMOVE_LINKS(child);
@@ -349,7 +349,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_succ_return(regs, 0);
goto out;
}
- if (!(child->flags & PF_PTRACED)) {
+ if (!(child->ptrace & PT_PTRACED)) {
pt_error_return(regs, ESRCH);
goto out;
}
@@ -566,9 +566,9 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
#ifdef DEBUG_PTRACE
@@ -605,7 +605,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_error_return(regs, EIO);
goto out;
}
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
wake_up_process(child);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
@@ -632,8 +632,8 @@ asmlinkage void syscall_trace(void)
#ifdef DEBUG_PTRACE
printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
#endif
- if ((current->flags & (PF_PTRACED|PF_TRACESYS))
- != (PF_PTRACED|PF_TRACESYS))
+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+ != (PT_PTRACED|PT_TRACESYS))
return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index e807683ea42a64..8ff82dd7e432d1 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.103 2000/05/09 17:40:13 davem Exp $
+/* $Id: signal.c,v 1.105 2000/06/19 06:24:37 davem Exp $
* linux/arch/sparc/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -1177,7 +1177,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
if (!signr) break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
current->exit_code = signr;
current->state = TASK_STOPPED;
@@ -1241,7 +1241,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
continue;
case SIGSTOP:
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 5beb3adf0596a9..18fe3790ad5d75 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.61 2000/02/16 07:31:29 davem Exp $
+/* $Id: sys_sparc.c,v 1.62 2000/06/19 06:24:37 davem Exp $
* linux/arch/sparc/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -215,7 +215,6 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len,
goto out;
}
- down(&current->mm->mmap_sem);
lock_kernel();
retval = -EINVAL;
len = PAGE_ALIGN(len);
@@ -230,11 +229,12 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len,
goto out_putf;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ down(&current->mm->mmap_sem);
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ up(&current->mm->mmap_sem);
out_putf:
unlock_kernel();
- up(&current->mm->mmap_sem);
if (file)
fput(file);
out:
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index 0dba9b1ca77742..e770f1dd16550e 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.123 2000/05/22 07:29:39 davem Exp $
+/* $Id: sys_sunos.c,v 1.124 2000/06/19 06:24:37 davem Exp $
* sys_sunos.c: SunOS specific syscall compatibility support.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -68,7 +68,6 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len,
struct file * file = NULL;
unsigned long retval, ret_type;
- down(&current->mm->mmap_sem);
lock_kernel();
if(flags & MAP_NORESERVE) {
static int cnt;
@@ -118,7 +117,9 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len,
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ down(&current->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, off);
+ up(&current->mm->mmap_sem);
if(!ret_type)
retval = ((retval < PAGE_OFFSET) ? 0 : retval);
@@ -127,7 +128,6 @@ out_putf:
fput(file);
out:
unlock_kernel();
- up(&current->mm->mmap_sem);
return retval;
}
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 05bb225d78ec77..43ffb3d33830ba 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.55 2000/05/09 17:40:13 davem Exp $
+/* $Id: time.c,v 1.56 2000/06/13 22:51:28 anton Exp $
* linux/arch/sparc/kernel/time.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -79,12 +79,15 @@ void sparc_do_profile(unsigned long pc, unsigned long o7)
extern int _stext;
extern int __copy_user_begin, __copy_user_end;
extern int __atomic_begin, __atomic_end;
+ extern int __bzero_begin, __bzero_end;
extern int __bitops_begin, __bitops_end;
if ((pc >= (unsigned long) &__copy_user_begin &&
pc < (unsigned long) &__copy_user_end) ||
(pc >= (unsigned long) &__atomic_begin &&
pc < (unsigned long) &__atomic_end) ||
+ (pc >= (unsigned long) &__bzero_begin &&
+ pc < (unsigned long) &__bzero_end) ||
(pc >= (unsigned long) &__bitops_begin &&
pc < (unsigned long) &__bitops_end))
pc = o7;
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index ca74c09fcecce9..3564a4517526f7 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.62 2000/05/09 17:40:13 davem Exp $
+/* $Id: traps.c,v 1.63 2000/06/04 06:23:52 anton Exp $
* arch/sparc/kernel/traps.c
*
* Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -499,8 +499,6 @@ void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc
extern void sparc_cpu_startup(void);
-extern ctxd_t *srmmu_ctx_table_phys;
-
int linux_smp_still_initting;
unsigned int thiscpus_tbr;
int thiscpus_mid;
diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S
index b8ca55e50bc88d..204e5517396a89 100644
--- a/arch/sparc/lib/memset.S
+++ b/arch/sparc/lib/memset.S
@@ -55,6 +55,9 @@
.text
.align 4
+ .globl __bzero_begin
+__bzero_begin:
+
.globl C_LABEL(__bzero), C_LABEL(__memset),
.globl C_LABEL(memset)
.globl C_LABEL(__memset_start), C_LABEL(__memset_end)
@@ -193,3 +196,6 @@ C_LABEL(__memset_end):
mov %i4, %o2
ret
restore
+
+ .globl __bzero_end
+__bzero_end:
diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S
index 10812273b5bb24..e5920a801abecc 100644
--- a/arch/sparc/mm/hypersparc.S
+++ b/arch/sparc/mm/hypersparc.S
@@ -1,4 +1,4 @@
-/* $Id: hypersparc.S,v 1.15 2000/05/09 17:40:13 davem Exp $
+/* $Id: hypersparc.S,v 1.16 2000/06/04 06:23:52 anton Exp $
* hypersparc.S: High speed Hypersparc mmu/cache operations.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -28,7 +28,7 @@
.globl hypersparc_flush_cache_all, hypersparc_flush_cache_mm
.globl hypersparc_flush_cache_range, hypersparc_flush_cache_page
- .globl hypersparc_flush_page_to_ram, hypersparc_flush_chunk
+ .globl hypersparc_flush_page_to_ram
.globl hypersparc_flush_page_for_dma, hypersparc_flush_sig_insns
.globl hypersparc_flush_tlb_all, hypersparc_flush_tlb_mm
.globl hypersparc_flush_tlb_range, hypersparc_flush_tlb_page
@@ -229,7 +229,6 @@ hypersparc_flush_sig_insns:
/* HyperSparc is copy-back. */
hypersparc_flush_page_to_ram:
-hypersparc_flush_chunk:
sethi %hi(vac_line_size), %g1
ld [%g1 + %lo(vac_line_size)], %o4
andn %o0, (PAGE_SIZE - 1), %o0
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index 3f350004675d81..2847bd443bb830 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -1,10 +1,10 @@
-/* $Id: init.c,v 1.85 2000/05/09 17:40:13 davem Exp $
+/* $Id: init.c,v 1.86 2000/06/04 06:23:52 anton Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 2000 Anton Blanchard (anton@progsoc.uts.edu.au)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
*/
#include <linux/config.h>
@@ -125,9 +125,13 @@ unsigned long __init bootmem_init(void)
unsigned long bootmap_pfn;
int i;
- /* Limit maximum memory until we implement highmem for sparc */
- if (!cmdline_memory_size || cmdline_memory_size > 0x0d000000)
- cmdline_memory_size = 0x0d000000;
+ /*
+ * XXX Limit maximum memory until we implement highmem for sparc.
+ * The nocache region has taken up some room but I'll rearrange
+ * the virtual address regions soon - Anton
+ */
+ if (!cmdline_memory_size || cmdline_memory_size > 0x0c000000)
+ cmdline_memory_size = 0x0c000000;
/* XXX It is a bit ambiguous here, whether we should
* XXX treat the user specified mem=xxx as total wanted
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 0b46e7d25fec72..fe497c290232bc 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1,11 +1,11 @@
-/* $Id: srmmu.c,v 1.209 2000/05/09 17:40:13 davem Exp $
+/* $Id: srmmu.c,v 1.212 2000/06/13 22:59:14 anton Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995 Pete Zaitcev
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1999 Anton Blanchard (anton@progsoc.uts.edu.au)
+ * Copyright (C) 1999,2000 Anton Blanchard (anton@linuxcare.com)
*/
#include <linux/config.h>
@@ -57,6 +57,8 @@ extern struct resource sparc_iomap;
extern unsigned long last_valid_pfn;
+pgd_t *srmmu_swapper_pg_dir;
+
#ifdef CONFIG_SMP
#define FLUSH_BEGIN(mm)
#define FLUSH_END
@@ -65,40 +67,29 @@ extern unsigned long last_valid_pfn;
#define FLUSH_END }
#endif
-BTFIXUPDEF_CALL(void, ctxd_set, ctxd_t *, pgd_t *)
BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *)
-
-#define ctxd_set(ctxp,pgdp) BTFIXUP_CALL(ctxd_set)(ctxp,pgdp)
#define pmd_set(pmdp,ptep) BTFIXUP_CALL(pmd_set)(pmdp,ptep)
BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long)
-BTFIXUPDEF_CALL(void, flush_chunk, unsigned long)
-
#define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page)
+
int flush_page_for_dma_global = 1;
-#define flush_chunk(chunk) BTFIXUP_CALL(flush_chunk)(chunk)
+
#ifdef CONFIG_SMP
BTFIXUPDEF_CALL(void, local_flush_page_for_dma, unsigned long)
-
#define local_flush_page_for_dma(page) BTFIXUP_CALL(local_flush_page_for_dma)(page)
#endif
-static struct srmmu_stats {
- int invall;
- int invpg;
- int invrnge;
- int invmm;
-} module_stats;
-
char *srmmu_name;
ctxd_t *srmmu_ctx_table_phys;
ctxd_t *srmmu_context_table;
int viking_mxcc_present = 0;
-static spinlock_t srmmu_context_spinlock = SPIN_LOCK_UNLOCKED;
+spinlock_t srmmu_context_spinlock = SPIN_LOCK_UNLOCKED;
-/* In general all page table modifications should use the V8 atomic
+/*
+ * In general all page table modifications should use the V8 atomic
* swap instruction. This insures the mmu and the cpu are in sync
* with respect to ref/mod bits in the page tables.
*/
@@ -108,8 +99,10 @@ static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value)
return value;
}
-/* Functions really use this, not srmmu_swap directly. */
-#define srmmu_set_entry(ptr, newentry) srmmu_swap((unsigned long *) (ptr), (newentry))
+static inline void srmmu_set_pte(pte_t *ptep, pte_t pteval)
+{
+ srmmu_swap((unsigned long *)ptep, pte_val(pteval));
+}
/* The very generic SRMMU page table operations. */
static inline int srmmu_device_memory(unsigned long x)
@@ -117,31 +110,55 @@ static inline int srmmu_device_memory(unsigned long x)
return ((x & 0xF0000000) != 0);
}
-static unsigned long srmmu_pgd_page(pgd_t pgd)
-{ return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); }
+int srmmu_cache_pagetables;
+
+/* XXX Make this dynamic based on ram size - Anton */
+#define SRMMU_NOCACHE_NPAGES 256
+#define SRMMU_NOCACHE_VADDR 0xfc000000
+#define SRMMU_NOCACHE_SIZE (SRMMU_NOCACHE_NPAGES*PAGE_SIZE)
+#define SRMMU_NOCACHE_END (SRMMU_NOCACHE_VADDR + SRMMU_NOCACHE_SIZE)
+#define SRMMU_NOCACHE_BITMAP_SIZE (SRMMU_NOCACHE_NPAGES * 16)
+#define SRMMU_NOCACHE_BITMAP_SHIFT (PAGE_SHIFT - 4)
+
+void *srmmu_nocache_pool;
+void *srmmu_nocache_bitmap;
+int srmmu_nocache_low;
+int srmmu_nocache_used;
+
+/* This makes sense. Honest it does - Anton */
+#define __nocache_pa(VADDR) (((unsigned long)VADDR) - SRMMU_NOCACHE_VADDR + __pa((unsigned long)srmmu_nocache_pool))
+#define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR)
+#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
+
+static inline unsigned long srmmu_pgd_page(pgd_t pgd)
+{ return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__nocache_va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); }
-static unsigned long srmmu_pmd_page(pmd_t pmd)
-{ return srmmu_device_memory(pmd_val(pmd))?~0:(unsigned long)__va((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); }
+static inline unsigned long srmmu_pmd_page(pmd_t pmd)
+{ return srmmu_device_memory(pmd_val(pmd))?~0:(unsigned long)__nocache_va((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); }
-static unsigned long srmmu_pte_pagenr(pte_t pte)
+static inline unsigned long srmmu_pte_pagenr(pte_t pte)
{ return srmmu_device_memory(pte_val(pte))?~0:(((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT); }
static inline int srmmu_pte_none(pte_t pte)
{ return !(pte_val(pte) & 0xFFFFFFF); }
+
static inline int srmmu_pte_present(pte_t pte)
{ return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); }
-static inline void srmmu_pte_clear(pte_t *ptep) { set_pte(ptep, __pte(0)); }
+static inline void srmmu_pte_clear(pte_t *ptep)
+{ srmmu_set_pte(ptep, __pte(0)); }
static inline int srmmu_pmd_none(pmd_t pmd)
{ return !(pmd_val(pmd) & 0xFFFFFFF); }
+
static inline int srmmu_pmd_bad(pmd_t pmd)
{ return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; }
static inline int srmmu_pmd_present(pmd_t pmd)
{ return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); }
-static inline void srmmu_pmd_clear(pmd_t *pmdp) { set_pte((pte_t *)pmdp, __pte(0)); }
+static inline void srmmu_pmd_clear(pmd_t *pmdp)
+{ srmmu_set_pte((pte_t *)pmdp, __pte(0)); }
static inline int srmmu_pgd_none(pgd_t pgd)
{ return !(pgd_val(pgd) & 0xFFFFFFF); }
@@ -152,18 +169,35 @@ static inline int srmmu_pgd_bad(pgd_t pgd)
static inline int srmmu_pgd_present(pgd_t pgd)
{ return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); }
-static inline void srmmu_pgd_clear(pgd_t * pgdp) { set_pte((pte_t *)pgdp, __pte(0)); }
+static inline void srmmu_pgd_clear(pgd_t * pgdp)
+{ srmmu_set_pte((pte_t *)pgdp, __pte(0)); }
+
+static inline int srmmu_pte_write(pte_t pte)
+{ return pte_val(pte) & SRMMU_WRITE; }
+
+static inline int srmmu_pte_dirty(pte_t pte)
+{ return pte_val(pte) & SRMMU_DIRTY; }
-static inline int srmmu_pte_write(pte_t pte) { return pte_val(pte) & SRMMU_WRITE; }
-static inline int srmmu_pte_dirty(pte_t pte) { return pte_val(pte) & SRMMU_DIRTY; }
-static inline int srmmu_pte_young(pte_t pte) { return pte_val(pte) & SRMMU_REF; }
+static inline int srmmu_pte_young(pte_t pte)
+{ return pte_val(pte) & SRMMU_REF; }
-static inline pte_t srmmu_pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~SRMMU_WRITE);}
-static inline pte_t srmmu_pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~SRMMU_DIRTY);}
-static inline pte_t srmmu_pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~SRMMU_REF);}
-static inline pte_t srmmu_pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | SRMMU_WRITE);}
-static inline pte_t srmmu_pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | SRMMU_DIRTY);}
-static inline pte_t srmmu_pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | SRMMU_REF);}
+static inline pte_t srmmu_pte_wrprotect(pte_t pte)
+{ return __pte(pte_val(pte) & ~SRMMU_WRITE);}
+
+static inline pte_t srmmu_pte_mkclean(pte_t pte)
+{ return __pte(pte_val(pte) & ~SRMMU_DIRTY);}
+
+static inline pte_t srmmu_pte_mkold(pte_t pte)
+{ return __pte(pte_val(pte) & ~SRMMU_REF);}
+
+static inline pte_t srmmu_pte_mkwrite(pte_t pte)
+{ return __pte(pte_val(pte) | SRMMU_WRITE);}
+
+static inline pte_t srmmu_pte_mkdirty(pte_t pte)
+{ return __pte(pte_val(pte) | SRMMU_DIRTY);}
+
+static inline pte_t srmmu_pte_mkyoung(pte_t pte)
+{ return __pte(pte_val(pte) | SRMMU_REF);}
/*
* Conversion functions: convert a page and protection to a page entry,
@@ -176,352 +210,242 @@ static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot)
{ return __pte(((page) >> 4) | pgprot_val(pgprot)); }
static pte_t srmmu_mk_pte_io(unsigned long page, pgprot_t pgprot, int space)
-{
- return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot));
-}
+{ return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); }
-static void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
-{
- set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__pa((unsigned long) pgdp) >> 4)));
-}
+/* XXX should we hyper_flush_whole_icache here - Anton */
+static inline void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
+{ srmmu_set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); }
-static void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{
- set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__pa((unsigned long) pmdp) >> 4)));
-}
+static inline void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+{ srmmu_set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pmdp) >> 4))); }
-static void srmmu_pmd_set(pmd_t * pmdp, pte_t * ptep)
-{
- set_pte((pte_t *)pmdp, (SRMMU_ET_PTD | (__pa((unsigned long) ptep) >> 4)));
-}
+static inline void srmmu_pmd_set(pmd_t * pmdp, pte_t * ptep)
+{ srmmu_set_pte((pte_t *)pmdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) ptep) >> 4))); }
static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot)
-{
- return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot));
-}
+{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); }
/* to find an entry in a top-level page table... */
extern inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address)
-{
- return mm->pgd + (address >> SRMMU_PGDIR_SHIFT);
-}
+{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); }
/* Find an entry in the second-level page table.. */
static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address)
-{
- return (pmd_t *) srmmu_pgd_page(*dir) + ((address >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1));
-}
+{ return (pmd_t *) srmmu_pgd_page(*dir) + ((address >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1)); }
/* Find an entry in the third-level page table.. */
static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address)
-{
- return (pte_t *) srmmu_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1));
-}
+{ return (pte_t *) srmmu_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)); }
-static inline pte_t *srmmu_get_pte_fast(void)
+/* XXX Make this SMP safe - Anton */
+unsigned long __srmmu_get_nocache(int size, int align)
{
- struct page *ret;
-
- spin_lock(&pte_spinlock);
- if ((ret = (struct page *)pte_quicklist) != NULL) {
- unsigned int mask = (unsigned int)ret->pprev_hash;
- unsigned int tmp, off;
-
- if (mask & 0xff)
- for (tmp = 0x001, off = 0; (mask & tmp) == 0; tmp <<= 1, off += 256);
- else
- for (tmp = 0x100, off = 2048; (mask & tmp) == 0; tmp <<= 1, off += 256);
- (unsigned int)ret->pprev_hash = mask & ~tmp;
- if (!(mask & ~tmp))
- pte_quicklist = (unsigned long *)ret->next_hash;
- ret = (struct page *)(page_address(ret) + off);
- pgtable_cache_size--;
+ int offset = srmmu_nocache_low;
+ int i;
+ unsigned long va_tmp, phys_tmp;
+ int lowest_failed = 0;
+
+ size = size >> SRMMU_NOCACHE_BITMAP_SHIFT;
+
+repeat:
+ offset = find_next_zero_bit(srmmu_nocache_bitmap, SRMMU_NOCACHE_BITMAP_SIZE, offset);
+
+ /* we align on physical address */
+ if (align) {
+ va_tmp = (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT));
+ phys_tmp = (__nocache_pa(va_tmp) + align - 1) & ~(align - 1);
+ va_tmp = (unsigned long)__nocache_va(phys_tmp);
+ offset = (va_tmp - SRMMU_NOCACHE_VADDR) >> SRMMU_NOCACHE_BITMAP_SHIFT;
}
- spin_unlock(&pte_spinlock);
- return (pte_t *)ret;
-}
-static inline pte_t *srmmu_get_pte_slow(void)
-{
- pte_t *ret;
- struct page *page;
-
- ret = (pte_t *)get_free_page(GFP_KERNEL);
- if (ret) {
- page = mem_map + MAP_NR(ret);
- flush_chunk((unsigned long)ret);
- (unsigned int)page->pprev_hash = 0xfffe;
- spin_lock(&pte_spinlock);
- (unsigned long *)page->next_hash = pte_quicklist;
- pte_quicklist = (unsigned long *)page;
- pgtable_cache_size += 15;
+ if ((SRMMU_NOCACHE_BITMAP_SIZE - offset) < size) {
+ printk("Run out of nocached RAM!\n");
+ return 0;
}
- return ret;
-}
-static inline pgd_t *srmmu_get_pgd_fast(void)
-{
- struct page *ret;
+ i = 0;
+ while(i < size) {
+ if (test_bit(offset + i, srmmu_nocache_bitmap)) {
+ lowest_failed = 1;
+ offset = offset + i + 1;
+ goto repeat;
+ }
+ i++;
+ }
- spin_lock(&pgd_spinlock);
- if ((ret = (struct page *)pgd_quicklist) != NULL) {
- unsigned int mask = (unsigned int)ret->pprev_hash;
- unsigned int tmp, off;
-
- for (tmp = 0x001, off = 0; (mask & tmp) == 0; tmp <<= 1, off += 1024);
- (unsigned int)ret->pprev_hash = mask & ~tmp;
- if (!(mask & ~tmp))
- pgd_quicklist = (unsigned long *)ret->next_hash;
- ret = (struct page *)(page_address(ret) + off);
- pgd_cache_size--;
+ i = 0;
+ while(i < size) {
+ set_bit(offset + i, srmmu_nocache_bitmap);
+ i++;
+ srmmu_nocache_used++;
}
- spin_unlock(&pgd_spinlock);
- return (pgd_t *)ret;
+
+ if (!lowest_failed && ((align >> SRMMU_NOCACHE_BITMAP_SHIFT) <= 1) && (offset > srmmu_nocache_low))
+ srmmu_nocache_low = offset;
+
+ return (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT));
}
-static inline pgd_t *srmmu_get_pgd_slow(void)
+unsigned inline long srmmu_get_nocache(int size, int align)
{
- pgd_t *ret;
- struct page *page;
-
- ret = (pgd_t *)__get_free_page(GFP_KERNEL);
- if (ret) {
- pgd_t *init = pgd_offset(&init_mm, 0);
- memset(ret + (0 * PTRS_PER_PGD), 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
- memcpy(ret + (0 * PTRS_PER_PGD) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
- memset(ret + (1 * PTRS_PER_PGD), 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
- memcpy(ret + (1 * PTRS_PER_PGD) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
- memset(ret + (2 * PTRS_PER_PGD), 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
- memcpy(ret + (2 * PTRS_PER_PGD) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
- memset(ret + (3 * PTRS_PER_PGD), 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
- memcpy(ret + (3 * PTRS_PER_PGD) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
- page = mem_map + MAP_NR(ret);
- flush_chunk((unsigned long)ret);
- (unsigned int)page->pprev_hash = 0xe;
- spin_lock(&pgd_spinlock);
- (unsigned long *)page->next_hash = pgd_quicklist;
- pgd_quicklist = (unsigned long *)page;
- pgd_cache_size += 3;
- spin_unlock(&pgd_spinlock);
- }
- return ret;
+ unsigned long tmp;
+
+ tmp = __srmmu_get_nocache(size, align);
+
+ if (tmp)
+ memset((void *)tmp, 0, size);
+
+ return tmp;
}
-static void srmmu_free_pte_slow(pte_t *pte)
+/* XXX Make this SMP safe - Anton */
+void srmmu_free_nocache(unsigned long vaddr, int size)
{
+ int offset = (vaddr - SRMMU_NOCACHE_VADDR) >> SRMMU_NOCACHE_BITMAP_SHIFT;
+
+ size = size >> SRMMU_NOCACHE_BITMAP_SHIFT;
+
+ while(size--) {
+ clear_bit(offset + size, srmmu_nocache_bitmap);
+ srmmu_nocache_used--;
+ }
+
+ if (offset < srmmu_nocache_low)
+ srmmu_nocache_low = offset;
}
-static void srmmu_free_pgd_slow(pgd_t *pgd)
+void srmmu_early_allocate_ptable_skeleton(unsigned long start, unsigned long end);
+
+void srmmu_nocache_init(void)
{
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long paddr, vaddr;
+ unsigned long pteval;
+
+ srmmu_nocache_pool = __alloc_bootmem(SRMMU_NOCACHE_SIZE, PAGE_SIZE, 0UL);
+ memset(srmmu_nocache_pool, 0, SRMMU_NOCACHE_SIZE);
+
+ srmmu_nocache_bitmap = __alloc_bootmem(SRMMU_NOCACHE_BITMAP_SIZE, SMP_CACHE_BYTES, 0UL);
+ memset(srmmu_nocache_bitmap, 0, SRMMU_NOCACHE_BITMAP_SIZE);
+
+ srmmu_swapper_pg_dir = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
+ memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE);
+ init_mm.pgd = srmmu_swapper_pg_dir;
+
+ srmmu_early_allocate_ptable_skeleton(SRMMU_NOCACHE_VADDR, SRMMU_NOCACHE_END);
+
+ paddr = __pa((unsigned long)srmmu_nocache_pool);
+ vaddr = SRMMU_NOCACHE_VADDR;
+
+ while (vaddr < SRMMU_NOCACHE_END) {
+ pgd = pgd_offset_k(vaddr);
+ pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr);
+ pte = srmmu_pte_offset(__nocache_fix(pmd), vaddr);
+
+ pteval = ((paddr >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
+
+ if (srmmu_cache_pagetables)
+ pteval |= SRMMU_CACHE;
+
+ srmmu_set_pte(__nocache_fix(pte), pteval);
+
+ vaddr += PAGE_SIZE;
+ paddr += PAGE_SIZE;
+ }
+
+ flush_cache_all();
+ flush_tlb_all();
}
-static inline void srmmu_pte_free(pte_t *pte)
+static inline pgd_t *srmmu_pgd_alloc(void)
{
- struct page *page = mem_map + MAP_NR(pte);
+ pgd_t *pgd = NULL;
- spin_lock(&pte_spinlock);
- if (!page->pprev_hash) {
- (unsigned long *)page->next_hash = pte_quicklist;
- pte_quicklist = (unsigned long *)page;
+ pgd = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
+ if (pgd) {
+ pgd_t *init = pgd_offset_k(0);
+ memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+ memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
}
- (unsigned int)page->pprev_hash |= (1 << ((((unsigned long)pte) >> 8) & 15));
- pgtable_cache_size++;
- spin_unlock(&pte_spinlock);
+
+ return pgd;
+}
+
+static void srmmu_pgd_free(pgd_t *pgd)
+{
+ srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE);
}
static pte_t *srmmu_pte_alloc(pmd_t * pmd, unsigned long address)
{
address = (address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1);
if(srmmu_pmd_none(*pmd)) {
- pte_t *page = srmmu_get_pte_fast();
-
- if (page) {
- pmd_set(pmd, page);
- return page + address;
- }
- page = srmmu_get_pte_slow();
- if(srmmu_pmd_none(*pmd)) {
- if(page) {
- spin_unlock(&pte_spinlock);
- pmd_set(pmd, page);
- return page + address;
- }
- pmd_set(pmd, BAD_PAGETABLE);
- return NULL;
- }
- if (page) {
- (unsigned int)(((struct page *)pte_quicklist)->pprev_hash) = 0xffff;
- pgtable_cache_size++;
+ pte_t *page = (pte_t *)srmmu_get_nocache(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE);
+ if(page) {
spin_unlock(&pte_spinlock);
+ srmmu_pmd_set(pmd, page);
+ return page + address;
}
+ /* XXX fix this - Anton */
+ pmd_set(pmd, BAD_PAGETABLE);
+ return NULL;
}
if(srmmu_pmd_bad(*pmd)) {
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+ /* XXX fix this - Anton */
pmd_set(pmd, BAD_PAGETABLE);
return NULL;
}
return ((pte_t *) pmd_page(*pmd)) + address;
}
-/* Real three-level page tables on SRMMU. */
-static void srmmu_pmd_free(pmd_t * pmd)
+static inline void srmmu_pte_free(pte_t *pte)
{
- return srmmu_pte_free((pte_t *)pmd);
+ srmmu_free_nocache((unsigned long)pte, SRMMU_PTE_TABLE_SIZE);
}
static pmd_t *srmmu_pmd_alloc(pgd_t * pgd, unsigned long address)
{
address = (address >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1);
if(srmmu_pgd_none(*pgd)) {
- pmd_t *page = (pmd_t *)srmmu_get_pte_fast();
-
- if (page) {
- pgd_set(pgd, page);
- return page + address;
- }
- page = (pmd_t *)srmmu_get_pte_slow();
- if(srmmu_pgd_none(*pgd)) {
- if(page) {
- spin_unlock(&pte_spinlock);
- pgd_set(pgd, page);
- return page + address;
- }
- pgd_set(pgd, (pmd_t *) BAD_PAGETABLE);
- return NULL;
- }
- if (page) {
- (unsigned int)(((struct page *)pte_quicklist)->pprev_hash) = 0xffff;
- pgtable_cache_size++;
+ pmd_t *page = (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
+ if(page) {
spin_unlock(&pte_spinlock);
+ srmmu_pgd_set(pgd, page);
+ return page + address;
}
+ /* XXX fix this - Anton */
+ pgd_set(pgd, (pmd_t *) BAD_PAGETABLE);
+ return NULL;
}
if(srmmu_pgd_bad(*pgd)) {
printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd));
+ /* XXX fix this - Anton */
pgd_set(pgd, (pmd_t *) BAD_PAGETABLE);
return NULL;
}
- return (pmd_t *) pgd_page(*pgd) + address;
-}
-
-static void srmmu_pgd_free(pgd_t *pgd)
-{
- struct page *page = mem_map + MAP_NR(pgd);
-
- spin_lock(&pgd_spinlock);
- if (!page->pprev_hash) {
- (unsigned long *)page->next_hash = pgd_quicklist;
- pgd_quicklist = (unsigned long *)page;
- }
- (unsigned int)page->pprev_hash |= (1 << ((((unsigned long)pgd) >> 10) & 3));
- pgd_cache_size++;
- spin_unlock(&pgd_spinlock);
+ return (pmd_t *) srmmu_pgd_page(*pgd) + address;
}
-static pgd_t *srmmu_pgd_alloc(void)
+static void srmmu_pmd_free(pmd_t * pmd)
{
- pgd_t *ret;
-
- ret = srmmu_get_pgd_fast();
- if (ret) return ret;
- return srmmu_get_pgd_slow();
+ srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE);
}
-
static void srmmu_set_pgdir(unsigned long address, pgd_t entry)
{
struct task_struct * p;
- struct page *page;
read_lock(&tasklist_lock);
for_each_task(p) {
if (!p->mm)
continue;
- *pgd_offset(p->mm,address) = entry;
+ *srmmu_pgd_offset(p->mm,address) = entry;
}
read_unlock(&tasklist_lock);
- spin_lock(&pgd_spinlock);
- address >>= SRMMU_PGDIR_SHIFT;
- for (page = (struct page *)pgd_quicklist; page; page = page->next_hash) {
- pgd_t *pgd = (pgd_t *)page_address(page);
- unsigned int mask = (unsigned int)page->pprev_hash;
-
- if (mask & 1)
- pgd[address + 0 * SRMMU_PTRS_PER_PGD] = entry;
- if (mask & 2)
- pgd[address + 1 * SRMMU_PTRS_PER_PGD] = entry;
- if (mask & 4)
- pgd[address + 2 * SRMMU_PTRS_PER_PGD] = entry;
- if (mask & 8)
- pgd[address + 3 * SRMMU_PTRS_PER_PGD] = entry;
- if (mask)
- flush_chunk((unsigned long)pgd);
- }
- spin_unlock(&pgd_spinlock);
-}
-
-static void srmmu_set_pte_cacheable(pte_t *ptep, pte_t pteval)
-{
- srmmu_set_entry(ptep, pte_val(pteval));
-}
-
-static void srmmu_set_pte_nocache_cypress(pte_t *ptep, pte_t pteval)
-{
- register unsigned long a, b, c, d, e, f, g;
- unsigned long line, page;
-
- srmmu_set_entry(ptep, pte_val(pteval));
- page = ((unsigned long)ptep) & PAGE_MASK;
- line = (page + PAGE_SIZE) - 0x100;
- a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
- goto inside;
- do {
- line -= 0x100;
- inside:
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- "sta %%g0, [%0 + %2] %1\n\t"
- "sta %%g0, [%0 + %3] %1\n\t"
- "sta %%g0, [%0 + %4] %1\n\t"
- "sta %%g0, [%0 + %5] %1\n\t"
- "sta %%g0, [%0 + %6] %1\n\t"
- "sta %%g0, [%0 + %7] %1\n\t"
- "sta %%g0, [%0 + %8] %1\n\t" : :
- "r" (line),
- "i" (ASI_M_FLUSH_PAGE),
- "r" (a), "r" (b), "r" (c), "r" (d),
- "r" (e), "r" (f), "r" (g));
- } while(line != page);
-}
-
-static void srmmu_set_pte_nocache_viking(pte_t *ptep, pte_t pteval)
-{
- unsigned long vaddr;
- int set;
- int i;
-
- set = ((unsigned long)ptep >> 5) & 0x7f;
- vaddr = (KERNBASE + PAGE_SIZE) | (set << 5);
- srmmu_set_entry(ptep, pte_val(pteval));
- for (i = 0; i < 8; i++) {
- __asm__ __volatile__ ("ld [%0], %%g0" : : "r" (vaddr));
- vaddr += PAGE_SIZE;
- }
-}
-
-static void srmmu_quick_kernel_fault(unsigned long address)
-{
-#ifdef CONFIG_SMP
- printk("CPU[%d]: Kernel faults at addr=0x%08lx\n",
- smp_processor_id(), address);
- while (1) ;
-#else
- printk("Kernel faults at addr=0x%08lx\n", address);
- printk("PTE=%08lx\n", srmmu_hwprobe((address & PAGE_MASK)));
- die_if_kernel("SRMMU bolixed...", current->thread.kregs);
-#endif
}
static inline void alloc_context(struct mm_struct *old_mm, struct mm_struct *mm)
@@ -567,8 +491,9 @@ static void srmmu_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
spin_lock(&srmmu_context_spinlock);
alloc_context(old_mm, mm);
spin_unlock(&srmmu_context_spinlock);
- ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
+ srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
}
+ /* XXX should we hyper_flush_whole_icache() here - Anton */
srmmu_set_context(mm->context);
}
@@ -581,12 +506,13 @@ void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_ty
unsigned long tmp;
physaddr &= PAGE_MASK;
- pgdp = srmmu_pgd_offset(&init_mm, virt_addr);
- pmdp = pmd_offset(pgdp, virt_addr);
- ptep = pte_offset(pmdp, virt_addr);
+ pgdp = pgd_offset_k(virt_addr);
+ pmdp = srmmu_pmd_offset(pgdp, virt_addr);
+ ptep = srmmu_pte_offset(pmdp, virt_addr);
tmp = (physaddr >> 4) | SRMMU_ET_PTE;
- /* I need to test whether this is consistent over all
+ /*
+ * I need to test whether this is consistent over all
* sun4m's. The bus_type represents the upper 4 bits of
* 36-bit physical address on the I/O space lines...
*/
@@ -596,7 +522,7 @@ void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_ty
else
tmp |= SRMMU_PRIV;
__flush_page_to_ram(virt_addr);
- set_pte(ptep, __pte(tmp));
+ srmmu_set_pte(ptep, __pte(tmp));
flush_tlb_all();
}
@@ -606,16 +532,17 @@ void srmmu_unmapioaddr(unsigned long virt_addr)
pmd_t *pmdp;
pte_t *ptep;
- pgdp = srmmu_pgd_offset(&init_mm, virt_addr);
- pmdp = pmd_offset(pgdp, virt_addr);
- ptep = pte_offset(pmdp, virt_addr);
+ pgdp = pgd_offset_k(virt_addr);
+ pmdp = srmmu_pmd_offset(pgdp, virt_addr);
+ ptep = srmmu_pte_offset(pmdp, virt_addr);
/* No need to flush uncacheable page. */
- pte_clear(ptep);
+ srmmu_pte_clear(ptep);
flush_tlb_all();
}
-/* On the SRMMU we do not have the problems with limited tlb entries
+/*
+ * On the SRMMU we do not have the problems with limited tlb entries
* for mapping kernel pages, so we just take things from the free page
* pool. As a side effect we are putting a little too much pressure
* on the gfp() subsystem. This setup also makes the logic of the
@@ -646,14 +573,14 @@ extern void tsunami_flush_cache_page(struct vm_area_struct *vma, unsigned long p
extern void tsunami_flush_page_to_ram(unsigned long page);
extern void tsunami_flush_page_for_dma(unsigned long page);
extern void tsunami_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-extern void tsunami_flush_chunk(unsigned long chunk);
extern void tsunami_flush_tlb_all(void);
extern void tsunami_flush_tlb_mm(struct mm_struct *mm);
extern void tsunami_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end);
extern void tsunami_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
extern void tsunami_setup_blockops(void);
-/* Workaround, until we find what's going on with Swift. When low on memory,
+/*
+ * Workaround, until we find what's going on with Swift. When low on memory,
* it sometimes loops in fault/handle_mm_fault incl. flush_tlb_page to find
* out it is already in page tables/ fault again on the same instruction.
* I really don't understand it, have checked it and contexts
@@ -693,7 +620,6 @@ extern void swift_flush_cache_page(struct vm_area_struct *vma, unsigned long pag
extern void swift_flush_page_to_ram(unsigned long page);
extern void swift_flush_page_for_dma(unsigned long page);
extern void swift_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-extern void swift_flush_chunk(unsigned long chunk);
extern void swift_flush_tlb_all(void);
extern void swift_flush_tlb_mm(struct mm_struct *mm);
extern void swift_flush_tlb_range(struct mm_struct *mm,
@@ -727,11 +653,11 @@ void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
/* same as above: srmmu_flush_tlb_page() */
}
}
- module_stats.invpg++;
}
#endif
-/* The following are all MBUS based SRMMU modules, and therefore could
+/*
+ * The following are all MBUS based SRMMU modules, and therefore could
* be found in a multiprocessor configuration. On the whole, these
* chips seems to be much more touchy about DVMA and page tables
* with respect to cache coherency.
@@ -900,11 +826,6 @@ static void cypress_flush_page_to_ram(unsigned long page)
} while(line != page);
}
-static void cypress_flush_chunk(unsigned long chunk)
-{
- cypress_flush_page_to_ram(chunk);
-}
-
/* Cypress is also IO cache coherent. */
static void cypress_flush_page_for_dma(unsigned long page)
{
@@ -921,7 +842,6 @@ static void cypress_flush_sig_insns(struct mm_struct *mm, unsigned long insn_add
static void cypress_flush_tlb_all(void)
{
srmmu_flush_whole_tlb();
- module_stats.invall++;
}
static void cypress_flush_tlb_mm(struct mm_struct *mm)
@@ -936,7 +856,6 @@ static void cypress_flush_tlb_mm(struct mm_struct *mm)
: "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context),
"i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
: "g5");
- module_stats.invmm++;
FLUSH_END
}
@@ -959,7 +878,6 @@ static void cypress_flush_tlb_range(struct mm_struct *mm, unsigned long start, u
"r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS),
"i" (ASI_M_FLUSH_PROBE)
: "g5", "cc");
- module_stats.invrnge++;
FLUSH_END
}
@@ -977,7 +895,6 @@ static void cypress_flush_tlb_page(struct vm_area_struct *vma, unsigned long pag
: "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK),
"i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
: "g5");
- module_stats.invpg++;
FLUSH_END
}
@@ -993,8 +910,6 @@ extern void viking_flush_page_for_dma(unsigned long page);
extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr);
extern void viking_flush_page(unsigned long page);
extern void viking_mxcc_flush_page(unsigned long page);
-extern void viking_flush_chunk(unsigned long chunk);
-extern void viking_mxcc_flush_chunk(unsigned long chunk);
extern void viking_flush_tlb_all(void);
extern void viking_flush_tlb_mm(struct mm_struct *mm);
extern void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start,
@@ -1014,7 +929,6 @@ extern void hypersparc_flush_cache_mm(struct mm_struct *mm);
extern void hypersparc_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end);
extern void hypersparc_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
extern void hypersparc_flush_page_to_ram(unsigned long page);
-extern void hypersparc_flush_chunk(unsigned long chunk);
extern void hypersparc_flush_page_for_dma(unsigned long page);
extern void hypersparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
extern void hypersparc_flush_tlb_all(void);
@@ -1023,39 +937,8 @@ extern void hypersparc_flush_tlb_range(struct mm_struct *mm, unsigned long start
extern void hypersparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
extern void hypersparc_setup_blockops(void);
-static void srmmu_set_pte_nocache_hyper(pte_t *ptep, pte_t pteval)
-{
- unsigned long page = ((unsigned long)ptep) & PAGE_MASK;
-
- srmmu_set_entry(ptep, pte_val(pteval));
- hypersparc_flush_page_to_ram(page);
-}
-
-static void hypersparc_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
-{
- srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (__pa((unsigned long) pgdp) >> 4))));
- hypersparc_flush_page_to_ram((unsigned long)ctxp);
- hyper_flush_whole_icache();
-}
-
-static void hypersparc_switch_mm(struct mm_struct *old_mm,
- struct mm_struct *mm, struct task_struct *tsk, int cpu)
-{
- if(mm->context == NO_CONTEXT) {
- ctxd_t *ctxp;
-
- spin_lock(&srmmu_context_spinlock);
- alloc_context(old_mm, mm);
- spin_unlock(&srmmu_context_spinlock);
- ctxp = &srmmu_context_table[mm->context];
- srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (__pa((unsigned long) mm->pgd) >> 4))));
- hypersparc_flush_page_to_ram((unsigned long)ctxp);
- }
- hyper_flush_whole_icache();
- srmmu_set_context(mm->context);
-}
-
-/* NOTE: All of this startup code assumes the low 16mb (approx.) of
+/*
+ * NOTE: All of this startup code assumes the low 16mb (approx.) of
* kernel mappings are done with one single contiguous chunk of
* ram. On small ram machines (classics mainly) we only get
* around 8mb mapped for us.
@@ -1067,17 +950,43 @@ void __init early_pgtable_allocfail(char *type)
prom_halt();
}
-static inline void srmmu_allocate_ptable_skeleton(unsigned long start, unsigned long end)
+void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, unsigned long end)
{
pgd_t *pgdp;
pmd_t *pmdp;
pte_t *ptep;
while(start < end) {
- pgdp = srmmu_pgd_offset(&init_mm, start);
+ pgdp = pgd_offset_k(start);
+ if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+ pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
+ if (pmdp == NULL)
+ early_pgtable_allocfail("pmd");
+ memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
+ srmmu_pgd_set(__nocache_fix(pgdp), pmdp);
+ }
+ 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_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE);
+ if (ptep == NULL)
+ early_pgtable_allocfail("pte");
+ memset(__nocache_fix(ptep), 0, SRMMU_PTE_TABLE_SIZE);
+ srmmu_pmd_set(__nocache_fix(pmdp), ptep);
+ }
+ start = (start + SRMMU_PMD_SIZE) & SRMMU_PMD_MASK;
+ }
+}
+
+void __init srmmu_allocate_ptable_skeleton(unsigned long start, unsigned long end)
+{
+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ while(start < end) {
+ pgdp = pgd_offset_k(start);
if(srmmu_pgd_none(*pgdp)) {
- pmdp = __alloc_bootmem(SRMMU_PMD_TABLE_SIZE,
- SRMMU_PMD_TABLE_SIZE, 0UL);
+ pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
if (pmdp == NULL)
early_pgtable_allocfail("pmd");
memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE);
@@ -1085,7 +994,7 @@ static inline void srmmu_allocate_ptable_skeleton(unsigned long start, unsigned
}
pmdp = srmmu_pmd_offset(pgdp, start);
if(srmmu_pmd_none(*pmdp)) {
- ptep = __alloc_bootmem(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE, 0UL);
+ ptep = (pte_t *)__srmmu_get_nocache(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
memset(ptep, 0, SRMMU_PTE_TABLE_SIZE);
@@ -1095,7 +1004,8 @@ static inline void srmmu_allocate_ptable_skeleton(unsigned long start, unsigned
}
}
-/* This is much cleaner than poking around physical address space
+/*
+ * This is much cleaner than poking around physical address space
* looking at the prom's page table directly which is what most
* other OS's do. Yuck... this is much better.
*/
@@ -1131,35 +1041,34 @@ void __init srmmu_inherit_prom_mappings(unsigned long start,unsigned long end)
what = 2;
}
- pgdp = srmmu_pgd_offset(&init_mm, start);
+ pgdp = pgd_offset_k(start);
if(what == 2) {
- *pgdp = __pgd(prompte);
+ *(pgd_t *)__nocache_fix(pgdp) = __pgd(prompte);
start += SRMMU_PGDIR_SIZE;
continue;
}
- if(srmmu_pgd_none(*pgdp)) {
- pmdp = __alloc_bootmem(SRMMU_PMD_TABLE_SIZE,
- SRMMU_PMD_TABLE_SIZE, 0UL);
+ if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+ pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
if (pmdp == NULL)
early_pgtable_allocfail("pmd");
- memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE);
- srmmu_pgd_set(pgdp, pmdp);
+ memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
+ srmmu_pgd_set(__nocache_fix(pgdp), pmdp);
}
- pmdp = srmmu_pmd_offset(pgdp, start);
+ pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start);
if(what == 1) {
- *pmdp = __pmd(prompte);
+ *(pmd_t *)__nocache_fix(pmdp) = __pmd(prompte);
start += SRMMU_PMD_SIZE;
continue;
}
- if(srmmu_pmd_none(*pmdp)) {
- ptep = __alloc_bootmem(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE, 0UL);
+ if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
+ ptep = (pte_t *)__srmmu_get_nocache(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
- memset(ptep, 0, SRMMU_PTE_TABLE_SIZE);
- srmmu_pmd_set(pmdp, ptep);
+ memset(__nocache_fix(ptep), 0, SRMMU_PTE_TABLE_SIZE);
+ srmmu_pmd_set(__nocache_fix(pmdp), ptep);
}
- ptep = srmmu_pte_offset(pmdp, start);
- *ptep = __pte(prompte);
+ ptep = srmmu_pte_offset(__nocache_fix(pmdp), start);
+ *(pte_t *)__nocache_fix(ptep) = __pte(prompte);
start += PAGE_SIZE;
}
}
@@ -1171,15 +1080,14 @@ static unsigned long end_of_phys_memory __initdata = 0;
/* Create a third-level SRMMU 16MB page mapping. */
static void __init do_large_mapping(unsigned long vaddr, unsigned long phys_base)
{
- pgd_t *pgdp = srmmu_pgd_offset(&init_mm, vaddr);
+ pgd_t *pgdp = pgd_offset_k(vaddr);
unsigned long big_pte;
big_pte = KERNEL_PTE(phys_base >> 4);
- *pgdp = __pgd(big_pte);
+ *(pgd_t *)__nocache_fix(pgdp) = __pgd(big_pte);
}
-/* Map sp_bank entry SP_ENTRY, starting at virtual address VBASE.
- */
+/* Map sp_bank entry SP_ENTRY, starting at virtual address VBASE. */
static unsigned long __init map_spbank(unsigned long vbase, int sp_entry)
{
unsigned long pstart = (sp_banks[sp_entry].base_addr & SRMMU_PGDIR_MASK);
@@ -1254,53 +1162,40 @@ void __init srmmu_paging_init(void)
prom_printf("Something wrong, can't find cpu node in paging_init.\n");
prom_halt();
}
-
- memset(swapper_pg_dir, 0, PAGE_SIZE);
last_valid_pfn = end_pfn = bootmem_init();
- srmmu_allocate_ptable_skeleton(KERNBASE, (unsigned long)__va(end_of_phys_memory));
-#if CONFIG_SUN_IO
- srmmu_allocate_ptable_skeleton(sparc_iomap.start, IOBASE_END);
- srmmu_allocate_ptable_skeleton(DVMA_VADDR, DVMA_END);
-#endif
-
- /* This does not logically belong here, but we need to
- * call it at the moment we are able to use the bootmem
- * allocator.
- */
- sun_serial_setup();
-
+ srmmu_nocache_init();
srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE));
map_kernel();
-#define BOOTMEM_BROKEN
-#ifdef BOOTMEM_BROKEN
- srmmu_context_table = __alloc_bootmem(num_contexts*sizeof(ctxd_t)*2, SMP_CACHE_BYTES, 0UL);
- (unsigned long)srmmu_context_table += num_contexts*sizeof(ctxd_t);
- (unsigned long)srmmu_context_table &= ~(num_contexts*sizeof(ctxd_t)-1);
-#else
- srmmu_context_table = __alloc_bootmem(num_contexts*sizeof(ctxd_t), num_contexts*sizeof(ctxd_t), 0UL);
-#endif
+ /* ctx table has to be physically aligned to its size */
+ srmmu_context_table = (ctxd_t *)__srmmu_get_nocache(num_contexts*sizeof(ctxd_t), num_contexts*sizeof(ctxd_t));
+ srmmu_ctx_table_phys = (ctxd_t *)__nocache_pa((unsigned long)srmmu_context_table);
- srmmu_ctx_table_phys = (ctxd_t *) __pa((unsigned long) srmmu_context_table);
for(i = 0; i < num_contexts; i++)
- ctxd_set(&srmmu_context_table[i], swapper_pg_dir);
+ srmmu_ctxd_set((ctxd_t *)__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir);
flush_cache_all();
- if(BTFIXUPVAL_CALL(flush_page_for_dma) == (unsigned long)viking_flush_page) {
- unsigned long start = (unsigned long)srmmu_context_table;
- unsigned long end = PAGE_ALIGN((unsigned long)srmmu_context_table + num_contexts*sizeof(ctxd_t));
-
- while(start < end) {
- viking_flush_page(start);
- start += PAGE_SIZE;
- }
- }
- srmmu_set_ctable_ptr((unsigned long) srmmu_ctx_table_phys);
+ srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys);
flush_tlb_all();
poke_srmmu();
+#if CONFIG_SUN_IO
+ srmmu_allocate_ptable_skeleton(sparc_iomap.start, IOBASE_END);
+ srmmu_allocate_ptable_skeleton(DVMA_VADDR, DVMA_END);
+#endif
+
+ flush_cache_all();
+ flush_tlb_all();
+
+ /*
+ * This does not logically belong here, but we need to
+ * call it at the moment we are able to use the bootmem
+ * allocator.
+ */
+ sun_serial_setup();
+
sparc_context_init(num_contexts);
{
@@ -1309,36 +1204,19 @@ void __init srmmu_paging_init(void)
zones_size[ZONE_DMA] = end_pfn;
free_area_init(zones_size);
}
-
-#ifdef CONFIG_BLK_DEV_INITRD
- /* If initial ramdisk was specified with physical address,
- translate it here, as the p2v translation in srmmu
- is not straightforward. */
- if (initrd_start && initrd_start < KERNBASE) {
- initrd_start = __va(initrd_start);
- initrd_end = __va(initrd_end);
- if (initrd_end <= initrd_start)
- initrd_start = 0;
- }
-#endif
-
}
static int srmmu_mmu_info(char *buf)
{
return sprintf(buf,
"MMU type\t: %s\n"
- "invall\t\t: %d\n"
- "invmm\t\t: %d\n"
- "invrnge\t\t: %d\n"
- "invpg\t\t: %d\n"
"contexts\t: %d\n"
+ "nocache total\t: %d\n"
+ "nocache used\t: %d\n"
, srmmu_name,
- module_stats.invall,
- module_stats.invmm,
- module_stats.invrnge,
- module_stats.invpg,
- num_contexts
+ num_contexts,
+ SRMMU_NOCACHE_SIZE,
+ (srmmu_nocache_used << SRMMU_NOCACHE_BITMAP_SHIFT)
);
}
@@ -1351,7 +1229,7 @@ static void srmmu_destroy_context(struct mm_struct *mm)
if(mm->context != NO_CONTEXT) {
flush_cache_mm(mm);
- ctxd_set(&srmmu_context_table[mm->context], swapper_pg_dir);
+ srmmu_ctxd_set(&srmmu_context_table[mm->context], srmmu_swapper_pg_dir);
flush_tlb_mm(mm);
spin_lock(&srmmu_context_spinlock);
free_context(mm->context);
@@ -1405,7 +1283,7 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
vmaring->vm_mm->context, start);
#endif
flush_cache_page(vmaring, start);
- set_pte(ptep, __pte((pte_val(*ptep) &
+ srmmu_set_pte(ptep, __pte((pte_val(*ptep) &
~SRMMU_CACHE)));
flush_tlb_page(vmaring, start);
}
@@ -1421,7 +1299,7 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
pmdp = srmmu_pmd_offset(pgdp, address);
ptep = srmmu_pte_offset(pmdp, address);
flush_cache_page(vma, address);
- set_pte(ptep, __pte((pte_val(*ptep) & ~SRMMU_CACHE)));
+ srmmu_set_pte(ptep, __pte((pte_val(*ptep) & ~SRMMU_CACHE)));
flush_tlb_page(vma, address);
}
done:
@@ -1429,30 +1307,6 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
}
}
-static void hypersparc_destroy_context(struct mm_struct *mm)
-{
- if(mm->context != NO_CONTEXT) {
- ctxd_t *ctxp;
-
- /* HyperSparc is copy-back, any data for this
- * process in a modified cache line is stale
- * and must be written back to main memory now
- * else we eat shit later big time.
- */
- flush_cache_mm(mm);
-
- ctxp = &srmmu_context_table[mm->context];
- srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (__pa((unsigned long) swapper_pg_dir) >> 4))));
- hypersparc_flush_page_to_ram((unsigned long)ctxp);
-
- flush_tlb_mm(mm);
- spin_lock(&srmmu_context_spinlock);
- free_context(mm->context);
- spin_unlock(&srmmu_context_spinlock);
- mm->context = NO_CONTEXT;
- }
-}
-
/* Init various srmmu chip types. */
static void __init srmmu_is_bad(void)
{
@@ -1527,7 +1381,7 @@ static void __init poke_hypersparc(void)
srmmu_set_mmureg(mreg);
-#if 0 /* I think this is bad news... -DaveM */
+#if 0 /* XXX I think this is bad news... -DaveM */
hyper_clear_all_tags();
#endif
@@ -1543,7 +1397,6 @@ static void __init init_hypersparc(void)
init_vac_layout();
- BTFIXUPSET_CALL(set_pte, srmmu_set_pte_nocache_hyper, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
@@ -1561,11 +1414,7 @@ static void __init init_hypersparc(void)
BTFIXUPSET_CALL(flush_sig_insns, hypersparc_flush_sig_insns, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_page_for_dma, hypersparc_flush_page_for_dma, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(flush_chunk, hypersparc_flush_chunk, BTFIXUPCALL_NORM); /* local flush _only_ */
- BTFIXUPSET_CALL(ctxd_set, hypersparc_ctxd_set, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(switch_mm, hypersparc_switch_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(destroy_context, hypersparc_destroy_context, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(update_mmu_cache, srmmu_vac_update_mmu_cache, BTFIXUPCALL_NORM);
poke_srmmu = poke_hypersparc;
@@ -1615,7 +1464,6 @@ static void __init init_cypress_common(void)
{
init_vac_layout();
- BTFIXUPSET_CALL(set_pte, srmmu_set_pte_nocache_cypress, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
@@ -1629,7 +1477,6 @@ static void __init init_cypress_common(void)
BTFIXUPSET_CALL(flush_tlb_page, cypress_flush_tlb_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_range, cypress_flush_tlb_range, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_chunk, cypress_flush_chunk, BTFIXUPCALL_NORM); /* local flush _only_ */
BTFIXUPSET_CALL(__flush_page_to_ram, cypress_flush_page_to_ram, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_sig_insns, cypress_flush_sig_insns, BTFIXUPCALL_NOP);
@@ -1673,7 +1520,8 @@ static void __init poke_swift(void)
/* Enable I & D caches */
mreg = srmmu_get_mmureg();
mreg |= (SWIFT_IE | SWIFT_DE);
- /* The Swift branch folding logic is completely broken. At
+ /*
+ * The Swift branch folding logic is completely broken. At
* trap time, if things are just right, if can mistakenly
* think that a trap is coming from kernel mode when in fact
* it is coming from user mode (it mis-executes the branch in
@@ -1702,7 +1550,8 @@ static void __init init_swift(void)
case 0x30:
srmmu_modtype = Swift_lots_o_bugs;
hwbug_bitmask |= (HWBUG_KERN_ACCBROKEN | HWBUG_KERN_CBITBROKEN);
- /* Gee george, I wonder why Sun is so hush hush about
+ /*
+ * Gee george, I wonder why Sun is so hush hush about
* this hardware bug... really braindamage stuff going
* on here. However I think we can find a way to avoid
* all of the workaround overhead under Linux. Basically,
@@ -1723,7 +1572,8 @@ static void __init init_swift(void)
case 0x31:
srmmu_modtype = Swift_bad_c;
hwbug_bitmask |= HWBUG_KERN_CBITBROKEN;
- /* You see Sun allude to this hardware bug but never
+ /*
+ * You see Sun allude to this hardware bug but never
* admit things directly, they'll say things like,
* "the Swift chip cache problems" or similar.
*/
@@ -1738,7 +1588,6 @@ static void __init init_swift(void)
BTFIXUPSET_CALL(flush_cache_page, swift_flush_cache_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_range, swift_flush_cache_range, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_chunk, swift_flush_chunk, BTFIXUPCALL_NORM); /* local flush _only_ */
BTFIXUPSET_CALL(flush_tlb_all, swift_flush_tlb_all, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_mm, swift_flush_tlb_mm, BTFIXUPCALL_NORM);
@@ -1753,7 +1602,8 @@ static void __init init_swift(void)
flush_page_for_dma_global = 0;
- /* Are you now convinced that the Swift is one of the
+ /*
+ * Are you now convinced that the Swift is one of the
* biggest VLSI abortions of all time? Bravo Fujitsu!
* Fujitsu, the !#?!%$'d up processor people. I bet if
* you examined the microcode of the Swift you'd find
@@ -1815,21 +1665,15 @@ static void turbosparc_flush_page_for_dma(unsigned long page)
turbosparc_flush_dcache();
}
-static void turbosparc_flush_chunk(unsigned long chunk)
-{
-}
-
static void turbosparc_flush_tlb_all(void)
{
srmmu_flush_whole_tlb();
- module_stats.invall++;
}
static void turbosparc_flush_tlb_mm(struct mm_struct *mm)
{
FLUSH_BEGIN(mm)
srmmu_flush_whole_tlb();
- module_stats.invmm++;
FLUSH_END
}
@@ -1837,7 +1681,6 @@ static void turbosparc_flush_tlb_range(struct mm_struct *mm, unsigned long start
{
FLUSH_BEGIN(mm)
srmmu_flush_whole_tlb();
- module_stats.invrnge++;
FLUSH_END
}
@@ -1845,7 +1688,6 @@ static void turbosparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long
{
FLUSH_BEGIN(vma->vm_mm)
srmmu_flush_whole_tlb();
- module_stats.invpg++;
FLUSH_END
}
@@ -1906,7 +1748,6 @@ static void __init init_turbosparc(void)
BTFIXUPSET_CALL(flush_tlb_range, turbosparc_flush_tlb_range, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(__flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_chunk, turbosparc_flush_chunk, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_sig_insns, turbosparc_flush_sig_insns, BTFIXUPCALL_NOP);
BTFIXUPSET_CALL(flush_page_for_dma, turbosparc_flush_page_for_dma, BTFIXUPCALL_NORM);
@@ -1927,7 +1768,8 @@ static void __init poke_tsunami(void)
static void __init init_tsunami(void)
{
- /* Tsunami's pretty sane, Sun and TI actually got it
+ /*
+ * Tsunami's pretty sane, Sun and TI actually got it
* somewhat right this time. Fujitsu should have
* taken some lessons from them.
*/
@@ -1940,7 +1782,6 @@ static void __init init_tsunami(void)
BTFIXUPSET_CALL(flush_cache_page, tsunami_flush_cache_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_range, tsunami_flush_cache_range, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_chunk, tsunami_flush_chunk, BTFIXUPCALL_NORM); /* local flush _only_ */
BTFIXUPSET_CALL(flush_tlb_all, tsunami_flush_tlb_all, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_mm, tsunami_flush_tlb_mm, BTFIXUPCALL_NORM);
@@ -1968,7 +1809,8 @@ static void __init poke_viking(void)
mxcc_control &= ~(MXCC_CTL_RRC);
mxcc_set_creg(mxcc_control);
- /* We don't need memory parity checks.
+ /*
+ * We don't need memory parity checks.
* XXX This is a mess, have to dig out later. ecd.
viking_mxcc_turn_off_parity(&mreg, &mxcc_control);
*/
@@ -1980,9 +1822,7 @@ static void __init poke_viking(void)
mreg &= ~(VIKING_TCENABLE);
if(smp_catch++) {
- /* Must disable mixed-cmd mode here for
- * other cpu's.
- */
+ /* Must disable mixed-cmd mode here for other cpu's. */
bpreg = viking_get_bpreg();
bpreg &= ~(VIKING_ACTION_MIX);
viking_set_bpreg(bpreg);
@@ -2021,14 +1861,12 @@ static void __init init_viking(void)
viking_mxcc_present = 0;
msi_set_sync();
- BTFIXUPSET_CALL(set_pte, srmmu_set_pte_nocache_viking, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_chunk, viking_flush_chunk, BTFIXUPCALL_NORM); /* local flush _only_ */
-
- /* We need this to make sure old viking takes no hits
+ /*
+ * We need this to make sure old viking takes no hits
* on it's cache for dma snoops to workaround the
* "load from non-cacheable memory" interrupt bug.
* This is only necessary because of the new way in
@@ -2041,7 +1879,7 @@ static void __init init_viking(void)
srmmu_name = "TI Viking/MXCC";
viking_mxcc_present = 1;
- BTFIXUPSET_CALL(flush_chunk, viking_mxcc_flush_chunk, BTFIXUPCALL_NOP); /* local flush _only_ */
+ srmmu_cache_pagetables = 1;
/* MXCC vikings lack the DMA snooping bug. */
BTFIXUPSET_CALL(flush_page_for_dma, viking_flush_page_for_dma, BTFIXUPCALL_NOP);
@@ -2118,8 +1956,10 @@ static void __init get_srmmu_type(void)
return;
}
- /* Now Fujitsu TurboSparc. It might happen that it is
- in Swift emulation mode, so we will check later... */
+ /*
+ * Now Fujitsu TurboSparc. It might happen that it is
+ * in Swift emulation mode, so we will check later...
+ */
if (psr_typ == 0 && psr_vers == 5) {
init_turbosparc();
return;
@@ -2166,74 +2006,10 @@ static void __init get_srmmu_type(void)
srmmu_is_bad();
}
+/* dont laugh, static pagetables */
static int srmmu_check_pgt_cache(int low, int high)
{
- struct page *page, *page2;
- int freed = 0;
-
- if (pgtable_cache_size > high) {
- spin_lock(&pte_spinlock);
- for (page2 = NULL, page = (struct page *)pte_quicklist; page;) {
- if ((unsigned int)page->pprev_hash == 0xffff) {
- if (page2)
- page2->next_hash = page->next_hash;
- else
- (struct page *)pte_quicklist = page->next_hash;
- page->next_hash = NULL;
- page->pprev_hash = NULL;
- pgtable_cache_size -= 16;
- __free_page(page);
- freed++;
- if (page2)
- page = page2->next_hash;
- else
- page = (struct page *)pte_quicklist;
- if (pgtable_cache_size <= low)
- break;
- continue;
- }
- page2 = page;
- page = page->next_hash;
- }
- spin_unlock(&pte_spinlock);
- }
- if (pgd_cache_size > high / 4) {
- spin_lock(&pgd_spinlock);
- for (page2 = NULL, page = (struct page *)pgd_quicklist; page;) {
- if ((unsigned int)page->pprev_hash == 0xf) {
- if (page2)
- page2->next_hash = page->next_hash;
- else
- (struct page *)pgd_quicklist = page->next_hash;
- page->next_hash = NULL;
- page->pprev_hash = NULL;
- pgd_cache_size -= 4;
- __free_page(page);
- freed++;
- if (page2)
- page = page2->next_hash;
- else
- page = (struct page *)pgd_quicklist;
- if (pgd_cache_size <= low / 4)
- break;
- continue;
- }
- page2 = page;
- page = page->next_hash;
- }
- spin_unlock(&pgd_spinlock);
- }
- return freed;
-}
-
-static void srmmu_flush_dma_area(unsigned long addr, int len)
-{
- /* XXX Later */
-}
-
-static void srmmu_inval_dma_area(unsigned long addr, int len)
-{
- /* XXX Later */
+ return 0;
}
extern unsigned long spwin_mmu_patchme, fwin_mmu_patchme,
@@ -2302,22 +2078,18 @@ void __init ld_mmu_srmmu(void)
#ifndef CONFIG_SMP
BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2);
#endif
- BTFIXUPSET_CALL(get_pte_fast, srmmu_get_pte_fast, BTFIXUPCALL_RETINT(0));
- BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_RETINT(0));
- BTFIXUPSET_CALL(free_pte_slow, srmmu_free_pte_slow, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(free_pgd_slow, srmmu_free_pgd_slow, BTFIXUPCALL_NOP);
BTFIXUPSET_CALL(do_check_pgt_cache, srmmu_check_pgt_cache, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(set_pgdir, srmmu_set_pgdir, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(set_pte, srmmu_set_pte_cacheable, BTFIXUPCALL_SWAPO0O1);
+ BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1);
BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pte_pagenr, srmmu_pte_pagenr, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_SETHI(none_mask, 0xF0000000); /* P3: is it used? */
+ BTFIXUPSET_SETHI(none_mask, 0xF0000000); /* XXX P3: is it used? */
BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0);
@@ -2369,17 +2141,9 @@ void __init ld_mmu_srmmu(void)
BTFIXUPSET_CALL(free_task_struct, srmmu_free_task_struct, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(get_task_struct, srmmu_get_task_struct, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(quick_kernel_fault, srmmu_quick_kernel_fault, BTFIXUPCALL_NORM);
-
/* SRMMU specific. */
- BTFIXUPSET_CALL(ctxd_set, srmmu_ctxd_set, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pmd_set, srmmu_pmd_set, BTFIXUPCALL_NORM);
-/* hmm isn't flush_dma_area the same thing as flush_page_for_dma? */
-/* It is, except flush_page_for_dma was local to srmmu.c */
- BTFIXUPSET_CALL(mmu_flush_dma_area, srmmu_flush_dma_area, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_inval_dma_area, srmmu_inval_dma_area, BTFIXUPCALL_NORM);
-
get_srmmu_type();
patch_window_trap_handlers();
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index b4b9a82768e7eb..944195694f020a 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1,10 +1,10 @@
-/* $Id: sun4c.c,v 1.192 2000/05/09 17:40:13 davem Exp $
+/* $Id: sun4c.c,v 1.194 2000/06/05 06:08:45 anton Exp $
* sun4c.c: Doing in software what should be done in hardware.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1996 Andrew Tridgell (Andrew.Tridgell@anu.edu.au)
- * Copyright (C) 1997,99 Anton Blanchard (anton@progsoc.uts.edu.au)
+ * Copyright (C) 1997-2000 Anton Blanchard (anton@linuxcare.com)
* Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
@@ -597,14 +597,6 @@ static void sun4c_unmap_dma_area(unsigned long busa, int len)
/* XXX Implement this */
}
-static void sun4c_inval_dma_area(unsigned long virt, int len)
-{
-}
-
-static void sun4c_flush_dma_area(unsigned long virt, int len)
-{
-}
-
/* TLB management. */
/* Don't change this struct without changing entry.S. This is used
@@ -1011,13 +1003,6 @@ void sun4c_grow_kernel_ring(void)
}
}
-/* This is now a fast in-window trap handler to avoid any and all races. */
-static void sun4c_quick_kernel_fault(unsigned long address)
-{
- printk("Kernel faults at addr 0x%08lx\n", address);
- panic("sun4c kernel fault handler bolixed...");
-}
-
/* 2 page buckets for task struct and kernel stack allocation.
*
* TASK_STACK_BEGIN
@@ -2280,22 +2265,6 @@ extern __inline__ pgd_t *sun4c_get_pgd_fast(void)
return (pgd_t *)ret;
}
-static int sun4c_check_pgt_cache(int low, int high)
-{
- int freed = 0;
- if (pgtable_cache_size > high) {
- do {
- if (pgd_quicklist)
- free_pgd_slow(get_pgd_fast()), freed++;
- if (pmd_quicklist)
- free_pmd_slow(get_pmd_fast()), freed++;
- if (pte_quicklist)
- free_pte_slow(get_pte_fast()), freed++;
- } while (pgtable_cache_size > low);
- }
- return freed;
-}
-
static void sun4c_set_pgdir(unsigned long address, pgd_t entry)
{
/* Nothing to do */
@@ -2361,11 +2330,6 @@ static pte_t *sun4c_pte_alloc(pmd_t * pmd, unsigned long address)
return (pte_t *) sun4c_pmd_page(*pmd) + address;
}
-static pte_t *sun4c_pte_get(void)
-{
- return sun4c_get_pte_fast();
-}
-
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
@@ -2389,6 +2353,22 @@ static pgd_t *sun4c_pgd_alloc(void)
return sun4c_get_pgd_fast();
}
+static int sun4c_check_pgt_cache(int low, int high)
+{
+ int freed = 0;
+ if (pgtable_cache_size > high) {
+ do {
+ if (pgd_quicklist)
+ sun4c_free_pgd_slow(sun4c_get_pgd_fast()), freed++;
+ if (pmd_quicklist)
+ sun4c_free_pmd_slow(sun4c_get_pmd_fast()), freed++;
+ if (pte_quicklist)
+ sun4c_free_pte_slow(sun4c_get_pte_fast()), freed++;
+ } while (pgtable_cache_size > low);
+ }
+ return freed;
+}
+
/* There are really two cases of aliases to watch out for, and these
* are:
*
@@ -2568,7 +2548,7 @@ void __init sun4c_paging_init(void)
memset(pg3, 0, PAGE_SIZE);
/* Save work later. */
- vaddr = SUN4C_VMALLOC_START;
+ vaddr = VMALLOC_START;
swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg0);
vaddr += SUN4C_PGDIR_SIZE;
swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg1);
@@ -2628,10 +2608,6 @@ void __init ld_mmu_sun4c(void)
#ifndef CONFIG_SMP
BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM);
#endif
- BTFIXUPSET_CALL(get_pte_fast, sun4c_pte_get, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(get_pgd_fast, sun4c_pgd_alloc, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(free_pte_slow, sun4c_free_pte_slow, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(free_pgd_slow, sun4c_free_pgd_slow, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(set_pgdir, sun4c_set_pgdir, BTFIXUPCALL_NOP);
@@ -2727,14 +2703,11 @@ void __init ld_mmu_sun4c(void)
BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(mmu_translate_dvma, sun4c_translate_dvma, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_flush_dma_area, sun4c_flush_dma_area, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(mmu_inval_dma_area, sun4c_inval_dma_area, BTFIXUPCALL_NORM);
/* Task struct and kernel stack allocating/freeing. */
BTFIXUPSET_CALL(alloc_task_struct, sun4c_alloc_task_struct, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(get_task_struct, sun4c_get_task_struct, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(quick_kernel_fault, sun4c_quick_kernel_fault, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM);
/* These should _never_ get called with two level tables. */
diff --git a/arch/sparc/mm/swift.S b/arch/sparc/mm/swift.S
index 2d952f5ad31162..2ba8a66104fdc0 100644
--- a/arch/sparc/mm/swift.S
+++ b/arch/sparc/mm/swift.S
@@ -1,4 +1,4 @@
-/* $Id: swift.S,v 1.5 2000/05/09 17:40:13 davem Exp $
+/* $Id: swift.S,v 1.6 2000/06/04 06:23:53 anton Exp $
* swift.S: MicroSparc-II mmu/cache operations.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -30,7 +30,7 @@
*/
.globl swift_flush_cache_all, swift_flush_cache_mm
.globl swift_flush_cache_range, swift_flush_cache_page
- .globl swift_flush_page_for_dma, swift_flush_chunk
+ .globl swift_flush_page_for_dma
.globl swift_flush_page_to_ram
swift_flush_cache_all:
@@ -38,7 +38,6 @@ swift_flush_cache_mm:
swift_flush_cache_range:
swift_flush_cache_page:
swift_flush_page_for_dma:
-swift_flush_chunk:
swift_flush_page_to_ram:
sethi %hi(0x2000), %o0
1: subcc %o0, 0x10, %o0
@@ -190,10 +189,8 @@ swift_flush_cache_page_out:
* caches which are virtually indexed and tagged.
*/
.globl swift_flush_page_for_dma
- .globl swift_flush_chunk
.globl swift_flush_page_to_ram
swift_flush_page_for_dma:
-swift_flush_chunk:
swift_flush_page_to_ram:
andn %o0, (PAGE_SIZE - 1), %o1
#if 1
diff --git a/arch/sparc/mm/tsunami.S b/arch/sparc/mm/tsunami.S
index 1eb8fd6da20745..316e00e3a80582 100644
--- a/arch/sparc/mm/tsunami.S
+++ b/arch/sparc/mm/tsunami.S
@@ -1,4 +1,4 @@
-/* $Id: tsunami.S,v 1.4 2000/05/09 17:40:13 davem Exp $
+/* $Id: tsunami.S,v 1.5 2000/06/04 06:23:53 anton Exp $
* tsunami.S: High speed MicroSparc-I mmu/cache operations.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -28,7 +28,7 @@
.globl tsunami_flush_cache_all, tsunami_flush_cache_mm
.globl tsunami_flush_cache_range, tsunami_flush_cache_page
.globl tsunami_flush_page_to_ram, tsunami_flush_page_for_dma
- .globl tsunami_flush_sig_insns, tsunami_flush_chunk
+ .globl tsunami_flush_sig_insns
.globl tsunami_flush_tlb_all, tsunami_flush_tlb_mm
.globl tsunami_flush_tlb_range, tsunami_flush_tlb_page
@@ -46,7 +46,6 @@ tsunami_flush_cache_all:
WINDOW_FLUSH(%g4, %g5)
tsunami_flush_page_for_dma:
sta %g0, [%g0] ASI_M_IC_FLCLEAR
-tsunami_flush_chunk:
sta %g0, [%g0] ASI_M_DC_FLCLEAR
tsunami_flush_cache_out:
tsunami_flush_page_to_ram:
diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S
index 4e083225799aea..ffbec2342719be 100644
--- a/arch/sparc/mm/viking.S
+++ b/arch/sparc/mm/viking.S
@@ -1,4 +1,4 @@
-/* $Id: viking.S,v 1.16 2000/05/09 17:40:13 davem Exp $
+/* $Id: viking.S,v 1.17 2000/06/04 06:23:53 anton Exp $
* viking.S: High speed Viking cache/mmu operations
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -31,12 +31,10 @@ sun4dsmp_flush_tlb_spin:
.globl viking_flush_cache_range, viking_flush_cache_page
.globl viking_flush_page, viking_mxcc_flush_page
.globl viking_flush_page_for_dma, viking_flush_page_to_ram
- .globl viking_flush_chunk, viking_mxcc_flush_chunk
.globl viking_flush_sig_insns
.globl viking_flush_tlb_all, viking_flush_tlb_mm
.globl viking_flush_tlb_range, viking_flush_tlb_page
-viking_flush_chunk:
viking_flush_page:
sethi %hi(PAGE_OFFSET), %g2
sub %o0, %g2, %g3
@@ -109,10 +107,6 @@ viking_mxcc_flush_page:
9: retl
nop
-viking_mxcc_flush_chunk:
- retl
- nop
-
#define WINDOW_FLUSH(tmp1, tmp2) \
mov 0, tmp1; \
98: ld [%g6 + AOFF_task_thread + AOFF_thread_uwinmask], tmp2; \
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index d27061c03675bc..ac0f91bdb03c71 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.112 2000/05/22 08:12:19 davem Exp $
+# $Id: config.in,v 1.114 2000/06/04 22:23:10 anton Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
@@ -10,6 +10,15 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_VT y
@@ -61,15 +70,6 @@ fi
endmenu
mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool ' Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
comment 'Console drivers'
bool 'PROM console' CONFIG_PROM_CONSOLE
bool 'Support Frame buffer devices' CONFIG_FB
@@ -294,7 +294,7 @@ endmenu
mainmenu_option next_comment
comment 'XFree86 DRI support'
bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
-# dep_tristate ' Creator/Creator3D/Elite3D' CONFIG_DRM_FFB $CONFIG_DRM
+dep_tristate ' Creator/Creator3D' CONFIG_DRM_FFB $CONFIG_DRM
endmenu
source fs/Config.in
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 2800d1bd571047..d4a7c4b53591d8 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -8,6 +8,13 @@
CONFIG_EXPERIMENTAL=y
#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
# General setup
#
CONFIG_VT=y
@@ -59,13 +66,6 @@ CONFIG_PRINTER=m
CONFIG_ENVCTRL=m
#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
# Console drivers
#
CONFIG_PROM_CONSOLE=y
@@ -170,9 +170,9 @@ CONFIG_ATALK=m
CONFIG_DECNET=m
CONFIG_DECNET_SIOCGIFCONF=y
# CONFIG_DECNET_ROUTER is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -208,6 +208,8 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDETAPE=m
@@ -227,7 +229,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
# CONFIG_BLK_DEV_AEC62XX is not set
@@ -237,25 +238,23 @@ CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_BLK_DEV_AMD7409 is not set
# CONFIG_AMD7409_OVERRIDE is not set
CONFIG_BLK_DEV_CMD64X=y
-# CONFIG_CMD64X_RAID is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_HPT366_FIP is not set
-# CONFIG_HPT366_MODE3 is not set
CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_PDC202XX_BURST is not set
-# CONFIG_PDC202XX_MASTER is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_VIA82CXXX_TUNING is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
CONFIG_BLK_DEV_IDE_MODES=y
#
@@ -287,20 +286,20 @@ CONFIG_SCSI_CONSTANTS=y
#
CONFIG_SCSI_SUNESP=y
CONFIG_SCSI_QLOGICPTI=m
-CONFIG_SCSI_AIC7XXX=y
+CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_TAGGED_QUEUEING=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
CONFIG_AIC7XXX_PROC_STATS=y
CONFIG_AIC7XXX_RESET_DELAY=5
-CONFIG_SCSI_NCR53C8XX=y
+CONFIG_SCSI_NCR53C8XX=m
CONFIG_SCSI_SYM53C8XX=y
CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4
CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
-CONFIG_SCSI_NCR53C8XX_SYNC=10
+CONFIG_SCSI_NCR53C8XX_SYNC=40
# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
-CONFIG_SCSI_QLOGIC_ISP=y
+CONFIG_SCSI_QLOGIC_ISP=m
CONFIG_SCSI_QLOGIC_FC=m
#
@@ -379,6 +378,7 @@ CONFIG_VIDEO_DEV=y
# XFree86 DRI support
#
CONFIG_DRM=y
+CONFIG_DRM_FFB=m
#
# File systems
@@ -429,6 +429,7 @@ CONFIG_NFS_V3=y
# CONFIG_ROOT_NFS is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index df823619ca9a62..d861c41c0249f2 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.54 2000/05/12 23:51:24 davem Exp $
+# $Id: Makefile,v 1.55 2000/05/27 00:49:35 davem Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index 9cc240293488a4..4460729333be42 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -277,20 +277,24 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
goto beyond_if;
}
+ down(&current->mm->mmap_sem);
error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset);
+ up(&current->mm->mmap_sem);
if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
}
+ down(&current->mm->mmap_sem);
error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text);
+ up(&current->mm->mmap_sem);
if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 529703dfc79774..01363d42f05f6a 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.115 2000/03/29 09:55:30 davem Exp $
+/* $Id: entry.S,v 1.116 2000/06/19 06:24:37 davem Exp $
* arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -867,8 +867,8 @@ sys_ptrace: add %sp, STACK_BIAS + REGWIN_SZ, %o0
add %o7, 1f-.-4, %o7
nop
.align 32
-1: ldx [%curptr + AOFF_task_flags], %l5
- andcc %l5, 0x20, %g0
+1: ldx [%curptr + AOFF_task_ptrace], %l5
+ andcc %l5, 0x02, %g0
be,pt %icc, rtrap
clr %l6
call syscall_trace
@@ -994,11 +994,11 @@ linux_sparc_syscall32:
mov %i4, %o4 ! IEU1
lduw [%l7 + %l4], %l7 ! Load
srl %i1, 0, %o1 ! IEU0 Group
- ldx [%curptr + AOFF_task_flags], %l0 ! Load
+ ldx [%curptr + AOFF_task_ptrace], %l0 ! Load
mov %i5, %o5 ! IEU1
srl %i2, 0, %o2 ! IEU0 Group
- andcc %l0, 0x20, %g0 ! IEU0 Group
+ andcc %l0, 0x02, %g0 ! IEU0 Group
bne,pn %icc, linux_syscall_trace32 ! CTI
mov %i0, %l5 ! IEU1
call %l7 ! CTI Group brk forced
@@ -1023,11 +1023,11 @@ linux_sparc_syscall:
mov %i1, %o1 ! IEU1
lduw [%l7 + %l4], %l7 ! Load
4: mov %i2, %o2 ! IEU0 Group
- ldx [%curptr + AOFF_task_flags], %l0 ! Load
+ ldx [%curptr + AOFF_task_ptrace], %l0 ! Load
mov %i3, %o3 ! IEU1
mov %i4, %o4 ! IEU0 Group
- andcc %l0, 0x20, %g0 ! IEU1 Group+1 bubble
+ andcc %l0, 0x02, %g0 ! IEU1 Group+1 bubble
bne,pn %icc, linux_syscall_trace ! CTI Group
mov %i0, %l5 ! IEU0
2: call %l7 ! CTI Group brk forced
@@ -1048,7 +1048,7 @@ ret_sys_call:
sllx %g2, 32, %g2
bgeu,pn %xcc, 1f
- andcc %l0, 0x20, %l6
+ andcc %l0, 0x02, %l6
andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */
stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE]
bne,pn %icc, linux_syscall_trace2
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 9f5626b5bc3ecb..c424722a599dc4 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.91 2000/05/23 05:25:44 davem Exp $
+/* $Id: ioctl32.c,v 1.92 2000/05/26 22:44:11 davem Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
@@ -2442,8 +2442,8 @@ out:
}
typedef struct drm32_unique {
- size_t unique_len; /* Length of unique */
- u32 unique; /* Unique name for driver instantiation */
+ int unique_len; /* Length of unique */
+ u32 unique; /* Unique name for driver instantiation */
} drm32_unique_t;
#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
@@ -2487,13 +2487,15 @@ static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long a
if (!ret) {
if (cmd == DRM32_IOCTL_GET_UNIQUE &&
+ uptr != NULL &&
copy_to_user(uptr, karg.unique, karg.unique_len))
ret = -EFAULT;
if (put_user(karg.unique_len, &uarg->unique_len))
ret = -EFAULT;
}
- kfree(karg.unique);
+ if (karg.unique != NULL)
+ kfree(karg.unique);
return ret;
}
@@ -2836,7 +2838,7 @@ typedef struct drm32_ctx_res {
int count;
u32 contexts; /* (drm_ctx_t *) */
} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
+#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
{
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index 27aa136fffae09..acb3b4192f4455 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -1,4 +1,4 @@
-/* $Id: iommu_common.c,v 1.3 2000/01/28 13:41:59 jj Exp $
+/* $Id: iommu_common.c,v 1.4 2000/06/04 21:50:23 anton Exp $
* iommu_common.c: UltraSparc SBUS/PCI common iommu code.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -45,7 +45,7 @@ int verify_lengths(struct scatterlist *sg, int nents, int npages)
}
if (pgcount != npages) {
- printk("verify_langths: Error, page count wrong, "
+ printk("verify_lengths: Error, page count wrong, "
"npages[%d] pgcount[%d]\n",
npages, pgcount);
return -1;
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index f061c417f87532..977d0f35ae64b7 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -139,12 +139,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
#endif
if(request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED) {
+ if (current->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
goto out;
}
/* set the ptrace bit in the process flags. */
- current->flags |= PF_PTRACED;
+ current->ptrace |= PT_PTRACED;
pt_succ_return(regs, 0);
goto out;
}
@@ -187,11 +187,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
goto out;
}
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED) {
+ if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
goto out;
}
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if(child->p_pptr != current) {
REMOVE_LINKS(child);
@@ -203,7 +203,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_succ_return(regs, 0);
goto out;
}
- if (!(child->flags & PF_PTRACED)) {
+ if (!(child->ptrace & PT_PTRACED)) {
pt_error_return(regs, ESRCH);
goto out;
}
@@ -544,9 +544,9 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
#ifdef DEBUG_PTRACE
@@ -584,7 +584,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_error_return(regs, EIO);
goto out;
}
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
@@ -627,8 +627,8 @@ asmlinkage void syscall_trace(void)
#ifdef DEBUG_PTRACE
printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
#endif
- if ((current->flags & (PF_PTRACED|PF_TRACESYS))
- != (PF_PTRACED|PF_TRACESYS))
+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+ != (PT_PTRACED|PT_TRACESYS))
return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index f893e7f3a504af..2b7cde28b49780 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.49 2000/04/08 02:11:46 davem Exp $
+/* $Id: signal.c,v 1.51 2000/06/19 06:24:37 davem Exp $
* arch/sparc64/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -693,7 +693,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
if (!signr) break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
@@ -749,7 +749,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
continue;
case SIGSTOP:
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index f908b0636381f7..5a772c7eb83e60 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.62 2000/04/12 08:10:19 davem Exp $
+/* $Id: signal32.c,v 1.64 2000/06/19 06:24:37 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -1314,7 +1314,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs,
if (!signr) break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
@@ -1370,7 +1370,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs,
continue;
case SIGSTOP:
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index c48a0a52d6fa8a..b560b7e22f3e37 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.39 2000/04/27 02:49:03 davem Exp $
+/* $Id: sys_sparc.c,v 1.40 2000/06/19 06:24:37 davem Exp $
* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -227,7 +227,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
len = PAGE_ALIGN(len);
retval = -EINVAL;
- down(&current->mm->mmap_sem);
lock_kernel();
if (current->thread.flags & SPARC_FLAG_32BIT) {
@@ -241,11 +240,12 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
goto out_putf;
}
+ down(&current->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, off);
+ up(&current->mm->mmap_sem);
out_putf:
unlock_kernel();
- up(&current->mm->mmap_sem);
if (file)
fput(file);
out:
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index db6d2b4d0fd3e2..13aecb756932a4 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.147 2000/05/22 07:29:40 davem Exp $
+/* $Id: sys_sparc32.c,v 1.149 2000/06/19 06:24:37 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -3028,9 +3028,7 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
- lock_kernel();
file = open_exec(filename);
- unlock_kernel();
retval = PTR_ERR(file);
if (IS_ERR(file))
@@ -3042,10 +3040,12 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
bprm.loader = 0;
bprm.exec = 0;
if ((bprm.argc = count32(argv)) < 0) {
+ allow_write_access(file);
fput(file);
return bprm.argc;
}
if ((bprm.envc = count32(envp)) < 0) {
+ allow_write_access(file);
fput(file);
return bprm.envc;
}
@@ -3074,6 +3074,7 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
out:
/* Something went wrong, return the inode and free the argument pages*/
+ allow_write_access(bprm.file);
if (bprm.file)
fput(bprm.file);
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 7aeb4781fafae4..376569eab70ff3 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.47 2000/05/22 07:29:40 davem Exp $
+/* $Id: sys_sunos32.c,v 1.48 2000/06/19 06:24:37 davem Exp $
* sys_sunos32.c: SunOS binary compatability layer on sparc64.
*
* Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -68,7 +68,6 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of
struct file *file = NULL;
unsigned long retval, ret_type;
- down(&current->mm->mmap_sem);
lock_kernel();
if(flags & MAP_NORESERVE) {
static int cnt;
@@ -102,10 +101,12 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of
flags &= ~_MAP_NEW;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ down(&current->mm->mmap_sem);
retval = do_mmap(file,
(unsigned long) addr, (unsigned long) len,
(unsigned long) prot, (unsigned long) flags,
(unsigned long) off);
+ up(&current->mm->mmap_sem);
if(!ret_type)
retval = ((retval < 0xf0000000) ? 0 : retval);
out_putf:
@@ -113,7 +114,6 @@ out_putf:
fput(file);
out:
unlock_kernel();
- up(&current->mm->mmap_sem);
return (u32) retval;
}
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index dbdcc2e1d2bc1b..37f38c75bd56d9 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -1,4 +1,4 @@
-/* $Id: timod.c,v 1.6 2000/03/25 03:23:21 davem Exp $
+/* $Id: timod.c,v 1.7 2000/06/09 07:35:30 davem Exp $
* timod.c: timod emulation.
*
* Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
@@ -18,6 +18,8 @@
#include <linux/netdevice.h>
#include <linux/poll.h>
+#include <net/sock.h>
+
#include <asm/uaccess.h>
#include <asm/termios.h>
@@ -151,8 +153,10 @@ static void timod_wake_socket(unsigned int fd)
SOLD("wakeing socket");
sock = &current->files->fd[fd]->f_dentry->d_inode->u.socket_i;
wake_up_interruptible(&sock->wait);
+ read_lock(&sock->sk->callback_lock);
if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
- kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
+ __kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
+ read_unlock(&sock->sk->callback_lock);
SOLD("done");
}
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
index 767a52dcb37114..aaad8e0c6bc29e 100644
--- a/drivers/cdrom/aztcd.c
+++ b/drivers/cdrom/aztcd.c
@@ -1543,14 +1543,17 @@ int aztcd_open(struct inode *ip, struct file *fp)
#ifdef AZT_DEBUG
printk("aztcd: starting aztcd_open\n");
#endif
+
if (aztPresent == 0)
return -ENXIO; /* no hardware */
+ MOD_INC_USE_COUNT;
+
if (!azt_open_count && azt_state == AZT_S_IDLE)
{ azt_invalidate_buffers();
st = getAztStatus(); /* check drive status */
- if (st == -1) return -EIO; /* drive doesn't respond */
+ if (st == -1) goto err_out; /* drive doesn't respond */
if (st & AST_DOOR_OPEN)
{ /* close door, then get the status again. */
@@ -1563,18 +1566,20 @@ int aztcd_open(struct inode *ip, struct file *fp)
{ printk("aztcd: Disk Changed or No Disk in Drive?\n");
aztTocUpToDate=0;
}
- if (aztUpdateToc()) return -EIO;
+ if (aztUpdateToc()) goto err_out;
}
++azt_open_count;
- MOD_INC_USE_COUNT;
aztLockDoor();
-
#ifdef AZT_DEBUG
printk("aztcd: exiting aztcd_open\n");
#endif
return 0;
+
+err_out:
+ MOD_DEC_USE_COUNT;
+ return -EIO;
}
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index ceb94b7e593902..6b117a6be8e42d 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -193,7 +193,7 @@
3.07 Feb 2, 2000 - Jens Axboe <axboe@suse.de>
-- Do same "read header length" trick in cdrom_get_disc_info() as
- we do in cdrom_get_track_info() -- some drive don't obbey specs and
+ we do in cdrom_get_track_info() -- some drive don't obey specs and
fail if they can't supply the full Mt Fuji size table.
-- Deleted stuff related to setting up write modes. It has a different
home now.
@@ -211,10 +211,24 @@
dvd_do_auth passed uninitialized data to drive because init_cdrom_command
did not clear a 0 sized buffer.
+ 3.09 May 12, 2000 - Jens Axboe <axboe@suse.de>
+ -- Fix Video-CD on SCSI drives that don't support READ_CD command. In
+ that case switch block size and issue plain READ_10 again, then switch
+ back.
+
+ 3.10 Jun 10, 2000 - Jens Axboe <axboe@suse.de>
+ -- Fix volume control on CD's - old SCSI-II drives now use their own
+ code, as doing MODE6 stuff in here is really not my intention.
+ -- Use READ_DISC_INFO for more reliable end-of-disc.
+
+ 3.11 Jun 12, 2000 - Jens Axboe <axboe@suse.de>
+ -- Fix bug in getting rpc phase 2 region info.
+ -- Reinstate "correct" CDROMPLAYTRKIND
+
-------------------------------------------------------------------------*/
-#define REVISION "Revision: 3.08"
-#define VERSION "Id: cdrom.c 3.08 2000/05/01"
+#define REVISION "Revision: 3.11"
+#define VERSION "Id: cdrom.c 3.11 2000/06/12"
/* I use an error-log mask to give fine grain control over the type of
messages dumped to the system logs. The available masks include: */
@@ -285,7 +299,7 @@ MODULE_PARM(check_media_type, "i");
/* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
a lot of places. This macro makes the code more clear. */
-#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & type)
+#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
/* used in the audio ioctls */
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
@@ -465,7 +479,7 @@ int cdrom_open(struct inode *ip, struct file *fp)
if ((cdi = cdrom_find_device(dev)) == NULL)
return -ENODEV;
- if (fp->f_mode & FMODE_WRITE)
+ if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_DVD_RAM))
return -EROFS;
/* if this was a O_NONBLOCK open and we should honor the flags,
@@ -993,6 +1007,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
u_char buf[20];
struct cdrom_generic_command cgc;
struct cdrom_device_ops *cdo = cdi->ops;
+ rpc_state_t rpc_state;
memset(buf, 0, sizeof(buf));
init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
@@ -1099,18 +1114,19 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
case DVD_LU_SEND_RPC_STATE:
cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
setup_report_key(&cgc, 0, 8);
+ memset(&rpc_state, 0, sizeof(rpc_state_t));
if ((ret = cdo->generic_packet(cdi, &cgc)))
return ret;
- ai->lrpcs.type = (buf[4] >> 6) & 3;
- ai->lrpcs.vra = (buf[4] >> 3) & 7;
- ai->lrpcs.ucca = buf[4] & 7;
- ai->lrpcs.region_mask = buf[5];
- ai->lrpcs.rpc_scheme = buf[6];
+ ai->lrpcs.type = rpc_state.type_code;
+ ai->lrpcs.vra = rpc_state.vra;
+ ai->lrpcs.ucca = rpc_state.ucca;
+ ai->lrpcs.region_mask = rpc_state.region_mask;
+ ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
break;
- /* Set region settings */
+ /* Set region settings */
case DVD_HOST_SEND_RPC_STATE:
cdinfo(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
setup_send_key(&cgc, 0, 6);
@@ -1371,6 +1387,28 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
return 0;
}
+/*
+ * Specific READ_10 interface
+ */
+static int cdrom_read_cd(struct cdrom_device_info *cdi,
+ struct cdrom_generic_command *cgc, int lba,
+ int blocksize, int nblocks)
+{
+ struct cdrom_device_ops *cdo = cdi->ops;
+
+ memset(&cgc->cmd, 0, sizeof(cgc->cmd));
+ cgc->cmd[0] = GPCMD_READ_10;
+ cgc->cmd[2] = (lba >> 24) & 0xff;
+ cgc->cmd[3] = (lba >> 16) & 0xff;
+ cgc->cmd[4] = (lba >> 8) & 0xff;
+ cgc->cmd[5] = lba & 0xff;
+ cgc->cmd[6] = (nblocks >> 16) & 0xff;
+ cgc->cmd[7] = (nblocks >> 8) & 0xff;
+ cgc->cmd[8] = nblocks & 0xff;
+ cgc->buflen = blocksize * nblocks;
+ return cdo->generic_packet(cdi, cgc);
+}
+
/* very generic interface for reading the various types of blocks */
static int cdrom_read_block(struct cdrom_device_info *cdi,
struct cdrom_generic_command *cgc,
@@ -1787,6 +1825,43 @@ int msf_to_lba(char m, char s, char f)
return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
}
+/*
+ * Required when we need to use READ_10 to issue other than 2048 block
+ * reads
+ */
+static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
+{
+ struct cdrom_device_ops *cdo = cdi->ops;
+ struct cdrom_generic_command cgc;
+ struct modesel_head mh;
+ int ret;
+
+ memset(&mh, 0, sizeof(mh));
+ mh.block_desc_length = 0x08;
+ mh.block_length_med = (size >> 8) & 0xff;
+ mh.block_length_lo = size & 0xff;
+
+ memset(&cgc, 0, sizeof(cgc));
+ cgc.cmd[0] = 0x15;
+ cgc.cmd[1] = 1 << 4;
+ cgc.cmd[4] = 12;
+ cgc.buflen = sizeof(mh);
+ cgc.buffer = (char *) &mh;
+ cgc.data_direction = CGC_DATA_WRITE;
+ mh.block_desc_length = 0x08;
+ mh.block_length_med = (size >> 8) & 0xff;
+ mh.block_length_lo = size & 0xff;
+
+ ret = cdo->generic_packet(cdi, &cgc);
+ if (ret) {
+ printk("switch_blocksize failed, ret %x ", ret);
+ if (cgc.sense)
+ printk("sense %02x.%02x.%02x", cgc.sense->sense_key, cgc.sense->asc, cgc.sense->ascq);
+ printk("\n");
+ }
+ return ret;
+}
+
static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
unsigned long arg)
{
@@ -1829,8 +1904,27 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
return -ENOMEM;
cgc.data_direction = CGC_DATA_READ;
ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
- if (!ret)
- if (copy_to_user((char *)arg, cgc.buffer, blocksize))
+ if (ret) {
+ /*
+ * SCSI-II devices are not required to support
+ * READ_CD, so let's try switching block size
+ */
+ /* FIXME: switch back again... */
+ if ((ret = cdrom_switch_blocksize(cdi, blocksize))) {
+ kfree(cgc.buffer);
+ return ret;
+ }
+ cgc.sense = NULL;
+ ret = cdrom_read_cd(cdi, &cgc, lba, blocksize, 1);
+ if (ret) {
+ printk("read_cd failed, ret %x ", ret);
+ if (cgc.sense)
+ printk("sense %02x.%02x.%02x", cgc.sense->sense_key, cgc.sense->asc, cgc.sense->ascq);
+ printk("\n");
+ }
+ ret |= cdrom_switch_blocksize(cdi, blocksize);
+ }
+ if (!ret && copy_to_user((char *)arg, cgc.buffer, blocksize))
ret = -EFAULT;
kfree(cgc.buffer);
return ret;
@@ -1867,8 +1961,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
}
cgc.data_direction = CGC_DATA_READ;
while (ra.nframes > 0) {
- ret = cdrom_read_block(cdi, &cgc, lba, frames, 1,
- CD_FRAMESIZE_RAW);
+ ret = cdrom_read_block(cdi, &cgc, lba, frames, 1, CD_FRAMESIZE_RAW);
if (ret) break;
__copy_to_user(ra.buf, cgc.buffer,
CD_FRAMESIZE_RAW * frames);
@@ -1899,37 +1992,15 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
}
case CDROMPLAYTRKIND: {
struct cdrom_ti ti;
- struct cdrom_tocentry entry;
- struct cdrom_tochdr tochdr;
cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
IOCTL_IN(arg, struct cdrom_ti, ti);
- entry.cdte_format = CDROM_MSF;
- /* get toc entry for start and end track */
- if (cdo->audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr))
- return -EINVAL;
- if ((entry.cdte_track = ti.cdti_trk0) > tochdr.cdth_trk1)
- return -EINVAL;
- if (cdo->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
- return -EINVAL;
-
- cgc.cmd[3] = entry.cdte_addr.msf.minute;
- cgc.cmd[4] = entry.cdte_addr.msf.second;
- cgc.cmd[5] = entry.cdte_addr.msf.frame;
-
- entry.cdte_track = ti.cdti_trk1 + 1;
- if (entry.cdte_track > tochdr.cdth_trk1)
- entry.cdte_track = CDROM_LEADOUT;
-
- if (cdo->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
- return -EINVAL;
-
- cgc.cmd[6] = entry.cdte_addr.msf.minute;
- cgc.cmd[7] = entry.cdte_addr.msf.second;
- cgc.cmd[8] = entry.cdte_addr.msf.frame;
- cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
- cgc.data_direction = CGC_DATA_NONE;
+ cgc.cmd[0] = GPCMD_PLAY_AUDIO_TI;
+ cgc.cmd[4] = ti.cdti_trk0;
+ cgc.cmd[5] = ti.cdti_ind0;
+ cgc.cmd[7] = ti.cdti_trk1;
+ cgc.cmd[8] = ti.cdti_ind1;
return cdo->generic_packet(cdi, &cgc);
}
case CDROMPLAYMSF: {
@@ -2158,6 +2229,7 @@ int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type,
return cdo->generic_packet(cdi, &cgc);
}
+/* requires CD R/RW */
int cdrom_get_disc_info(kdev_t dev, disc_information *di)
{
struct cdrom_device_info *cdi = cdrom_find_device(dev);
@@ -2201,6 +2273,9 @@ int cdrom_get_last_written(kdev_t dev, long *last_written)
if (!CDROM_CAN(CDC_GENERIC_PACKET))
goto use_toc;
+ if (!CDROM_CAN(CDC_CD_R | CDC_CD_RW | CDC_DVD_R | CDC_DVD_RAM))
+ goto use_toc;
+
if ((ret = cdrom_get_disc_info(dev, &di)))
goto use_toc;
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index 45af244842f591..9e8889ac6ed2e7 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -736,13 +736,14 @@ void get_disc_status(void)
static int cm206_open(struct cdrom_device_info * cdi, int purpose)
{
+ MOD_INC_USE_COUNT;
if (!cd->openfiles) { /* reset only first time */
cd->background=0;
reset_cm260();
cd->adapter_last = -1; /* invalidate adapter memory */
cd->sector_last = -1;
}
- ++cd->openfiles; MOD_INC_USE_COUNT;
+ ++cd->openfiles;
stats(open);
return 0;
}
@@ -757,7 +758,8 @@ static void cm206_release(struct cdrom_device_info * cdi)
cd->sector_last = -1; /* Make our internal buffer invalid */
FIRST_TRACK = 0; /* No valid disc status */
}
- --cd->openfiles; MOD_DEC_USE_COUNT;
+ --cd->openfiles;
+ MOD_DEC_USE_COUNT;
}
/* Empty buffer empties $sectors$ sectors of the adapter card buffer,
@@ -1258,6 +1260,7 @@ static struct cdrom_device_info cm206_info = {
&cm206_dops, /* device operations */
NULL, /* link */
NULL, /* handle (not used by cm206) */
+ 0, /* devfs handle */
0, /* dev */
0, /* mask */
2, /* maximum speed */
diff --git a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c
index 44cde3738ca956..91bde1a1d5e880 100644
--- a/drivers/cdrom/mcd.c
+++ b/drivers/cdrom/mcd.c
@@ -1110,12 +1110,16 @@ static int mcd_open(struct cdrom_device_info * cdi, int purpose)
if (mcdPresent == 0)
return -ENXIO; /* no hardware */
- if (!mcd_open_count && mcd_state == MCD_S_IDLE) {
+ MOD_INC_USE_COUNT;
+
+ if (mcd_open_count || mcd_state != MCD_S_IDLE)
+ goto bump_count;
+
mcd_invalidate_buffers();
do {
st = statusCmd(); /* check drive status */
if (st == -1)
- return -EIO; /* drive doesn't respond */
+ goto err_out; /* drive doesn't respond */
if ((st & MST_READY) == 0) { /* no disk? wait a sec... */
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ);
@@ -1123,11 +1127,15 @@ static int mcd_open(struct cdrom_device_info * cdi, int purpose)
} while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
if (updateToc() < 0)
- return -EIO;
- }
+ goto err_out;
+
+bump_count:
++mcd_open_count;
- MOD_INC_USE_COUNT;
return 0;
+
+err_out:
+ MOD_DEC_USE_COUNT;
+ return -EIO;
}
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
index ad190c6ef15adc..07f1f030cb7a67 100644
--- a/drivers/cdrom/optcd.c
+++ b/drivers/cdrom/optcd.c
@@ -1871,6 +1871,8 @@ static int opt_open(struct inode *ip, struct file *fp)
{
DEBUG((DEBUG_VFS, "starting opt_open"));
+ MOD_INC_USE_COUNT;
+
if (!open_count && state == S_IDLE) {
int status;
@@ -1885,12 +1887,12 @@ static int opt_open(struct inode *ip, struct file *fp)
status = drive_status();
if (status < 0) {
DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
- return -EIO;
+ goto err_out;
}
DEBUG((DEBUG_VFS, "status: %02x", status));
if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
printk(KERN_INFO "optcd: no disk or door open\n");
- return -EIO;
+ goto err_out;
}
status = exec_cmd(COMLOCK); /* Lock door */
if (status < 0) {
@@ -1904,15 +1906,18 @@ static int opt_open(struct inode *ip, struct file *fp)
DEBUG((DEBUG_VFS,
"exec_cmd COMUNLOCK: %02x", -status));
}
- return -EIO;
+ goto err_out;
}
open_count++;
}
- MOD_INC_USE_COUNT;
DEBUG((DEBUG_VFS, "exiting opt_open"));
return 0;
+
+err_out:
+ MOD_DEC_USE_COUNT;
+ return -EIO;
}
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
index 5b8db1278e66ac..82dd5e5b9a1beb 100644
--- a/drivers/cdrom/sjcd.c
+++ b/drivers/cdrom/sjcd.c
@@ -58,10 +58,7 @@
#define SJCD_VERSION_MAJOR 1
#define SJCD_VERSION_MINOR 7
-#ifdef MODULE
#include <linux/module.h>
-#endif /* MODULE */
-
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -1339,6 +1336,8 @@ int sjcd_open( struct inode *ip, struct file *fp ){
*/
if( fp->f_mode & 2 ) return( -EROFS );
+ MOD_INC_USE_COUNT;
+
if( sjcd_open_count == 0 ){
int s, sjcd_open_tries;
/* We don't know that, do we? */
@@ -1360,7 +1359,7 @@ int sjcd_open( struct inode *ip, struct file *fp ){
#if defined( SJCD_DIAGNOSTIC )
printk( "SJCD: open: timed out when check status.\n" );
#endif
- return( -EIO );
+ goto err_out;
} else if( !sjcd_media_is_available ){
#if defined( SJCD_DIAGNOSTIC )
printk("SJCD: open: no disk in drive\n");
@@ -1375,10 +1374,10 @@ int sjcd_open( struct inode *ip, struct file *fp ){
#if defined( SJCD_DIAGNOSTIC )
printk("SJCD: open: tray close attempt failed\n");
#endif
- return( -EIO );
+ goto err_out;
}
continue;
- } else return( -EIO );
+ } else goto err_out;
}
break;
}
@@ -1387,17 +1386,19 @@ int sjcd_open( struct inode *ip, struct file *fp ){
#if defined( SJCD_DIAGNOSTIC )
printk("SJCD: open: tray lock attempt failed\n");
#endif
- return( -EIO );
+ goto err_out;
}
#if defined( SJCD_TRACE )
printk( "SJCD: open: done\n" );
#endif
}
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
+
++sjcd_open_count;
return( 0 );
+
+err_out:
+ MOD_DEC_USE_COUNT;
+ return( -EIO );
}
/*
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 21a638fe26595f..355a9a8d11157c 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -31,6 +31,7 @@ enum aper_size_type {
U8_APER_SIZE,
U16_APER_SIZE,
U32_APER_SIZE,
+ LVL2_APER_SIZE,
FIXED_APER_SIZE
};
@@ -63,6 +64,12 @@ typedef struct _aper_size_info_32 {
u32 size_value;
} aper_size_info_32;
+typedef struct _aper_size_info_lvl2 {
+ int size;
+ int num_entries;
+ u32 size_value;
+} aper_size_info_lvl2;
+
typedef struct _aper_size_info_fixed {
int size;
int num_entries;
@@ -124,10 +131,12 @@ struct agp_bridge_data {
#define A_SIZE_8(x) ((aper_size_info_8 *) x)
#define A_SIZE_16(x) ((aper_size_info_16 *) x)
#define A_SIZE_32(x) ((aper_size_info_32 *) x)
+#define A_SIZE_LVL2(x) ((aper_size_info_lvl2 *) x)
#define A_SIZE_FIX(x) ((aper_size_info_fixed *) x)
#define A_IDX8() (A_SIZE_8(agp_bridge.aperture_sizes) + i)
#define A_IDX16() (A_SIZE_16(agp_bridge.aperture_sizes) + i)
#define A_IDX32() (A_SIZE_32(agp_bridge.aperture_sizes) + i)
+#define A_IDXLVL2() (A_SIZE_LVL2(agp_bridge.aperture_sizes) + i)
#define A_IDXFIX() (A_SIZE_FIX(agp_bridge.aperture_sizes) + i)
#define MAXKEY (4096 * 32)
@@ -151,6 +160,9 @@ struct agp_bridge_data {
#ifndef PCI_DEVICE_ID_INTEL_810_0
#define PCI_DEVICE_ID_INTEL_810_0 0x7120
#endif
+#ifndef PCI_DEVICE_ID_INTEL_840_0
+#define PCI_DEVICE_ID_INTEL_840_0 0x1a21
+#endif
#ifndef PCI_DEVICE_ID_INTEL_810_DC100_0
#define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122
#endif
@@ -190,6 +202,10 @@ struct agp_bridge_data {
#define INTEL_NBXCFG 0x50
#define INTEL_ERRSTS 0x91
+/* intel i840 registers */
+#define INTEL_I840_MCHCFG 0x50
+#define INTEL_I840_ERRSTS 0xc8
+
/* intel i810 registers */
#define I810_GMADDR 0x10
#define I810_MMADDR 0x14
diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
index 274c9a86b44c87..dcc8176f9e4e29 100644
--- a/drivers/char/agp/agpgart_be.c
+++ b/drivers/char/agp/agpgart_be.c
@@ -315,6 +315,9 @@ static int agp_return_size(void)
case U32_APER_SIZE:
current_size = A_SIZE_32(temp)->size;
break;
+ case LVL2_APER_SIZE:
+ current_size = A_SIZE_LVL2(temp)->size;
+ break;
case FIXED_APER_SIZE:
current_size = A_SIZE_FIX(temp)->size;
break;
@@ -539,6 +542,11 @@ static int agp_generic_create_gatt_table(void)
int i;
void *temp;
+ /* The generic routines can't handle 2 level gatt's */
+ if (agp_bridge.size_type == LVL2_APER_SIZE) {
+ return -EINVAL;
+ }
+
table = NULL;
i = agp_bridge.aperture_size_idx;
temp = agp_bridge.current_size;
@@ -566,6 +574,7 @@ static int agp_generic_create_gatt_table(void)
break;
/* This case will never really happen. */
case FIXED_APER_SIZE:
+ case LVL2_APER_SIZE:
default:
size = page_order = num_entries = 0;
break;
@@ -590,6 +599,7 @@ static int agp_generic_create_gatt_table(void)
* happen.
*/
case FIXED_APER_SIZE:
+ case LVL2_APER_SIZE:
default:
agp_bridge.current_size =
agp_bridge.current_size;
@@ -663,6 +673,10 @@ static int agp_generic_free_gatt_table(void)
case FIXED_APER_SIZE:
page_order = A_SIZE_FIX(temp)->page_order;
break;
+ case LVL2_APER_SIZE:
+ /* The generic routines can't deal with 2 level gatt's */
+ return -EINVAL;
+ break;
default:
page_order = 0;
break;
@@ -706,6 +720,10 @@ static int agp_generic_insert_memory(agp_memory * mem,
case FIXED_APER_SIZE:
num_entries = A_SIZE_FIX(temp)->num_entries;
break;
+ case LVL2_APER_SIZE:
+ /* The generic routines can't deal with 2 level gatt's */
+ return -EINVAL;
+ break;
default:
num_entries = 0;
break;
@@ -1126,6 +1144,38 @@ static int intel_configure(void)
return 0;
}
+static int intel_840_configure(void)
+{
+ u32 temp;
+ u16 temp2;
+ aper_size_info_16 *current_size;
+
+ current_size = A_SIZE_16(agp_bridge.current_size);
+
+ /* aperture size */
+ pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
+ (char)current_size->size_value);
+
+ /* address to map to */
+ pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+ /* attbase - aperture base */
+ pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
+ agp_bridge.gatt_bus_addr);
+
+ /* agpctrl */
+ pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
+
+ /* mcgcfg */
+ pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2);
+ pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG,
+ temp2 | (1 << 9));
+ /* clear any possible error conditions */
+ pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000);
+ return 0;
+}
+
static unsigned long intel_mask_memory(unsigned long addr, int type)
{
/* Memory type is ignored */
@@ -1179,6 +1229,34 @@ static int __init intel_generic_setup (struct pci_dev *pdev)
(void) pdev; /* unused */
}
+static int __init intel_840_setup (struct pci_dev *pdev)
+{
+ agp_bridge.masks = intel_generic_masks;
+ agp_bridge.num_of_masks = 1;
+ agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
+ agp_bridge.size_type = U16_APER_SIZE;
+ agp_bridge.num_aperture_sizes = 7;
+ agp_bridge.dev_private_data = NULL;
+ agp_bridge.needs_scratch_page = FALSE;
+ agp_bridge.configure = intel_840_configure;
+ agp_bridge.fetch_size = intel_fetch_size;
+ agp_bridge.cleanup = intel_cleanup;
+ agp_bridge.tlb_flush = intel_tlbflush;
+ agp_bridge.mask_memory = intel_mask_memory;
+ agp_bridge.agp_enable = agp_generic_agp_enable;
+ agp_bridge.cache_flush = global_cache_flush;
+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+ agp_bridge.insert_memory = agp_generic_insert_memory;
+ agp_bridge.remove_memory = agp_generic_remove_memory;
+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+ agp_bridge.free_by_type = agp_generic_free_by_type;
+
+ return 0;
+
+ (void) pdev; /* unused */
+}
+
#endif /* CONFIG_AGP_INTEL */
#ifdef CONFIG_AGP_VIA
@@ -1403,19 +1481,180 @@ static int __init sis_generic_setup (struct pci_dev *pdev)
#ifdef CONFIG_AGP_AMD
+typedef struct _amd_page_map {
+ unsigned long *real;
+ unsigned long *remapped;
+} amd_page_map;
+
static struct _amd_irongate_private {
volatile u8 *registers;
+ amd_page_map **gatt_pages;
+ int num_tables;
} amd_irongate_private;
+static int amd_create_page_map(amd_page_map *page_map)
+{
+ int i;
+
+ page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
+ if (page_map->real == NULL) {
+ return -ENOMEM;
+ }
+ set_bit(PG_reserved, &mem_map[MAP_NR(page_map->real)].flags);
+ CACHE_FLUSH();
+ page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
+ PAGE_SIZE);
+ if (page_map->remapped == NULL) {
+ clear_bit(PG_reserved,
+ &mem_map[MAP_NR(page_map->real)].flags);
+ free_page((unsigned long) page_map->real);
+ page_map->real = NULL;
+ return -ENOMEM;
+ }
+ CACHE_FLUSH();
+
+ for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
+ page_map->remapped[i] = agp_bridge.scratch_page;
+ }
+
+ return 0;
+}
+
+static void amd_free_page_map(amd_page_map *page_map)
+{
+ iounmap(page_map->remapped);
+ clear_bit(PG_reserved,
+ &mem_map[MAP_NR(page_map->real)].flags);
+ free_page((unsigned long) page_map->real);
+}
+
+static void amd_free_gatt_pages(void)
+{
+ int i;
+ amd_page_map **tables;
+ amd_page_map *entry;
+
+ tables = amd_irongate_private.gatt_pages;
+ for(i = 0; i < amd_irongate_private.num_tables; i++) {
+ entry = tables[i];
+ if (entry != NULL) {
+ if (entry->real != NULL) {
+ amd_free_page_map(entry);
+ }
+ kfree(entry);
+ }
+ }
+ kfree(tables);
+}
+
+static int amd_create_gatt_pages(int nr_tables)
+{
+ amd_page_map **tables;
+ amd_page_map *entry;
+ int retval = 0;
+ int i;
+
+ tables = kmalloc((nr_tables + 1) * sizeof(amd_page_map *),
+ GFP_KERNEL);
+ if (tables == NULL) {
+ return -ENOMEM;
+ }
+ memset(tables, 0, sizeof(amd_page_map *) * (nr_tables + 1));
+ for (i = 0; i < nr_tables; i++) {
+ entry = kmalloc(sizeof(amd_page_map), GFP_KERNEL);
+ if (entry == NULL) {
+ retval = -ENOMEM;
+ break;
+ }
+ memset(entry, 0, sizeof(amd_page_map));
+ tables[i] = entry;
+ retval = amd_create_page_map(entry);
+ if (retval != 0) break;
+ }
+ amd_irongate_private.num_tables = nr_tables;
+ amd_irongate_private.gatt_pages = tables;
+
+ if (retval != 0) amd_free_gatt_pages();
+
+ return retval;
+}
+
+/* Since we don't need contigious memory we just try
+ * to get the gatt table once
+ */
+
+#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
+#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
+ GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr))
+#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
+#define GET_GATT(addr) (amd_irongate_private.gatt_pages[\
+ GET_PAGE_DIR_IDX(addr)]->remapped)
+
+static int amd_create_gatt_table(void)
+{
+ aper_size_info_lvl2 *value;
+ amd_page_map page_dir;
+ unsigned long addr;
+ int retval;
+ u32 temp;
+ int i;
+
+ value = A_SIZE_LVL2(agp_bridge.current_size);
+ retval = amd_create_page_map(&page_dir);
+ if (retval != 0) {
+ return retval;
+ }
+
+ retval = amd_create_gatt_pages(value->num_entries / 1024);
+ if (retval != 0) {
+ amd_free_page_map(&page_dir);
+ return retval;
+ }
+
+ agp_bridge.gatt_table_real = page_dir.real;
+ agp_bridge.gatt_table = page_dir.remapped;
+ agp_bridge.gatt_bus_addr = virt_to_bus(page_dir.real);
+
+ /* Get the address for the gart region.
+ * This is a bus address even on the alpha, b/c its
+ * used to program the agp master not the cpu
+ */
+
+ pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
+ addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+ agp_bridge.gart_bus_addr = addr;
+
+ /* Calculate the agp offset */
+ for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
+ page_dir.remapped[GET_PAGE_DIR_OFF(addr)] =
+ virt_to_bus(amd_irongate_private.gatt_pages[i]->real);
+ page_dir.remapped[GET_PAGE_DIR_OFF(addr)] |= 0x00000001;
+ }
+
+ return 0;
+}
+
+static int amd_free_gatt_table(void)
+{
+ amd_page_map page_dir;
+
+ page_dir.real = agp_bridge.gatt_table_real;
+ page_dir.remapped = agp_bridge.gatt_table;
+
+ amd_free_gatt_pages();
+ amd_free_page_map(&page_dir);
+ return 0;
+}
+
static int amd_irongate_fetch_size(void)
{
int i;
u32 temp;
- aper_size_info_32 *values;
+ aper_size_info_lvl2 *values;
pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
temp = (temp & 0x0000000e);
- values = A_SIZE_32(agp_bridge.aperture_sizes);
+ values = A_SIZE_LVL2(agp_bridge.aperture_sizes);
for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge.previous_size =
@@ -1431,12 +1670,11 @@ static int amd_irongate_fetch_size(void)
static int amd_irongate_configure(void)
{
- aper_size_info_32 *current_size;
- unsigned long addr;
+ aper_size_info_lvl2 *current_size;
u32 temp;
u16 enable_reg;
- current_size = A_SIZE_32(agp_bridge.current_size);
+ current_size = A_SIZE_LVL2(agp_bridge.current_size);
/* Get the memory mapped registers */
pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp);
@@ -1451,7 +1689,7 @@ static int amd_irongate_configure(void)
pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80);
/* Set indexing mode */
- pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL2, 0x02);
+ pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL2, 0x00);
/* Write the enable register */
enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
@@ -1467,28 +1705,16 @@ static int amd_irongate_configure(void)
/* Flush the tlb */
OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
- /* Get the address for the gart region */
- pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
- addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-#ifdef __alpha__
- /* ??? Presumably what is wanted is the bus address as seen
- from the CPU side, since it appears that this value is
- exported to userland via an ioctl. The terminology below
- is confused, mixing `physical address' with `bus address',
- as x86 folk are wont to do. */
- addr = virt_to_phys(ioremap(addr, 0));
-#endif
- agp_bridge.gart_bus_addr = addr;
return 0;
}
static void amd_irongate_cleanup(void)
{
- aper_size_info_32 *previous_size;
+ aper_size_info_lvl2 *previous_size;
u32 temp;
u16 enable_reg;
- previous_size = A_SIZE_32(agp_bridge.previous_size);
+ previous_size = A_SIZE_LVL2(agp_bridge.previous_size);
enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
enable_reg = (enable_reg & ~(0x0004));
@@ -1521,15 +1747,76 @@ static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
return addr | agp_bridge.masks[0].mask;
}
-static aper_size_info_32 amd_irongate_sizes[7] =
+static int amd_insert_memory(agp_memory * mem,
+ off_t pg_start, int type)
{
- {2048, 524288, 9, 0x0000000c},
- {1024, 262144, 8, 0x0000000a},
- {512, 131072, 7, 0x00000008},
- {256, 65536, 6, 0x00000006},
- {128, 32768, 5, 0x00000004},
- {64, 16384, 4, 0x00000002},
- {32, 8192, 3, 0x00000000}
+ int i, j, num_entries;
+ unsigned long *cur_gatt;
+ unsigned long addr;
+
+ num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries;
+
+ if (type != 0 || mem->type != 0) {
+ return -EINVAL;
+ }
+ if ((pg_start + mem->page_count) > num_entries) {
+ return -EINVAL;
+ }
+
+ j = pg_start;
+ while (j < (pg_start + mem->page_count)) {
+ addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+ cur_gatt = GET_GATT(addr);
+ if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) {
+ return -EBUSY;
+ }
+ j++;
+ }
+
+ if (mem->is_flushed == FALSE) {
+ CACHE_FLUSH();
+ mem->is_flushed = TRUE;
+ }
+
+ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+ addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+ cur_gatt = GET_GATT(addr);
+ cur_gatt[GET_GATT_OFF(addr)] = mem->memory[i];
+ }
+ agp_bridge.tlb_flush(mem);
+ return 0;
+}
+
+static int amd_remove_memory(agp_memory * mem, off_t pg_start,
+ int type)
+{
+ int i;
+ unsigned long *cur_gatt;
+ unsigned long addr;
+
+ if (type != 0 || mem->type != 0) {
+ return -EINVAL;
+ }
+ for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+ addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+ cur_gatt = GET_GATT(addr);
+ cur_gatt[GET_GATT_OFF(addr)] =
+ (unsigned long) agp_bridge.scratch_page;
+ }
+
+ agp_bridge.tlb_flush(mem);
+ return 0;
+}
+
+static aper_size_info_lvl2 amd_irongate_sizes[7] =
+{
+ {2048, 524288, 0x0000000c},
+ {1024, 262144, 0x0000000a},
+ {512, 131072, 0x00000008},
+ {256, 65536, 0x00000006},
+ {128, 32768, 0x00000004},
+ {64, 16384, 0x00000002},
+ {32, 8192, 0x00000000}
};
static gatt_mask amd_irongate_masks[] =
@@ -1542,7 +1829,7 @@ static int __init amd_irongate_setup (struct pci_dev *pdev)
agp_bridge.masks = amd_irongate_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) amd_irongate_sizes;
- agp_bridge.size_type = U32_APER_SIZE;
+ agp_bridge.size_type = LVL2_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = (void *) &amd_irongate_private;
agp_bridge.needs_scratch_page = FALSE;
@@ -1553,10 +1840,10 @@ static int __init amd_irongate_setup (struct pci_dev *pdev)
agp_bridge.mask_memory = amd_irongate_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
- agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
- agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
- agp_bridge.insert_memory = agp_generic_insert_memory;
- agp_bridge.remove_memory = agp_generic_remove_memory;
+ agp_bridge.create_gatt_table = amd_create_gatt_table;
+ agp_bridge.free_gatt_table = amd_free_gatt_table;
+ agp_bridge.insert_memory = amd_insert_memory;
+ agp_bridge.remove_memory = amd_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
@@ -1755,6 +2042,12 @@ static struct {
"Intel",
"440GX",
intel_generic_setup },
+ { PCI_DEVICE_ID_INTEL_840_0,
+ PCI_VENDOR_ID_INTEL,
+ INTEL_I840,
+ "Intel",
+ "i840",
+ intel_840_setup },
{ 0,
PCI_VENDOR_ID_INTEL,
INTEL_GENERIC,
diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c
index 199d5c0791f66d..66ec50b9f2e263 100644
--- a/drivers/char/agp/agpgart_fe.c
+++ b/drivers/char/agp/agpgart_fe.c
@@ -687,7 +687,6 @@ static int agp_release(struct inode *inode, struct file *file)
}
agp_remove_file_private(priv);
kfree(priv);
- MOD_DEC_USE_COUNT;
AGP_UNLOCK();
return 0;
}
@@ -697,19 +696,17 @@ static int agp_open(struct inode *inode, struct file *file)
int minor = MINOR(inode->i_rdev);
agp_file_private *priv;
agp_client *client;
+ int rc = -ENXIO;
AGP_LOCK();
- if (minor != AGPGART_MINOR) {
- AGP_UNLOCK();
- return -ENXIO;
- }
+ if (minor != AGPGART_MINOR)
+ goto err_out;
+
priv = kmalloc(sizeof(agp_file_private), GFP_KERNEL);
+ if (priv == NULL)
+ goto err_out_nomem;
- if (priv == NULL) {
- AGP_UNLOCK();
- return -ENOMEM;
- }
memset(priv, 0, sizeof(agp_file_private));
set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
priv->my_pid = current->pid;
@@ -726,9 +723,14 @@ static int agp_open(struct inode *inode, struct file *file)
}
file->private_data = (void *) priv;
agp_insert_file_private(priv);
- MOD_INC_USE_COUNT;
AGP_UNLOCK();
return 0;
+
+err_out_nomem:
+ rc = -ENOMEM;
+err_out:
+ AGP_UNLOCK();
+ return rc;
}
diff --git a/drivers/char/buz.c b/drivers/char/buz.c
index cbf085e9e3bd73..299a4f8ca1dc54 100644
--- a/drivers/char/buz.c
+++ b/drivers/char/buz.c
@@ -48,6 +48,7 @@
#include <linux/types.h>
#include <linux/wrapper.h>
#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
#include <linux/videodev.h>
diff --git a/drivers/char/c-qcam.c b/drivers/char/c-qcam.c
index 1e0582bdf0b248..fa96cc925923ed 100644
--- a/drivers/char/c-qcam.c
+++ b/drivers/char/c-qcam.c
@@ -12,9 +12,15 @@
* probe=1 -- use IEEE-1284 autoprobe data only (default)
* probe=2 -- probe aggressively for cameras
*
+ * force_rgb=1 -- force data format to RGB (default is BGR)
+ *
* The parport parameter controls which parports will be scanned.
* Scanning all parports causes some printers to print a garbage page.
* -- March 14, 1999 Billy Donahue <billy@escape.com>
+ *
+ * Fixed data format to BGR, added force_rgb parameter. Added missing
+ * parport_unregister_driver() on module removal.
+ * -- May 28, 2000 Claudio Matsuoka <claudio@conectiva.com>
*/
#include <linux/module.h>
@@ -62,6 +68,7 @@ struct qcam_device {
static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
static int probe = 2;
+static int force_rgb = 0;
static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
{
@@ -278,6 +285,7 @@ static void qc_setup(struct qcam_device *q)
static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
{
unsigned int bytes = 0;
+
qcam_set_ack(q, 0);
if (q->bidirectional)
{
@@ -285,6 +293,8 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u
while (bytes < nbytes)
{
unsigned int lo1, hi1, lo2, hi2;
+ unsigned char r, g, b;
+
if (qcam_await_ready2(q, 1)) return bytes;
lo1 = parport_read_data(q->pport) >> 1;
hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
@@ -293,17 +303,30 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u
lo2 = parport_read_data(q->pport) >> 1;
hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
qcam_set_ack(q, 0);
- buf[bytes++] = (lo1 | ((hi1 & 1)<<7));
- buf[bytes++] = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
- buf[bytes++] = (lo2 | ((hi2 & 1)<<7));
+ r = (lo1 | ((hi1 & 1)<<7));
+ g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
+ b = (lo2 | ((hi2 & 1)<<7));
+ if (force_rgb) {
+ buf[bytes++] = r;
+ buf[bytes++] = g;
+ buf[bytes++] = b;
+ } else {
+ buf[bytes++] = b;
+ buf[bytes++] = g;
+ buf[bytes++] = r;
+ }
}
}
else
{
/* It's a unidirectional port */
+ int i = 0, n = bytes;
+ unsigned char rgb[3];
+
while (bytes < nbytes)
{
unsigned int hi, lo;
+
if (qcam_await_ready1(q, 1)) return bytes;
hi = (parport_read_status(q->pport) & 0xf0);
qcam_set_ack(q, 1);
@@ -311,7 +334,23 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u
lo = (parport_read_status(q->pport) & 0xf0);
qcam_set_ack(q, 0);
/* flip some bits */
- buf[bytes++] = (hi | (lo >> 4)) ^ 0x88;
+ rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
+ if (i >= 2) {
+get_fragment:
+ if (force_rgb) {
+ buf[n++] = rgb[0];
+ buf[n++] = rgb[1];
+ buf[n++] = rgb[2];
+ } else {
+ buf[n++] = rgb[2];
+ buf[n++] = rgb[1];
+ buf[n++] = rgb[0];
+ }
+ }
+ }
+ if (i) {
+ i = 0;
+ goto get_fragment;
}
}
return bytes;
@@ -408,8 +447,13 @@ static long qc_capture(struct qcam_device *q, char *buf, unsigned long len)
if (current->need_resched)
schedule();
} while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
- if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
- printk("qcam: bad EOF\n");
+ if (force_rgb) {
+ if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
+ printk("qcam: bad EOF\n");
+ } else {
+ if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
+ printk("qcam: bad EOF\n");
+ }
qcam_set_ack(q, 0);
if (qcam_await_ready1(q, 1))
{
@@ -437,8 +481,13 @@ static long qc_capture(struct qcam_device *q, char *buf, unsigned long len)
schedule();
} while (l && tmpbuf[0] == 0x7e);
l = qcam_read_bytes(q, tmpbuf+1, 2);
- if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
- printk("qcam: bad EOF\n");
+ if (force_rgb) {
+ if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
+ printk("qcam: bad EOF\n");
+ } else {
+ if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
+ printk("qcam: bad EOF\n");
+ }
}
qcam_write_data(q, 0);
@@ -829,19 +878,24 @@ static int __init cqcam_init (void)
return parport_register_driver(&cqcam_driver);
}
-MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
-MODULE_DESCRIPTION(BANNER);
-MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method \n\
-probe=<0|1|2> # for camera detection method");
-MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i");
-MODULE_PARM(probe, "i");
-
static void __exit cqcam_cleanup (void)
{
unsigned int i;
+
for (i = 0; i < num_cams; i++)
close_cqcam(qcams[i]);
+
+ parport_unregister_driver(&cqcam_driver);
}
+MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
+MODULE_DESCRIPTION(BANNER);
+MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
+probe=<0|1|2> for camera detection method\n\
+force_rgb=<0|1> for RGB data format (default BGR)");
+MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i");
+MODULE_PARM(probe, "i");
+MODULE_PARM(force_rgb, "i");
+
module_init(cqcam_init);
module_exit(cqcam_cleanup);
diff --git a/drivers/char/joystick/joy-amiga.c b/drivers/char/joystick/joy-amiga.c
index 5e3198f7024207..8c0ba6923a99fe 100644
--- a/drivers/char/joystick/joy-amiga.c
+++ b/drivers/char/joystick/joy-amiga.c
@@ -78,26 +78,6 @@ static int js_am_read(void *info, int **axes, int **buttons)
}
/*
- * js_am_open() is a callback from the file open routine.
- */
-
-static int js_am_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_am_close() is a callback from the file release routine.
- */
-
-static int js_am_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_am_init_corr() initializes correction values of
* Amiga joysticks.
*/
@@ -139,7 +119,7 @@ int __init js_am_init(void)
if (js_am[i]) {
js_am_port = js_register_port(js_am_port, &i, 1, sizeof(int), js_am_read);
printk(KERN_INFO "js%d: Amiga joystick at joy%ddat\n",
- js_register_device(js_am_port, 0, 2, 1, "Amiga joystick", js_am_open, js_am_close), i);
+ js_register_device(js_am_port, 0, 2, 1, "Amiga joystick", THIS_MODULE, NULL, NULL), i);
js_am_init_corr(js_am_port->corr);
}
if (js_am_port) return 0;
diff --git a/drivers/char/joystick/joy-analog.c b/drivers/char/joystick/joy-analog.c
index a4a7b9849c4ab3..f73ee8ded76a2f 100644
--- a/drivers/char/joystick/joy-analog.c
+++ b/drivers/char/joystick/joy-analog.c
@@ -153,26 +153,6 @@ static int js_an_read(void *xinfo, int **axes, int **buttons)
}
/*
- * js_an_open() is a callback from the file open routine.
- */
-
-static int js_an_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_an_close() is a callback from the file release routine.
- */
-
-static int js_an_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_an_calibrate_timer() calibrates the timer and computes loop
* and timeout values for a joystick port.
*/
@@ -248,7 +228,7 @@ static struct js_port __init *js_an_probe(int io, int mask0, int mask1, struct j
for (i = 0; i < numdev; i++)
printk(KERN_INFO "js%d: %s at %#x ["TIME_NAME" timer, %d %sHz clock, %d ns res]\n",
js_register_device(port, i, js_an_axes(i, &ax->an), js_an_buttons(i, &ax->an),
- js_an_name(i, &ax->an), js_an_open, js_an_close),
+ js_an_name(i, &ax->an), THIS_MODULE, NULL, NULL),
js_an_name(i, &ax->an),
ax->io,
ax->speed > 10000 ? (ax->speed + 800) / 1000 : ax->speed,
diff --git a/drivers/char/joystick/joy-assassin.c b/drivers/char/joystick/joy-assassin.c
index b76ba8e36b77ab..469c6c8cee51df 100644
--- a/drivers/char/joystick/joy-assassin.c
+++ b/drivers/char/joystick/joy-assassin.c
@@ -177,26 +177,6 @@ static int js_as_read(void *xinfo, int **axes, int **buttons)
}
/*
- * js_as_open() is a callback from the file open routine.
- */
-
-static int js_as_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_as_close() is a callback from the file release routine.
- */
-
-static int js_as_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_as_pxl_init_corr() initializes the correction values for
* the Panther XL.
*/
@@ -317,13 +297,13 @@ static struct js_port __init *js_as_probe(int io, int mask0, int mask1, struct j
if (info->mode == JS_AS_MODE_PXL) {
printk(KERN_INFO "js%d: MadCatz Panther XL at %#x\n",
- js_register_device(port, 0, 9, 9, "MadCatz Panther XL", js_as_open, js_as_close),
+ js_register_device(port, 0, 9, 9, "MadCatz Panther XL", THIS_MODULE, NULL, NULL),
info->io);
js_as_read(port->info, port->axes, port->buttons);
js_as_pxl_init_corr(port->corr, port->axes);
if (info->an.axes[0] < 254) {
printk(KERN_INFO "js%d: Analog rudder on MadCatz Panther XL\n",
- js_register_device(port, 1, 1, 0, "Analog rudder", js_as_open, js_as_close));
+ js_register_device(port, 1, 1, 0, "Analog rudder", THIS_MODULE, NULL, NULL));
info->rudder = 1;
port->axes[1][0] = info->an.axes[0];
js_as_rudder_init_corr(port->corr, port->axes);
@@ -339,7 +319,7 @@ static struct js_port __init *js_as_probe(int io, int mask0, int mask1, struct j
}
printk(KERN_INFO "js%d: %s at %#x\n",
- js_register_device(port, 0, 2, 3, name, js_as_open, js_as_close),
+ js_register_device(port, 0, 2, 3, name, THIS_MODULE, NULL, NULL),
name, info->io);
js_as_as_init_corr(port->corr);
@@ -354,7 +334,7 @@ static struct js_port __init *js_as_probe(int io, int mask0, int mask1, struct j
for (i = 0; i < numdev; i++)
printk(KERN_INFO "js%d: %s on %s\n",
js_register_device(port, i + 1, js_an_axes(i, &info->an), js_an_buttons(i, &info->an),
- js_an_name(i, &info->an), js_as_open, js_as_close),
+ js_an_name(i, &info->an), THIS_MODULE, NULL, NULL),
js_an_name(i, &info->an), name);
js_an_decode(&info->an, port->axes + 1, port->buttons + 1);
diff --git a/drivers/char/joystick/joy-console.c b/drivers/char/joystick/joy-console.c
index 58392f83917662..e56da540adde54 100644
--- a/drivers/char/joystick/joy-console.c
+++ b/drivers/char/joystick/joy-console.c
@@ -501,6 +501,7 @@ static int js_console_read(void *xinfo, int **axes, int **buttons)
/*
* open callback: claim parport.
+ * FIXME: if parport_claim() will sleep we can get into mess.
*/
int js_console_open(struct js_dev *dev)
@@ -754,7 +755,7 @@ static struct js_port __init *js_console_probe(int *config, struct js_port *port
for (i = 0; i < info.pads; i++) {
printk(KERN_INFO "js%d: %s on %s\n",
- js_register_device(port, i, axes[i], buttons[i], name[i], js_console_open, js_console_close),
+ js_register_device(port, i, axes[i], buttons[i], name[i], NULL, js_console_open, js_console_close),
name[i], info.port->port->name);
js_console_init_corr(axes[i], type[i], port->corr[i]);
diff --git a/drivers/char/joystick/joy-creative.c b/drivers/char/joystick/joy-creative.c
index 8faec5f82e9078..b5ae4c0197d539 100644
--- a/drivers/char/joystick/joy-creative.c
+++ b/drivers/char/joystick/joy-creative.c
@@ -151,26 +151,6 @@ static int js_cr_read(void *xinfo, int **axes, int **buttons)
}
/*
- * js_cr_open() is a callback from the file open routine.
- */
-
-static int js_cr_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_cr_close() is a callback from the file release routine.
- */
-
-static int js_cr_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_cr_init_corr() initializes correction values of
* Blaster gamepads.
*/
@@ -243,7 +223,7 @@ static struct js_port __init *js_cr_probe(int io, struct js_port *port)
if (info.mode[i]) {
printk(KERN_INFO "js%d: %s at %#x\n",
js_register_device(port, i, axes[info.mode[i]], buttons[info.mode[i]],
- names[info.mode[i]], js_cr_open, js_cr_close),
+ names[info.mode[i]], THIS_MODULE, NULL, NULL),
names[info.mode[i]], io);
js_cr_init_corr(info.mode[i], port->corr[i]);
}
diff --git a/drivers/char/joystick/joy-db9.c b/drivers/char/joystick/joy-db9.c
index d5b6565eebadbe..41169b12c027f6 100644
--- a/drivers/char/joystick/joy-db9.c
+++ b/drivers/char/joystick/joy-db9.c
@@ -244,6 +244,7 @@ static int js_db9_read(void *xinfo, int **axes, int **buttons)
/*
* open callback: claim parport.
+ * FIXME: race possible.
*/
int js_db9_open(struct js_dev *dev)
@@ -364,7 +365,7 @@ static struct js_port __init *js_db9_probe(int *config, struct js_port *port)
for (i = 0; i < 1 + (info.mode == JS_MULTI_0802_2); i++) {
printk(KERN_INFO "js%d: %s on %s\n",
- js_register_device(port, i, 2, buttons[info.mode], name[info.mode], js_db9_open, js_db9_close),
+ js_register_device(port, i, 2, buttons[info.mode], name[info.mode], NULL, js_db9_open, js_db9_close),
name[info.mode], info.port->port->name);
js_db9_init_corr(port->corr[i]);
diff --git a/drivers/char/joystick/joy-gravis.c b/drivers/char/joystick/joy-gravis.c
index 3863d161f4cf00..84a6def1667c73 100644
--- a/drivers/char/joystick/joy-gravis.c
+++ b/drivers/char/joystick/joy-gravis.c
@@ -231,26 +231,6 @@ static int js_gr_read(void *xinfo, int **axes, int **buttons)
}
/*
- * js_gr_open() is a callback from the file open routine.
- */
-
-static int js_gr_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_gr_close() is a callback from the file release routine.
- */
-
-static int js_gr_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_gr_init_corr() initializes correction values of
* GrIP joysticks.
*/
@@ -359,7 +339,7 @@ static struct js_port __init *js_gr_probe(int io, struct js_port *port)
if (info.mode[i]) {
printk(KERN_INFO "js%d: %s at %#x\n",
js_register_device(port, i, axes[info.mode[i]], buttons[info.mode[i]],
- names[info.mode[i]], js_gr_open, js_gr_close),
+ names[info.mode[i]], THIS_MODULE, NULL, NULL),
names[info.mode[i]], io);
js_gr_init_corr(info.mode[i], port->corr[i]);
}
diff --git a/drivers/char/joystick/joy-lightning.c b/drivers/char/joystick/joy-lightning.c
index 038d33a3c1ca1c..26c18856a16811 100644
--- a/drivers/char/joystick/joy-lightning.c
+++ b/drivers/char/joystick/joy-lightning.c
@@ -208,26 +208,6 @@ static void js_l4_calibrate(struct js_l4_info *info)
js_l4_setcal(info->port, cal);
}
-
-/*
- * js_l4_open() is a callback from the file open routine.
- */
-
-static int js_l4_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_l4_close() is a callback from the file release routine.
- */
-
-static int js_l4_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
/*
* js_l4_probe() probes for joysticks on the L4 cards.
@@ -262,7 +242,7 @@ static struct js_port __init *js_l4_probe(unsigned char *cards, int l4port, int
for (i = 0; i < numdev; i++)
printk(KERN_INFO "js%d: %s on L4 port %d\n",
js_register_device(port, i, js_an_axes(i, &info->an), js_an_buttons(i, &info->an),
- js_an_name(i, &info->an), js_l4_open, js_l4_close),
+ js_an_name(i, &info->an), THIS_MODULE, NULL, NULL),
js_an_name(i, &info->an), info->port);
js_l4_calibrate(info);
diff --git a/drivers/char/joystick/joy-logitech.c b/drivers/char/joystick/joy-logitech.c
index daea89c8bd3f17..6044cbfb0ffd49 100644
--- a/drivers/char/joystick/joy-logitech.c
+++ b/drivers/char/joystick/joy-logitech.c
@@ -276,26 +276,6 @@ static int js_lt_read(void *xinfo, int **axes, int **buttons)
}
/*
- * js_lt_open() is a callback from the file open routine.
- */
-
-static int js_lt_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_lt_close() is a callback from the file release routine.
- */
-
-static int js_lt_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_lt_init_digital() sends a trigger & delay sequence
* to reset and initialize a Logitech joystick into digital mode.
*/
@@ -482,7 +462,7 @@ static struct js_port __init *js_lt_probe(int io, struct js_port *port)
printk(KERN_INFO "js%d: %s [%s] at %#x\n",
js_register_device(port, i,
info->axes10[i] + info->axes8[i] + ((info->hats[i] + (info->pad[i] >= 0)) << 1),
- info->buttons[i], name, js_lt_open, js_lt_close), name, info->name[i], io);
+ info->buttons[i], name, THIS_MODULE, NULL, NULL), name, info->name[i], io);
}
mdelay(JS_LT_INIT_DELAY);
diff --git a/drivers/char/joystick/joy-magellan.c b/drivers/char/joystick/joy-magellan.c
index 3a54d157eaca76..cb14646e85673e 100644
--- a/drivers/char/joystick/joy-magellan.c
+++ b/drivers/char/joystick/joy-magellan.c
@@ -232,7 +232,6 @@ static int js_mag_open(struct js_dev *jd)
{
struct js_mag_info *info = jd->port->info;
info->used++;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -247,7 +246,6 @@ static int js_mag_close(struct js_dev *jd)
js_unregister_device(jd->port->devs[0]);
js_mag_port = js_unregister_port(jd->port);
}
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -298,7 +296,7 @@ static int js_mag_ldisc_open(struct tty_struct *tty)
}
printk(KERN_INFO "js%d: Magellan [%s] on %s%d\n",
- js_register_device(js_mag_port, 0, 6, 9, "Magellan", js_mag_open, js_mag_close),
+ js_register_device(js_mag_port, 0, 6, 9, "Magellan", THIS_MODULE, js_mag_open, js_mag_close),
info->name, tty->driver.name, MINOR(tty->device) - tty->driver.minor_start);
diff --git a/drivers/char/joystick/joy-pci.c b/drivers/char/joystick/joy-pci.c
index ae49fd8e1129b0..fbf9125e5115c1 100644
--- a/drivers/char/joystick/joy-pci.c
+++ b/drivers/char/joystick/joy-pci.c
@@ -150,26 +150,6 @@ static int js_pci_read(void *xinfo, int **axes, int **buttons)
return 0;
}
-
-/*
- * js_pci_open() is a callback from the file open routine.
- */
-
-static int js_pci_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_pci_close() is a callback from the file release routine.
- */
-
-static int js_pci_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
static struct js_port * __init js_pci_probe(struct js_port *port, int type, int number,
struct pci_dev *pci_p, struct js_pci_data *data)
@@ -212,7 +192,7 @@ static struct js_port * __init js_pci_probe(struct js_port *port, int type, int
for (i = 0; i < numdev; i++)
printk(KERN_WARNING "js%d: %s on %s #%d\n",
js_register_device(port, i, js_an_axes(i, &info->an), js_an_buttons(i, &info->an),
- js_an_name(i, &info->an), js_pci_open, js_pci_close), js_an_name(i, &info->an), data->name, number);
+ js_an_name(i, &info->an), THIS_MODULE, NULL, NULL), js_an_name(i, &info->an), data->name, number);
js_pci_read(info, port->axes, port->buttons);
js_an_init_corr(&info->an, port->axes, port->corr, 32);
@@ -243,7 +223,8 @@ int __init js_pci_init(void)
for (i = 0; js_pci_data[i].vendor; i++)
for (j = 0; (pci_p = pci_find_device(js_pci_data[i].vendor, js_pci_data[i].model, pci_p)); j++)
- js_pci_port = js_pci_probe(js_pci_port, i, j, pci_p, js_pci_data + i);
+ if (pci_enable_device(pci_p) == 0)
+ js_pci_port = js_pci_probe(js_pci_port, i, j, pci_p, js_pci_data + i);
if (!js_pci_port) {
#ifdef MODULE
diff --git a/drivers/char/joystick/joy-sidewinder.c b/drivers/char/joystick/joy-sidewinder.c
index 37d276ba1ca8c5..da11598f4a41d3 100644
--- a/drivers/char/joystick/joy-sidewinder.c
+++ b/drivers/char/joystick/joy-sidewinder.c
@@ -476,26 +476,6 @@ static int js_sw_read(void *xinfo, int **axes, int **buttons)
}
/*
- * js_sw_open() is a callback from the file open routine.
- */
-
-static int js_sw_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_sw_close() is a callback from the file release routine.
- */
-
-static int js_sw_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_sw_init_corr() initializes the correction values for
* SideWinders.
*/
@@ -810,7 +790,7 @@ static struct js_port __init *js_sw_probe(int io, struct js_port *port)
for (i = 0; i < info.number; i++)
printk(KERN_INFO "js%d: %s%s at %#x [%d ns res %d-bit id %d data %d]\n",
js_register_device(port, i, axes[info.type], buttons[info.type],
- names[info.type], js_sw_open, js_sw_close), names[info.type], comment, io,
+ names[info.type], THIS_MODULE, NULL, NULL), names[info.type], comment, io,
1000000 / speed, m, j, k);
js_sw_init_corr(axes[info.type], info.type, info.number, port->corr);
diff --git a/drivers/char/joystick/joy-spaceball.c b/drivers/char/joystick/joy-spaceball.c
index 874eb526881dd5..3ace1364215486 100644
--- a/drivers/char/joystick/joy-spaceball.c
+++ b/drivers/char/joystick/joy-spaceball.c
@@ -152,7 +152,6 @@ static int js_sball_open(struct js_dev *jd)
{
struct js_sball_info *info = jd->port->info;
info->used++;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -167,7 +166,6 @@ static int js_sball_close(struct js_dev *jd)
js_unregister_device(jd->port->devs[0]);
js_sball_port = js_unregister_port(jd->port);
}
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -219,7 +217,7 @@ static int js_sball_ldisc_open(struct tty_struct *tty)
info->port = js_sball_port;
tty->disc_data = info;
- info->js = js_register_device(js_sball_port, 0, 6, 12, "SpaceBall 4000 FLX", js_sball_open, js_sball_close);
+ info->js = js_register_device(js_sball_port, 0, 6, 12, "SpaceBall 4000 FLX", THIS_MODULE, js_sball_open, js_sball_close);
js_sball_init_corr(js_sball_port->corr);
diff --git a/drivers/char/joystick/joy-spaceorb.c b/drivers/char/joystick/joy-spaceorb.c
index a154bcdd5539a7..0fb4f4c7128a73 100644
--- a/drivers/char/joystick/joy-spaceorb.c
+++ b/drivers/char/joystick/joy-spaceorb.c
@@ -152,7 +152,6 @@ static int js_orb_open(struct js_dev *jd)
{
struct js_orb_info *info = jd->port->info;
info->used++;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -167,7 +166,6 @@ static int js_orb_close(struct js_dev *jd)
js_unregister_device(jd->port->devs[0]);
js_orb_port = js_unregister_port(jd->port);
}
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -211,7 +209,7 @@ static int js_orb_ldisc_open(struct tty_struct *tty)
info->port = js_orb_port;
tty->disc_data = info;
- info->js = js_register_device(js_orb_port, 0, 6, 7, "SpaceOrb 360", js_orb_open, js_orb_close);
+ info->js = js_register_device(js_orb_port, 0, 6, 7, "SpaceOrb 360", THIS_MODULE, js_orb_open, js_orb_close);
js_orb_init_corr(js_orb_port->corr);
diff --git a/drivers/char/joystick/joy-thrustmaster.c b/drivers/char/joystick/joy-thrustmaster.c
index 4cd3de23ff296f..56e043a592ece8 100644
--- a/drivers/char/joystick/joy-thrustmaster.c
+++ b/drivers/char/joystick/joy-thrustmaster.c
@@ -163,26 +163,6 @@ static int js_tm_read(void *xinfo, int **axes, int **buttons)
}
/*
- * js_tm_open() is a callback from the file open routine.
- */
-
-static int js_tm_open(struct js_dev *jd)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * js_tm_close() is a callback from the file release routine.
- */
-
-static int js_tm_close(struct js_dev *jd)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
* js_tm_init_corr() initializes the correction values for
* ThrustMaster joysticks.
*/
@@ -261,7 +241,7 @@ static struct js_port __init *js_tm_probe(int io, struct js_port *port)
request_region(io, 1, "joystick (thrustmaster)");
port = js_register_port(port, &info, 1, sizeof(struct js_tm_info), js_tm_read);
printk(KERN_INFO "js%d: %s revision %d at %#x\n",
- js_register_device(port, 0, a, b, name, js_tm_open, js_tm_close), name, data[JS_TM_BYTE_REV], io);
+ js_register_device(port, 0, a, b, name, THIS_MODULE, NULL, NULL), name, data[JS_TM_BYTE_REV], io);
js_tm_init_corr(a, info.mode, port->axes, port->corr);
return port;
diff --git a/drivers/char/joystick/joy-turbografx.c b/drivers/char/joystick/joy-turbografx.c
index 0211ea6f9ae627..c138a99d02eaa7 100644
--- a/drivers/char/joystick/joy-turbografx.c
+++ b/drivers/char/joystick/joy-turbografx.c
@@ -101,6 +101,7 @@ static int js_tg_read(void *xinfo, int **axes, int **buttons)
/*
* open callback: claim parport.
+ * FIXME: race possible here.
*/
int js_tg_open(struct js_dev *dev)
@@ -205,7 +206,7 @@ static struct js_port __init *js_tg_probe(int *config, struct js_port *port)
for (i = 0; i < 7; i++)
if (config[i+1] > 0 && config[i+1] < 6) {
printk(KERN_INFO "js%d: Multisystem joystick on %s\n",
- js_register_device(port, i, 2, config[i+1], "Multisystem joystick", js_tg_open, js_tg_close),
+ js_register_device(port, i, 2, config[i+1], "Multisystem joystick", NULL, js_tg_open, js_tg_close),
info->port->port->name);
info->sticks |= (1 << i);
}
diff --git a/drivers/char/joystick/joy-warrior.c b/drivers/char/joystick/joy-warrior.c
index 8737d1cc92865e..23269985993080 100644
--- a/drivers/char/joystick/joy-warrior.c
+++ b/drivers/char/joystick/joy-warrior.c
@@ -123,7 +123,6 @@ static int js_war_open(struct js_dev *jd)
{
struct js_war_info *info = jd->port->info;
info->used++;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -138,7 +137,6 @@ static int js_war_close(struct js_dev *jd)
js_unregister_device(jd->port->devs[0]);
js_war_port = js_unregister_port(jd->port);
}
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -200,7 +198,7 @@ static int js_war_ldisc_open(struct tty_struct *tty)
tty->disc_data = info;
printk(KERN_INFO "js%d: WingMan Warrior on %s%d\n",
- js_register_device(js_war_port, 0, 6, 4, "WingMan Warrior", js_war_open, js_war_close),
+ js_register_device(js_war_port, 0, 6, 4, "WingMan Warrior", THIS_MODULE, js_war_open, js_war_close),
tty->driver.name, MINOR(tty->device) - tty->driver.minor_start);
js_war_init_corr(js_war_port->corr);
diff --git a/drivers/char/joystick/joystick.c b/drivers/char/joystick/joystick.c
index 1b156538ed333a..81ec240ba4c43e 100644
--- a/drivers/char/joystick/joystick.c
+++ b/drivers/char/joystick/joystick.c
@@ -511,15 +511,21 @@ static int js_open(struct inode *inode, struct file *file)
if (!jd) return -ENODEV;
- if ((result = jd->open(jd)))
+ if (jd->owner)
+ __MOD_INC_USE_COUNT(jd->owner);
+ if (jd->open && (result = jd->open(jd))) {
+ if (jd->owner)
+ __MOD_DEC_USE_COUNT(jd->owner);
return result;
-
- MOD_INC_USE_COUNT;
+ }
new = kmalloc(sizeof(struct js_list), GFP_KERNEL);
if (!new) {
- jd->close(jd);
- MOD_DEC_USE_COUNT;
+ if (jd->close)
+ jd->close(jd);
+ if (jd->owner)
+ __MOD_DEC_USE_COUNT(jd->owner);
+
return -ENOMEM;
}
@@ -577,9 +583,10 @@ static int js_release(struct inode *inode, struct file *file)
if (!--js_use_count) del_timer(&js_timer);
- jd->close(jd);
-
- MOD_DEC_USE_COUNT;
+ if (jd->close)
+ jd->close(jd);
+ if (jd->owner)
+ __MOD_DEC_USE_COUNT(jd->owner);
return 0;
}
@@ -659,8 +666,9 @@ extern struct file_operations js_fops;
static devfs_handle_t devfs_handle = NULL;
-int js_register_device(struct js_port *port, int number, int axes, int buttons, char *name,
- js_ops_func open, js_ops_func close)
+int js_register_device(struct js_port *port, int number, int axes,
+ int buttons, char *name, struct module *owner,
+ js_ops_func open, js_ops_func close)
{
struct js_dev **ptrd = &js_dev;
struct js_dev *curd;
@@ -681,6 +689,7 @@ int js_register_device(struct js_port *port, int number, int axes, int buttons,
curd->port = port;
curd->open = open;
curd->close = close;
+ curd->owner = owner;
init_waitqueue_head(&curd->wait);
diff --git a/drivers/char/pcmcia/serial_cb.c b/drivers/char/pcmcia/serial_cb.c
index 457b2f647bbe34..86bb70f57a24ec 100644
--- a/drivers/char/pcmcia/serial_cb.c
+++ b/drivers/char/pcmcia/serial_cb.c
@@ -92,6 +92,7 @@ static dev_node_t *serial_attach(dev_locator_t *loc)
if (loc->bus != LOC_PCI) goto err_out;
pdev = pci_find_slot (loc->b.pci.bus, loc->b.pci.devfn);
if (!pdev) goto err_out;
+ if (pci_enable_device(pdev)) goto err_out;
printk(KERN_INFO "serial_attach(bus %d, fn %d)\n", pdev->bus->number, pdev->devfn);
io = pci_resource_start (pdev, 0);
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index f4c84ac9575ca8..19224560203661 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -83,6 +83,63 @@ struct pp_struct {
/* ROUND_UP macro from fs/select.c */
#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
+struct pp_port_list_struct {
+ struct parport *port;
+ struct pp_port_list_struct *next;
+};
+static struct pp_port_list_struct *pp_port_list;
+static DECLARE_MUTEX(pp_port_list_lock);
+
+/* pp_attach and pp_detach are for keeping a list of currently
+ * available ports, held under a mutex. We do this rather than
+ * using parport_enumerate because it stops a load of races.
+ */
+
+static void pp_attach (struct parport *port)
+{
+ struct pp_port_list_struct *add;
+
+ add = kmalloc (sizeof (struct pp_port_list_struct), GFP_KERNEL);
+ if (!add) {
+ printk (KERN_WARNING CHRDEV ": memory squeeze\n");
+ return;
+ }
+
+ add->next = pp_port_list;
+ down (&pp_port_list_lock);
+ pp_port_list = add;
+ up (&pp_port_list_lock);
+}
+
+static void pp_detach (struct parport *port)
+{
+ struct pp_port_list_struct *del;
+
+ down (&pp_port_list_lock);
+ del = pp_port_list;
+ if (del->port == port)
+ pp_port_list = del->next;
+ else {
+ struct pp_port_list_struct *prev;
+ do {
+ prev = del;
+ del = del->next;
+ } while (del && del->port != port);
+ if (del)
+ prev->next = del->next;
+ }
+ up (&pp_port_list_lock);
+
+ if (del)
+ kfree (del);
+}
+
+static struct parport_driver ppdev_driver = {
+ name: CHRDEV,
+ attach: pp_attach,
+ detach: pp_detach
+};
+
static inline void pp_enable_irq (struct pp_struct *pp)
{
struct parport *port = pp->pdev->port;
@@ -216,7 +273,7 @@ static void pp_irq (int irq, void * private, struct pt_regs * unused)
static int register_device (int minor, struct pp_struct *pp)
{
- struct parport * port;
+ struct pp_port_list_struct *ports;
struct pardevice * pdev = NULL;
char *name;
int fl;
@@ -226,20 +283,24 @@ static int register_device (int minor, struct pp_struct *pp)
return -ENOMEM;
sprintf (name, CHRDEV "%x", minor);
- port = parport_enumerate (); /* FIXME: use attach/detach */
- while (port && port->number != minor)
- port = port->next;
+ down (&pp_port_list_lock);
+ ports = pp_port_list;
+ while (ports && ports->port->number != minor)
+ ports = ports->next;
+ if (ports->port) {
+ fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
+ pdev = parport_register_device (ports->port, name, NULL,
+ NULL, pp_irq, fl, pp);
+ }
+ up (&pp_port_list_lock);
- if (!port) {
+ if (!ports->port) {
printk (KERN_WARNING "%s: no associated port!\n", name);
kfree (name);
return -ENXIO;
}
- fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
- pdev = parport_register_device (port, name, NULL, NULL, pp_irq, fl,
- pp);
if (!pdev) {
printk (KERN_WARNING "%s: failed to register device!\n", name);
@@ -507,13 +568,9 @@ static int pp_open (struct inode * inode, struct file * file)
if (minor >= PARPORT_MAX)
return -ENXIO;
- MOD_INC_USE_COUNT;
-
pp = kmalloc (sizeof (struct pp_struct), GFP_KERNEL);
- if (!pp) {
- MOD_DEC_USE_COUNT;
+ if (!pp)
return -ENOMEM;
- }
pp->state.mode = IEEE1284_MODE_COMPAT;
pp->state.phase = init_phase (pp->state.mode);
@@ -565,7 +622,6 @@ static int pp_release (struct inode * inode, struct file * file)
kfree (pp);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -596,6 +652,10 @@ static devfs_handle_t devfs_handle = NULL;
static int __init ppdev_init (void)
{
+ if (parport_register_driver (&ppdev_driver)) {
+ printk (KERN_WARNING CHRDEV ": unable to register driver\n");
+ return -EIO;
+ }
if (devfs_register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
PP_MAJOR);
@@ -616,6 +676,7 @@ static void __exit ppdev_cleanup (void)
/* Clean up all parport stuff */
devfs_unregister (devfs_handle);
devfs_unregister_chrdev (PP_MAJOR, CHRDEV);
+ parport_unregister_driver (&ppdev_driver);
}
module_init(ppdev_init);
diff --git a/drivers/char/scan_keyb.c b/drivers/char/scan_keyb.c
new file mode 100644
index 00000000000000..5bc1bdff9b942a
--- /dev/null
+++ b/drivers/char/scan_keyb.c
@@ -0,0 +1,127 @@
+/*
+ * $Id: scan_keyb.c,v 1.1 2000/06/10 21:45:30 yaegashi Exp $
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * Generic scan keyboard driver
+ */
+
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
+#include <linux/kbd_kern.h>
+
+struct scan_keyboard {
+ struct scan_keyboard *next;
+ void (*scan)(unsigned char *buffer);
+ const unsigned char *table;
+ unsigned char *s0, *s1;
+ int length;
+};
+
+static struct scan_keyboard *keyboards=NULL;
+static struct tq_struct task_scan_kbd;
+
+static void check_kbd(const unsigned char *table,
+ unsigned char *new, unsigned char *old, int length)
+{
+ int need_tasklet_schedule=0;
+ unsigned char xor, bit;
+
+ while(length-->0) {
+ if((xor=*new^*old)==0) {
+ table+=8;
+ }
+ else {
+ for(bit=0x80; bit!=0; bit>>=1) {
+ if(xor&bit) {
+ handle_scancode(*table, !(*new&bit));
+ need_tasklet_schedule=1;
+ }
+ table++;
+ }
+ }
+ new++; old++;
+ }
+
+ if(need_tasklet_schedule)
+ tasklet_schedule(&keyboard_tasklet);
+}
+
+
+static void scan_kbd(void *dummy)
+{
+ struct scan_keyboard *kbd;
+
+ for(kbd=keyboards; kbd!=NULL; kbd=kbd->next) {
+ if(jiffies&1) {
+ kbd->scan(kbd->s0);
+ check_kbd(kbd->table, kbd->s0, kbd->s1, kbd->length);
+ }
+ else {
+ kbd->scan(kbd->s1);
+ check_kbd(kbd->table, kbd->s1, kbd->s0, kbd->length);
+ }
+
+ }
+ queue_task(&task_scan_kbd, &tq_timer);
+}
+
+
+int register_scan_keyboard(void (*scan)(unsigned char *buffer),
+ const unsigned char *table,
+ int length)
+{
+ struct scan_keyboard *kbd;
+
+ if((kbd=kmalloc(sizeof(struct scan_keyboard), GFP_KERNEL))==NULL)
+ goto error_out;
+
+ kbd->scan=scan;
+ kbd->table=table;
+ kbd->length=length;
+
+ kbd->s0=kbd->s1=NULL;
+ if((kbd->s0=kmalloc(length, GFP_KERNEL))==NULL)
+ goto error_out;
+ if((kbd->s1=kmalloc(length, GFP_KERNEL))==NULL)
+ goto error_out;
+
+ kbd->scan(kbd->s0);
+ kbd->scan(kbd->s1);
+
+ kbd->next=keyboards;
+ keyboards=kbd;
+
+ return 0;
+
+ error_mem_free:
+ if(kbd->s0)
+ kfree(kbd->s0);
+ if(kbd->s1)
+ kfree(kbd->s1);
+ kfree(kbd);
+
+ error_out:
+ return -ENOMEM;
+}
+
+
+void __init scan_kbd_init(void)
+{
+
+ task_scan_kbd.next=NULL;
+ task_scan_kbd.sync=0;
+ task_scan_kbd.routine=scan_kbd;
+ task_scan_kbd.data=NULL;
+ queue_task(&task_scan_kbd, &tq_timer);
+ printk(KERN_INFO "Generic scan keyboard driver initialized\n");
+}
diff --git a/drivers/char/scan_keyb.h b/drivers/char/scan_keyb.h
new file mode 100644
index 00000000000000..849b508706f109
--- /dev/null
+++ b/drivers/char/scan_keyb.h
@@ -0,0 +1,15 @@
+#ifndef __DRIVER_CHAR_SCAN_KEYB_H
+#define __DRIVER_CHAR_SCAN_KEYB_H
+/*
+ * $Id: scan_keyb.h,v 1.1 2000/06/10 21:45:30 yaegashi Exp $
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * Generic scan keyboard driver
+ */
+
+int register_scan_keyboard(void (*scan)(unsigned char *buffer),
+ const unsigned char *table,
+ int length);
+
+void __init scan_kbd_init(void);
+
+#endif
diff --git a/drivers/char/sh-sci.c b/drivers/char/sh-sci.c
index 05bfcb607c7153..b51e91557a0416 100644
--- a/drivers/char/sh-sci.c
+++ b/drivers/char/sh-sci.c
@@ -5,6 +5,7 @@
* SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
* Copyright (C) 1999, 2000 Niibe Yutaka
* Copyright (C) 2000 Sugioka Toshinobu
+ * Modified to support multiple serial ports. Stuart Menefy (May 2000).
*
* TTY code is based on sx.c (Specialix SX driver) by:
*
@@ -31,7 +32,9 @@
#include <linux/malloc.h>
#include <linux/init.h>
#include <linux/delay.h>
+#ifdef CONFIG_SERIAL_CONSOLE
#include <linux/console.h>
+#endif
#include <asm/system.h>
#include <asm/io.h>
@@ -40,15 +43,23 @@
#include <asm/bitops.h>
#include <linux/generic_serial.h>
-#include "sh-sci.h"
#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
static void gdb_detach(void);
+static int in_gdb = 1;
+#define IN_GDB in_gdb
#endif
+#include "sh-sci.h"
-struct sci_port sci_ports[1];
+#ifdef CONFIG_SERIAL_CONSOLE
+static struct console sercons;
+static struct sci_port* sercons_port;
+static int sercons_baud;
+#endif
/* Function prototypes */
+static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag);
+static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag);
static void sci_disable_tx_interrupts(void *ptr);
static void sci_enable_tx_interrupts(void *ptr);
static void sci_disable_rx_interrupts(void *ptr);
@@ -63,9 +74,10 @@ static int sci_init_drivers(void);
static struct tty_driver sci_driver, sci_callout_driver;
-#define SCI_NPORTS 1
+static struct sci_port sci_ports[SCI_NPORTS] = SCI_INIT;
static struct tty_struct *sci_table[SCI_NPORTS] = { NULL, };
-static struct termios *sci_termios[2]; /* nomal, locked */
+static struct termios *sci_termios[SCI_NPORTS];
+static struct termios *sci_termios_locked[SCI_NPORTS];
int sci_refcount;
int sci_debug = 0;
@@ -88,6 +100,63 @@ static struct real_driver sci_real_driver = {
NULL
};
+#if defined(SCI_ONLY) || defined(SCI_AND_SCIF)
+static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag)
+{
+}
+#endif
+
+#if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
+#if defined(__sh3__)
+/* For SH7709, SH7709A, SH7729 */
+static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag)
+{
+ unsigned int fcr_val = 0;
+
+ {
+ unsigned short data;
+
+ /* We need to set SCPCR to enable RTS/CTS */
+ data = ctrl_inw(SCPCR);
+ /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
+ ctrl_outw(data&0x0fcf, SCPCR);
+ }
+ if (cflag & CRTSCTS)
+ fcr_val |= SCFCR_MCE;
+ else {
+ unsigned short data;
+
+ /* We need to set SCPCR to enable RTS/CTS */
+ data = ctrl_inw(SCPCR);
+ /* Clear out SCP7MD1,0, SCP4MD1,0,
+ Set SCP6MD1,0 = {01} (output) */
+ ctrl_outw((data&0x0fcf)|0x1000, SCPCR);
+
+ data = ctrl_inb(SCPDR);
+ /* Set /RTS2 (bit6) = 0 */
+ ctrl_outb(data&0xbf, SCPDR);
+ }
+ sci_out(port, SCFCR, fcr_val);
+}
+
+#else
+
+/* For SH7750 */
+static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag)
+{
+ unsigned int fcr_val = 0;
+
+ if (cflag & CRTSCTS) {
+ fcr_val |= SCFCR_MCE;
+ } else {
+ ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */
+ }
+ sci_out(port, SCFCR, fcr_val);
+}
+
+#endif
+#endif /* SCIF_ONLY || SCI_AND_SCIF */
+
static void sci_setsignals(struct sci_port *port, int dtr, int rts)
{
/* This routine is used for seting signals of: DTR, DCD, CTS/RTS */
@@ -112,11 +181,11 @@ static int sci_getsignals(struct sci_port *port)
*/
}
-static void sci_set_baud(struct sci_port *port)
+static void sci_set_baud(struct sci_port *port, int baud)
{
int t;
- switch (port->gs.baud) {
+ switch (baud) {
case 0:
t = -1;
break;
@@ -136,7 +205,7 @@ static void sci_set_baud(struct sci_port *port)
t = BPS_38400;
break;
default:
- printk(KERN_INFO "sci: unsupported baud rate: %d, use 115200 instead.\n", port->gs.baud);
+ printk(KERN_INFO "sci: unsupported baud rate: %d, use 115200 instead.\n", baud);
case 115200:
t = BPS_115200;
break;
@@ -145,93 +214,57 @@ static void sci_set_baud(struct sci_port *port)
if (t > 0) {
sci_setsignals (port, 1, -1);
if(t >= 256) {
- ctrl_out((ctrl_in(SCSMR) & ~3) | 1, SCSMR);
+ sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
t >>= 2;
}
- ctrl_outb(t, SCBRR);
- ctrl_outw(0xa400, RFCR); /* Refresh counter clear */
- while (ctrl_inw(RFCR) < WAIT_RFCR_COUNTER)
- ;
+ sci_out(port, SCBRR, t);
+ udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
} else {
sci_setsignals (port, 0, -1);
}
}
-static void sci_set_termios_cflag(struct sci_port *port)
+static void sci_set_termios_cflag(struct sci_port *port, int cflag, int baud)
{
- unsigned short status;
- unsigned short smr_val;
-#if defined(CONFIG_SH_SCIF_SERIAL)
- unsigned short fcr_val=6; /* TFRST=1, RFRST=1 */
-#endif
+ unsigned int status;
+ unsigned int smr_val;
do
- status = ctrl_in(SC_SR);
- while (!(status & SCI_TEND));
+ status = sci_in(port, SCxSR);
+ while (!(status & SCxSR_TEND(port)));
- port->old_cflag = port->gs.tty->termios->c_cflag;
+ sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
- ctrl_out(0x00, SCSCR); /* TE=0, RE=0, CKE1=0 */
-#if defined(CONFIG_SH_SCIF_SERIAL)
- ctrl_out(fcr_val, SCFCR);
- fcr_val = 0;
-#endif
+ if (port->type == PORT_SCIF) {
+ sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+ }
- smr_val = ctrl_in(SCSMR) & 3;
- if ((port->gs.tty->termios->c_cflag & CSIZE) == CS7)
+ smr_val = sci_in(port, SCSMR) & 3;
+ if ((cflag & CSIZE) == CS7)
smr_val |= 0x40;
- if (C_PARENB(port->gs.tty))
+ if (cflag & PARENB)
smr_val |= 0x20;
- if (C_PARODD(port->gs.tty))
+ if (cflag & PARODD)
smr_val |= 0x10;
- if (C_CSTOPB(port->gs.tty))
+ if (cflag & CSTOPB)
smr_val |= 0x08;
- ctrl_out(smr_val, SCSMR);
-
-#if defined(CONFIG_SH_SCIF_SERIAL)
-#if defined(__sh3__)
- { /* For SH7709, SH7709A, SH7729 */
- unsigned short data;
-
- /* We need to set SCPCR to enable RTS/CTS */
- data = ctrl_inw(SCPCR);
- /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
- ctrl_outw(data&0x0fcf, SCPCR);
- }
-#endif
- if (C_CRTSCTS(port->gs.tty))
- fcr_val |= 0x08;
- else {
-#if defined(__sh3__)
- unsigned short data;
-
- /* We need to set SCPCR to enable RTS/CTS */
- data = ctrl_inw(SCPCR);
- /* Clear out SCP7MD1,0, SCP4MD1,0,
- Set SCP6MD1,0 = {01} (output) */
- ctrl_outw((data&0x0fcf)|0x1000, SCPCR);
+ sci_out(port, SCSMR, smr_val);
- data = ctrl_inb(SCPDR);
- /* Set /RTS2 (bit6) = 0 */
- ctrl_outb(data&0xbf, SCPDR);
-#elif defined(__SH4__)
- ctrl_outw(0x0080, SCSPTR); /* Set RTS = 1 */
-#endif
- }
- ctrl_out(fcr_val, SCFCR);
-#endif
+ port->init_pins(port, cflag);
- sci_set_baud(port);
- ctrl_out(SCSCR_INIT, SCSCR); /* TIE=0,RIE=0,TE=1,RE=1 */
- sci_enable_rx_interrupts(port);
+ sci_set_baud(port, baud);
+ sci_out(port, SCSCR, SCSCR_INIT(port));
}
static int sci_set_real_termios(void *ptr)
{
struct sci_port *port = ptr;
- if (port->old_cflag != port->gs.tty->termios->c_cflag)
- sci_set_termios_cflag(port);
+ if (port->old_cflag != port->gs.tty->termios->c_cflag) {
+ port->old_cflag = port->gs.tty->termios->c_cflag;
+ sci_set_termios_cflag(port, port->old_cflag, port->gs.baud);
+ sci_enable_rx_interrupts(port);
+ }
/* Tell line discipline whether we will do input cooking */
if (I_OTHER(port->gs.tty))
@@ -265,27 +298,27 @@ static void sci_transmit_chars(struct sci_port *port)
unsigned short ctrl;
unsigned char c;
- status = ctrl_in(SC_SR);
- if (!(status & SCI_TD_E)) {
+ status = sci_in(port, SCxSR);
+ if (!(status & SCxSR_TDxE(port))) {
save_and_cli(flags);
- ctrl = ctrl_in(SCSCR);
+ ctrl = sci_in(port, SCSCR);
if (port->gs.xmit_cnt == 0) {
ctrl &= ~SCI_CTRL_FLAGS_TIE;
port->gs.flags &= ~GS_TX_INTEN;
} else
ctrl |= SCI_CTRL_FLAGS_TIE;
- ctrl_out(ctrl, SCSCR);
+ sci_out(port, SCSCR, ctrl);
restore_flags(flags);
return;
}
while (1) {
count = port->gs.xmit_cnt;
-#if defined(CONFIG_SH_SCIF_SERIAL)
- txroom = 16 - (ctrl_inw(SCFDR)>>8);
-#else
- txroom = (ctrl_in(SC_SR)&SCI_TD_E)?1:0;
-#endif
+ if (port->type == PORT_SCIF) {
+ txroom = 16 - (sci_in(port, SCFDR)>>8);
+ } else {
+ txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
+ }
if (count > txroom)
count = txroom;
@@ -299,9 +332,9 @@ static void sci_transmit_chars(struct sci_port *port)
for (i=0; i<count; i++) {
c = port->gs.xmit_buf[port->gs.xmit_tail + i];
- ctrl_outb(c, SC_TDR);
+ sci_out(port, SCxTDR, c);
}
- ctrl_out(SCI_TD_E_CLEAR, SC_SR);
+ sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
/* Update the kernel buffer end */
port->gs.xmit_tail = (port->gs.xmit_tail + count) & (SERIAL_XMIT_SIZE-1);
@@ -319,18 +352,18 @@ static void sci_transmit_chars(struct sci_port *port)
}
save_and_cli(flags);
- ctrl = ctrl_in(SCSCR);
+ ctrl = sci_in(port, SCSCR);
if (port->gs.xmit_cnt == 0) {
ctrl &= ~SCI_CTRL_FLAGS_TIE;
port->gs.flags &= ~GS_TX_INTEN;
} else {
-#if defined(CONFIG_SH_SCIF_SERIAL)
- ctrl_in(SC_SR); /* Dummy read */
- ctrl_out(SCI_TD_E_CLEAR, SC_SR);
-#endif
+ if (port->type == PORT_SCIF) {
+ sci_in(port, SCxSR); /* Dummy read */
+ sci_out(port, SCxSR, SCIF_TDFE);
+ }
ctrl |= SCI_CTRL_FLAGS_TIE;
}
- ctrl_out(ctrl, SCSCR);
+ sci_out(port, SCSCR, ctrl);
restore_flags(flags);
}
@@ -341,17 +374,17 @@ static inline void sci_receive_chars(struct sci_port *port)
int copied=0;
unsigned short status;
- status = ctrl_in(SC_SR);
- if (!(status & SCI_RD_F))
+ status = sci_in(port, SCxSR);
+ if (!(status & SCxSR_RDxF(port)))
return;
tty = port->gs.tty;
while (1) {
-#if defined(CONFIG_SH_SCIF_SERIAL)
- count = ctrl_inw(SCFDR)&0x001f;
-#else
- count = (ctrl_in(SC_SR)&SCI_RD_F)?1:0;
-#endif
+ if (port->type == PORT_SCIF) {
+ count = sci_in(port, SCFDR)&0x001f;
+ } else {
+ count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
+ }
/* Don't copy more bytes than there is room for in the buffer */
if (tty->flip.count + count > TTY_FLIPBUF_SIZE)
@@ -362,9 +395,9 @@ static inline void sci_receive_chars(struct sci_port *port)
break;
for (i=0; i<count; i++)
- tty->flip.char_buf_ptr[i] = ctrl_inb(SC_RDR);
- ctrl_in(SC_SR); /* dummy read */
- ctrl_out(SCI_RDRF_CLEAR, SC_SR);
+ tty->flip.char_buf_ptr[i] = sci_in(port, SCxRDR);
+ sci_in(port, SCxSR); /* dummy read */
+ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
memset(tty->flip.flag_buf_ptr, TTY_NORMAL, count);
@@ -384,16 +417,13 @@ static inline void sci_receive_chars(struct sci_port *port)
static void sci_rx_interrupt(int irq, void *ptr, struct pt_regs *regs)
{
struct sci_port *port = ptr;
- unsigned long flags;
if (port->gs.flags & GS_ACTIVE)
if (!(port->gs.flags & SCI_RX_THROTTLE)) {
sci_receive_chars(port);
return;
}
- save_and_cli(flags);
- ctrl_out(ctrl_in(SCSCR) & ~SCI_CTRL_FLAGS_RIE, SCSCR);
- restore_flags(flags);
+ sci_disable_rx_interrupts(port);
}
static void sci_tx_interrupt(int irq, void *ptr, struct pt_regs *regs)
@@ -403,19 +433,17 @@ static void sci_tx_interrupt(int irq, void *ptr, struct pt_regs *regs)
if (port->gs.flags & GS_ACTIVE)
sci_transmit_chars(port);
else {
- unsigned long flags;
-
- save_and_cli(flags);
- ctrl_out(ctrl_in(SCSCR) & ~SCI_CTRL_FLAGS_TIE, SCSCR);
- restore_flags(flags);
+ sci_disable_tx_interrupts(port);
}
}
static void sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
{
+ struct sci_port *port = ptr;
+
/* Handle errors */
- if (ctrl_in(SC_SR) & SCI_ERRORS)
- ctrl_out(SCI_ERROR_CLEAR, SC_SR);
+ if (sci_in(port, SCxSR) & SCxSR_ERRORS(port))
+ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
/* Kick the transmission */
sci_tx_interrupt(irq, ptr, regs);
@@ -428,14 +456,15 @@ static void sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
static void sci_disable_tx_interrupts(void *ptr)
{
+ struct sci_port *port = ptr;
unsigned long flags;
unsigned short ctrl;
/* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
save_and_cli(flags);
- ctrl = ctrl_in(SCSCR);
+ ctrl = sci_in(port, SCSCR);
ctrl &= ~SCI_CTRL_FLAGS_TIE;
- ctrl_out(ctrl, SCSCR);
+ sci_out(port, SCSCR, ctrl);
restore_flags(flags);
}
@@ -443,34 +472,36 @@ static void sci_enable_tx_interrupts(void *ptr)
{
struct sci_port *port = ptr;
- disable_irq(SCI_TXI_IRQ);
+ disable_irq(port->irqs[SCIx_TXI_IRQ]);
sci_transmit_chars(port);
- enable_irq(SCI_TXI_IRQ);
+ enable_irq(port->irqs[SCIx_TXI_IRQ]);
}
static void sci_disable_rx_interrupts(void * ptr)
{
+ struct sci_port *port = ptr;
unsigned long flags;
unsigned short ctrl;
/* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
save_and_cli(flags);
- ctrl = ctrl_in(SCSCR);
+ ctrl = sci_in(port, SCSCR);
ctrl &= ~SCI_CTRL_FLAGS_RIE;
- ctrl_out(ctrl, SCSCR);
+ sci_out(port, SCSCR, ctrl);
restore_flags(flags);
}
static void sci_enable_rx_interrupts(void * ptr)
{
+ struct sci_port *port = ptr;
unsigned long flags;
unsigned short ctrl;
/* Set RIE (Receive Interrupt Enable) bit in SCSCR */
save_and_cli(flags);
- ctrl = ctrl_in(SCSCR);
+ ctrl = sci_in(port, SCSCR);
ctrl |= SCI_CTRL_FLAGS_RIE;
- ctrl_out(ctrl, SCSCR);
+ sci_out(port, SCSCR, ctrl);
restore_flags(flags);
}
@@ -482,11 +513,13 @@ static int sci_get_CD(void * ptr)
static int sci_chars_in_buffer(void * ptr)
{
-#if defined(CONFIG_SH_SCIF_SERIAL)
- return (ctrl_inw(SCFDR) >> 8) + ((ctrl_in(SC_SR) & SCI_TEND)? 0: 1);
-#else
- return (ctrl_in(SC_SR) & SCI_TEND)? 0: 1;
-#endif
+ struct sci_port *port = ptr;
+
+ if (port->type == PORT_SCIF) {
+ return (sci_in(port, SCFDR) >> 8) + ((sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1);
+ } else {
+ return (sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1;
+ }
}
static void sci_shutdown_port(void * ptr)
@@ -551,6 +584,15 @@ static int sci_open(struct tty_struct * tty, struct file * filp)
sci_set_real_termios(port);
}
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (sercons.cflag && sercons.index == line) {
+ tty->termios->c_cflag = sercons.cflag;
+ port->gs.baud = sercons_baud;
+ sercons.cflag = 0;
+ sci_set_real_termios(port);
+ }
+#endif
+
sci_enable_rx_interrupts(port);
port->gs.session = current->session;
@@ -665,6 +707,25 @@ static void sci_unthrottle(struct tty_struct * tty)
return;
}
+#ifdef CONFIG_PROC_FS
+static int sci_read_proc(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ int i;
+ struct sci_port *port;
+ int len = 0;
+
+ len += sprintf(page, "serinfo:1.0\n");
+ for (i = 0; i < SCI_NPORTS && len < 4000; i++) {
+ port = &sci_ports[i];
+ len += sprintf(page+len, "%d: uart:%s address: %08x\n", i,
+ (port->type == PORT_SCI) ? "SCI" : "SCIF",
+ port->base);
+ }
+ return len;
+}
+#endif
+
/* ********************************************************************** *
* Here are the initialization routines. *
* ********************************************************************** */
@@ -678,20 +739,19 @@ static int sci_init_drivers(void)
sci_driver.magic = TTY_DRIVER_MAGIC;
sci_driver.driver_name = "serial";
sci_driver.name = "ttyS";
- sci_driver.major = TTY_MAJOR;
+ sci_driver.major = SCI_MAJOR;
sci_driver.minor_start = SCI_MINOR_START;
- sci_driver.num = 1;
+ sci_driver.num = SCI_NPORTS;
sci_driver.type = TTY_DRIVER_TYPE_SERIAL;
sci_driver.subtype = SERIAL_TYPE_NORMAL;
sci_driver.init_termios = tty_std_termios;
sci_driver.init_termios.c_cflag =
- B115200 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS;
+ B9600 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS;
sci_driver.flags = TTY_DRIVER_REAL_RAW;
sci_driver.refcount = &sci_refcount;
sci_driver.table = sci_table;
- sci_driver.termios = &sci_termios[0];
- sci_driver.termios_locked = &sci_termios[1];
- sci_termios[0] = sci_termios[1] = NULL;
+ sci_driver.termios = sci_termios;
+ sci_driver.termios_locked = sci_termios_locked;
sci_driver.open = sci_open;
sci_driver.close = gs_close;
@@ -708,11 +768,15 @@ static int sci_init_drivers(void)
sci_driver.stop = gs_stop;
sci_driver.start = gs_start;
sci_driver.hangup = gs_hangup;
+#ifdef CONFIG_PROC_FS
+ sci_driver.read_proc = sci_read_proc;
+#endif
sci_callout_driver = sci_driver;
- sci_callout_driver.name = "cua";
- sci_callout_driver.major = TTYAUX_MAJOR;
+ sci_callout_driver.name = "cusc";
+ sci_callout_driver.major = SCI_MAJOR + 1;
sci_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+ sci_callout_driver.read_proc = NULL;
if ((error = tty_register_driver(&sci_driver))) {
printk(KERN_ERR "sci: Couldn't register SCI driver, error = %d\n",
@@ -726,16 +790,17 @@ static int sci_init_drivers(void)
return 1;
}
- port = &sci_ports[0];
- port->gs.callout_termios = tty_std_termios;
- port->gs.normal_termios = tty_std_termios;
- port->gs.magic = SCI_MAGIC;
- port->gs.close_delay = HZ/2;
- port->gs.closing_wait = 30 * HZ;
- port->gs.rd = &sci_real_driver;
- init_waitqueue_head(&port->gs.open_wait);
- init_waitqueue_head(&port->gs.close_wait);
- port->old_cflag = 0;
+ for (port = &sci_ports[0]; port < &sci_ports[SCI_NPORTS]; port++) {
+ port->gs.callout_termios = sci_callout_driver.init_termios;
+ port->gs.normal_termios = sci_driver.init_termios;
+ port->gs.magic = SCI_MAGIC;
+ port->gs.close_delay = HZ/2;
+ port->gs.closing_wait = 30 * HZ;
+ port->gs.rd = &sci_real_driver;
+ init_waitqueue_head(&port->gs.open_wait);
+ init_waitqueue_head(&port->gs.close_wait);
+ port->old_cflag = 0;
+ }
return 0;
}
@@ -744,26 +809,20 @@ int __init sci_init(void)
{
struct sci_port *port;
int i;
-
- for (i=SCI_ERI_IRQ; i<SCI_IRQ_END; i++)
- set_ipr_data(i, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-
- port = &sci_ports[0];
-
- if (request_irq(SCI_ERI_IRQ, sci_er_interrupt, SA_INTERRUPT,
- "serial", port)) {
- printk(KERN_ERR "sci: Cannot allocate error irq.\n");
- return -ENODEV;
- }
- if (request_irq(SCI_RXI_IRQ, sci_rx_interrupt, SA_INTERRUPT,
- "serial", port)) {
- printk(KERN_ERR "sci: Cannot allocate rx irq.\n");
- return -ENODEV;
- }
- if (request_irq(SCI_TXI_IRQ, sci_tx_interrupt, SA_INTERRUPT,
- "serial", port)) {
- printk(KERN_ERR "sci: Cannot allocate tx irq.\n");
- return -ENODEV;
+ void (*handlers[3])(int irq, void *ptr, struct pt_regs *regs) = {
+ sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt
+ };
+
+ for (port = &sci_ports[0]; port < &sci_ports[SCI_NPORTS]; port++) {
+ for (i=0; i<3; i++) {
+ set_ipr_data(port->irqs[i], port->intc_addr, port->intc_pos, SCI_PRIORITY);
+
+ if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
+ "serial", port)) {
+ printk(KERN_ERR "sci: Cannot allocate irq.\n");
+ return -ENODEV;
+ }
+ }
}
/* XXX: How about BRI interrupt?? */
@@ -802,121 +861,21 @@ void cleanup_module(void)
* ------------------------------------------------------------
*/
-static inline void put_char(char c)
-{
- unsigned long flags;
- unsigned short status;
-
- save_and_cli(flags);
-
- do
- status = ctrl_in(SC_SR);
- while (!(status & SCI_TD_E));
-
- ctrl_outb(c, SC_TDR);
- ctrl_in(SC_SR); /* Dummy read */
- ctrl_out(SCI_TD_E_CLEAR, SC_SR);
-
- restore_flags(flags);
-}
-
#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
-static int in_gdb = 1;
-static inline void handle_error(void)
-{ /* Clear error flags */
- ctrl_out(SCI_ERROR_CLEAR, SC_SR);
-}
-
-static inline int get_char(void)
-{
- unsigned long flags;
- unsigned short status;
- int c;
-
- save_and_cli(flags);
- do {
- status = ctrl_in(SC_SR);
- if (status & SCI_ERRORS) {
- handle_error();
- continue;
- }
- } while (!(status & SCI_RD_F));
- c = ctrl_inb(SC_RDR);
- ctrl_in(SC_SR); /* Dummy read */
- ctrl_out(SCI_RDRF_CLEAR, SC_SR);
- restore_flags(flags);
-
- return c;
-}
-
-/* Taken from sh-stub.c of GDB 4.18 */
-static const char hexchars[] = "0123456789abcdef";
-static char highhex(int x)
-{
- return hexchars[(x >> 4) & 0xf];
-}
-
-static char lowhex(int x)
-{
- return hexchars[x & 0xf];
-}
-
-static void gdb_detach(void)
+static void __init gdb_detach(void)
{
asm volatile("trapa #0xff");
if (in_gdb == 1) {
in_gdb = 0;
- get_char();
- put_char('\r');
- put_char('\n');
+ get_char(sercons_port);
+ put_char(sercons_port, '\r');
+ put_char(sercons_port, '\n');
}
}
#endif
-/* send the packet in buffer. The host get's one chance to read it.
- This routine does not wait for a positive acknowledge. */
-
-static void
-put_string(const char *buffer, int count)
-{
- int i;
- const unsigned char *p = buffer;
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
- int checksum;
-
-if (in_gdb) {
- /* $<packet info>#<checksum>. */
- do {
- unsigned char c;
- put_char('$');
- put_char('O'); /* 'O'utput to console */
- checksum = 'O';
-
- for (i=0; i<count; i++) { /* Don't use run length encoding */
- int h, l;
-
- c = *p++;
- h = highhex(c);
- l = lowhex(c);
- put_char(h);
- put_char(l);
- checksum += h + l;
- }
- put_char('#');
- put_char(highhex(checksum));
- put_char(lowhex(checksum));
- } while (get_char() != '+');
-} else
-#endif
- for (i=0; i<count; i++) {
- if (*p == 10)
- put_char('\r');
- put_char(*p++);
- }
-}
-
/*
* Print a string to the serial port trying not to disturb
* any possible real use of the port...
@@ -924,7 +883,7 @@ if (in_gdb) {
static void serial_console_write(struct console *co, const char *s,
unsigned count)
{
- put_string(s, count);
+ put_string(sercons_port, s, count);
}
/*
@@ -938,7 +897,7 @@ static int serial_console_wait_key(struct console *co)
static kdev_t serial_console_device(struct console *c)
{
- return MKDEV(TTY_MAJOR, SCI_MINOR_START + c->index);
+ return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index);
}
/*
@@ -949,12 +908,14 @@ static kdev_t serial_console_device(struct console *c)
*/
static int __init serial_console_setup(struct console *co, char *options)
{
- int baud = 115200;
+ int baud = 9600;
int bits = 8;
int parity = 'n';
int cflag = CREAD | HUPCL | CLOCAL;
char *s;
+ sercons_port = &sci_ports[co->index];
+
if (options) {
baud = simple_strtoul(options, NULL, 10);
s = options;
@@ -983,6 +944,7 @@ static int __init serial_console_setup(struct console *co, char *options)
case 9600:
default:
cflag |= B9600;
+ baud = 9600;
break;
}
switch (bits) {
@@ -1002,14 +964,18 @@ static int __init serial_console_setup(struct console *co, char *options)
cflag |= PARENB;
break;
}
+
co->cflag = cflag;
+ sercons_baud = baud;
+
+ sci_set_termios_cflag(sercons_port, cflag, baud);
+ sercons_port->old_cflag = cflag;
- /* XXX: set baud, char, and parity here. */
return 0;
}
static struct console sercons = {
- "ttyS",
+ "ttySC",
serial_console_write,
NULL,
serial_console_device,
diff --git a/drivers/char/sh-sci.h b/drivers/char/sh-sci.h
index f501951ec718f7..ddf5712a5ddee7 100644
--- a/drivers/char/sh-sci.h
+++ b/drivers/char/sh-sci.h
@@ -5,148 +5,135 @@
* SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
* Copyright (C) 1999, 2000 Niibe Yutaka
* Copyright (C) 2000 Greg Banks
+ * Modified to support multiple serial ports. Stuart Menefy (May 2000).
*
*/
#include <linux/config.h>
-#if defined(CONFIG_SH_SCI_SERIAL)
-#if defined(__sh3__)
-#define SCSMR (volatile unsigned char *)0xfffffe80
-#define SCBRR 0xfffffe82
-#define SCSCR (volatile unsigned char *)0xfffffe84
-#define SC_TDR 0xfffffe86
-#define SC_SR (volatile unsigned char *)0xfffffe88
-#define SC_RDR 0xfffffe8a
-#define SCSPTR 0xffffff7c
-#elif defined(__SH4__)
-#define SCSMR (volatile unsigned char *)0xffe00000
-#define SCBRR 0xffe00004
-#define SCSCR (volatile unsigned char *)0xffe00008
-#define SC_TDR 0xffe0000c
-#define SC_SR (volatile unsigned char *)0xffe00010
-#define SC_RDR 0xffe00014
-#define SCSPTR 0xffe0001c
+/* Values for sci_port->type */
+#define PORT_SCI 0
+#define PORT_SCIF 1
+
+/* Offsets into the sci_port->irqs array */
+#define SCIx_ERI_IRQ 0
+#define SCIx_RXI_IRQ 1
+#define SCIx_TXI_IRQ 2
+
+/* ERI, RXI, TXI, INTC reg, INTC pos */
+#define SCI_IRQS { 23, 24, 25 }, INTC_IPRB, 1
+#define SH3_SCIF_IRQS { 56, 57, 59 }, INTC_IPRE, 1
+#define SH4_SCIF_IRQS { 40, 41, 43 }, INTC_IPRC, 1
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7708)
+# define SCI_NPORTS 1
+# define SCI_INIT { \
+ { {}, PORT_SCI, 0xfffffe80, SCI_IRQS, sci_init_pins_sci } \
+}
+# define SCSPTR 0xffffff7c /* 8 bit */
+# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
+# define SCI_ONLY
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+# define SCI_NPORTS 2
+# define SCI_INIT { \
+ { {}, PORT_SCI, 0xfffffe80, SCI_IRQS, sci_init_pins_sci }, \
+ { {}, PORT_SCIF, 0xA4000150, SH3_SCIF_IRQS, sci_init_pins_scif } \
+}
+# define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */
+# define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */
+# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
+# define SCI_AND_SCIF
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750)
+# define SCI_NPORTS 2
+# define SCI_INIT { \
+ { {}, PORT_SCI, 0xffe00000, SCI_IRQS, sci_init_pins_sci }, \
+ { {}, PORT_SCIF, 0xFFE80000, SH4_SCIF_IRQS, sci_init_pins_scif } \
+}
+# define SCSPTR1 0xffe0001c /* 8 bit SCI */
+# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
+# define SCLSR2 0xFFE80024 /* 16 bit SCIF */
+# define SCSCR_INIT(port) (((port)->type == PORT_SCI) ? \
+ 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \
+ 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ )
+# define SCI_AND_SCIF
+#else
+# error CPU subtype not defined
#endif
-#define SCSCR_INIT 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
+/* SCSCR */
+#define SCI_CTRL_FLAGS_TIE 0x80 /* all */
+#define SCI_CTRL_FLAGS_RIE 0x40 /* all */
+#define SCI_CTRL_FLAGS_TE 0x20 /* all */
+#define SCI_CTRL_FLAGS_RE 0x10 /* all */
+/* SCI_CTRL_FLAGS_REIE 0x08 * 7750 SCIF */
+/* SCI_CTRL_FLAGS_MPIE 0x08 * 7708 SCI, 7709 SCI, 7750 SCI */
+/* SCI_CTRL_FLAGS_TEIE 0x04 * 7708 SCI, 7709 SCI, 7750 SCI */
+/* SCI_CTRL_FLAGS_CKE1 0x02 * all */
+/* SCI_CTRL_FLAGS_CKE0 0x01 * 7708 SCI, 7709 SCI/SCIF, 7750 SCI */
-#define SCI_TD_E 0x80
-#define SCI_RD_F 0x40
-#define SCI_ORER 0x20
-#define SCI_FER 0x10
-#define SCI_PER 0x08
-#define SCI_TEND 0x04
+/* SCxSR SCI */
+#define SCI_TDRE 0x80 /* 7708 SCI, 7709 SCI, 7750 SCI */
+#define SCI_RDRF 0x40 /* 7708 SCI, 7709 SCI, 7750 SCI */
+#define SCI_ORER 0x20 /* 7708 SCI, 7709 SCI, 7750 SCI */
+#define SCI_FER 0x10 /* 7708 SCI, 7709 SCI, 7750 SCI */
+#define SCI_PER 0x08 /* 7708 SCI, 7709 SCI, 7750 SCI */
+#define SCI_TEND 0x04 /* 7708 SCI, 7709 SCI, 7750 SCI */
+/* SCI_MPB 0x02 * 7708 SCI, 7709 SCI, 7750 SCI */
+/* SCI_MPBT 0x01 * 7708 SCI, 7709 SCI, 7750 SCI */
#define SCI_ERRORS ( SCI_PER | SCI_FER | SCI_ORER)
-#define SCI_TD_E_CLEAR 0x78
-#define SCI_RDRF_CLEAR 0xbc
-#define SCI_ERROR_CLEAR 0xc4
-
-#define SCI_CTRL_FLAGS_TIE 0x80
-#define SCI_CTRL_FLAGS_RIE 0x40
-#define SCI_CTRL_FLAGS_TE 0x20
-#define SCI_CTRL_FLAGS_RE 0x10
-/* TEIE=0x04 */
-#define SCI_CTRL_FLAGS_CKE1 0x02
-#define SCI_CTRL_FLAGS_CKE0 0x01
-
-#define SCI_ERI_IRQ 23
-#define SCI_RXI_IRQ 24
-#define SCI_TXI_IRQ 25
-#define SCI_TEI_IRQ 26
-#define SCI_IRQ_END 27
-
-#define SCI_IPR_ADDR INTC_IPRB
-#define SCI_IPR_POS 1
-#endif
-
-#if defined(CONFIG_SH_SCIF_SERIAL)
-#if defined(__sh3__)
-#define SCSMR (volatile unsigned char *)0xA4000150
-#define SCBRR 0xA4000152
-#define SCSCR (volatile unsigned char *)0xA4000154
-#define SC_TDR 0xA4000156
-#define SC_SR (volatile unsigned short *)0xA4000158
-#define SC_RDR 0xA400015A
-#define SCFCR (volatile unsigned char *)0xA400015C
-#define SCFDR 0xA400015E
-
-#undef SCSPTR /* SH7709 doesn't have SCSPTR */
-#define SCPCR 0xA4000116 /* Instead, it has SCPCR and SCPDR */
-#define SCPDR 0xA4000136
-#undef SCLSR
-
-#define SCSCR_INIT 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
- /* 0x33 when external clock is used */
-#define SCI_IPR_ADDR INTC_IPRE
-#define SCI_IPR_POS 1
-
-#elif defined(__SH4__)
-#define SCSMR (volatile unsigned short *)0xFFE80000
-#define SCBRR 0xFFE80004
-#define SCSCR (volatile unsigned short *)0xFFE80008
-#define SC_TDR 0xFFE8000C
-#define SC_SR (volatile unsigned short *)0xFFE80010
-#define SC_RDR 0xFFE80014
-#define SCFCR (volatile unsigned short *)0xFFE80018
-#define SCFDR 0xFFE8001C
-#define SCSPTR 0xFFE80020
-#define SCLSR 0xFFE80024
-
-#define SCSCR_INIT 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
-#define SCI_IPR_ADDR INTC_IPRC
-#define SCI_IPR_POS 1
-#endif
+/* SCxSR SCIF */
+#define SCIF_ER 0x0080 /* 7709 SCIF, 7750 SCIF */
+#define SCIF_TEND 0x0040 /* 7709 SCIF, 7750 SCIF */
+#define SCIF_TDFE 0x0020 /* 7709 SCIF, 7750 SCIF */
+#define SCIF_BRK 0x0010 /* 7709 SCIF, 7750 SCIF */
+#define SCIF_FER 0x0008 /* 7709 SCIF, 7750 SCIF */
+#define SCIF_PER 0x0004 /* 7709 SCIF, 7750 SCIF */
+#define SCIF_RDF 0x0002 /* 7709 SCIF, 7750 SCIF */
+#define SCIF_DR 0x0001 /* 7709 SCIF, 7750 SCIF */
-#define SCI_ER 0x0080
-#define SCI_TEND 0x0040
-#define SCI_TD_E 0x0020
-#define SCI_BRK 0x0010
-#define SCI_FER 0x0008
-#define SCI_PER 0x0004
-#define SCI_RD_F 0x0002
-#define SCI_DR 0x0001
-
-#define SCI_ERRORS ( SCI_PER | SCI_FER | SCI_ER | SCI_BRK)
-#define SCI_TD_E_CLEAR 0x00df
-#define SCI_TEND_CLEAR 0x00bf
-#define SCI_RDRF_CLEAR 0x00fc
-#define SCI_ERROR_CLEAR 0x0063
-
-#define SCI_CTRL_FLAGS_TIE 0x80
-#define SCI_CTRL_FLAGS_RIE 0x40
-#define SCI_CTRL_FLAGS_TE 0x20
-#define SCI_CTRL_FLAGS_RE 0x10
-#define SCI_CTRL_FLAGS_REIE 0x08
-#define SCI_CTRL_FLAGS_CKE1 0x02
-
-#if defined(__sh3__)
-#define SCI_ERI_IRQ 56
-#define SCI_RXI_IRQ 57
-#define SCI_BRI_IRQ 58
-#define SCI_TXI_IRQ 59
-#define SCI_IRQ_END 60
-#elif defined(__SH4__)
-#define SCI_ERI_IRQ 40
-#define SCI_RXI_IRQ 41
-#define SCI_BRI_IRQ 42
-#define SCI_TXI_IRQ 43
-#define SCI_IRQ_END 44
-#endif
-#endif
-
-#if defined(__sh3__)
-#define RFCR 0xffffff74
-#elif defined(__SH4__)
-#define RFCR 0xFF800028
+#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
+
+#if defined(SCI_ONLY)
+# define SCxSR_TEND(port) SCI_TEND
+# define SCxSR_ERRORS(port) SCI_ERRORS
+# define SCxSR_RDxF(port) SCI_RDRF
+# define SCxSR_TDxE(port) SCI_TDRE
+# define SCxSR_RDxF_CLEAR(port) 0xbc
+# define SCxSR_ERROR_CLEAR(port) 0xc4
+# define SCxSR_TDxE_CLEAR(port) 0x78
+#elif defined(SCIF_ONLY)
+# define SCxSR_TEND(port) SCIF_TEND
+# define SCxSR_ERRORS(port) SCIF_ERRORS
+# define SCxSR_RDxF(port) SCIF_RDF
+# define SCxSR_TDxE(port) SCIF_TDFE
+# define SCxSR_RDxF_CLEAR(port) 0x00fc
+# define SCxSR_ERROR_CLEAR(port) 0x0063
+# define SCxSR_TDxE_CLEAR(port) 0x00df
+#else
+# define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
+# define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
+# define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
+# define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)
+# define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc)
+# define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0063)
+# define SCxSR_TDxE_CLEAR(port) (((port)->type == PORT_SCI) ? 0x78 : 0x00df)
#endif
+/* SCFCR */
+#define SCFCR_RFRST 0x0002
+#define SCFCR_TFRST 0x0004
+#define SCFCR_MCE 0x0008
+
#define SCI_PRIORITY 3
-#define SCI_MINOR_START 64
+#define SCI_MAJOR 204
+#define SCI_MINOR_START 8
+
+/* Generic serial flags */
#define SCI_RX_THROTTLE 0x0000001
+/* generic serial tty */
#define O_OTHER(tty) \
((O_OLCUC(tty)) ||\
(O_ONLCR(tty)) ||\
@@ -173,10 +160,85 @@
struct sci_port {
struct gs_port gs;
+ int type;
+ unsigned int base;
+ unsigned char irqs[3]; /* ERI, RXI, TXI */
+ unsigned int intc_addr, intc_pos;
+ void (*init_pins)(struct sci_port* port, unsigned int cflag);
unsigned int old_cflag;
};
-#define WAIT_RFCR_COUNTER 200
+#define SCI_IN(size, offset) \
+ unsigned int addr = port->base + (offset); \
+ if ((size) == 8) { \
+ return ctrl_inb(addr); \
+ } else { \
+ return ctrl_inw(addr); \
+ }
+#define SCI_OUT(size, offset, value) \
+ unsigned int addr = port->base + (offset); \
+ if ((size) == 8) { \
+ ctrl_outb(value, addr); \
+ } else { \
+ ctrl_outw(value, addr); \
+ }
+
+#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
+ static inline unsigned int sci_##name##_in(struct sci_port* port) \
+ { \
+ if (port->type == PORT_SCI) { \
+ SCI_IN(sci_size, sci_offset) \
+ } else { \
+ SCI_IN(scif_size, scif_offset); \
+ } \
+ } \
+ static inline void sci_##name##_out(struct sci_port* port, unsigned int value) \
+ { \
+ if (port->type == PORT_SCI) { \
+ SCI_OUT(sci_size, sci_offset, value) \
+ } else { \
+ SCI_OUT(scif_size, scif_offset, value); \
+ } \
+ }
+
+#define CPU_SCIF_FNS(name, scif_offset, scif_size) \
+ static inline unsigned int sci_##name##_in(struct sci_port* port) \
+ { \
+ SCI_IN(scif_size, scif_offset); \
+ } \
+ static inline void sci_##name##_out(struct sci_port* port, unsigned int value) \
+ { \
+ SCI_OUT(scif_size, scif_offset, value); \
+ }
+
+#ifdef __sh3__
+#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
+ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size)
+#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
+#else
+#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
+ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
+#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
+#endif
+
+/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 */
+/* name off sz off sz off sz off sz */
+SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16)
+SCIx_FNS(SCBRR, 0x02, 8, 0x04, 8, 0x02, 8, 0x04, 8)
+SCIx_FNS(SCSCR, 0x04, 8, 0x08, 8, 0x04, 8, 0x08, 16)
+SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8)
+SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16)
+SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8)
+SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
+SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
+
+#define sci_in(port, reg) sci_##reg##_in(port)
+#define sci_out(port, reg, value) sci_##reg##_out(port, value)
+
/*
* Values for the BitRate Register (SCBRR)
@@ -191,22 +253,17 @@ struct sci_port {
* the SCSMR register would also need to be set to non-zero values.
*
* -- Greg Banks 27Feb2000
+ *
+ * Answer: The SCBRR register is only eight bits, and the value in
+ * it gets larger with lower baud rates. At around 2400 (depending on
+ * the peripherial module clock) you run out of bits. However the
+ * lower two bits of SCSMR allow the module clock to be divided down,
+ * scaling the value which is needed in SCBRR.
+ *
+ * -- Stuart Menefy - 23 May 2000
*/
-/*
- * XXX: Well, this is not relevant...
- * Should we have config option for peripheral clock?
- * Or we get the value from time.c.
- */
-#if defined(__sh3__)
-#if defined(CONFIG_CPU_SUBTYPE_SH7709)
-#define PCLK 33333333
-#else
-#define PCLK 14745600 /* Isn't it 15MHz? */
-#endif
-#elif defined(__SH4__)
-#define PCLK 33333333
-#endif
+#define PCLK (current_cpu_data.module_clock)
#define SCBRR_VALUE(bps) (PCLK/(32*bps)-1)
#define BPS_2400 SCBRR_VALUE(2400)
@@ -215,3 +272,107 @@ struct sci_port {
#define BPS_19200 SCBRR_VALUE(19200)
#define BPS_38400 SCBRR_VALUE(38400)
#define BPS_115200 SCBRR_VALUE(115200)
+
+#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+/* Taken from sh-stub.c of GDB 4.18 */
+static const char hexchars[] = "0123456789abcdef";
+
+static __inline__ char highhex(int x)
+{
+ return hexchars[(x >> 4) & 0xf];
+}
+
+static __inline__ char lowhex(int x)
+{
+ return hexchars[x & 0xf];
+}
+#endif
+
+static __inline__ void put_char(struct sci_port *port, char c)
+{
+ unsigned long flags;
+ unsigned short status;
+
+ save_and_cli(flags);
+
+ do
+ status = sci_in(port, SCxSR);
+ while (!(status & SCxSR_TDxE(port)));
+
+ sci_out(port, SCxTDR, c);
+ sci_in(port, SCxSR); /* Dummy read */
+ sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+
+ restore_flags(flags);
+}
+
+static __inline__ void handle_error(struct sci_port *port)
+{ /* Clear error flags */
+ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+}
+
+static __inline__ int get_char(struct sci_port *port)
+{
+ unsigned long flags;
+ unsigned short status;
+ int c;
+
+ save_and_cli(flags);
+ do {
+ status = sci_in(port, SCxSR);
+ if (status & SCxSR_ERRORS(port)) {
+ handle_error(port);
+ continue;
+ }
+ } while (!(status & SCxSR_RDxF(port)));
+ c = sci_in(port, SCxRDR);
+ sci_in(port, SCxSR); /* Dummy read */
+ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ restore_flags(flags);
+
+ return c;
+}
+
+/*
+ * Send the packet in buffer. The host get's one chance to read it.
+ * This routine does not wait for a positive acknowledge.
+ */
+
+static __inline__ void put_string(struct sci_port *port,
+ const char *buffer, int count)
+{
+ int i;
+ const unsigned char *p = buffer;
+#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+ int checksum;
+
+if (IN_GDB) {
+ /* $<packet info>#<checksum>. */
+ do {
+ unsigned char c;
+ put_char(port, '$');
+ put_char(port, 'O'); /* 'O'utput to console */
+ checksum = 'O';
+
+ for (i=0; i<count; i++) { /* Don't use run length encoding */
+ int h, l;
+
+ c = *p++;
+ h = highhex(c);
+ l = lowhex(c);
+ put_char(port, h);
+ put_char(port, l);
+ checksum += h + l;
+ }
+ put_char(port, '#');
+ put_char(port, highhex(checksum));
+ put_char(port, lowhex(checksum));
+ } while (get_char(port) != '+');
+} else
+#endif
+ for (i=0; i<count; i++) {
+ if (*p == 10)
+ put_char(port, '\r');
+ put_char(port, *p++);
+ }
+}
diff --git a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile
index f2ce588974d316..c89374f45517d4 100644
--- a/drivers/ieee1394/Makefile
+++ b/drivers/ieee1394/Makefile
@@ -25,15 +25,13 @@ O_OBJS :=
OX_OBJS :=
ifeq ($(CONFIG_IEEE1394),y)
-L_OBJS += ieee1394.o hosts.o highlevel.o csr.o
-O_TARGET = ieee1394.o
-O_OBJS += ieee1394_core.o ieee1394_transactions.o
-OX_OBJS += ieee1394_syms.o
+L_OBJS += ieee1394_core.o ieee1394_transactions.o hosts.o highlevel.o csr.o guid.o
+LX_OBJS += ieee1394_syms.o
else
ifeq ($(CONFIG_IEEE1394),m)
M_OBJS += ieee1394.o
O_TARGET = ieee1394.o
- O_OBJS += ieee1394_core.o ieee1394_transactions.o hosts.o highlevel.o csr.o
+ O_OBJS += ieee1394_core.o ieee1394_transactions.o hosts.o highlevel.o csr.o guid.o
OX_OBJS += ieee1394_syms.o
endif
endif
diff --git a/drivers/ieee1394/aic5800.c b/drivers/ieee1394/aic5800.c
index be65166848cc79..6cf3779d5ecc68 100644
--- a/drivers/ieee1394/aic5800.c
+++ b/drivers/ieee1394/aic5800.c
@@ -723,15 +723,18 @@ inline static void * quadquadalign(void *buf)
static int add_card(struct pci_dev *dev)
{
-#define FAIL(fmt, args...) \
+#define FAIL(fmt, args...) do {\
PRINT_G(KERN_ERR, fmt , ## args); \
num_of_cards--; \
remove_card(aic); \
- return 1;
+ return 1; } while (0)
struct aic5800 *aic; /* shortcut to currently handled device */
unsigned long page;
+ if (pci_enable_device(dev))
+ return 1;
+
if (num_of_cards == MAX_AIC5800_CARDS) {
PRINT_G(KERN_WARNING, "cannot handle more than %d cards. "
"Adjust MAX_AIC5800_CARDS in aic5800.h.",
diff --git a/drivers/ieee1394/guid.c b/drivers/ieee1394/guid.c
new file mode 100644
index 00000000000000..36ac332c588613
--- /dev/null
+++ b/drivers/ieee1394/guid.c
@@ -0,0 +1,226 @@
+/*
+ * IEEE 1394 for Linux
+ *
+ * GUID collection and management
+ *
+ * Copyright (C) 2000 Andreas E. Bombe
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h>
+#include <asm/atomic.h>
+
+#include "ieee1394_types.h"
+#include "ieee1394.h"
+#include "hosts.h"
+#include "ieee1394_transactions.h"
+#include "highlevel.h"
+#include "csr.h"
+
+
+static atomic_t outstanding_requests;
+
+static LIST_HEAD(guid_list);
+rwlock_t guid_lock = RW_LOCK_UNLOCKED;
+
+struct guid_entry {
+ struct list_head list;
+ atomic_t refcount;
+
+ u64 guid;
+
+ struct hpsb_host *host;
+ nodeid_t node_id;
+
+ atomic_t generation;
+};
+
+struct guid_req {
+ struct hpsb_packet *pkt;
+ struct tq_struct tq;
+};
+
+
+static struct guid_entry *create_guid_entry(void)
+{
+ struct guid_entry *ge;
+ unsigned long flags;
+
+ ge = kmalloc(sizeof(struct guid_entry), SLAB_ATOMIC);
+ if (!ge) return NULL;
+
+ INIT_LIST_HEAD(&ge->list);
+ atomic_set(&ge->refcount, 0);
+ ge->guid = (u64) -1;
+ ge->host = NULL;
+ ge->node_id = 0;
+ atomic_set(&ge->generation, -1);
+
+ write_lock_irqsave(&guid_lock, flags);
+ list_add_tail(&ge->list, &guid_list);
+ write_unlock_irqrestore(&guid_lock, flags);
+
+ return ge;
+}
+
+static struct guid_entry *find_entry(u64 guid)
+{
+ struct list_head *lh;
+ struct guid_entry *ge;
+
+ lh = guid_list.next;
+ while (lh != &guid_list) {
+ ge = list_entry(lh, struct guid_entry, list);
+ if (ge->guid == guid) return ge;
+ lh = lh->next;
+ }
+
+ return NULL;
+}
+
+static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid)
+{
+ struct guid_entry *ge;
+ unsigned long flags;
+
+ HPSB_DEBUG("node %d on host 0x%p has GUID 0x%08x%08x",
+ nodeid & NODE_MASK, host, (unsigned int)(guid >> 32),
+ (unsigned int)(guid & 0xffffffff));
+
+ read_lock_irqsave(&guid_lock, flags);
+ ge = find_entry(guid);
+ read_unlock_irqrestore(&guid_lock, flags);
+
+ if (!ge) ge = create_guid_entry();
+ if (!ge) return;
+
+ ge->host = host;
+ ge->node_id = nodeid;
+ ge->guid = guid;
+
+ atomic_set(&ge->generation, get_hpsb_generation());
+}
+
+static void pkt_complete(struct guid_req *req)
+{
+ struct hpsb_packet *pkt = req->pkt;
+ int rcode = (pkt->header[1] >> 12) & 0xf;
+
+ if (pkt->ack_code == ACK_PENDING && rcode == RCODE_COMPLETE) {
+ if (*(char *)pkt->data > 1) {
+ associate_guid(pkt->host, pkt->node_id,
+ ((u64)be32_to_cpu(pkt->data[3]) << 32)
+ | be32_to_cpu(pkt->data[4]));
+ } else {
+ HPSB_DEBUG("minimal ROM on node %d",
+ pkt->node_id & NODE_MASK);
+ }
+ } else {
+ HPSB_DEBUG("guid transaction error: ack %d, rcode %d",
+ pkt->ack_code, rcode);
+ }
+
+ free_tlabel(pkt->host, pkt->node_id, pkt->tlabel);
+ free_hpsb_packet(pkt);
+ kfree(req);
+
+ if (atomic_dec_and_test(&outstanding_requests)) {
+ /* FIXME: free unreferenced and inactive GUID entries. */
+ }
+}
+
+
+static void host_reset(struct hpsb_host *host)
+{
+ struct guid_req *greq;
+ struct hpsb_packet *pkt;
+ struct selfid *sid = (struct selfid *)host->topology_map;
+ int nodecount = host->node_count;
+ nodeid_t nodeid = LOCAL_BUS;
+
+ for (; nodecount; nodecount--, nodeid++, sid++) {
+ while (sid->extended) sid++;
+ if (!sid->link_active) continue;
+ if (nodeid == host->node_id) continue;
+
+ greq = kmalloc(sizeof(struct guid_req), SLAB_ATOMIC);
+ if (!greq) {
+ HPSB_ERR("out of memory in GUID processing");
+ return;
+ }
+
+ pkt = hpsb_make_readbpacket(host, nodeid,
+ CSR_REGISTER_BASE + CSR_CONFIG_ROM,
+ 20);
+ if (!pkt) {
+ kfree(greq);
+ HPSB_ERR("out of memory in GUID processing");
+ return;
+ }
+
+ greq->tq.next = NULL;
+ greq->tq.sync = 0;
+ greq->tq.routine = (void (*)(void*))pkt_complete;
+ greq->tq.data = greq;
+ greq->pkt = pkt;
+
+ queue_task(&greq->tq, &pkt->complete_tq);
+
+ if (!hpsb_send_packet(pkt)) {
+ free_tlabel(pkt->host, pkt->node_id, pkt->tlabel);
+ free_hpsb_packet(pkt);
+ kfree(greq);
+ HPSB_NOTICE("failed to send packet in GUID processing");
+ }
+
+ HPSB_INFO("GUID request sent to node %d", nodeid & NODE_MASK);
+ atomic_inc(&outstanding_requests);
+ }
+}
+
+
+struct guid_entry *hpsb_guid_get_handle(u64 guid)
+{
+ unsigned long flags;
+ struct guid_entry *ge;
+
+ read_lock_irqsave(&guid_lock, flags);
+ ge = find_entry(guid);
+ if (ge) atomic_inc(&ge->refcount);
+ read_unlock_irqrestore(&guid_lock, flags);
+
+ return ge;
+}
+
+struct hpsb_host *hpsb_guid_localhost(struct guid_entry *ge)
+{
+ if (atomic_read(&ge->generation) != get_hpsb_generation()) return NULL;
+ if (ge->node_id == ge->host->node_id) return ge->host;
+ return NULL;
+}
+
+int hpsb_guid_fill_packet(struct guid_entry *ge, struct hpsb_packet *pkt)
+{
+ if (atomic_read(&ge->generation) != get_hpsb_generation()) return 0;
+
+ pkt->host = ge->host;
+ pkt->node_id = ge->node_id;
+ pkt->generation = atomic_read(&ge->generation);
+ return 1;
+}
+
+
+static struct hpsb_highlevel_ops guid_ops = {
+ host_reset: host_reset,
+};
+
+void init_ieee1394_guid(void)
+{
+ atomic_set(&outstanding_requests, 0);
+
+ if (!hpsb_register_highlevel("GUID manager", &guid_ops)) {
+ HPSB_ERR("out of memory during ieee1394 initialization");
+ }
+}
diff --git a/drivers/ieee1394/guid.h b/drivers/ieee1394/guid.h
new file mode 100644
index 00000000000000..e3a87dda931d3e
--- /dev/null
+++ b/drivers/ieee1394/guid.h
@@ -0,0 +1,54 @@
+
+#ifndef _IEEE1394_GUID_H
+#define _IEEE1394_GUID_H
+
+
+/*
+ * General information: Finding out which GUID belongs to which node is done by
+ * sending packets and therefore waiting for the answers. Wherever it is
+ * mentioned that a node is inaccessible this could just as well mean that we
+ * just don't know yet (usually, bus reset handlers can't rely on GUIDs being
+ * associated with current nodes).
+ */
+
+struct guid_entry;
+typedef struct guid_entry *hpsb_guid_t;
+
+
+/*
+ * Returns a guid handle (which has its reference count incremented) or NULL if
+ * there is the GUID in question is not known of. Getting a valid handle does
+ * not mean that the node with this GUID is currently accessible (might not be
+ * plugged in or powered down).
+ */
+hpsb_guid_t hpsb_guid_get_handle(u64 guid);
+
+/*
+ * If the handle refers to a local host, this function will return the pointer
+ * to the hpsb_host structure. It will return NULL otherwise. Once you have
+ * established it is a local host, you can use that knowledge from then on (the
+ * GUID won't wander to an external node).
+ *
+ * Note that the local GUID currently isn't collected, so this will always
+ * return NULL.
+ */
+struct hpsb_host *hpsb_guid_localhost(hpsb_guid_t handle);
+
+/*
+ * This will fill in the given, pre-initialised hpsb_packet with the current
+ * information from the GUID handle (host, node ID, generation number). It will
+ * return false if the node owning the GUID is not accessible (and not modify the
+ * hpsb_packet) and return true otherwise.
+ *
+ * Note that packet sending may still fail in hpsb_send_packet if a bus reset
+ * happens while you are trying to set up the packet (due to obsolete generation
+ * number). It will at least reliably fail so that you don't accidentally and
+ * unknowingly send your packet to the wrong node.
+ */
+int hpsb_guid_fill_packet(hpsb_guid_t handle, struct hpsb_packet *pkt);
+
+
+void init_ieee1394_guid(void);
+
+
+#endif /* _IEEE1394_GUID_H */
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index c7ce7314437af2..ffcfc7f5261ca5 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -25,6 +25,7 @@
#include "highlevel.h"
#include "ieee1394_transactions.h"
#include "csr.h"
+#include "guid.h"
atomic_t hpsb_generation = ATOMIC_INIT(0);
@@ -45,6 +46,26 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
}
+/**
+ * alloc_hpsb_packet - allocate new packet structure
+ * @data_size: size of the data block to be allocated
+ *
+ * This function allocates, initializes and returns a new &struct hpsb_packet.
+ * It can be used in interrupt context. A header block is always included, its
+ * size is big enough to contain all possible 1394 headers. The data block is
+ * only allocated when @data_size is not zero.
+ *
+ * For packets for which responses will be received the @data_size has to be big
+ * enough to contain the response's data block since no further allocation
+ * occurs at response matching time.
+ *
+ * The packet's generation value will be set to the current generation number
+ * for ease of use. Remember to overwrite it with your own recorded generation
+ * number if you can not be sure that your code will not race with a bus reset.
+ *
+ * Return value: A pointer to a &struct hpsb_packet or NULL on allocation
+ * failure.
+ */
struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
{
struct hpsb_packet *packet = NULL;
@@ -83,6 +104,14 @@ struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
return packet;
}
+
+/**
+ * free_hpsb_packet - free packet and data associated with it
+ * @packet: packet to free (is NULL safe)
+ *
+ * This function will free packet->data, packet->header and finally the packet
+ * itself.
+ */
void free_hpsb_packet(struct hpsb_packet *packet)
{
if (packet == NULL) {
@@ -336,6 +365,20 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
queue_task(&host->timeout_tq, &tq_timer);
}
+/**
+ * hpsb_send_packet - transmit a packet on the bus
+ * @packet: packet to send
+ *
+ * The packet is sent through the host specified in the packet->host field.
+ * Before sending, the packet's transmit speed is automatically determined using
+ * the local speed map.
+ *
+ * Possibilities for failure are that host is either not initialized, in bus
+ * reset, the packet's generation number doesn't match the current generation
+ * number or the host reports a transmit error.
+ *
+ * Return value: False (0) on failure, true (1) otherwise.
+ */
int hpsb_send_packet(struct hpsb_packet *packet)
{
struct hpsb_host *host = packet->host;
@@ -721,47 +764,6 @@ void abort_timedouts(struct hpsb_host *host)
}
-#if 0
-int hpsb_host_thread(void *hostPointer)
-{
- struct hpsb_host *host = (struct hpsb_host *)hostPointer;
-
- /* I don't understand why, but I just want to be on the safe side. */
- lock_kernel();
-
- HPSB_INFO(__FUNCTION__ " starting for one %s adapter",
- host->template->name);
-
- exit_mm(current);
- exit_files(current);
- exit_fs(current);
-
- strcpy(current->comm, "ieee1394 thread");
-
- /* ... but then again, I think the following is safe. */
- unlock_kernel();
-
- for (;;) {
- siginfo_t info;
- unsigned long signr;
-
- if (signal_pending(current)) {
- spin_lock_irq(&current->sigmask_lock);
- signr = dequeue_signal(&current->blocked, &info);
- spin_unlock_irq(&current->sigmask_lock);
-
- break;
- }
-
- abort_timedouts(host);
- }
-
- HPSB_INFO(__FUNCTION__ " exiting");
- return 0;
-}
-#endif
-
-
#ifndef MODULE
void __init ieee1394_init(void)
@@ -769,6 +771,7 @@ void __init ieee1394_init(void)
register_builtin_lowlevels();
init_hpsb_highlevel();
init_csr();
+ init_ieee1394_guid();
}
#else
@@ -777,6 +780,8 @@ int init_module(void)
{
init_hpsb_highlevel();
init_csr();
+ init_ieee1394_guid();
+
return 0;
}
diff --git a/drivers/ieee1394/ieee1394_syms.c b/drivers/ieee1394/ieee1394_syms.c
index 3a99b09238b092..c1ebadd109629e 100644
--- a/drivers/ieee1394/ieee1394_syms.c
+++ b/drivers/ieee1394/ieee1394_syms.c
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/module.h>
+#include <linux/string.h>
#include "ieee1394_types.h"
#include "hosts.h"
@@ -15,6 +16,7 @@
#include "ieee1394_transactions.h"
/* #include "events.h" */
#include "highlevel.h"
+#include "guid.h"
EXPORT_SYMBOL(hpsb_register_lowlevel);
EXPORT_SYMBOL(hpsb_unregister_lowlevel);
@@ -52,3 +54,7 @@ EXPORT_SYMBOL(highlevel_read);
EXPORT_SYMBOL(highlevel_write);
EXPORT_SYMBOL(highlevel_lock);
EXPORT_SYMBOL(highlevel_lock64);
+
+EXPORT_SYMBOL(hpsb_guid_get_handle);
+EXPORT_SYMBOL(hpsb_guid_localhost);
+EXPORT_SYMBOL(hpsb_guid_fill_packet);
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index 6f07a7f6a2e9b4..c5c5cc4ad85f00 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -132,6 +132,26 @@ void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
}
+/**
+ * get_tlabel - allocate a transaction label
+ * @host: host to be used for transmission
+ * @nodeid: the node ID of the transmission target
+ * @wait: whether to sleep if no tlabel is available
+ *
+ * Every asynchronous transaction on the 1394 bus needs a transaction label to
+ * match the response to the request. This label has to be different from any
+ * other transaction label in an outstanding request to the same node to make
+ * matching possible without ambiguity.
+ *
+ * There are 64 different tlabels, so an allocated tlabel has to be freed with
+ * free_tlabel() after the transaction is complete (unless it's reused again for
+ * the same target node).
+ *
+ * @wait must not be set to true if you are calling from interrupt context.
+ *
+ * Return value: The allocated transaction label or -1 if there was no free
+ * tlabel and @wait is false.
+ */
int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
{
unsigned long flags;
@@ -166,6 +186,18 @@ int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
}
}
+/**
+ * free_tlabel - free an allocated transaction label
+ * @host: host to be used for transmission
+ * @nodeid: the node ID of the transmission target
+ * @tlabel: the transaction label to free
+ *
+ * Frees the transaction label allocated with get_tlabel(). The tlabel has to
+ * be freed after the transaction is complete (i.e. response was received for a
+ * split transaction or packet was sent for a unified transaction).
+ *
+ * A tlabel must not be freed twice.
+ */
void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel)
{
unsigned long flags;
diff --git a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h
index d817e61c6a9549..411b79b36e3a6a 100644
--- a/drivers/ieee1394/ieee1394_types.h
+++ b/drivers/ieee1394/ieee1394_types.h
@@ -27,7 +27,19 @@ static __inline__ void list_add_tail(struct list_head *new, struct list_head *he
#define __constant_cpu_to_be32(x) __constant_htonl((x))
-#endif
+#define set_current_state(state_value) \
+ do { current->state = (state_value); } while (0)
+
+#include <linux/pci.h>
+inline static int pci_enable_device(struct pci_dev *dev)
+{
+ u16 cmd;
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY);
+ return 0;
+}
+
+#endif /* Linux version < 2.3 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
#include <asm/spinlock.h>
@@ -39,6 +51,9 @@ static __inline__ void list_add_tail(struct list_head *new, struct list_head *he
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
typedef __u32 quadlet_t;
typedef __u64 octlet_t;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index c7db523b81b899..a0933c3e4a8fad 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -38,15 +38,25 @@
* . Self-id are sometimes not received properly
* if card is initialized with no other nodes
* on the bus
+ * . SONY CXD3222 chip is not working properly
+ * . Apple PowerBook detected but not working yet
*/
/*
* Acknowledgments:
*
* Emilie Chung <emilie.chung@axis.com>
- * .Tip on Async Request Filter
+ * . Tip on Async Request Filter
* Pascal Drolet <pascal.drolet@informission.ca>
- * .Various tips for optimization and functionnalities
+ * . Various tips for optimization and functionnalities
+ * Robert Ficklin <rficklin@westengineering.com>
+ * . Loop in irq_handler
+ * James Goodwin <jamesg@Filanet.com>
+ * . Various tips on initialization, self-id reception, etc.
+ * Albrecht Dress <ad@mpifr-bonn.mpg.de>
+ * . Apple PowerBook detection
+ * Daniel Kobras <daniel.kobras@student.uni-tuebingen.de>
+ * . Reset the board properly before leaving
*/
#include <linux/config.h>
@@ -65,6 +75,7 @@
#include <asm/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/tqueue.h>
+#include <linux/delay.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -118,6 +129,7 @@ int supported_chips[][2] = {
{ PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_UPD72862 },
{ PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_UPD72870 },
{ PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_UPD72871 },
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW },
{ -1, -1 }
};
@@ -128,7 +140,619 @@ static int add_card(struct pci_dev *dev);
static void remove_card(struct ti_ohci *ohci);
static int init_driver(void);
static void dma_trm_bh(void *data);
+static void dma_rcv_bh(void *data);
static void dma_trm_reset(struct dma_trm_ctx *d);
+static void stop_context(struct ti_ohci *ohci, int reg, char *msg);
+
+#ifdef _VIDEO_1394_H
+
+/* Taken from bttv.c */
+/*******************************/
+/* Memory management functions */
+/*******************************/
+
+#define MDEBUG(x) do { } while(0) /* Debug memory management */
+
+/* [DaveM] I've recoded most of this so that:
+ * 1) It's easier to tell what is happening
+ * 2) It's more portable, especially for translating things
+ * out of vmalloc mapped areas in the kernel.
+ * 3) Less unnecessary translations happen.
+ *
+ * The code used to assume that the kernel vmalloc mappings
+ * existed in the page tables of every process, this is simply
+ * not guarenteed. We now use pgd_offset_k which is the
+ * defined way to get at the kernel page tables.
+ */
+
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
+{
+ unsigned long ret = 0UL;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
+
+ if (!pgd_none(*pgd)) {
+ pmd = pmd_offset(pgd, adr);
+ if (!pmd_none(*pmd)) {
+ ptep = pte_offset(pmd, adr);
+ pte = *ptep;
+ if(pte_present(pte))
+ ret = (pte_page(pte)|(adr&(PAGE_SIZE-1)));
+ }
+ }
+ MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+static inline unsigned long uvirt_to_bus(unsigned long adr)
+{
+ unsigned long kva, ret;
+
+ kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
+ ret = virt_to_bus((void *)kva);
+ MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+static inline unsigned long kvirt_to_bus(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = uvirt_to_kva(pgd_offset_k(va), va);
+ ret = virt_to_bus((void *)kva);
+ MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+/* Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+static inline unsigned long kvirt_to_pa(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = uvirt_to_kva(pgd_offset_k(va), va);
+ ret = __pa(kva);
+ MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+static void * rvmalloc(unsigned long size)
+{
+ void * mem;
+ unsigned long adr, page;
+
+ mem=vmalloc(size);
+ if (mem)
+ {
+ memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+ adr=(unsigned long) mem;
+ while (size > 0)
+ {
+ page = kvirt_to_pa(adr);
+ mem_map_reserve(MAP_NR(__va(page)));
+ adr+=PAGE_SIZE;
+ size-=PAGE_SIZE;
+ }
+ }
+ return mem;
+}
+
+static void rvfree(void * mem, unsigned long size)
+{
+ unsigned long adr, page;
+
+ if (mem)
+ {
+ adr=(unsigned long) mem;
+ while (size > 0)
+ {
+ page = kvirt_to_pa(adr);
+ mem_map_unreserve(MAP_NR(__va(page)));
+ adr+=PAGE_SIZE;
+ size-=PAGE_SIZE;
+ }
+ vfree(mem);
+ }
+}
+
+static int free_dma_fbuf_ctx(struct dma_fbuf_ctx **d)
+{
+ int i;
+ struct ti_ohci *ohci;
+
+ if ((*d)==NULL) return -1;
+
+ ohci = (struct ti_ohci *)(*d)->ohci;
+
+ DBGMSG(ohci->id, "Freeing dma_fbuf_ctx %d", (*d)->ctx);
+
+ stop_context(ohci, (*d)->ctrlClear, NULL);
+
+ if ((*d)->buf) rvfree((void *)(*d)->buf,
+ (*d)->num_desc * (*d)->buf_size);
+
+ if ((*d)->prg) {
+ for (i=0;i<(*d)->num_desc;i++)
+ if ((*d)->prg[i]) kfree((*d)->prg[i]);
+ kfree((*d)->prg);
+ }
+
+ if ((*d)->buffer_status)
+ kfree((*d)->buffer_status);
+
+ kfree(*d);
+ *d = NULL;
+
+ return 0;
+}
+
+static struct dma_fbuf_ctx *
+alloc_dma_fbuf_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
+ int buf_size, int channel)
+{
+ struct dma_fbuf_ctx *d=NULL;
+ int i;
+
+ d = (struct dma_fbuf_ctx *)kmalloc(sizeof(struct dma_fbuf_ctx),
+ GFP_KERNEL);
+
+ if (d==NULL) {
+ PRINT(KERN_ERR, ohci->id, "failed to allocate dma_fbuf_ctx");
+ return NULL;
+ }
+
+ d->ohci = (void *)ohci;
+ d->ctx = ctx;
+ d->channel = channel;
+ d->num_desc = num_desc;
+ d->frame_size = buf_size;
+ if (buf_size%PAGE_SIZE)
+ d->buf_size = buf_size + PAGE_SIZE - (buf_size%PAGE_SIZE);
+ else
+ d->buf_size = buf_size;
+ d->ctrlSet = OHCI1394_IrRcvContextControlSet+32*d->ctx;
+ d->ctrlClear = OHCI1394_IrRcvContextControlClear+32*d->ctx;
+ d->cmdPtr = OHCI1394_IrRcvCommandPtr+32*d->ctx;
+ d->ctxMatch = OHCI1394_IrRcvContextMatch+32*d->ctx;
+ d->nb_cmd = d->buf_size / PAGE_SIZE + 1;
+ d->last_buffer = 0;
+ d->buf = NULL;
+ d->prg = NULL;
+ init_waitqueue_head(&d->waitq);
+
+ d->buf = rvmalloc(d->num_desc * d->buf_size);
+
+ if (d->buf == NULL) {
+ PRINT(KERN_ERR, ohci->id, "failed to allocate dma fbuffer");
+ free_dma_fbuf_ctx(&d);
+ return NULL;
+ }
+ memset(d->buf, 0, d->num_desc * d->buf_size);
+
+ d->prg = kmalloc(d->num_desc * sizeof(struct dma_cmd *),
+ GFP_KERNEL);
+
+ if (d->prg == NULL) {
+ PRINT(KERN_ERR, ohci->id, "failed to allocate dma fbuf prg");
+ free_dma_fbuf_ctx(&d);
+ return NULL;
+ }
+ memset(d->prg, 0, d->num_desc * sizeof(struct dma_cmd *));
+
+ for (i=0;i<d->num_desc;i++) {
+ d->prg[i] = kmalloc(d->nb_cmd * sizeof(struct dma_cmd),
+ GFP_KERNEL);
+ if (d->prg[i] == NULL) {
+ PRINT(KERN_ERR, ohci->id,
+ "failed to allocate dma fbuf prg");
+ free_dma_fbuf_ctx(&d);
+ return NULL;
+ }
+ }
+
+ d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int),
+ GFP_KERNEL);
+
+ if (d->buffer_status == NULL) {
+ PRINT(KERN_ERR, ohci->id, "failed to allocate dma fbuf prg");
+ free_dma_fbuf_ctx(&d);
+ return NULL;
+ }
+ memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int));
+
+ PRINT(KERN_INFO, ohci->id, "Iso DMA to User's Space: %d buffers "
+ "of size %d allocated for a frame size %d, each with %d prgs",
+ d->num_desc, d->buf_size, d->frame_size, d->nb_cmd);
+
+ return d;
+}
+
+static void initialize_dma_fbuf_prg(struct dma_cmd *prg, int n,
+ int frame_size, unsigned long buf)
+{
+ int i;
+ int leftsize = (frame_size%PAGE_SIZE) ?
+ frame_size%PAGE_SIZE : PAGE_SIZE;
+
+ /* the first descriptor will sync and read only 4 bytes */
+ prg[0].control = (0x280F << 16) | 4;
+ prg[0].address = kvirt_to_bus(buf);
+ prg[0].branchAddress = (virt_to_bus(&(prg[1].control))
+ & 0xfffffff0) | 0x1;
+ prg[0].status = 0;
+
+ /* the second descriptor will read PAGE_SIZE-4 bytes */
+ prg[1].control = (0x280C << 16) | (PAGE_SIZE-4);
+ prg[1].address = kvirt_to_bus(buf+4);
+ prg[1].branchAddress = (virt_to_bus(&(prg[2].control))
+ & 0xfffffff0) | 0x1;
+ prg[1].status = 0;
+
+ for (i=2;i<n-1;i++) {
+ prg[i].control = (0x280C << 16) | PAGE_SIZE;
+ prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
+
+ prg[i].branchAddress =
+ (virt_to_bus(&(prg[i+1].control))
+ & 0xfffffff0) | 0x1;
+
+ prg[i].status = 0;
+ }
+
+ /* the last descriptor will generate an interrupt */
+ prg[i].control = (0x283C << 16) | leftsize;
+ prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
+ prg[i].status = 0;
+}
+
+static void initialize_dma_fbuf_ctx(struct dma_fbuf_ctx *d, int tag)
+{
+ struct ti_ohci *ohci = (struct ti_ohci *)d->ohci;
+ int i;
+
+ stop_context(ohci, d->ctrlClear, NULL);
+
+ for (i=0;i<d->num_desc;i++) {
+ initialize_dma_fbuf_prg(d->prg[i], d->nb_cmd, d->frame_size,
+ (unsigned long)d->buf+i*d->buf_size);
+ }
+
+ /* Set bufferFill, no header */
+ reg_write(ohci, d->ctrlSet, 0x80000000);
+
+ /* Set the context match register to match on all tags,
+ sync for sync tag, and listen to d->channel */
+ reg_write(ohci, d->ctxMatch, 0xf0000000|((tag&0xf)<<8)|d->channel);
+
+ /* Set up isoRecvIntMask to generate interrupts */
+ reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1<<d->ctx);
+}
+
+/* find which context is listening to this channel */
+int fbuf_ctx_listening(struct ti_ohci *ohci, int channel)
+{
+ int i;
+ for (i=0;i<ohci->nb_iso_ctx-1;i++)
+ if (ohci->fbuf_context[i]) {
+ if (ohci->fbuf_context[i]->channel==channel)
+ return i;
+ }
+
+ PRINT(KERN_ERR, ohci->id,
+ "no iso context is listening to channel %d",
+ channel);
+ return -1;
+}
+
+static int ohci_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct ti_ohci *ohci=&cards[MINOR(inode->i_rdev)];
+
+ switch(cmd)
+ {
+ case VIDEO1394_LISTEN_CHANNEL:
+ {
+ struct video1394_mmap v;
+ int i;
+
+ if(copy_from_user(&v, (void *)arg, sizeof(v)))
+ return -EFAULT;
+ if (v.channel<0 || v.channel>(ISO_CHANNELS-1)) {
+ PRINT(KERN_ERR, ohci->id,
+ "iso channel %d out of bound", v.channel);
+ return -EFAULT;
+ }
+ if (test_and_set_bit(v.channel, &ohci->IR_channel_usage)) {
+ PRINT(KERN_ERR, ohci->id,
+ "channel %d is already taken", v.channel);
+ return -EFAULT;
+ }
+
+ /* find a free iso context */
+ for (i=0;i<ohci->nb_iso_ctx-1;i++)
+ if (ohci->fbuf_context[i]==NULL) break;
+
+ if (i==(ohci->nb_iso_ctx-1)) {
+ PRINT(KERN_ERR, ohci->id, "no iso context available");
+ return -EFAULT;
+ }
+
+ if (v.nb_buffers * v.buf_size > VIDEO1394_MAX_SIZE) {
+ PRINT(KERN_ERR, ohci->id,
+ "%d buffers of size %d bytes is too big",
+ v.nb_buffers, v.buf_size);
+ return -EFAULT;
+ }
+
+ ohci->fbuf_context[i] =
+ alloc_dma_fbuf_ctx(ohci, i+1, v.nb_buffers,
+ v.buf_size, v.channel);
+
+ if (ohci->fbuf_context[i] == NULL) {
+ PRINT(KERN_ERR, ohci->id,
+ "Couldn't allocate fbuf context");
+ return -EFAULT;
+ }
+ initialize_dma_fbuf_ctx(ohci->fbuf_context[i], v.sync_tag);
+
+ ohci->current_fbuf_ctx = ohci->fbuf_context[i];
+
+ v.buf_size = ohci->fbuf_context[i]->buf_size;
+
+ PRINT(KERN_INFO, ohci->id,
+ "iso context %d listen on channel %d", i+1,
+ v.channel);
+
+ if(copy_to_user((void *)arg, &v, sizeof(v)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case VIDEO1394_UNLISTEN_CHANNEL:
+ {
+ int channel;
+ int i;
+
+ if(copy_from_user(&channel, (void *)arg, sizeof(int)))
+ return -EFAULT;
+
+ if (!test_and_clear_bit(channel, &ohci->IR_channel_usage)) {
+ PRINT(KERN_ERR, ohci->id,
+ "channel %d is not being used", channel);
+ return -EFAULT;
+ }
+
+ i = fbuf_ctx_listening(ohci, channel);
+ if (i<0) return -EFAULT;
+
+ free_dma_fbuf_ctx(&ohci->fbuf_context[i]);
+
+ PRINT(KERN_INFO, ohci->id,
+ "iso context %d stop listening on channel %d",
+ i+1, channel);
+
+ return 0;
+ }
+ case VIDEO1394_QUEUE_BUFFER:
+ {
+ struct video1394_wait v;
+ struct dma_fbuf_ctx *d;
+ int i;
+
+ if(copy_from_user(&v, (void *)arg, sizeof(v)))
+ return -EFAULT;
+
+ i = fbuf_ctx_listening(ohci, v.channel);
+ if (i<0) return -EFAULT;
+ d = ohci->fbuf_context[i];
+
+ if ((v.buffer<0) || (v.buffer>d->num_desc)) {
+ PRINT(KERN_ERR, ohci->id,
+ "buffer %d out of range",v.buffer);
+ return -EFAULT;
+ }
+
+ if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) {
+ PRINT(KERN_ERR, ohci->id,
+ "buffer %d is already used",v.buffer);
+ return -EFAULT;
+ }
+
+ d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED;
+
+ d->prg[d->last_buffer][d->nb_cmd-1].branchAddress =
+ (virt_to_bus(&(d->prg[v.buffer][0].control))
+ & 0xfffffff0) | 0x1;
+
+ d->last_buffer = v.buffer;
+
+ if (!(reg_read(ohci, d->ctrlSet) & 0x8000))
+ {
+ DBGMSG(ohci->id, "Starting iso DMA ctx=%d",d->ctx);
+
+ /* Tell the controller where the first program is */
+ reg_write(ohci, d->cmdPtr,
+ virt_to_bus(&(d->prg[v.buffer][0])) | 0x1 );
+
+ /* Run IR context */
+ reg_write(ohci, d->ctrlSet, 0x8000);
+ }
+ else {
+ /* Wake up dma context if necessary */
+ if (!(reg_read(ohci, d->ctrlSet) & 0x400)) {
+ PRINT(KERN_INFO, ohci->id,
+ "Waking up iso dma ctx=%d", d->ctx);
+ reg_write(ohci, d->ctrlSet, 0x1000);
+ }
+ }
+ return 0;
+
+ }
+ case VIDEO1394_WAIT_BUFFER:
+ {
+ struct video1394_wait v;
+ struct dma_fbuf_ctx *d;
+ int i;
+
+ if(copy_from_user(&v, (void *)arg, sizeof(v)))
+ return -EFAULT;
+
+ i = fbuf_ctx_listening(ohci, v.channel);
+ if (i<0) return -EFAULT;
+ d = ohci->fbuf_context[i];
+
+ if ((v.buffer<0) || (v.buffer>d->num_desc)) {
+ PRINT(KERN_ERR, ohci->id,
+ "buffer %d out of range",v.buffer);
+ return -EFAULT;
+ }
+
+ switch(d->buffer_status[v.buffer]) {
+ case VIDEO1394_BUFFER_READY:
+ d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE;
+ return 0;
+ case VIDEO1394_BUFFER_QUEUED:
+ while(d->buffer_status[v.buffer]!=
+ VIDEO1394_BUFFER_READY) {
+ interruptible_sleep_on(&d->waitq);
+ if(signal_pending(current)) return -EINTR;
+ }
+ d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE;
+ return 0;
+ default:
+ PRINT(KERN_ERR, ohci->id,
+ "buffer %d is not queued",v.buffer);
+ return -EFAULT;
+ }
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * This maps the vmalloced and reserved fbuffer to user space.
+ *
+ * FIXME:
+ * - PAGE_READONLY should suffice!?
+ * - remap_page_range is kind of inefficient for page by page remapping.
+ * But e.g. pte_alloc() does not work in modules ... :-(
+ */
+
+static int do_fbuf_mmap(struct ti_ohci *ohci, struct dma_fbuf_ctx *d,
+ const char *adr, unsigned long size)
+{
+ unsigned long start=(unsigned long) adr;
+ unsigned long page,pos;
+
+ if (size>d->num_desc * d->buf_size) {
+ PRINT(KERN_ERR, ohci->id,
+ "fbuf context %d buf size is different from mmap size",
+ d->ctx);
+ return -EINVAL;
+ }
+ if (!d->buf) {
+ PRINT(KERN_ERR, ohci->id,
+ "fbuf context %d is not allocated", d->ctx);
+ return -EINVAL;
+ }
+
+ pos=(unsigned long) d->buf;
+ while (size > 0) {
+ page = kvirt_to_pa(pos);
+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+ return -EAGAIN;
+ start+=PAGE_SIZE;
+ pos+=PAGE_SIZE;
+ size-=PAGE_SIZE;
+ }
+ return 0;
+}
+
+int ohci_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct ti_ohci *ohci=&cards[MINOR(file->f_dentry->d_inode->i_rdev)];
+ PRINT(KERN_INFO, ohci->id, "mmap");
+ if (ohci->current_fbuf_ctx == NULL) {
+ PRINT(KERN_ERR, ohci->id, "current fbuf context not set");
+ return -EINVAL;
+ }
+
+ return do_fbuf_mmap(ohci, ohci->current_fbuf_ctx,
+ (char *)vma->vm_start,
+ (unsigned long)(vma->vm_end-vma->vm_start));
+ return 0;
+}
+
+static int ohci_open(struct inode *inode, struct file *file)
+{
+ struct ti_ohci *ohci=&cards[MINOR(inode->i_rdev)];
+ PRINT(KERN_INFO, ohci->id, "open");
+ return 0;
+}
+
+static int ohci_release(struct inode *inode, struct file *file)
+{
+ struct ti_ohci *ohci=&cards[MINOR(inode->i_rdev)];
+ int i;
+
+ PRINT(KERN_INFO, ohci->id, "release");
+ for (i=0;i<ohci->nb_iso_ctx-1;i++)
+ if (ohci->fbuf_context[i]) {
+ if (!test_and_clear_bit(ohci->fbuf_context[i]->channel,
+ &ohci->IR_channel_usage)) {
+ PRINT(KERN_ERR, ohci->id,
+ "channel %d is not being used",
+ ohci->fbuf_context[i]->channel);
+ }
+ PRINT(KERN_INFO, ohci->id,
+ "iso context %d stop listening on channel %d",
+ i+1, ohci->fbuf_context[i]->channel);
+ free_dma_fbuf_ctx(&ohci->fbuf_context[i]);
+ }
+ return 0;
+}
+
+static struct file_operations ohci_fops=
+{
+ owner: THIS_MODULE,
+ ioctl: ohci_ioctl,
+ mmap: ohci_mmap,
+ open: ohci_open,
+ release: ohci_release
+};
+
+int wakeup_dma_fbuf_ctx(struct ti_ohci *ohci, struct dma_fbuf_ctx *d)
+{
+ int i;
+
+ if (d==NULL) {
+ PRINT(KERN_ERR, ohci->id, "Iso receive event received but "
+ "context not allocated");
+ return -EFAULT;
+ }
+
+ for (i=0;i<d->num_desc;i++) {
+ if (d->prg[i][d->nb_cmd-1].status) {
+ d->prg[i][d->nb_cmd-1].status=0;
+ d->buffer_status[i] = VIDEO1394_BUFFER_READY;
+ }
+ }
+ if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
+ return 0;
+}
+
+#endif
+
+
/***********************************
* IEEE-1394 functionality section *
@@ -220,6 +844,22 @@ inline static int handle_selfid(struct ti_ohci *ohci, struct hpsb_host *host,
"Error in reception of self-id packets"
"Self-id count: %08x q[0]: %08x",
self_id_count, q[0]);
+
+ /*
+ * Tip by James Goodwin <jamesg@Filanet.com>:
+ * We had an error, generate another bus reset in response.
+ * TODO. Actually read the current value in the phy before
+ * generating a bus reset (read modify write). This way
+ * we don't stomp any current gap count settings, etc.
+ */
+ if (ohci->self_id_errors<OHCI1394_MAX_SELF_ID_ERRORS) {
+ reg_write(ohci, OHCI1394_PhyControl, 0x000041ff);
+ ohci->self_id_errors++;
+ }
+ else {
+ PRINT(KERN_ERR, ohci->id,
+ "Timeout on self-id error reception");
+ }
return -1;
}
@@ -411,15 +1051,34 @@ static int ohci_initialize(struct hpsb_host *host)
spin_lock_init(&ohci->phy_reg_lock);
+ /*
+ * Tip by James Goodwin <jamesg@Filanet.com>:
+ * We need to add delays after the soft reset, setting LPS, and
+ * enabling our link. This might fixes the self-id reception
+ * problem at initialization.
+ */
+
/* Soft reset */
if ((retval=ohci_soft_reset(ohci))<0) return retval;
-
- /* Set the bus number */
- reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);
+ /*
+ *Delay aftger soft reset to make sure everything has settled
+ * down (sanity)
+ */
+ mdelay(100);
+
/* Set Link Power Status (LPS) */
reg_write(ohci, OHCI1394_HCControlSet, 0x00080000);
+ /*
+ * Delay after setting LPS in order to make sure link/phy
+ * communication is established
+ */
+ mdelay(100);
+
+ /* Set the bus number */
+ reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);
+
/* Enable posted writes */
reg_write(ohci, OHCI1394_HCControlSet, 0x00040000);
@@ -464,9 +1123,6 @@ static int ohci_initialize(struct hpsb_host *host)
/* Don't accept phy packets into AR request context */
reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);
- /* Enable link */
- reg_write(ohci, OHCI1394_HCControlSet, 0x00020000);
-
/* Initialize IR dma */
ohci->nb_iso_ctx = get_nb_iso_ctx(ohci);
PRINT(KERN_INFO, ohci->id, "%d iso contexts available",
@@ -477,7 +1133,18 @@ static int ohci_initialize(struct hpsb_host *host)
reg_write(ohci, OHCI1394_IrRcvContextMatch+32*i, 0);
reg_write(ohci, OHCI1394_IrRcvCommandPtr+32*i, 0);
}
-
+#ifdef _VIDEO_1394_H
+ ohci->fbuf_context = (struct dma_fbuf_ctx **)
+ kmalloc((ohci->nb_iso_ctx-1)*sizeof(struct dma_fbuf_ctx *),
+ GFP_KERNEL);
+ if (ohci->fbuf_context)
+ memset(ohci->fbuf_context, 0,
+ (ohci->nb_iso_ctx-1)*sizeof(struct dma_fbuf_ctx *));
+ else {
+ PRINT(KERN_ERR, ohci->id, "Cannot allocate fbuf_context");
+ return -1;
+ }
+#endif
/* Set bufferFill, isochHeader, multichannel for IR context */
reg_write(ohci, OHCI1394_IrRcvContextControlSet, 0xd0000000);
@@ -495,16 +1162,6 @@ static int ohci_initialize(struct hpsb_host *host)
(thanks to Michael Greger for seeing that I forgot this) */
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 0x00000001);
- initialize_dma_rcv_ctx(ohci->ir_context);
-
- /* Initialize AR dma */
- initialize_dma_rcv_ctx(ohci->ar_req_context);
- initialize_dma_rcv_ctx(ohci->ar_resp_context);
-
- /* Initialize AT dma */
- initialize_dma_trm_ctx(ohci->at_req_context);
- initialize_dma_trm_ctx(ohci->at_resp_context);
-
/*
* Accept AT requests from all nodes. This probably
* will have to be controlled from the subsystem
@@ -539,6 +1196,20 @@ static int ohci_initialize(struct hpsb_host *host)
OHCI1394_isochRx
);
+ /* Enable link */
+ reg_write(ohci, OHCI1394_HCControlSet, 0x00020000);
+
+ /* Initialize AR dma */
+ initialize_dma_rcv_ctx(ohci->ar_req_context);
+ initialize_dma_rcv_ctx(ohci->ar_resp_context);
+
+ /* Initialize AT dma */
+ initialize_dma_trm_ctx(ohci->at_req_context);
+ initialize_dma_trm_ctx(ohci->at_resp_context);
+
+ /* Initialize IR dma */
+ initialize_dma_rcv_ctx(ohci->ir_context);
+
return 1;
}
@@ -619,7 +1290,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
struct ti_ohci *ohci = host->hostdata;
struct dma_trm_ctx *d;
unsigned char tcode;
- int i=50;
+ int timeout=50;
if (packet->data_size >= ohci->max_packet_size) {
PRINT(KERN_ERR, ohci->id,
@@ -642,8 +1313,9 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
}
while (d->free_prgs<1) {
spin_unlock(&d->lock);
- schedule();
- if (i-- <0) {
+ interruptible_sleep_on(&d->waitq);
+ if(signal_pending(current)) return -EINTR;
+ if (timeout--<0) {
stop_context(ohci, d->ctrlClear,
"AT DMA runaway loop... bailing out");
return 0;
@@ -687,7 +1359,7 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
switch (cmd) {
case RESET_BUS:
- host->attempt_root=1;
+ host->attempt_root=1;
PRINT(KERN_INFO, ohci->id, "resetting bus on request%s",
(host->attempt_root ? " and attempting to become root"
: ""));
@@ -743,6 +1415,11 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
spin_lock_irqsave(&ohci->IR_channel_lock, flags);
+#if 0
+ PRINT(KERN_INFO, ohci->id, "!!! try listen on channel %d !!!",
+ arg);
+#endif
+
if (!test_and_set_bit(arg, &ohci->IR_channel_usage)) {
PRINT(KERN_INFO, ohci->id,
"listening enabled on channel %d", arg);
@@ -845,137 +1522,179 @@ static void ohci_irq_handler(int irq, void *dev_id,
struct ti_ohci *ohci = (struct ti_ohci *)dev_id;
struct hpsb_host *host = ohci->host;
int phyid = -1, isroot = 0;
+ int timeout = 255;
- /* read the interrupt event register */
- event=reg_read(ohci, OHCI1394_IntEventSet);
+ do {
+ /* read the interrupt event register */
+ event=reg_read(ohci, OHCI1394_IntEventClear);
-#if 0
- /*
- * clear the interrupt event register, except for the
- * bus reset event interrupt (if any). This is an
- * attempt to comply with ohci spec 7.2.3.2
- */
- reg_write(ohci, OHCI1394_IntEventClear, event & (~OHCI1394_busReset));
-#else
- /* The above attempt doesn't work */
- reg_write(ohci, OHCI1394_IntEventClear, event);
-#endif
- if (event & OHCI1394_busReset) {
- if (!host->in_bus_reset) {
- PRINT(KERN_INFO, ohci->id, "Bus reset");
+ DBGMSG(ohci->id, "IntEvent: %08x",event);
- /* Wait for the AT fifo to be flushed */
- dma_trm_reset(ohci->at_req_context);
- dma_trm_reset(ohci->at_resp_context);
+ if (!event) return;
-#if 0
- /* clear the bus reset event */
- reg_write(ohci, OHCI1394_IntEventClear,
- OHCI1394_busReset);
-#endif
- /* Subsystem call */
- hpsb_bus_reset(ohci->host);
+ /* clear the interrupt event register */
+ reg_write(ohci, OHCI1394_IntEventClear, event);
+
+ if (event & OHCI1394_busReset) {
+ if (!host->in_bus_reset) {
+ PRINT(KERN_INFO, ohci->id, "Bus reset");
+
+ /* Wait for the AT fifo to be flushed */
+ dma_trm_reset(ohci->at_req_context);
+ dma_trm_reset(ohci->at_resp_context);
- ohci->NumBusResets++;
+ /* Subsystem call */
+ hpsb_bus_reset(ohci->host);
+
+ ohci->NumBusResets++;
+ }
}
- }
- /*
- * Problem: How can I ensure that the AT bottom half will be
- * executed before the AR bottom half (both events may have
- * occured within a single irq event)
- * Quick hack: just launch it within the IRQ handler
- */
- if (event & OHCI1394_reqTxComplete) {
- struct dma_trm_ctx *d = ohci->at_req_context;
- DBGMSG(ohci->id, "Got reqTxComplete interrupt status=0x%08X",
- reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- stop_context(ohci, d->ctrlClear, "reqTxComplete");
- else
- dma_trm_bh((void *)d);
- }
- if (event & OHCI1394_respTxComplete) {
- struct dma_trm_ctx *d = ohci->at_resp_context;
- DBGMSG(ohci->id, "Got respTxComplete interrupt status=0x%08X",
- reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- stop_context(ohci, d->ctrlClear, "respTxComplete");
- else
- dma_trm_bh((void *)d);
- }
- if (event & OHCI1394_RQPkt) {
- struct dma_rcv_ctx *d = ohci->ar_req_context;
- DBGMSG(ohci->id, "Got RQPkt interrupt status=0x%08X",
- reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- stop_context(ohci, d->ctrlClear, "RQPkt");
- else {
- queue_task(&d->task, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ /*
+ * Problem: How can I ensure that the AT bottom half will be
+ * executed before the AR bottom half (both events may have
+ * occured within a single irq event)
+ * Quick hack: just launch it within the IRQ handler
+ */
+ if (event & OHCI1394_reqTxComplete) {
+ struct dma_trm_ctx *d = ohci->at_req_context;
+ DBGMSG(ohci->id, "Got reqTxComplete interrupt "
+ "status=0x%08X", reg_read(ohci, d->ctrlSet));
+ if (reg_read(ohci, d->ctrlSet) & 0x800)
+ stop_context(ohci, d->ctrlClear,
+ "reqTxComplete");
+ else
+ dma_trm_bh((void *)d);
}
- }
- if (event & OHCI1394_RSPkt) {
- struct dma_rcv_ctx *d = ohci->ar_resp_context;
- DBGMSG(ohci->id, "Got RSPkt interrupt status=0x%08X",
- reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- stop_context(ohci, d->ctrlClear, "RSPkt");
- else {
- queue_task(&d->task, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ if (event & OHCI1394_respTxComplete) {
+ struct dma_trm_ctx *d = ohci->at_resp_context;
+ DBGMSG(ohci->id, "Got respTxComplete interrupt "
+ "status=0x%08X", reg_read(ohci, d->ctrlSet));
+ if (reg_read(ohci, d->ctrlSet) & 0x800)
+ stop_context(ohci, d->ctrlClear,
+ "respTxComplete");
+ else
+ dma_trm_bh((void *)d);
}
- }
- if (event & OHCI1394_isochRx) {
- quadlet_t isoRecvIntEvent;
- struct dma_rcv_ctx *d = ohci->ir_context;
- isoRecvIntEvent = reg_read(ohci, OHCI1394_IsoRecvIntEventSet);
- reg_write(ohci, OHCI1394_IsoRecvIntEventClear,
- isoRecvIntEvent);
- DBGMSG(ohci->id, "Got reqTxComplete interrupt status=0x%08X",
- reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- stop_context(ohci, d->ctrlClear, "isochRx");
- else {
- queue_task(&d->task, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ if (event & OHCI1394_RQPkt) {
+ struct dma_rcv_ctx *d = ohci->ar_req_context;
+ DBGMSG(ohci->id, "Got RQPkt interrupt status=0x%08X",
+ reg_read(ohci, d->ctrlSet));
+ if (reg_read(ohci, d->ctrlSet) & 0x800)
+ stop_context(ohci, d->ctrlClear, "RQPkt");
+ else {
+#if 1
+ queue_task(&d->task, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+#else
+ dma_rcv_bh((void *)d);
+#endif
+ }
}
- }
- if (event & OHCI1394_selfIDComplete) {
- if (host->in_bus_reset) {
- node_id = reg_read(ohci, OHCI1394_NodeID);
- if (node_id & 0x80000000) { /* NodeID valid */
- phyid = node_id & 0x0000003f;
- isroot = (node_id & 0x40000000) != 0;
-
- PRINT(KERN_INFO, ohci->id,
- "SelfID process finished (phyid %d, %s)",
- phyid, (isroot ? "root" : "not root"));
-
- handle_selfid(ohci, host, phyid, isroot);
+ if (event & OHCI1394_RSPkt) {
+ struct dma_rcv_ctx *d = ohci->ar_resp_context;
+ DBGMSG(ohci->id, "Got RSPkt interrupt status=0x%08X",
+ reg_read(ohci, d->ctrlSet));
+ if (reg_read(ohci, d->ctrlSet) & 0x800)
+ stop_context(ohci, d->ctrlClear, "RSPkt");
+ else {
+#if 1
+ queue_task(&d->task, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+#else
+ dma_rcv_bh((void *)d);
+#endif
}
- else
- PRINT(KERN_ERR, ohci->id,
- "SelfID process finished but NodeID"
- " not valid: %08X",node_id);
-
- /* Accept Physical requests from all nodes. */
- reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0xffffffff);
- reg_write(ohci,OHCI1394_AsReqFilterLoSet, 0xffffffff);
- }
- else PRINT(KERN_INFO, ohci->id,
- "phy reg received without reset\n");
- }
- if (event & OHCI1394_phyRegRcvd) {
-#if 0
- if (host->in_bus_reset) {
- PRINT(KERN_INFO, ohci->id, "PhyControl: %08X",
- reg_read(ohci, OHCI1394_PhyControl));
- } else
- PRINT(KERN_ERR, ohci->id,
- "phy reg received without reset");
+ }
+ if (event & OHCI1394_isochRx) {
+ quadlet_t isoRecvIntEvent;
+ struct dma_rcv_ctx *d = ohci->ir_context;
+#ifdef _VIDEO_1394_H
+ int i;
#endif
- }
+ isoRecvIntEvent =
+ reg_read(ohci, OHCI1394_IsoRecvIntEventSet);
+ reg_write(ohci, OHCI1394_IsoRecvIntEventClear,
+ isoRecvIntEvent);
+ DBGMSG(ohci->id, "Got isochRx interrupt "
+ "status=0x%08X isoRecvIntEvent=%08x",
+ reg_read(ohci, d->ctrlSet), isoRecvIntEvent);
+ if (isoRecvIntEvent & 0x1) {
+ if (reg_read(ohci, d->ctrlSet) & 0x800)
+ stop_context(ohci, d->ctrlClear,
+ "isochRx");
+ else {
+#if 1
+ queue_task(&d->task, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+#else
+ dma_rcv_bh((void *)d);
+#endif
+ }
+ }
+#ifdef _VIDEO_1394_H
+ for (i=0;i<ohci->nb_iso_ctx-1;i++)
+ if (isoRecvIntEvent & (1<<(i+1)))
+ wakeup_dma_fbuf_ctx(
+ ohci,ohci->fbuf_context[i]);
+#endif
+ }
+ if (event & OHCI1394_selfIDComplete) {
+ if (host->in_bus_reset) {
+ node_id = reg_read(ohci, OHCI1394_NodeID);
+ if (node_id & 0x80000000) { /* NodeID valid */
+ phyid = node_id & 0x0000003f;
+ isroot = (node_id & 0x40000000) != 0;
+
+ PRINT(KERN_INFO, ohci->id,
+ "SelfID process finished "
+ "(phyid %d, %s)", phyid,
+ (isroot ? "root" : "not root"));
+
+ handle_selfid(ohci, host,
+ phyid, isroot);
+ }
+ else
+ PRINT(KERN_ERR, ohci->id,
+ "SelfID process finished but "
+ "NodeID not valid: %08X",
+ node_id);
+
+ /* Accept Physical requests from all nodes. */
+ reg_write(ohci,OHCI1394_AsReqFilterHiSet,
+ 0xffffffff);
+ reg_write(ohci,OHCI1394_AsReqFilterLoSet,
+ 0xffffffff);
+ /*
+ * Tip by James Goodwin <jamesg@Filanet.com>
+ * Turn on phys dma reception. We should
+ * probably manage the filtering somehow,
+ * instead of blindly turning it on.
+ */
+ reg_write(ohci,OHCI1394_PhyReqFilterHiSet,
+ 0xffffffff);
+ reg_write(ohci,OHCI1394_PhyReqFilterLoSet,
+ 0xffffffff);
+ reg_write(ohci,OHCI1394_PhyUpperBound,
+ 0xffff0000);
+ }
+ else PRINT(KERN_ERR, ohci->id,
+ "self-id received outside of bus reset"
+ "sequence");
+ }
+ if (event & OHCI1394_phyRegRcvd) {
+#if 1
+ if (host->in_bus_reset) {
+ PRINT(KERN_INFO, ohci->id, "PhyControl: %08X",
+ reg_read(ohci, OHCI1394_PhyControl));
+ }
+ else PRINT(KERN_ERR, ohci->id,
+ "phy reg received outside of bus reset"
+ "sequence");
+#endif
+ }
+ } while (--timeout);
+ PRINT(KERN_ERR, ohci->id, "irq_handler timeout event=0x%08x", event);
}
/* Put the buffer back into the dma context */
@@ -1119,6 +1838,17 @@ static void dma_rcv_bh(void *data)
buf_ptr += offset/4;
}
+ /*
+ * Tip by James Goodwin <jamesg@Filanet.com>
+ * We need to handle write requests that are received
+ * to our middle address space (posted writes).
+ * In this case, the hardware generates an
+ * ack_complete... but, if we pass the packet up to
+ * the subsystem, it will try and send a response
+ * (which it shouldn't), because it assumes we
+ * returned ack_pending.
+ */
+
/*
* We get one phy packet for each bus reset.
* we know that from now on the bus topology may
@@ -1132,6 +1862,20 @@ static void dma_rcv_bh(void *data)
(d->spb[length/4-1]>>16)&0x1f,
(d->spb[length/4-1]>>21)&0x3,
tcode, length, d->spb[3], d->ctx);
+
+ /*
+ * Tip by James Goodwin <jamesg@Filanet.com>
+ * Handle case of posted writes. If we receive
+ * an ack_complete, we should not send a
+ * response. Fake out upper layers by turning
+ * the packet into a broadcast packet... we
+ * should really modify the core stack to
+ * accept an ack received argument and figure
+ * out whether to reply.
+ */
+ if (((d->spb[length/4-1]>>16)&0x1f) == 0x11) {
+ d->spb[0] |= (ALL_NODES<<16);
+ }
hpsb_packet_received(ohci->host, d->spb,
length);
}
@@ -1154,6 +1898,20 @@ static void dma_rcv_bh(void *data)
(buf_ptr[length/4-1]>>16)&0x1f,
(buf_ptr[length/4-1]>>21)&0x3,
tcode, length, buf_ptr[3], d->ctx);
+
+ /*
+ * Tip by James Goodwin <jamesg@Filanet.com>
+ * Handle case of posted writes. If we receive
+ * an ack_complete, we should not send a
+ * response. Fake out upper layers by turning
+ * the packet into a broadcast packet... we
+ * should really modify the core stack to
+ * accept an ack received argument and figure
+ * out whether to reply.
+ */
+ if (((d->spb[length/4-1]>>16)&0x1f) == 0x11) {
+ buf_ptr[0] |= (ALL_NODES<<16);
+ }
hpsb_packet_received(ohci->host, buf_ptr,
length);
}
@@ -1207,32 +1965,42 @@ static void dma_trm_bh(void *data)
d->sent_ind = (d->sent_ind+1)%d->num_desc;
d->free_prgs++;
spin_unlock(&d->lock);
-
+
+ if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
+
DBGMSG(ohci->id, "Packet sent to node %d ack=0x%X spd=%d ctx=%d",
(packet->header[0]>>16)&0x3f, ack&0x1f, (ack>>5)&0x3, d->ctx);
hpsb_packet_sent(ohci->host, packet, ack&0xf);
}
-static int free_dma_rcv_ctx(struct dma_rcv_ctx *d)
+static int free_dma_rcv_ctx(struct dma_rcv_ctx **d)
{
int i;
+ struct ti_ohci *ohci;
+
+ if (*d==NULL) return -1;
+
+ ohci = (struct ti_ohci *)(*d)->ohci;
- if (d==NULL) return -1;
+ DBGMSG(ohci->id, "Freeing dma_rcv_ctx %d",(*d)->ctx);
+
+ stop_context(ohci, (*d)->ctrlClear, NULL);
- if (d->buf) {
- for (i=0; i<d->num_desc; i++)
- if (d->buf[i]) kfree(d->buf[i]);
- kfree(d->buf);
+ if ((*d)->buf) {
+ for (i=0; i<(*d)->num_desc; i++)
+ if ((*d)->buf[i]) kfree((*d)->buf[i]);
+ kfree((*d)->buf);
}
- if (d->prg) {
- for (i=0; i<d->num_desc; i++)
- if (d->prg[i]) kfree(d->prg[i]);
- kfree(d->prg);
+ if ((*d)->prg) {
+ for (i=0; i<(*d)->num_desc; i++)
+ if ((*d)->prg[i]) kfree((*d)->prg[i]);
+ kfree((*d)->prg);
}
- if (d->spb) kfree(d->spb);
-
- kfree(d);
+ if ((*d)->spb) kfree((*d)->spb);
+ kfree(*d);
+ *d = NULL;
+
return 0;
}
@@ -1270,7 +2038,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
if (d->buf == NULL) {
PRINT(KERN_ERR, ohci->id, "failed to allocate dma buffer");
- free_dma_rcv_ctx(d);
+ free_dma_rcv_ctx(&d);
return NULL;
}
memset(d->buf, 0, d->num_desc * sizeof(quadlet_t*));
@@ -1279,7 +2047,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
if (d->prg == NULL) {
PRINT(KERN_ERR, ohci->id, "failed to allocate dma prg");
- free_dma_rcv_ctx(d);
+ free_dma_rcv_ctx(&d);
return NULL;
}
memset(d->prg, 0, d->num_desc * sizeof(struct dma_cmd*));
@@ -1288,7 +2056,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
if (d->spb == NULL) {
PRINT(KERN_ERR, ohci->id, "failed to allocate split buffer");
- free_dma_rcv_ctx(d);
+ free_dma_rcv_ctx(&d);
return NULL;
}
@@ -1300,7 +2068,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
} else {
PRINT(KERN_ERR, ohci->id,
"failed to allocate dma buffer");
- free_dma_rcv_ctx(d);
+ free_dma_rcv_ctx(&d);
return NULL;
}
@@ -1311,7 +2079,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
} else {
PRINT(KERN_ERR, ohci->id,
"failed to allocate dma prg");
- free_dma_rcv_ctx(d);
+ free_dma_rcv_ctx(&d);
return NULL;
}
}
@@ -1319,17 +2087,29 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
spin_lock_init(&d->lock);
/* initialize bottom handler */
+ d->task.sync = 0;
+ d->task.next = NULL;
d->task.routine = dma_rcv_bh;
d->task.data = (void*)d;
return d;
}
-static int free_dma_trm_ctx(struct dma_trm_ctx *d)
+static int free_dma_trm_ctx(struct dma_trm_ctx **d)
{
- if (d==NULL) return -1;
- if (d->prg) kfree(d->prg);
- kfree(d);
+ struct ti_ohci *ohci;
+
+ if (*d==NULL) return -1;
+
+ ohci = (struct ti_ohci *)(*d)->ohci;
+
+ DBGMSG(ohci->id, "Freeing dma_trm_ctx %d",(*d)->ctx);
+
+ stop_context(ohci, (*d)->ctrlClear, NULL);
+
+ if ((*d)->prg) kfree((*d)->prg);
+ kfree(*d);
+ *d = NULL;
return 0;
}
@@ -1359,7 +2139,7 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
if (d->prg == NULL) {
PRINT(KERN_ERR, ohci->id, "failed to allocate at dma prg");
- free_dma_trm_ctx(d);
+ free_dma_trm_ctx(&d);
return NULL;
}
memset(d->prg, 0, d->num_desc * sizeof(struct at_dma_prg));
@@ -1370,6 +2150,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
d->task.routine = dma_trm_bh;
d->task.data = (void*)d;
+ init_waitqueue_head(&d->waitq);
+
return d;
}
@@ -1385,10 +2167,12 @@ static int add_card(struct pci_dev *dev)
return 1;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
- /* XXX check return value */
- pci_enable_device(dev);
-#endif
+ if (pci_enable_device(dev)) {
+ PRINT_G(KERN_NOTICE, "failed to enable OHCI hardware %d",
+ num_of_cards);
+ return 1;
+ }
+ pci_set_master(dev);
ohci = &cards[num_of_cards++];
@@ -1397,13 +2181,6 @@ static int add_card(struct pci_dev *dev)
ohci->state = 0;
- if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
- OHCI1394_DRIVER_NAME, ohci)) {
- PRINT(KERN_INFO, ohci->id, "allocated interrupt %d", dev->irq);
- } else {
- FAIL("failed to allocate shared interrupt %d", dev->irq);
- }
-
/* csr_config rom allocation */
ohci->csr_config_rom = kmalloc(1024, GFP_KERNEL);
if (ohci->csr_config_rom == NULL) {
@@ -1437,7 +2214,9 @@ static int add_card(struct pci_dev *dev)
OHCI1394_AsRspRcvContextControlClear,
OHCI1394_AsRspRcvCommandPtr);
- if (ohci->ar_resp_context == NULL) return 1;
+ if (ohci->ar_resp_context == NULL) {
+ FAIL("failed to allocate AR Resp context");
+ }
ohci->at_req_context =
alloc_dma_trm_ctx(ohci, 0, AT_REQ_NUM_DESC,
@@ -1445,7 +2224,9 @@ static int add_card(struct pci_dev *dev)
OHCI1394_AsReqTrContextControlClear,
OHCI1394_AsReqTrCommandPtr);
- if (ohci->at_req_context == NULL) return 1;
+ if (ohci->at_req_context == NULL) {
+ FAIL("failed to allocate AT Req context");
+ }
ohci->at_resp_context =
alloc_dma_trm_ctx(ohci, 1, AT_RESP_NUM_DESC,
@@ -1453,7 +2234,9 @@ static int add_card(struct pci_dev *dev)
OHCI1394_AsRspTrContextControlClear,
OHCI1394_AsRspTrCommandPtr);
- if (ohci->at_resp_context == NULL) return 1;
+ if (ohci->at_resp_context == NULL) {
+ FAIL("failed to allocate AT Resp context");
+ }
ohci->ir_context =
alloc_dma_rcv_ctx(ohci, 2, IR_NUM_DESC,
@@ -1462,7 +2245,9 @@ static int add_card(struct pci_dev *dev)
OHCI1394_IrRcvContextControlClear,
OHCI1394_IrRcvCommandPtr);
- if (ohci->ir_context == NULL) return 1;
+ if (ohci->ir_context == NULL) {
+ FAIL("failed to allocate IR context");
+ }
ohci->IR_channel_usage= 0x0000000000000000;
spin_lock_init(&ohci->IR_channel_lock);
@@ -1482,6 +2267,13 @@ static int add_card(struct pci_dev *dev)
PRINT(KERN_INFO, ohci->id, "remapped memory spaces reg 0x%p",
ohci->registers);
+ if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
+ OHCI1394_DRIVER_NAME, ohci)) {
+ PRINT(KERN_INFO, ohci->id, "allocated interrupt %d", dev->irq);
+ } else {
+ FAIL("failed to allocate shared interrupt %d", dev->irq);
+ }
+
return 0;
#undef FAIL
}
@@ -1507,6 +2299,10 @@ int ohci_get_info(char *buf, char **start, off_t fpos,
int i;
struct dma_rcv_ctx *d=NULL;
struct dma_trm_ctx *dt=NULL;
+#ifdef _VIDEO_1394_H
+ int j;
+ struct dma_fbuf_ctx *f=ohci->fbuf_context[0];
+#endif
p += sprintf(p,"IEEE-1394 OHCI Driver status report:\n");
p += sprintf(p," bus number: 0x%x Node ID: 0x%x\n",
@@ -1535,6 +2331,27 @@ int ohci_get_info(char *buf, char **start, off_t fpos,
host->is_busmgr ? "bus_mgr" : "");
p += sprintf(p,"\n---Iso Receive DMA---\n");
+
+#ifdef _VIDEO_1394_H
+
+#if 0
+ if (f!=NULL) {
+ for (i=0; i<f->num_desc; i++) {
+ for (j=0;j<f->nb_cmd;j++) {
+ p += sprintf(p,
+ "prg[%d][%d]: %p %08x %08x %08x %08x\n",
+ i,j,virt_to_bus(&(f->prg[i][j])),
+ f->prg[i][j].control,
+ f->prg[i][j].address,
+ f->prg[i][j].branchAddress,
+ f->prg[i][j].status);
+ }
+ }
+ }
+#endif
+
+#else
+
d = ohci->ir_context;
#if 0
for (i=0; i<d->num_desc; i++) {
@@ -1621,7 +2438,8 @@ int ohci_get_info(char *buf, char **start, off_t fpos,
dt->branchAddrPtr);
p += sprintf(p, "AT resp queue: first: %p last: %p\n",
dt->first, dt->last);
-
+#endif
+
/* ----- Register Dump ----- */
p += sprintf(p,"\n### HC Register dump ###\n");
SR("Version : %08x GUID_ROM : %08x ATRetries : %08x\n",
@@ -1736,19 +2554,34 @@ struct proc_dir_entry ohci_proc_entry =
static void remove_card(struct ti_ohci *ohci)
{
- if (ohci->registers)
- iounmap(ohci->registers);
+#ifdef _VIDEO_1394_H
+ int i;
+#endif
/* Free AR dma */
- free_dma_rcv_ctx(ohci->ar_req_context);
- free_dma_rcv_ctx(ohci->ar_resp_context);
+ free_dma_rcv_ctx(&ohci->ar_req_context);
+ free_dma_rcv_ctx(&ohci->ar_resp_context);
/* Free AT dma */
- free_dma_trm_ctx(ohci->at_req_context);
- free_dma_trm_ctx(ohci->at_resp_context);
+ free_dma_trm_ctx(&ohci->at_req_context);
+ free_dma_trm_ctx(&ohci->at_resp_context);
/* Free IR dma */
- free_dma_rcv_ctx(ohci->ir_context);
+ free_dma_rcv_ctx(&ohci->ir_context);
+
+#ifdef _VIDEO_1394_H
+ /* Free the frame buffer context */
+ if (ohci->fbuf_context)
+ for (i=0;i<ohci->nb_iso_ctx-1;i++) {
+ free_dma_fbuf_ctx(&ohci->fbuf_context[i]);
+ }
+#endif
+
+ /*
+ * Reset the board properly before leaving
+ * Daniel Kobras <daniel.kobras@student.uni-tuebingen.de>
+ */
+ ohci_soft_reset(ohci);
/* Free self-id buffer */
if (ohci->self_id_buffer)
@@ -1761,6 +2594,9 @@ static void remove_card(struct ti_ohci *ohci)
/* Free the IRQ */
free_irq(ohci->dev->irq, ohci);
+ if (ohci->registers)
+ iounmap(ohci->registers);
+
ohci->state = 0;
}
@@ -1858,16 +2694,30 @@ void cleanup_module(void)
proc_unregister(&proc_root, ohci_proc_entry.low_ino);
#endif
#endif
+
+#ifdef _VIDEO_1394_H
+ unregister_chrdev(OHCI1394_MAJOR, "ohci1394");
+#endif
+
PRINT_G(KERN_INFO, "removed " OHCI1394_DRIVER_NAME " module\n");
}
int init_module(void)
{
-
+ memset(cards, 0, MAX_OHCI1394_CARDS * sizeof (struct ti_ohci));
+
if (hpsb_register_lowlevel(get_ohci_template())) {
PRINT_G(KERN_ERR, "registering failed\n");
return -ENXIO;
} else {
+#ifdef _VIDEO_1394_H
+ if (register_chrdev(OHCI1394_MAJOR, "ohci1394", &ohci_fops))
+ {
+ printk("ohci1394: unable to get major %d\n",
+ OHCI1394_MAJOR);
+ return -EIO;
+ }
+#endif
return 0;
}
}
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
index f0ec83d48021f5..d778cbe7d6c36c 100644
--- a/drivers/ieee1394/ohci1394.h
+++ b/drivers/ieee1394/ohci1394.h
@@ -1,8 +1,29 @@
+/*
+ * ohci1394.h - driver for OHCI 1394 boards
+ * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
+ * Gord Peters <GordPeters@smarttech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
#ifndef _OHCI1394_H
#define _OHCI1394_H
#include "ieee1394_types.h"
+/* include this for the video frame grabber */
+/* #include "video1394.h" */
#define OHCI1394_DRIVER_NAME "ohci1394"
@@ -46,11 +67,16 @@
#define PCI_DEVICE_ID_NEC_UPD72871 0x00ce
#endif
+#ifndef PCI_DEVICE_ID_APPLE_UNI_N_FW
+#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018
+#endif
+
#define MAX_OHCI1394_CARDS 4
#define OHCI1394_MAX_AT_REQ_RETRIES 0x2
#define OHCI1394_MAX_AT_RESP_RETRIES 0x2
#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
+#define OHCI1394_MAX_SELF_ID_ERRORS 16
#define AR_REQ_NUM_DESC 4 /* number of AR req descriptors */
#define AR_REQ_BUF_SIZE 4096 /* size of AR req buffers */
@@ -116,8 +142,34 @@ struct dma_trm_ctx {
int ctrlClear;
int ctrlSet;
int cmdPtr;
+ wait_queue_head_t waitq;
};
+#ifdef _VIDEO_1394_H
+
+#define OHCI1394_MAJOR 172
+#define ISO_CHANNELS 64
+
+struct dma_fbuf_ctx {
+ void *ohci;
+ int ctx;
+ int channel;
+ int last_buffer;
+ unsigned int num_desc;
+ unsigned int buf_size;
+ unsigned int frame_size;
+ unsigned int nb_cmd;
+ unsigned char *buf;
+ struct dma_cmd **prg;
+ unsigned int *buffer_status;
+ int ctrlClear;
+ int ctrlSet;
+ int cmdPtr;
+ int ctxMatch;
+ wait_queue_head_t waitq;
+};
+#endif
+
struct ti_ohci {
int id; /* sequential card number */
@@ -147,6 +199,12 @@ struct ti_ohci {
spinlock_t IR_channel_lock;
int nb_iso_ctx;
+#ifdef _VIDEO_1394_H
+ /* frame buffer context */
+ struct dma_fbuf_ctx **fbuf_context;
+ struct dma_fbuf_ctx *current_fbuf_ctx;
+#endif
+
/* IEEE-1394 part follows */
struct hpsb_host *host;
@@ -154,6 +212,7 @@ struct ti_ohci {
spinlock_t phy_reg_lock;
+ int self_id_errors;
int NumBusResets;
};
@@ -328,8 +387,8 @@ quadlet_t ohci_csr_rom[] = {
#define OHCI1394_RSPkt 0x00000020
#define OHCI1394_isochTx 0x00000040
#define OHCI1394_isochRx 0x00000080
-#define OHCI1394_postedWriteErr 0x00001000
-#define OHCI1394_lockRespErr 0x00002000
+#define OHCI1394_postedWriteErr 0x00000100
+#define OHCI1394_lockRespErr 0x00000200
#define OHCI1394_selfIDComplete 0x00010000
#define OHCI1394_busReset 0x00020000
#define OHCI1394_phy 0x00080000
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index 773d68983431fb..368c5137bf8a8f 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -99,6 +99,8 @@ static pcl_t alloc_pcl(struct ti_lynx *lynx)
return -1;
}
+
+#if 0
static void free_pcl(struct ti_lynx *lynx, pcl_t pclid)
{
int off, bit;
@@ -145,6 +147,7 @@ static void print_pcl(const struct ti_lynx *lynx, pcl_t pclid)
get_pcl(lynx, pclid, &pcl);
pretty_print_pcl(&pcl);
}
+#endif
static int add_card(struct pci_dev *dev);
@@ -486,7 +489,8 @@ static int lynx_initialize(struct hpsb_host *host)
put_pcl(lynx, lynx->iso_rcv.pcl_start, &pcl);
/* 85 bytes for each FIFO - FIXME - optimize or make configurable */
- reg_write(lynx, FIFO_SIZES, 0x00555555);
+ /* reg_write(lynx, FIFO_SIZES, 0x00555555); */
+ reg_write(lynx, FIFO_SIZES, 0x002020c0);
/* 20 byte threshold before triggering PCI transfer */
reg_write(lynx, DMA_GLOBAL_REGISTER, 0x2<<24);
/* 69 byte threshold on both send FIFOs before transmitting */
@@ -597,15 +601,16 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
} else {
arg = 1 << 6;
}
-
+
+ retval = get_phy_reg(lynx, 1);
+ arg |= (retval == -1 ? 63 : retval);
+ retval = 0;
+
PRINT(KERN_INFO, lynx->id, "resetting bus on request%s",
(host->attempt_root ? " and attempting to become root"
: ""));
- spin_lock_irqsave(&lynx->phy_reg_lock, flags);
- reg_write(lynx, LINK_PHY, LINK_PHY_WRITE | LINK_PHY_ADDR(1)
- | LINK_PHY_WDATA(arg));
- spin_unlock_irqrestore(&lynx->phy_reg_lock, flags);
+ set_phy_reg(lynx, 1, arg);
break;
case GET_CYCLE_COUNTER:
@@ -705,6 +710,7 @@ static ssize_t mem_write(struct file*, const char*, size_t, loff_t*);
static struct file_operations aux_ops = {
+ owner: THIS_MODULE,
/* FIXME: should have custom llseek with bounds checking */
read: mem_read,
write: mem_write,
@@ -717,61 +723,10 @@ static struct file_operations aux_ops = {
static void aux_setup_pcls(struct ti_lynx *lynx)
{
struct ti_pcl pcl;
- unsigned long membufbus = virt_to_bus(lynx->mem_dma_buffer);
- int i;
- /* This pcl is used to start any aux transfers, the pointer to next
- points to itself to avoid a dummy pcl (the PCL engine only executes
- the next pcl on startup. The real chain is done by branch */
- pcl.next = pcl_bus(lynx, lynx->mem_pcl.start);
- pcl.buffer[0].control = PCL_CMD_BRANCH | PCL_COND_DMARDY_SET;
- pcl.buffer[0].pointer = pcl_bus(lynx, lynx->mem_pcl.max);
- pcl.buffer[1].control = PCL_CMD_BRANCH | PCL_COND_DMARDY_CLEAR;
- pcl.buffer[1].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd);
- put_pcl(lynx, lynx->mem_pcl.start, &pcl);
-
- /* let maxpcl transfer exactly 32kB */
pcl.next = PCL_NEXT_INVALID;
- for (i=0; i<8; i++) {
- pcl.buffer[i].control = 4000;
- pcl.buffer[i].pointer = membufbus + i * 4000;
- }
- pcl.buffer[0].control |= PCL_CMD_LBUS_TO_PCI /*| PCL_GEN_INTR*/;
- pcl.buffer[8].control = 768 | PCL_LAST_BUFF;
- pcl.buffer[8].pointer = membufbus + 8 * 4000;
- put_pcl(lynx, lynx->mem_pcl.max, &pcl);
-
-
- /* magic stuff - self and modpcl modifying pcl */
- pcl.next = pcl_bus(lynx, lynx->mem_pcl.mod);
- pcl.user_data = 4000;
- pcl.buffer[0].control = PCL_CMD_LOAD;
- pcl.buffer[0].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd)
- + pcloffs(user_data);
- pcl.buffer[1].control = PCL_CMD_STOREQ;
- pcl.buffer[1].pointer = pcl_bus(lynx, lynx->mem_pcl.mod)
- + pcloffs(buffer[1].control);
- pcl.buffer[2].control = PCL_CMD_LOAD;
- pcl.buffer[2].pointer = membufbus;
- pcl.buffer[3].control = PCL_CMD_STOREQ;
- pcl.buffer[3].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd)
- + pcloffs(buffer[1].pointer);
- pcl.buffer[4].control = PCL_CMD_STOREQ;
- pcl.buffer[4].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd)
- + pcloffs(buffer[6].pointer);
- pcl.buffer[5].control = PCL_CMD_LOAD;
- pcl.buffer[5].pointer = membufbus + 4;
- pcl.buffer[6].control = PCL_CMD_STOREQ | PCL_LAST_CMD;
- put_pcl(lynx, lynx->mem_pcl.cmd, &pcl);
-
- /* modified by cmdpcl when actual transfer occurs */
- pcl.next = PCL_NEXT_INVALID;
- pcl.buffer[0].control = PCL_CMD_LBUS_TO_PCI; /* null transfer */
- for (i=1; i<13; i++) {
- pcl.buffer[i].control = 4000;
- pcl.buffer[i].pointer = membufbus + (i-1) * 4000;
- }
- put_pcl(lynx, lynx->mem_pcl.mod, &pcl);
+ pcl.user_data = pcl_bus(lynx, lynx->dmem_pcl);
+ put_pcl(lynx, lynx->dmem_pcl, &pcl);
}
static int mem_open(struct inode *inode, struct file *file)
@@ -779,24 +734,19 @@ static int mem_open(struct inode *inode, struct file *file)
int cid = MINOR(inode->i_rdev);
enum { rom, aux, ram } type;
struct memdata *md;
-
- MOD_INC_USE_COUNT;
if (cid < PCILYNX_MINOR_AUX_START) {
/* just for completeness */
- MOD_DEC_USE_COUNT;
return -ENXIO;
} else if (cid < PCILYNX_MINOR_ROM_START) {
cid -= PCILYNX_MINOR_AUX_START;
if (cid >= num_of_cards || !cards[cid].aux_port) {
- MOD_DEC_USE_COUNT;
return -ENXIO;
}
type = aux;
} else if (cid < PCILYNX_MINOR_RAM_START) {
cid -= PCILYNX_MINOR_ROM_START;
if (cid >= num_of_cards || !cards[cid].local_rom) {
- MOD_DEC_USE_COUNT;
return -ENXIO;
}
type = rom;
@@ -805,7 +755,6 @@ static int mem_open(struct inode *inode, struct file *file)
* It is currently used inside the driver! */
cid -= PCILYNX_MINOR_RAM_START;
if (cid >= num_of_cards || !cards[cid].local_ram) {
- MOD_DEC_USE_COUNT;
return -ENXIO;
}
type = ram;
@@ -813,7 +762,6 @@ static int mem_open(struct inode *inode, struct file *file)
md = (struct memdata *)vmalloc(sizeof(struct memdata));
if (md == NULL) {
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
@@ -828,7 +776,8 @@ static int mem_open(struct inode *inode, struct file *file)
md->type = ram;
break;
case aux:
- md->aux_intr_last_seen = atomic_read(&cards[cid].aux_intr_seen);
+ atomic_set(&md->aux_intr_last_seen,
+ atomic_read(&cards[cid].aux_intr_seen));
md->type = aux;
break;
}
@@ -844,7 +793,6 @@ static int mem_release(struct inode *inode, struct file *file)
vfree(md);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -862,11 +810,9 @@ static unsigned int aux_poll(struct file *file, poll_table *pt)
poll_wait(file, &cards[cid].aux_intr_wait, pt);
intr_seen = atomic_read(&cards[cid].aux_intr_seen);
- if (md->aux_intr_last_seen != intr_seen) {
+ if (atomic_read(&md->aux_intr_last_seen) != intr_seen) {
mask |= POLLPRI;
- /* md->aux_intr_last_seen = intr_seen; */
- md->aux_intr_last_seen++; /* don't miss interrupts */
- /* FIXME - make ioctl for configuring this */
+ atomic_inc(&md->aux_intr_last_seen);
}
}
@@ -882,38 +828,104 @@ static unsigned int aux_poll(struct file *file, poll_table *pt)
short mem_mindma = 2400;
MODULE_PARM(mem_mindma, "h");
+static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count,
+ int offset)
+{
+ pcltmp_t pcltmp;
+ struct ti_pcl *pcl;
+ size_t retval;
+ int i;
+ DECLARE_WAITQUEUE(wait, current);
+
+ //printk("buf 0x%08x %x count %d offset %d\n", physbuf, physbuf % 3, count, offset);
+
+ count &= ~3;
+ count = MIN(count, 53196);
+ retval = count;
+
+ if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS))
+ & DMA_CHAN_CTRL_BUSY) {
+ PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!");
+ }
+
+ switch (md->type) {
+ case rom:
+ reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_ROM | offset);
+ break;
+ case ram:
+ reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_RAM | offset);
+ break;
+ case aux:
+ reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_AUX | offset);
+ break;
+ }
+
+ pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp);
+ pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | MIN(count, 4092);
+ pcl->buffer[0].pointer = physbuf;
+ count -= 4092;
+
+ i = 0;
+ while (count > 0) {
+ i++;
+ pcl->buffer[i].control = MIN(count, 4092);
+ pcl->buffer[i].pointer = physbuf + i * 4092;
+ count -= 4092;
+ }
+ pcl->buffer[i].control |= PCL_LAST_BUFF;
+ commit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait);
+ run_sub_pcl(md->lynx, md->lynx->dmem_pcl, 2, CHANNEL_LOCALBUS);
+
+ schedule();
+ while (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS))
+ & DMA_CHAN_CTRL_BUSY) {
+ if (signal_pending(current)) {
+ retval = -EINTR;
+ break;
+ }
+ schedule();
+ }
+
+ reg_write(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS), 0);
+ remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait);
+
+ if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS))
+ & DMA_CHAN_CTRL_BUSY) {
+ PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!");
+ }
+
+ return retval;
+}
+
static ssize_t mem_read(struct file *file, char *buffer, size_t count,
loff_t *offset)
{
struct memdata *md = (struct memdata *)file->private_data;
- size_t bcount;
+ ssize_t bcount;
size_t alignfix;
int off = (int)*offset; /* avoid useless 64bit-arithmetic */
+ ssize_t retval;
void *membase;
- DECLARE_WAITQUEUE(wait, current);
-
- if ((off + count) > PCILYNX_MAX_MEMORY+1) {
- count = PCILYNX_MAX_MEMORY+1 - off;
+ if ((off + count) > PCILYNX_MAX_MEMORY + 1) {
+ count = PCILYNX_MAX_MEMORY + 1 - off;
}
if (count <= 0) {
return 0;
}
- down(&md->lynx->mem_dma_mutex);
-
switch (md->type) {
case rom:
- reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_ROM | off);
membase = md->lynx->local_rom;
break;
case ram:
- reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_RAM | off);
membase = md->lynx->local_ram;
break;
case aux:
- reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_AUX | off);
membase = md->lynx->aux_port;
break;
default:
@@ -921,89 +933,49 @@ static ssize_t mem_read(struct file *file, char *buffer, size_t count,
md->lynx->id, md->type);
}
+ down(&md->lynx->mem_dma_mutex);
+
if (count < mem_mindma) {
memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count);
- copy_to_user(buffer, md->lynx->mem_dma_buffer, count);
- bcount = 0;
- goto done;
+ goto out;
}
-
+
bcount = count;
alignfix = 4 - (off % 4);
if (alignfix != 4) {
if (bcount < alignfix) {
alignfix = bcount;
}
- memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, alignfix);
- copy_to_user(buffer, md->lynx->mem_dma_buffer, alignfix);
+ memcpy_fromio(md->lynx->mem_dma_buffer, membase+off,
+ alignfix);
if (bcount == alignfix) {
- goto done;
+ goto out;
}
bcount -= alignfix;
- buffer += alignfix;
off += alignfix;
}
- if (reg_read(md->lynx, DMA0_CHAN_CTRL) & DMA_CHAN_CTRL_BUSY) {
- PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!");
- }
-
- add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait);
-
- if (bcount > 32768) {
- current->state = TASK_INTERRUPTIBLE;
+ while (bcount >= 4) {
+ retval = mem_dmaread(md, virt_to_phys(md->lynx->mem_dma_buffer)
+ + count - bcount, bcount, off);
+ if (retval < 0) return retval;
- reg_write(md->lynx, DMA0_READY, 1); /* select maxpcl */
- run_pcl(md->lynx, md->lynx->mem_pcl.start, 0);
-
- while (reg_read(md->lynx, DMA0_CHAN_CTRL)
- & DMA_CHAN_CTRL_BUSY) {
- if (signal_pending(current)) {
- reg_write(md->lynx, DMA0_CHAN_CTRL, 0);
- goto rmwait_done;
- }
- schedule();
- }
-
- copy_to_user(buffer, md->lynx->mem_dma_buffer, 32768);
- buffer += 32768;
- bcount -= 32768;
- }
-
- *(u32 *)(md->lynx->mem_dma_buffer) =
- pcl_bus(md->lynx, md->lynx->mem_pcl.mod)
- + pcloffs(buffer[bcount/4000+1].control);
- *(u32 *)(md->lynx->mem_dma_buffer+4) = PCL_LAST_BUFF | (bcount % 4000);
-
- current->state = TASK_INTERRUPTIBLE;
-
- reg_write(md->lynx, DMA0_READY, 0);
- run_pcl(md->lynx, md->lynx->mem_pcl.start, 0);
-
- while (reg_read(md->lynx, DMA0_CHAN_CTRL) & DMA_CHAN_CTRL_BUSY) {
- if (signal_pending(current)) {
- reg_write(md->lynx, DMA0_CHAN_CTRL, 0);
- goto rmwait_done;
- }
- schedule();
+ bcount -= retval;
+ off += retval;
}
- copy_to_user(buffer, md->lynx->mem_dma_buffer, bcount);
- bcount = 0;
-
- if (reg_read(md->lynx, DMA0_CHAN_CTRL) & DMA_CHAN_CTRL_BUSY) {
- PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!");
+ if (bcount) {
+ memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount,
+ membase+off, bcount);
}
- rmwait_done:
- reg_write(md->lynx, DMA0_CHAN_CTRL, 0);
- remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait);
- done:
+ out:
+ retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count);
up(&md->lynx->mem_dma_mutex);
- count -= bcount;
+ if (retval < 0) return retval;
*offset += count;
- return (count ? count : -EINTR);
+ return count;
}
@@ -1200,6 +1172,12 @@ static void iso_rcv_bh(struct ti_lynx *lynx)
data = lynx->iso_rcv.page[idx / ISORCV_PER_PAGE]
+ (idx % ISORCV_PER_PAGE) * MAX_ISORCV_SIZE;
+ if ((*data >> 16) + 4 != (lynx->iso_rcv.stat[idx] & 0x1fff)) {
+ PRINT(KERN_ERR, lynx->id,
+ "iso length mismatch 0x%08x/0x%08x", *data,
+ lynx->iso_rcv.stat[idx]);
+ }
+
if (lynx->iso_rcv.stat[idx]
& (DMA_CHAN_STAT_PCIERR | DMA_CHAN_STAT_PKTERR)) {
PRINT(KERN_INFO, lynx->id,
@@ -1224,11 +1202,12 @@ static void iso_rcv_bh(struct ti_lynx *lynx)
static int add_card(struct pci_dev *dev)
{
-#define FAIL(fmt, args...) \
+#define FAIL(fmt, args...) do { \
PRINT_G(KERN_ERR, fmt , ## args); \
num_of_cards--; \
remove_card(lynx); \
- return 1
+ return 1; \
+ } while (0)
struct ti_lynx *lynx; /* shortcut to currently handled device */
unsigned long page;
@@ -1246,6 +1225,9 @@ static int add_card(struct pci_dev *dev)
lynx->id = num_of_cards-1;
lynx->dev = dev;
+ if (pci_enable_device(dev)) {
+ FAIL("failed to enable PCILynx hardware %d", lynx->id);
+ }
pci_set_master(dev);
if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ,
@@ -1271,7 +1253,7 @@ static int add_card(struct pci_dev *dev)
}
#endif
- lynx->mem_dma_buffer = kmalloc(32768, GFP_KERNEL);
+ lynx->mem_dma_buffer = kmalloc(65536, GFP_KERNEL);
if (lynx->mem_dma_buffer != NULL) {
lynx->state = have_aux_buf;
} else {
@@ -1301,15 +1283,15 @@ static int add_card(struct pci_dev *dev)
lynx->local_ram = ioremap(dev->base_address[1], PCILYNX_MAX_MEMORY);
lynx->aux_port = ioremap(dev->base_address[2], PCILYNX_MAX_MEMORY);
#else
- lynx->registers = ioremap_nocache(dev->resource[0].start,
+ lynx->registers = ioremap_nocache(pci_resource_start(dev,0),
PCILYNX_MAX_REGISTER);
- lynx->local_ram = ioremap(dev->resource[1].start, PCILYNX_MAX_MEMORY);
- lynx->aux_port = ioremap(dev->resource[2].start, PCILYNX_MAX_MEMORY);
+ lynx->local_ram = ioremap(pci_resource_start(dev,1), PCILYNX_MAX_MEMORY);
+ lynx->aux_port = ioremap(pci_resource_start(dev,2), PCILYNX_MAX_MEMORY);
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,15)
lynx->local_rom = ioremap(dev->rom_address, PCILYNX_MAX_MEMORY);
#else
- lynx->local_rom = ioremap(dev->resource[PCI_ROM_RESOURCE].start,
+ lynx->local_rom = ioremap(pci_resource_start(dev,PCI_ROM_RESOURCE),
PCILYNX_MAX_MEMORY);
#endif
lynx->state = have_iomappings;
@@ -1328,12 +1310,8 @@ static int add_card(struct pci_dev *dev)
/* alloc_pcl return values are not checked, it is expected that the
* provided PCL space is sufficient for the initial allocations */
if (lynx->aux_port != NULL) {
- lynx->mem_pcl.start = alloc_pcl(lynx);
- lynx->mem_pcl.cmd = alloc_pcl(lynx);
- lynx->mem_pcl.mod = alloc_pcl(lynx);
- lynx->mem_pcl.max = alloc_pcl(lynx);
+ lynx->dmem_pcl = alloc_pcl(lynx);
aux_setup_pcls(lynx);
-
sema_init(&lynx->mem_dma_mutex, 1);
}
lynx->rcv_pcl = alloc_pcl(lynx);
diff --git a/drivers/ieee1394/pcilynx.h b/drivers/ieee1394/pcilynx.h
index f8154bb42c958c..cf45d8d0a22a18 100644
--- a/drivers/ieee1394/pcilynx.h
+++ b/drivers/ieee1394/pcilynx.h
@@ -19,7 +19,7 @@
#define ISORCV_PER_PAGE (PAGE_SIZE / MAX_ISORCV_SIZE)
#define ISORCV_PAGES (NUM_ISORCV_PCL / ISORCV_PER_PAGE)
-/* only iso rcv uses these definitions so far */
+/* only iso rcv and localbus use these definitions so far */
#define CHANNEL_LOCALBUS 0
#define CHANNEL_ASYNC_RCV 1
#define CHANNEL_ISO_RCV 2
@@ -70,9 +70,7 @@ struct ti_lynx {
#endif
/* PCLs for local mem / aux transfers */
- struct {
- pcl_t start, cmd, mod, max;
- } mem_pcl;
+ pcl_t dmem_pcl;
/* IEEE-1394 part follows */
struct hpsb_host *host;
@@ -105,7 +103,7 @@ struct ti_lynx {
struct memdata {
struct ti_lynx *lynx;
int cid;
- int aux_intr_last_seen;
+ atomic_t aux_intr_last_seen;
enum { rom, aux, ram } type;
};
@@ -415,6 +413,38 @@ inline static u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid)
#endif /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */
+#if defined (CONFIG_IEEE1394_PCILYNX_LOCALRAM) || defined (__BIG_ENDIAN)
+typedef struct ti_pcl pcltmp_t;
+
+inline static struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid,
+ pcltmp_t *tmp)
+{
+ get_pcl(lynx, pclid, tmp);
+ return tmp;
+}
+
+inline static void commit_pcl(const struct ti_lynx *lynx, pcl_t pclid,
+ pcltmp_t *tmp)
+{
+ put_pcl(lynx, pclid, tmp);
+}
+
+#else
+typedef int pcltmp_t; /* just a dummy */
+
+inline static struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid,
+ pcltmp_t *tmp)
+{
+ return lynx->pcl_mem + pclid * sizeof(struct ti_pcl);
+}
+
+inline static void commit_pcl(const struct ti_lynx *lynx, pcl_t pclid,
+ pcltmp_t *tmp)
+{
+}
+#endif
+
+
inline static void run_sub_pcl(const struct ti_lynx *lynx, pcl_t pclid, int idx,
int dmachan)
{
@@ -464,73 +494,73 @@ inline static void run_pcl(const struct ti_lynx *lynx, pcl_t pclid, int dmachan)
#define _(x) (__constant_cpu_to_be32(x))
-quadlet_t lynx_csr_rom[] = {
- /* bus info block */
- _(0x04040000), /* info/CRC length, CRC */
- _(0x31333934), /* 1394 magic number */
- _(0xf064a000), /* misc. settings */
- _(0x08002850), /* vendor ID, chip ID high */
- _(0x0000ffff), /* chip ID low */
- /* root directory */
- _(0x00090000), /* CRC length, CRC */
- _(0x03080028), /* vendor ID (Texas Instr.) */
- _(0x81000009), /* offset to textual ID */
- _(0x0c000200), /* node capabilities */
- _(0x8d00000e), /* offset to unique ID */
- _(0xc7000010), /* offset to module independent info */
- _(0x04000000), /* module hardware version */
- _(0x81000026), /* offset to textual ID */
- _(0x09000000), /* node hardware version */
- _(0x81000026), /* offset to textual ID */
- /* module vendor ID textual */
- _(0x00080000), /* CRC length, CRC */
- _(0x00000000),
- _(0x00000000),
- _(0x54455841), /* "Texas Instruments" */
- _(0x5320494e),
- _(0x53545255),
- _(0x4d454e54),
- _(0x53000000),
- /* node unique ID leaf */
- _(0x00020000), /* CRC length, CRC */
- _(0x08002850), /* vendor ID, chip ID high */
- _(0x0000ffff), /* chip ID low */
- /* module dependent info */
- _(0x00060000), /* CRC length, CRC */
- _(0xb8000006), /* offset to module textual ID */
- _(0x81000004), /* ??? textual descriptor */
- _(0x39010000), /* SRAM size */
- _(0x3a010000), /* AUXRAM size */
- _(0x3b000000), /* AUX device */
- /* module textual ID */
- _(0x00050000), /* CRC length, CRC */
- _(0x00000000),
- _(0x00000000),
- _(0x54534231), /* "TSB12LV21" */
- _(0x324c5632),
- _(0x31000000),
- /* part number */
- _(0x00060000), /* CRC length, CRC */
- _(0x00000000),
- _(0x00000000),
- _(0x39383036), /* "9806000-0001" */
- _(0x3030342d),
- _(0x30303431),
- _(0x20000001),
- /* module hardware version textual */
- _(0x00050000), /* CRC length, CRC */
- _(0x00000000),
- _(0x00000000),
- _(0x5453424b), /* "TSBKPCITST" */
- _(0x50434954),
- _(0x53540000),
- /* node hardware version textual */
- _(0x00050000), /* CRC length, CRC */
- _(0x00000000),
- _(0x00000000),
- _(0x54534232), /* "TSB21LV03" */
- _(0x313c5630),
- _(0x33000000)
+static quadlet_t lynx_csr_rom[] = {
+/* bus info block offset (hex) */
+ _(0x04040000), /* info/CRC length, CRC 400 */
+ _(0x31333934), /* 1394 magic number 404 */
+ _(0xf064a000), /* misc. settings 408 */
+ _(0x08002850), /* vendor ID, chip ID high 40c */
+ _(0x0000ffff), /* chip ID low 410 */
+/* root directory */
+ _(0x00090000), /* directory length, CRC 414 */
+ _(0x03080028), /* vendor ID (Texas Instr.) 418 */
+ _(0x81000008), /* offset to textual ID 41c */
+ _(0x0c000200), /* node capabilities 420 */
+ _(0x8d00000e), /* offset to unique ID 424 */
+ _(0xc7000010), /* offset to module independent info 428 */
+ _(0x04000000), /* module hardware version 42c */
+ _(0x81000014), /* offset to textual ID 430 */
+ _(0x09000000), /* node hardware version 434 */
+ _(0x81000018), /* offset to textual ID 438 */
+ /* module vendor ID textual */
+ _(0x00070000), /* CRC length, CRC 43c */
+ _(0x00000000), /* 440 */
+ _(0x00000000), /* 444 */
+ _(0x54455841), /* "Texas Instruments" 448 */
+ _(0x5320494e), /* 44c */
+ _(0x53545255), /* 450 */
+ _(0x4d454e54), /* 454 */
+ _(0x53000000), /* 458 */
+/* node unique ID leaf */
+ _(0x00020000), /* CRC length, CRC 45c */
+ _(0x08002850), /* vendor ID, chip ID high 460 */
+ _(0x0000ffff), /* chip ID low 464 */
+/* module dependent info */
+ _(0x00050000), /* CRC length, CRC 468 */
+ _(0x81000012), /* offset to module textual ID 46c */
+ _(0x81000017), /* textual descriptor 470 */
+ _(0x39010000), /* SRAM size 474 */
+ _(0x3a010000), /* AUXRAM size 478 */
+ _(0x3b000000), /* AUX device 47c */
+/* module textual ID */
+ _(0x00050000), /* CRC length, CRC 480 */
+ _(0x00000000), /* 484 */
+ _(0x00000000), /* 488 */
+ _(0x54534231), /* "TSB12LV21" 48c */
+ _(0x324c5632), /* 490 */
+ _(0x31000000), /* 494 */
+/* part number */
+ _(0x00060000), /* CRC length, CRC 498 */
+ _(0x00000000), /* 49c */
+ _(0x00000000), /* 4a0 */
+ _(0x39383036), /* "9806000-0001" 4a4 */
+ _(0x3030302d), /* 4a8 */
+ _(0x30303031), /* 4ac */
+ _(0x20000001), /* 4b0 */
+/* module hardware version textual */
+ _(0x00050000), /* CRC length, CRC 4b4 */
+ _(0x00000000), /* 4b8 */
+ _(0x00000000), /* 4bc */
+ _(0x5453424b), /* "TSBKPCITST" 4c0 */
+ _(0x50434954), /* 4c4 */
+ _(0x53540000), /* 4c8 */
+/* node hardware version textual */
+ _(0x00050000), /* CRC length, CRC 4d0 */
+ _(0x00000000), /* 4d4 */
+ _(0x00000000), /* 4d8 */
+ _(0x54534232), /* "TSB21LV03" 4dc */
+ _(0x314c5630), /* 4e0 */
+ _(0x33000000) /* 4e4 */
};
#undef _
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 4a994aba5a4c91..523f5d39397a3d 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -575,8 +575,8 @@ static int handle_local_request(struct file_info *fi,
break;
case RAW1394_REQ_LOCK:
- if ((req->req.misc != EXTCODE_FETCH_ADD)
- && (req->req.misc != EXTCODE_LITTLE_ADD)) {
+ if ((req->req.misc == EXTCODE_FETCH_ADD)
+ || (req->req.misc == EXTCODE_LITTLE_ADD)) {
if (req->req.length != 4) {
req->req.error = RAW1394_ERROR_INVALID_ARG;
break;
@@ -667,8 +667,8 @@ static int handle_remote_request(struct file_info *fi,
break;
case RAW1394_REQ_LOCK:
- if ((req->req.misc != EXTCODE_FETCH_ADD)
- && (req->req.misc != EXTCODE_LITTLE_ADD)) {
+ if ((req->req.misc == EXTCODE_FETCH_ADD)
+ || (req->req.misc == EXTCODE_LITTLE_ADD)) {
if (req->req.length != 4) {
req->req.error = RAW1394_ERROR_INVALID_ARG;
break;
@@ -690,6 +690,7 @@ static int handle_remote_request(struct file_info *fi,
break;
}
+ req->data = packet->data;
req->req.length = 4;
break;
@@ -716,6 +717,7 @@ static int handle_remote_request(struct file_info *fi,
if (!hpsb_send_packet(packet)) {
req->req.error = RAW1394_ERROR_SEND_ERROR;
req->req.length = 0;
+ free_tlabel(packet->host, packet->node_id, packet->tlabel);
queue_complete_req(req);
}
return sizeof(struct raw1394_request);
@@ -843,7 +845,6 @@ static int dev_open(struct inode *inode, struct file *file)
file->private_data = fi;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -897,7 +898,6 @@ static int dev_release(struct inode *inode, struct file *file)
kfree(fi);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -910,6 +910,7 @@ static struct hpsb_highlevel_ops hl_ops = {
};
static struct file_operations file_ops = {
+ owner: THIS_MODULE,
read: dev_read,
write: dev_write,
poll: dev_poll,
diff --git a/drivers/ieee1394/video1394.h b/drivers/ieee1394/video1394.h
new file mode 100644
index 00000000000000..47b8e64a28c207
--- /dev/null
+++ b/drivers/ieee1394/video1394.h
@@ -0,0 +1,50 @@
+/*
+ * video1394.h - driver for OHCI 1394 boards
+ * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _VIDEO_1394_H
+#define _VIDEO_1394_H
+
+#define VIDEO1394_MAX_SIZE 0x400000
+
+enum {
+ VIDEO1394_BUFFER_FREE = 0,
+ VIDEO1394_BUFFER_QUEUED,
+ VIDEO1394_BUFFER_READY
+};
+
+enum {
+ VIDEO1394_LISTEN_CHANNEL = 0,
+ VIDEO1394_UNLISTEN_CHANNEL,
+ VIDEO1394_QUEUE_BUFFER,
+ VIDEO1394_WAIT_BUFFER
+};
+
+struct video1394_mmap {
+ int channel;
+ int sync_tag;
+ int nb_buffers;
+ int buf_size;
+};
+
+struct video1394_wait {
+ int channel;
+ int buffer;
+};
+
+#endif
diff --git a/drivers/isdn/avmb1/b1pci.c b/drivers/isdn/avmb1/b1pci.c
index c82de87172ea7b..e98066806f404e 100644
--- a/drivers/isdn/avmb1/b1pci.c
+++ b/drivers/isdn/avmb1/b1pci.c
@@ -466,12 +466,15 @@ static int add_card(struct pci_dev *dev)
struct capicardparams param;
int retval;
- if (dev->resource[ 2].start & PCI_BASE_ADDRESS_IO_MASK) { /* B1 PCI V4 */
+ if (pci_enable_device(dev))
+ return 0; /* return failure */
+
+ if (pci_resource_flags(dev, 2) & IORESOURCE_IO) { /* B1 PCI V4 */
#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
driver = &b1pciv4_driver;
#endif
- param.membase = dev->resource[ 0].start & PCI_BASE_ADDRESS_MEM_MASK;
- param.port = dev->resource[ 2].start & PCI_BASE_ADDRESS_IO_MASK;
+ param.membase = pci_resource_start (dev, 0);
+ param.port = pci_resource_start (dev, 2);
param.irq = dev->irq;
printk(KERN_INFO
"%s: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
@@ -488,7 +491,7 @@ static int add_card(struct pci_dev *dev)
}
} else {
param.membase = 0;
- param.port = dev->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK;
+ param.port = pci_resource_start (dev, 1);
param.irq = dev->irq;
printk(KERN_INFO
"%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
diff --git a/drivers/isdn/avmb1/c4.c b/drivers/isdn/avmb1/c4.c
index e3fcabf9b92885..104c0f5ccd350f 100644
--- a/drivers/isdn/avmb1/c4.c
+++ b/drivers/isdn/avmb1/c4.c
@@ -1333,9 +1333,12 @@ int c4_init(void)
PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, dev))) {
struct capicardparams param;
- param.port = dev->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK;
+ if (pci_enable_device(dev))
+ continue;
+
+ param.port = pci_resource_start (dev, 1);
param.irq = dev->irq;
- param.membase = dev->resource[ 0].start & PCI_BASE_ADDRESS_MEM_MASK;
+ param.membase = pci_resource_start (dev, 0);
printk(KERN_INFO
"%s: PCI BIOS reports AVM-C4 at i/o %#x, irq %d, mem %#x\n",
diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c
index 06c0686af8cd2f..638dc2f9e6f383 100644
--- a/drivers/isdn/avmb1/capi.c
+++ b/drivers/isdn/avmb1/capi.c
@@ -653,6 +653,7 @@ int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
datahandle, skb->len);
#endif
mp->tty->ldisc.receive_buf(mp->tty, skb->data, 0, skb->len);
+ kfree_skb(skb);
return 0;
} else if (mp->file) {
diff --git a/drivers/isdn/avmb1/kcapi.c b/drivers/isdn/avmb1/kcapi.c
index 6da2d24c1a2d16..848f4af9736c82 100644
--- a/drivers/isdn/avmb1/kcapi.c
+++ b/drivers/isdn/avmb1/kcapi.c
@@ -354,7 +354,7 @@ endloop:
*eof = 1;
if (off >= len+begin)
return 0;
- *start = page + (begin-off);
+ *start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
@@ -385,7 +385,7 @@ endloop:
*eof = 1;
if (off >= len+begin)
return 0;
- *start = page + (begin-off);
+ *start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
@@ -422,7 +422,7 @@ endloop:
*eof = 1;
if (off >= len+begin)
return 0;
- *start = page + (begin-off);
+ *start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
@@ -459,7 +459,7 @@ endloop:
*eof = 1;
if (off >= len+begin)
return 0;
- *start = page + (begin-off);
+ *start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
@@ -496,7 +496,7 @@ endloop:
*eof = 1;
if (off >= len+begin)
return 0;
- *start = page + (begin-off);
+ *start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
diff --git a/drivers/isdn/avmb1/t1pci.c b/drivers/isdn/avmb1/t1pci.c
index 70355abcaa3e47..37ed305c25ba22 100644
--- a/drivers/isdn/avmb1/t1pci.c
+++ b/drivers/isdn/avmb1/t1pci.c
@@ -305,12 +305,13 @@ int t1pci_init(void)
while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, dev))) {
struct capicardparams param;
+ if (pci_enable_device(dev))
+ continue;
+
param.port = pci_resource_start (dev, 1);
param.irq = dev->irq;
param.membase = pci_resource_start (dev, 0);
- pci_enable_device (dev); /* XXX check return */
-
printk(KERN_INFO
"%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n",
driver->name, param.port, param.irq, param.membase);
diff --git a/drivers/isdn/eicon/eicon_pci.c b/drivers/isdn/eicon/eicon_pci.c
index 47196f953a018f..e696b55844e18b 100644
--- a/drivers/isdn/eicon/eicon_pci.c
+++ b/drivers/isdn/eicon/eicon_pci.c
@@ -148,6 +148,8 @@ int eicon_pci_find_card(char *ID)
}
}
+ pci_enable_device(pdev); /* XXX handle error return */
+
pci_akt = 0;
switch(pci_type)
{
@@ -156,8 +158,8 @@ int eicon_pci_find_card(char *ID)
aparms->type = EICON_CTYPE_MAESTRA;
aparms->irq = pdev->irq;
- preg = pdev->resource[ 2].start & 0xfffffffc;
- pcfg = pdev->resource[ 1].start & 0xffffff80;
+ preg = pci_resource_start(pdev, 2);
+ pcfg = pci_resource_start(pdev, 1);
#ifdef EICON_PCI_DEBUG
printk(KERN_DEBUG "eicon_pci: irq=%d\n", aparms->irq);
@@ -178,9 +180,9 @@ int eicon_pci_find_card(char *ID)
printk(KERN_INFO "Eicon: DIVA Server PRI/PCI detected !\n");
aparms->type = EICON_CTYPE_MAESTRAP; /*includes 9M,30M*/
aparms->irq = pdev->irq;
- pram = pdev->resource[ 0].start & 0xfffff000;
- preg = pdev->resource[ 2].start & 0xfffff000;
- pcfg = pdev->resource[ 4].start & 0xfffff000;
+ pram = pci_resource_start(pdev, 0);
+ preg = pci_resource_start(pdev, 2);
+ pcfg = pci_resource_start(pdev, 4);
#ifdef EICON_PCI_DEBUG
printk(KERN_DEBUG "eicon_pci: irq=%d\n", aparms->irq);
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index d87c43f3783475..5af207b5eb9474 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -820,11 +820,12 @@ setup_avm_pcipnp(struct IsdnCard *card))
PCI_FRITZPCI_ID, dev_avm))) {
cs->irq = dev_avm->irq;
if (!cs->irq) {
- printk(KERN_WARNING "FritzPCI: No IRQ for PCI card found\n");
+ printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n");
return(0);
}
- cs->hw.avm.cfg_reg = dev_avm->resource[ 1].start &
- PCI_BASE_ADDRESS_IO_MASK;
+ if (pci_enable_device(dev_avm))
+ return(0);
+ cs->hw.avm.cfg_reg = pci_resource_start (dev_avm, 1);
if (!cs->hw.avm.cfg_reg) {
printk(KERN_WARNING "FritzPCI: No IO-Adr for PCI card found\n");
return(0);
diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c
index ce02a1bc679c7f..6221cc19729c17 100644
--- a/drivers/isdn/hisax/bkm_a4t.c
+++ b/drivers/isdn/hisax/bkm_a4t.c
@@ -319,11 +319,13 @@ __initfunc(int
if ((dev_a4t = pci_find_device(I20_VENDOR_ID, I20_DEVICE_ID, dev_a4t))) {
u_int sub_sys_id = 0;
+ if (pci_enable_device(dev_a4t))
+ return (0);
pci_read_config_dword(dev_a4t, PCI_SUBSYSTEM_VENDOR_ID,
&sub_sys_id);
if (sub_sys_id == ((A4T_SUBSYS_ID << 16) | A4T_SUBVEN_ID)) {
found = 1;
- pci_memaddr = dev_a4t->resource[ 0].start;
+ pci_memaddr = pci_resource_start (dev_a4t, 0);
cs->irq = dev_a4t->irq;
}
}
@@ -339,7 +341,6 @@ __initfunc(int
printk(KERN_WARNING "HiSax: %s: No Memory base address\n", CardType[card->typ]);
return (0);
}
- pci_memaddr &= PCI_BASE_ADDRESS_MEM_MASK;
cs->hw.ax.base = (u_int) ioremap(pci_memaddr, 4096);
/* Check suspecious address */
pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base);
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index 30c6331a504fdb..43a4dc0c16a779 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -936,26 +936,28 @@ setup_diva(struct IsdnCard *card))
cs->subtyp = 0;
if ((dev_diva = pci_find_device(PCI_VENDOR_EICON_DIEHL,
PCI_DIVA20_ID, dev_diva))) {
+ if (pci_enable_device(dev_diva))
+ return (0);
cs->subtyp = DIVA_PCI;
cs->irq = dev_diva->irq;
- cs->hw.diva.cfg_reg = dev_diva->resource[ 2].start
- & PCI_BASE_ADDRESS_IO_MASK;
+ cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
} else if ((dev_diva_u = pci_find_device(PCI_VENDOR_EICON_DIEHL,
PCI_DIVA20_U_ID, dev_diva_u))) {
+ if (pci_enable_device(dev_diva_u))
+ return (0);
cs->subtyp = DIVA_PCI;
cs->irq = dev_diva_u->irq;
- cs->hw.diva.cfg_reg = dev_diva_u->resource[ 2].start
- & PCI_BASE_ADDRESS_IO_MASK;
+ cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
} else if ((dev_diva201 = pci_find_device(PCI_VENDOR_EICON_DIEHL,
PCI_DIVA_201, dev_diva201))) {
+ if (pci_enable_device(dev_diva201))
+ return (0);
cs->subtyp = DIVA_IPAC_PCI;
cs->irq = dev_diva201->irq;
cs->hw.diva.pci_cfg =
- (ulong) ioremap((dev_diva201->resource[ 0].start
- & PCI_BASE_ADDRESS_IO_MASK), 4096);
+ (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096);
cs->hw.diva.cfg_reg =
- (ulong) ioremap((dev_diva201->resource[ 1].start
- & PCI_BASE_ADDRESS_IO_MASK), 4096);
+ (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
} else {
printk(KERN_WARNING "Diva: No PCI card found\n");
return(0);
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 1e425ccc580611..3c78e04a7bdd7f 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -1058,20 +1058,20 @@ setup_elsa(struct IsdnCard *card)
cs->subtyp = 0;
if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ELSA, PCI_QS1000_ID,
dev_qs1000))) {
- cs->subtyp = ELSA_QS1000PCI;
+ if (pci_enable_device(dev_qs1000))
+ return (0);
+ cs->subtyp = ELSA_QS1000PCI;
cs->irq = dev_qs1000->irq;
- cs->hw.elsa.cfg = dev_qs1000->resource[ 1].start &
- PCI_BASE_ADDRESS_IO_MASK;
- cs->hw.elsa.base = dev_qs1000->resource[ 3].start &
- PCI_BASE_ADDRESS_IO_MASK;
+ cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
+ cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
} else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ELSA,
PCI_QS3000_ID, dev_qs3000))) {
+ if (pci_enable_device(dev_qs1000))
+ return (0);
cs->subtyp = ELSA_QS3000PCI;
cs->irq = dev_qs3000->irq;
- cs->hw.elsa.cfg = dev_qs3000->resource[ 1].start &
- PCI_BASE_ADDRESS_IO_MASK;
- cs->hw.elsa.base = dev_qs3000->resource[ 3].start &
- PCI_BASE_ADDRESS_IO_MASK;
+ cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);
+ cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);
} else {
printk(KERN_WARNING "Elsa: No PCI card found\n");
return(0);
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index d8a2259b2d8230..ee7ef15784fdd8 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -1301,10 +1301,66 @@ MODULE_PARM(timid, "1i");
static struct net_device *dev_plip[PLIP_MAX] = { NULL, };
+static int inline
+plip_searchfor(int list[], int a)
+{
+ int i;
+ for (i = 0; i < PLIP_MAX && list[i] != -1; i++) {
+ if (list[i] == a) return 1;
+ }
+ return 0;
+}
+
+/* plip_attach() is called (by the parport code) when a port is
+ * available to use. */
+static void plip_attach (struct parport *port)
+{
+ static int i = 0;
+
+ if ((parport[0] == -1 && (!timid || !port->devices)) ||
+ plip_searchfor(parport, port->number)) {
+ if (i == PLIP_MAX) {
+ printk(KERN_ERR "plip: too many devices\n");
+ return;
+ }
+ dev_plip[i] = kmalloc(sizeof(struct net_device),
+ GFP_KERNEL);
+ if (!dev_plip[i]) {
+ printk(KERN_ERR "plip: memory squeeze\n");
+ return;
+ }
+ memset(dev_plip[i], 0, sizeof(struct net_device));
+ sprintf(dev_plip[i]->name, "plip%d", i);
+ dev_plip[i]->priv = port;
+ if (plip_init_dev(dev_plip[i],port) ||
+ register_netdev(dev_plip[i])) {
+ kfree(dev_plip[i]);
+ dev_plip[i] = NULL;
+ } else {
+ i++;
+ }
+ }
+}
+
+/* plip_detach() is called (by the parport code) when a port is
+ * no longer available to use. */
+static void plip_detach (struct parport *port)
+{
+ /* Nothing to do */
+}
+
+static struct parport_driver plip_driver = {
+ name: "plip",
+ attach: plip_attach,
+ detach: plip_detach
+};
+
static void __exit plip_cleanup_module (void)
{
int i;
+ parport_unregister_driver (&plip_driver);
+
for (i=0; i < PLIP_MAX; i++) {
if (dev_plip[i]) {
struct net_local *nl =
@@ -1314,7 +1370,6 @@ static void __exit plip_cleanup_module (void)
parport_release(nl->pardev);
parport_unregister_device(nl->pardev);
kfree(dev_plip[i]->priv);
- kfree(dev_plip[i]->name);
kfree(dev_plip[i]);
dev_plip[i] = NULL;
}
@@ -1357,21 +1412,8 @@ __setup("plip=", plip_setup);
#endif /* !MODULE */
-static int inline
-plip_searchfor(int list[], int a)
-{
- int i;
- for (i = 0; i < PLIP_MAX && list[i] != -1; i++) {
- if (list[i] == a) return 1;
- }
- return 0;
-}
-
static int __init plip_init (void)
{
- struct parport *pb = parport_enumerate();
- int i=0;
-
if (parport[0] == -2)
return 0;
@@ -1380,38 +1422,11 @@ static int __init plip_init (void)
timid = 0;
}
- /* If the user feeds parameters, use them */
- while (pb) {
- if ((parport[0] == -1 && (!timid || !pb->devices)) ||
- plip_searchfor(parport, pb->number)) {
- if (i == PLIP_MAX) {
- printk(KERN_ERR "plip: too many devices\n");
- break;
- }
- dev_plip[i] = kmalloc(sizeof(struct net_device),
- GFP_KERNEL);
- if (!dev_plip[i]) {
- printk(KERN_ERR "plip: memory squeeze\n");
- break;
- }
- memset(dev_plip[i], 0, sizeof(struct net_device));
- sprintf(dev_plip[i]->name, "plip%d", i);
- dev_plip[i]->priv = pb;
- if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) {
- kfree(dev_plip[i]->name);
- kfree(dev_plip[i]);
- dev_plip[i] = NULL;
- } else {
- i++;
- }
- }
- pb = pb->next;
- }
-
- if (i == 0) {
- printk(KERN_INFO "plip: no devices registered\n");
- return -EIO;
+ if (parport_register_driver (&plip_driver)) {
+ printk (KERN_WARNING "plip: couldn't register driver\n");
+ return 1;
}
+
return 0;
}
diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
index 9ce07690be1b35..a945167c5abb51 100644
--- a/drivers/pcmcia/yenta.c
+++ b/drivers/pcmcia/yenta.c
@@ -788,7 +788,7 @@ static int yenta_open(pci_socket_t *socket)
*/
if (pci_enable_device(dev))
return -1;
- if (!dev->resource[0].start) {
+ if (!pci_resource_start(dev, 0)) {
printk("No cardbus resource!\n");
return -1;
}
@@ -797,7 +797,7 @@ static int yenta_open(pci_socket_t *socket)
* Ok, start setup.. Map the cardbus registers,
* and request the IRQ.
*/
- socket->base = ioremap(dev->resource[0].start, 0x1000);
+ socket->base = ioremap(pci_resource_start(dev, 0), 0x1000);
if (!socket->base)
return -1;
diff --git a/drivers/sbus/audio/audio.c b/drivers/sbus/audio/audio.c
index 4c7e8003c35783..31856af31e812b 100644
--- a/drivers/sbus/audio/audio.c
+++ b/drivers/sbus/audio/audio.c
@@ -1,4 +1,4 @@
-/* $Id: audio.c,v 1.50 2000/03/13 03:54:07 davem Exp $
+/* $Id: audio.c,v 1.51 2000/06/19 06:24:47 davem Exp $
* drivers/sbus/audio/audio.c
*
* Copyright 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu)
@@ -87,8 +87,6 @@ static devfs_handle_t devfs_handle = NULL;
#include <linux/poll.h>
#define COPY_IN(arg, get) get_user(get, (int *)arg)
#define COPY_OUT(arg, ret) put_user(ret, (int *)arg)
-#define sparcaudio_release_ret sparcaudio_release
-#define sparcaudioctl_release_ret sparcaudioctl_release
#define sparcaudio_select sparcaudio_poll
#endif
@@ -1767,24 +1765,10 @@ static int sparcaudio_ioctl(struct inode * inode, struct file * file,
return retval;
}
-static int sparcaudioctl_release_ret(struct inode * inode, struct file * file)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/* For 2.0 kernels */
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-static void sparcaudioctl_release(struct inode * inode, struct file * file)
-{
- sparcaudioctl_release_ret(inode, file);
-}
-#endif
-
static struct file_operations sparcaudioctl_fops = {
+ owner: THIS_MODULE,
poll: sparcaudio_select,
ioctl: sparcaudio_ioctl,
- release: sparcaudioctl_release,
};
static int sparcaudio_open(struct inode * inode, struct file * file)
@@ -1917,13 +1901,11 @@ static int sparcaudio_open(struct inode * inode, struct file * file)
}
}
- MOD_INC_USE_COUNT;
-
/* Success! */
return 0;
}
-static int sparcaudio_release_ret(struct inode * inode, struct file * file)
+static int sparcaudio_release(struct inode * inode, struct file * file)
{
struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
SPARCAUDIO_DEVICE_SHIFT)];
@@ -1968,21 +1950,11 @@ static int sparcaudio_release_ret(struct inode * inode, struct file * file)
/* Status changed. Signal control device */
kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
- MOD_DEC_USE_COUNT;
-
wake_up_interruptible(&drv->open_wait);
return 0;
}
-/* For 2.0 kernels */
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-static void sparcaudio_release(struct inode * inode, struct file * file)
-{
- sparcaudio_release_ret(inode, file);
-}
-#endif
-
static struct file_operations sparcaudio_fops = {
llseek: sparcaudio_lseek,
read: sparcaudio_read,
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index fb18a63c173189..ba68100177ec2c 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -835,6 +835,7 @@ static int bpp_ioctl(struct inode *inode, struct file *f, unsigned int cmd,
}
static struct file_operations bpp_fops = {
+ owner: THIS_MODULE,
read: bpp_read,
write: bpp_write,
ioctl: bpp_ioctl,
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 039994471719a4..dbba073de9a2d1 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -1,4 +1,4 @@
-/* $Id: envctrl.c,v 1.16 2000/03/22 21:29:23 ecd Exp $
+/* $Id: envctrl.c,v 1.17 2000/06/19 06:24:47 davem Exp $
* envctrl.c: Temperature and Fan monitoring on Machines providing it.
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
@@ -1507,24 +1507,16 @@ static int
envctrl_open(struct inode *inode, struct file *file)
{
file->private_data = 0;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int
-envctrl_release(struct inode *inode, struct file *file)
-{
- MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations envctrl_fops = {
+ owner: THIS_MODULE,
llseek: envctrl_llseek,
read: envctrl_read,
write: envctrl_write,
ioctl: envctrl_ioctl,
open: envctrl_open,
- release: envctrl_release,
};
static struct miscdevice envctrl_dev = {
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 2e60789cfa25d0..8bdee5e0418548 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -1,4 +1,4 @@
-/* $Id: flash.c,v 1.17 2000/02/10 02:51:35 davem Exp $
+/* $Id: flash.c,v 1.18 2000/06/19 06:24:47 davem Exp $
* flash.c: Allow mmap access to the OBP Flash, for OBP updates.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -115,14 +115,12 @@ flash_open(struct inode *inode, struct file *file)
if (test_and_set_bit(0, (void *)&flash.busy) != 0)
return -EBUSY;
- MOD_INC_USE_COUNT;
return 0;
}
static int
flash_release(struct inode *inode, struct file *file)
{
- MOD_DEC_USE_COUNT;
flash.busy = 0;
return 0;
}
@@ -131,6 +129,7 @@ static struct file_operations flash_fops = {
/* no write to the Flash, use mmap
* and play flash dependent tricks.
*/
+ owner: THIS_MODULE,
llseek: flash_llseek,
read: flash_read,
mmap: flash_mmap,
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index 44692c7e903ecd..d31ef519338e75 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -479,7 +479,6 @@ static int jsf_open(struct inode * inode, struct file * filp)
if (test_and_set_bit(0, (void *)&jsf0.busy) != 0)
return -EBUSY;
- MOD_INC_USE_COUNT;
return 0; /* XXX What security? */
}
@@ -505,9 +504,6 @@ static int jsfd_open(struct inode *inode, struct file *file)
static int jsf_release(struct inode *inode, struct file *file)
{
-
- MOD_DEC_USE_COUNT;
-
jsf0.busy = 0;
return 0;
}
@@ -537,6 +533,7 @@ static int jsfd_release(struct inode *inode, struct file *file)
}
static struct file_operations jsf_fops = {
+ owner: THIS_MODULE,
llseek: jsf_lseek,
read: jsf_read,
write: jsf_write,
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 8bba6512eb38fc..38e7a2ed08530b 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -595,19 +595,17 @@ static int openprom_open(struct inode * inode, struct file * file)
data->lastnode = prom_root_node;
file->private_data = (void *)data;
- MOD_INC_USE_COUNT;
-
return 0;
}
static int openprom_release(struct inode * inode, struct file * file)
{
kfree_s(file->private_data, sizeof(DATA));
- MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations openprom_fops = {
+ owner: THIS_MODULE,
llseek: openprom_lseek,
ioctl: openprom_ioctl,
open: openprom_open,
diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c
index d1bc70d67452d1..93673e3b8a741a 100644
--- a/drivers/sbus/char/pcikbd.c
+++ b/drivers/sbus/char/pcikbd.c
@@ -1,4 +1,4 @@
-/* $Id: pcikbd.c,v 1.46 2000/05/03 06:37:05 davem Exp $
+/* $Id: pcikbd.c,v 1.48 2000/06/19 06:24:47 davem Exp $
* pcikbd.c: Ultra/AX PC keyboard support.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -737,8 +737,7 @@ void pcimouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock_irqrestore(&pcikbd_lock, flags);
- if (queue->fasync)
- kill_fasync(queue->fasync, SIGIO, POLL_IN);
+ kill_fasync(&queue->fasync, SIGIO, POLL_IN);
wake_up_interruptible(&queue->proc_list);
}
@@ -762,7 +761,6 @@ static int aux_release(struct inode * inode, struct file * file)
spin_unlock_irqrestore(&pcikbd_lock, flags);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -790,8 +788,6 @@ static int aux_open(struct inode * inode, struct file * file)
}
queue->head = queue->tail = 0; /* Flush input queue */
- MOD_INC_USE_COUNT;
-
poll_aux_status();
pcimouse_outb(KBD_CCMD_MOUSE_ENABLE, pcimouse_iobase+KBD_CNTL_REG); /* Enable Aux */
aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */
@@ -902,6 +898,7 @@ static unsigned int aux_poll(struct file *file, poll_table * wait)
}
struct file_operations psaux_fops = {
+ owner: THIS_MODULE,
read: aux_read,
write: aux_write,
poll: aux_poll,
@@ -916,6 +913,7 @@ static int aux_no_open(struct inode *inode, struct file *file)
}
struct file_operations psaux_no_fops = {
+ owner: THIS_MODULE,
open: aux_no_open,
};
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 31f3596d50424a..bda9e3a264427e 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -1,4 +1,4 @@
-/* $Id: rtc.c,v 1.19 2000/02/09 22:33:26 davem Exp $
+/* $Id: rtc.c,v 1.20 2000/06/19 06:24:47 davem Exp $
*
* Linux/SPARC Real Time Clock Driver
* Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -124,19 +124,17 @@ static int rtc_open(struct inode *inode, struct file *file)
rtc_busy = 1;
- MOD_INC_USE_COUNT;
-
return 0;
}
static int rtc_release(struct inode *inode, struct file *file)
{
- MOD_DEC_USE_COUNT;
rtc_busy = 0;
return 0;
}
static struct file_operations rtc_fops = {
+ owner: THIS_MODULE,
llseek: rtc_lseek,
ioctl: rtc_ioctl,
open: rtc_open,
diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c
index e6f0042ca63f98..5f7ea69233ec11 100644
--- a/drivers/sbus/char/sunkbd.c
+++ b/drivers/sbus/char/sunkbd.c
@@ -1310,8 +1310,7 @@ push_kbd (int scan)
}
spin_unlock_irqrestore(&kbd_queue_lock, flags);
- if (kb_fasync)
- kill_fasync (kb_fasync, SIGIO, POLL_IN);
+ kill_fasync (&kb_fasync, SIGIO, POLL_IN);
wake_up_interruptible (&kbd_wait);
}
diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c
index af23df56a11b1d..46d335c2a3591b 100644
--- a/drivers/sbus/char/sunmouse.c
+++ b/drivers/sbus/char/sunmouse.c
@@ -147,8 +147,7 @@ push_char (char c)
spin_unlock_irqrestore(&sunmouse.lock, flags);
- if (sunmouse.fasync)
- kill_fasync (sunmouse.fasync, SIGIO, POLL_IN);
+ kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN);
wake_up_interruptible (&sunmouse.proc_list);
}
@@ -382,8 +381,7 @@ sun_mouse_inbyte(unsigned char byte, int is_break)
/* We just completed a transaction, wake up whoever is awaiting
* this event.
*/
- if (sunmouse.fasync)
- kill_fasync (sunmouse.fasync, SIGIO, POLL_IN);
+ kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN);
wake_up_interruptible(&sunmouse.proc_list);
}
return;
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 78f45613dd60bb..6294d0e3774ce8 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -1,4 +1,4 @@
-/* $Id: uctrl.c,v 1.7 2000/02/09 22:33:28 davem Exp $
+/* $Id: uctrl.c,v 1.8 2000/06/19 06:24:47 davem Exp $
* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
*
* Copyright 1999 Derrick J Brashear (shadow@dementia.org)
@@ -218,19 +218,11 @@ uctrl_ioctl(struct inode *inode, struct file *file,
static int
uctrl_open(struct inode *inode, struct file *file)
{
- MOD_INC_USE_COUNT;
uctrl_get_event_status();
uctrl_get_external_status();
return 0;
}
-static int
-uctrl_release(struct inode *inode, struct file *file)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
void uctrl_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct uctrl_driver *driver = (struct uctrl_driver *)dev_id;
@@ -238,10 +230,10 @@ void uctrl_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
static struct file_operations uctrl_fops = {
+ owner: THIS_MODULE,
llseek: uctrl_llseek,
ioctl: uctrl_ioctl,
open: uctrl_open,
- release: uctrl_release,
};
static struct miscdevice uctrl_dev = {
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index a5e61bb9a3673e..dee47f98bf643d 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -190,7 +190,6 @@ static int vfc_open(struct inode *inode, struct file *file)
return -EBUSY;
dev->busy = 1;
- MOD_INC_USE_COUNT;
vfc_lock_device(dev);
vfc_csr_init(dev);
@@ -214,7 +213,6 @@ static void vfc_release(struct inode *inode,struct file *file)
if (!dev->busy)
return;
dev->busy = 0;
- MOD_DEC_USE_COUNT;
}
static int vfc_debug(struct vfc_dev *dev, int cmd, unsigned long arg)
@@ -635,6 +633,7 @@ static int vfc_lseek(struct inode *inode, struct file *file,
}
static struct file_operations vfc_fops = {
+ owner: THIS_MODULE,
llseek: vfc_lseek,
ioctl: vfc_ioctl,
mmap: vfc_mmap,
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 31adb57fad2024..b3b8d17fb94e2c 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -565,6 +565,8 @@ int tw_findcards(Scsi_Host_Template *tw_host)
dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) {
+ if (pci_enable_device(tw_pci_dev))
+ continue;
/* Prepare temporary device extension */
tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
if (tw_dev == NULL) {
@@ -582,11 +584,11 @@ int tw_findcards(Scsi_Host_Template *tw_host)
}
/* Calculate the cards register addresses */
- tw_dev->registers.base_addr = tw_pci_dev->resource[0].start;
- tw_dev->registers.control_reg_addr = (tw_pci_dev->resource[0].start & ~15);
- tw_dev->registers.status_reg_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x4);
- tw_dev->registers.command_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x8);
- tw_dev->registers.response_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0xC);
+ tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0);
+ tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0);
+ tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
+ tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
+ tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
/* Save pci_dev struct to device extension */
tw_dev->tw_pci_dev = tw_pci_dev;
diff --git a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c
index 30ad34200673ab..7a3e28f7adc3f7 100644
--- a/drivers/scsi/53c7,8xx.c
+++ b/drivers/scsi/53c7,8xx.c
@@ -1412,8 +1412,10 @@ ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip,
" perhaps you specified an incorrect PCI bus, device, or function.\n", error);
return -1;
}
- io_port = pdev->resource[0].start;
- base = pdev->resource[1].start;
+ if (pci_enable_device(pdev))
+ return -1;
+ io_port = pci_resource_start(pdev, 0);
+ base = pci_resource_start(pdev, 1);
irq = pdev->irq;
/* If any one ever clones the NCR chips, this will have to change */
diff --git a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
index 74b63bd37631b0..7abe05e6c64e65 100644
--- a/drivers/scsi/AM53C974.c
+++ b/drivers/scsi/AM53C974.c
@@ -616,27 +616,23 @@ void AM53C974_setup(char *str, int *ints)
*
* Returns : number of host adapters detected
**************************************************************************/
-static __inline__ int AM53C974_pci_detect(Scsi_Host_Template * tpnt)
+static inline int AM53C974_pci_detect(Scsi_Host_Template * tpnt)
{
int count = 0; /* number of boards detected */
struct pci_dev *pdev = NULL;
unsigned short command;
while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI, pdev))) {
+ if (pci_enable_device(pdev))
+ continue;
pci_read_config_word(pdev, PCI_COMMAND, &command);
/* check whether device is I/O mapped -- should be */
if (!(command & PCI_COMMAND_IO))
continue;
- /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
- to set the PCI Master Enable Bit if needed.
- (from Mark Stockton <marks@schooner.sys.hou.compaq.com>) */
- if (!(command & PCI_COMMAND_MASTER)) {
- command |= PCI_COMMAND_MASTER;
- printk("PCI Master Bit has not been set. Setting...\n");
- pci_write_config_word(pdev, PCI_COMMAND, command);
- }
+ pci_set_master (pdev);
+
/* everything seems OK now, so initialize */
if (AM53C974_init(tpnt, pdev))
count++;
@@ -696,7 +692,7 @@ static int __init AM53C974_init(Scsi_Host_Template * tpnt, struct pci_dev *pdev
instance = scsi_register(tpnt, sizeof(struct AM53C974_hostdata));
hostdata = (struct AM53C974_hostdata *) instance->hostdata;
instance->base = 0;
- instance->io_port = pdev->resource[0].start;
+ instance->io_port = pci_resource_start(pdev, 0);
instance->irq = pdev->irq;
instance->dma_channel = -1;
AM53C974_setio(instance);
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index aa61a55f8b25d5..c648fed02cd923 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -771,12 +771,15 @@ static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
unsigned char Bus = PCI_Device->bus->number;
unsigned char Device = PCI_Device->devfn >> 3;
unsigned int IRQ_Channel = PCI_Device->irq;
- unsigned long BaseAddress0 = PCI_Device->resource[0].start;
- unsigned long BaseAddress1 = PCI_Device->resource[1].start;
+ unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
+ unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
BusLogic_IO_Address_T IO_Address = BaseAddress0;
BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
+
+ if (pci_enable_device(PCI_Device))
+ continue;
- if (!(PCI_Device->resource[0].flags & PCI_BASE_ADDRESS_SPACE_IO))
+ if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
{
BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
"MultiMaster Host Adapter\n", NULL, BaseAddress0);
@@ -784,7 +787,7 @@ static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
NULL, Bus, Device, IO_Address);
continue;
}
- if (PCI_Device->resource[1].flags & PCI_BASE_ADDRESS_SPACE_IO)
+ if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO)
{
BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
"MultiMaster Host Adapter\n", NULL, BaseAddress1);
@@ -973,7 +976,10 @@ static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
unsigned char Bus = PCI_Device->bus->number;
unsigned char Device = PCI_Device->devfn >> 3;
unsigned int IRQ_Channel = PCI_Device->irq;
- BusLogic_IO_Address_T IO_Address = PCI_Device->resource[0].start;
+ BusLogic_IO_Address_T IO_Address = pci_resource_start(PCI_Device, 0);
+
+ if (pci_enable_device(PCI_Device))
+ continue;
if (IO_Address == 0 || IRQ_Channel == 0) continue;
for (i = 0; i < BusLogic_ProbeInfoCount; i++)
@@ -1017,12 +1023,16 @@ static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
unsigned char Bus = PCI_Device->bus->number;
unsigned char Device = PCI_Device->devfn >> 3;
unsigned int IRQ_Channel = PCI_Device->irq;
- unsigned long BaseAddress0 = PCI_Device->resource[0].start;
- unsigned long BaseAddress1 = PCI_Device->resource[1].start;
+ unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
+ unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
BusLogic_IO_Address_T IO_Address = BaseAddress0;
BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
+
+ if (pci_enable_device(PCI_Device))
+ continue;
+
#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
- if (!(PCI_Device->resource[0].flags & PCI_BASE_ADDRESS_SPACE_IO))
+ if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
{
BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
"FlashPoint Host Adapter\n", NULL, BaseAddress0);
@@ -1030,7 +1040,7 @@ static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
NULL, Bus, Device, IO_Address);
continue;
}
- if (PCI_Device->resource[1].flags & PCI_BASE_ADDRESS_SPACE_IO)
+ if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO)
{
BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
"FlashPoint Host Adapter\n", NULL, BaseAddress1);
diff --git a/drivers/scsi/ChangeLog.ncr53c8xx b/drivers/scsi/ChangeLog.ncr53c8xx
index 80a28c9f46624f..bce816f9ecbca6 100644
--- a/drivers/scsi/ChangeLog.ncr53c8xx
+++ b/drivers/scsi/ChangeLog.ncr53c8xx
@@ -1,3 +1,6 @@
+Thu May 11 12:30 2000 Pam Delaney (pam.delaney@lsil.com)
+ * revision 3.3b
+
Mon Apr 24 12:00 2000 Gerard Roudier (groudier@club-internet.fr)
* revision 3.2i
- Return value 1 (instead of 0) from the driver setup routine.
@@ -14,6 +17,11 @@ Sat Apr 1 12:00 2000 Gerard Roudier (groudier@club-internet.fr)
that supply SCSI_DATA_NONE direction (this avoids some BUG()
statement in the PCI code when a data buffer is also supplied).
+Thu Mar 16 9:30 2000 Pam Delaney (pam.delaney@lsil.com)
+ * revision 3.3b-3
+ - Added exclusion for the 53C1010 and 53C1010_66 chips
+ to the driver (change to sym53c8xx_comm.h).
+
Mon March 6 23:15 2000 Gerard Roudier (groudier@club-internet.fr)
* revision 3.2g
- Add the file sym53c8xx_comm.h that collects code that should
@@ -31,6 +39,40 @@ Mon March 6 23:15 2000 Gerard Roudier (groudier@club-internet.fr)
- Get data transfer direction from the scsi command structure
(Scsi_Cmnd) when this information is available.
+Mon March 6 23:15 2000 Gerard Roudier (groudier@club-internet.fr)
+ * revision 3.2g
+ - Add the file sym53c8xx_comm.h that collects code that should
+ be shared by sym53c8xx and ncr53c8xx drivers. For now, it is
+ a header file that is only included by the ncr53c8xx driver,
+ but things will be cleaned up later. This code addresses
+ notably:
+ * Chip detection and PCI related initialisations
+ * NVRAM detection and reading
+ * DMA mapping
+ * Boot setup command
+ * And some other ...
+ - Add support for the new dynamic dma mapping kernel interface.
+ Requires Linux-2.3.47 (tested with pre-2.3.47-6).
+ - Get data transfer direction from the scsi command structure
+ (Scsi_Cmnd) when this information is available.
+
+Fri Jan 14 14:00 2000 Pam Delaney (pam.delaney@lsil.com)
+ * revision pre-3.3b-1
+ - Merge parallel driver series 3.31 and 3.2e
+
+Tue Jan 11 14:00 2000 Pam Delaney (pam.delaney@lsil.com)
+ * revision 3.31
+ - Added support for mounting disks on wide-narrow-wide
+ scsi configurations.
+ - Built off of version 3.30
+
+Mon Jan 10 13:30 2000 Pam Delaney (pam.delaney@lsil.com)
+ * revision 3.30
+ - Added capability to use the integrity checking code
+ in the kernel (optional).
+ - Disabled support for the 53C1010.
+ - Built off of version 3.2c
+
Sat Jan 8 22:00 2000 Gerard Roudier (groudier@club-internet.fr)
* revision 3.2e
- Add year 2000 copyright.
@@ -94,7 +136,7 @@ Thu Mar 11 23:00 1999 Gerard Roudier (groudier@club-internet.fr)
* revision 3.2 (8xx-896 driver bundle)
- Only define the host template in ncr53c8xx.h and include the
sym53c8xx_defs.h file.
- - Declare static all symbols that donnot need to be visible from
+ - Declare static all symbols that do not need to be visible from
outside the driver code.
- Add 'excl' boot command option that allows to pass to the driver
io address of devices not to attach.
diff --git a/drivers/scsi/ChangeLog.sym53c8xx b/drivers/scsi/ChangeLog.sym53c8xx
index ced86ef14f97bb..f17cc74662320a 100644
--- a/drivers/scsi/ChangeLog.sym53c8xx
+++ b/drivers/scsi/ChangeLog.sym53c8xx
@@ -1,9 +1,20 @@
+Thu May 11 12:40 2000 Pam Delaney (pam.delaney@lsil.com)
+ * version sym53c8xx-1.6b
+ - Merged version.
+
Mon Apr 24 12:00 2000 Gerard Roudier (groudier@club-internet.fr)
* version sym53c8xx-1.5m
- Return value 1 (instead of 0) from the driver setup routine.
- - Donnot enable PCI DAC cycles. This just broke support for
+ - Do not enable PCI DAC cycles. This just broke support for
SYM534C896 on sparc64. Problem fixed by David S. Miller.
+Fri Apr 14 9:00 2000 Pam Delaney (pam.delaney@lsil.com)
+ * version sym53c8xx-1.6b-9
+ - Added 53C1010_66 support.
+ - Small fix to integrity checking code.
+ - Removed requirement for integrity checking if want to run
+ at ultra 3.
+
Sat Apr 1 12:00 2000 Gerard Roudier (groudier@club-internet.fr)
* version sym53c8xx-1.5l
- Tiny change for __sparc__ appeared in 2.3.99-pre4.1 that
@@ -12,6 +23,16 @@ Sat Apr 1 12:00 2000 Gerard Roudier (groudier@club-internet.fr)
that supply SCSI_DATA_NONE direction (this avoids some BUG()
statement in the PCI code when a data buffer is also supplied).
+Sat Mar 11 12:00 2000 Gerard Roudier (groudier@club-internet.fr)
+ * version sym53c8xx-1.6b-5
+ - Test against expected data transfer direction from SCRIPTS.
+ - Add support for the new dynamic dma mapping kernel interface.
+ Requires Linux-2.3.47 (tested with pre-2.3.47-6).
+ Many thanks to David S. Miller for his preliminary changes
+ that have been useful guidelines.
+ - Get data transfer direction from the scsi command structure
+ (Scsi_Cmnd) with kernels that provide this information.
+
Mon Mar 6 23:30 2000 Gerard Roudier (groudier@club-internet.fr)
* version sym53c8xx-1.5k
- Test against expected data transfer direction from SCRIPTS.
@@ -21,6 +42,16 @@ Mon Mar 6 23:30 2000 Gerard Roudier (groudier@club-internet.fr)
- Miscellaneous (minor) fixes in the code added in driver
version 1.5j.
+Mon Feb 14 4:00 2000 Pam Delaney (pam.delaney@lsil.com)
+ * version sym53c8xx-pre-1.6b-2.
+ - Updated the SCRIPTS error handling of the SWIDE
+ condition - to remove any reads of the sbdl
+ register. Changes needed because the 896 and 1010
+ chips will check parity in some special circumstances.
+ This will cause a parity error interrupt if not in
+ data phase. Changes based on those made in the
+ FreeBSD driver version 1.3.2.
+
Sun Feb 20 11:00 2000 Gerard Roudier (groudier@club-internet.fr)
* version sym53c8xx-1.5j
- Add support for the new dynamic dma mapping kernel interface.
@@ -35,6 +66,26 @@ Sun Feb 20 11:00 2000 Gerard Roudier (groudier@club-internet.fr)
- Fix an old bug that only affected 896 rev. 1 when driver
profile support option was set in kernel configuration.
+Fri Jan 14 14:00 2000 Pam Delaney (pam.delaney@lsil.com)
+ * version sym53c8xx-pre-1.6b-1.
+ - Merge parallel driver series 1.61 and 1.5e
+
+Tue Jan 11 14:00 2000 Pam Delaney (pam.delaney@lsil.com)
+ * version sym53c8xx-1.61
+ - Added support for mounting disks on wide-narrow-wide
+ scsi configurations.
+ - Modified offset to be a maximum of 31 in ST mode,
+ 62 in DT mode.
+ - Based off of 1.60
+
+Mon Jan 10 10:00 2000 Pam Delaney (pam.delaney@lsil.com)
+ * version sym53c8xx-1.60
+ - Added capability to use the integrity checking code
+ in the kernel (optional).
+ - Added PPR negotiation.
+ - Added support for 53C1010 Ultra 3 part.
+ - Based off of 1.5f
+
Sat Jan 8 22:00 2000 Gerard Roudier (groudier@club-internet.fr)
* version sym53c8xx-1.5h
- Add year 2000 copyright.
@@ -118,7 +169,7 @@ Sat Sep 11 11:00 1999 Gerard Roudier (groudier@club-internet.fr)
Sat Jun 5 11:00 1999 Gerard Roudier (groudier@club-internet.fr)
* version sym53c8xx-1.5c
- - Donnot negotiate on auto-sense if we are currently using 8 bit
+ - Do not negotiate on auto-sense if we are currently using 8 bit
async transfer for the target.
- Only check for SISL/RAID on i386 platforms.
(A problem has been reported on PPC with that code).
@@ -179,7 +230,7 @@ Sun May 9 11:00 1999 Gerard Roudier (groudier@club-internet.fr)
- Do some work in SCRIPTS after the SELECT instruction and prior
to testing for a PHASE. SYMBIOS say this feature is working fine.
(Btw, only problems with Toshiba 3401B had been reported).
- - Measure the PCI clock speed and donnot attach controllers if
+ - Measure the PCI clock speed and do not attach controllers if
result is greater than 37 MHz. Since the precision of the
algorithm (from Stefan Esser) is better than 2%, this should
be fine.
@@ -353,7 +404,7 @@ Thu Nov 19 23:00 1998 Gerard Roudier (groudier@club-internet.fr)
transactions since those early chip revisions may use such on
LOAD/STORE instructions (work-around).
- Remove some useless and bloat code from the pci init stuff.
- - Donnot use the readX()/writeX() kernel functions for __i386__,
+ - Do not use the readX()/writeX() kernel functions for __i386__,
since they perform useless masking operations in order to deal
with broken driver in 2.1.X kernel.
@@ -379,7 +430,7 @@ Wed Oct 30 22H00 1998 Gerard Roudier (groudier@club-internet.fr)
* version pre-sym53c8xx-0.12
- Damned! I just broke the driver for Alpha by leaving a stale
instruction in the source code. Hopefully fixed.
- - Donnot set PFEN when it is useless. Doing so we are sure that BOF
+ - Do not set PFEN when it is useless. Doing so we are sure that BOF
will be active, since the manual appears to be very unclear on what
feature is actually used by the chip when both PFEN and BOF are
set.
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index fbd167eb8b4593..0340ab5c44b886 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -3578,7 +3578,7 @@ repeat:
}
#else
/* For SMP we only service one ESP on the list list at our IRQ level! */
-static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
{
struct NCR_ESP *esp;
unsigned long flags;
diff --git a/drivers/scsi/README.ncr53c8xx b/drivers/scsi/README.ncr53c8xx
index 858673c3368fc8..e1d965b1a5f4f2 100644
--- a/drivers/scsi/README.ncr53c8xx
+++ b/drivers/scsi/README.ncr53c8xx
@@ -168,6 +168,12 @@ Chip SDMS BIOS Wide SCSI std. Max. sync driver driver
895 Y Y FAST40 80 MB/s Y Y
895A Y Y FAST40 80 MB/s Y Y
896 Y Y FAST40 80 MB/s Y Y
+897 Y Y FAST40 80 MB/s Y Y
+1510D Y Y FAST40 80 MB/s Y Y
+1010 Y Y FAST80 160 MB/s N Y
+1010_66* Y Y FAST80 160 MB/s N Y
+
+* Chip supports 33MHz and 66MHz PCI buses.
Summary of other supported features:
@@ -686,11 +692,12 @@ port address 0x1400.
Invalidate.
10.2.5 Ultra SCSI support
- Only apply to 860, 875 and 895 controllers.
+ Only apply to 860, 875, 895, 895a, 896, 1010 and 1010_66 controllers.
Have no effect with other ones.
+ ultra:n All ultra speeds enabled
ultra:2 Ultra2 enabled
ultra:1 Ultra enabled
- ultra:n disabled
+ ultra:0 Ultra speeds disabled
10.2.6 Default number of tagged commands
tags:0 (or tags:1 ) tagged command queuing disabled
@@ -822,6 +829,7 @@ port address 0x1400.
0x0: No check.
0x1: Check and donnot attach the controller on error.
0x2: Check and just warn on error.
+ 0x4: Disable SCSI bus integrity checking.
10.2.20 Exclude a host from being attached
excl=<io_address>
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index 99cfa7e8c1fbe6..1bd2cdfcf41663 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -148,7 +148,7 @@ void fake_drq(int irq, void *dev_id, struct pt_regs *pregs)
#define DRIVER_SETUP
/*
- * Function : mac_scsi_setup(char *str, int *ints)
+ * Function : mac_esp_setup(char *str, int *ints)
*
* Purpose : booter command line initialization of the overrides array,
*
@@ -160,7 +160,7 @@ void fake_drq(int irq, void *dev_id, struct pt_regs *pregs)
*
*/
-void mac_esp_setup(char *str, int *ints) {
+static int __init mac_esp_setup(char *str, int *ints) {
#ifdef DRIVER_SETUP
/* Format of mac53c9x parameter is:
* mac53c9x=<num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
@@ -186,7 +186,7 @@ void mac_esp_setup(char *str, int *ints) {
if (ints[0] < 1) {
printk( "mac_esp_setup: no arguments!\n" );
- return;
+ return 0;
}
if (ints[0] >= 1) {
@@ -237,6 +237,7 @@ void mac_esp_setup(char *str, int *ints) {
}
#endif
#endif
+ return 1;
}
__setup("mac53c9x=", mac_esp_setup);
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index 11a58c478848fb..62f7bd3c11c961 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -133,7 +133,7 @@ static volatile unsigned char *mac_scsi_nodrq = NULL;
*
*/
-void mac_scsi_setup(char *str, int *ints) {
+static int __init mac_scsi_setup(char *str, int *ints) {
#ifdef DRIVER_SETUP
/* Format of mac5380 parameter is:
* mac5380=<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
@@ -159,7 +159,7 @@ void mac_scsi_setup(char *str, int *ints) {
if (ints[0] < 1) {
printk( "mac_scsi_setup: no arguments!\n" );
- return;
+ return 0;
}
if (ints[0] >= 1) {
@@ -193,6 +193,7 @@ void mac_scsi_setup(char *str, int *ints) {
}
#endif
#endif
+ return 1;
}
__setup("mac5380=", mac_scsi_setup);
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index aecbd4cf067355..72f4ce11d3b151 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -73,7 +73,7 @@
*/
/*
-** April 24 2000, version 3.2i
+** May 11 2000, version 3.3b
**
** Supported SCSI-II features:
** Synchronous negotiation
@@ -93,6 +93,7 @@
** 53C895 (Wide, Fast 40, on board rom BIOS)
** 53C895A (Wide, Fast 40, on board rom BIOS)
** 53C896 (Wide, Fast 40, on board rom BIOS)
+** 53C897 (Wide, Fast 40, on board rom BIOS)
** 53C1510D (Wide, Fast 40, on board rom BIOS)
**
** Other features:
@@ -104,7 +105,7 @@
/*
** Name and version of the driver
*/
-#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - version 3.2i"
+#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - version 3.3b"
#define SCSI_NCR_DEBUG_FLAGS (0)
@@ -187,6 +188,14 @@ typedef u64 u_int64;
typedef u_long vm_offset_t;
#include "ncr53c8xx.h"
+/*
+** Donnot compile integrity checking code for Linux-2.3.0
+** and above since SCSI data structures are not ready yet.
+*/
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,0)
+#define SCSI_NCR_INTEGRITY_CHECKING
+#endif
+
#define NAME53C "ncr53c"
#define NAME53C8XX "ncr53c8xx"
#define DRIVER_SMP_LOCK ncr53c8xx_lock
@@ -472,8 +481,10 @@ static u_char Tekram_sync[16] __initdata =
**==========================================================
*/
+#define NS_NOCHANGE (0)
#define NS_SYNC (1)
#define NS_WIDE (2)
+#define NS_PPR (4)
/*==========================================================
**
@@ -666,6 +677,13 @@ struct tcb {
/*2*/ u_char widedone;
/*3*/ u_char wval;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ u_char ic_min_sync;
+ u_char ic_max_width;
+ u_char ic_maximums_set;
+ u_char ic_done;
+#endif
+
/*----------------------------------------------------------------
** User settable limits and options.
** These limits are read from the NVRAM if present.
@@ -1204,6 +1222,17 @@ struct ncb {
struct ccb *ccb; /* Global CCB */
struct usrcmd user; /* Command from user */
u_char release_stage; /* Synchronisation stage on release */
+
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ /*----------------------------------------------------------------
+ ** Fields that are used for integrity check
+ **----------------------------------------------------------------
+ */
+ unsigned char check_integrity; /* Enable midlayer integ.check on
+ * bus scan. */
+ unsigned char check_integ_par; /* Set if par or Init. Det. error
+ * used only during integ check */
+#endif
};
#define NCB_SCRIPT_PHYS(np,lbl) (np->p_script + offsetof (struct script, lbl))
@@ -1382,6 +1411,10 @@ static void ncr_int_sir (ncb_p np);
static void ncr_int_sto (ncb_p np);
static u_long ncr_lookup (char* id);
static void ncr_negotiate (struct ncb* np, struct tcb* tp);
+static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr);
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+static int ncr_ic_nego(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd, u_char *msgptr);
+#endif
#ifdef SCSI_NCR_PROFILE_SUPPORT
static void ncb_profile (ncb_p np, ccb_p cp);
@@ -1396,6 +1429,7 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer);
static void ncr_setup_tags (ncb_p np, u_char tn, u_char ln);
static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack);
static int ncr_show_msg (u_char * msg);
+static void ncr_print_msg (ccb_p cp, char *label, u_char *msg);
static int ncr_snooptest (ncb_p np);
static void ncr_timeout (ncb_p np);
static void ncr_wakeup (ncb_p np, u_long code);
@@ -3792,6 +3826,17 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
instance->can_queue = (MAX_START-4);
instance->select_queue_depths = ncr53c8xx_select_queue_depths;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ np->check_integrity = 0;
+ instance->check_integrity = 0;
+
+#ifdef SCSI_NCR_ENABLE_INTEGRITY_CHECK
+ if ( !(driver_setup.bus_check & 0x04) ) {
+ np->check_integrity = 1;
+ instance->check_integrity = 1;
+ }
+#endif
+#endif
/*
** Patch script to physical addresses
*/
@@ -4020,6 +4065,270 @@ static inline void ncr_flush_done_cmds(Scsi_Cmnd *lcmd)
}
}
+/*==========================================================
+**
+**
+** Prepare the next negotiation message for integrity check,
+** if needed.
+**
+** Fill in the part of message buffer that contains the
+** negotiation and the nego_status field of the CCB.
+** Returns the size of the message in bytes.
+**
+**
+**==========================================================
+*/
+
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+static int ncr_ic_nego(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd, u_char *msgptr)
+{
+ tcb_p tp = &np->target[cp->target];
+ int msglen = 0;
+ int nego = 0;
+ u_char no_increase;
+
+ if (tp->inq_done) {
+
+ if (!tp->ic_maximums_set) {
+ tp->ic_maximums_set = 1;
+
+ /* check target and host adapter capabilities */
+ if ( (tp->inq_byte7 & INQ7_WIDE16) &&
+ np->maxwide && tp->usrwide )
+ tp->ic_max_width = 1;
+ else
+ tp->ic_max_width = 0;
+
+ if ((tp->inq_byte7 & INQ7_SYNC) && tp->maxoffs) {
+ tp->ic_min_sync = (tp->minsync < np->minsync) ?
+ np->minsync : tp->minsync;
+ }
+ else
+ tp->ic_min_sync = 255;
+
+ tp->period = 1;
+ tp->widedone = 1;
+ }
+
+ if (DEBUG_FLAGS & DEBUG_IC) {
+ printk("%s: cmd->ic_nego %d, 1st byte 0x%2X\n",
+ ncr_name(np), cmd->ic_nego, cmd->cmnd[0]);
+ }
+
+ /* First command from integrity check routine will request
+ * a PPR message. Disable.
+ */
+ if ((cmd->ic_nego & NS_PPR) == NS_PPR)
+ cmd->ic_nego &= ~NS_PPR;
+ /* Previous command recorded a parity or an initiator
+ * detected error condition. Force bus to narrow for this
+ * target. Clear flag. Negotation on request sense.
+ * Note: kernel forces 2 bus resets :o( but clears itself out.
+ * Minor bug? in scsi_obsolete.c (ugly)
+ */
+ if (np->check_integ_par) {
+ printk("%s: Parity Error. Target set to narrow.\n",
+ ncr_name(np));
+ tp->ic_max_width = 0;
+ tp->widedone = tp->period = 0;
+ }
+
+ /* In case of a bus reset, ncr_negotiate will reset
+ * the flags tp->widedone and tp->period to 0, forcing
+ * a new negotiation.
+ */
+ no_increase = 0;
+ if (tp->widedone == 0) {
+ cmd->ic_nego = NS_WIDE;
+ tp->widedone = 1;
+ no_increase = 1;
+ }
+ else if (tp->period == 0) {
+ cmd->ic_nego = NS_SYNC;
+ tp->period = 1;
+ no_increase = 1;
+ }
+
+ switch (cmd->ic_nego) {
+ case NS_WIDE:
+ /*
+ ** negotiate wide transfers ?
+ ** Do NOT negotiate if device only supports
+ ** narrow.
+ */
+ if (tp->ic_max_width | np->check_integ_par) {
+ nego = NS_WIDE;
+
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 2;
+ msgptr[msglen++] = M_X_WIDE_REQ;
+ msgptr[msglen++] = cmd->ic_nego_width & tp->ic_max_width;
+ }
+ else
+ cmd->ic_nego_width &= tp->ic_max_width;
+
+ break;
+
+ case NS_SYNC:
+ /*
+ ** negotiate synchronous transfers?
+ ** Target must support sync transfers.
+ **
+ ** If period becomes longer than max, reset to async
+ */
+
+ if (tp->inq_byte7 & INQ7_SYNC) {
+
+ nego = NS_SYNC;
+
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 3;
+ msgptr[msglen++] = M_X_SYNC_REQ;
+
+ switch (cmd->ic_nego_sync) {
+ case 2: /* increase the period */
+ if (!no_increase) {
+ if (tp->ic_min_sync <= 0x0A)
+ tp->ic_min_sync = 0x0C;
+ else if (tp->ic_min_sync <= 0x0C)
+ tp->ic_min_sync = 0x19;
+ else if (tp->ic_min_sync <= 0x19)
+ tp->ic_min_sync *= 2;
+ else {
+ tp->ic_min_sync = 255;
+ cmd->ic_nego_sync = 0;
+ tp->maxoffs = 0;
+ }
+ }
+ msgptr[msglen++] = tp->maxoffs?tp->ic_min_sync:0;
+ msgptr[msglen++] = tp->maxoffs;
+ break;
+
+ case 1: /* nego. to maximum */
+ msgptr[msglen++] = tp->maxoffs?tp->ic_min_sync:0;
+ msgptr[msglen++] = tp->maxoffs;
+ break;
+
+ case 0: /* nego to async */
+ default:
+ msgptr[msglen++] = 0;
+ msgptr[msglen++] = 0;
+ break;
+ };
+ }
+ else
+ cmd->ic_nego_sync = 0;
+ break;
+
+ case NS_NOCHANGE:
+ default:
+ break;
+ };
+ };
+
+ cp->nego_status = nego;
+ np->check_integ_par = 0;
+
+ if (nego) {
+ tp->nego_cp = cp;
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ ncr_print_msg(cp, nego == NS_WIDE ?
+ "wide/narrow msgout": "sync/async msgout", msgptr);
+ };
+ };
+
+ return msglen;
+}
+#endif /* SCSI_NCR_INTEGRITY_CHECKING */
+
+/*==========================================================
+**
+**
+** Prepare the next negotiation message if needed.
+**
+** Fill in the part of message buffer that contains the
+** negotiation and the nego_status field of the CCB.
+** Returns the size of the message in bytes.
+**
+**
+**==========================================================
+*/
+
+
+static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr)
+{
+ tcb_p tp = &np->target[cp->target];
+ int msglen = 0;
+ int nego = 0;
+
+ if (tp->inq_done) {
+
+ /*
+ ** negotiate wide transfers ?
+ */
+
+ if (!tp->widedone) {
+ if (tp->inq_byte7 & INQ7_WIDE16) {
+ nego = NS_WIDE;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ if (tp->ic_done)
+ tp->usrwide &= tp->ic_max_width;
+#endif
+ } else
+ tp->widedone=1;
+
+ };
+
+ /*
+ ** negotiate synchronous transfers?
+ */
+
+ if (!nego && !tp->period) {
+ if (tp->inq_byte7 & INQ7_SYNC) {
+ nego = NS_SYNC;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ if ((tp->ic_done) &&
+ (tp->minsync < tp->ic_min_sync))
+ tp->minsync = tp->ic_min_sync;
+#endif
+ } else {
+ tp->period =0xffff;
+ PRINT_TARGET(np, cp->target);
+ printk ("target did not report SYNC.\n");
+ };
+ };
+ };
+
+ switch (nego) {
+ case NS_SYNC:
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 3;
+ msgptr[msglen++] = M_X_SYNC_REQ;
+ msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0;
+ msgptr[msglen++] = tp->maxoffs;
+ break;
+ case NS_WIDE:
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 2;
+ msgptr[msglen++] = M_X_WIDE_REQ;
+ msgptr[msglen++] = tp->usrwide;
+ break;
+ };
+
+ cp->nego_status = nego;
+
+ if (nego) {
+ tp->nego_cp = cp;
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ ncr_print_msg(cp, nego == NS_WIDE ?
+ "wide msgout":"sync_msgout", msgptr);
+ };
+ };
+
+ return msglen;
+}
+
+
/*==========================================================
**
@@ -4038,7 +4347,7 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
ccb_p cp;
int segments;
- u_char nego, idmsg, *msgptr;
+ u_char idmsg, *msgptr;
u_int msglen;
int direction;
u_int32 lastp, goalp;
@@ -4120,51 +4429,6 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
cp->phys.header.stamp.start = jiffies;
#endif
- /*---------------------------------------------------
- **
- ** negotiation required?
- **
- **---------------------------------------------------
- */
-
- nego = 0;
-
- if ((!tp->widedone || !tp->period) && !tp->nego_cp && tp->inq_done && lp) {
-
- /*
- ** negotiate wide transfers ?
- */
-
- if (!tp->widedone) {
- if (tp->inq_byte7 & INQ7_WIDE16) {
- nego = NS_WIDE;
- } else
- tp->widedone=1;
- };
-
- /*
- ** negotiate synchronous transfers?
- */
-
- if (!nego && !tp->period) {
- if (tp->inq_byte7 & INQ7_SYNC) {
- nego = NS_SYNC;
- } else {
- tp->period =0xffff;
- PRINT_TARGET(np, cmd->target);
- printk ("device did not report SYNC.\n");
- };
- };
-
- /*
- ** remember nego is pending for the target.
- ** Avoid to start a nego for all queued commands
- ** when tagged command queuing is enabled.
- */
-
- if (nego)
- tp->nego_cp = cp;
- };
/*----------------------------------------------------
**
@@ -4225,34 +4489,6 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
msgptr[msglen++] = (cp->tag << 1) + 1;
}
- switch (nego) {
- case NS_SYNC:
- msgptr[msglen++] = M_EXTENDED;
- msgptr[msglen++] = 3;
- msgptr[msglen++] = M_X_SYNC_REQ;
- msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0;
- msgptr[msglen++] = tp->maxoffs;
- if (DEBUG_FLAGS & DEBUG_NEGO) {
- PRINT_ADDR(cp->cmd);
- printk ("sync msgout: ");
- ncr_show_msg (&cp->scsi_smsg [msglen-5]);
- printk (".\n");
- };
- break;
- case NS_WIDE:
- msgptr[msglen++] = M_EXTENDED;
- msgptr[msglen++] = 2;
- msgptr[msglen++] = M_X_WIDE_REQ;
- msgptr[msglen++] = tp->usrwide;
- if (DEBUG_FLAGS & DEBUG_NEGO) {
- PRINT_ADDR(cp->cmd);
- printk ("wide msgout: ");
- ncr_show_msg (&cp->scsi_smsg [msglen-4]);
- printk (".\n");
- };
- break;
- };
-
/*----------------------------------------------------
**
** Build the data descriptors
@@ -4273,6 +4509,84 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
segments = 0;
}
+ /*---------------------------------------------------
+ **
+ ** negotiation required?
+ **
+ ** (nego_status is filled by ncr_prepare_nego())
+ **
+ **---------------------------------------------------
+ */
+
+ cp->nego_status = 0;
+
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ if ((np->check_integrity && tp->ic_done) || !np->check_integrity) {
+ if ((!tp->widedone || !tp->period) && !tp->nego_cp && lp) {
+ msglen += ncr_prepare_nego (np, cp, msgptr + msglen);
+ }
+ }
+ else if (np->check_integrity && (cmd->ic_in_progress)) {
+ msglen += ncr_ic_nego (np, cp, cmd, msgptr + msglen);
+ }
+ else if (np->check_integrity && cmd->ic_complete) {
+ /*
+ * Midlayer signal to the driver that all of the scsi commands
+ * for the integrity check have completed. Save the negotiated
+ * parameters (extracted from sval and wval).
+ */
+
+ {
+ u_char idiv;
+ idiv = (tp->wval>>4) & 0x07;
+ if ((tp->sval&0x1f) && idiv )
+ tp->period = (((tp->sval>>5)+4)
+ *div_10M[idiv-1])/np->clock_khz;
+ else
+ tp->period = 0xffff;
+ }
+ /*
+ * tp->period contains 10 times the transfer period,
+ * which itself is 4 * the requested negotiation rate.
+ */
+ if (tp->period <= 250) tp->ic_min_sync = 10;
+ else if (tp->period <= 303) tp->ic_min_sync = 11;
+ else if (tp->period <= 500) tp->ic_min_sync = 12;
+ else
+ tp->ic_min_sync = (tp->period + 40 - 1) / 40;
+
+
+ /*
+ * Negotiation for this target it complete.
+ */
+ tp->ic_max_width = (tp->wval & EWS) ? 1: 0;
+ tp->ic_done = 1;
+ tp->widedone = 1;
+
+ printk("%s: Integrity Check Complete: \n", ncr_name(np));
+
+ printk("%s: %s %s SCSI", ncr_name(np),
+ (tp->sval&0x1f)?"SYNC":"ASYNC",
+ tp->ic_max_width?"WIDE":"NARROW");
+
+ if (tp->sval&0x1f) {
+ u_long mbs = 10000 * (tp->ic_max_width + 1);
+
+ printk(" %d.%d MB/s",
+ (int) (mbs / tp->period), (int) (mbs % tp->period));
+
+ printk(" (%d ns, %d offset)\n",
+ tp->period/10, tp->sval&0x1f);
+ }
+ else
+ printk(" %d MB/s. \n ", (tp->ic_max_width+1)*5);
+ }
+#else
+ if ((!tp->widedone || !tp->period) && !tp->nego_cp && lp) {
+ msglen += ncr_prepare_nego (np, cp, msgptr + msglen);
+ }
+#endif /* SCSI_NCR_INTEGRITY_CHECKING */
+
/*----------------------------------------------------
**
** Determine xfer direction.
@@ -4376,12 +4690,11 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
** status
*/
cp->actualquirks = tp->quirks;
- cp->host_status = nego ? HS_NEGOTIATE : HS_BUSY;
+ cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
cp->scsi_status = S_ILLEGAL;
cp->parity_status = 0;
cp->xerr_status = XE_OK;
- cp->nego_status = nego;
#if 0
cp->sync_status = tp->sval;
cp->wide_status = tp->wval;
@@ -5041,7 +5354,13 @@ void ncr_complete (ncb_p np, ccb_p cp)
for (i=0; i<14; i++) printk (" %x", *p++);
printk (".\n");
}
-
+ } else if ((cp->host_status == HS_COMPLETE)
+ && (cp->scsi_status == S_CONFLICT)) {
+ /*
+ ** Reservation Conflict condition code
+ */
+ cmd->result = ScsiResult(DID_OK, S_CONFLICT);
+
} else if ((cp->host_status == HS_COMPLETE)
&& (cp->scsi_status == S_BUSY ||
cp->scsi_status == S_QUEUE_FULL)) {
@@ -6398,6 +6717,14 @@ static int ncr_int_par (ncb_p np)
else
msg = M_ID_ERROR;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ /*
+ ** Save error message. For integrity check use only.
+ */
+ if (np->check_integrity)
+ np->check_integ_par = msg;
+#endif
+
/*
* If the NCR stopped on a MOVE ^ DATA_IN, we jump to a
* script that will ignore all data in bytes until phase
@@ -6908,6 +7235,16 @@ static int ncr_show_msg (u_char * msg)
return (1);
}
+static void ncr_print_msg ( ccb_p cp, char *label, u_char *msg)
+{
+ if (cp)
+ PRINT_ADDR(cp->cmd);
+ if (label)
+ printk("%s: ", label);
+
+ (void) ncr_show_msg (msg);
+ printk(".\n");
+}
void ncr_int_sir (ncb_p np)
{
@@ -8275,6 +8612,7 @@ static void ncr_selectclock(ncb_p np, u_char scntl3)
static unsigned __init ncrgetfreq (ncb_p np, int gen)
{
unsigned ms = 0;
+ char count = 0;
/*
* Measure GEN timer delay in order
@@ -8299,8 +8637,10 @@ static unsigned __init ncrgetfreq (ncb_p np, int gen)
OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */
OUTB (nc_stime1, 0); /* disable general purpose timer */
OUTB (nc_stime1, gen); /* set to nominal delay of 1<<gen * 125us */
- while (!(INW(nc_sist) & GEN) && ms++ < 100000)
- UDELAY (1000); /* count ms */
+ while (!(INW(nc_sist) & GEN) && ms++ < 100000) {
+ for (count = 0; count < 10; count ++)
+ UDELAY (100); /* count ms */
+ }
OUTB (nc_stime1, 0); /* disable general purpose timer */
/*
* set prescaler to divide by whatever 0 means
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 7f67db94c82c4a..56ef67cb2ff7f0 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -38,7 +38,6 @@
#define BLIST_MAX5LUN 0x080
#define BLIST_ISDISK 0x100
#define BLIST_ISROM 0x200
-#define BLIST_GHOST 0x400
static void print_inquiry(unsigned char *data);
static int scan_scsis_single(int channel, int dev, int lun, int *max_scsi_dev,
@@ -137,13 +136,7 @@ static struct dev_info device_list[] =
{"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
{"MATSHITA", "PD-1", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
- {"CREATIVE","DVD-RAM RAM","*", BLIST_GHOST},
- {"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST},
- {"AOpen", "PD-2 DVD-520S", "*", BLIST_GHOST},
- {"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */
{"TOSHIBA","CDROM","*", BLIST_ISROM},
- {"TOSHIBA","DVD-RAM SD-W1101","*", BLIST_GHOST},
- {"TOSHIBA","DVD-RAM SD-W1111","*", BLIST_GHOST},
{"MegaRAID", "LD", "*", BLIST_FORCELUN},
/*
@@ -468,8 +461,6 @@ static int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
Scsi_Device *SDtail, *SDpnt = *SDpnt2;
Scsi_Request * SRpnt;
int bflags, type = -1;
- static int ghost_channel=-1, ghost_dev=-1;
- int org_lun = lun;
extern devfs_handle_t scsi_devfs_handle;
SDpnt->host = shpnt;
@@ -480,13 +471,6 @@ static int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
scsi_build_commandblocks(SDpnt);
- if ((channel == ghost_channel) && (dev == ghost_dev) && (lun == 1)) {
- SDpnt->lun = 0;
- } else {
- ghost_channel = ghost_dev = -1;
- }
-
-
/* Some low level driver could use device->type (DB) */
SDpnt->type = -1;
@@ -499,39 +483,14 @@ static int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
SDpnt->expecting_cc_ua = 0;
SDpnt->starved = 0;
- scsi_cmd[0] = TEST_UNIT_READY;
- scsi_cmd[1] = lun << 5;
- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0;
-
SRpnt = scsi_allocate_request(SDpnt);
- SRpnt->sr_data_direction = SCSI_DATA_NONE;
-
- scsi_wait_req (SRpnt, (void *) scsi_cmd,
- (void *) NULL,
- 0, SCSI_TIMEOUT + 4 * HZ, 5);
-
- SCSI_LOG_SCAN_BUS(3, printk("scsi: scan_scsis_single id %d lun %d. Return code 0x%08x\n",
- dev, lun, SRpnt->sr_result));
- SCSI_LOG_SCAN_BUS(3, print_driverbyte(SRpnt->sr_result));
- SCSI_LOG_SCAN_BUS(3, print_hostbyte(SRpnt->sr_result));
- SCSI_LOG_SCAN_BUS(3, printk("\n"));
+ /*
+ * We used to do a TEST_UNIT_READY before the INQUIRY but that was
+ * not really necessary. Spec recommends using INQUIRY to scan for
+ * devices (and TEST_UNIT_READY to poll for media change). - Paul G.
+ */
- if (SRpnt->sr_result) {
- if (((driver_byte(SRpnt->sr_result) & DRIVER_SENSE) ||
- (status_byte(SRpnt->sr_result) & CHECK_CONDITION)) &&
- ((SRpnt->sr_sense_buffer[0] & 0x70) >> 4) == 7) {
- if (((SRpnt->sr_sense_buffer[2] & 0xf) != NOT_READY) &&
- ((SRpnt->sr_sense_buffer[2] & 0xf) != UNIT_ATTENTION) &&
- ((SRpnt->sr_sense_buffer[2] & 0xf) != ILLEGAL_REQUEST || lun > 0)) {
- scsi_release_request(SRpnt);
- return 1;
- }
- } else {
- scsi_release_request(SRpnt);
- return 0;
- }
- }
SCSI_LOG_SCAN_BUS(3, printk("scsi: performing INQUIRY\n"));
/*
* Build an INQUIRY command block.
@@ -547,7 +506,7 @@ static int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
scsi_wait_req (SRpnt, (void *) scsi_cmd,
(void *) scsi_result,
- 256, SCSI_TIMEOUT, 3);
+ 256, SCSI_TIMEOUT+4*HZ, 3);
SCSI_LOG_SCAN_BUS(3, printk("scsi: INQUIRY %s with code 0x%x\n",
SRpnt->sr_result ? "failed" : "successful", SRpnt->sr_result));
@@ -588,18 +547,6 @@ static int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
scsi_result[1] |= 0x80; /* removable */
}
- if (bflags & BLIST_GHOST) {
- if ((ghost_channel == channel) && (ghost_dev == dev) && (org_lun == 1)) {
- lun=1;
- } else {
- ghost_channel = channel;
- ghost_dev = dev;
- scsi_result[0] = TYPE_MOD;
- scsi_result[1] |= 0x80; /* removable */
- }
- }
-
-
memcpy(SDpnt->vendor, scsi_result + 8, 8);
memcpy(SDpnt->model, scsi_result + 16, 16);
memcpy(SDpnt->rev, scsi_result + 32, 4);
@@ -808,19 +755,9 @@ static int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
}
/*
- * If this device is Ghosted, scan upto two luns. (It physically only
- * has one). -- REW
- */
- if (bflags & BLIST_GHOST) {
- *max_dev_lun = 2;
- return 1;
- }
-
-
- /*
- * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI
- * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1
- * (ANSI SCSI Revision 1) and Response Data Format 0
+ * We assume the device can't handle lun!=0 if: - it reports scsi-0
+ * (ANSI SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it
+ * reports scsi-1 (ANSI SCSI Revision 1) and Response Data Format 0
*/
if (((scsi_result[2] & 0x07) == 0)
||
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index dc6712247482f7..e568c6d1bd52c2 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -25,6 +25,9 @@
*
* Modified by Richard Gooch <rgooch@atnf.csiro.au> to support devfs
*
+ * Modified by Jens Axboe <axboe@suse.de> - support DVD-RAM
+ * transparently and loose the GHOST hack
+ *
*/
#include <linux/module.h>
@@ -297,9 +300,10 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
else
printk("sr: can't switch blocksize: in interrupt\n");
}
- if (SCpnt->request.cmd == WRITE) {
+
+ if ((SCpnt->request.cmd == WRITE) && !scsi_CDs[dev].device->writeable)
return 0;
- }
+
if (scsi_CDs[dev].device->sector_size == 1024) {
if ((block & 1) || (SCpnt->request.nr_sectors & 1)) {
printk("sr.c:Bad 1K block number requested (%d %ld)",
@@ -322,9 +326,6 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
}
switch (SCpnt->request.cmd) {
case WRITE:
- if (!scsi_CDs[dev].device->writeable) {
- return 0;
- }
SCpnt->cmnd[0] = WRITE_10;
SCpnt->sc_data_direction = SCSI_DATA_WRITE;
break;
@@ -587,10 +588,11 @@ void get_capabilities(int i)
scsi_CDs[i].readcd_known = 1;
scsi_CDs[i].readcd_cdda = buffer[n + 5] & 0x01;
/* print some capability bits */
- printk("sr%i: scsi3-mmc drive: %dx/%dx %s%s%s%s%s\n", i,
+ printk("sr%i: scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", i,
((buffer[n + 14] << 8) + buffer[n + 15]) / 176,
scsi_CDs[i].cdi.speed,
buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */
+ buffer[n + 3] & 0x20 ? "dvd-ram " : "",
buffer[n + 2] & 0x02 ? "cd/rw " : "", /* can read rewriteable */
buffer[n + 4] & 0x20 ? "xa/form2 " : "", /* can read xa/from2 */
buffer[n + 5] & 0x01 ? "cdda " : "", /* can read audio data */
@@ -601,9 +603,12 @@ void get_capabilities(int i)
if ((buffer[n + 2] & 0x8) == 0)
/* not a DVD drive */
scsi_CDs[i].cdi.mask |= CDC_DVD;
- if ((buffer[n + 3] & 0x20) == 0)
+ if ((buffer[n + 3] & 0x20) == 0) {
/* can't write DVD-RAM media */
scsi_CDs[i].cdi.mask |= CDC_DVD_RAM;
+ } else {
+ scsi_CDs[i].device->writeable = 1;
+ }
if ((buffer[n + 3] & 0x10) == 0)
/* can't write DVD-R media */
scsi_CDs[i].cdi.mask |= CDC_DVD_R;
@@ -627,7 +632,6 @@ void get_capabilities(int i)
/*else I don't think it can close its tray
scsi_CDs[i].cdi.mask |= CDC_CLOSE_TRAY; */
-
scsi_free(buffer, 512);
}
diff --git a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
index 965543f8d2810e..bec37e4a71f511 100644
--- a/drivers/scsi/sym53c8xx.c
+++ b/drivers/scsi/sym53c8xx.c
@@ -55,7 +55,7 @@
*/
/*
-** April 24 2000, sym53c8xx 1.5m
+** May 11 2000, sym53c8xx 1.6b
**
** Supported SCSI features:
** Synchronous data transfers
@@ -73,7 +73,10 @@
** 53C895 (Wide, Fast 40, on-board rom BIOS)
** 53C895A (Wide, Fast 40, on-board rom BIOS)
** 53C896 (Wide, Fast 40 Dual, on-board rom BIOS)
+** 53C897 (Wide, Fast 40 Dual, on-board rom BIOS)
** 53C1510D (Wide, Fast 40 Dual, on-board rom BIOS)
+** 53C1010 (Wide, Fast 80 Dual, on-board rom BIOS)
+** 53C1010_66(Wide, Fast 80 Dual, on-board rom BIOS, 33/66MHz PCI)
**
** Other features:
** Memory mapped IO
@@ -84,7 +87,7 @@
/*
** Name and version of the driver
*/
-#define SCSI_NCR_DRIVER_NAME "sym53c8xx - version 1.5m"
+#define SCSI_NCR_DRIVER_NAME "sym53c8xx - version 1.6b"
/* #define DEBUG_896R1 */
#define SCSI_NCR_OPTIMIZE_896
@@ -174,6 +177,14 @@ typedef u64 u_int64;
#include "sym53c8xx.h"
+/*
+** Donnot compile integrity checking code for Linux-2.3.0
+** and above since SCSI data structures are not ready yet.
+*/
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,0)
+#define SCSI_NCR_INTEGRITY_CHECKING
+#endif
+
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
@@ -606,6 +617,7 @@ pci_get_base_address(pcidev_t dev, int offset, u_long *base)
#define DEBUG_TIMING (0x0100)
#define DEBUG_NEGO (0x0200)
#define DEBUG_TAGS (0x0400)
+#define DEBUG_IC (0x0800)
/*
** Enable/Disable debug messages.
@@ -1654,6 +1666,8 @@ typedef struct {
#define XE_EXTRA_DATA (1) /* unexpected data phase */
#define XE_BAD_PHASE (2) /* illegal phase (4/5) */
#define XE_PARITY_ERR (4) /* unrecovered SCSI parity error */
+#define XE_SODL_UNRUN (1<<3)
+#define XE_SWIDE_OVRUN (1<<4)
/*==========================================================
**
@@ -1663,8 +1677,10 @@ typedef struct {
**==========================================================
*/
+#define NS_NOCHANGE (0)
#define NS_SYNC (1)
#define NS_WIDE (2)
+#define NS_PPR (4)
/*==========================================================
**
@@ -1819,7 +1835,7 @@ struct tcb {
/*----------------------------------------------------------------
** negotiation of wide and synch transfer and device quirks.
- ** sval and wval are read from SCRIPTS and so have alignment
+ ** sval, wval and uval are read from SCRIPTS and so have alignment
** constraints.
**----------------------------------------------------------------
*/
@@ -1830,6 +1846,15 @@ struct tcb {
/*1*/ u_char quirks;
/*2*/ u_char widedone;
/*3*/ u_char wval;
+/*0*/ u_char uval;
+
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ u_char ic_min_sync;
+ u_char ic_max_width;
+ u_char ic_done;
+#endif
+ u_char ic_maximums_set;
+ u_char ppr_negotiation;
/*----------------------------------------------------------------
** User settable limits and options.
@@ -1838,8 +1863,8 @@ struct tcb {
*/
u_char usrsync;
u_char usrwide;
- u_char usrflag;
u_short usrtags;
+ u_char usrflag;
};
/*========================================================================
@@ -2049,6 +2074,7 @@ struct head {
#define HF_AUTO_SENSE (1u<<4)
#define HF_DATA_IN (1u<<5)
#define HF_PM_TO_C (1u<<6)
+#define HF_EXT_ERR (1u<<7)
#ifdef SCSI_NCR_IARB_SUPPORT
#define HF_HINT_IARB (1u<<7)
@@ -2106,6 +2132,7 @@ struct dsb {
struct scr_tblmove smsg_ext ;
struct scr_tblmove cmd ;
struct scr_tblmove sense ;
+ struct scr_tblmove wresid;
struct scr_tblmove data [MAX_SCATTER];
/*
@@ -2269,7 +2296,7 @@ struct ncb {
**----------------------------------------------------------------
*/
u_char sv_scntl0, sv_scntl3, sv_dmode, sv_dcntl, sv_ctest3, sv_ctest4,
- sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4, sv_stest1;
+ sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4, sv_stest1, sv_scntl4;
/*----------------------------------------------------------------
** Actual initial value of IO register bits used by the
@@ -2278,7 +2305,7 @@ struct ncb {
**----------------------------------------------------------------
*/
u_char rv_scntl0, rv_scntl3, rv_dmode, rv_dcntl, rv_ctest3, rv_ctest4,
- rv_ctest5, rv_stest2, rv_ccntl0, rv_ccntl1;
+ rv_ctest5, rv_stest2, rv_ccntl0, rv_ccntl1, rv_scntl4;
/*----------------------------------------------------------------
** Target data.
@@ -2393,8 +2420,8 @@ struct ncb {
** written with a script command.
**----------------------------------------------------------------
*/
- u_char msgout[8]; /* Buffer for MESSAGE OUT */
- u_char msgin [8]; /* Buffer for MESSAGE IN */
+ u_char msgout[12]; /* Buffer for MESSAGE OUT */
+ u_char msgin [12]; /* Buffer for MESSAGE IN */
u_int32 lastmsg; /* Last SCSI message sent */
u_char scratch; /* Scratch for SCSI receive */
@@ -2466,6 +2493,17 @@ struct ncb {
*/
struct usrcmd user; /* Command from user */
u_char release_stage; /* Synchronisation stage on release */
+
+ /*----------------------------------------------------------------
+ ** Fields that are used (primarily) for integrity check
+ **----------------------------------------------------------------
+ */
+ unsigned char check_integrity; /* Enable midlayer integ. check on
+ * bus scan. */
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ unsigned char check_integ_par; /* Set if par or Init. Det. error
+ * used only during integ check */
+#endif
};
#define NCB_PHYS(np, lbl) (np->p_ncb + offsetof(struct ncb, lbl))
@@ -2511,20 +2549,20 @@ struct script {
ncrcmd select2 [ 2];
#endif
ncrcmd command [ 2];
- ncrcmd dispatch [ 28];
+ ncrcmd dispatch [ 30];
ncrcmd sel_no_cmd [ 10];
ncrcmd init [ 6];
ncrcmd clrack [ 4];
- ncrcmd disp_msg_in [ 2];
ncrcmd disp_status [ 4];
- ncrcmd datai_done [ 16];
- ncrcmd datao_done [ 10];
+ ncrcmd datai_done [ 26];
+ ncrcmd datao_done [ 12];
ncrcmd ign_i_w_r_msg [ 4];
#ifdef SCSI_NCR_PROFILE_SUPPORT
- ncrcmd dataphase [ 4];
+ ncrcmd datai_phase [ 4];
#else
- ncrcmd dataphase [ 2];
+ ncrcmd datai_phase [ 2];
#endif
+ ncrcmd datao_phase [ 4];
ncrcmd msg_in [ 2];
ncrcmd msg_in2 [ 10];
#ifdef SCSI_NCR_IARB_SUPPORT
@@ -2562,16 +2600,17 @@ struct script {
ncrcmd ungetjob [ 4];
#endif
ncrcmd reselect [ 4];
- ncrcmd reselected [ 48];
+ ncrcmd reselected [ 20];
+ ncrcmd resel_scntl4 [ 30];
#if MAX_TASKS*4 > 512
- ncrcmd resel_tag [ 16];
+ ncrcmd resel_tag [ 18];
#elif MAX_TASKS*4 > 256
- ncrcmd resel_tag [ 10];
+ ncrcmd resel_tag [ 12];
#else
- ncrcmd resel_tag [ 6];
+ ncrcmd resel_tag [ 8];
#endif
ncrcmd resel_go [ 6];
- ncrcmd resel_notag [ 4];
+ ncrcmd resel_notag [ 2];
ncrcmd resel_dsa [ 8];
ncrcmd data_in [MAX_SCATTER * SCR_SG_SIZE];
ncrcmd data_in2 [ 4];
@@ -2591,6 +2630,7 @@ struct script {
*/
struct scripth {
ncrcmd start64 [ 2];
+ ncrcmd no_data [ 2];
ncrcmd sel_for_abort [ 18];
ncrcmd sel_for_abort_1 [ 2];
ncrcmd select_no_atn [ 8];
@@ -2608,11 +2648,13 @@ struct scripth {
ncrcmd send_wdtr [ 4];
ncrcmd sdtr_resp [ 6];
ncrcmd send_sdtr [ 4];
+ ncrcmd ppr_resp [ 6];
+ ncrcmd send_ppr [ 4];
ncrcmd nego_bad_phase [ 4];
- ncrcmd msg_out_abort [ 12];
- ncrcmd msg_out [ 6];
+ ncrcmd msg_out [ 4];
ncrcmd msg_out_done [ 4];
- ncrcmd no_data [ 28];
+ ncrcmd data_ovrun [ 18];
+ ncrcmd data_ovrun1 [ 20];
ncrcmd abort_resel [ 16];
ncrcmd resend_ident [ 4];
ncrcmd ident_break [ 4];
@@ -2621,7 +2663,7 @@ struct scripth {
ncrcmd data_io [ 2];
ncrcmd data_io_com [ 8];
ncrcmd data_io_out [ 12];
- ncrcmd bad_identify [ 12];
+ ncrcmd resel_bad_lun [ 4];
ncrcmd bad_i_t_l [ 4];
ncrcmd bad_i_t_l_q [ 4];
ncrcmd bad_status [ 6];
@@ -2632,14 +2674,13 @@ struct scripth {
ncrcmd pm0_save [ 14];
ncrcmd pm1_save [ 14];
- /* SWIDE handling */
- ncrcmd swide_ma_32 [ 4];
- ncrcmd swide_ma_64 [ 6];
- ncrcmd swide_scr_64 [ 26];
- ncrcmd swide_scr_64_1 [ 12];
- ncrcmd swide_com_64 [ 6];
- ncrcmd swide_common [ 10];
- ncrcmd swide_fin_32 [ 24];
+ /* WSR handling */
+#ifdef SYM_DEBUG_PM_WITH_WSR
+ ncrcmd pm_wsr_handle [ 44];
+#else
+ ncrcmd pm_wsr_handle [ 42];
+#endif
+ ncrcmd wsr_ma_helper [ 4];
/* Data area */
ncrcmd zero [ 1];
@@ -2697,6 +2738,9 @@ static void ncr_int_sto (ncb_p np);
static void ncr_int_udc (ncb_p np);
static void ncr_negotiate (ncb_p np, tcb_p tp);
static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr);
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+static int ncr_ic_nego(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd, u_char *msgptr);
+#endif
#ifdef SCSI_NCR_PROFILE_SUPPORT
static void ncb_profile (ncb_p np, ccb_p cp);
#endif
@@ -2706,9 +2750,12 @@ static void ncr_script_fill (struct script * scr, struct scripth * scripth);
static int ncr_scatter_896R1 (ncb_p np, ccb_p cp, Scsi_Cmnd *cmd);
static int ncr_scatter (ncb_p np, ccb_p cp, Scsi_Cmnd *cmd);
static void ncr_getsync (ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p);
-static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer);
+static void ncr_get_xfer_info(ncb_p np, tcb_p tp, u_char *factor, u_char *offset, u_char *width);
+static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer, u_char scntl4);
+static void ncr_set_sync_wide_status (ncb_p np, u_char target);
static void ncr_setup_tags (ncb_p np, u_char tn, u_char ln);
static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack);
+static void ncr_setsyncwide (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer, u_char scntl4, u_char wide);
static int ncr_show_msg (u_char * msg);
static void ncr_print_msg (ccb_p cp, char *label, u_char * msg);
static int ncr_snooptest (ncb_p np);
@@ -2978,9 +3025,9 @@ static struct script script0 __initdata = {
SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),
PADDR (msg_in),
SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)),
- PADDR (dataphase),
+ PADDR (datao_phase),
SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)),
- PADDR (dataphase),
+ PADDR (datai_phase),
SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)),
PADDR (status),
SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)),
@@ -2988,6 +3035,12 @@ static struct script script0 __initdata = {
SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),
PADDRH (msg_out),
/*
+ * Set the extended error flag.
+ */
+ SCR_REG_REG (HF_REG, SCR_OR, HF_EXT_ERR),
+ 0,
+
+ /*
** Discard one illegal phase byte, if required.
*/
SCR_LOAD_REL (scratcha, 1),
@@ -3056,17 +3109,6 @@ static struct script script0 __initdata = {
SCR_JUMP,
PADDR (dispatch),
-}/*-------------------------< DISP_MSG_IN >----------------------*/,{
- /*
- ** Anticipate MSG_IN phase then STATUS phase.
- **
- ** May spare 2 SCRIPTS instructions when we have
- ** completed the OUTPUT of the data and the device
- ** goes directly to STATUS phase.
- */
- SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),
- PADDR (msg_in),
-
}/*-------------------------< DISP_STATUS >----------------------*/,{
/*
** Anticipate STATUS phase.
@@ -3081,6 +3123,12 @@ static struct script script0 __initdata = {
}/*-------------------------< DATAI_DONE >-------------------*/,{
/*
+ * If the device wants us to send more data,
+ * we must count the extra bytes.
+ */
+ SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_IN)),
+ PADDRH (data_ovrun),
+ /*
** If the SWIDE is not full, jump to dispatcher.
** We anticipate a STATUS phase.
** If we get later an IGNORE WIDE RESIDUE, we
@@ -3097,36 +3145,56 @@ static struct script script0 __initdata = {
SCR_REG_REG (scntl2, SCR_OR, WSR),
0,
/*
- ** Since the device is required to send any
- ** IGNORE WIDE RESIDUE message prior to any
- ** other information, we just snoop the SCSI
- ** BUS to check for such a message.
+ * We are expecting an IGNORE RESIDUE message
+ * from the device, otherwise we are in data
+ * overrun condition. Check against MSG_IN phase.
*/
+ SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),
+ SIR_SWIDE_OVERRUN,
SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
PADDR (disp_status),
- SCR_FROM_REG (sbdl),
- 0,
+ /*
+ * We are in MSG_IN phase,
+ * Read the first byte of the message.
+ * If it is not an IGNORE RESIDUE message,
+ * signal overrun and jump to message
+ * processing.
+ */
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin[0]),
+ SCR_INT ^ IFFALSE (DATA (M_IGN_RESIDUE)),
+ SIR_SWIDE_OVERRUN,
SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)),
- PADDR (disp_status),
+ PADDR (msg_in2),
+
/*
- ** We have been ODD at the end of the transfer,
- ** but the device hasn't be so.
- ** Signal a DATA OVERRUN condition to the C code.
- */
- SCR_INT,
- SIR_SWIDE_OVERRUN,
+ * We got the message we expected.
+ * Read the 2nd byte, and jump to dispatcher.
+ */
+ SCR_CLR (SCR_ACK),
+ 0,
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin[1]),
+ SCR_CLR (SCR_ACK),
+ 0,
SCR_JUMP,
- PADDR (dispatch),
+ PADDR (disp_status),
}/*-------------------------< DATAO_DONE >-------------------*/,{
/*
+ * If the device wants us to send more data,
+ * we must count the extra bytes.
+ */
+ SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
+ PADDRH (data_ovrun),
+ /*
** If the SODL is not full jump to dispatcher.
** We anticipate a MSG IN phase or a STATUS phase.
*/
SCR_FROM_REG (scntl2),
0,
SCR_JUMP ^ IFFALSE (MASK (WSS, WSS)),
- PADDR (disp_msg_in),
+ PADDR (disp_status),
/*
** The SODL is full, clear this condition.
*/
@@ -3157,13 +3225,25 @@ static struct script script0 __initdata = {
SCR_JUMP,
PADDR (clrack),
-}/*-------------------------< DATAPHASE >------------------*/,{
+}/*-------------------------< DATAI_PHASE >------------------*/,{
#ifdef SCSI_NCR_PROFILE_SUPPORT
SCR_REG_REG (QU_REG, SCR_OR, HF_DATA_ST),
0,
#endif
SCR_RETURN,
0,
+}/*-------------------------< DATAO_PHASE >------------------*/,{
+ /*
+ ** Patch for 53c1010_66 only - to allow A0 part
+ ** to operate properly in a 33MHz PCI bus.
+ **
+ ** SCR_REG_REG(scntl4, SCR_OR, 0x0c),
+ ** 0,
+ */
+ SCR_NO_OP,
+ 0,
+ SCR_RETURN,
+ 0,
}/*-------------------------< MSG_IN >--------------------*/,{
/*
** Get the first byte of the message.
@@ -3524,31 +3604,42 @@ static struct script script0 __initdata = {
offsetof(struct tcb, wval),
SCR_LOAD_REL (sxfer, 1),
offsetof(struct tcb, sval),
+}/*-------------------------< RESEL_SCNTL4 >------------------*/,{
/*
- ** If MESSAGE IN phase as expected,
- ** read the data directly from the BUS DATA lines.
- ** This helps to support very old SCSI devices that
- ** may reselect without sending an IDENTIFY.
+ ** Write with uval value. Patch if device
+ ** does not support Ultra3.
+ **
+ ** SCR_LOAD_REL (scntl4, 1),
+ ** offsetof(struct tcb, uval),
*/
+
+ SCR_NO_OP,
+ 0,
+ /*
+ * We expect MESSAGE IN phase.
+ * If not, get help from the C code.
+ */
SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),
SIR_RESEL_NO_MSG_IN,
- SCR_FROM_REG (sbdl),
- 0,
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin),
+
/*
- ** If message phase but not an IDENTIFY,
- ** get some help from the C code.
- ** Old SCSI device may behave so.
- */
+ * If IDENTIFY LUN #0, use a faster path
+ * to find the LCB structure.
+ */
+ SCR_JUMPR ^ IFTRUE (MASK (0x80, 0xbf)),
+ 56,
+ /*
+ * If message isn't an IDENTIFY,
+ * tell the C code about.
+ */
SCR_INT ^ IFFALSE (MASK (0x80, 0x80)),
SIR_RESEL_NO_IDENTIFY,
/*
- ** It is an IDENTIFY message,
- ** Load the LUN control block address.
- ** If LUN 0, avoid a PCI BUS ownership by loading
- ** directly 'b_lun0' from the TCB.
- */
- SCR_JUMPR ^ IFTRUE (MASK (0x0, 0x3f)),
- 48,
+ * It is an IDENTIFY message,
+ * Load the LUN control block address.
+ */
SCR_LOAD_REL (dsa, 4),
offsetof(struct tcb, b_luntbl),
SCR_SFBR_REG (dsa, SCR_SHL, 0),
@@ -3578,15 +3669,20 @@ static struct script script0 __initdata = {
offsetof(struct lcb, b_tasktbl),
SCR_RETURN,
0,
-
}/*-------------------------< RESEL_TAG >-------------------*/,{
/*
+ ** ACK the IDENTIFY or TAG previously received
+ */
+
+ SCR_CLR (SCR_ACK),
+ 0,
+ /*
** Read IDENTIFY + SIMPLE + TAG using a single MOVE.
** Agressive optimization, is'nt it?
** No need to test the SIMPLE TAG message, since the
** driver only supports conformant devices for tags. ;-)
*/
- SCR_MOVE_ABS (3) ^ SCR_MSG_IN,
+ SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
NADDR (msgin),
/*
** Read the TAG from the SIDL.
@@ -3627,14 +3723,9 @@ static struct script script0 __initdata = {
offsetof(struct ccb, phys.header.go.restart),
SCR_RETURN,
0,
+ /* In normal situations we branch to RESEL_DSA */
}/*-------------------------< RESEL_NOTAG >-------------------*/,{
/*
- ** No tag expected.
- ** Read an throw away the IDENTIFY.
- */
- SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
- NADDR (msgin),
- /*
** JUMP indirectly to the restart point of the CCB.
*/
SCR_JUMP,
@@ -3681,7 +3772,7 @@ static struct script script0 __initdata = {
SCR_CALL,
PADDR (datai_done),
SCR_JUMP,
- PADDRH (no_data),
+ PADDRH (data_ovrun),
}/*-------------------------< DATA_OUT >--------------------*/,{
/*
** Because the size depends on the
@@ -3700,7 +3791,7 @@ static struct script script0 __initdata = {
SCR_CALL,
PADDR (datao_done),
SCR_JUMP,
- PADDRH (no_data),
+ PADDRH (data_ovrun),
}/*-------------------------< PM0_DATA >--------------------*/,{
/*
@@ -3719,7 +3810,7 @@ static struct script script0 __initdata = {
** Check against expected direction.
*/
SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),
- PADDRH (no_data),
+ PADDRH (data_ovrun),
/*
** Keep track we are moving data from the
** PM0 DATA mini-script.
@@ -3739,7 +3830,7 @@ static struct script script0 __initdata = {
** Check against expected direction.
*/
SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),
- PADDRH (no_data),
+ PADDRH (data_ovrun),
/*
** Keep track we are moving data from the
** PM0 DATA mini-script.
@@ -3784,7 +3875,7 @@ static struct script script0 __initdata = {
** Check against expected direction.
*/
SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),
- PADDRH (no_data),
+ PADDRH (data_ovrun),
/*
** Keep track we are moving data from the
** PM1 DATA mini-script.
@@ -3804,7 +3895,7 @@ static struct script script0 __initdata = {
** Check against expected direction.
*/
SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),
- PADDRH (no_data),
+ PADDRH (data_ovrun),
/*
** Keep track we are moving data from the
** PM1 DATA mini-script.
@@ -3835,6 +3926,7 @@ static struct script script0 __initdata = {
}/*---------------------------------------------------------*/
};
+
static struct scripth scripth0 __initdata = {
/*------------------------< START64 >-----------------------*/{
/*
@@ -3844,7 +3936,9 @@ static struct scripth scripth0 __initdata = {
*/
SCR_JUMP,
PADDR (init),
-
+}/*-------------------------< NO_DATA >-------------------*/,{
+ SCR_JUMP,
+ PADDRH (data_ovrun),
}/*-----------------------< SEL_FOR_ABORT >------------------*/,{
/*
** We are jumped here by the C code, if we have
@@ -4078,33 +4172,31 @@ static struct scripth scripth0 __initdata = {
SCR_JUMP,
PADDRH (msg_out_done),
-}/*-------------------------< NEGO_BAD_PHASE >------------*/,{
- SCR_INT,
- SIR_NEGO_PROTO,
- SCR_JUMP,
- PADDR (dispatch),
-
-}/*-------------------------< MSG_OUT_ABORT >-------------*/,{
+}/*-------------------------< PPR_RESP >-------------*/,{
/*
- ** After ABORT message,
- **
- ** expect an immediate disconnect, ...
+ ** let the target fetch our answer.
*/
- SCR_REG_REG (scntl2, SCR_AND, 0x7f),
- 0,
- SCR_CLR (SCR_ACK|SCR_ATN),
+ SCR_SET (SCR_ATN),
0,
- SCR_WAIT_DISC,
+ SCR_CLR (SCR_ACK),
0,
- SCR_INT,
- SIR_MSG_OUT_DONE,
+ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),
+ PADDRH (nego_bad_phase),
+
+}/*-------------------------< SEND_PPR >-------------*/,{
/*
- ** ... and set the status to "ABORTED"
+ ** Send the M_X_PPR_REQ
*/
- SCR_LOAD_REG (HS_REG, HS_ABORTED),
- 0,
+ SCR_MOVE_ABS (8) ^ SCR_MSG_OUT,
+ NADDR (msgout),
SCR_JUMP,
- PADDR (complete2),
+ PADDRH (msg_out_done),
+
+}/*-------------------------< NEGO_BAD_PHASE >------------*/,{
+ SCR_INT,
+ SIR_NEGO_PROTO,
+ SCR_JUMP,
+ PADDR (dispatch),
}/*-------------------------< MSG_OUT >-------------------*/,{
/*
@@ -4113,11 +4205,6 @@ static struct scripth scripth0 __initdata = {
SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
NADDR (msgout),
/*
- ** If it was no ABORT message ...
- */
- SCR_JUMP ^ IFTRUE (DATA (M_ABORT)),
- PADDRH (msg_out_abort),
- /*
** ... wait for the next phase
** if it's a message out, send it again, ...
*/
@@ -4135,34 +4222,56 @@ static struct scripth scripth0 __initdata = {
SCR_JUMP,
PADDR (dispatch),
-}/*-------------------------< NO_DATA >--------------------*/,{
+}/*-------------------------< DATA_OVRUN >--------------------*/,{
/*
- ** The target wants to tranfer too much data
- ** or in the wrong direction.
- ** Remember that in extended error.
- */
+ * The target may want to transfer too much data.
+ *
+ * If phase is DATA OUT write 1 byte and count it.
+ */
+ SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),
+ 16,
+ SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT,
+ NADDR (scratch),
+ SCR_JUMP,
+ PADDRH (data_ovrun1),
+ /*
+ * If WSR is set, clear this condition, and
+ * count this byte.
+ */
+ SCR_FROM_REG (scntl2),
+ 0,
+ SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),
+ 16,
+ SCR_REG_REG (scntl2, SCR_OR, WSR),
+ 0,
+ SCR_JUMP,
+ PADDRH (data_ovrun1),
+ /*
+ * Finally check against DATA IN phase.
+ * Jump to dispatcher if not so.
+ * Read 1 byte otherwise and count it.
+ */
+ SCR_JUMP ^ IFFALSE (IF (SCR_DATA_IN)),
+ PADDR (dispatch),
+ SCR_CHMOV_ABS (1) ^ SCR_DATA_IN,
+ NADDR (scratch),
+}/*-------------------------< DATA_OVRUN1 >--------------------*/,{
+ /*
+ * Set the extended error flag.
+ */
+ SCR_REG_REG (HF_REG, SCR_OR, HF_EXT_ERR),
+ 0,
SCR_LOAD_REL (scratcha, 1),
offsetof (struct ccb, xerr_status),
- SCR_REG_REG (scratcha, SCR_OR, XE_EXTRA_DATA),
+ SCR_REG_REG (scratcha, SCR_OR, XE_EXTRA_DATA),
0,
SCR_STORE_REL (scratcha, 1),
offsetof (struct ccb, xerr_status),
/*
- ** Discard one data byte, if required.
- */
- SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),
- 8,
- SCR_MOVE_ABS (1) ^ SCR_DATA_OUT,
- NADDR (scratch),
- SCR_JUMPR ^ IFFALSE (IF (SCR_DATA_IN)),
- 8,
- SCR_MOVE_ABS (1) ^ SCR_DATA_IN,
- NADDR (scratch),
- /*
- ** Count this byte.
- ** This will allow to return a positive
- ** residual to user.
- */
+ * Count this byte.
+ * This will allow to return a negative
+ * residual to user.
+ */
SCR_LOAD_REL (scratcha, 4),
offsetof (struct ccb, phys.extra_bytes),
SCR_REG_REG (scratcha, SCR_ADD, 0x01),
@@ -4174,12 +4283,10 @@ static struct scripth scripth0 __initdata = {
SCR_STORE_REL (scratcha, 4),
offsetof (struct ccb, phys.extra_bytes),
/*
- ** .. and repeat as required.
- */
- SCR_CALL,
- PADDR (dispatch),
+ * .. and repeat as required.
+ */
SCR_JUMP,
- PADDRH (no_data),
+ PADDRH (data_ovrun),
}/*-------------------------< ABORT_RESEL >----------------*/,{
SCR_SET (SCR_ATN),
@@ -4227,10 +4334,9 @@ static struct scripth scripth0 __initdata = {
SCR_CHMOV_TBL ^ SCR_DATA_IN,
offsetof (struct dsb, sense),
SCR_CALL,
- PADDR (dispatch),
+ PADDR (datai_done),
SCR_JUMP,
- PADDRH (no_data),
-
+ PADDRH (data_ovrun),
}/*-------------------------< DATA_IO >--------------------*/,{
/*
** We jump here if the data direction was unknown at the
@@ -4280,29 +4386,14 @@ static struct scripth scripth0 __initdata = {
SCR_JUMP,
PADDRH(data_io_com),
-}/*-------------------------< BAD_IDENTIFY >---------------*/,{
- /*
- ** If message phase but not an IDENTIFY,
- ** get some help from the C code.
- ** Old SCSI device may behave so.
- */
- SCR_JUMPR ^ IFTRUE (MASK (0x80, 0x80)),
- 16,
- SCR_INT,
- SIR_RESEL_NO_IDENTIFY,
- SCR_JUMP,
- PADDRH (abort_resel),
+}/*-------------------------< RESEL_BAD_LUN >---------------*/,{
/*
** Message is an IDENTIFY, but lun is unknown.
- ** Read the message, since we got it directly
- ** from the SCSI BUS data lines.
** Signal problem to C code for logging the event.
** Send a M_ABORT to clear all pending tasks.
*/
SCR_INT,
SIR_RESEL_BAD_LUN,
- SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
- NADDR (msgin),
SCR_JUMP,
PADDRH (abort_resel),
}/*-------------------------< BAD_I_T_L >------------------*/,{
@@ -4441,7 +4532,7 @@ static struct scripth scripth0 __initdata = {
SCR_FROM_REG (scntl2),
0,
SCR_CALL ^ IFTRUE (MASK (WSR, WSR)),
- PADDRH (swide_scr_64),
+ PADDRH (pm_wsr_handle),
/*
** Save the remaining byte count, the updated
** address and the return address.
@@ -4468,7 +4559,7 @@ static struct scripth scripth0 __initdata = {
SCR_FROM_REG (scntl2),
0,
SCR_CALL ^ IFTRUE (MASK (WSR, WSR)),
- PADDRH (swide_scr_64),
+ PADDRH (pm_wsr_handle),
/*
** Save the remaining byte count, the updated
** address and the return address.
@@ -4484,101 +4575,32 @@ static struct scripth scripth0 __initdata = {
PADDRH (pm1_data_addr),
SCR_JUMP,
PADDR (dispatch),
-
-}/*--------------------------< SWIDE_MA_32 >-----------------------*/,{
- /*
- ** Handling of the SWIDE for 32 bit chips.
- **
- ** We jump here from the C code with SCRATCHA
- ** containing the address to write the SWIDE.
- ** - Save 32 bit address in <scratch>.
- */
- SCR_STORE_ABS (scratcha, 4),
- PADDRH (scratch),
- SCR_JUMP,
- PADDRH (swide_common),
-}/*--------------------------< SWIDE_MA_64 >-----------------------*/,{
+}/*--------------------------< PM_WSR_HANDLE >-----------------------*/,{
/*
- ** Handling of the SWIDE for 64 bit chips when the
- ** hardware handling of phase mismatch is disabled.
- **
- ** We jump here from the C code with SCRATCHA
- ** containing the address to write the SWIDE and
- ** SBR containing bit 32..39 of this address.
- ** - Save 32 bit address in <scratch>.
- ** - Move address bit 32..39 to SFBR.
- */
- SCR_STORE_ABS (scratcha, 4),
- PADDRH (scratch),
- SCR_FROM_REG (sbr),
- 0,
- SCR_JUMP,
- PADDRH (swide_com_64),
-}/*--------------------------< SWIDE_SCR_64 >-----------------------*/,{
- /*
- ** Handling of the SWIDE for 64 bit chips when
- ** hardware phase mismatch is enabled.
- ** We are entered with a SCR_CALL from PMO_SAVE
- ** and PM1_SAVE sub-scripts.
- **
- ** Snoop the SCSI BUS in case of the device
- ** willing to ignore this residue.
- ** If it does, we must only increment the RBC,
- ** since this register does reflect all bytes
- ** received from the SCSI BUS including the SWIDE.
- */
- SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
- PADDRH (swide_scr_64_1),
- SCR_FROM_REG (sbdl),
- 0,
- SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)),
- PADDRH (swide_scr_64_1),
- SCR_REG_REG (rbc, SCR_ADD, 1),
- 0,
- SCR_REG_REG (rbc1, SCR_ADDC, 0),
- 0,
- SCR_REG_REG (rbc2, SCR_ADDC, 0),
- 0,
- /*
- ** Save UA and RBC, since the PM0/1_SAVE
- ** sub-scripts haven't moved them to the
- ** context yet and the below MOV may just
- ** change their value.
- */
- SCR_STORE_ABS (ua, 4),
- PADDRH (scratch),
- SCR_STORE_ABS (rbc, 4),
- PADDRH (scratch1),
+ * Phase mismatch handling from SCRIPT with WSR set.
+ * Such a condition can occur if the chip wants to
+ * execute a CHMOV(size > 1) when the WSR bit is
+ * set and the target changes PHASE.
+ */
+#ifdef SYM_DEBUG_PM_WITH_WSR
/*
- ** Throw away the IGNORE WIDE RESIDUE message.
- ** since we just did take care of it.
- */
- SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
- NADDR (scratch),
- SCR_CLR (SCR_ACK),
- 0,
+ * Some debugging may still be needed.:)
+ */
+ SCR_INT,
+ SIR_PM_WITH_WSR,
+#endif
/*
- ** Restore UA and RBC registers and return.
- */
- SCR_LOAD_ABS (ua, 4),
- PADDRH (scratch),
- SCR_LOAD_ABS (rbc, 4),
- PADDRH (scratch1),
- SCR_RETURN,
- 0,
-}/*--------------------------< SWIDE_SCR_64_1 >---------------------*/,{
+ * We must move the residual byte to memory.
+ *
+ * UA contains bit 0..31 of the address to
+ * move the residual byte.
+ * Move it to the table indirect.
+ */
+ SCR_STORE_REL (ua, 4),
+ offsetof (struct ccb, phys.wresid.addr),
/*
- ** We must grab the SWIDE and move it to
- ** memory.
- **
- ** - Save UA (32 bit address) in <scratch>.
- ** - Move address bit 32..39 to SFBR.
- ** - Increment UA (updated address).
- */
- SCR_STORE_ABS (ua, 4),
- PADDRH (scratch),
- SCR_FROM_REG (rbc3),
- 0,
+ * Increment UA (move address to next position).
+ */
SCR_REG_REG (ua, SCR_ADD, 1),
0,
SCR_REG_REG (ua1, SCR_ADDC, 0),
@@ -4587,70 +4609,45 @@ static struct scripth scripth0 __initdata = {
0,
SCR_REG_REG (ua3, SCR_ADDC, 0),
0,
-}/*--------------------------< SWIDE_COM_64 >-----------------------*/,{
/*
- ** - Save DRS.
- ** - Load DRS with address bit 32..39 of the
- ** location to write the SWIDE.
- ** SFBR has been loaded with these bits.
- ** (Look above).
- */
- SCR_STORE_ABS (drs, 4),
- PADDRH (saved_drs),
- SCR_LOAD_ABS (drs, 4),
+ * Compute SCRATCHA as:
+ * - size to transfer = 1 byte.
+ * - bit 24..31 = high address bit [32...39].
+ */
+ SCR_LOAD_ABS (scratcha, 4),
PADDRH (zero),
- SCR_TO_REG (drs),
+ SCR_REG_REG (scratcha, SCR_OR, 1),
0,
-}/*--------------------------< SWIDE_COMMON >-----------------------*/,{
- /*
- ** - Save current DSA
- ** - Load DSA with bit 0..31 of the memory
- ** location to write the SWIDE.
- */
- SCR_STORE_ABS (dsa, 4),
- PADDRH (saved_dsa),
- SCR_LOAD_ABS (dsa, 4),
- PADDRH (scratch),
- /*
- ** Move the SWIDE to memory.
- ** Clear the WSR bit.
- */
- SCR_STORE_REL (swide, 1),
+ SCR_FROM_REG (rbc3),
0,
- SCR_REG_REG (scntl2, SCR_OR, WSR),
+ SCR_TO_REG (scratcha3),
0,
/*
- ** Restore the original DSA.
- */
- SCR_LOAD_ABS (dsa, 4),
- PADDRH (saved_dsa),
-}/*--------------------------< SWIDE_FIN_32 >-----------------------*/,{
- /*
- ** For 32 bit chip, the following SCRIPTS
- ** instruction is patched with a JUMP to dispatcher.
- ** (Look into the C code).
- */
- SCR_LOAD_ABS (drs, 4),
- PADDRH (saved_drs),
- /*
- ** 64 bit chip only.
- ** If PM handling from SCRIPTS, we are just
- ** a helper for the C code, so jump to
- ** dispatcher now.
- */
- SCR_FROM_REG (ccntl0),
+ * Move this value to the table indirect.
+ */
+ SCR_STORE_REL (scratcha, 4),
+ offsetof (struct ccb, phys.wresid.size),
+ /*
+ * Wait for a valid phase.
+ * While testing with bogus QUANTUM drives, the C1010
+ * sometimes raised a spurious phase mismatch with
+ * WSR and the CHMOV(1) triggered another PM.
+ * Waiting explicitely for the PHASE seemed to avoid
+ * the nested phase mismatch. Btw, this didn't happen
+ * using my IBM drives.
+ */
+ SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)),
0,
- SCR_JUMP ^ IFFALSE (MASK (ENPMJ, ENPMJ)),
- PADDR (dispatch),
/*
- ** 64 bit chip with hardware PM handling enabled.
- **
- ** Since we are paranoid:), we donnot want
- ** a SWIDE followed by a CHMOV(1) to lead to
- ** a CHMOV(0) in our PM context.
- ** We check against such a condition.
- ** Also does the C code.
- */
+ * Perform the move of the residual byte.
+ */
+ SCR_CHMOV_TBL ^ SCR_DATA_IN,
+ offsetof (struct ccb, phys.wresid),
+ /*
+ * We can now handle the phase mismatch with UA fixed.
+ * RBC[0..23]=0 is a special case that does not require
+ * a PM context. The C code also checks against this.
+ */
SCR_FROM_REG (rbc),
0,
SCR_RETURN ^ IFFALSE (DATA (0)),
@@ -4664,19 +4661,29 @@ static struct scripth scripth0 __initdata = {
SCR_RETURN ^ IFFALSE (DATA (0)),
0,
/*
- ** If we are there, RBC(0..23) is zero,
- ** and we just have to load the current
- ** DATA SCRIPTS address (register TEMP)
- ** with the IA and go to dispatch.
- ** No PM context is needed.
- */
+ * RBC[0..23]=0.
+ * Not only we donnot need a PM context, but this would
+ * lead to a bogus CHMOV(0). This condition means that
+ * the residual was the last byte to move from this CHMOV.
+ * So, we just have to move the current data script pointer
+ * (i.e. TEMP) to the SCRIPTS address following the
+ * interrupted CHMOV and jump to dispatcher.
+ */
SCR_STORE_ABS (ia, 4),
PADDRH (scratch),
SCR_LOAD_ABS (temp, 4),
PADDRH (scratch),
SCR_JUMP,
PADDR (dispatch),
-
+}/*--------------------------< WSR_MA_HELPER >-----------------------*/,{
+ /*
+ * Helper for the C code when WSR bit is set.
+ * Perform the move of the residual byte.
+ */
+ SCR_CHMOV_TBL ^ SCR_DATA_IN,
+ offsetof (struct ccb, phys.wresid),
+ SCR_JUMP,
+ PADDR (dispatch),
}/*-------------------------< ZERO >------------------------*/,{
SCR_DATA_ZERO,
}/*-------------------------< SCRATCH >---------------------*/,{
@@ -4792,6 +4799,7 @@ void __init ncr_script_fill (struct script * scr, struct scripth * scrh)
assert ((u_long)p == (u_long)&scr->data_in + sizeof (scr->data_in));
p = scr->data_out;
+
for (i=0; i<MAX_SCATTER; i++) {
*p++ =SCR_CHMOV_TBL ^ SCR_DATA_OUT;
*p++ =offsetof (struct dsb, data[i]);
@@ -4963,6 +4971,7 @@ ncr_script_copy_and_bind (ncb_p np,ncrcmd *src,ncrcmd *dst,int len)
break;
#ifdef RELOC_KVAR
case RELOC_KVAR:
+ new=0;
if (((old & ~RELOC_MASK) < SCRIPT_KVAR_FIRST) ||
((old & ~RELOC_MASK) > SCRIPT_KVAR_LAST))
panic("ncr KVAR out of range");
@@ -5152,16 +5161,30 @@ ncr_Tekram_setup_target(ncb_p np, int target, Tekram_nvram *nvram)
static void __init ncr_save_initial_setting(ncb_p np)
{
np->sv_scntl0 = INB(nc_scntl0) & 0x0a;
- np->sv_scntl3 = INB(nc_scntl3) & 0x07;
np->sv_dmode = INB(nc_dmode) & 0xce;
np->sv_dcntl = INB(nc_dcntl) & 0xa8;
np->sv_ctest3 = INB(nc_ctest3) & 0x01;
np->sv_ctest4 = INB(nc_ctest4) & 0x80;
- np->sv_ctest5 = INB(nc_ctest5) & 0x24;
np->sv_gpcntl = INB(nc_gpcntl);
np->sv_stest2 = INB(nc_stest2) & 0x20;
np->sv_stest4 = INB(nc_stest4);
np->sv_stest1 = INB(nc_stest1);
+
+ np->sv_scntl3 = INB(nc_scntl3) & 0x07;
+
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66) ){
+ /*
+ ** C1010 always uses large fifo, bit 5 rsvd
+ ** scntl4 used ONLY with C1010
+ */
+ np->sv_ctest5 = INB(nc_ctest5) & 0x04 ;
+ np->sv_scntl4 = INB(nc_scntl4);
+ }
+ else {
+ np->sv_ctest5 = INB(nc_ctest5) & 0x24 ;
+ np->sv_scntl4 = 0;
+ }
}
/*
@@ -5200,15 +5223,35 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
/*
* Divisor to be used for async (timer pre-scaler).
+ *
+ * Note: For C1010 the async divisor is 2(8) if he
+ * quadrupler is disabled (enabled).
*/
- i = np->clock_divn - 1;
- while (--i >= 0) {
- if (10ul * SCSI_NCR_MIN_ASYNC * np->clock_khz > div_10M[i]) {
- ++i;
- break;
+
+ if ( (np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+
+ np->rv_scntl3 = 0;
+ }
+ else
+ {
+ i = np->clock_divn - 1;
+ while (--i >= 0) {
+ if (10ul * SCSI_NCR_MIN_ASYNC * np->clock_khz
+ > div_10M[i]) {
+ ++i;
+ break;
+ }
}
+ np->rv_scntl3 = i+1;
}
- np->rv_scntl3 = i+1;
+
+
+ /*
+ * Save the ultra3 register for the C1010/C1010_66
+ */
+
+ np->rv_scntl4 = np->sv_scntl4;
/*
* Minimum synchronous period factor supported by the chip.
@@ -5222,13 +5265,28 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
else np->minsync = (period + 40 - 1) / 40;
/*
+ * Fix up. If sync. factor is 10 (160000Khz clock) and chip
+ * supports ultra3, then min. sync. period 12.5ns and the factor is 9
+ */
+
+ if ((np->minsync == 10) && (np->features & FE_ULTRA3))
+ np->minsync = 9;
+
+ /*
* Check against chip SCSI standard support (SCSI-2,ULTRA,ULTRA2).
+ *
+ * Transfer period minimums: SCSI-1 200 (50); Fast 100 (25)
+ * Ultra 50 (12); Ultra2 (6); Ultra3 (3)
*/
- if (np->minsync < 25 && !(np->features & (FE_ULTRA|FE_ULTRA2)))
+ if (np->minsync < 25 && !(np->features & (FE_ULTRA|FE_ULTRA2|FE_ULTRA3)))
np->minsync = 25;
- else if (np->minsync < 12 && !(np->features & FE_ULTRA2))
+ else if (np->minsync < 12 && (np->features & FE_ULTRA))
np->minsync = 12;
+ else if (np->minsync < 10 && (np->features & FE_ULTRA2))
+ np->minsync = 10;
+ else if (np->minsync < 9 && (np->features & FE_ULTRA3))
+ np->minsync = 9;
/*
* Maximum synchronous period factor supported by the chip.
@@ -5248,7 +5306,7 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
#endif
/*
- ** Phase mismatch handled by SCRIPTS (53C895A or 53C896) ?
+ ** Phase mismatch handled by SCRIPTS (53C895A, 53C896 or C1010) ?
*/
if (np->features & FE_NOPM)
np->rv_ccntl0 |= (ENPMJ);
@@ -5292,6 +5350,14 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);
/*
+ ** DEL ? - 53C1010 Rev 1 - Part Number 609-0393638
+ ** 64-bit Slave Cycles must be disabled.
+ */
+ if ( ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) && (np->revision_id < 0x02) )
+ || (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 ) )
+ np->rv_ccntl1 |= 0x10;
+
+ /*
** Select all supported special features.
** If we are using on-board RAM for scripts, prefetch (PFEN)
** does not help, but burst op fetch (BOF) does.
@@ -5313,8 +5379,13 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
np->rv_dcntl |= CLSE; /* Cache Line Size Enable */
if (np->features & FE_WRIE)
np->rv_ctest3 |= WRIE; /* Write and Invalidate */
- if (np->features & FE_DFS)
+
+
+ if ( (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) &&
+ (np->features & FE_DFS))
np->rv_ctest5 |= DFS; /* Dma Fifo Size */
+ /* C1010/C1010_66 always large fifo */
/*
** Select some other
@@ -5362,14 +5433,15 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
/*
** Set SCSI BUS mode.
**
- ** - ULTRA2 chips (895/895A/896) report the current
+ ** - ULTRA2 chips (895/895A/896)
+ ** and ULTRA 3 chips (1010) report the current
** BUS mode through the STEST4 IO register.
** - For previous generation chips (825/825A/875),
** user has to tell us how to check against HVD,
** since a 100% safe algorithm is not possible.
*/
np->scsi_mode = SMODE_SE;
- if (np->features & FE_ULTRA2)
+ if (np->features & (FE_ULTRA2 | FE_ULTRA3))
np->scsi_mode = (np->sv_stest4 & SMODE);
else if (np->features & FE_DIFF) {
switch(driver_setup.diff_support) {
@@ -5471,7 +5543,8 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
i == SCSI_NCR_SYMBIOS_NVRAM ? "Symbios format NVRAM, " :
(i == SCSI_NCR_TEKRAM_NVRAM ? "Tekram format NVRAM, " : ""),
np->myaddr,
- np->minsync < 12 ? 40 : (np->minsync < 25 ? 20 : 10),
+ np->minsync < 10 ? 80 :
+ (np->minsync < 12 ? 40 : (np->minsync < 25 ? 20 : 10) ),
(np->rv_scntl0 & 0xa) ? ", Parity Checking" : ", NO Parity",
(np->rv_stest2 & 0x20) ? ", Differential" : "");
@@ -5864,14 +5937,6 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
ncr_script_copy_and_bind (np, (ncrcmd *) &scripth0, (ncrcmd *) np->scripth0, sizeof(struct scripth));
/*
- ** If not 64 bit chip, patch some places in SCRIPTS.
- */
- if (!(np->features & FE_64BIT)) {
- np->scripth0->swide_fin_32[0] = cpu_to_scr(SCR_JUMP);
- np->scripth0->swide_fin_32[1] =
- cpu_to_scr(NCB_SCRIPT_PHYS(np, dispatch));
- }
- /*
** Patch some variables in SCRIPTS
*/
np->scripth0->pm0_data_addr[0] =
@@ -5879,6 +5944,15 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
np->scripth0->pm1_data_addr[0] =
cpu_to_scr(NCB_SCRIPT_PHYS(np, pm1_data));
+ /*
+ ** Patch if not Ultra 3 - Do not write to scntl4
+ */
+ if (np->features & FE_ULTRA3) {
+ np->script0->resel_scntl4[0] = cpu_to_scr(SCR_LOAD_REL (scntl4, 1));
+ np->script0->resel_scntl4[1] = cpu_to_scr(offsetof(struct tcb, uval));
+ }
+
+
#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
np->scripth0->script0_ba[0] = cpu_to_scr(vtobus(np->script0));
np->scripth0->script0_ba64[0] = cpu_to_scr(vtobus(np->script0));
@@ -5912,7 +5986,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
goto attach_error;
assert (offsetof(struct lcb, resel_task) == 0);
- np->resel_badlun = cpu_to_scr(NCB_SCRIPTH_PHYS(np, bad_identify));
+ np->resel_badlun = cpu_to_scr(NCB_SCRIPTH_PHYS(np, resel_bad_lun));
for (i = 0 ; i < 64 ; i++)
np->badluntbl[i] = cpu_to_scr(NCB_PHYS(np, resel_badlun));
@@ -5940,6 +6014,15 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
cpu_to_scr(SCR_REG_REG(gpreg, SCR_AND, 0xfe));
}
+ /*
+ ** Patch the script to provide an extra clock cycle on
+ ** data out phase - 53C1010_66MHz part only.
+ */
+ if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66){
+ np->script0->datao_phase[0] =
+ cpu_to_scr(SCR_REG_REG(scntl4, SCR_OR, 0x0c));
+ }
+
#ifdef SCSI_NCR_IARB_SUPPORT
/*
** If user does not want to use IMMEDIATE ARBITRATION
@@ -5968,8 +6051,11 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
#else
#define XXX 2
#endif
- np->script0->dataphase[XXX] = cpu_to_scr(SCR_JUMP);
- np->script0->dataphase[XXX+1] =
+ np->script0->datai_phase[XXX] = cpu_to_scr(SCR_JUMP);
+ np->script0->datai_phase[XXX+1] =
+ cpu_to_scr(NCB_SCRIPTH_PHYS (np, tweak_pmj));
+ np->script0->datao_phase[0] = cpu_to_scr(SCR_JUMP);
+ np->script0->datao_phase[1] =
cpu_to_scr(NCB_SCRIPTH_PHYS (np, tweak_pmj));
#undef XXX
}
@@ -5985,6 +6071,9 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
** We should use ncr_soft_reset(), but we donnot want to do
** so, since we may not be safe if ABRT interrupt occurs due
** to the BIOS or previous O/S having enable this interrupt.
+ **
+ ** For C1010 need to set ABRT bit prior to SRST if SCRIPTs
+ ** are running. Not true in this case.
*/
ncr_chip_reset(np);
@@ -6089,6 +6178,19 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
instance->dma_channel = 0;
instance->cmd_per_lun = MAX_TAGS;
instance->can_queue = (MAX_START-4);
+
+ np->check_integrity = 0;
+
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ instance->check_integrity = 0;
+
+#ifdef SCSI_NCR_ENABLE_INTEGRITY_CHECK
+ if ( !(driver_setup.bus_check & 0x04) ) {
+ np->check_integrity = 1;
+ instance->check_integrity = 1;
+ }
+#endif
+#endif
instance->select_queue_depths = sym53c8xx_select_queue_depths;
@@ -6214,6 +6316,299 @@ static inline void ncr_flush_done_cmds(Scsi_Cmnd *lcmd)
/*==========================================================
**
**
+** Prepare the next negotiation message for integrity check,
+** if needed.
+**
+** Fill in the part of message buffer that contains the
+** negotiation and the nego_status field of the CCB.
+** Returns the size of the message in bytes.
+**
+** If tp->ppr_negotiation is 1 and a M_REJECT occurs, then
+** we disable ppr_negotiation. If the first ppr_negotiation is
+** successful, set this flag to 2.
+**
+**==========================================================
+*/
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+static int ncr_ic_nego(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd, u_char *msgptr)
+{
+ tcb_p tp = &np->target[cp->target];
+ int msglen = 0;
+ int nego = 0;
+ u_char new_width, new_offset, new_period;
+ u_char no_increase;
+
+ if (tp->ppr_negotiation == 1) /* PPR message successful */
+ tp->ppr_negotiation = 2;
+
+ if (tp->inq_done) {
+
+ if (!tp->ic_maximums_set) {
+ tp->ic_maximums_set = 1;
+
+ /*
+ * Check against target, host and user limits
+ */
+ if ( (tp->inq_byte7 & INQ7_WIDE16) &&
+ np->maxwide && tp->usrwide)
+ tp->ic_max_width = 1;
+ else
+ tp->ic_max_width = 0;
+
+
+ if ((tp->inq_byte7 & INQ7_SYNC) && tp->maxoffs)
+ tp->ic_min_sync = (tp->minsync < np->minsync) ?
+ np->minsync : tp->minsync;
+ else
+ tp->ic_min_sync = 255;
+
+ tp->period = 1;
+ tp->widedone = 1;
+
+ /*
+ * Enable PPR negotiation - only if Ultra3 support
+ * is accessible.
+ */
+
+#if 0
+ if (tp->ic_max_width && (tp->ic_min_sync != 255 ))
+ tp->ppr_negotiation = 1;
+#endif
+ tp->ppr_negotiation = 0;
+ if (np->features & FE_ULTRA3) {
+ if (tp->ic_max_width && (tp->ic_min_sync == 0x09))
+ tp->ppr_negotiation = 1;
+ }
+
+ if (!tp->ppr_negotiation)
+ cmd->ic_nego &= ~NS_PPR;
+ }
+
+ if (DEBUG_FLAGS & DEBUG_IC) {
+ printk("%s: cmd->ic_nego %d, 1st byte 0x%2X\n",
+ ncr_name(np), cmd->ic_nego, cmd->cmnd[0]);
+ }
+
+ /* Previous command recorded a parity or an initiator
+ * detected error condition. Force bus to narrow for this
+ * target. Clear flag. Negotation on request sense.
+ * Note: kernel forces 2 bus resets :o( but clears itself out.
+ * Minor bug? in scsi_obsolete.c (ugly)
+ */
+ if (np->check_integ_par) {
+ printk("%s: Parity Error. Target set to narrow.\n",
+ ncr_name(np));
+ tp->ic_max_width = 0;
+ tp->widedone = tp->period = 0;
+ }
+
+ /* Initializing:
+ * If ic_nego == NS_PPR, we are in the initial test for
+ * PPR messaging support. If driver flag is clear, then
+ * either we don't support PPR nego (narrow or async device)
+ * or this is the second TUR and we have had a M. REJECT
+ * or unexpected disconnect on the first PPR negotiation.
+ * Do not negotiate, reset nego flags (in case a reset has
+ * occurred), clear ic_nego and return.
+ * General case: Kernel will clear flag on a fallback.
+ * Do only SDTR or WDTR in the future.
+ */
+ if (!tp->ppr_negotiation && (cmd->ic_nego == NS_PPR )) {
+ tp->ppr_negotiation = 0;
+ cmd->ic_nego &= ~NS_PPR;
+ tp->widedone = tp->period = 1;
+ return msglen;
+ }
+ else if (( tp->ppr_negotiation && !(cmd->ic_nego & NS_PPR )) ||
+ (!tp->ppr_negotiation && (cmd->ic_nego & NS_PPR )) ) {
+ tp->ppr_negotiation = 0;
+ cmd->ic_nego &= ~NS_PPR;
+ }
+
+ /*
+ * Always check the PPR nego. flag bit if ppr_negotiation
+ * is set. If the ic_nego PPR bit is clear,
+ * there must have been a fallback. Do only
+ * WDTR / SDTR in the future.
+ */
+ if ((tp->ppr_negotiation) && (!(cmd->ic_nego & NS_PPR)))
+ tp->ppr_negotiation = 0;
+
+ /* In case of a bus reset, ncr_negotiate will reset
+ * the flags tp->widedone and tp->period to 0, forcing
+ * a new negotiation. Do WDTR then SDTR. If PPR, do both.
+ * Do NOT increase the period. It is possible for the Scsi_Cmnd
+ * flags to be set to increase the period when a bus reset
+ * occurs - we don't want to change anything.
+ */
+
+ no_increase = 0;
+
+ if (tp->ppr_negotiation && (!tp->widedone) && (!tp->period) ) {
+ cmd->ic_nego = NS_PPR;
+ tp->widedone = tp->period = 1;
+ no_increase = 1;
+ }
+ else if (!tp->widedone) {
+ cmd->ic_nego = NS_WIDE;
+ tp->widedone = 1;
+ no_increase = 1;
+ }
+ else if (!tp->period) {
+ cmd->ic_nego = NS_SYNC;
+ tp->period = 1;
+ no_increase = 1;
+ }
+
+ new_width = cmd->ic_nego_width & tp->ic_max_width;
+
+ switch (cmd->ic_nego_sync) {
+ case 2: /* increase the period */
+ if (!no_increase) {
+ if (tp->ic_min_sync <= 0x09)
+ tp->ic_min_sync = 0x0A;
+ else if (tp->ic_min_sync <= 0x0A)
+ tp->ic_min_sync = 0x0C;
+ else if (tp->ic_min_sync <= 0x0C)
+ tp->ic_min_sync = 0x19;
+ else if (tp->ic_min_sync <= 0x19)
+ tp->ic_min_sync *= 2;
+ else {
+ tp->ic_min_sync = 255;
+ cmd->ic_nego_sync = 0;
+ tp->maxoffs = 0;
+ }
+ }
+ new_period = tp->maxoffs?tp->ic_min_sync:0;
+ new_offset = tp->maxoffs;
+ break;
+
+ case 1: /* nego. to maximum */
+ new_period = tp->maxoffs?tp->ic_min_sync:0;
+ new_offset = tp->maxoffs;
+ break;
+
+ case 0: /* nego to async */
+ default:
+ new_period = 0;
+ new_offset = 0;
+ break;
+ };
+
+
+ nego = NS_NOCHANGE;
+ if (tp->ppr_negotiation) {
+ u_char options_byte = 0;
+
+ /*
+ ** Must make sure data is consistent.
+ ** If period is 9 and sync, must be wide and DT bit set.
+ ** else period must be larger. If the width is 0,
+ ** reset bus to wide but increase the period to 0x0A.
+ ** Note: The strange else clause is due to the integrity check.
+ ** If fails at 0x09, wide, the I.C. code will redo at the same
+ ** speed but a narrow bus. The driver must take care of slowing
+ ** the bus speed down.
+ **
+ ** The maximum offset in ST mode is 31, in DT mode 62 (1010/1010_66 only)
+ */
+ if ( (new_period==0x09) && new_offset) {
+ if (new_width)
+ options_byte = 0x02;
+ else {
+ tp->ic_min_sync = 0x0A;
+ new_period = 0x0A;
+ cmd->ic_nego_width = 1;
+ new_width = 1;
+ new_offset &= 0x1f;
+ }
+ }
+ else if (new_period > 0x09)
+ new_offset &= 0x1f;
+
+ nego = NS_PPR;
+
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 6;
+ msgptr[msglen++] = M_X_PPR_REQ;
+ msgptr[msglen++] = new_period;
+ msgptr[msglen++] = 0;
+ msgptr[msglen++] = new_offset;
+ msgptr[msglen++] = new_width;
+ msgptr[msglen++] = options_byte;
+
+ }
+ else {
+ switch (cmd->ic_nego & ~NS_PPR) {
+ case NS_WIDE:
+ /*
+ ** WDTR negotiation on if device supports
+ ** wide or if wide device forced narrow
+ ** due to a parity error.
+ */
+
+ cmd->ic_nego_width &= tp->ic_max_width;
+
+ if (tp->ic_max_width | np->check_integ_par) {
+ nego = NS_WIDE;
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 2;
+ msgptr[msglen++] = M_X_WIDE_REQ;
+ msgptr[msglen++] = new_width;
+ }
+ break;
+
+ case NS_SYNC:
+ /*
+ ** negotiate synchronous transfers
+ ** Target must support sync transfers.
+ ** Min. period = 0x0A, maximum offset of 31=0x1f.
+ */
+
+ if (tp->inq_byte7 & INQ7_SYNC) {
+
+ if (new_offset && (new_period < 0x0A)) {
+ tp->ic_min_sync = 0x0A;
+ new_period = 0x0A;
+ }
+ nego = NS_SYNC;
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 3;
+ msgptr[msglen++] = M_X_SYNC_REQ;
+ msgptr[msglen++] = new_period;
+ msgptr[msglen++] = new_offset & 0x1f;
+ }
+ else
+ cmd->ic_nego_sync = 0;
+ break;
+
+ case NS_NOCHANGE:
+ break;
+ }
+ }
+
+ };
+
+ cp->nego_status = nego;
+ np->check_integ_par = 0;
+
+ if (nego) {
+ tp->nego_cp = cp;
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ ncr_print_msg(cp, nego == NS_WIDE ?
+ "wide/narrow msgout":
+ (nego == NS_SYNC ? "sync/async msgout" : "ppr msgout"),
+ msgptr);
+ };
+ };
+
+ return msglen;
+}
+#endif /* SCSI_NCR_INTEGRITY_CHECKING */
+
+/*==========================================================
+**
+**
** Prepare the next negotiation message if needed.
**
** Fill in the part of message buffer that contains the
@@ -6224,13 +6619,42 @@ static inline void ncr_flush_done_cmds(Scsi_Cmnd *lcmd)
**==========================================================
*/
+
static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr)
{
tcb_p tp = &np->target[cp->target];
int msglen = 0;
int nego = 0;
+ u_char width, offset, factor, last_byte;
+
+ if (!np->check_integrity) {
+ /* If integrity checking disabled, enable PPR messaging
+ * if device supports wide, sync and ultra 3
+ */
+ if (tp->ppr_negotiation == 1) /* PPR message successful */
+ tp->ppr_negotiation = 2;
+
+ if ((tp->inq_done) && (!tp->ic_maximums_set)) {
+ tp->ic_maximums_set = 1;
+
+ /*
+ * Issue PPR only if board is capable
+ * and set-up for Ultra3 transfers.
+ */
+ tp->ppr_negotiation = 0;
+ if ( (np->features & FE_ULTRA3) &&
+ (tp->usrwide) && (tp->maxoffs) &&
+ (tp->minsync == 0x09) )
+ tp->ppr_negotiation = 1;
+ }
+ }
if (tp->inq_done) {
+ /*
+ * Get the current width, offset and period
+ */
+ ncr_get_xfer_info( np, tp, &factor,
+ &offset, &width);
/*
** negotiate wide transfers ?
@@ -6238,19 +6662,50 @@ static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr)
if (!tp->widedone) {
if (tp->inq_byte7 & INQ7_WIDE16) {
- nego = NS_WIDE;
+ if (tp->ppr_negotiation)
+ nego = NS_PPR;
+ else
+ nego = NS_WIDE;
+
+ width = tp->usrwide;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ if (tp->ic_done)
+ width &= tp->ic_max_width;
+#endif
} else
tp->widedone=1;
+
};
/*
** negotiate synchronous transfers?
*/
- if (!nego && !tp->period) {
+ if ((nego != NS_WIDE) && !tp->period) {
if (tp->inq_byte7 & INQ7_SYNC) {
- nego = NS_SYNC;
+ if (tp->ppr_negotiation)
+ nego = NS_PPR;
+ else
+ nego = NS_SYNC;
+
+ /* Check for async flag */
+ if (tp->maxoffs == 0) {
+ offset = 0;
+ factor = 0;
+ }
+ else {
+ offset = tp->maxoffs;
+ factor = tp->minsync;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ if ((tp->ic_done) &&
+ (factor < tp->ic_min_sync))
+ factor = tp->ic_min_sync;
+#endif
+ }
+
} else {
+ offset = 0;
+ factor = 0;
tp->period =0xffff;
PRINT_TARGET(np, cp->target);
printk ("target did not report SYNC.\n");
@@ -6259,18 +6714,54 @@ static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr)
};
switch (nego) {
+ case NS_PPR:
+ /*
+ ** Must make sure data is consistent.
+ ** If period is 9 and sync, must be wide and DT bit set
+ ** else period must be larger.
+ ** Maximum offset is 31=0x1f is ST mode, 62 if DT mode
+ */
+ last_byte = 0;
+ if ( (factor==9) && offset) {
+ if (!width) {
+ factor = 0x0A;
+ offset &= 0x1f;
+ }
+ else
+ last_byte = 0x02;
+ }
+ else if (factor > 0x09)
+ offset &= 0x1f;
+
+ msgptr[msglen++] = M_EXTENDED;
+ msgptr[msglen++] = 6;
+ msgptr[msglen++] = M_X_PPR_REQ;
+ msgptr[msglen++] = factor;
+ msgptr[msglen++] = 0;
+ msgptr[msglen++] = offset;
+ msgptr[msglen++] = width;
+ msgptr[msglen++] = last_byte;
+ break;
case NS_SYNC:
+ /*
+ ** Never negotiate faster than Ultra 2 (25ns periods)
+ */
+ if (offset && (factor < 0x0A)) {
+ factor = 0x0A;
+ tp->minsync = 0x0A;
+ }
+
msgptr[msglen++] = M_EXTENDED;
msgptr[msglen++] = 3;
msgptr[msglen++] = M_X_SYNC_REQ;
- msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0;
- msgptr[msglen++] = tp->maxoffs;
+ msgptr[msglen++] = factor;
+ msgptr[msglen++] = offset & 0x1f;
break;
case NS_WIDE:
msgptr[msglen++] = M_EXTENDED;
msgptr[msglen++] = 2;
msgptr[msglen++] = M_X_WIDE_REQ;
- msgptr[msglen++] = tp->usrwide;
+ msgptr[msglen++] = width;
break;
};
@@ -6280,7 +6771,9 @@ static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr)
tp->nego_cp = cp;
if (DEBUG_FLAGS & DEBUG_NEGO) {
ncr_print_msg(cp, nego == NS_WIDE ?
- "wide msgout":"sync_msgout", msgptr);
+ "wide msgout":
+ (nego == NS_SYNC ? "sync msgout" : "ppr msgout"),
+ msgptr);
};
};
@@ -6464,6 +6957,73 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
cp->segments = 0;
}
+ /*---------------------------------------------------
+ **
+ ** negotiation required?
+ **
+ ** (nego_status is filled by ncr_prepare_nego())
+ **
+ **---------------------------------------------------
+ */
+
+ cp->nego_status = 0;
+
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ if ((np->check_integrity && tp->ic_done) || !np->check_integrity) {
+ if ((!tp->widedone || !tp->period) && !tp->nego_cp && lp) {
+ msglen += ncr_prepare_nego (np, cp, msgptr + msglen);
+ }
+ }
+ else if (np->check_integrity && (cmd->ic_in_progress)) {
+ msglen += ncr_ic_nego (np, cp, cmd, msgptr + msglen);
+ }
+ else if (np->check_integrity && cmd->ic_complete) {
+ u_long current_period;
+ u_char current_offset, current_width, current_factor;
+
+ ncr_get_xfer_info (np, tp, &current_factor,
+ &current_offset, &current_width);
+
+ tp->ic_max_width = current_width;
+ tp->ic_min_sync = current_factor;
+
+ if (current_factor == 9) current_period = 125;
+ else if (current_factor == 10) current_period = 250;
+ else if (current_factor == 11) current_period = 303;
+ else if (current_factor == 12) current_period = 500;
+ else current_period = current_factor * 40;
+
+ /*
+ * Negotiation for this target is complete. Update flags.
+ */
+ tp->period = current_period;
+ tp->widedone = 1;
+ tp->ic_done = 1;
+
+ printk("%s: Integrity Check Complete: \n", ncr_name(np));
+
+ printk("%s: %s %s SCSI", ncr_name(np),
+ current_offset?"SYNC":"ASYNC",
+ tp->ic_max_width?"WIDE":"NARROW");
+ if (current_offset) {
+ u_long mbs = 10000 * (tp->ic_max_width + 1);
+
+ printk(" %d.%d MB/s",
+ (int) (mbs / current_period), (int) (mbs % current_period));
+
+ printk(" (%d ns, %d offset)\n",
+ (int) current_period/10, current_offset);
+ }
+ else
+ printk(" %d MB/s. \n ", (tp->ic_max_width+1)*5);
+ }
+#else
+ if ((!tp->widedone || !tp->period) && !tp->nego_cp && lp) {
+ msglen += ncr_prepare_nego (np, cp, msgptr + msglen);
+ }
+#endif /* SCSI_NCR_INTEGRITY_CHECKING */
+
+
/*----------------------------------------------------
**
** Determine xfer direction.
@@ -6524,19 +7084,6 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
cp->startp = cp->phys.header.savep;
cp->lastp0 = cp->phys.header.lastp;
- /*---------------------------------------------------
- **
- ** negotiation required?
- **
- ** (nego_status is filled by ncr_prepare_nego())
- **
- **---------------------------------------------------
- */
-
- cp->nego_status = 0;
- if ((!tp->widedone || !tp->period) && !tp->nego_cp && lp)
- msglen += ncr_prepare_nego (np, cp, msgptr + msglen);
-
/*----------------------------------------------------
**
** fill in ccb
@@ -6559,6 +7106,7 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
cp->phys.select.sel_id = cp->target;
cp->phys.select.sel_scntl3 = tp->wval;
cp->phys.select.sel_sxfer = tp->sval;
+ cp->phys.select.sel_scntl4 = tp->uval;
/*
** message
*/
@@ -7091,6 +7639,14 @@ void ncr_complete (ncb_p np, ccb_p cp)
PRINT_ADDR(cmd);
printk ("illegal scsi phase (4/5).\n");
}
+ if (cp->xerr_status & XE_SODL_UNRUN) {
+ PRINT_ADDR(cmd);
+ printk ("ODD transfer in DATA OUT phase.\n");
+ }
+ if (cp->xerr_status & XE_SWIDE_OVRUN){
+ PRINT_ADDR(cmd);
+ printk ("ODD transfer in DATA IN phase.\n");
+ }
if (cp->host_status==HS_COMPLETE)
cp->host_status = HS_FAIL;
@@ -7167,6 +7723,12 @@ void ncr_complete (ncb_p np, ccb_p cp)
PRINT_ADDR(cmd);
ncr_printl_hex("sense data:", cmd->sense_buffer, 14);
}
+ } else if ((cp->host_status == HS_COMPLETE)
+ && (cp->scsi_status == S_CONFLICT)) {
+ /*
+ ** Reservation Conflict condition code
+ */
+ SetScsiResult(cmd, DID_OK, S_CONFLICT);
} else if ((cp->host_status == HS_COMPLETE)
&& (cp->scsi_status == S_BUSY ||
@@ -7418,7 +7980,11 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
OUTB (nc_ctest3, np->rv_ctest3); /* Write and invalidate */
OUTB (nc_ctest4, np->rv_ctest4); /* Master parity checking */
- OUTB (nc_stest2, EXT|np->rv_stest2); /* Extended Sreq/Sack filtering */
+ if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66)){
+ OUTB (nc_stest2, EXT|np->rv_stest2);
+ /* Extended Sreq/Sack filtering, not supported in C1010/C1010_66 */
+ }
OUTB (nc_stest3, TE); /* TolerANT enable */
OUTB (nc_stime0, 0x0c); /* HTH disabled STO 0.25 sec */
@@ -7427,14 +7993,24 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
** Disable overlapped arbitration for all dual-function
** devices, regardless revision id.
** We may consider it is a post-chip-design feature. ;-)
+ **
+ ** Errata applies to all 896 and 1010 parts.
*/
if (np->device_id == PCI_DEVICE_ID_NCR_53C875)
OUTB (nc_ctest0, (1<<5));
- else if (np->device_id == PCI_DEVICE_ID_NCR_53C896)
+ else if (np->device_id == PCI_DEVICE_ID_NCR_53C896 ||
+ np->device_id == PCI_DEVICE_ID_LSI_53C1010 ||
+ np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 )
np->rv_ccntl0 |= DPR;
/*
- ** If 64 bit (895A/896/1010) write the CCNTL1 register to
+ ** C1010_66MHz rev 0 part requies AIPCNTL1 bit 3 to be set.
+ */
+ if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)
+ OUTB(nc_aipcntl1, (1<<3));
+
+ /*
+ ** If 64 bit (895A/896/1010/1010_66) write the CCNTL1 register to
** enable 40 bit address table indirect addressing for MOVE.
** Also write CCNTL0 if 64 bit chip, since this register seems
** to only be used by 64 bit cores.
@@ -7445,8 +8021,8 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
}
/*
- ** If phase mismatch handled by scripts (53C895A or 53C896),
- ** set PM jump addresses.
+ ** If phase mismatch handled by scripts (53C895A or 53C896
+ ** or 53C1010 or 53C1010_66), set PM jump addresses.
*/
if (np->features & FE_NOPM) {
@@ -7475,9 +8051,10 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
OUTB (nc_dien , MDPE|BF|SSI|SIR|IID);
/*
- ** For 895/6 enable SBMC interrupt and save current SCSI bus mode.
+ ** For 895/895A/896/c1010
+ ** Enable SBMC interrupt and save current SCSI bus mode.
*/
- if (np->features & FE_ULTRA2) {
+ if ( (np->features & FE_ULTRA2) || (np->features & FE_ULTRA3) ) {
OUTONW (nc_sien, SBMC);
np->scsi_mode = INB (nc_stest4) & SMODE;
}
@@ -7496,6 +8073,7 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
tp->sval = 0;
tp->wval = np->rv_scntl3;
+ tp->uval = np->rv_scntl4;
if (tp->usrsync != 255) {
if (tp->usrsync <= np->maxsync) {
@@ -7626,6 +8204,10 @@ static void ncr_getsync(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p)
/*
** Compute the synchronous period in tenths of nano-seconds
+ ** from sfac.
+ **
+ ** Note, if sfac == 9, DT is being used. Double the period of 125
+ ** to 250.
*/
if (sfac <= 10) per = 250;
else if (sfac == 11) per = 303;
@@ -7673,7 +8255,76 @@ static void ncr_getsync(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p)
** Compute and return sync parameters for the ncr
*/
*fakp = fak - 4;
- *scntl3p = ((div+1) << 4) + (sfac < 25 ? 0x80 : 0);
+
+ /*
+ ** If sfac < 25, and 8xx parts, desire that the chip operate at
+ ** least at Ultra speeds. Must set bit 7 of scntl3.
+ ** For C1010, do not set this bit. If operating at Ultra3 speeds,
+ ** set the U3EN bit instead.
+ */
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+ *scntl3p = (div+1) << 4;
+ *fakp = 0;
+ }
+ else {
+ *scntl3p = ((div+1) << 4) + (sfac < 25 ? 0x80 : 0);
+ *fakp = fak - 4;
+ }
+}
+
+/*==========================================================
+**
+** Utility routine to return the current bus width
+** synchronous period and offset.
+** Utilizes target sval, wval and uval
+**
+**==========================================================
+*/
+static void ncr_get_xfer_info(ncb_p np, tcb_p tp, u_char *factor,
+ u_char *offset, u_char *width)
+{
+
+ u_char idiv;
+ u_long period;
+
+ *width = (tp->wval & EWS) ? 1 : 0;
+
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
+ *offset = (tp->sval & 0x3f);
+ else
+ *offset = (tp->sval & 0x1f);
+
+ /*
+ * Midlayer signal to the driver that all of the scsi commands
+ * for the integrity check have completed. Save the negotiated
+ * parameters (extracted from sval, wval and uval).
+ * See ncr_setsync for alg. details.
+ */
+
+ idiv = (tp->wval>>4) & 0x07;
+
+ if ( *offset && idiv ) {
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)){
+ if (tp->uval & 0x80)
+ period = (2*div_10M[idiv-1])/np->clock_khz;
+ else
+ period = (4*div_10M[idiv-1])/np->clock_khz;
+ }
+ else
+ period = (((tp->sval>>5)+4)*div_10M[idiv-1])/np->clock_khz;
+ }
+ else
+ period = 0xffff;
+
+ if (period <= 125) *factor = 9;
+ else if (period <= 250) *factor = 10;
+ else if (period <= 303) *factor = 11;
+ else if (period <= 500) *factor = 12;
+ else *factor = (period + 40 - 1) / 40;
+
}
@@ -7687,14 +8338,20 @@ static void ncr_getsync(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p)
static void ncr_set_sync_wide_status (ncb_p np, u_char target)
{
- ccb_p cp;
+ ccb_p cp = np->ccbc;
tcb_p tp = &np->target[target];
/*
** set actual value and sync_status
+ **
+ ** TEMP register contains current scripts address
+ ** which is data type/direction/dependent.
*/
OUTB (nc_sxfer, tp->sval);
OUTB (nc_scntl3, tp->wval);
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
+ OUTB (nc_scntl4, tp->uval);
/*
** patch ALL ccbs of this target.
@@ -7706,6 +8363,9 @@ static void ncr_set_sync_wide_status (ncb_p np, u_char target)
continue;
cp->phys.select.sel_scntl3 = tp->wval;
cp->phys.select.sel_sxfer = tp->sval;
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
+ cp->phys.select.sel_scntl4 = tp->uval;
};
}
@@ -7716,11 +8376,13 @@ static void ncr_set_sync_wide_status (ncb_p np, u_char target)
**==========================================================
*/
-static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer)
+static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer,
+ u_char scntl4)
{
tcb_p tp;
u_char target = INB (nc_sdid) & 0x0f;
u_char idiv;
+ u_char offset;
assert (cp);
if (!cp) return;
@@ -7729,9 +8391,21 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer)
tp = &np->target[target];
- if (!scntl3 || !(sxfer & 0x1f))
- scntl3 = np->rv_scntl3;
- scntl3 = (scntl3 & 0xf0) | (tp->wval & EWS) | (np->rv_scntl3 & 0x07);
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+ offset = sxfer & 0x3f; /* bits 5-0 */
+ scntl3 = (scntl3 & 0xf0) | (tp->wval & EWS);
+ scntl4 = (scntl4 & 0x80);
+ }
+ else {
+ offset = sxfer & 0x1f; /* bits 4-0 */
+ if (!scntl3 || !offset)
+ scntl3 = np->rv_scntl3;
+
+ scntl3 = (scntl3 & 0xf0) | (tp->wval & EWS) |
+ (np->rv_scntl3 & 0x07);
+ }
+
/*
** Deduce the value of controller sync period from scntl3.
@@ -7739,27 +8413,42 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer)
*/
idiv = ((scntl3 >> 4) & 0x7);
- if ((sxfer & 0x1f) && idiv)
- tp->period = (((sxfer>>5)+4)*div_10M[idiv-1])/np->clock_khz;
+ if ( offset && idiv) {
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+ /* Note: If extra data hold clocks are used,
+ * the formulas below must be modified.
+ * When scntl4 == 0, ST mode.
+ */
+ if (scntl4 & 0x80)
+ tp->period = (2*div_10M[idiv-1])/np->clock_khz;
+ else
+ tp->period = (4*div_10M[idiv-1])/np->clock_khz;
+ }
+ else
+ tp->period = (((sxfer>>5)+4)*div_10M[idiv-1])/np->clock_khz;
+ }
else
tp->period = 0xffff;
+
/*
** Stop there if sync parameters are unchanged
*/
- if (tp->sval == sxfer && tp->wval == scntl3) return;
+ if (tp->sval == sxfer && tp->wval == scntl3 && tp->uval == scntl4) return;
tp->sval = sxfer;
tp->wval = scntl3;
+ tp->uval = scntl4;
/*
** Bells and whistles ;-)
** Donnot announce negotiations due to auto-sense,
** unless user really want us to be verbose. :)
*/
- if (bootverbose < 2 && (cp->host_flags & HF_AUTO_SENSE))
+ if ( bootverbose < 2 && (cp->host_flags & HF_AUTO_SENSE))
goto next;
PRINT_TARGET(np, target);
- if (sxfer & 0x01f) {
+ if (offset) {
unsigned f10 = 100000 << (tp->widedone ? tp->widedone -1 : 0);
unsigned mb10 = (f10 + tp->period/2) / tp->period;
char *scsi;
@@ -7767,19 +8456,23 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer)
/*
** Disable extended Sreq/Sack filtering
*/
- if (tp->period <= 2000) OUTOFFB (nc_stest2, EXT);
+ if ((tp->period <= 2000) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
+ OUTOFFB (nc_stest2, EXT);
/*
** Bells and whistles ;-)
*/
- if (tp->period < 500) scsi = "FAST-40";
+ if (tp->period < 250) scsi = "FAST-80";
+ else if (tp->period < 500) scsi = "FAST-40";
else if (tp->period < 1000) scsi = "FAST-20";
else if (tp->period < 2000) scsi = "FAST-10";
else scsi = "FAST-5";
printk ("%s %sSCSI %d.%d MB/s (%d ns, offset %d)\n", scsi,
tp->widedone > 1 ? "WIDE " : "",
- mb10 / 10, mb10 % 10, tp->period / 10, sxfer & 0x1f);
+ mb10 / 10, mb10 % 10, tp->period / 10, offset);
} else
printk ("%sasynchronous.\n", tp->widedone > 1 ? "wide " : "");
next:
@@ -7790,6 +8483,7 @@ next:
ncr_set_sync_wide_status(np, target);
}
+
/*==========================================================
**
** Switch wide mode for current job and it's target
@@ -7843,6 +8537,126 @@ static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack)
ncr_set_sync_wide_status(np, target);
}
+
+/*==========================================================
+**
+** Switch sync/wide mode for current job and it's target
+** PPR negotiations only
+**
+**==========================================================
+*/
+
+static void ncr_setsyncwide (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer,
+ u_char scntl4, u_char wide)
+{
+ tcb_p tp;
+ u_char target = INB (nc_sdid) & 0x0f;
+ u_char idiv;
+ u_char offset;
+
+ assert (cp);
+ if (!cp) return;
+
+ assert (target == (cp->target & 0xf));
+
+ tp = &np->target[target];
+ tp->widedone = wide+1;
+
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+ offset = sxfer & 0x3f; /* bits 5-0 */
+ scntl3 = (scntl3 & 0xf0) | (wide ? EWS : 0);
+ scntl4 = (scntl4 & 0x80);
+ }
+ else {
+ offset = sxfer & 0x1f; /* bits 4-0 */
+ if (!scntl3 || !offset)
+ scntl3 = np->rv_scntl3;
+
+ scntl3 = (scntl3 & 0xf0) | (wide ? EWS : 0) |
+ (np->rv_scntl3 & 0x07);
+ }
+
+
+ /*
+ ** Deduce the value of controller sync period from scntl3.
+ ** period is in tenths of nano-seconds.
+ */
+
+ idiv = ((scntl3 >> 4) & 0x7);
+ if ( offset && idiv) {
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+ /* Note: If extra data hold clocks are used,
+ * the formulas below must be modified.
+ * When scntl4 == 0, ST mode.
+ */
+ if (scntl4 & 0x80)
+ tp->period = (2*div_10M[idiv-1])/np->clock_khz;
+ else
+ tp->period = (4*div_10M[idiv-1])/np->clock_khz;
+ }
+ else
+ tp->period = (((sxfer>>5)+4)*div_10M[idiv-1])/np->clock_khz;
+ }
+ else
+ tp->period = 0xffff;
+
+
+ /*
+ ** Stop there if sync parameters are unchanged
+ */
+ if (tp->sval == sxfer && tp->wval == scntl3 && tp->uval == scntl4) return;
+ tp->sval = sxfer;
+ tp->wval = scntl3;
+ tp->uval = scntl4;
+
+ /*
+ ** Bells and whistles ;-)
+ ** Donnot announce negotiations due to auto-sense,
+ ** unless user really want us to be verbose. :)
+ */
+ if ( bootverbose < 2 && (cp->host_flags & HF_AUTO_SENSE))
+ goto next;
+ PRINT_TARGET(np, target);
+ if (offset) {
+ unsigned f10 = 100000 << (tp->widedone ? tp->widedone -1 : 0);
+ unsigned mb10 = (f10 + tp->period/2) / tp->period;
+ char *scsi;
+
+ /*
+ ** Disable extended Sreq/Sack filtering
+ */
+ if ((tp->period <= 2000) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
+ OUTOFFB (nc_stest2, EXT);
+
+ /*
+ ** Bells and whistles ;-)
+ */
+ if (tp->period < 250) scsi = "FAST-80";
+ else if (tp->period < 500) scsi = "FAST-40";
+ else if (tp->period < 1000) scsi = "FAST-20";
+ else if (tp->period < 2000) scsi = "FAST-10";
+ else scsi = "FAST-5";
+
+ printk ("%s %sSCSI %d.%d MB/s (%d ns, offset %d)\n", scsi,
+ tp->widedone > 1 ? "WIDE " : "",
+ mb10 / 10, mb10 % 10, tp->period / 10, offset);
+ } else
+ printk ("%sasynchronous.\n", tp->widedone > 1 ? "wide " : "");
+next:
+ /*
+ ** set actual value and sync_status
+ ** patch ALL ccbs of this target.
+ */
+ ncr_set_sync_wide_status(np, target);
+}
+
+
+
+
/*==========================================================
**
** Switch tagged mode for a target.
@@ -8452,6 +9266,28 @@ void ncr_exception (ncb_p np)
ncr_log_hard_error(np, sist, dstat);
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+ u_char ctest4_o, ctest4_m;
+ u_char shadow;
+
+ /*
+ * Get shadow register data
+ * Write 1 to ctest4
+ */
+ ctest4_o = INB(nc_ctest4);
+
+ OUTB(nc_ctest4, ctest4_o | 0x10);
+
+ ctest4_m = INB(nc_ctest4);
+ shadow = INW_OFF(0x42);
+
+ OUTB(nc_ctest4, ctest4_o);
+
+ printk("%s: ctest4/sist original 0x%x/0x%X mod: 0x%X/0x%x\n",
+ ncr_name(np), ctest4_o, sist, ctest4_m, shadow);
+ }
+
if ((sist & (GEN|HTH|SGE)) ||
(dstat & (MDPE|BF|ABRT|IID))) {
ncr_start_reset(np);
@@ -8577,6 +9413,20 @@ void ncr_int_sto (ncb_p np)
*/
void ncr_int_udc (ncb_p np)
{
+ u_int32 dsa = INL (nc_dsa);
+ ccb_p cp = ncr_ccb_from_dsa(np, dsa);
+ tcb_p tp = &np->target[cp->target];
+
+ /*
+ * Fix Up. Some disks respond to a PPR negotation with
+ * a bus free instead of a message reject.
+ * Disable ppr negotiation if this is first time
+ * tried ppr negotiation.
+ */
+
+ if (tp->ppr_negotiation == 1)
+ tp->ppr_negotiation = 0;
+
printk ("%s: unexpected disconnect\n", ncr_name(np));
ncr_recover_scsi_int(np, HS_UNEXPECTED);
}
@@ -8688,6 +9538,7 @@ static void ncr_int_par (ncb_p np, u_short sist)
/*
** Keep track of the parity error.
*/
+ OUTONB (HF_PRT, HF_EXT_ERR);
cp->xerr_status |= XE_PARITY_ERR;
/*
@@ -8695,14 +9546,22 @@ static void ncr_int_par (ncb_p np, u_short sist)
*/
np->msgout[0] = (phase == 7) ? M_PARITY : M_ID_ERROR;
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
/*
- ** If the old phase was DATA IN phase, we have to deal with
- ** the 3 situations described above.
+ ** Save error message. For integrity check use only.
+ */
+ if (np->check_integrity)
+ np->check_integ_par = np->msgout[0];
+#endif
+
+ /*
+ ** If the old phase was DATA IN or DT DATA IN phase,
+ ** we have to deal with the 3 situations described above.
** For other input phases (MSG IN and STATUS), the device
** must resend the whole thing that failed parity checking
** or signal error. So, jumping to dispatcher should be OK.
*/
- if (phase == 1) {
+ if ((phase == 1) || (phase == 5)) {
/* Phase mismatch handled by SCRIPTS */
if (dsp == NCB_SCRIPTH_PHYS (np, pm_handle))
OUTL (nc_dsp, dsp);
@@ -8772,45 +9631,64 @@ static void ncr_int_ma (ncb_p np)
*/
cp = ncr_ccb_from_dsa(np, dsa);
+ if (DEBUG_FLAGS & DEBUG_PHASE)
+ printk("CCB = %2x %2x %2x %2x %2x %2x\n",
+ cp->cmd->cmnd[0], cp->cmd->cmnd[1], cp->cmd->cmnd[2],
+ cp->cmd->cmnd[3], cp->cmd->cmnd[4], cp->cmd->cmnd[5]);
+
/*
** Donnot take into account dma fifo and various buffers in
** INPUT phase since the chip flushes everything before
** raising the MA interrupt for interrupted INPUT phases.
** For DATA IN phase, we will check for the SWIDE later.
*/
- if ((cmd & 7) != 1) {
+ if ( !(((cmd & 7) == 1) || ((cmd & 7) == 5) ) ) {
u_int32 dfifo;
u_char ss0, ss2;
/*
- ** Read DFIFO, CTEST[4-6] using 1 PCI bus ownership.
+ ** If C1010, DFBC contains number of bytes in DMA fifo.
+ ** else read DFIFO, CTEST[4-6] using 1 PCI bus ownership.
*/
- dfifo = INL(nc_dfifo);
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
+ delta = INL(nc_dfbc) & 0xffff;
+ else {
+ dfifo = INL(nc_dfifo);
- /*
- ** Calculate remaining bytes in DMA fifo.
- ** (CTEST5 = dfifo >> 16)
- */
- if (dfifo & (DFS << 16))
- delta = ((((dfifo >> 8) & 0x300) |
- (dfifo & 0xff)) - rest) & 0x3ff;
- else
- delta = ((dfifo & 0xff) - rest) & 0x7f;
+ /*
+ ** Calculate remaining bytes in DMA fifo.
+ ** C1010 - always large fifo, value in dfbc
+ ** Otherwise, (CTEST5 = dfifo >> 16)
+ */
+ if (dfifo & (DFS << 16))
+ delta = ((((dfifo >> 8) & 0x300) |
+ (dfifo & 0xff)) - rest) & 0x3ff;
+ else
+ delta = ((dfifo & 0xff) - rest) & 0x7f;
- /*
- ** The data in the dma fifo has not been transfered to
- ** the target -> add the amount to the rest
- ** and clear the data.
- ** Check the sstat2 register in case of wide transfer.
- */
+ /*
+ ** The data in the dma fifo has not been
+ ** transferred to the target -> add the amount
+ ** to the rest and clear the data.
+ ** Check the sstat2 register in case of wide
+ ** transfer.
+ */
+
+ }
+
rest += delta;
ss0 = INB (nc_sstat0);
if (ss0 & OLF) rest++;
- if (ss0 & ORF) rest++;
+ if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) && (ss0 & ORF))
+ rest++;
if (cp && (cp->phys.select.sel_scntl3 & EWS)) {
ss2 = INB (nc_sstat2);
if (ss2 & OLF1) rest++;
- if (ss2 & ORF1) rest++;
+ if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) && (ss2 & ORF))
+ rest++;
};
/*
@@ -8902,9 +9780,10 @@ static void ncr_int_ma (ncb_p np)
/*
** if old phase not dataphase, leave here.
+ ** C/D line is low if data.
*/
- if (cmd & 0x06) {
+ if (cmd & 0x02) {
PRINT_ADDR(cp->cmd);
printk ("phase change %x-%x %d@%08x resid=%d.\n",
cmd&7, INB(nc_sbcl)&7, (unsigned)olen,
@@ -8962,45 +9841,42 @@ static void ncr_int_ma (ncb_p np)
** - move current data pointer context by one byte.
*/
nxtdsp = NCB_SCRIPT_PHYS (np, dispatch);
- if ((cmd & 7) == 1 && cp && (cp->phys.select.sel_scntl3 & EWS) &&
+ if ( ((cmd & 7) == 1 || (cmd & 7) == 5)
+ && cp && (cp->phys.select.sel_scntl3 & EWS) &&
(INB (nc_scntl2) & WSR)) {
+ u32 tmp;
+
+#ifdef SYM_DEBUG_PM_WITH_WSR
+ PRINT_ADDR(cp);
+ printf ("MA interrupt with WSR set - "
+ "pm->sg.addr=%x - pm->sg.size=%d\n",
+ pm->sg.addr, pm->sg.size);
+#endif
/*
- ** Hmmm... The device may want to also ignore
- ** this residue but it must send immediately the
- ** appropriate message. We snoop the SCSI BUS
- ** and will just throw away this message from
- ** SCRIPTS if the SWIDE is to be ignored.
- */
- if ((INB (nc_sbcl) & 7) == 7 &&
- INB (nc_sbdl) == M_IGN_RESIDUE) {
- nxtdsp = NCB_SCRIPT_PHYS (np, ign_i_w_r_msg);
- }
+ * Set up the table indirect for the MOVE
+ * of the residual byte and adjust the data
+ * pointer context.
+ */
+ tmp = scr_to_cpu(pm->sg.addr);
+ cp->phys.wresid.addr = cpu_to_scr(tmp);
+ pm->sg.addr = cpu_to_scr(tmp + 1);
+ tmp = scr_to_cpu(pm->sg.size);
+ cp->phys.wresid.size = cpu_to_scr((tmp&0xff000000) | 1);
+ pm->sg.size = cpu_to_scr(tmp - 1);
+
/*
- ** We must grab the SWIDE.
- ** We will use some complex SCRIPTS for that.
- */
- else {
- OUTL (nc_scratcha, pm->sg.addr);
- nxtdsp = NCB_SCRIPTH_PHYS (np, swide_ma_32);
- if (np->features & FE_64BIT) {
- OUTB (nc_sbr, (pm->sg.size >> 24));
- nxtdsp = NCB_SCRIPTH_PHYS (np, swide_ma_64);
- }
- /*
- ** Adjust our data pointer context.
- */
- ++pm->sg.addr;
- --pm->sg.size;
- /*
- ** Hmmm... Could it be possible that a SWIDE that
- ** is followed by a 1 byte CHMOV would lead to
- ** a CHMOV(0). Anyway, we handle it by just
- ** skipping context that would attempt a CHMOV(0).
- */
- if (!pm->sg.size)
- newcmd = pm->ret;
- }
- }
+ * If only the residual byte is to be moved,
+ * no PM context is needed.
+ */
+ if ((tmp&0xffffff) == 1)
+ newcmd = pm->ret;
+
+ /*
+ * Prepare the address of SCRIPTS that will
+ * move the residual byte to memory.
+ */
+ nxtdsp = NCB_SCRIPTH_PHYS (np, wsr_ma_helper);
+ }
if (DEBUG_FLAGS & DEBUG_PHASE) {
PRINT_ADDR(cp->cmd);
@@ -9076,7 +9952,8 @@ unexpected_phase:
nxtdsp = NCB_SCRIPTH_PHYS (np, ident_break);
}
else if (dsp == NCB_SCRIPTH_PHYS (np, send_wdtr) ||
- dsp == NCB_SCRIPTH_PHYS (np, send_sdtr)) {
+ dsp == NCB_SCRIPTH_PHYS (np, send_sdtr) ||
+ dsp == NCB_SCRIPTH_PHYS (np, send_ppr)) {
nxtdsp = NCB_SCRIPTH_PHYS (np, nego_bad_phase);
}
break;
@@ -9277,12 +10154,56 @@ next:
** to be stuck with WIDE and/or SYNC data transfer.
**
** cp->nego_status is filled by ncr_prepare_nego().
+ **
+ ** Do NOT negotiate if performing integrity check
+ ** or if integrity check has completed, all check
+ ** conditions will have been cleared.
+ */
+
+#ifdef SCSI_NCR_INTEGRITY_CHECKING
+ if (DEBUG_FLAGS & DEBUG_IC) {
+ printk("%s: ncr_sir_to_redo: ic_done %2X, in_progress %2X\n",
+ ncr_name(np), tp->ic_done, cp->cmd->ic_in_progress);
+ }
+
+ /*
+ ** If parity error during integrity check,
+ ** set the target width to narrow. Otherwise,
+ ** do not negotiate on a request sense.
*/
+ if ( np->check_integ_par && np->check_integrity
+ && cp->cmd->ic_in_progress ) {
+ cp->nego_status = 0;
+ msglen +=
+ ncr_ic_nego (np, cp, cmd ,&cp->scsi_smsg2[msglen]);
+ }
+
+ if (!np->check_integrity ||
+ (np->check_integrity &&
+ (!cp->cmd->ic_in_progress && !tp->ic_done)) ) {
+ ncr_negotiate(np, tp);
+ cp->nego_status = 0;
+ {
+ u_char sync_offset;
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
+ sync_offset = tp->sval & 0x3f;
+ else
+ sync_offset = tp->sval & 0x1f;
+
+ if ((tp->wval & EWS) || sync_offset)
+ msglen +=
+ ncr_prepare_nego (np, cp, &cp->scsi_smsg2[msglen]);
+ }
+
+ }
+#else
ncr_negotiate(np, tp);
cp->nego_status = 0;
if ((tp->wval & EWS) || (tp->sval & 0x1f))
msglen +=
ncr_prepare_nego (np, cp, &cp->scsi_smsg2[msglen]);
+#endif /* SCSI_NCR_INTEGRITY_CHECKING */
/*
** Message table indirect structure.
@@ -9489,6 +10410,7 @@ static void ncr_sir_task_recovery(ncb_p np, int num)
np->abrt_sel.sel_id = target;
np->abrt_sel.sel_scntl3 = tp->wval;
np->abrt_sel.sel_sxfer = tp->sval;
+ np->abrt_sel.sel_scntl4 = tp->uval;
OUTL(nc_dsa, np->p_ncb);
OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, sel_for_abort));
return;
@@ -9696,6 +10618,7 @@ static void ncr_sir_task_recovery(ncb_p np, int num)
if (np->abrt_msg[0] == M_RESET) {
tp->sval = 0;
tp->wval = np->rv_scntl3;
+ tp->uval = np->rv_scntl4;
ncr_set_sync_wide_status(np, target);
ncr_negotiate(np, tp);
}
@@ -10014,11 +10937,30 @@ out_reject:
static int ncr_compute_residual(ncb_p np, ccb_p cp)
{
- int dp_sg, dp_sgmin, resid, tmp;
+ int dp_sg, dp_sgmin, tmp;
+ int resid=0;
int dp_ofs = 0;
/*
- ** Should have been checked by the caller.
+ * Check for some data lost or just thrown away.
+ * We are not required to be quite accurate in this
+ * situation. Btw, if we are odd for output and the
+ * device claims some more data, it may well happen
+ * than our residual be zero. :-)
+ */
+ if (cp->xerr_status & (XE_EXTRA_DATA|XE_SODL_UNRUN|XE_SWIDE_OVRUN)) {
+ if (cp->xerr_status & XE_EXTRA_DATA)
+ resid -= scr_to_cpu(cp->phys.extra_bytes);
+ if (cp->xerr_status & XE_SODL_UNRUN)
+ ++resid;
+ if (cp->xerr_status & XE_SWIDE_OVRUN)
+ --resid;
+ }
+
+
+ /*
+ ** If all data has been transferred,
+ ** there is no residual.
*/
if (cp->phys.header.lastp == cp->phys.header.goalp)
return 0;
@@ -10159,7 +11101,7 @@ static void ncr_print_msg (ccb_p cp, char *label, u_char *msg)
*/
static void ncr_sync_nego(ncb_p np, tcb_p tp, ccb_p cp)
{
- u_char scntl3;
+ u_char scntl3, scntl4;
u_char chg, ofs, per, fak;
/*
@@ -10203,6 +11145,7 @@ static void ncr_sync_nego(ncb_p np, tcb_p tp, ccb_p cp)
*/
fak = 7;
scntl3 = 0;
+ scntl4 = 0;
if (ofs != 0) {
ncr_getsync(np, per, &fak, &scntl3);
if (fak > 7) {
@@ -10214,13 +11157,14 @@ static void ncr_sync_nego(ncb_p np, tcb_p tp, ccb_p cp)
fak = 7;
per = 0;
scntl3 = 0;
+ scntl4 = 0;
tp->minsync = 0;
}
if (DEBUG_FLAGS & DEBUG_NEGO) {
PRINT_ADDR(cp->cmd);
- printk ("sync: per=%d scntl3=0x%x ofs=%d fak=%d chg=%d.\n",
- per, scntl3, ofs, fak, chg);
+ printk ("sync: per=%d scntl3=0x%x scntl4=0x%x ofs=%d fak=%d chg=%d.\n",
+ per, scntl3, scntl4, ofs, fak, chg);
}
if (INB (HS_PRT) == HS_NEGOTIATE) {
@@ -10234,13 +11178,18 @@ static void ncr_sync_nego(ncb_p np, tcb_p tp, ccb_p cp)
/*
** Answer wasn't acceptable.
*/
- ncr_setsync (np, cp, 0, 0xe0);
+ ncr_setsync (np, cp, 0, 0xe0, 0);
OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_bad));
} else {
/*
** Answer is ok.
*/
- ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
+ if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
+ ncr_setsync (np, cp, scntl3, (fak<<5)|ofs,0);
+ else
+ ncr_setsync (np, cp, scntl3, ofs, scntl4);
+
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
};
return;
@@ -10256,7 +11205,11 @@ static void ncr_sync_nego(ncb_p np, tcb_p tp, ccb_p cp)
** prepare an answer message
*/
- ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
+ if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
+ ncr_setsync (np, cp, scntl3, (fak<<5)|ofs,0);
+ else
+ ncr_setsync (np, cp, scntl3, ofs, scntl4);
np->msgout[0] = M_EXTENDED;
np->msgout[1] = 3;
@@ -10350,7 +11303,7 @@ static void ncr_wide_nego(ncb_p np, tcb_p tp, ccb_p cp)
return;
case NS_SYNC:
- ncr_setsync (np, cp, 0, 0xe0);
+ ncr_setsync (np, cp, 0, 0xe0, 0);
break;
};
};
@@ -10377,6 +11330,205 @@ static void ncr_wide_nego(ncb_p np, tcb_p tp, ccb_p cp)
OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, wdtr_resp));
}
+/*==========================================================
+**
+** ncr chip handler for PARALLEL PROTOCOL REQUEST
+** (PPR) message.
+**
+**==========================================================
+**
+** Read comments above.
+**
+**----------------------------------------------------------
+*/
+static void ncr_ppr_nego(ncb_p np, tcb_p tp, ccb_p cp)
+{
+ u_char scntl3, scntl4;
+ u_char chg, ofs, per, fak, wth, dt;
+
+ /*
+ ** PPR message received.
+ */
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ ncr_print_msg(cp, "ppr msg in", np->msgin);
+ };
+
+ /*
+ ** get requested values.
+ */
+
+ chg = 0;
+ per = np->msgin[3];
+ ofs = np->msgin[5];
+ wth = np->msgin[6];
+ dt = np->msgin[7];
+ if (ofs==0) per=255;
+
+ /*
+ ** if target sends sync (wide),
+ ** it CAN transfer synch (wide).
+ */
+
+ if (ofs)
+ tp->inq_byte7 |= INQ7_SYNC;
+
+ if (wth)
+ tp->inq_byte7 |= INQ7_WIDE16;
+
+ /*
+ ** check values against driver limits.
+ */
+
+ if (wth > tp->usrwide)
+ {chg = 1; wth = tp->usrwide;}
+ if (per < np->minsync)
+ {chg = 1; per = np->minsync;}
+ if (per < tp->minsync)
+ {chg = 1; per = tp->minsync;}
+ if (ofs > tp->maxoffs)
+ {chg = 1; ofs = tp->maxoffs;}
+
+ /*
+ ** Check against controller limits.
+ */
+ fak = 7;
+ scntl3 = 0;
+ scntl4 = 0;
+ if (ofs != 0) {
+ scntl4 = dt ? 0x80 : 0;
+ ncr_getsync(np, per, &fak, &scntl3);
+ if (fak > 7) {
+ chg = 1;
+ ofs = 0;
+ }
+ }
+ if (ofs == 0) {
+ fak = 7;
+ per = 0;
+ scntl3 = 0;
+ scntl4 = 0;
+ tp->minsync = 0;
+ }
+
+ /*
+ ** If target responds with Ultra 3 speed
+ ** but narrow or not DT, reject.
+ ** If target responds with DT request
+ ** but not Ultra3 speeds, reject message,
+ ** reset min sync for target to 0x0A and
+ ** set flags to re-negotiate.
+ */
+
+ if ((per == 0x09) && ofs && (!wth || !dt))
+ chg = 1;
+ else if (( (per > 0x09) && dt) )
+ chg = 2;
+
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ PRINT_ADDR(cp->cmd);
+ printk ("ppr: wth=%d per=%d scntl3=0x%x scntl4=0x%x ofs=%d fak=%d chg=%d.\n",
+ wth, per, scntl3, scntl4, ofs, fak, chg);
+ }
+
+ if (INB (HS_PRT) == HS_NEGOTIATE) {
+ OUTB (HS_PRT, HS_BUSY);
+ switch (cp->nego_status) {
+ case NS_PPR:
+ /*
+ ** This was an answer message
+ */
+ if (chg) {
+ /*
+ ** Answer wasn't acceptable.
+ */
+ if (chg == 2) {
+ /* Send message reject and reset flags for
+ ** host to re-negotiate with min period 0x0A.
+ */
+ tp->minsync = 0x0A;
+ tp->period = 0;
+ tp->widedone = 0;
+ }
+ ncr_setsyncwide (np, cp, 0, 0xe0, 0, 0);
+ OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_bad));
+ } else {
+ /*
+ ** Answer is ok.
+ */
+
+ if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
+ ncr_setsyncwide (np, cp, scntl3, (fak<<5)|ofs,0, wth);
+ else
+ ncr_setsyncwide (np, cp, scntl3, ofs, scntl4, wth);
+
+ OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
+
+ };
+ return;
+
+ case NS_SYNC:
+ ncr_setsync (np, cp, 0, 0xe0, 0);
+ break;
+
+ case NS_WIDE:
+ ncr_setwide (np, cp, 0, 0);
+ break;
+ };
+ };
+
+ /*
+ ** It was a request. Set value and
+ ** prepare an answer message
+ **
+ ** If narrow or not DT and requesting Ultra3
+ ** slow the bus down and force ST. If not
+ ** requesting Ultra3, force ST.
+ ** Max offset is 31=0x1f if ST mode.
+ */
+
+ if ((per == 0x09) && ofs && (!wth || !dt)) {
+ per = 0x0A;
+ dt = 0;
+ ofs &= 0x1f;
+ }
+ else if ( (per > 0x09) && dt) {
+ dt = 0;
+ ofs &= 0x1f;
+ }
+
+ if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
+ ncr_setsyncwide (np, cp, scntl3, (fak<<5)|ofs,0, wth);
+ else
+ ncr_setsyncwide (np, cp, scntl3, ofs, scntl4, wth);
+
+ np->msgout[0] = M_EXTENDED;
+ np->msgout[1] = 6;
+ np->msgout[2] = M_X_PPR_REQ;
+ np->msgout[3] = per;
+ np->msgout[4] = 0;
+ np->msgout[5] = ofs;
+ np->msgout[6] = wth;
+ np->msgout[7] = dt;
+
+ cp->nego_status = NS_PPR;
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ ncr_print_msg(cp, "ppr msgout", np->msgout);
+ }
+
+ np->msgin [0] = M_NOOP;
+
+ if (!ofs)
+ OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_bad));
+ else
+ OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, ppr_resp));
+}
+
+
/*
** Reset SYNC or WIDE to default settings.
@@ -10392,13 +11544,45 @@ static void ncr_nego_default(ncb_p np, tcb_p tp, ccb_p cp)
switch (cp->nego_status) {
case NS_SYNC:
- ncr_setsync (np, cp, 0, 0xe0);
+ ncr_setsync (np, cp, 0, 0xe0, 0);
break;
case NS_WIDE:
ncr_setwide (np, cp, 0, 0);
break;
+ case NS_PPR:
+ /*
+ * ppr_negotiation is set to 1 on the first ppr nego command.
+ * If ppr is successful, it is reset to 2.
+ * If unsuccessful it is reset to 0.
+ */
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ tcb_p tp=&np->target[cp->target];
+ u_char factor, offset, width;
+
+ ncr_get_xfer_info ( np, tp, &factor, &offset, &width);
+
+ printk("Current factor %d offset %d width %d\n",
+ factor, offset, width);
+ }
+ if (tp->ppr_negotiation == 2)
+ ncr_setsyncwide (np, cp, 0, 0xe0, 0, 0);
+ else if (tp->ppr_negotiation == 1) {
+
+ /* First ppr command has received a M REJECT.
+ * Do not change the existing wide/sync parameter
+ * values (asyn/narrow if this as the first nego;
+ * may be different if target initiates nego.).
+ */
+ tp->ppr_negotiation = 0;
+ }
+ else
+ {
+ tp->ppr_negotiation = 0;
+ ncr_setwide (np, cp, 0, 0);
+ }
+ break;
};
np->msgin [0] = M_NOOP;
np->msgout[0] = M_NOOP;
@@ -10410,6 +11594,9 @@ static void ncr_nego_default(ncb_p np, tcb_p tp, ccb_p cp)
** ncr chip handler for MESSAGE REJECT received for
** a WIDE or SYNCHRONOUS negotiation.
**
+** clear the PPR negotiation flag, all future nego.
+** will be SDTR and WDTR
+**
**==========================================================
**
** Read comments above.
@@ -10451,6 +11638,7 @@ void ncr_int_sir (ncb_p np)
case SIR_DUMMY_INTERRUPT:
goto out;
#endif
+
/*
** The C code is currently trying to recover from something.
** Typically, user want to abort some command.
@@ -10529,8 +11717,11 @@ void ncr_int_sir (ncb_p np)
np->msgout[0] = M_NOOP;
/* Should we really care of that */
if (np->lastmsg == M_PARITY || np->lastmsg == M_ID_ERROR) {
- if (cp)
+ if (cp) {
cp->xerr_status &= ~XE_PARITY_ERR;
+ if (!cp->xerr_status)
+ OUTOFFB (HF_PRT, HF_EXT_ERR);
+ }
}
goto out;
/*
@@ -10558,8 +11749,10 @@ void ncr_int_sir (ncb_p np)
** It is a data overrun condition.
*/
case SIR_SWIDE_OVERRUN:
- if (cp)
- cp->xerr_status |= XE_EXTRA_DATA;
+ if (cp) {
+ OUTONB (HF_PRT, HF_EXT_ERR);
+ cp->xerr_status |= XE_SWIDE_OVRUN;
+ }
goto out;
/*
** We have been ODD at the end of a DATA OUT
@@ -10567,8 +11760,10 @@ void ncr_int_sir (ncb_p np)
** It is a data underrun condition.
*/
case SIR_SODL_UNDERRUN:
- if (cp)
- cp->xerr_status |= XE_EXTRA_DATA;
+ if (cp) {
+ OUTONB (HF_PRT, HF_EXT_ERR);
+ cp->xerr_status |= XE_SODL_UNRUN;
+ }
goto out;
/*
** We received a message.
@@ -10597,6 +11792,9 @@ void ncr_int_sir (ncb_p np)
case M_X_WIDE_REQ:
ncr_wide_nego(np, tp, cp);
return;
+ case M_X_PPR_REQ:
+ ncr_ppr_nego(np, tp, cp);
+ return;
default:
goto out_reject;
}
@@ -10910,6 +12108,11 @@ static void ncr_init_tcb (ncb_p np, u_char tn)
offsetof(struct tcb , sval )) &3) == 0);
assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
offsetof(struct tcb , wval )) &3) == 0);
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)){
+ assert (( (offsetof(struct ncr_reg, nc_scntl4) ^
+ offsetof(struct tcb , uval )) &3) == 0);
+ }
}
/*------------------------------------------------------------------------
@@ -11446,7 +12649,8 @@ static void ncb_profile (ncb_p np, ccb_p cp)
** do not have a clock doubler and so are provided with a
** 80 MHz clock. All other fast20 boards incorporate a doubler
** and so should be delivered with a 40 MHz clock.
-** The recent fast40 chips (895/896/895A) use a 40 Mhz base clock
+** The recent fast40 chips (895/896/895A) and the
+** fast80 chip (C1010) use a 40 Mhz base clock
** and provide a clock quadrupler (160 Mhz). The code below
** tries to deal as cleverly as possible with all this stuff.
**
@@ -11467,14 +12671,20 @@ static void ncr_selectclock(ncb_p np, u_char scntl3)
printk ("%s: enabling clock multiplier\n", ncr_name(np));
OUTB(nc_stest1, DBLEN); /* Enable clock multiplier */
- if (np->multiplier > 2) { /* Poll bit 5 of stest4 for quadrupler */
- int i = 20;
+
+ if ( (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
+ (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) &&
+ (np->multiplier > 2)) {
+ int i = 20; /* Poll bit 5 of stest4 for quadrupler */
while (!(INB(nc_stest4) & LCKFRQ) && --i > 0)
UDELAY (20);
if (!i)
- printk("%s: the chip cannot lock the frequency\n", ncr_name(np));
- } else /* Wait 20 micro-seconds for doubler */
- UDELAY (20);
+ printk("%s: the chip cannot lock the frequency\n",
+ ncr_name(np));
+
+ } else /* Wait 120 micro-seconds for multiplier*/
+ UDELAY (120);
+
OUTB(nc_stest3, HSC); /* Halt the scsi clock */
OUTB(nc_scntl3, scntl3);
OUTB(nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */
@@ -11489,6 +12699,7 @@ static unsigned __init ncrgetfreq (ncb_p np, int gen)
{
unsigned int ms = 0;
unsigned int f;
+ int count;
/*
* Measure GEN timer delay in order
@@ -11505,15 +12716,21 @@ static unsigned __init ncrgetfreq (ncb_p np, int gen)
* performed trust the higher delay
* (lower frequency returned).
*/
- OUTW (nc_sien , 0); /* mask all scsi interrupts */
+ OUTW (nc_sien , 0x0);/* mask all scsi interrupts */
+ /* enable general purpose timer */
(void) INW (nc_sist); /* clear pending scsi interrupt */
OUTB (nc_dien , 0); /* mask all dma interrupts */
(void) INW (nc_sist); /* another one, just to be sure :) */
OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */
OUTB (nc_stime1, 0); /* disable general purpose timer */
OUTB (nc_stime1, gen); /* set to nominal delay of 1<<gen * 125us */
- while (!(INW(nc_sist) & GEN) && ms++ < 100000)
- UDELAY (1000); /* count ms */
+ /* Temporary fix for udelay issue with Alpha
+ platform */
+ while (!(INW(nc_sist) & GEN) && ms++ < 100000) {
+ /* count 1ms */
+ for (count = 0; count < 10; count++)
+ UDELAY (100);
+ }
OUTB (nc_stime1, 0); /* disable general purpose timer */
/*
* set prescaler to divide by whatever 0 means
@@ -11524,7 +12741,14 @@ static unsigned __init ncrgetfreq (ncb_p np, int gen)
/*
* adjust for prescaler, and convert into KHz
+ * scale values derived empirically. C1010 uses
+ * different dividers
*/
+#if 0
+ if (np->device_id == PCI_DEVICE_ID_LSI_53C1010)
+ f = ms ? ((1 << gen) * 2866 ) / ms : 0;
+ else
+#endif
f = ms ? ((1 << gen) * 4340) / ms : 0;
if (bootverbose >= 2)
@@ -11568,11 +12792,19 @@ static void __init ncr_getclock (ncb_p np, int mult)
}
/*
+ ** If multiplier not found but a C1010, assume a mult of 4.
** If multiplier not found or scntl3 not 7,5,3,
** reset chip and get frequency from general purpose timer.
** Otherwise trust scntl3 BIOS setting.
*/
- if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
+ if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
+ f1=40000;
+ np->multiplier = mult;
+ if (bootverbose >= 2)
+ printk ("%s: clock multiplier assumed\n", ncr_name(np));
+ }
+ else if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
OUTB (nc_stest1, 0); /* make sure doubler is OFF */
f1 = ncr_getfreq (np);
@@ -11587,8 +12819,14 @@ static void __init ncr_getclock (ncb_p np, int mult)
** to make sure our frequency calculation algorithm
** is not too biased.
*/
- np->pciclock_min = (33000*55+80-1)/80;
- np->pciclock_max = (33000*55)/40;
+ if (np->features & FE_66MHZ) {
+ np->pciclock_min = (66000*55+80-1)/80;
+ np->pciclock_max = (66000*55)/40;
+ }
+ else {
+ np->pciclock_min = (33000*55+80-1)/80;
+ np->pciclock_max = (33000*55)/40;
+ }
if (f1 == 40000 && mult > 1) {
if (bootverbose >= 2)
@@ -11728,7 +12966,8 @@ int __init sym53c8xx_setup(char *str)
#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
char *cur = str;
char *pc, *pv;
- int i, val, c;
+ unsigned long val;
+ int i, c;
int xi = 0;
while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
@@ -12165,7 +13404,7 @@ next:
static int __init
sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device)
{
- u_short vendor_id, device_id, command;
+ u_short vendor_id, device_id, command, status_reg;
u_char cache_line_size, latency_timer;
u_char suggested_cache_line_size = 0;
u_char pci_fix_up = driver_setup.pci_fix_up;
@@ -12205,6 +13444,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device)
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size);
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);
+ pci_read_config_word(pdev, PCI_STATUS, &status_reg);
#ifdef SCSI_NCR_PQS_PDS_SUPPORT
/*
@@ -12402,16 +13642,53 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device)
if (driver_setup.special_features & 4)
chip->features &= ~FE_NOPM;
}
+
+ /*
+ ** Work around for errant bit in 895A. The 66Mhz
+ ** capable bit is set erroneously. Clear this bit.
+ ** (Item 1 DEL 533)
+ **
+ ** Make sure Config space and Features agree.
+ **
+ ** Recall: writes are not normal to status register -
+ ** write a 1 to clear and a 0 to leave unchanged.
+ ** Can only reset bits.
+ */
+ if (chip->features & FE_66MHZ) {
+ if (!(status_reg & PCI_STATUS_66MHZ))
+ chip->features &= ~FE_66MHZ;
+ }
+ else {
+ if (status_reg & PCI_STATUS_66MHZ) {
+ status_reg = PCI_STATUS_66MHZ;
+ pci_write_config_word(pdev, PCI_STATUS, status_reg);
+ pci_read_config_word(pdev, PCI_STATUS, &status_reg);
+ }
+ }
+
+ if (driver_setup.ultra_scsi < 3 && (chip->features & FE_ULTRA3)) {
+ chip->features |= FE_ULTRA2;
+ chip->features &= ~FE_ULTRA3;
+ }
if (driver_setup.ultra_scsi < 2 && (chip->features & FE_ULTRA2)) {
chip->features |= FE_ULTRA;
chip->features &= ~FE_ULTRA2;
}
if (driver_setup.ultra_scsi < 1)
chip->features &= ~FE_ULTRA;
+
if (!driver_setup.max_wide)
chip->features &= ~FE_WIDE;
/*
+ * C1010 Ultra3 support requires 16 bit data transfers.
+ */
+ if (!driver_setup.max_wide && (chip->features & FE_ULTRA3)) {
+ chip->features |= FE_ULTRA2;
+ chip->features |= ~FE_ULTRA3;
+ }
+
+ /*
** Some features are required to be enabled in order to
** work around some chip problems. :) ;)
** (ITEM 12 of a DEL about the 896 I haven't yet).
diff --git a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h
index 2ffbd62711fadf..703b36c3193ac2 100644
--- a/drivers/scsi/sym53c8xx_comm.h
+++ b/drivers/scsi/sym53c8xx_comm.h
@@ -155,6 +155,7 @@
#define DEBUG_NEGO (0x0200)
#define DEBUG_TAGS (0x0400)
#define DEBUG_SCATTER (0x0800)
+#define DEBUG_IC (0x1000)
/*
** Enable/Disable debug messages.
@@ -2414,6 +2415,11 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device)
/*
** Check if the chip is supported
*/
+ if ((device_id == PCI_DEVICE_ID_LSI_53C1010) ||
+ (device_id == PCI_DEVICE_ID_LSI_53C1010_66)){
+ printk(NAME53C8XX ": not initializing, device not supported\n");
+ return -1;
+ }
chip = 0;
for (i = 0; i < sizeof(ncr_chip_table)/sizeof(ncr_chip_table[0]); i++) {
if (device_id != ncr_chip_table[i].device_id)
diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h
index 14ab35a192bf49..0ab0d274555856 100644
--- a/drivers/scsi/sym53c8xx_defs.h
+++ b/drivers/scsi/sym53c8xx_defs.h
@@ -102,6 +102,14 @@
# define SCSI_NCR_USER_INFO_SUPPORT
#endif
+/*
+** To disable integrity checking, do not define the
+** following option.
+*/
+#ifdef CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
+# define SCSI_NCR_ENABLE_INTEGRITY_CHECK
+#endif
+
/*==========================================================
**
** nvram settings - #define SCSI_NCR_NVRAM_SUPPORT to enable
@@ -121,10 +129,9 @@
*/
/*
- * For Ultra2 SCSI support option, use special features and allow 40Mhz
- * synchronous data transfers.
+ * For Ultra2 and Ultra3 SCSI support option, use special features.
*
- * Value 5 (default) means:
+ * Value (default) means:
* bit 0 : all features enabled, except:
* bit 1 : PCI Write And Invalidate.
* bit 2 : Data Phase Mismatch handling from SCRIPTS.
@@ -133,8 +140,20 @@
* enabled by the driver.
*/
#define SCSI_NCR_SETUP_SPECIAL_FEATURES (3)
-#define SCSI_NCR_SETUP_ULTRA_SCSI (2)
-#define SCSI_NCR_MAX_SYNC (40)
+
+/*
+ * For Ultra2 and Ultra3 SCSI support allow 80Mhz synchronous data transfers.
+ * Value means:
+ * 0 - Ultra speeds disabled
+ * 1 - Ultra enabled (Maximum 20Mtrans/sec)
+ * 2 - Ultra2 enabled (Maximum 40Mtrans/sec)
+ * 3 - Ultra3 enabled (Maximum 80Mtrans/sec)
+ *
+ * Use boot options sym53c8xx=ultra:3 to enable Ultra3 support.
+ */
+
+#define SCSI_NCR_SETUP_ULTRA_SCSI (3)
+#define SCSI_NCR_MAX_SYNC (80)
/*
* Allow tags from 2 to 256, default 8
@@ -190,7 +209,7 @@
/*
* Sync transfer frequency at startup.
- * Allow from 5Mhz to 40Mhz default 20 Mhz.
+ * Allow from 5Mhz to 80Mhz default 20 Mhz.
*/
#ifndef CONFIG_SCSI_NCR53C8XX_SYNC
#define CONFIG_SCSI_NCR53C8XX_SYNC (20)
@@ -207,8 +226,10 @@
#define SCSI_NCR_SETUP_DEFAULT_SYNC (250/(CONFIG_SCSI_NCR53C8XX_SYNC))
#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 33
#define SCSI_NCR_SETUP_DEFAULT_SYNC (11)
-#else
+#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 40
#define SCSI_NCR_SETUP_DEFAULT_SYNC (10)
+#else
+#define SCSI_NCR_SETUP_DEFAULT_SYNC (9)
#endif
/*
@@ -469,6 +490,15 @@
#define PCI_DEVICE_ID_NCR_53C1510D 0xa
#endif
+#ifndef PCI_DEVICE_ID_LSI_53C1010
+#define PCI_DEVICE_ID_LSI_53C1010 0x20
+#endif
+
+#ifndef PCI_DEVICE_ID_LSI_53C1010_66
+#define PCI_DEVICE_ID_LSI_53C1010_66 0x21
+#endif
+
+
/*
** NCR53C8XX devices features table.
*/
@@ -502,6 +532,8 @@ typedef struct {
#define FE_NOPM (1<<19) /* Scripts handles phase mismatch */
#define FE_LEDC (1<<20) /* Hardware control of LED */
#define FE_DIFF (1<<21) /* Support Differential SCSI */
+#define FE_ULTRA3 (1<<22) /* Ultra-3 80Mtrans/sec */
+#define FE_66MHZ (1<<23) /* 66MHz PCI Support */
#define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
#define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_ULTRA2|FE_DBLR|FE_QUAD|F_CLK80)
@@ -586,7 +618,15 @@ typedef struct {
, \
{PCI_DEVICE_ID_NCR_53C1510D, 0xff, "1510D", 7, 31, 7, \
FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \
- FE_RAM|FE_IO256}\
+ FE_RAM|FE_IO256} \
+ , \
+ {PCI_DEVICE_ID_LSI_53C1010, 0xff, "1010", 6, 62, 7, \
+ FE_WIDE|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \
+ FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC|FE_ULTRA3} \
+ , \
+ {PCI_DEVICE_ID_LSI_53C1010_66, 0xff, "1010_66", 6, 62, 7, \
+ FE_WIDE|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \
+ FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC|FE_ULTRA3|FE_66MHZ} \
}
/*
@@ -605,7 +645,9 @@ typedef struct {
PCI_DEVICE_ID_NCR_53C895, \
PCI_DEVICE_ID_NCR_53C896, \
PCI_DEVICE_ID_NCR_53C895A, \
- PCI_DEVICE_ID_NCR_53C1510D \
+ PCI_DEVICE_ID_NCR_53C1510D, \
+ PCI_DEVICE_ID_LSI_53C1010, \
+ PCI_DEVICE_ID_LSI_53C1010_66 \
}
/*
@@ -640,7 +682,7 @@ struct ncr_driver_setup {
u_char recovery;
u_char host_id;
u_short iarb;
- u_int excludes[SCSI_NCR_MAX_EXCLUDES];
+ u_long excludes[SCSI_NCR_MAX_EXCLUDES];
char tag_ctrl[100];
};
@@ -662,7 +704,7 @@ struct ncr_driver_setup {
1, \
SCSI_NCR_SETUP_DEFAULT_TAGS, \
SCSI_NCR_SETUP_DEFAULT_SYNC, \
- 0x00, \
+ 0x0200, \
7, \
SCSI_NCR_SETUP_LED_PIN, \
1, \
@@ -864,12 +906,14 @@ struct ncr_reg {
/*03*/ u_char nc_scntl3; /* cnf system clock dependent */
#define EWS 0x08 /* cmd: enable wide scsi [W]*/
#define ULTRA 0x80 /* cmd: ULTRA enable */
+ /* bits 0-2, 7 rsvd for C1010 */
/*04*/ u_char nc_scid; /* cnf host adapter scsi address */
#define RRE 0x40 /* r/w:e enable response to resel. */
#define SRE 0x20 /* r/w:e enable response to select */
/*05*/ u_char nc_sxfer; /* ### Sync speed and count */
+ /* bits 6-7 rsvd for C1010 */
/*06*/ u_char nc_sdid; /* ### Destination-ID */
@@ -944,12 +988,14 @@ struct ncr_reg {
/*1a*/ u_char nc_ctest2;
#define CSIGP 0x40
+ /* bits 0-2,7 rsvd for C1010 */
/*1b*/ u_char nc_ctest3;
#define FLF 0x08 /* cmd: flush dma fifo */
#define CLF 0x04 /* cmd: clear dma fifo */
#define FM 0x02 /* mod: fetch pin mode */
#define WRIE 0x01 /* mod: write and invalidate enable */
+ /* bits 4-7 rsvd for C1010 */
/*1c*/ u_int32 nc_temp; /* ### Temporary stack */
@@ -960,6 +1006,7 @@ struct ncr_reg {
/*22*/ u_char nc_ctest5;
#define DFS 0x20 /* mod: dma fifo size */
+ /* bits 0-1, 3-7 rsvd for C1010 */
/*23*/ u_char nc_ctest6;
/*24*/ u_int32 nc_dbc; /* ### Byte count and command */
@@ -991,6 +1038,7 @@ struct ncr_reg {
#define STD 0x04 /* cmd: start dma mode */
#define IRQD 0x02 /* mod: irq disable */
#define NOCOM 0x01 /* cmd: protect sfbr while reselect */
+ /* bits 0-1 rsvd for C1010 */
/*3c*/ u_int32 nc_adder;
@@ -1041,6 +1089,7 @@ struct ncr_reg {
#define SMODE_SE 0x80 /* Single Ended */
#define SMODE_LVD 0xc0 /* Low Voltage Differential */
#define LCKFRQ 0x20 /* Frequency Lock (895/6 only) */
+ /* bits 0-5 rsvd for C1010 */
/*53*/ u_char nc_53_;
/*54*/ u_short nc_sodl; /* Lowlevel: data out to scsi data */
@@ -1054,6 +1103,7 @@ struct ncr_reg {
/*57*/ u_char nc_ccntl1; /* Chip Control 1 (896) */
#define ZMOD 0x80 /* High Impedance Mode */
+ #define DIC 0x10 /* Disable Internal Cycles */
#define DDAC 0x08 /* Disable Dual Address Cycle */
#define XTIMOD 0x04 /* 64-bit Table Ind. Indexing Mode */
#define EXTIBMV 0x02 /* Enable 64-bit Table Ind. BMOV */
@@ -1075,7 +1125,16 @@ struct ncr_reg {
/*b0*/ u_int32 nc_sbms; /* Static Block Move Selector */
/*b4*/ u_int32 nc_dbms; /* Dynamic Block Move Selector */
/*b8*/ u_int32 nc_dnad64; /* DMA Next Address 64 */
-/*bc*/ u_int32 nc_bc_;
+/*bc*/ u_short nc_scntl4; /* C1010 only */
+ #define U3EN 0x80 /* Enable Ultra 3 */
+ #define AIPEN 0x40 /* Allow check upper byte lanes */
+ #define XCLKH_DT 0x08 /* Extra clock of data hold on DT
+ transfer edge */
+ #define XCLKH_ST 0x04 /* Extra clock of data hold on ST
+ transfer edge */
+
+/*be*/ u_char nc_aipcntl0; /* Epat Control 1 C1010 only */
+/*bf*/ u_char nc_aipcntl1; /* AIP Control C1010_66 Only */
/*c0*/ u_int32 nc_pmjad1; /* Phase Mismatch Jump Address 1 */
/*c4*/ u_int32 nc_pmjad2; /* Phase Mismatch Jump Address 2 */
@@ -1095,6 +1154,17 @@ struct ncr_reg {
/*d7*/ u_char nc_ia3;
/*d8*/ u_int32 nc_sbc; /* SCSI Byte Count (3 bytes only) */
/*dc*/ u_int32 nc_csbc; /* Cumulative SCSI Byte Count */
+
+ /* Following for C1010 only */
+/*e0*/ u_short nc_crcpad; /* CRC Value */
+/*e2*/ u_char nc_crccntl0; /* CRC control register */
+ #define SNDCRC 0x10 /* Send CRC Request */
+/*e3*/ u_char nc_crccntl1; /* CRC control register */
+/*e4*/ u_int32 nc_crcdata; /* CRC data register */
+/*e8*/ u_int32 nc_e8_; /* rsvd */
+/*ec*/ u_int32 nc_ec_; /* rsvd */
+/*f0*/ u_short nc_dfbc; /* DMA FIFO byte count */
+
};
/*-----------------------------------------------------------
@@ -1113,6 +1183,8 @@ typedef u_int32 ncrcmd;
**
** SCSI phases
**
+** DT phases illegal for ncr driver.
+**
**-----------------------------------------------------------
*/
@@ -1120,11 +1192,14 @@ typedef u_int32 ncrcmd;
#define SCR_DATA_IN 0x01000000
#define SCR_COMMAND 0x02000000
#define SCR_STATUS 0x03000000
-#define SCR_ILG_OUT 0x04000000
-#define SCR_ILG_IN 0x05000000
+#define SCR_DT_DATA_OUT 0x04000000
+#define SCR_DT_DATA_IN 0x05000000
#define SCR_MSG_OUT 0x06000000
#define SCR_MSG_IN 0x07000000
+#define SCR_ILG_OUT 0x04000000
+#define SCR_ILG_IN 0x05000000
+
/*-----------------------------------------------------------
**
** Data transfer via SCSI.
@@ -1179,7 +1254,7 @@ struct scr_tblmove {
#define SCR_SEL_TBL_ATN 0x43000000
struct scr_tblsel {
- u_char sel_0;
+ u_char sel_scntl4;
u_char sel_sxfer;
u_char sel_id;
u_char sel_scntl3;
@@ -1463,6 +1538,7 @@ struct scr_tblsel {
#define M_X_MODIFY_DP (0x00)
#define M_X_SYNC_REQ (0x01)
#define M_X_WIDE_REQ (0x03)
+#define M_X_PPR_REQ (0x04)
/*
** Status
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index ef4af4dfefda4b..ade9091a54059f 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -406,7 +406,7 @@ beyond_if:
regs->gp = ex.a_gpvalue;
#endif
start_thread(regs, ex.a_entry, current->mm->start_stack);
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
send_sig(SIGTRAP, current, 0);
return 0;
}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 39279c752d0735..9f005062541b3f 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -747,7 +747,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
#endif
start_thread(regs, elf_entry, bprm->p);
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
send_sig(SIGTRAP, current, 0);
retval = 0;
out:
diff --git a/fs/exec.c b/fs/exec.c
index 6811398438e1b7..a1401b4cc24641 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -528,7 +528,7 @@ flush_failed:
*/
static inline int must_not_trace_exec(struct task_struct * p)
{
- return (p->flags & PF_PTRACED) && !cap_raised(p->p_pptr->cap_effective, CAP_SYS_PTRACE);
+ return (p->ptrace & PT_PTRACED) && !cap_raised(p->p_pptr->cap_effective, CAP_SYS_PTRACE);
}
/*
diff --git a/fs/proc/base.c b/fs/proc/base.c
index d513987d828b3e..ecb8a29919d545 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -285,7 +285,7 @@ static struct file_operations proc_info_file_operations = {
};
#define MAY_PTRACE(p) \
-(p==current||(p->p_pptr==current&&(p->flags&PF_PTRACED)&&p->state==TASK_STOPPED))
+(p==current||(p->p_pptr==current&&(p->ptrace & PT_PTRACED)&&p->state==TASK_STOPPED))
static ssize_t mem_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
diff --git a/include/asm-alpha/console.h b/include/asm-alpha/console.h
index 89f39911f33726..8a7d1d1fc96436 100644
--- a/include/asm-alpha/console.h
+++ b/include/asm-alpha/console.h
@@ -22,6 +22,9 @@
#define CCB_GET_ENV 0x22
#define CCB_SAVE_ENV 0x23
+#define CCB_PSWITCH 0x30
+#define CCB_BIOS_EMUL 0x32
+
/*
* Environment variable numbers
*/
@@ -36,20 +39,30 @@
#define ENV_BOOT_RESET 0x09
#define ENV_DUMP_DEV 0x0A
#define ENV_ENABLE_AUDIT 0x0B
-#define ENV_LICENCE 0x0C
+#define ENV_LICENSE 0x0C
#define ENV_CHAR_SET 0x0D
#define ENV_LANGUAGE 0x0E
#define ENV_TTY_DEV 0x0F
#ifdef __KERNEL__
-extern long srm_dispatch(long code, ...);
-extern void srm_puts(const char *);
+#ifndef __ASSEMBLY__
+extern long callback_puts(long unit, const char *s, long length);
+extern long callback_open(const char *device, long length);
+extern long callback_close(long unit);
+extern long callback_read(long channel, long count, const char *buf, long lbn);
+extern long callback_getenv(long id, const char *buf, unsigned long buf_size);
+
+extern int srm_fixup(unsigned long new_callback_addr,
+ unsigned long new_hwrpb_addr);
+extern long srm_puts(const char *, long);
extern long srm_printk(const char *, ...)
__attribute__ ((format (printf, 1, 2)));
struct crb_struct;
struct hwrpb_struct;
-extern long srm_fixup(struct crb_struct *, struct hwrpb_struct *);
+extern int callback_init_done;
+extern void * callback_init(void *);
+#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* __AXP_CONSOLE_H */
diff --git a/include/asm-alpha/core_titan.h b/include/asm-alpha/core_titan.h
new file mode 100644
index 00000000000000..04338b46d73e82
--- /dev/null
+++ b/include/asm-alpha/core_titan.h
@@ -0,0 +1,525 @@
+#ifndef __ALPHA_TITAN__H__
+#define __ALPHA_TITAN__H__
+
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+/*
+ * TITAN is the internal names for a core logic chipset which provides
+ * memory controller and PCI/AGP access for 21264 based systems.
+ *
+ * This file is based on:
+ *
+ * Titan Chipset Engineering Specification
+ * Revision 0.12
+ * 13 July 1999
+ *
+ */
+
+/* XXX: Do we need to conditionalize on this? */
+#ifdef USE_48_BIT_KSEG
+#define TI_BIAS 0x80000000000UL
+#else
+#define TI_BIAS 0x10000000000UL
+#endif
+
+/*
+ * CChip, DChip, and PChip registers
+ */
+
+typedef struct {
+ volatile unsigned long csr __attribute__((aligned(64)));
+} titan_64;
+
+typedef struct {
+ titan_64 csc;
+ titan_64 mtr;
+ titan_64 misc;
+ titan_64 mpd;
+ titan_64 aar0;
+ titan_64 aar1;
+ titan_64 aar2;
+ titan_64 aar3;
+ titan_64 dim0;
+ titan_64 dim1;
+ titan_64 dir0;
+ titan_64 dir1;
+ titan_64 drir;
+ titan_64 prben;
+ titan_64 iic0;
+ titan_64 iic1;
+ titan_64 mpr0;
+ titan_64 mpr1;
+ titan_64 mpr2;
+ titan_64 mpr3;
+ titan_64 rsvd[2];
+ titan_64 ttr;
+ titan_64 tdr;
+ titan_64 dim2;
+ titan_64 dim3;
+ titan_64 dir2;
+ titan_64 dir3;
+ titan_64 iic2;
+ titan_64 iic3;
+ titan_64 pwr;
+ titan_64 reserved[17];
+ titan_64 cmonctla;
+ titan_64 cmonctlb;
+ titan_64 cmoncnt01;
+ titan_64 cmoncnt23;
+ titan_64 cpen;
+} titan_cchip;
+
+typedef struct {
+ titan_64 dsc;
+ titan_64 str;
+ titan_64 drev;
+ titan_64 dsc2;
+} titan_dchip;
+
+typedef struct {
+ titan_64 wsba[4];
+ titan_64 wsm[4];
+ titan_64 tba[4];
+ titan_64 pctl;
+ titan_64 plat;
+ titan_64 reserved0[2];
+ union {
+ struct {
+ titan_64 serror;
+ titan_64 serren;
+ titan_64 serrset;
+ titan_64 reserved0;
+ titan_64 gperror;
+ titan_64 gperren;
+ titan_64 gperrset;
+ titan_64 reserved1;
+ titan_64 gtlbiv;
+ titan_64 gtlbia;
+ titan_64 reserved2[2];
+ titan_64 sctl;
+ titan_64 reserved3[3];
+ } g;
+ struct {
+ titan_64 agperror;
+ titan_64 agperren;
+ titan_64 agperrset;
+ titan_64 agplastwr;
+ titan_64 aperror;
+ titan_64 aperren;
+ titan_64 aperrset;
+ titan_64 reserved0;
+ titan_64 atlbiv;
+ titan_64 atlbia;
+ titan_64 reserved1[6];
+ } a;
+ } port_specific;
+ titan_64 sprst;
+ titan_64 reserved1[31];
+} titan_pachip_port;
+
+typedef struct {
+ titan_pachip_port g_port;
+ titan_pachip_port a_port;
+} titan_pachip;
+
+#define TITAN_cchip ((titan_cchip *)(IDENT_ADDR+TI_BIAS+0x1A0000000UL))
+#define TITAN_dchip ((titan_dchip *)(IDENT_ADDR+TI_BIAS+0x1B0000800UL))
+#define TITAN_pachip0 ((titan_pachip *)(IDENT_ADDR+TI_BIAS+0x180000000UL))
+#define TITAN_pachip1 ((titan_pachip *)(IDENT_ADDR+TI_BIAS+0x380000000UL))
+extern unsigned TITAN_agp;
+extern int TITAN_bootcpu;
+
+/*
+ * TITAN PA-chip Window Space Base Address register.
+ * (WSBA[0-2])
+ */
+#define wsba_m_ena 0x1
+#define wsba_m_sg 0x2
+#define wsba_m_addr 0xFFF00000
+#define wmask_k_sz1gb 0x3FF00000
+union TPAchipWSBA {
+ struct {
+ unsigned wsba_v_ena : 1;
+ unsigned wsba_v_sg : 1;
+ unsigned wsba_v_rsvd1 : 18;
+ unsigned wsba_v_addr : 12;
+ unsigned wsba_v_rsvd2 : 32;
+ } wsba_r_bits;
+ int wsba_q_whole [2];
+};
+
+/*
+ * TITAN PA-chip Control Register
+ * This definition covers both the G-Port GPCTL and the A-PORT APCTL.
+ * Bits <51:0> are the same in both cases. APCTL<63:52> are only
+ * applicable to AGP.
+ */
+#define pctl_m_fbtb 0x00000001
+#define pctl_m_thdis 0x00000002
+#define pctl_m_chaindis 0x00000004
+#define pctl_m_tgtlat 0x00000018
+#define pctl_m_hole 0x00000020
+#define pctl_m_mwin 0x00000040
+#define pctl_m_arbena 0x00000080
+#define pctl_m_prigrp 0x0000FF00
+#define pctl_m_ppri 0x00010000
+#define pctl_m_pcispd66 0x00020000
+#define pctl_m_cngstlt 0x003C0000
+#define pctl_m_ptpdesten 0x3FC00000
+#define pctl_m_dpcen 0x40000000
+#define pctl_m_apcen 0x0000000080000000UL
+#define pctl_m_dcrtv 0x0000000300000000UL
+#define pctl_m_en_stepping 0x0000000400000000UL
+#define apctl_m_rsvd1 0x000FFFF800000000UL
+#define apctl_m_agp_rate 0x0030000000000000UL
+#define apctl_m_agp_sba_en 0x0040000000000000UL
+#define apctl_m_agp_en 0x0080000000000000UL
+#define apctl_m_rsvd2 0x0100000000000000UL
+#define apctl_m_agp_present 0x0200000000000000UL
+#define apctl_agp_hp_rd 0x1C00000000000000UL
+#define apctl_agp_lp_rd 0xE000000000000000UL
+#define gpctl_m_rsvd 0xFFFFFFF800000000UL
+union TPAchipPCTL {
+ struct {
+ unsigned pctl_v_fbtb : 1; /* A/G [0] */
+ unsigned pctl_v_thdis : 1; /* A/G [1] */
+ unsigned pctl_v_chaindis : 1; /* A/G [2] */
+ unsigned pctl_v_tgtlat : 2; /* A/G [4:3] */
+ unsigned pctl_v_hole : 1; /* A/G [5] */
+ unsigned pctl_v_mwin : 1; /* A/G [6] */
+ unsigned pctl_v_arbena : 1; /* A/G [7] */
+ unsigned pctl_v_prigrp : 8; /* A/G [15:8] */
+ unsigned pctl_v_ppri : 1; /* A/G [16] */
+ unsigned pctl_v_pcispd66 : 1; /* A/G [17] */
+ unsigned pctl_v_cngstlt : 4; /* A/G [21:18] */
+ unsigned pctl_v_ptpdesten : 8; /* A/G [29:22] */
+ unsigned pctl_v_dpcen : 1; /* A/G [30] */
+ unsigned pctl_v_apcen : 1; /* A/G [31] */
+ unsigned pctl_v_dcrtv : 2; /* A/G [33:32] */
+ unsigned pctl_v_en_stepping :1; /* A/G [34] */
+ unsigned apctl_v_rsvd1 : 17; /* A [51:35] */
+ unsigned apctl_v_agp_rate : 2; /* A [53:52] */
+ unsigned apctl_v_agp_sba_en : 1; /* A [54] */
+ unsigned apctl_v_agp_en : 1; /* A [55] */
+ unsigned apctl_v_rsvd2 : 1; /* A [56] */
+ unsigned apctl_v_agp_present : 1; /* A [57] */
+ unsigned apctl_v_agp_hp_rd : 3; /* A [60:58] */
+ unsigned apctl_v_agp_lp_rd : 3; /* A [63:61] */
+ } pctl_r_bits;
+ unsigned int pctl_l_whole [2];
+ unsigned long pctl_q_whole;
+};
+
+/*
+ * SERROR / SERREN / SERRSET
+ */
+union TPAchipSERR {
+ struct {
+ unsigned serr_v_lost_uecc : 1; /* [0] */
+ unsigned serr_v_uecc : 1; /* [1] */
+ unsigned serr_v_cre : 1; /* [2] */
+ unsigned serr_v_nxio : 1; /* [3] */
+ unsigned serr_v_lost_cre : 1; /* [4] */
+ unsigned serr_v_rsvd0 : 10; /* [14:5] */
+ unsigned serr_v_addr : 32; /* [46:15] */
+ unsigned serr_v_rsvd1 : 5; /* [51:47] */
+ unsigned serr_v_source : 2; /* [53:52] */
+ unsigned serr_v_cmd : 2; /* [55:54] */
+ unsigned serr_v_syn : 8; /* [63:56] */
+ } serr_r_bits;
+ unsigned int serr_l_whole[2];
+ unsigned long serr_q_whole;
+};
+
+/*
+ * GPERROR / APERROR / GPERREN / APERREN / GPERRSET / APERRSET
+ */
+union TPAchipPERR {
+ struct {
+ unsigned long perr_v_lost : 1; /* [0] */
+ unsigned long perr_v_serr : 1; /* [1] */
+ unsigned long perr_v_perr : 1; /* [2] */
+ unsigned long perr_v_dcrto : 1; /* [3] */
+ unsigned long perr_v_sge : 1; /* [4] */
+ unsigned long perr_v_ape : 1; /* [5] */
+ unsigned long perr_v_ta : 1; /* [6] */
+ unsigned long perr_v_dpe : 1; /* [7] */
+ unsigned long perr_v_nds : 1; /* [8] */
+ unsigned long perr_v_iptpr : 1; /* [9] */
+ unsigned long perr_v_iptpw : 1; /* [10] */
+ unsigned long perr_v_rsvd0 : 3; /* [13:11] */
+ unsigned long perr_v_addr : 33; /* [46:14] */
+ unsigned long perr_v_dac : 1; /* [47] */
+ unsigned long perr_v_mwin : 1; /* [48] */
+ unsigned long perr_v_rsvd1 : 3; /* [51:49] */
+ unsigned long perr_v_cmd : 4; /* [55:52] */
+ unsigned long perr_v_rsvd2 : 8; /* [63:56] */
+ } perr_r_bits;
+ unsigned int perr_l_whole[2];
+ unsigned long perr_q_whole;
+};
+
+/*
+ * AGPERROR / AGPERREN / AGPERRSET
+ */
+union TPAchipAGPERR {
+ struct {
+ unsigned agperr_v_lost : 1; /* [0] */
+ unsigned agperr_v_lpqfull : 1; /* [1] */
+ unsigned apgerr_v_hpqfull : 1; /* [2] */
+ unsigned agperr_v_rescmd : 1; /* [3] */
+ unsigned agperr_v_ipte : 1; /* [4] */
+ unsigned agperr_v_ptp : 1; /* [5] */
+ unsigned agperr_v_nowindow : 1; /* [6] */
+ unsigned agperr_v_rsvd0 : 8; /* [14:7] */
+ unsigned agperr_v_addr : 32; /* [46:15] */
+ unsigned agperr_v_rsvd1 : 1; /* [47] */
+ unsigned agperr_v_dac : 1; /* [48] */
+ unsigned agperr_v_mwin : 1; /* [49] */
+ unsigned agperr_v_cmd : 3; /* [52:50] */
+ unsigned agperr_v_length : 6; /* [58:53] */
+ unsigned agperr_v_fence : 1; /* [59] */
+ unsigned agperr_v_rsvd2 : 4; /* [63:60] */
+ } agperr_r_bits;
+ unsigned int agperr_l_whole[2];
+ unsigned long agperr_q_whole;
+};
+/*
+ * Memory spaces:
+ * Hose numbers are assigned as follows:
+ * 0 - pachip 0 / G Port
+ * 1 - pachip 1 / G Port
+ * 2 - pachip 0 / A Port
+ * 3 - pachip 1 / A Port
+ */
+#define TITAN_HOSE(h) (((unsigned long)(h)) << 33)
+#define TITAN_BASE (IDENT_ADDR + TI_BIAS)
+#define TITAN_MEM(h) (TITAN_BASE+TITAN_HOSE(h)+0x000000000UL)
+#define _TITAN_IACK_SC(h) (TITAN_BASE+TITAN_HOSE(h)+0x1F8000000UL)
+#define TITAN_IO(h) (TITAN_BASE+TITAN_HOSE(h)+0x1FC000000UL)
+#define TITAN_CONF(h) (TITAN_BASE+TITAN_HOSE(h)+0x1FE000000UL)
+
+#define TITAN_IACK_SC _TITAN_IACK_SC(0) /* hack! */
+
+/*
+ * The canonical non-remaped I/O and MEM addresses have these values
+ * subtracted out. This is arranged so that folks manipulating ISA
+ * devices can use their familiar numbers and have them map to bus 0.
+ */
+
+#define TITAN_IO_BIAS TITAN_IO(0)
+#define TITAN_MEM_BIAS TITAN_MEM(0)
+
+/* The IO address space is larger than 0xffff */
+#define TITAN_IO_SPACE (TITAN_CONF(0) - TITAN_IO(0))
+
+/* TIG Space */
+#define TITAN_TIG_SPACE (TITAN_BASE + 0x100000000UL)
+
+/*
+ * Data structure for handling TITAN machine checks:
+ */
+#define SCB_Q_SYSERR 0x620
+#define SCB_Q_PROCERR 0x630
+#define SCB_Q_SYSMCHK 0x660
+#define SCB_Q_PROCMCHK 0x670
+#define SCB_Q_SYSEVENT 0x680 /* environmental / system management */
+struct el_TITAN_sysdata_mcheck {
+ u64 summary; /* 0x00 */
+ u64 c_dirx; /* 0x08 */
+ u64 c_misc; /* 0x10 */
+ u64 p0_serror; /* 0x18 */
+ u64 p0_gperror; /* 0x20 */
+ u64 p0_aperror; /* 0x28 */
+ u64 p0_agperror;/* 0x30 */
+ u64 p1_serror; /* 0x38 */
+ u64 p1_gperror; /* 0x40 */
+ u64 p1_aperror; /* 0x48 */
+ u64 p1_agperror;/* 0x50 */
+};
+
+/*
+ * System area for a privateer 680 environmental/system management mcheck
+ */
+struct el_PRIVATEER_envdata_mcheck {
+ u64 summary; /* 0x00 */
+ u64 c_dirx; /* 0x08 */
+ u64 smir; /* 0x10 */
+ u64 cpuir; /* 0x18 */
+ u64 psir; /* 0x20 */
+ u64 fault; /* 0x28 */
+ u64 sys_doors; /* 0x30 */
+ u64 temp_warn; /* 0x38 */
+ u64 fan_ctrl; /* 0x40 */
+ u64 code; /* 0x48 */
+ u64 reserved; /* 0x50 */
+};
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * I/O functions:
+ *
+ * TITAN, a 21??? PCI/memory support chipset for the EV6 (21264)
+ * can only use linear accesses to get at PCI/AGP memory and I/O spaces.
+ */
+
+#define vucp volatile unsigned char *
+#define vusp volatile unsigned short *
+#define vuip volatile unsigned int *
+#define vulp volatile unsigned long *
+
+__EXTERN_INLINE unsigned int titan_inb(unsigned long addr)
+{
+ /* ??? I wish I could get rid of this. But there's no ioremap
+ equivalent for I/O space. PCI I/O can be forced into the
+ correct hose's I/O region, but that doesn't take care of
+ legacy ISA crap. */
+
+ addr += TITAN_IO_BIAS;
+ return __kernel_ldbu(*(vucp)addr);
+}
+
+__EXTERN_INLINE void titan_outb(unsigned char b, unsigned long addr)
+{
+ addr += TITAN_IO_BIAS;
+ __kernel_stb(b, *(vucp)addr);
+ mb();
+}
+
+__EXTERN_INLINE unsigned int titan_inw(unsigned long addr)
+{
+ addr += TITAN_IO_BIAS;
+ return __kernel_ldwu(*(vusp)addr);
+}
+
+__EXTERN_INLINE void titan_outw(unsigned short b, unsigned long addr)
+{
+ addr += TITAN_IO_BIAS;
+ __kernel_stw(b, *(vusp)addr);
+ mb();
+}
+
+__EXTERN_INLINE unsigned int titan_inl(unsigned long addr)
+{
+ addr += TITAN_IO_BIAS;
+ return *(vuip)addr;
+}
+
+__EXTERN_INLINE void titan_outl(unsigned int b, unsigned long addr)
+{
+ addr += TITAN_IO_BIAS;
+ *(vuip)addr = b;
+ mb();
+}
+
+/*
+ * Memory functions. all accesses are done through linear space.
+ */
+
+__EXTERN_INLINE unsigned long titan_ioremap(unsigned long addr)
+{
+ return addr + TITAN_MEM_BIAS;
+}
+
+__EXTERN_INLINE int titan_is_ioaddr(unsigned long addr)
+{
+ return addr >= TITAN_BASE;
+}
+
+__EXTERN_INLINE unsigned long titan_readb(unsigned long addr)
+{
+ return __kernel_ldbu(*(vucp)addr);
+}
+
+__EXTERN_INLINE unsigned long titan_readw(unsigned long addr)
+{
+ return __kernel_ldwu(*(vusp)addr);
+}
+
+__EXTERN_INLINE unsigned long titan_readl(unsigned long addr)
+{
+ return *(vuip)addr;
+}
+
+__EXTERN_INLINE unsigned long titan_readq(unsigned long addr)
+{
+ return *(vulp)addr;
+}
+
+__EXTERN_INLINE void titan_writeb(unsigned char b, unsigned long addr)
+{
+ __kernel_stb(b, *(vucp)addr);
+}
+
+__EXTERN_INLINE void titan_writew(unsigned short b, unsigned long addr)
+{
+ __kernel_stw(b, *(vusp)addr);
+}
+
+__EXTERN_INLINE void titan_writel(unsigned int b, unsigned long addr)
+{
+ *(vuip)addr = b;
+}
+
+__EXTERN_INLINE void titan_writeq(unsigned long b, unsigned long addr)
+{
+ *(vulp)addr = b;
+}
+
+#undef vucp
+#undef vusp
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define __inb titan_inb
+#define __inw titan_inw
+#define __inl titan_inl
+#define __outb titan_outb
+#define __outw titan_outw
+#define __outl titan_outl
+#define __readb titan_readb
+#define __readw titan_readw
+#define __writeb titan_writeb
+#define __writew titan_writew
+#define __readl titan_readl
+#define __readq titan_readq
+#define __writel titan_writel
+#define __writeq titan_writeq
+#define __ioremap titan_ioremap
+#define __is_ioaddr titan_is_ioaddr
+
+#define inb(port) __inb((port))
+#define inw(port) __inw((port))
+#define inl(port) __inl((port))
+#define outb(v, port) __outb((v),(port))
+#define outw(v, port) __outw((v),(port))
+#define outl(v, port) __outl((v),(port))
+
+#define __raw_readb(a) __readb((unsigned long)(a))
+#define __raw_readw(a) __readw((unsigned long)(a))
+#define __raw_readl(a) __readl((unsigned long)(a))
+#define __raw_readq(a) __readq((unsigned long)(a))
+#define __raw_writeb(v,a) __writeb((v),(unsigned long)(a))
+#define __raw_writew(v,a) __writew((v),(unsigned long)(a))
+#define __raw_writel(v,a) __writel((v),(unsigned long)(a))
+#define __raw_writeq(v,a) __writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_TITAN__H__ */
diff --git a/include/asm-alpha/core_tsunami.h b/include/asm-alpha/core_tsunami.h
index 5d0d7cf7a36cfb..00d20922b46d6d 100644
--- a/include/asm-alpha/core_tsunami.h
+++ b/include/asm-alpha/core_tsunami.h
@@ -52,6 +52,7 @@ typedef struct {
tsunami_64 mpr2;
tsunami_64 mpr3;
tsunami_64 mctl;
+ tsunami_64 __pad1;
tsunami_64 ttr;
tsunami_64 tdr;
tsunami_64 dim2;
diff --git a/include/asm-alpha/core_wildfire.h b/include/asm-alpha/core_wildfire.h
new file mode 100644
index 00000000000000..33666c02d626a9
--- /dev/null
+++ b/include/asm-alpha/core_wildfire.h
@@ -0,0 +1,427 @@
+#ifndef __ALPHA_WILDFIRE__H__
+#define __ALPHA_WILDFIRE__H__
+
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+#define WILDFIRE_MAX_QBB 8 /* more than 8 requires other mods */
+#define WILDFIRE_PCA_PER_QBB 4
+#define WILDFIRE_IRQ_PER_PCA 64
+
+#define WILDFIRE_NR_IRQS \
+ (WILDFIRE_MAX_QBB * WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)
+
+extern unsigned char wildfire_hard_qbb_map[WILDFIRE_MAX_QBB];
+extern unsigned char wildfire_soft_qbb_map[WILDFIRE_MAX_QBB];
+#define QBB_MAP_EMPTY 0xff
+
+extern unsigned long wildfire_hard_qbb_mask;
+extern unsigned long wildfire_soft_qbb_mask;
+extern unsigned long wildfire_gp_mask;
+extern unsigned long wildfire_hs_mask;
+extern unsigned long wildfire_iop_mask;
+extern unsigned long wildfire_ior_mask;
+extern unsigned long wildfire_pca_mask;
+extern unsigned long wildfire_cpu_mask;
+extern unsigned long wildfire_mem_mask;
+
+#define WILDFIRE_QBB_EXISTS(qbbno) (wildfire_soft_qbb_mask & (1 << (qbbno)))
+
+#define WILDFIRE_MEM_EXISTS(qbbno) (wildfire_mem_mask & (0xf << ((qbbno) << 2)))
+
+#define WILDFIRE_PCA_EXISTS(qbbno, pcano) \
+ (wildfire_pca_mask & (1 << (((qbbno) << 2) + (pcano))))
+
+typedef struct {
+ volatile unsigned long csr __attribute__((aligned(64)));
+} wildfire_64;
+
+typedef struct {
+ volatile unsigned long csr __attribute__((aligned(256)));
+} wildfire_256;
+
+typedef struct {
+ volatile unsigned long csr __attribute__((aligned(2048)));
+} wildfire_2k;
+
+typedef struct {
+ wildfire_64 qsd_whami;
+ wildfire_64 qsd_rev;
+ wildfire_64 qsd_port_present;
+ wildfire_64 qsd_port_active;
+ wildfire_64 qsd_fault_ena;
+ wildfire_64 qsd_cpu_int_ena;
+ wildfire_64 qsd_mem_config;
+ wildfire_64 qsd_err_sum;
+ wildfire_64 ce_sum[4];
+ wildfire_64 dev_init[4];
+ wildfire_64 it_int[4];
+ wildfire_64 ip_int[4];
+ wildfire_64 uce_sum[4];
+ wildfire_64 se_sum__non_dev_int[4];
+ wildfire_64 scratch[4];
+ wildfire_64 qsd_timer;
+ wildfire_64 qsd_diag;
+} wildfire_qsd;
+
+typedef struct {
+ wildfire_256 qsd_whami;
+ wildfire_256 __pad1;
+ wildfire_256 ce_sum;
+ wildfire_256 dev_init;
+ wildfire_256 it_int;
+ wildfire_256 ip_int;
+ wildfire_256 uce_sum;
+ wildfire_256 se_sum;
+} wildfire_fast_qsd;
+
+typedef struct {
+ wildfire_2k qsa_qbb_id;
+ wildfire_2k __pad1;
+ wildfire_2k qsa_port_ena;
+ wildfire_2k qsa_scratch;
+ wildfire_2k qsa_config[5];
+ wildfire_2k qsa_ref_int;
+ wildfire_2k qsa_qbb_pop[2];
+ wildfire_2k qsa_dtag_fc;
+ wildfire_2k __pad2[3];
+ wildfire_2k qsa_diag;
+ wildfire_2k qsa_diag_lock[4];
+ wildfire_2k __pad3[11];
+ wildfire_2k qsa_cpu_err_sum;
+ wildfire_2k qsa_misc_err_sum;
+ wildfire_2k qsa_tmo_err_sum;
+ wildfire_2k qsa_err_ena;
+ wildfire_2k qsa_tmo_config;
+ wildfire_2k qsa_ill_cmd_err_sum;
+ wildfire_2k __pad4[26];
+ wildfire_2k qsa_busy_mask;
+ wildfire_2k qsa_arr_valid;
+ wildfire_2k __pad5[2];
+ wildfire_2k qsa_port_map[4];
+ wildfire_2k qsa_arr_addr[8];
+ wildfire_2k qsa_arr_mask[8];
+} wildfire_qsa;
+
+typedef struct {
+ wildfire_64 ioa_config;
+ wildfire_64 iod_config;
+ wildfire_64 iop_switch_credits;
+ wildfire_64 __pad1;
+ wildfire_64 iop_hose_credits;
+ wildfire_64 __pad2[11];
+ struct {
+ wildfire_64 __pad3;
+ wildfire_64 init;
+ } iop_hose[4];
+ wildfire_64 ioa_hose_0_ctrl;
+ wildfire_64 iod_hose_0_ctrl;
+ wildfire_64 ioa_hose_1_ctrl;
+ wildfire_64 iod_hose_1_ctrl;
+ wildfire_64 ioa_hose_2_ctrl;
+ wildfire_64 iod_hose_2_ctrl;
+ wildfire_64 ioa_hose_3_ctrl;
+ wildfire_64 iod_hose_3_ctrl;
+ struct {
+ wildfire_64 target;
+ wildfire_64 __pad4;
+ } iop_dev_int[4];
+
+ wildfire_64 iop_err_int_target;
+ wildfire_64 __pad5[7];
+ wildfire_64 iop_qbb_err_sum;
+ wildfire_64 __pad6;
+ wildfire_64 iop_qbb_se_sum;
+ wildfire_64 __pad7;
+ wildfire_64 ioa_err_sum;
+ wildfire_64 iod_err_sum;
+ wildfire_64 __pad8[4];
+ wildfire_64 ioa_diag_force_err;
+ wildfire_64 iod_diag_force_err;
+ wildfire_64 __pad9[4];
+ wildfire_64 iop_diag_send_err_int;
+ wildfire_64 __pad10[15];
+ wildfire_64 ioa_scratch;
+ wildfire_64 iod_scratch;
+} wildfire_iop;
+
+typedef struct {
+ wildfire_2k gpa_qbb_map[4];
+ wildfire_2k gpa_mem_pop_map;
+ wildfire_2k gpa_scratch;
+ wildfire_2k gpa_diag;
+ wildfire_2k gpa_config_0;
+ wildfire_2k __pad1;
+ wildfire_2k gpa_init_id;
+ wildfire_2k gpa_config_2;
+ /* not complete */
+} wildfire_gp;
+
+typedef struct {
+ wildfire_64 pca_what_am_i;
+ wildfire_64 pca_err_sum;
+ wildfire_64 pca_diag_force_err;
+ wildfire_64 pca_diag_send_err_int;
+ wildfire_64 pca_hose_credits;
+ wildfire_64 pca_scratch;
+ wildfire_64 pca_micro_addr;
+ wildfire_64 pca_micro_data;
+ wildfire_64 pca_pend_int;
+ wildfire_64 pca_sent_int;
+ wildfire_64 __pad1;
+ wildfire_64 pca_stdio_edge_level;
+ wildfire_64 __pad2[52];
+ struct {
+ wildfire_64 target;
+ wildfire_64 enable;
+ } pca_int[4];
+ wildfire_64 __pad3[56];
+ wildfire_64 pca_alt_sent_int[32];
+} wildfire_pca;
+
+typedef struct {
+ wildfire_64 ne_what_am_i;
+ /* not complete */
+} wildfire_ne;
+
+typedef struct {
+ wildfire_64 fe_what_am_i;
+ /* not complete */
+} wildfire_fe;
+
+typedef struct {
+ wildfire_64 pci_io_addr_ext;
+ wildfire_64 pci_ctrl;
+ wildfire_64 pci_err_sum;
+ wildfire_64 pci_err_addr;
+ wildfire_64 pci_stall_cnt;
+ wildfire_64 pci_iack_special;
+ wildfire_64 __pad1[2];
+ wildfire_64 pci_pend_int;
+ wildfire_64 pci_sent_int;
+ wildfire_64 __pad2[54];
+ struct {
+ wildfire_64 wbase;
+ wildfire_64 wmask;
+ wildfire_64 tbase;
+ } pci_window[4];
+ wildfire_64 pci_flush_tlb;
+ wildfire_64 pci_perf_mon;
+} wildfire_pci;
+
+#define WILDFIRE_ENTITY_SHIFT 18
+
+#define WILDFIRE_GP_ENTITY (0x10UL << WILDFIRE_ENTITY_SHIFT)
+#define WILDFIRE_IOP_ENTITY (0x08UL << WILDFIRE_ENTITY_SHIFT)
+#define WILDFIRE_QSA_ENTITY (0x04UL << WILDFIRE_ENTITY_SHIFT)
+#define WILDFIRE_QSD_ENTITY_SLOW (0x05UL << WILDFIRE_ENTITY_SHIFT)
+#define WILDFIRE_QSD_ENTITY_FAST (0x01UL << WILDFIRE_ENTITY_SHIFT)
+
+#define WILDFIRE_PCA_ENTITY(pca) ((0xc|(pca))<<WILDFIRE_ENTITY_SHIFT)
+
+#define WILDFIRE_BASE (IDENT_ADDR | (1UL << 40))
+
+#define WILDFIRE_QBB_MASK 0x0fUL /* for now, only 4 bits/16 QBBs */
+
+#define WILDFIRE_QBB(q) ((~((long)(q)) & WILDFIRE_QBB_MASK) << 36)
+#define WILDFIRE_HOSE(h) ((long)(h) << 33)
+
+#define WILDFIRE_QBB_IO(q) (WILDFIRE_BASE | WILDFIRE_QBB(q))
+#define WILDFIRE_QBB_HOSE(q,h) (WILDFIRE_QBB_IO(q) | WILDFIRE_HOSE(h))
+
+#define WILDFIRE_MEM(q,h) (WILDFIRE_QBB_HOSE(q,h) | 0x000000000UL)
+#define WILDFIRE_CONF(q,h) (WILDFIRE_QBB_HOSE(q,h) | 0x1FE000000UL)
+#define WILDFIRE_IO(q,h) (WILDFIRE_QBB_HOSE(q,h) | 0x1FF000000UL)
+
+#define WILDFIRE_qsd(q) \
+ ((wildfire_qsd *)(WILDFIRE_QBB_IO(q)|WILDFIRE_QSD_ENTITY_SLOW|(((1UL<<13)-1)<<23)))
+
+#define WILDFIRE_fast_qsd() \
+ ((wildfire_fast_qsd *)(WILDFIRE_QBB_IO(0)|WILDFIRE_QSD_ENTITY_FAST|(((1UL<<13)-1)<<23)))
+
+#define WILDFIRE_qsa(q) \
+ ((wildfire_qsa *)(WILDFIRE_QBB_IO(q)|WILDFIRE_QSA_ENTITY|(((1UL<<13)-1)<<23)))
+
+#define WILDFIRE_iop(q) \
+ ((wildfire_iop *)(WILDFIRE_QBB_IO(q)|WILDFIRE_IOP_ENTITY|(((1UL<<13)-1)<<23)))
+
+#define WILDFIRE_gp(q) \
+ ((wildfire_gp *)(WILDFIRE_QBB_IO(q)|WILDFIRE_GP_ENTITY|(((1UL<<13)-1)<<23)))
+
+#define WILDFIRE_pca(q,pca) \
+ ((wildfire_pca *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)))
+
+#define WILDFIRE_ne(q,pca) \
+ ((wildfire_ne *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)|(1UL<<16)))
+
+#define WILDFIRE_fe(q,pca) \
+ ((wildfire_fe *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)|(3UL<<15)))
+
+#define WILDFIRE_pci(q,h) \
+ ((wildfire_pci *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(((h)&6)>>1)|((((h)&1)|2)<<16)|(((1UL<<13)-1)<<23)))
+
+#define WILDFIRE_IO_BIAS WILDFIRE_IO(0,0)
+#define WILDFIRE_MEM_BIAS WILDFIRE_MEM(0,0) /* ??? */
+
+/* The IO address space is larger than 0xffff */
+#define WILDFIRE_IO_SPACE (8UL*1024*1024)
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+#define vucp volatile unsigned char *
+#define vusp volatile unsigned short *
+#define vuip volatile unsigned int *
+#define vulp volatile unsigned long *
+
+__EXTERN_INLINE unsigned int wildfire_inb(unsigned long addr)
+{
+ /* ??? I wish I could get rid of this. But there's no ioremap
+ equivalent for I/O space. PCI I/O can be forced into the
+ correct hose's I/O region, but that doesn't take care of
+ legacy ISA crap. */
+
+ addr += WILDFIRE_IO_BIAS;
+ return __kernel_ldbu(*(vucp)addr);
+}
+
+__EXTERN_INLINE void wildfire_outb(unsigned char b, unsigned long addr)
+{
+ addr += WILDFIRE_IO_BIAS;
+ __kernel_stb(b, *(vucp)addr);
+ mb();
+}
+
+__EXTERN_INLINE unsigned int wildfire_inw(unsigned long addr)
+{
+ addr += WILDFIRE_IO_BIAS;
+ return __kernel_ldwu(*(vusp)addr);
+}
+
+__EXTERN_INLINE void wildfire_outw(unsigned short b, unsigned long addr)
+{
+ addr += WILDFIRE_IO_BIAS;
+ __kernel_stw(b, *(vusp)addr);
+ mb();
+}
+
+__EXTERN_INLINE unsigned int wildfire_inl(unsigned long addr)
+{
+ addr += WILDFIRE_IO_BIAS;
+ return *(vuip)addr;
+}
+
+__EXTERN_INLINE void wildfire_outl(unsigned int b, unsigned long addr)
+{
+ addr += WILDFIRE_IO_BIAS;
+ *(vuip)addr = b;
+ mb();
+}
+
+/*
+ * Memory functions. all accesses are done through linear space.
+ */
+
+__EXTERN_INLINE unsigned long wildfire_ioremap(unsigned long addr)
+{
+ return addr + WILDFIRE_MEM_BIAS;
+}
+
+__EXTERN_INLINE int wildfire_is_ioaddr(unsigned long addr)
+{
+ return addr >= WILDFIRE_BASE;
+}
+
+__EXTERN_INLINE unsigned long wildfire_readb(unsigned long addr)
+{
+ return __kernel_ldbu(*(vucp)addr);
+}
+
+__EXTERN_INLINE unsigned long wildfire_readw(unsigned long addr)
+{
+ return __kernel_ldwu(*(vusp)addr);
+}
+
+__EXTERN_INLINE unsigned long wildfire_readl(unsigned long addr)
+{
+ return *(vuip)addr;
+}
+
+__EXTERN_INLINE unsigned long wildfire_readq(unsigned long addr)
+{
+ return *(vulp)addr;
+}
+
+__EXTERN_INLINE void wildfire_writeb(unsigned char b, unsigned long addr)
+{
+ __kernel_stb(b, *(vucp)addr);
+}
+
+__EXTERN_INLINE void wildfire_writew(unsigned short b, unsigned long addr)
+{
+ __kernel_stw(b, *(vusp)addr);
+}
+
+__EXTERN_INLINE void wildfire_writel(unsigned int b, unsigned long addr)
+{
+ *(vuip)addr = b;
+}
+
+__EXTERN_INLINE void wildfire_writeq(unsigned long b, unsigned long addr)
+{
+ *(vulp)addr = b;
+}
+
+#undef vucp
+#undef vusp
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define __inb(p) wildfire_inb((unsigned long)(p))
+#define __inw(p) wildfire_inw((unsigned long)(p))
+#define __inl(p) wildfire_inl((unsigned long)(p))
+#define __outb(x,p) wildfire_outb((x),(unsigned long)(p))
+#define __outw(x,p) wildfire_outw((x),(unsigned long)(p))
+#define __outl(x,p) wildfire_outl((x),(unsigned long)(p))
+#define __readb(a) wildfire_readb((unsigned long)(a))
+#define __readw(a) wildfire_readw((unsigned long)(a))
+#define __readl(a) wildfire_readl((unsigned long)(a))
+#define __readq(a) wildfire_readq((unsigned long)(a))
+#define __writeb(x,a) wildfire_writeb((x),(unsigned long)(a))
+#define __writew(x,a) wildfire_writew((x),(unsigned long)(a))
+#define __writel(x,a) wildfire_writel((x),(unsigned long)(a))
+#define __writeq(x,a) wildfire_writeq((x),(unsigned long)(a))
+#define __ioremap(a) wildfire_ioremap((unsigned long)(a))
+#define __is_ioaddr(a) wildfire_is_ioaddr((unsigned long)(a))
+
+#define inb(p) __inb(p)
+#define inw(p) __inw(p)
+#define inl(p) __inl(p)
+#define outb(x,p) __outb((x),(p))
+#define outw(x,p) __outw((x),(p))
+#define outl(x,p) __outl((x),(p))
+#define __raw_readb(a) __readb(a)
+#define __raw_readw(a) __readw(a)
+#define __raw_readl(a) __readl(a)
+#define __raw_readq(a) __readq(a)
+#define __raw_writeb(v,a) __writeb((v),(a))
+#define __raw_writew(v,a) __writew((v),(a))
+#define __raw_writel(v,a) __writel((v),(a))
+#define __raw_writeq(v,a) __writeq((v),(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_WILDFIRE__H__ */
diff --git a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h
index a08aa973c5b48f..92c213b2743c31 100644
--- a/include/asm-alpha/floppy.h
+++ b/include/asm-alpha/floppy.h
@@ -31,6 +31,51 @@
"floppy", NULL)
#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL);
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+#define fd_dma_setup(addr,size,mode,io) alpha_fd_dma_setup(addr,size,mode,io)
+
+static __inline__ int
+alpha_fd_dma_setup(char *addr, unsigned long size, int mode, int io)
+{
+ static unsigned long prev_size;
+ static dma_addr_t bus_addr = 0;
+ static char *prev_addr;
+ static int prev_dir;
+ int dir;
+
+ dir = (mode != DMA_MODE_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE;
+
+ if (bus_addr
+ && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
+ /* different from last time -- unmap prev */
+ pci_unmap_single(NULL, bus_addr, prev_size, prev_dir);
+ bus_addr = 0;
+ }
+
+ if (!bus_addr) /* need to map it */
+ bus_addr = pci_map_single(NULL, addr, size, dir);
+
+ /* remember this one as prev */
+ prev_addr = addr;
+ prev_size = size;
+ prev_dir = dir;
+
+ fd_clear_dma_ff();
+ fd_cacheflush(addr, size);
+ fd_set_dma_mode(mode);
+ set_dma_addr(FLOPPY_DMA, bus_addr);
+ fd_set_dma_count(size);
+ virtual_dma_port = io;
+ fd_enable_dma();
+
+ return 0;
+}
+
+#endif /* CONFIG_PCI */
+
__inline__ void virtual_dma_init(void)
{
/* Nothing to do on an Alpha */
diff --git a/include/asm-alpha/hwrpb.h b/include/asm-alpha/hwrpb.h
index 39d84de1be8c85..1e8f35fe7a461b 100644
--- a/include/asm-alpha/hwrpb.h
+++ b/include/asm-alpha/hwrpb.h
@@ -14,9 +14,10 @@
#define EV5_CPU 5 /* EV5 (21164) */
#define EV45_CPU 6 /* EV4.5 (21064/xxx) */
#define EV56_CPU 7 /* EV5.6 (21164) */
-#define EV6_CPU 8 /* EV6 (21164) */
+#define EV6_CPU 8 /* EV6 (21264) */
#define PCA56_CPU 9 /* PCA56 (21164PC) */
#define PCA57_CPU 10 /* PCA57 (notyet) */
+#define EV67_CPU 11 /* EV67 (21264A) */
/*
* DEC system types for Alpha systems. Found in HWRPB.
@@ -56,6 +57,7 @@
#define ST_DEC_WILDFIRE 35 /* Wildfire systype */
#define ST_DEC_CUSCO 36 /* CUSCO systype */
#define ST_DEC_EIGER 37 /* Eiger systype */
+#define ST_DEC_TITAN 38 /* Titan systype */
/* UNOFFICIAL!!! */
#define ST_UNOFFICIAL_BIAS 100
diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h
index 0e532f6e558101..35a9dafc3f30af 100644
--- a/include/asm-alpha/io.h
+++ b/include/asm-alpha/io.h
@@ -170,6 +170,10 @@ extern void _sethae (unsigned long addr); /* cached version */
# include <asm/core_t2.h>
#elif defined(CONFIG_ALPHA_TSUNAMI)
# include <asm/core_tsunami.h>
+#elif defined(CONFIG_ALPHA_TITAN)
+# include <asm/core_titan.h>
+#elif defined(CONFIG_ALPHA_WILDFIRE)
+# include <asm/core_wildfire.h>
#else
#error "What system is this?"
#endif
diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h
index f9b4d9f12a7690..254d8f17fddc6c 100644
--- a/include/asm-alpha/irq.h
+++ b/include/asm-alpha/irq.h
@@ -16,7 +16,7 @@
many places throughout the kernel to size static arrays. That's ok,
we'll use alpha_mv.nr_irqs when we want the real thing. */
-# define NR_IRQS 128
+# define NR_IRQS 2048 /* enuff for WILDFIRE with 8 QBBs */
#elif defined(CONFIG_ALPHA_CABRIOLET) || \
defined(CONFIG_ALPHA_EB66P) || \
@@ -46,10 +46,16 @@
defined(CONFIG_ALPHA_EIGER)
# define NR_IRQS 64
+#elif defined(CONFIG_ALPHA_TITAN)
+#define NR_IRQS 80
+
#elif defined(CONFIG_ALPHA_RAWHIDE) || \
defined(CONFIG_ALPHA_TAKARA)
# define NR_IRQS 128
+#elif defined(CONFIG_ALPHA_WILDFIRE)
+# define NR_IRQS 2048 /* enuff for 8 QBBs */
+
#else /* everyone else */
# define NR_IRQS 16
#endif
diff --git a/include/asm-alpha/mc146818rtc.h b/include/asm-alpha/mc146818rtc.h
new file mode 100644
index 00000000000000..097703f1c8cb8d
--- /dev/null
+++ b/include/asm-alpha/mc146818rtc.h
@@ -0,0 +1,27 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_ALPHA_MC146818RTC_H
+#define __ASM_ALPHA_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* __ASM_ALPHA_MC146818RTC_H */
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index ef04b09bafc6a2..2614e818982e33 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -45,7 +45,8 @@
/* Number of pointers that fit on a page: this will go away. */
#define PTRS_PER_PAGE (1UL << (PAGE_SHIFT-3))
-#define VMALLOC_START 0xFFFFFE0000000000
+#define CONSOLE_REMAP_START 0xFFFFFE0000000000
+#define VMALLOC_START (CONSOLE_REMAP_START + PMD_SIZE)
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
#define VMALLOC_END (~0UL)
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index 919d2b7517008c..4c2f70170f48e5 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -22,14 +22,17 @@
/* Remove when official MILO sources have ELF support: */
#define BOOT_SIZE (16*1024)
-#define KERNEL_START (PAGE_OFFSET+0x300000)
-#define SWAPPER_PGD (PAGE_OFFSET+0x300000)
-#define INIT_STACK (PAGE_OFFSET+0x302000)
-#define EMPTY_PGT (PAGE_OFFSET+0x304000)
-#define EMPTY_PGE (PAGE_OFFSET+0x308000)
-#define ZERO_PGE (PAGE_OFFSET+0x30A000)
-#define START_ADDR (PAGE_OFFSET+0x310000)
+#define KERNEL_START_PHYS 0x800000 /* Wildfire has a huge console */
+
+#define KERNEL_START (PAGE_OFFSET+KERNEL_START_PHYS)
+#define SWAPPER_PGD KERNEL_START
+#define INIT_STACK (PAGE_OFFSET+KERNEL_START_PHYS+0x02000)
+#define EMPTY_PGT (PAGE_OFFSET+KERNEL_START_PHYS+0x04000)
+#define EMPTY_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x08000)
+#define ZERO_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x0A000)
+
+#define START_ADDR (PAGE_OFFSET+KERNEL_START_PHYS+0x10000)
#ifndef __ASSEMBLY__
@@ -111,6 +114,7 @@ struct el_common_EV6_mcheck {
};
extern void halt(void) __attribute__((noreturn));
+#define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
#define prepare_to_switch() do { } while(0)
#define switch_to(prev,next,last) \
diff --git a/include/asm-alpha/uaccess.h b/include/asm-alpha/uaccess.h
index adba04b1fe8426..98c446942f05e8 100644
--- a/include/asm-alpha/uaccess.h
+++ b/include/asm-alpha/uaccess.h
@@ -530,7 +530,7 @@ struct exception_table_entry
};
/* Returns 0 if exception not found and fixup.unit otherwise. */
-extern unsigned search_exception_table(unsigned long);
+extern unsigned search_exception_table(unsigned long, unsigned long);
/* Returns the new pc */
#define fixup_exception(map_reg, fixup_unit, pc) \
diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
index b71c3a708506ee..75453ddfd08d85 100644
--- a/include/asm-alpha/unistd.h
+++ b/include/asm-alpha/unistd.h
@@ -315,7 +315,7 @@
#define __NR_mincore 375
#define __NR_pciconfig_iobase 376
-#if defined(__LIBRARY__) && defined(__GNUC__)
+#if defined(__GNUC__)
#define _syscall_return(type) \
return (_sc_err ? errno = _sc_ret, _sc_ret = -1L : 0), (type) _sc_ret
diff --git a/include/asm-arm/arch-arc/hardware.h b/include/asm-arm/arch-arc/hardware.h
index 9a9313fa436e6d..294c18b5786019 100644
--- a/include/asm-arm/arch-arc/hardware.h
+++ b/include/asm-arm/arch-arc/hardware.h
@@ -25,11 +25,6 @@
#include <asm/memc.h>
#define HAS_VIDC
-/*
- * Optional hardware
- */
-#define HAS_EXPMASK
-
/* Hardware addresses of major areas.
* *_START is the physical address
* *_SIZE is the size of the region
@@ -100,7 +95,6 @@
#endif
-#ifdef HAS_EXPMASK
#ifndef __ASSEMBLY__
#define __EXPMASK(offset) (((volatile unsigned char *)EXPMASK_BASE)[offset])
#else
@@ -111,5 +105,3 @@
#define EXPMASK_ENABLE __EXPMASK(0x04)
#endif
-
-#endif
diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h
index b3c1f29310c79d..142a2ddbc9d708 100644
--- a/include/asm-arm/arch-ebsa285/hardware.h
+++ b/include/asm-arm/arch-ebsa285/hardware.h
@@ -11,7 +11,7 @@
#include <linux/config.h>
#include <asm/arch/memory.h>
-#ifdef CONFIG_HOST_FOOTBRIDGE
+#ifdef CONFIG_FOOTBRIDGE_HOST
/* Virtual Physical Size
* 0xff800000 0x40000000 1MB X-Bus
* 0xff000000 0x7c000000 1MB PCI I/O space
diff --git a/include/asm-arm/arch-ebsa285/irq.h b/include/asm-arm/arch-ebsa285/irq.h
index 134729f34af599..b6f2639b563e35 100644
--- a/include/asm-arm/arch-ebsa285/irq.h
+++ b/include/asm-arm/arch-ebsa285/irq.h
@@ -10,8 +10,6 @@
* 26-Jan-1999 PJB Don't use IACK on CATS
* 16-Mar-1999 RMK Added autodetect of ISA PICs
*/
-/* no need for config.h - arch/arm/kernel/irq.c does this for us */
-#include <linux/config.h>
#include <asm/hardware.h>
#include <asm/dec21285.h>
#include <asm/irq.h>
@@ -36,29 +34,31 @@ static int dc21285_irq_mask[] = {
IRQ_MASK_PCI, /* 12 */
IRQ_MASK_SDRAMPARITY, /* 13 */
IRQ_MASK_I2OINPOST, /* 14 */
- IRQ_MASK_PCI_ERR /* 15 */
+ IRQ_MASK_PCI_ABORT, /* 15 */
+ IRQ_MASK_PCI_SERR, /* 16 */
+ IRQ_MASK_DISCARD_TIMER, /* 17 */
+ IRQ_MASK_PCI_DPERR, /* 18 */
+ IRQ_MASK_PCI_PERR, /* 19 */
};
static int isa_irq = -1;
static inline int fixup_irq(unsigned int irq)
{
-#ifdef CONFIG_HOST_FOOTBRIDGE
if (irq == isa_irq)
irq = *(unsigned char *)PCIIACK_BASE;
-#endif
return irq;
}
static void dc21285_mask_irq(unsigned int irq)
{
- *CSR_IRQ_DISABLE = dc21285_irq_mask[irq & 15];
+ *CSR_IRQ_DISABLE = dc21285_irq_mask[_DC21285_INR(irq)];
}
static void dc21285_unmask_irq(unsigned int irq)
{
- *CSR_IRQ_ENABLE = dc21285_irq_mask[irq & 15];
+ *CSR_IRQ_ENABLE = dc21285_irq_mask[_DC21285_INR(irq)];
}
static void isa_mask_pic_lo_irq(unsigned int irq)
@@ -124,7 +124,7 @@ static __inline__ void irq_init_irq(void)
*CSR_IRQ_DISABLE = -1;
*CSR_FIQ_DISABLE = -1;
- for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(16); irq++) {
+ for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
irq_desc[irq].mask_ack = dc21285_mask_irq;
@@ -138,19 +138,21 @@ static __inline__ void irq_init_irq(void)
*/
isa_irq = -1;
- if (machine_is_ebsa285())
- /* The following is dependent on which slot
- * you plug the Southbridge card into. We
- * currently assume that you plug it into
- * the right-hand most slot.
- */
- isa_irq = IRQ_PCI;
+ if (footbridge_cfn_mode()) {
+ if (machine_is_ebsa285())
+ /* The following is dependent on which slot
+ * you plug the Southbridge card into. We
+ * currently assume that you plug it into
+ * the right-hand most slot.
+ */
+ isa_irq = IRQ_PCI;
- if (machine_is_cats())
- isa_irq = IRQ_IN2;
+ if (machine_is_cats())
+ isa_irq = IRQ_IN2;
- if (machine_is_netwinder())
- isa_irq = IRQ_IN3;
+ if (machine_is_netwinder())
+ isa_irq = IRQ_IN3;
+ }
if (isa_irq != -1) {
/*
diff --git a/include/asm-arm/arch-ebsa285/irqs.h b/include/asm-arm/arch-ebsa285/irqs.h
index afb2e379de8f09..9ad99a4589a0c1 100644
--- a/include/asm-arm/arch-ebsa285/irqs.h
+++ b/include/asm-arm/arch-ebsa285/irqs.h
@@ -9,11 +9,13 @@
* 01-Feb-1999 PJB ISA IRQs start at 0 not 16
*/
-#define NR_IRQS 32
+#define NR_IRQS 36
#define NR_DC21285_IRQS 16
#define _ISA_IRQ(x) (0 + (x))
+#define _ISA_INR(x) ((x) - 0)
#define _DC21285_IRQ(x) (16 + (x))
+#define _DC21285_INR(x) ((x) - 16)
/*
* This is a list of all interrupts that the 21285
@@ -34,7 +36,11 @@
#define IRQ_PCI _DC21285_IRQ(12)
#define IRQ_SDRAMPARITY _DC21285_IRQ(13)
#define IRQ_I2OINPOST _DC21285_IRQ(14)
-#define IRQ_PCI_ERR _DC21285_IRQ(15)
+#define IRQ_PCI_ABORT _DC21285_IRQ(15)
+#define IRQ_PCI_SERR _DC21285_IRQ(16)
+#define IRQ_DISCARD_TIMER _DC21285_IRQ(17)
+#define IRQ_PCI_DPERR _DC21285_IRQ(18)
+#define IRQ_PCI_PERR _DC21285_IRQ(19)
#define IRQ_ISA_TIMER _ISA_IRQ(0)
#define IRQ_ISA_KEYBOARD _ISA_IRQ(1)
@@ -64,7 +70,11 @@
#define IRQ_MASK_PCI (1 << 18)
#define IRQ_MASK_SDRAMPARITY (1 << 24)
#define IRQ_MASK_I2OINPOST (1 << 25)
-#define IRQ_MASK_PCI_ERR ((1 <<23) | (1 << 27) | (1 << 28) | (1 << 29) | (1 << 30) | (1 << 31))
+#define IRQ_MASK_PCI_ABORT ((1 << 29) | (1 << 30))
+#define IRQ_MASK_PCI_SERR (1 << 23)
+#define IRQ_MASK_DISCARD_TIMER (1 << 27)
+#define IRQ_MASK_PCI_DPERR (1 << 28)
+#define IRQ_MASK_PCI_PERR (1 << 31)
/*
* Netwinder interrupt allocations
diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h
index 14ba9d4fdd9f56..18d7dacb00f075 100644
--- a/include/asm-arm/arch-ebsa285/memory.h
+++ b/include/asm-arm/arch-ebsa285/memory.h
@@ -17,7 +17,7 @@
#include <linux/config.h>
-#if defined(CONFIG_HOST_FOOTBRIDGE)
+#if defined(CONFIG_FOOTBRIDGE_HOST)
/*
* Task size: 3GB
@@ -36,7 +36,7 @@
#define __bus_to_virt__is_a_macro
#define __bus_to_virt(x) ((x) + 0xe0000000)
-#elif defined(CONFIG_ADDIN_FOOTBRIDGE)
+#elif defined(CONFIG_FOOTBRIDGE_ADDIN)
#if defined(CONFIG_ARCH_CO285)
diff --git a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h
index 222419960869dc..ab71831400b38e 100644
--- a/include/asm-arm/arch-rpc/hardware.h
+++ b/include/asm-arm/arch-rpc/hardware.h
@@ -93,7 +93,6 @@
#endif
-#ifdef HAS_EXPMASK
#ifndef __ASSEMBLY__
#define __EXPMASK(offset) (((volatile unsigned char *)EXPMASK_BASE)[offset])
#else
@@ -104,5 +103,3 @@
#define EXPMASK_ENABLE __EXPMASK(0x04)
#endif
-
-#endif
diff --git a/include/asm-arm/arch-sa1100/assabet.h b/include/asm-arm/arch-sa1100/assabet.h
new file mode 100644
index 00000000000000..75bd395a5dc6f3
--- /dev/null
+++ b/include/asm-arm/arch-sa1100/assabet.h
@@ -0,0 +1,154 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/assabet.h
+ *
+ * Created 2000/06/05 by Nicolas Pitre <nico@cam.org>
+ *
+ * This file contains the hardware specific definitions for Assabet
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for Neponset added.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+
+/* System Configuration Register flags */
+
+#define SCR_SDRAM_LOW (1<<2) /* SDRAM size (low bit) */
+#define SCR_SDRAM_HIGH (1<<3) /* SDRAM size (high bit) */
+#define SCR_FLASH_LOW (1<<4) /* Flash size (low bit) */
+#define SCR_FLASH_HIGH (1<<5) /* Flash size (high bit) */
+#define SCR_GFX (1<<8) /* Graphics Accelerator (0 = present) */
+#define SCR_SA1111 (1<<9) /* Neponset (0 = present) */
+
+#define SCR_INIT -1
+
+
+/* Board Control Register */
+
+#define BCR_BASE 0xdc000000
+#define BCR (*(volatile unsigned int *)(BCR_BASE))
+
+#define BCR_DB1110 (0x00A07410)
+#define BCR_DB1111 (0x00A07462)
+
+#define BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */
+#define BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */
+#define BCR_GFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */
+#define BCR_CODEC_RST (1<<2) /* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */
+#define BCR_IRDA_FSEL (1<<3) /* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */
+#define BCR_IRDA_MD0 (1<<4) /* Range/Power select */
+#define BCR_IRDA_MD1 (1<<5) /* Range/Power select */
+#define BCR_STEREO_LB (1<<6) /* Stereo Loopback */
+#define BCR_CF_BUS_OFF (1<<7) /* Compact Flash bus (0 = on, 1 = off (float)) */
+#define BCR_AUDIO_ON (1<<8) /* Audio power on */
+#define BCR_LIGHT_ON (1<<9) /* Backlight */
+#define BCR_LCD_12RGB (1<<10) /* 0 = 16RGB, 1 = 12RGB */
+#define BCR_LCD_ON (1<<11) /* LCD power on */
+#define BCR_RS232EN (1<<12) /* RS232 transceiver enable */
+#define BCR_LED_RED (1<<13) /* D9 (0 = on, 1 = off) */
+#define BCR_LED_GREEN (1<<14) /* D8 (0 = on, 1 = off) */
+#define BCR_VIB_ON (1<<15) /* Vibration motor (quiet alert) */
+#define BCR_COM_DTR (1<<16) /* COMport Data Terminal Ready */
+#define BCR_COM_RTS (1<<17) /* COMport Request To Send */
+#define BCR_RAD_WU (1<<18) /* Radio wake up interrupt */
+#define BCR_SMB_EN (1<<19) /* System management bus enable */
+#define BCR_TV_IR_DEC (1<<20) /* TV IR Decode Enable */
+#define BCR_QMUTE (1<<21) /* Quick Mute */
+#define BCR_RAD_ON (1<<22) /* Radio Power On */
+#define BCR_SPK_OFF (1<<23) /* 1 = Speaker amplifier power off */
+
+#ifndef __ASSEMBLY__
+extern unsigned long SCR_value;
+extern unsigned long BCR_value;
+#define BCR_set( x ) BCR = (BCR_value |= (x))
+#define BCR_clear( x ) BCR = (BCR_value &= ~(x))
+#endif
+
+
+/* GPIOs for which the generic definition doesn't say much */
+#define GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */
+#define GPIO_L3_I2C_SDA GPIO_GPIO (15) /* L3 and SMB control ports */
+#define GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */
+#define GPIO_L3_MODE GPIO_GPIO (17) /* L3 mode signal with LED */
+#define GPIO_L3_I2C_SCL GPIO_GPIO (18) /* L3 and I2C control ports */
+#define GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */
+#define GPIO_CF_IRQ GPIO_GPIO (21) /* CF IRQ */
+#define GPIO_MBGNT GPIO_GPIO (21) /* 1111 MBGNT */
+#define GPIO_CF_CD GPIO_GPIO (22) /* CF CD */
+#define GPIO_MBREQ GPIO_GPIO (22) /* 1111 MBREQ */
+#define GPIO_UCB1300_IRQ GPIO_GPIO (23) /* UCB GPIO and touchscreen */
+#define GPIO_CF_BVD2 GPIO_GPIO (24) /* CF BVD */
+#define GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */
+#define GPIO_CF_BVD1 GPIO_GPIO (25) /* CF BVD */
+#define GPIO_NEP_IRQ GPIO_GPIO (25) /* Neponset IRQ */
+#define GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */
+#define GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */
+
+#define IRQ_GPIO_CF_IRQ IRQ_GPIO21
+#define IRQ_GPIO_CF_CD IRQ_GPIO22
+#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO23
+#define IRQ_GPIO_CF_BVD2 IRQ_GPIO24
+#define IRQ_GPIO_CF_BVD1 IRQ_GPIO25
+#define IRQ_GPIO_NEP_IRQ IRQ_GPIO25
+
+
+/*
+ * Neponset definitions:
+ */
+
+#define SA1111_BASE (0x40000000)
+
+#define NEPONSET_ETHERNET_IRQ MISC_IRQ0
+#define NEPONSET_USAR_IRQ MISC_IRQ1
+
+#define NEPONSET_CPLD_BASE (0x10000000)
+#define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xd4000000)
+#define Nep_v2p( x ) ((x) - 0xd4000000 + NEPONSET_CPLD_BASE)
+
+#define _IRR 0x10000024 /* Interrupt Reason Register */
+#define _AUD_CTL 0x100000c0 /* Audio controls (RW) */
+#define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */
+#define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */
+#define _NCR_0 0x100000a0 /* Control Register (RW) */
+#define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */
+#define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */
+#define _SWPK 0x10000020 /* Switch pack (RO) */
+#define _WHOAMI 0x10000000 /* System ID Register (RO) */
+
+#define _LEDS 0x10000010 /* LEDs [31:0] (WO) */
+
+#ifndef __ASSEMBLY__
+
+#define IRR (*((volatile u_char *) Nep_p2v(_IRR)))
+#define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL)))
+#define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0)))
+#define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1)))
+#define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0)))
+#define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT)))
+#define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN)))
+#define SWPK (*((volatile u_char *) Nep_p2v(_SWPK)))
+#define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI)))
+
+#define LEDS (*((volatile Word *) Nep_p2v(_LEDS)))
+
+#endif
+
+#define IRR_ETHERNET (1<<0)
+#define IRR_USAR (1<<1)
+#define IRR_SA1111 (1<<2)
+
+#define NCR_GP01_OFF (1<<0)
+#define NCR_TP_PWR_EN (1<<1)
+#define NCR_MS_PWR_EN (1<<2)
+#define NCR_ENET_OSC_EN (1<<3)
+#define NCR_SPI_KB_WK_UP (1<<4)
+#define NCR_A0VPP (1<<5)
+#define NCR_A1VPP (1<<6)
+
+#ifndef __ASSEMBLY__
+#define machine_has_neponset() ((SCR_value & SCR_SA1111) == 0)
+#endif
+
diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h
index e93cbe7d9e22fb..3b9ba67b5b641e 100644
--- a/include/asm-arm/arch-sa1100/hardware.h
+++ b/include/asm-arm/arch-sa1100/hardware.h
@@ -1,26 +1,113 @@
/*
- * linux/include/asm-arm/arch-brutus/hardware.h
+ * linux/include/asm-arm/arch-sa1100/hardware.h
*
* Copyright (C) 1998 Nicolas Pitre <nico@cam.org>
*
* This file contains the hardware definitions for SA1100 architecture
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for SA1111 added.
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
+#include <linux/config.h>
+
/* Flushing areas */
#define FLUSH_BASE_PHYS 0xe0000000 /* SA1100 zero bank */
#define FLUSH_BASE 0xdf000000
#define FLUSH_BASE_MINICACHE 0xdf800000
#define UNCACHEABLE_ADDR 0xfa050000
+
+/*
+ * We requires absolute addresses i.e. (0xe00000 + 0x3f8) for in*()/out*()
+ * macros to be useful for all cases.
+ */
+#define PCIO_BASE 0
+
+
+/*
+ * SA1100 internal I/O mappings
+ *
+ * We have the following mapping:
+ * phys virt
+ * 80000000 f8000000
+ * 90000000 fa000000
+ * a0000000 fc000000
+ * b0000000 fe000000
+ *
+ * Nb: PCMCIA is mapped from 0xe0000000 to f7ffffff in mm-sa1100.c
+ */
+
+#define VIO_BASE 0xf8000000 /* virtual start of IO space */
+#define VIO_SHIFT 3 /* x = IO space shrink power */
+#define PIO_START 0x80000000 /* physical start of IO space */
+
+#define io_p2v( x ) \
+ ( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE )
+#define io_v2p( x ) \
+ ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
+
+#include "SA-1100.h"
+
+
+/*
+ * SA1100 GPIO edge detection for IRQs:
+ * IRQs are generated on Falling-Edge, Rising-Edge, or both.
+ * This must be called *before* the corresponding IRQ is registered.
+ * Use this instead of directly setting GRER/GFER.
+ */
+#define GPIO_FALLING_EDGE 1
+#define GPIO_RISING_EDGE 2
+#define GPIO_BOTH_EDGES 3
+#ifndef __ASSEMBLY__
+extern void set_GPIO_IRQ_edge( int gpio_mask, int edge_mask );
+#endif
+
+
+/*
+ * Implementation specifics
+ */
+
+#ifdef CONFIG_SA1100_ASSABET
+#include "assabet.h"
+#else
+#define machine_has_neponset() (0)
+#endif
+
+#ifdef CONFIG_SA1100_EMPEG
+#include "empeg.h"
+#endif
+
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
+#include "thinclient.h"
+#endif
+
+
+#ifdef CONFIG_SA1101
+
/*
- * PCMCIA IO is mapped to 0xe0000000. We are likely to use in*()/out*()
- * IO macros for what might appear there...
- * The SA1100 PCMCIA interface can be seen like a PC ISA bus for IO.
+ * We have mapped the sa1101 depending on the value of SA1101_BASE.
+ * It then appears from 0xdc000000.
*/
-#define PCIO_BASE 0xe0000000 /* PCMCIA0 IO space */
+
+#define SA1101_p2v( x ) ((x) - SA1101_BASE + 0xdc000000)
+#define SA1101_v2p( x ) ((x) - 0xdc000000 + SA1101_BASE)
+
+#include "SA-1101.h"
+
+#endif
+
+
+#ifdef CONFIG_SA1111
+
+#define SA1111_p2v( x ) ((x) - SA1111_BASE + 0xd8000000)
+#define SA1111_v2p( x ) ((x) - 0xd8000000 + SA1111_BASE)
+
+#include "SA-1111.h"
#endif
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-sa1100/irq.h b/include/asm-arm/arch-sa1100/irq.h
index 3289801ac77744..6f447f497badd8 100644
--- a/include/asm-arm/arch-sa1100/irq.h
+++ b/include/asm-arm/arch-sa1100/irq.h
@@ -11,106 +11,296 @@
* 17-02-1999 NP empeg henry ugly hacks now in a separate file ;)
* 11-08-1999 PD SA1101 support added
* 25-09-1999 RMK Merged into main ARM tree, cleaned up
+ * 12-05-2000 NP IRQ dispatcher handler for GPIO 11 to 27.
+ * 26-05-2000 JD SA-1111 support added
*/
#include <linux/config.h>
-static inline unsigned int fixup_irq(unsigned int irq)
+#define fixup_irq(x) (x)
+
+/*
+ * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
+ * this is for internal IRQs i.e. from 11 to 31.
+ */
+
+static void sa1100_mask_irq(unsigned int irq)
{
-#ifdef CONFIG_SA1101
- if (irq == SA1101_IRQ) {
- unsigned long mask;
- mask = INTSTATCLR0 & INTENABLE0;
- irq = 32;
- if (!mask) {
- mask = IRQSTATCLR1 & INTENABLE1;
- irq = 64;
- }
- if (mask)
- while ((mask & 1) == 0) {
- mask >>= 1;
- irq += 1;
- }
- }
-#endif
- return irq;
+ ICMR &= ~(1 << irq);
+}
+
+static void sa1100_unmask_irq(unsigned int irq)
+{
+ ICMR |= (1 << irq);
}
-/* We don't need to ACK IRQs on the SA1100 unless they're <= 10,
- * ie, an edge-detect.
+/*
+ * SA1100 GPIO edge detection for IRQs.
*/
-static void sa1100_mask_and_ack_irq(unsigned int irq)
+extern int GPIO_IRQ_rising_edge;
+extern int GPIO_IRQ_falling_edge;
+
+/*
+ * GPIO IRQs must be acknoledged. This is for IRQs from 0 to 10.
+ */
+
+static void sa1100_mask_and_ack_GPIO0_10_irq(unsigned int irq)
{
ICMR &= ~(1 << irq);
- if (irq <= 10)
- GEDR = 1 << irq;
+ GEDR = (1 << irq);
}
-static void sa1100_mask_irq(unsigned int irq)
+static void sa1100_mask_GPIO0_10_irq(unsigned int irq)
{
ICMR &= ~(1 << irq);
}
-static void sa1100_unmask_irq(unsigned int irq)
+static void sa1100_unmask_GPIO0_10_irq(unsigned int irq)
+{
+ GRER = (GRER & ~(1 << irq)) | (GPIO_IRQ_rising_edge & (1 << irq));
+ GFER = (GFER & ~(1 << irq)) | (GPIO_IRQ_falling_edge & (1 << irq));
+ ICMR |= (1 << irq);
+}
+
+/*
+ * Install handler for GPIO 11-27 edge detect interrupts
+ */
+
+void do_IRQ(int irq, struct pt_regs * regs);
+
+static int GPIO_11_27_enabled; /* enabled i.e. unmasked GPIO IRQs */
+static int GPIO_11_27_spurious; /* GPIOs that triggered when masked */
+
+static void sa1100_GPIO11_27_demux(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ int i, irq, spurious;
+
+ while( (irq = (GEDR & 0xfffff800)) ){
+ /*
+ * We don't want to clear GRER/GFER when the corresponding
+ * IRQ is masked because we could miss a level transition
+ * i.e. an IRQ which need servicing as soon as it is
+ * unmasked. However, such situation should happen only
+ * during the loop below. Thus all IRQs which aren't
+ * enabled at this point are considered spurious. Those
+ * are cleared but only de-activated if they happened twice.
+ */
+ spurious = irq & ~GPIO_11_27_enabled;
+ if (spurious) {
+ GEDR = spurious;
+ GRER &= ~(spurious & GPIO_11_27_spurious);
+ GFER &= ~(spurious & GPIO_11_27_spurious);
+ GPIO_11_27_spurious |= spurious;
+ irq ^= spurious;
+ if (!irq) continue;
+ }
+
+ for (i = 11; i <= 27; ++i) {
+ if (irq & (1<<i)) {
+ do_IRQ( IRQ_GPIO_11_27(i), regs );
+ }
+ }
+ }
+}
+
+static struct irqaction GPIO11_27_irq = {
+ name: "GPIO 11-27",
+ handler: sa1100_GPIO11_27_demux,
+ flags: SA_INTERRUPT
+};
+
+static void sa1100_mask_and_ack_GPIO11_27_irq(unsigned int irq)
+{
+ int mask = (1 << GPIO_11_27_IRQ(irq));
+ GPIO_11_27_enabled &= ~mask;
+ GEDR = mask;
+}
+
+static void sa1100_mask_GPIO11_27_irq(unsigned int irq)
+{
+ GPIO_11_27_enabled &= ~(1 << GPIO_11_27_IRQ(irq));
+}
+
+static void sa1100_unmask_GPIO11_27_irq(unsigned int irq)
{
- ICMR |= 1 << irq;
+ int mask = (1 << GPIO_11_27_IRQ(irq));
+ GPIO_11_27_enabled |= mask;
+ GPIO_11_27_spurious &= ~mask;
+ GRER = (GRER & ~mask) | (GPIO_IRQ_rising_edge & mask);
+ GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask);
}
-#ifdef CONFIG_SA1101
-static void sa1101_mask_and_ack_lowirq(unsigned int irq)
+#if defined(CONFIG_SA1111)
+
+/*
+ * Install handler for SA1111 IRQ handler.
+ */
+
+static void sa1111_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
{
- unsigned int mask = 1 << (irq & 31);
+ int i;
+ unsigned long stat0, stat1;
+
+ while( (stat0 = INTSTATCLR0) && (stat1 = INTSTATCLR1) ){
+ if( stat0 )
+ for( i = 0; i < 32; i++ )
+ if( stat0 & (1<<i) )
+ do_IRQ( SA1111_IRQ(i), regs );
- INTENABLE0 &= ~mask;
- GEDR = 1 << SA1101_IRQ;
+ if( stat1 )
+ for( i = 32; i < 55; i++ )
+ if( stat1 & (1<<(i-32)) )
+ do_IRQ( SA1111_IRQ(i), regs );
+ }
+}
+
+static struct irqaction sa1111_irq = {
+ name: "SA1111",
+ handler: sa1111_IRQ_demux,
+ flags: SA_INTERRUPT
+};
+
+static void sa1111_mask_and_ack_lowirq(unsigned int irq)
+{
+ unsigned int mask = 1 << (irq - SA1111_IRQ(0));
+
+ //INTEN0 &= ~mask;
INTSTATCLR0 = mask;
}
-static void sa1101_mask_and_ack_highirq(unsigned int irq)
+static void sa1111_mask_and_ack_highirq(unsigned int irq)
{
- unsigned int mask = 1 << (irq & 31);
+ unsigned int mask = 1 << (irq - SA1111_IRQ(32));
- INTENABLE1 &= ~mask;
- GEDR = 1 << SA1101_IRQ;
+ //INTEN1 &= ~mask;
INTSTATCLR1 = mask;
}
-static void sa1101_mask_lowirq(unsigned int irq)
+static void sa1111_mask_lowirq(unsigned int irq)
{
- unsigned int mask = 1 << (irq & 31);
+ //INTEN0 &= ~(1 << (irq - SA1111_IRQ(0)));
+}
- INTENABLE0 &= ~mask;
+static void sa1111_mask_highirq(unsigned int irq)
+{
+ //INTEN1 &= ~(1 << (irq - SA1111_IRQ(32)));
}
-static void sa1101_mask_highirq(unsigned int irq)
+static void sa1111_unmask_lowirq(unsigned int irq)
+{
+ INTEN0 |= 1 << (irq - SA1111_IRQ(0));
+}
+
+static void sa1111_unmask_highirq(unsigned int irq)
+{
+ INTEN1 |= 1 << ((irq - SA1111_IRQ(32)));
+}
+
+#endif /* CONFIG_SA1111 */
+
+
+#ifdef CONFIG_ASSABET_NEPONSET
+
+/*
+ * Install handler for Neponset IRQ. Yes, yes... we are way down the IRQ
+ * cascade which is not good for IRQ latency, but the hardware has been
+ * designed that way...
+ */
+
+static void neponset_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
{
- unsigned int mask = 1 << (irq & 31);
+ int irr;
- INTENABLE1 &= ~mask;
+ for(;;){
+ irr = IRR & (IRR_ETHERNET | IRR_USAR | IRR_SA1111);
+ /* Let's have all active IRQ bits high.
+ * Note: there is a typo in the Neponset user's guide
+ * for the SA1111 IRR level.
+ */
+ irr ^= (IRR_ETHERNET | IRR_USAR);
+ if (!irr) break;
+
+ if( irr & IRR_ETHERNET )
+ do_IRQ(NEPONSET_ETHERNET_IRQ, regs);
+
+ if( irr & IRR_USAR )
+ do_IRQ(NEPONSET_USAR_IRQ, regs);
+
+ if( irr & IRR_SA1111 )
+ sa1111_IRQ_demux(irq, dev_id, regs);
+ }
}
+static struct irqaction neponset_irq = {
+ name: "Neponset",
+ handler: neponset_IRQ_demux,
+ flags: SA_INTERRUPT
+};
+
+#endif
+
+
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
+
/*
- * unmasking an IRq with the wrong polarity can be
- * fatal, but there is no need to check this in the
- * interrupt code - it will be spotted anyway ;-)
+ * IRQ handler for the ThinClient/GraphicsClient external IRQ controller
*/
-static void sa1101_unmask_lowirq(unsigned int irq)
+
+static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
{
- unsigned int mask = 1 << (irq & 31);
+ int irq, i;
- INTENABLE0 |= mask;
- ICMR |= 1 << SA1101_IRQ;
+ while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
+ for( i = 0; i < 16; i++ )
+ if( irq & (1<<i) )
+ do_IRQ( ADS_EXT_IRQ(i), regs );
+ }
}
-static void sa1101_unmask_highirq(unsigned int irq)
+static struct irqaction ADS_ext_irq = {
+ name: "ADS_ext_IRQ",
+ handler: ADS_IRQ_demux,
+ flags: SA_INTERRUPT
+};
+
+static void ADS_mask_and_ack_irq0(unsigned int irq)
{
- unsigned int mask = 1 << (irq & 31);
+ int mask = (1 << (irq - ADS_EXT_IRQ(0)));
+ ADS_INT_EN1 &= ~mask;
+ ADS_INT_ST1 = mask;
+}
+
+static void ADS_mask_irq0(unsigned int irq)
+{
+ ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
+}
- INTENABLE1 |= mask;
- ICMR |= 1 << SA1101_IRQ;
+static void ADS_unmask_irq0(unsigned int irq)
+{
+ ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
+}
+
+static void ADS_mask_and_ack_irq1(unsigned int irq)
+{
+ int mask = (1 << (irq - ADS_EXT_IRQ(8)));
+ ADS_INT_EN2 &= ~mask;
+ ADS_INT_ST2 = mask;
}
+
+static void ADS_mask_irq1(unsigned int irq)
+{
+ ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
+}
+
+static void ADS_unmask_irq1(unsigned int irq)
+{
+ ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
+}
+
#endif
+
static __inline__ void irq_init_irq(void)
{
int irq;
@@ -122,64 +312,116 @@ static __inline__ void irq_init_irq(void)
ICLR = 0;
/* clear all GPIO edge detects */
+ GFER = 0;
+ GRER = 0;
GEDR = -1;
-#ifdef CONFIG_SA1101
- /* turn on interrupt controller */
- SKPCR |= 4;
-
- /* disable all IRQs */
- INTENABLE0 = 0;
- INTENABLE1 = 0;
-
- /* detect on rising edge */
- INTPOL0 = 0;
- INTPOL1 = 0;
-
- /* clear all IRQs */
- INTSTATCLR0 = -1;
- INTSTATCLR1 = -1;
-
- /* SA1101 generates a rising edge */
- GRER |= 1 << SA1101_IRQ;
- GPER &= ~(1 << SA1101_IRQ);
-#endif
-
/*
* Whatever the doc says, this has to be set for the wait-on-irq
* instruction to work... on a SA1100 rev 9 at least.
*/
ICCR = 1;
-#ifndef CONFIG_SA1101
- for (irq = 0; irq < NR_IRQS; irq++) {
+ for (irq = 0; irq <= 10; irq++) {
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
- irq_desc[irq].mask_ack = sa1100_mask_and_ack_irq;
- irq_desc[irq].mask = sa1100_mask_irq;
- irq_desc[irq].unmask = sa1100_unmask_irq;
+ irq_desc[irq].mask_ack = sa1100_mask_and_ack_GPIO0_10_irq;
+ irq_desc[irq].mask = sa1100_mask_GPIO0_10_irq;
+ irq_desc[irq].unmask = sa1100_unmask_GPIO0_10_irq;
}
-#else
- for (irq = 0; irq < 31; irq++) {
+
+ for (irq = 11; irq <= 31; irq++) {
irq_desc[irq].valid = 1;
- irq_desc[irq].probe_ok = 1;
- irq_desc[irq].mask_ack = sa1100_mask_and_ack_irq;
+ irq_desc[irq].probe_ok = 0;
+ irq_desc[irq].mask_ack = sa1100_mask_irq;
irq_desc[irq].mask = sa1100_mask_irq;
irq_desc[irq].unmask = sa1100_unmask_irq;
}
- for (irq = 32; irq < 63; irq++) {
+
+ for (irq = 32; irq <= 48; irq++) {
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
- irq_desc[irq].mask_ack = sa1101_mask_and_ack_lowirq;
- irq_desc[irq].mask = sa1101_mask_lowirq;
- irq_desc[irq].unmask = sa1101_unmask_lowirq;
+ irq_desc[irq].mask_ack = sa1100_mask_and_ack_GPIO11_27_irq;
+ irq_desc[irq].mask = sa1100_mask_GPIO11_27_irq;
+ irq_desc[irq].unmask = sa1100_unmask_GPIO11_27_irq;
}
- for (irq = 64; irq < NR_IRQS; irq++) {
- irq_desc[irq].valid = 1;
- irq_desc[irq].probe_ok = 1;
- irq_desc[irq].mask_ack = sa1101_mask_and_ack_highirq;
- irq_desc[irq].mask = sa1101_mask_highirq;
- irq_desc[irq].unmask = sa1101_unmask_highirq;
+ setup_arm_irq( IRQ_GPIO11_27, &GPIO11_27_irq );
+
+#ifdef CONFIG_SA1111
+ if( machine_is_assabet() && machine_has_neponset() ){
+
+ /* disable all IRQs */
+ INTEN0 = 0;
+ INTEN1 = 0;
+
+ /* detect on rising edge */
+ INTPOL0 = 0;
+ INTPOL1 = 0;
+
+ /* clear all IRQs */
+ INTSTATCLR0 = -1;
+ INTSTATCLR1 = -1;
+
+ for (irq = SA1111_IRQ(0); irq <= SA1111_IRQ(26); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = sa1111_mask_and_ack_lowirq;
+ irq_desc[irq].mask = sa1111_mask_lowirq;
+ irq_desc[irq].unmask = sa1111_unmask_lowirq;
+ }
+ for (irq = SA1111_IRQ(32); irq <= SA1111_IRQ(54); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = sa1111_mask_and_ack_highirq;
+ irq_desc[irq].mask = sa1111_mask_highirq;
+ irq_desc[irq].unmask = sa1111_unmask_highirq;
+ }
+
+ if( machine_has_neponset() ){
+ /* setup extra Neponset IRQs */
+ irq = NEPONSET_ETHERNET_IRQ;
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq = NEPONSET_USAR_IRQ;
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ set_GPIO_IRQ_edge( GPIO_NEP_IRQ, GPIO_RISING_EDGE );
+ setup_arm_irq( IRQ_GPIO_NEP_IRQ, &neponset_irq );
+ }else{
+ /* for pure SA1111 designs to come (currently unused) */
+ set_GPIO_IRQ_edge( 0, GPIO_RISING_EDGE );
+ setup_arm_irq( -1, &sa1111_irq );
+ }
}
#endif
+
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
+ if( machine_is_graphicsclient() || machine_is_thinclient() ){
+ /* disable all IRQs */
+ ADS_INT_EN1 = 0;
+ ADS_INT_EN2 = 0;
+ /* clear all IRQs */
+ ADS_INT_ST1 = 0xff;
+ ADS_INT_ST2 = 0xff;
+
+ for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = ADS_mask_and_ack_irq0;
+ irq_desc[irq].mask = ADS_mask_irq0;
+ irq_desc[irq].unmask = ADS_unmask_irq0;
+ }
+ for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = ADS_mask_and_ack_irq1;
+ irq_desc[irq].mask = ADS_mask_irq1;
+ irq_desc[irq].unmask = ADS_unmask_irq1;
+ }
+ GPDR &= ~GPIO_GPIO0;
+ set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
+ setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
+ }
+#endif
+
}
diff --git a/include/asm-arm/arch-sa1100/irqs.h b/include/asm-arm/arch-sa1100/irqs.h
index 246ad93442a714..909247f72a751d 100644
--- a/include/asm-arm/arch-sa1100/irqs.h
+++ b/include/asm-arm/arch-sa1100/irqs.h
@@ -3,110 +3,151 @@
*
* Copyright (C) 1996 Russell King
* Copyright (C) 1998 Deborah Wallach (updates for SA1100/Brutus).
+ * Copyright (C) 1999 Nicolas Pitre (full GPIO irq isolation)
*/
+
#include <linux/config.h>
-#ifdef CONFIG_SA1101
-#define NR_IRQS 95
-
-#define GPAIN0 32
-#define GPAIN1 33
-#define GPAIN2 34
-#define GPAIN3 35
-#define GPAIN4 36
-#define GPAIN5 37
-#define GPAIN6 38
-#define GPAIN7 39
-#define GPBIN0 40
-#define GPBIN1 41
-#define GPBIN2 42
-#define GPBIN3 43
-#define GPBIN4 44
-#define GPBIN5 45
-#define GPBIN6 46
-#define RESERVED 47
-#define KPXIN0 48
-#define KPXIN1 49
-#define KPXIN2 50
-#define KPXIN3 51
-#define KPXIN4 52
-#define KPXIN5 53
-#define KPXIN6 54
-#define KPXIN7 55
-#define KPYIN0 56
-#define KPYIN1 57
-#define KPYIN2 58
-#define KPYIN3 59
-#define KPYIN4 60
-#define KPYIN5 61
-#define KPYIN6 62
-#define KPYIN7 63
-#define KPYIN8 64
-#define KPYIN9 65
-#define KPYIN10 66
-#define KPYIN11 67
-#define KPYIN12 68
-#define KPYIN13 69
-#define KPYIN14 70
-#define KPYIN15 71
-#define MSTXINT 72
-#define MSRXINT 73
-#define TPTXINT 74
-#define TPRXINT 75
-#define INTREQTRC 76
-#define INTREQTIM 77
-#define INTREQRAV 78
-#define INTREQINT 79
-#define INTREQEMP 80
-#define INTREQDAT 81
-#define VIDEOINT 82
-#define FIFOINT 83
-#define NIRQHCIM 84
-#define IRQHCIBUFFACC 85
-#define IRQHCIRMTWKP 86
-#define NHCIMFCLIR 87
-#define USBERROR 88
-#define S0_READY_NIREQ 89
-#define S1_READY_NIREQ 90
-#define S0_CDVALID 91
-#define S1_CDVALID 92
-#define S0_BVD1_STSCHG 93
-#define S1_BVD1_STSCHG 94
-#define USB_PORT_RESUME 95
-
-#else
-#define NR_IRQS 32
+#define SA1100_IRQ(x) (0 + (x))
+
+#define IRQ_GPIO0 SA1100_IRQ(0)
+#define IRQ_GPIO1 SA1100_IRQ(1)
+#define IRQ_GPIO2 SA1100_IRQ(2)
+#define IRQ_GPIO3 SA1100_IRQ(3)
+#define IRQ_GPIO4 SA1100_IRQ(4)
+#define IRQ_GPIO5 SA1100_IRQ(5)
+#define IRQ_GPIO6 SA1100_IRQ(6)
+#define IRQ_GPIO7 SA1100_IRQ(7)
+#define IRQ_GPIO8 SA1100_IRQ(8)
+#define IRQ_GPIO9 SA1100_IRQ(9)
+#define IRQ_GPIO10 SA1100_IRQ(10)
+#define IRQ_GPIO11_27 SA1100_IRQ(11)
+#define IRQ_LCD SA1100_IRQ(12) /* LCD controller */
+#define IRQ_Ser0UDC SA1100_IRQ(13) /* Ser. port 0 UDC */
+#define IRQ_Ser1SDLC SA1100_IRQ(14) /* Ser. port 1 SDLC */
+#define IRQ_Ser1UART SA1100_IRQ(15) /* Ser. port 1 UART */
+#define IRQ_Ser2ICP SA1100_IRQ(16) /* Ser. port 2 ICP */
+#define IRQ_Ser3UART SA1100_IRQ(17) /* Ser. port 3 UART */
+#define IRQ_Ser4MCP SA1100_IRQ(18) /* Ser. port 4 MCP */
+#define IRQ_Ser4SSP SA1100_IRQ(19) /* Ser. port 4 SSP */
+#define IRQ_DMA0 SA1100_IRQ(20) /* DMA controller channel 0 */
+#define IRQ_DMA1 SA1100_IRQ(21) /* DMA controller channel 1 */
+#define IRQ_DMA2 SA1100_IRQ(22) /* DMA controller channel 2 */
+#define IRQ_DMA3 SA1100_IRQ(23) /* DMA controller channel 3 */
+#define IRQ_DMA4 SA1100_IRQ(24) /* DMA controller channel 4 */
+#define IRQ_DMA5 SA1100_IRQ(25) /* DMA controller channel 5 */
+#define IRQ_OST0 SA1100_IRQ(26) /* OS Timer match 0 */
+#define IRQ_OST1 SA1100_IRQ(27) /* OS Timer match 1 */
+#define IRQ_OST2 SA1100_IRQ(28) /* OS Timer match 2 */
+#define IRQ_OST3 SA1100_IRQ(29) /* OS Timer match 3 */
+#define IRQ_RTC1Hz SA1100_IRQ(30) /* RTC 1 Hz clock */
+#define IRQ_RTCAlrm SA1100_IRQ(31) /* RTC Alarm */
+
+#define IRQ_GPIO_11_27(x) (32 + (x) - 11)
+
+#define IRQ_GPIO11 IRQ_GPIO_11_27(11)
+#define IRQ_GPIO12 IRQ_GPIO_11_27(12)
+#define IRQ_GPIO13 IRQ_GPIO_11_27(13)
+#define IRQ_GPIO14 IRQ_GPIO_11_27(14)
+#define IRQ_GPIO15 IRQ_GPIO_11_27(15)
+#define IRQ_GPIO16 IRQ_GPIO_11_27(16)
+#define IRQ_GPIO17 IRQ_GPIO_11_27(17)
+#define IRQ_GPIO18 IRQ_GPIO_11_27(18)
+#define IRQ_GPIO19 IRQ_GPIO_11_27(19)
+#define IRQ_GPIO20 IRQ_GPIO_11_27(20)
+#define IRQ_GPIO21 IRQ_GPIO_11_27(21)
+#define IRQ_GPIO22 IRQ_GPIO_11_27(22)
+#define IRQ_GPIO23 IRQ_GPIO_11_27(23)
+#define IRQ_GPIO24 IRQ_GPIO_11_27(24)
+#define IRQ_GPIO25 IRQ_GPIO_11_27(25)
+#define IRQ_GPIO26 IRQ_GPIO_11_27(26)
+#define IRQ_GPIO27 IRQ_GPIO_11_27(27)
+
+#define SA1100_GPIO_TO_IRQ(i) (((i) < 11) ? SA1100_IRQ(i) : IRQ_GPIO_11_27(i))
+
+/* To get the GPIO number from an IRQ number */
+#define GPIO_11_27_IRQ(i) (11 + (i) - 32)
+#define SA1100_IRQ_TO_GPIO(i) (((i) < 11) ? (i) : GPIO_11_27_IRQ(i))
+
+#define NR_IRQS (IRQ_GPIO27 + 1)
+
+
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
+#define ADS_EXT_IRQ(x) (IRQ_GPIO27 + 1 + (x))
+#undef NR_IRQS
+#define NR_IRQS (ADS_EXT_IRQ(15) + 1)
#endif
-#define IRQ_GPIO0 0
-#define IRQ_GPIO1 1
-#define IRQ_GPIO2 2
-#define IRQ_GPIO3 3
-#define IRQ_GPIO4 4
-#define IRQ_GPIO5 5
-#define IRQ_GPIO6 6
-#define IRQ_GPIO7 7
-#define IRQ_GPIO8 8
-#define IRQ_GPIO9 9
-#define IRQ_GPIO10 10
-#define IRQ_GPIO11_27 11
-#define IRQ_LCD 12 /* LCD controller */
-#define IRQ_Ser0UDC 13 /* Ser. port 0 UDC */
-#define IRQ_Ser1SDLC 14 /* Ser. port 1 SDLC */
-#define IRQ_Ser1UART 15 /* Ser. port 1 UART */
-#define IRQ_Ser2ICP 16 /* Ser. port 2 ICP */
-#define IRQ_Ser3UART 17 /* Ser. port 3 UART */
-#define IRQ_Ser4MCP 18 /* Ser. port 4 MCP */
-#define IRQ_Ser4SSP 19 /* Ser. port 4 SSP */
-#define IRQ_DMA0 20 /* DMA controller channel 0 */
-#define IRQ_DMA1 21 /* DMA controller channel 1 */
-#define IRQ_DMA2 22 /* DMA controller channel 2 */
-#define IRQ_DMA3 23 /* DMA controller channel 3 */
-#define IRQ_DMA4 24 /* DMA controller channel 4 */
-#define IRQ_DMA5 25 /* DMA controller channel 5 */
-#define IRQ_OST0 26 /* OS Timer match 0 */
-#define IRQ_OST1 27 /* OS Timer match 1 */
-#define IRQ_OST2 28 /* OS Timer match 2 */
-#define IRQ_OST3 29 /* OS Timer match 3 */
-#define IRQ_RTC1Hz 30 /* RTC 1 Hz clock */
-#define IRQ_RTCAlrm 31 /* RTC Alarm */
+
+#if defined(CONFIG_SA1111)
+
+#define SA1111_IRQ(x) (IRQ_GPIO27 + 1 + (x))
+
+#define GPAIN0 SA1111_IRQ(0)
+#define GPAIN1 SA1111_IRQ(1)
+#define GPAIN2 SA1111_IRQ(2)
+#define GPAIN3 SA1111_IRQ(3)
+#define GPBIN0 SA1111_IRQ(4)
+#define GPBIN1 SA1111_IRQ(5)
+#define GPBIN2 SA1111_IRQ(6)
+#define GPBIN3 SA1111_IRQ(7)
+#define GPBIN4 SA1111_IRQ(8)
+#define GPBIN5 SA1111_IRQ(9)
+#define GPCIN0 SA1111_IRQ(10)
+#define GPCIN1 SA1111_IRQ(11)
+#define GPCIN2 SA1111_IRQ(12)
+#define GPCIN3 SA1111_IRQ(13)
+#define GPCIN4 SA1111_IRQ(14)
+#define GPCIN5 SA1111_IRQ(15)
+#define GPCIN6 SA1111_IRQ(16)
+#define GPCIN7 SA1111_IRQ(17)
+#define MSTXINT SA1111_IRQ(18)
+#define MSRXINT SA1111_IRQ(19)
+#define MSSTOPERRINT SA1111_IRQ(20)
+#define TPTXINT SA1111_IRQ(21)
+#define TPRXINT SA1111_IRQ(22)
+#define TPSTOPERRINT SA1111_IRQ(23)
+#define SSPXMTINT SA1111_IRQ(24)
+#define SSPRCVINT SA1111_IRQ(25)
+#define SSPROR SA1111_IRQ(26)
+#define AUDXMTDMADONEA SA1111_IRQ(32)
+#define AUDRCVDMADONEA SA1111_IRQ(33)
+#define AUDXMTDMADONEB SA1111_IRQ(34)
+#define AUDRCVDMADONEB SA1111_IRQ(35)
+#define AUDTFSR SA1111_IRQ(36)
+#define AUDRFSR SA1111_IRQ(37)
+#define AUDTUR SA1111_IRQ(38)
+#define AUDROR SA1111_IRQ(39)
+#define AUDDTS SA1111_IRQ(40)
+#define AUDRDD SA1111_IRQ(41)
+#define AUDSTO SA1111_IRQ(42)
+#define USBPWR SA1111_IRQ(43)
+#define NIRQHCIM SA1111_IRQ(44)
+#define IRQHCIBUFFACC SA1111_IRQ(45)
+#define IRQHCIRMTWKP SA1111_IRQ(46)
+#define NHCIMFCIR SA1111_IRQ(47)
+#define USB_PORT_RESUME SA1111_IRQ(48)
+#define S0_READY_NINT SA1111_IRQ(49)
+#define S1_READY_NINT SA1111_IRQ(50)
+#define S0_CD_VALID SA1111_IRQ(51)
+#define S1_CD_VALID SA1111_IRQ(52)
+#define S0_BVD1_STSCHG SA1111_IRQ(53)
+#define S1_BVD1_STSCHG SA1111_IRQ(54)
+
+#define SA1111_IRQ_MAX SA1111_IRQ(54)
+
+#undef NR_IRQS
+#define NR_IRQS (SA1111_IRQ_MAX + 1)
+
+
+#ifdef CONFIG_ASSABET_NEPONSET
+
+#define MISC_IRQ0 SA1111_IRQ(55)
+#define MISC_IRQ1 SA1111_IRQ(56)
+
+#undef NR_IRQS
+#define NR_IRQS (SA1111_IRQ_MAX + 3)
+
+#endif /* CONFIG_ASSABET_NEPONSET */
+
+#endif /* CONFIG_SA1111 */
diff --git a/include/asm-arm/arch-sa1100/mmzone.h b/include/asm-arm/arch-sa1100/mmzone.h
new file mode 100644
index 00000000000000..b7abea6f778ba7
--- /dev/null
+++ b/include/asm-arm/arch-sa1100/mmzone.h
@@ -0,0 +1,81 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/mmzone.h
+ *
+ * (C) 1999-2000, Nicolas Pitre <nico@cam.org>
+ * (inspired by Kanoj Sarcar's code)
+ *
+ * Because of the wide memory address space between physical RAM banks on the
+ * SA1100, it's much convenient to use Linux's NUMA support to implement our
+ * memory map representation. Assuming all memory nodes have equal access
+ * characteristics, we then have generic discontigous memory support.
+ *
+ * Of course, all this isn't mandatory for SA1100 implementations with only
+ * one used memory bank. For those, simply undefine CONFIG_DISCONTIGMEM.
+ */
+
+
+/*
+ * Currently defined in arch/arm/mm/mm-sa1100.c
+ */
+extern pg_data_t sa1100_node_data[];
+
+/*
+ * 32MB max in each bank, must fit with __virt_to_phys() & __phys_to_virt()
+ */
+#define NODE_MAX_MEM_SHIFT 25
+#define NODE_MAX_MEM_SIZE (1<<NODE_MAX_MEM_SHIFT)
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(addr) \
+ (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
+
+/*
+ * Return a pointer to the node data for node n.
+ */
+#define NODE_DATA(nid) (&sa1100_node_data[nid])
+
+/*
+ * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
+ */
+#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
+
+/*
+ * Given a mem_map_t, LOCAL_MAP_BASE finds the owning node for the
+ * physical page and returns the kaddr for the mem_map of that node.
+ */
+#define LOCAL_MAP_BASE(page) \
+ NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(page)))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) \
+ NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+
+/*
+ * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
+ * and returns the kaddr corresponding to first physical page in the
+ * node's mem_map.
+ */
+#define LOCAL_BASE_ADDR(kaddr) ((unsigned long)(kaddr) & ~(NODE_MAX_MEM_SIZE-1))
+
+/*
+ * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
+ * and returns the index corresponding to the appropriate page in the
+ * node's mem_map.
+ */
+#define LOCAL_MAP_NR(kvaddr) \
+ (((unsigned long)(kvaddr)-LOCAL_BASE_ADDR((kvaddr))) >> PAGE_SHIFT)
+
+/*
+ * With discontigmem, the conceptual mem_map array starts from PAGE_OFFSET.
+ * Given a kaddr, MAP_NR returns the appropriate global mem_map index so
+ * it matches the corresponding node's local mem_map.
+ */
+#define MAP_NR(kaddr) (LOCAL_MAP_NR((kaddr)) + \
+ (((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \
+ sizeof(mem_map_t)))
+
diff --git a/include/asm-arm/arch-sa1100/time.h b/include/asm-arm/arch-sa1100/time.h
index 205a317a01703a..4adca24559f428 100644
--- a/include/asm-arm/arch-sa1100/time.h
+++ b/include/asm-arm/arch-sa1100/time.h
@@ -9,9 +9,6 @@
*
*/
-#include <asm/arch/hardware.h>
-#include <asm/arch/irqs.h>
-
/* IRQs are disabled before entering here from do_gettimeofday() */
static unsigned long sa1100_gettimeoffset (void)
@@ -33,16 +30,22 @@ static unsigned long sa1100_gettimeoffset (void)
static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+ long flags;
int next_match;
/* Loop until we get ahead of the free running timer.
* This ensures an exact clock tick count and time acuracy.
- * Should be IRQ race free.
+ * IRQs are disabled inside the loop to ensure coherence between
+ * lost_ticks (updated in do_timer()) and the match reg value, so we
+ * can use do_gettimeofday() from interrupt handlers.
*/
do {
+ do_leds();
+ save_flags_cli( flags );
do_timer(regs);
OSSR = OSSR_M0; /* Clear match on timer 0 */
next_match = (OSMR0 += LATCH);
+ restore_flags( flags );
} while( (signed long)(next_match - OSCR) <= 0 );
}
diff --git a/include/asm-arm/arch-sa1100/uncompress.h b/include/asm-arm/arch-sa1100/uncompress.h
index 33ced71ba995a6..69b3140d3e2004 100644
--- a/include/asm-arm/arch-sa1100/uncompress.h
+++ b/include/asm-arm/arch-sa1100/uncompress.h
@@ -2,58 +2,51 @@
* linux/include/asm-arm/arch-brutus/uncompress.h
*
* (C) 1999 Nicolas Pitre <nico@cam.org>
+ *
+ * Reorganised to use machine_is_*() macros.
*/
-#include <linux/config.h>
-
-#if defined(CONFIG_SA1100_EMPEG) || \
- defined(CONFIG_SA1100_VICTOR) || \
- defined(CONFIG_SA1100_LART)
-#define SERBASE _Ser3UTCR0;
-#elif defined(CONFIG_SA1100_BRUTUS)
-#define SERBASE _Ser1UTCR0;
-#endif
-
-
-#ifdef SERBASE
-
#include "hardware.h"
#include "serial_reg.h"
-static volatile unsigned long* serial_port = (unsigned long*)SERBASE;
-
/*
* The following code assumes the serial port has already been
* initialized by the bootloader or such...
*/
-
static void puts( const char *s )
{
- int i;
-
- for (i = 0; *s; i++, s++) {
- /* wait for space in the UART's transmiter */
- while( !(serial_port[UTSR1] & UTSR1_TNF) );
-
- /* send the character out. */
- serial_port[UART_TX] = *s;
-
- /* if a LF, also do CR... */
- if (*s == 10) {
- while( !(serial_port[UTSR1] & UTSR1_TNF) );
- serial_port[UART_TX] = 13;
+ volatile unsigned long *serial_port;
+
+ if (machine_is_assabet()) {
+ if (0/*SA1111 connected*/)
+ serial_port = (unsigned long *)_Ser3UTCR0;
+ else
+ serial_port = (unsigned long *)_Ser1UTCR0;
+ } else if (machine_is_brutus())
+ serial_port = (unsigned long *)_Ser1UTCR0;
+ else if (machine_is_empeg() || machine_is_bitsy() ||
+ machine_is_victor() || machine_is_lart())
+ serial_port = (unsigned long *)_Ser3UTCR0;
+ else
+ return;
+
+ for (; *s; s++) {
+ /* wait for space in the UART's transmiter */
+ while (!(serial_port[UTSR1] & UTSR1_TNF));
+
+ /* send the character out. */
+ serial_port[UART_TX] = *s;
+
+ /* if a LF, also do CR... */
+ if (*s == 10) {
+ while (!(serial_port[UTSR1] & UTSR1_TNF));
+ serial_port[UART_TX] = 13;
+ }
}
- }
}
-#else
-
-static inline void puts( const char *s ) {}
-
-#endif
-
-
-/* Nothing to do for these */
+/*
+ * Nothing to do for these
+ */
#define arch_decomp_setup()
#define arch_decomp_wdog()
-
diff --git a/include/asm-arm/arch-shark/time.h b/include/asm-arm/arch-shark/time.h
index 32f9d7593cf602..5bfc2cf060ef22 100644
--- a/include/asm-arm/arch-shark/time.h
+++ b/include/asm-arm/arch-shark/time.h
@@ -13,7 +13,6 @@
* Copyright (c) 1996,1997,1998 Russell King.
*/
-#include <linux/config.h>
#include <asm/leds.h>
#include <linux/mc146818rtc.h>
@@ -28,15 +27,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
CMOS_READ(RTC_INTR_FLAGS);
-#ifdef CONFIG_LEDS
- {
- static int count = 50;
- if (--count == 0) {
- count = 50;
- leds_event(led_timer);
- }
- }
-#endif
+ do_leds();
{
#ifdef DIVISOR
diff --git a/include/asm-arm/dec21285.h b/include/asm-arm/dec21285.h
index c86e2c85105c78..39184ef9a8f6b5 100644
--- a/include/asm-arm/dec21285.h
+++ b/include/asm-arm/dec21285.h
@@ -14,6 +14,7 @@
#define DC21285_PCI_IO 0x7c000000
#define DC21285_PCI_MEM 0x80000000
+#include <linux/config.h>
#ifndef __ASSEMBLY__
#include <asm/arch/hardware.h>
#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x)))
@@ -80,6 +81,31 @@
#define SA110_CNTL_XCSDIR(x) ((x)<<28)
#define SA110_CNTL_PCICFN (1 << 31)
+/*
+ * footbridge_cfn_mode() is used when we want
+ * to check whether we are the central function
+ */
+#define __footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN)
+#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN)
+#define footbridge_cfn_mode() __footbridge_cfn_mode()
+#elif defined(CONFIG_FOOTBRIDGE_HOST)
+#define footbridge_cfn_mode() (1)
+#else
+#define footbridge_cfn_mode() (0)
+#endif
+
+/*
+ * footbridge_cfn_mode() is used when we want
+ * to check whether we are the central function
+ */
+#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN)
+#define footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN)
+#elif defined(CONFIG_FOOTBRIDGE_HOST)
+#define footbridge_cfn_mode() (1)
+#else
+#define footbridge_cfn_mode() (0)
+#endif
+
#define CSR_PCIADDR_EXTN DC21285_IO(0x0140)
#define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144)
#define CSR_XBUS_CYCLE DC21285_IO(0x0148)
diff --git a/include/asm-arm/mc146818rtc.h b/include/asm-arm/mc146818rtc.h
new file mode 100644
index 00000000000000..8729c5dfb0d397
--- /dev/null
+++ b/include/asm-arm/mc146818rtc.h
@@ -0,0 +1,27 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/include/asm-arm/mmzone.h b/include/asm-arm/mmzone.h
new file mode 100644
index 00000000000000..97ddd97184ad30
--- /dev/null
+++ b/include/asm-arm/mmzone.h
@@ -0,0 +1,12 @@
+/*
+ * linux/include/asm-arm/mmzone.h
+ *
+ * 1999-12-29 Nicolas Pitre Created
+ */
+
+#ifndef __ASM_MMZONE_H
+#define __ASM_MMZONE_H
+
+#include <asm/arch/mmzone.h>
+
+#endif
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h
index e1de021c422904..10f470048b6738 100644
--- a/include/asm-arm/page.h
+++ b/include/asm-arm/page.h
@@ -84,11 +84,15 @@ extern __inline__ int get_order(unsigned long size)
#endif /* !__ASSEMBLY__ */
+#include <linux/config.h>
#include <asm/arch/memory.h>
#define __pa(x) __virt_to_phys((unsigned long)(x))
#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
+
+#ifndef CONFIG_DISCONTIGMEM
#define MAP_NR(addr) ((__pa(addr) - PHYS_OFFSET) >> PAGE_SHIFT)
+#endif
#endif
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 5a05e2ef249fa0..b18e572d0723ed 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -4,6 +4,7 @@
#ifndef _ASMARM_PGTABLE_H
#define _ASMARM_PGTABLE_H
+#include <linux/config.h>
#include <asm/arch/memory.h>
#include <asm/proc-fns.h>
#include <asm/system.h>
@@ -77,7 +78,18 @@ extern void __handle_bad_pmd_kernel(pmd_t *pmd);
#define pte_none(pte) (!pte_val(pte))
#define pte_clear(ptep) set_pte((ptep), __pte(0))
+
+#ifndef CONFIG_DISCONTIGMEM
#define pte_pagenr(pte) ((unsigned long)(((pte_val(pte) - PHYS_OFFSET) >> PAGE_SHIFT)))
+#else
+/*
+ * I'm not happy with this - we needlessly convert a physical address
+ * to a virtual one, and then immediately back to a physical address,
+ * which, if __va and __pa are expensive causes twice the expense for
+ * zero gain. --rmk
+ */
+#define pte_pagenr(pte) MAP_NR(__va(pte_val(pte)))
+#endif
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0))
diff --git a/include/asm-arm/proc-armv/assembler.h b/include/asm-arm/proc-armv/assembler.h
index 128dd198209bd6..788a22b87e8208 100644
--- a/include/asm-arm/proc-armv/assembler.h
+++ b/include/asm-arm/proc-armv/assembler.h
@@ -1,10 +1,10 @@
/*
* linux/asm-arm/proc-armv/assembler.h
*
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-2000 Russell King
*
- * This file contains arm architecture specific defines
- * for the different processors
+ * This file contains ARM processor specifics for
+ * the ARM6 and better processors.
*/
#ifndef __ASSEMBLY__
#error "Only include this from assembly code"
@@ -19,68 +19,36 @@
/*
* LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
- * RETINSTR - return instruction (eg, mov pc, lr)
*/
#ifdef __STDC__
#define LOADREGS(cond, base, reglist...)\
ldm##cond base,reglist
-
-#define RETINSTR(instr, regs...)\
- instr regs
#else
#define LOADREGS(cond, base, reglist...)\
ldm/**/cond base,reglist
-
-#define RETINSTR(instr, regs...)\
- instr regs
#endif
/*
- * No nop required after mode change
- */
-#define MODENOP
-
-/*
- * Change to `mode'
- */
-#define MODE(savereg,tmpreg,mode) \
- mrs savereg, cpsr; \
- bic tmpreg, savereg, $0x1f; \
- orr tmpreg, tmpreg, $mode; \
- msr cpsr, tmpreg
-
-/*
- * Restore mode
+ * Build a return instruction for this processor type.
*/
-#define RESTOREMODE(savereg) \
- msr cpsr, savereg
-
-/*
- * save interrupt state (uses stack)
- */
-#define SAVEIRQS(tmpreg)\
- mrs tmpreg, cpsr; \
- str tmpreg, [sp, $-4]!
-
-/*
- * restore interrupt state (uses stack)
- */
-#define RESTOREIRQS(tmpreg)\
- ldr tmpreg, [sp], $4; \
- msr cpsr, tmpreg
+#define RETINSTR(instr, regs...)\
+ instr regs
/*
- * disable IRQs
+ * Save the current IRQ state and disable IRQs
+ * Note that this macro assumes FIQs are enabled, and
+ * that the processor is in SVC mode.
*/
-#define DISABLEIRQS(tmpreg)\
- mrs tmpreg , cpsr; \
- orr tmpreg , tmpreg , $I_BIT; \
- msr cpsr, tmpreg
+ .macro save_and_disable_irqs, oldcpsr, temp
+ mrs \oldcpsr, cpsr
+ mov \temp, #I_BIT | MODE_SVC
+ msr cpsr_c, \temp
+ .endm
/*
- * enable IRQs
+ * Restore interrupt state previously stored in
+ * a register
*/
-#define ENABLEIRQS(tmpreg)\
- mrs tmpreg , cpsr; \
- bic tmpreg , tmpreg , $I_BIT; \
- msr cpsr, tmpreg
+ .macro restore_irqs, oldcpsr
+ msr cpsr_c, \oldcpsr
+ .endm
diff --git a/include/asm-arm/proc-armv/locks.h b/include/asm-arm/proc-armv/locks.h
index 0a0391faee7ea8..047f0ce16911aa 100644
--- a/include/asm-arm/proc-armv/locks.h
+++ b/include/asm-arm/proc-armv/locks.h
@@ -72,7 +72,8 @@
* BIAS once per CPU will result in the long remaining
* negative.
*/
-#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
#define __down_op_write(ptr,fail) \
({ \
diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h
index 90e7f6efe9776a..f50c2f4e7fa34e 100644
--- a/include/asm-arm/setup.h
+++ b/include/asm-arm/setup.h
@@ -74,6 +74,7 @@ struct meminfo {
struct {
unsigned long start;
unsigned long size;
+ int node;
} bank[NR_BANKS];
};
diff --git a/include/asm-arm/socket.h b/include/asm-arm/socket.h
index 48775c3ea176c3..595ba22839b42b 100644
--- a/include/asm-arm/socket.h
+++ b/include/asm-arm/socket.h
@@ -41,4 +41,19 @@
#define SO_PEERNAME 28
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM 1 /* stream (connection) socket */
+#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
+#define SOCK_RAW 3 /* raw socket */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequential packet socket */
+#define SOCK_PACKET 10 /* linux specific way of */
+ /* getting packets at the dev */
+ /* level. For writing rarp and */
+ /* other similar things on the */
+ /* user level. */
+#endif
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 0283a7f2362f0d..b75a88411bf839 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -46,6 +46,7 @@ extern unsigned int __machine_arch_type;
#define MACH_TYPE_LART 27
#define MACH_TYPE_RANGER 28
#define MACH_TYPE_GRAPHICSCLIENT 29
+#define MACH_TYPE_XP860 30
/*
* Sort out a definition for machine_arch_type
@@ -280,6 +281,32 @@ extern unsigned int __machine_arch_type;
# define machine_is_lart() (0)
#endif
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+# ifdef machine_arch_type
+# undef machine_arch_type
+# define machine_arch_type __machine_arch_type
+# else
+# define machine_arch_type MACH_TYPE_GRAPHICSCLIENT
+# endif
+# define machine_is_grpahicsclient() \
+ (machine_arch_type == MACH_TYPE_GRAPHICSCLIENT)
+#else
+# define machine_is_graphicsclient() \
+ (0)
+#endif
+
+#ifdef CONFIG_SA1100_XP860
+# ifdef machine_arch_type
+# undef machine_arch_type
+# define machine_arch_type __machine_arch_type
+# else
+# define machine_arch_type MACH_TYPE_XP860
+# endif
+# define machine_is_xp860() (machine_arch_type == MACH_TYPE_XP860)
+#else
+# define machine_is_xp860() (0)
+#endif
+
/*
* The following are currently unregistered
*/
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 9755af1ab0e533..241cb03a8d57a8 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -116,7 +116,7 @@
#define __NR_lstat (__NR_SYSCALL_BASE+107)
#define __NR_fstat (__NR_SYSCALL_BASE+108)
-#define __NR_iopl (__NR_SYSCALL_BASE+110)
+
#define __NR_vhangup (__NR_SYSCALL_BASE+111)
#define __NR_idle (__NR_SYSCALL_BASE+112)
#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index e1ee66d0333fde..3e14e04d1f6dcb 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -519,4 +519,6 @@ struct microcode {
unsigned int bits[500];
};
+#define MICROCODE_IOCFREE _IO('6',0) /* because it is for P6 */
+
#endif /* __ASM_I386_PROCESSOR_H */
diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h
index f62ad151f29c87..7f6f121556a66d 100644
--- a/include/asm-ppc/bitops.h
+++ b/include/asm-ppc/bitops.h
@@ -29,67 +29,121 @@ extern int test_and_change_bit(int nr, volatile void *addr);
#define SMP_MB
#endif /* CONFIG_SMP */
+#define __INLINE_BITOPS 1
+
+#if __INLINE_BITOPS
/*
- * These are if'd out here because using : "cc" as a constraint
- * results in errors from gcc. -- Cort
- * Besides, they need to be changed so we have both set_bit
- * and test_and_set_bit, etc.
+ * These used to be if'd out here because using : "cc" as a constraint
+ * resulted in errors from egcs. Things may be OK with gcc-2.95.
*/
-#if 0
-extern __inline__ int set_bit(int nr, void * addr)
+extern __inline__ void set_bit(int nr, volatile void * addr)
{
- unsigned long old, t;
+ unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- __asm__ __volatile__(
- "1:lwarx %0,0,%3 \n\t"
- "or %1,%0,%2 \n\t"
- "stwcx. %1,0,%3 \n\t"
- "bne 1b \n\t"
- : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
- /*: "cc" */);
-
- return (old & mask) != 0;
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%3
+ or %0,%0,%2
+ stwcx. %0,0,%3
+ bne 1b"
+ SMP_MB
+ : "=&r" (old), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
+ : "cc" );
}
-extern __inline__ unsigned long clear_bit(unsigned long nr, void *addr)
+extern __inline__ void clear_bit(int nr, volatile void *addr)
{
- unsigned long old, t;
+ unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- __asm__ __volatile__("\n\
+ __asm__ __volatile__(SMP_WMB "\
1: lwarx %0,0,%3
- andc %1,%0,%2
- stwcx. %1,0,%3
+ andc %0,%0,%2
+ stwcx. %0,0,%3
bne 1b"
- : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
- /*: "cc"*/);
-
- return (old & mask) != 0;
+ SMP_MB
+ : "=&r" (old), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
+ : "cc");
}
-extern __inline__ unsigned long change_bit(unsigned long nr, void *addr)
+extern __inline__ void change_bit(int nr, volatile void *addr)
{
- unsigned long old, t;
+ unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- __asm__ __volatile__("\n\
+ __asm__ __volatile__(SMP_WMB "\
1: lwarx %0,0,%3
- xor %1,%0,%2
- stwcx. %1,0,%3
+ xor %0,%0,%2
+ stwcx. %0,0,%3
+ bne 1b"
+ SMP_MB
+ : "=&r" (old), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
+ : "cc");
+}
+
+extern __inline__ int test_and_set_bit(int nr, volatile void *addr)
+{
+ unsigned int old, t;
+ unsigned int mask = 1 << (nr & 0x1f);
+ volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
+
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%4
+ or %1,%0,%3
+ stwcx. %1,0,%4
+ bne 1b"
+ SMP_MB
+ : "=&r" (old), "=&r" (t), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
+ : "cc");
+
+ return (old & mask) != 0;
+}
+
+extern __inline__ int test_and_clear_bit(int nr, volatile void *addr)
+{
+ unsigned int old, t;
+ unsigned int mask = 1 << (nr & 0x1f);
+ volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
+
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%4
+ andc %1,%0,%3
+ stwcx. %1,0,%4
+ bne 1b"
+ SMP_MB
+ : "=&r" (old), "=&r" (t), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
+ : "cc");
+
+ return (old & mask) != 0;
+}
+
+extern __inline__ int test_and_change_bit(int nr, volatile void *addr)
+{
+ unsigned int old, t;
+ unsigned int mask = 1 << (nr & 0x1f);
+ volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
+
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%4
+ xor %1,%0,%3
+ stwcx. %1,0,%4
bne 1b"
- : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
- /*: "cc"*/);
+ SMP_MB
+ : "=&r" (old), "=&r" (t), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
+ : "cc");
return (old & mask) != 0;
}
-#endif
+#endif /* __INLINE_BITOPS */
extern __inline__ int test_bit(int nr, __const__ volatile void *addr)
{
@@ -277,4 +331,3 @@ found_middle:
#define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size)
#endif /* _PPC_BITOPS_H */
-
diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h
index 453c846d2e017c..0fdd6784493fef 100644
--- a/include/asm-ppc/byteorder.h
+++ b/include/asm-ppc/byteorder.h
@@ -9,7 +9,7 @@
#ifdef __GNUC__
-extern __inline__ unsigned ld_le16(volatile unsigned short *addr)
+extern __inline__ unsigned ld_le16(const volatile unsigned short *addr)
{
unsigned val;
@@ -17,12 +17,12 @@ extern __inline__ unsigned ld_le16(volatile unsigned short *addr)
return val;
}
-extern __inline__ void st_le16(volatile unsigned short *addr, unsigned val)
+extern __inline__ void st_le16(volatile unsigned short *addr, const unsigned val)
{
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
-extern __inline__ unsigned ld_le32(volatile unsigned *addr)
+extern __inline__ unsigned ld_le32(const volatile unsigned *addr)
{
unsigned val;
@@ -30,7 +30,7 @@ extern __inline__ unsigned ld_le32(volatile unsigned *addr)
return val;
}
-extern __inline__ void st_le32(volatile unsigned *addr, unsigned val)
+extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
{
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h
index 069ad9707bccfc..c45fd8409c461a 100644
--- a/include/asm-ppc/cache.h
+++ b/include/asm-ppc/cache.h
@@ -9,7 +9,11 @@
/* bytes per L1 cache line */
#if !defined(CONFIG_8xx) || defined(CONFIG_8260)
+#if defined(CONFIG_PPC64BRIDGE)
+#define L1_CACHE_BYTES 128
+#else
#define L1_CACHE_BYTES 32
+#endif /* PPC64 */
#else
#define L1_CACHE_BYTES 16
#endif /* !8xx || 8260 */
diff --git a/include/asm-ppc/est8260.h b/include/asm-ppc/est8260.h
index 201286ab460ce7..99337e7907848f 100644
--- a/include/asm-ppc/est8260.h
+++ b/include/asm-ppc/est8260.h
@@ -1,4 +1,10 @@
+/* Board information for the EST8260, which should be generic for
+ * all 8260 boards. The IMMR is now given to us so the hard define
+ * will soon be removed. All of the clock values are computed from
+ * the configuration SCMR and the Power-On-Reset word.
+ */
+
#define IMAP_ADDR ((uint)0xf0000000)
@@ -12,8 +18,10 @@ typedef struct bd_info {
unsigned int bi_busfreq; /* Bus Freq, in MHz */
unsigned int bi_cpmfreq; /* CPM Freq, in MHz */
unsigned int bi_brgfreq; /* BRG Freq, in MHz */
+ unsigned int bi_vco; /* VCO Out from PLL */
+ unsigned int bi_baudrate; /* Default console baud rate */
+ unsigned int bi_immr; /* IMMR when called from boot rom */
unsigned char bi_enetaddr[6];
- unsigned int bi_baudrate;
} bd_t;
extern bd_t m8xx_board_info;
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index a4be6b7e296246..6e5a57ad61ef3a 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -161,6 +161,20 @@ extern inline void * bus_to_virt(unsigned long address)
}
/*
+ * The PCI bus bridge can translate addresses issued by the processor(s)
+ * into a different address on the PCI bus. On 32-bit cpus, we assume
+ * this mapping is 1-1, but on 64-bit systems it often isn't.
+ */
+#ifndef CONFIG_PPC64BRIDGE
+#define phys_to_bus(x) (x)
+#define bus_to_phys(x) (x)
+
+#else
+extern unsigned long phys_to_bus(unsigned long pa);
+extern unsigned long bus_to_phys(unsigned int ba, int busnr);
+#endif /* CONFIG_PPC64BRIDGE */
+
+/*
* Change virtual addresses to physical addresses and vv, for
* addresses in the area where the kernel has the RAM mapped.
*/
diff --git a/include/asm-ppc/mc146818rtc.h b/include/asm-ppc/mc146818rtc.h
new file mode 100644
index 00000000000000..7e406b07dc4c7c
--- /dev/null
+++ b/include/asm-ppc/mc146818rtc.h
@@ -0,0 +1,27 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_PPC_MC146818RTC_H
+#define __ASM_PPC_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* __ASM_PPC_MC146818RTC_H */
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h
index 55f185d918f94e..4a3a42f264c69b 100644
--- a/include/asm-ppc/mmu.h
+++ b/include/asm-ppc/mmu.h
@@ -10,20 +10,20 @@
#ifndef __ASSEMBLY__
/* Hardware Page Table Entry */
typedef struct _PTE {
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
unsigned long long vsid:52;
unsigned long api:5;
unsigned long :5;
unsigned long h:1;
unsigned long v:1;
unsigned long long rpn:52;
-#else /* CONFIG_PPC64 */
+#else /* CONFIG_PPC64BRIDGE */
unsigned long v:1; /* Entry is valid */
unsigned long vsid:24; /* Virtual segment identifier */
unsigned long h:1; /* Hash algorithm indicator */
unsigned long api:6; /* Abbreviated page index */
unsigned long rpn:20; /* Real (physical) page number */
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64BRIDGE */
unsigned long :3; /* Unused */
unsigned long r:1; /* Referenced */
unsigned long c:1; /* Changed */
@@ -64,11 +64,11 @@ typedef struct _P601_BATU { /* Upper part of BAT for 601 processor */
} P601_BATU;
typedef struct _BATU { /* Upper part of BAT (all except 601) */
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
unsigned long long bepi:47;
-#else /* CONFIG_PPC64 */
+#else /* CONFIG_PPC64BRIDGE */
unsigned long bepi:15; /* Effective page index (virtual address) */
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64BRIDGE */
unsigned long :4; /* Unused */
unsigned long bl:11; /* Block size mask */
unsigned long vs:1; /* Supervisor valid */
@@ -83,11 +83,11 @@ typedef struct _P601_BATL { /* Lower part of BAT for 601 processor */
} P601_BATL;
typedef struct _BATL { /* Lower part of BAT (all except 601) */
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
unsigned long long brpn:47;
-#else /* CONFIG_PPC64 */
+#else /* CONFIG_PPC64BRIDGE */
unsigned long brpn:15; /* Real page index (physical address) */
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64BRIDGE */
unsigned long :10; /* Unused */
unsigned long w:1; /* Write-thru cache */
unsigned long i:1; /* Cache inhibit */
@@ -135,12 +135,7 @@ typedef struct _MMU_context {
pte **pmap; /* Two-level page-map structure */
} MMU_context;
-/* invalidate a TLB entry */
-extern inline void _tlbie(unsigned long va)
-{
- asm volatile ("tlbie %0" : : "r"(va));
-}
-
+extern void _tlbie(unsigned long va); /* invalidate a TLB entry */
extern void _tlbia(void); /* invalidate all TLB entries */
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
index 88d6970a5649e4..bdb1447ed2aec8 100644
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -48,8 +48,12 @@ extern void mmu_context_overflow(void);
* Set the current MMU context.
* On 32-bit PowerPCs (other than the 8xx embedded chips), this is done by
* loading up the segment registers for the user part of the address space.
+ *
+ * On the 8xx parts, the context currently includes the page directory,
+ * and once I implement a real TLB context manager this will disappear.
+ * The PGD is ignored on other processors. - Dan
*/
-extern void set_context(int context);
+extern void set_context(int context, void *pgd);
#ifdef CONFIG_8xx
extern inline void mmu_context_overflow(void)
@@ -85,7 +89,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
{
tsk->thread.pgdir = next->pgd;
get_mmu_context(next);
- set_context(next->context);
+ set_context(next->context, next->pgd);
}
/*
@@ -96,7 +100,7 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm
{
current->thread.pgdir = mm->pgd;
get_mmu_context(mm);
- set_context(mm->context);
+ set_context(mm->context, mm->pgd);
}
/*
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index 5c4e39902a5e81..505f0c5b65f890 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -72,7 +72,7 @@ extern void __flush_page_to_ram(unsigned long page_va);
#define flush_page_to_ram(page) __flush_page_to_ram(page_address(page))
extern unsigned long va_to_phys(unsigned long address);
-extern pte_t *va_to_pte(struct task_struct *tsk, unsigned long address);
+extern pte_t *va_to_pte(unsigned long address);
extern unsigned long ioremap_bot, ioremap_base;
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h
index 47539d3a70ad24..2d8f38fd5397b5 100644
--- a/include/asm-ppc/posix_types.h
+++ b/include/asm-ppc/posix_types.h
@@ -1,8 +1,6 @@
#ifndef _PPC_POSIX_TYPES_H
#define _PPC_POSIX_TYPES_H
-#include <linux/config.h> /* for CONFIG_PPC64 */
-
/*
* This file is generally used by user-level software, so you need to
* be a little careful about namespace pollution etc. Also, we cannot
@@ -17,17 +15,8 @@ typedef long __kernel_off_t;
typedef int __kernel_pid_t;
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
-
-/* Grrr... gcc thinks size_t is unsigned int, so we either
- have to have this nonsense or use -fno-builtin. - paulus */
-#ifdef CONFIG_PPC64
-typedef unsigned long __kernel_size_t;
-typedef long __kernel_ssize_t;
-#else
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
-#endif /* CONFIG_PPC64 */
-
typedef long __kernel_ptrdiff_t;
typedef long __kernel_time_t;
typedef long __kernel_suseconds_t;
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index 3088dd279e1741..86a086e7945f82 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -15,10 +15,10 @@
/* Machine State Register (MSR) Fields */
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
#define MSR_SF (1<<63)
#define MSR_ISF (1<<61)
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64BRIDGE */
#define MSR_VEC (1<<25) /* Enable AltiVec */
#define MSR_POW (1<<18) /* Enable Power Management */
#define MSR_WE (1<<18) /* Wait State Enable */
diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h
index 66eaedda534358..70ff81302e4324 100644
--- a/include/asm-ppc/prom.h
+++ b/include/asm-ppc/prom.h
@@ -4,6 +4,8 @@
*
* Copyright (C) 1996 Paul Mackerras.
*/
+#ifndef _PPC_PROM_H
+#define _PPC_PROM_H
typedef void *phandle;
typedef void *ihandle;
@@ -86,3 +88,5 @@ extern int call_rtas(const char *service, int nargs, int nret,
extern void prom_drawstring(const char *c);
extern void prom_drawhex(unsigned long v);
extern void prom_drawchar(char c);
+
+#endif /* _PPC_PROM_H */
diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h
index 448f0b274201d6..f95656dd2fd4c6 100644
--- a/include/asm-ppc/ptrace.h
+++ b/include/asm-ppc/ptrace.h
@@ -20,7 +20,7 @@
#include <linux/config.h>
#ifndef __ASSEMBLY__
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
#define PPC_REG unsigned long /*long*/
#else
#define PPC_REG unsigned long
diff --git a/include/asm-ppc/rpxclassic.h b/include/asm-ppc/rpxclassic.h
index 74be5608530157..b84a20d120c3e3 100644
--- a/include/asm-ppc/rpxclassic.h
+++ b/include/asm-ppc/rpxclassic.h
@@ -8,6 +8,8 @@
#ifndef __MACH_RPX_DEFS
#define __MACH_RPX_DEFS
+#include <linux/config.h>
+
/* A Board Information structure that is given to a program when
* prom starts it up.
*/
@@ -26,8 +28,6 @@ extern bd_t m8xx_board_info;
* We just map a few things we need. The CSR is actually 4 byte-wide
* registers that can be accessed as 8-, 16-, or 32-bit values.
*/
-#define PCMCIA_MEM_ADDR ((uint)0x04000000)
-#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
#define PCI_ISA_IO_ADDR ((unsigned)0x80000000)
#define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024))
#define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000)
@@ -38,6 +38,12 @@ extern bd_t m8xx_board_info;
#define IMAP_SIZE ((uint)(64 * 1024))
#define PCI_CSR_ADDR ((uint)0x80000000)
#define PCI_CSR_SIZE ((uint)(64 * 1024))
+#define PCMCIA_MEM_ADDR ((uint)0xe0000000)
+#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
+#define PCMCIA_IO_ADDR ((uint)0xe4000000)
+#define PCMCIA_IO_SIZE ((uint)(4 * 1024))
+#define PCMCIA_ATTRB_ADDR ((uint)0xe8000000)
+#define PCMCIA_ATTRB_SIZE ((uint)(4 * 1024))
/* Things of interest in the CSR.
*/
@@ -49,8 +55,19 @@ extern bd_t m8xx_board_info;
#define BCSR0_FLASH_SEL ((uint)0x02000000)
#define BCSR0_ENMONXCVR ((uint)0x01000000)
+#define BCSR0_PCMCIAVOLT ((uint)0x000f0000) /* CLLF */
+#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) /* CLLF */
+#define BCSR0_PCMCIA5VOLT ((uint)0x00060000) /* CLLF */
+
#define BCSR2_EN232XCVR ((uint)0x00008000)
#define BCSR2_QSPACESEL ((uint)0x00004000)
+#define BCSR2_FETHLEDMODE ((uint)0x00000800) /* CLLF */
+
+#if defined(CONFIG_RPXLCD) || defined(CONFIG_HTDMSOUND)
+/* HIOX Expansion card.
+*/
+#include <asm/rpx_hiox.h>
+#endif
/* Interrupt level assignments.
*/
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
index af62f7b5a6e7dd..aec727670a6d7e 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -37,9 +37,11 @@ void smp_send_tlb_invalidate(int);
#define cpu_number_map(x) (x)
extern volatile unsigned long cpu_callin_map[NR_CPUS];
-#define hard_smp_processor_id() (0)
#define smp_processor_id() (current->processor)
+extern int smp_hw_index[NR_CPUS];
+#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
+
struct klock_info_struct {
unsigned long kernel_flag;
unsigned char akp;
diff --git a/include/asm-ppc/socket.h b/include/asm-ppc/socket.h
index 39a7bac369ce7d..c6c1899e8cbaf9 100644
--- a/include/asm-ppc/socket.h
+++ b/include/asm-ppc/socket.h
@@ -47,4 +47,19 @@
#define SO_PEERNAME 28
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM 1 /* stream (connection) socket */
+#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
+#define SOCK_RAW 3 /* raw socket */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequential packet socket */
+#define SOCK_PACKET 10 /* linux specific way of */
+ /* getting packets at the dev */
+ /* level. For writing rarp and */
+ /* other similar things on the */
+ /* user level. */
+#endif
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index fa9bc9944ee483..162a09a1d181dd 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -8,7 +8,6 @@
#include <linux/config.h>
#include <linux/kdev_t.h>
-#include <linux/bitops.h>
#include <asm/processor.h>
#include <asm/atomic.h>
diff --git a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h
index c2a9c91e5564a7..3eafdbd9137a85 100644
--- a/include/asm-ppc/uaccess.h
+++ b/include/asm-ppc/uaccess.h
@@ -211,16 +211,28 @@ extern int __copy_tofrom_user(void *to, const void *from, unsigned long size);
extern inline unsigned long
copy_from_user(void *to, const void *from, unsigned long n)
{
+ unsigned long over;
+
if (access_ok(VERIFY_READ, from, n))
return __copy_tofrom_user(to, from, n);
+ if ((unsigned long)from < TASK_SIZE) {
+ over = (unsigned long)from + n - TASK_SIZE;
+ return __copy_tofrom_user(to, from, n - over) + over;
+ }
return n;
}
extern inline unsigned long
copy_to_user(void *to, const void *from, unsigned long n)
{
+ unsigned long over;
+
if (access_ok(VERIFY_WRITE, to, n))
return __copy_tofrom_user(to, from, n);
+ if ((unsigned long)to < TASK_SIZE) {
+ over = (unsigned long)to + n - TASK_SIZE;
+ return __copy_tofrom_user(to, from, n - over) + over;
+ }
return n;
}
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index f5f8547491ef29..bca251d933b31a 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -270,6 +270,7 @@ do { \
extern inline int pte_none(pte_t pte) { return ((pte_val(pte) & (_PAGE_INVALID | _PAGE_RO)) == _PAGE_INVALID); }
extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = _PAGE_INVALID; }
+#define PTE_INIT(x) pte_clear(x)
extern inline int pte_pagenr(pte_t pte) { return ((unsigned long)((pte_val(pte) >> PAGE_SHIFT))); }
extern inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; }
diff --git a/include/asm-s390/socket.h b/include/asm-s390/socket.h
index 21368c91bd5eae..703a7bd58c1167 100644
--- a/include/asm-s390/socket.h
+++ b/include/asm-s390/socket.h
@@ -41,20 +41,6 @@
#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
#define SO_SECURITY_ENCRYPTION_NETWORK 24
-#ifdef __KERNEL__
-/* Socket types. */
-#define SOCK_STREAM 1 /* stream (connection) socket */
-#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
-#define SOCK_RAW 3 /* raw socket */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequential packet socket */
-#define SOCK_PACKET 10 /* linux specific way of */
- /* getting packets at the dev */
- /* level. For writing rarp and */
- /* other similar things on the */
- /* user level. */
-#endif
-
#define SO_BINDTODEVICE 25
/* Socket filtering */
@@ -63,4 +49,19 @@
#define SO_PEERNAME 28
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM 1 /* stream (connection) socket */
+#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
+#define SOCK_RAW 3 /* raw socket */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequential packet socket */
+#define SOCK_PACKET 10 /* linux specific way of */
+ /* getting packets at the dev */
+ /* level. For writing rarp and */
+ /* other similar things on the */
+ /* user level. */
+#endif
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-sh/hd64461.h b/include/asm-sh/hd64461.h
new file mode 100644
index 00000000000000..1f5851fccb4da7
--- /dev/null
+++ b/include/asm-sh/hd64461.h
@@ -0,0 +1,38 @@
+#ifndef __ASM_SH_HD64461
+#define __ASM_SH_HD64461
+/*
+ * $Id: hd64461.h,v 1.1 2000/06/10 21:45:48 yaegashi Exp $
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * Hitachi HD64461 companion chip support
+ */
+#include <linux/config.h>
+
+#define HD64461_CPTWAR 0x1030
+#define HD64461_CPTWDR 0x1032
+#define HD64461_CPTRAR 0x1034
+#define HD64461_CPTRDR 0x1036
+
+#define HD64461_PCC0ISR 0x2000
+#define HD64461_PCC0GCR 0x2002
+#define HD64461_PCC0CSCR 0x2004
+#define HD64461_PCC0CSCIER 0x2006
+#define HD64461_PCC0SCR 0x2008
+#define HD64461_PCC1ISR 0x2010
+#define HD64461_PCC1GCR 0x2012
+#define HD64461_PCC1CSCR 0x2014
+#define HD64461_PCC1CSCIER 0x2016
+#define HD64461_PCC1SCR 0x2018
+#define HD64461_P0OCR 0x202a
+#define HD64461_P1OCR 0x202c
+#define HD64461_PGCR 0x202e
+
+#define HD64461_NIRR 0x5000
+#define HD64461_NIMR 0x5002
+
+#ifndef CONFIG_HD64461_IOBASE
+#define CONFIG_HD64461_IOBASE 0xb0000000
+#endif
+
+#define HD64461_IRQBASE 64
+
+#endif
diff --git a/include/asm-sh/hitachi_se.h b/include/asm-sh/hitachi_se.h
index 282bbce8faf2b7..05b701e1f1c633 100644
--- a/include/asm-sh/hitachi_se.h
+++ b/include/asm-sh/hitachi_se.h
@@ -39,6 +39,22 @@
#define PA_BCR 0xb1400000 /* FPGA */
#define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC_MW1 0xb8400000 /* MR-SHPC-01 memory window base */
+#define PA_MRSHPC_MW2 0xb8500000 /* MR-SHPC-01 attribute window base */
+#define PA_MRSHPC_IO 0xb8600000 /* MR-SHPC-01 I/O window base */
+#define MRSHPC_OPTION (PA_MRSHPC + 6)
+#define MRSHPC_CSR (PA_MRSHPC + 8)
+#define MRSHPC_ISR (PA_MRSHPC + 10)
+#define MRSHPC_ICR (PA_MRSHPC + 12)
+#define MRSHPC_CPWCR (PA_MRSHPC + 14)
+#define MRSHPC_MW0CR1 (PA_MRSHPC + 16)
+#define MRSHPC_MW1CR1 (PA_MRSHPC + 18)
+#define MRSHPC_IOWCR1 (PA_MRSHPC + 20)
+#define MRSHPC_MW0CR2 (PA_MRSHPC + 22)
+#define MRSHPC_MW1CR2 (PA_MRSHPC + 24)
+#define MRSHPC_IOWCR2 (PA_MRSHPC + 26)
+#define MRSHPC_CDCR (PA_MRSHPC + 28)
+#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30)
#define BCR_ILCRA (PA_BCR + 0)
#define BCR_ILCRB (PA_BCR + 2)
diff --git a/include/asm-sh/ide.h b/include/asm-sh/ide.h
index cc30fac03d327d..1112ea36c21970 100644
--- a/include/asm-sh/ide.h
+++ b/include/asm-sh/ide.h
@@ -17,7 +17,7 @@
#include <linux/config.h>
#ifndef MAX_HWIFS
-#define MAX_HWIFS 1 /* XXX: For my board -- gniibe */
+#define MAX_HWIFS 1
#endif
#define ide__sti() __sti()
@@ -25,8 +25,13 @@
static __inline__ int ide_default_irq(ide_ioreg_t base)
{
switch (base) {
- case 0xba0001f0: return 14;
- case 0xba000170: return 14;
+#ifdef CONFIG_SH_HP600
+ case 0x201f0: return 77;
+ case 0x20170: return 77;
+#else
+ case 0x01f0: return 14;
+ case 0x0170: return 15;
+#endif
default:
return 0;
}
@@ -35,10 +40,17 @@ static __inline__ int ide_default_irq(ide_ioreg_t base)
static __inline__ ide_ioreg_t ide_default_io_base(int index)
{
switch (index) {
+#ifdef CONFIG_SH_HP600
+ case 0:
+ return 0x201f0;
+ case 1:
+ return 0x20170;
+#else
case 0:
- return 0xba0001f0;
+ return 0x1f0;
case 1:
- return 0xba000170;
+ return 0x170;
+#endif
default:
return 0;
}
diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h
index c6de2a42a59689..0d516620c71202 100644
--- a/include/asm-sh/io.h
+++ b/include/asm-sh/io.h
@@ -85,9 +85,6 @@ extern unsigned long sh_isa_slot(unsigned long offset);
#define isa_memcpy_toio(a,b,c) \
memcpy((void *)(sh_isa_slot((unsigned long)(a))),(b),(c))
-#define ctrl_in(addr) *(addr)
-#define ctrl_out(data,addr) *(addr) = (data)
-
extern __inline__ unsigned long ctrl_inb(unsigned long addr)
{
return *(volatile unsigned char*)addr;
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index d013f35fc63374..951ad2e9f6681a 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -43,8 +43,12 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
#define NR_IRQS 32
#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+#ifdef CONFIG_HD64461
+#define NR_IRQS 80 /* HD64461_IRQBASE+16, see hd64461.h */
+#else
#define NR_IRQS 61
#endif
+#endif
extern void disable_irq(unsigned int);
extern void disable_irq_nosync(unsigned int);
diff --git a/include/asm-sh/keyboard.h b/include/asm-sh/keyboard.h
new file mode 100644
index 00000000000000..9a64c5113c449d
--- /dev/null
+++ b/include/asm-sh/keyboard.h
@@ -0,0 +1,44 @@
+#ifndef __ASM_SH_KEYBOARD_H
+#define __ASM_SH_KEYBOARD_H
+/*
+ * $Id: keyboard.h,v 1.1 2000/06/10 21:45:48 yaegashi Exp $
+ */
+#include <linux/config.h>
+
+static __inline__ int kbd_setkeycode(unsigned int scancode,
+ unsigned int keycode)
+{
+ return -EOPNOTSUPP;
+}
+
+static __inline__ int kbd_getkeycode(unsigned int scancode)
+{
+ return scancode > 127 ? -EINVAL : scancode;
+}
+
+static __inline__ int kbd_translate(unsigned char scancode,
+ unsigned char *keycode, char raw_mode)
+{
+ *keycode = scancode;
+ return 1;
+}
+
+static __inline__ char kbd_unexpected_up(unsigned char keycode)
+{
+ return 0200;
+}
+
+static __inline__ void kbd_leds(unsigned char leds)
+{
+}
+
+#ifdef CONFIG_SH_HP600
+void __init hp600_kbd_init_hw(void);
+#define kbd_init_hw hp600_kbd_init_hw
+#else
+static __inline__ void kbd_init_hw(void)
+{
+}
+#endif
+
+#endif
diff --git a/include/asm-sh/linux_logo.h b/include/asm-sh/linux_logo.h
new file mode 100644
index 00000000000000..b7d11eddb4542c
--- /dev/null
+++ b/include/asm-sh/linux_logo.h
@@ -0,0 +1,48 @@
+/* $Id: linux_logo.h,v 1.1 2000/06/10 21:45:48 yaegashi Exp $
+ * include/asm-sh/linux_logo.h: This is a linux logo
+ * to be displayed on boot.
+ *
+ * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *
+ * You can put anything here, but:
+ * LINUX_LOGO_COLORS has to be less than 224
+ * image size has to be 80x80
+ * values have to start from 0x20
+ * (i.e. RGB(linux_logo_red[0],
+ * linux_logo_green[0],
+ * linux_logo_blue[0]) is color 0x20)
+ * BW image has to be 80x80 as well, with MS bit
+ * on the left
+ * Serial_console ascii image can be any size,
+ * but should contain %s to display the version
+ */
+
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/SuperH version " UTS_RELEASE
+
+#define LINUX_LOGO_COLORS 214
+
+#ifdef INCLUDE_LINUX_LOGO_DATA
+
+#define INCLUDE_LINUX_LOGOBW
+#define INCLUDE_LINUX_LOGO16
+
+#include <linux/linux_logo.h>
+
+#else
+
+/* prototypes only */
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+extern unsigned char linux_logo[];
+extern unsigned char linux_logo_bw[];
+extern unsigned char linux_logo16_red[];
+extern unsigned char linux_logo16_green[];
+extern unsigned char linux_logo16_blue[];
+extern unsigned char linux_logo16[];
+
+#endif
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index f39d88aaa37ff7..31920c13bf0c03 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -89,26 +89,26 @@ extern unsigned long empty_zero_page[1024];
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
#define VMALLOC_END P4SEG
-#define _PAGE_READ 0x001 /* software: read access allowed */
+#define _PAGE_PRESENT 0x001 /* software: page is present */
#define _PAGE_ACCESSED 0x002 /* software: page referenced */
#define _PAGE_DIRTY 0x004 /* D-bit : page changed */
#define _PAGE_CACHABLE 0x008 /* C-bit : cachable */
-/* 0x010 */
+/* 0x010 SZ-bit : size of page */
#define _PAGE_RW 0x020 /* PR0-bit : write access allowed */
#define _PAGE_USER 0x040 /* PR1-bit : user space access allowed */
#define _PAGE_PROTNONE 0x080 /* software: if not present */
-#define _PAGE_PRESENT 0x100 /* V-bit : page is valid */
+/* 0x100 V-bit : page is valid */
#if defined(__sh3__)
/* Mask which drop software flags */
-#define _PAGE_FLAGS_HARDWARE_MASK 0x1ffff16c
+#define _PAGE_FLAGS_HARDWARE_MASK 0x1ffff06c
/* Flags defalult: SZ=1 (4k-byte), C=0 (non-cachable), SH=0 (not shared) */
-#define _PAGE_FLAGS_HARDWARE_DEFAULT 0x00000010
+#define _PAGE_FLAGS_HARDWARE_DEFAULT 0x00000110
#elif defined(__SH4__)
/* Mask which drops software flags */
-#define _PAGE_FLAGS_HARDWARE_MASK 0x1ffff16c
+#define _PAGE_FLAGS_HARDWARE_MASK 0x1ffff06c
/* Flags defalult: SZ=01 (4k-byte), C=0 (non-cachable), SH=0 (not shared), WT=0 */
-#define _PAGE_FLAGS_HARDWARE_DEFAULT 0x00000010
+#define _PAGE_FLAGS_HARDWARE_DEFAULT 0x00000110
#endif
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h
index 1fcfb130028899..cf59dbb881a363 100644
--- a/include/asm-sh/processor.h
+++ b/include/asm-sh/processor.h
@@ -36,6 +36,7 @@ struct sh_cpuinfo {
unsigned long *pgd_quick;
unsigned long *pte_quick;
unsigned long pgtable_cache_sz;
+ unsigned int cpu_clock, master_clock, bus_clock, module_clock;
};
extern struct sh_cpuinfo boot_cpu_data;
diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h
index a61cd3ababc92b..e716331ee90f2a 100644
--- a/include/asm-sh/ptrace.h
+++ b/include/asm-sh/ptrace.h
@@ -92,11 +92,11 @@ extern void show_regs(struct pt_regs *);
#define BAMR_ASID (1 << 2)
#define BAMR_NONE 0
-#define BAMR_10 0x1
-#define BAMR_12 0x2
+#define BAMR_10 0x1
+#define BAMR_12 0x2
#define BAMR_ALL 0x3
-#define BAMR_16 0x8
-#define BAMR_20 0x9
+#define BAMR_16 0x8
+#define BAMR_20 0x9
#define BBR_INST (1 << 4)
#define BBR_DATA (2 << 4)
diff --git a/include/asm-sh/socket.h b/include/asm-sh/socket.h
index a3de49dc298fcb..ebcb6a333aed64 100644
--- a/include/asm-sh/socket.h
+++ b/include/asm-sh/socket.h
@@ -41,4 +41,19 @@
#define SO_PEERNAME 28
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM 1 /* stream (connection) socket */
+#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
+#define SOCK_RAW 3 /* raw socket */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequential packet socket */
+#define SOCK_PACKET 10 /* linux specific way of */
+ /* getting packets at the dev */
+ /* level. For writing rarp and */
+ /* other similar things on the */
+ /* user level. */
+#endif
+
#endif /* __ASM_SH_SOCKET_H */
diff --git a/include/asm-sh/uaccess.h b/include/asm-sh/uaccess.h
index 65ed58fd83101b..2237d34a468ff2 100644
--- a/include/asm-sh/uaccess.h
+++ b/include/asm-sh/uaccess.h
@@ -209,6 +209,7 @@ __asm__ __volatile__( \
extern void __put_user_unknown(void);
/* Generic arbitrary sized copy. */
+/* Return the number of bytes NOT copied */
/* XXX: should be such that: 4byte and the rest. */
extern __inline__ __kernel_size_t
__copy_user(void *__to, const void *__from, __kernel_size_t __n)
@@ -216,6 +217,7 @@ __copy_user(void *__to, const void *__from, __kernel_size_t __n)
unsigned long __dummy, _f, _t;
__kernel_size_t res;
+ if ((res = __n))
__asm__ __volatile__(
"9:\n\t"
"mov.b @%2+, %1\n\t"
@@ -229,17 +231,17 @@ __copy_user(void *__to, const void *__from, __kernel_size_t __n)
"3:\n\t"
"mov.l 5f, %1\n\t"
"jmp @%1\n\t"
- " mov %7, %0\n\t"
+ " add #1, %0\n\t"
".balign 4\n"
"5: .long 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
" .balign 4\n"
- " .long 9b,3b\n"
- " .long 1b,2b\n"
+ " .long 9b,2b\n"
+ " .long 1b,3b\n"
".previous"
: "=r" (res), "=&z" (__dummy), "=r" (_f), "=r" (_t)
- : "2" (__from), "3" (__to), "0" (__n), "i" (-EFAULT)
+ : "2" (__from), "3" (__to), "0" (res)
: "memory");
return res;
diff --git a/include/asm-sparc/asm_offsets.h b/include/asm-sparc/asm_offsets.h
index e46a4c1cee4906..f4af06b1f7387a 100644
--- a/include/asm-sparc/asm_offsets.h
+++ b/include/asm-sparc/asm_offsets.h
@@ -36,155 +36,157 @@
#define ASIZ_task_has_cpu 0x00000004
#define AOFF_task_processor 0x00000038
#define ASIZ_task_processor 0x00000004
-#define AOFF_task_run_list 0x0000003c
+#define AOFF_task_ptrace 0x0000003c
+#define ASIZ_task_ptrace 0x00000004
+#define AOFF_task_run_list 0x00000040
#define ASIZ_task_run_list 0x00000008
-#define AOFF_task_next_task 0x00000044
+#define AOFF_task_next_task 0x00000048
#define ASIZ_task_next_task 0x00000004
-#define AOFF_task_prev_task 0x00000048
+#define AOFF_task_prev_task 0x0000004c
#define ASIZ_task_prev_task 0x00000004
-#define AOFF_task_last_processor 0x0000004c
+#define AOFF_task_last_processor 0x00000050
#define ASIZ_task_last_processor 0x00000004
-#define AOFF_task_binfmt 0x00000050
+#define AOFF_task_binfmt 0x00000054
#define ASIZ_task_binfmt 0x00000004
-#define AOFF_task_exit_code 0x00000054
+#define AOFF_task_exit_code 0x00000058
#define ASIZ_task_exit_code 0x00000004
-#define AOFF_task_exit_signal 0x00000058
+#define AOFF_task_exit_signal 0x0000005c
#define ASIZ_task_exit_signal 0x00000004
-#define AOFF_task_pdeath_signal 0x0000005c
+#define AOFF_task_pdeath_signal 0x00000060
#define ASIZ_task_pdeath_signal 0x00000004
-#define AOFF_task_personality 0x00000060
+#define AOFF_task_personality 0x00000064
#define ASIZ_task_personality 0x00000004
-#define AOFF_task_pid 0x00000068
+#define AOFF_task_pid 0x0000006c
#define ASIZ_task_pid 0x00000004
-#define AOFF_task_pgrp 0x0000006c
+#define AOFF_task_pgrp 0x00000070
#define ASIZ_task_pgrp 0x00000004
-#define AOFF_task_tty_old_pgrp 0x00000070
+#define AOFF_task_tty_old_pgrp 0x00000074
#define ASIZ_task_tty_old_pgrp 0x00000004
-#define AOFF_task_session 0x00000074
+#define AOFF_task_session 0x00000078
#define ASIZ_task_session 0x00000004
-#define AOFF_task_leader 0x00000078
+#define AOFF_task_leader 0x0000007c
#define ASIZ_task_leader 0x00000004
-#define AOFF_task_p_opptr 0x0000007c
+#define AOFF_task_p_opptr 0x00000080
#define ASIZ_task_p_opptr 0x00000004
-#define AOFF_task_p_pptr 0x00000080
+#define AOFF_task_p_pptr 0x00000084
#define ASIZ_task_p_pptr 0x00000004
-#define AOFF_task_p_cptr 0x00000084
+#define AOFF_task_p_cptr 0x00000088
#define ASIZ_task_p_cptr 0x00000004
-#define AOFF_task_p_ysptr 0x00000088
+#define AOFF_task_p_ysptr 0x0000008c
#define ASIZ_task_p_ysptr 0x00000004
-#define AOFF_task_p_osptr 0x0000008c
+#define AOFF_task_p_osptr 0x00000090
#define ASIZ_task_p_osptr 0x00000004
-#define AOFF_task_pidhash_next 0x00000090
+#define AOFF_task_pidhash_next 0x00000094
#define ASIZ_task_pidhash_next 0x00000004
-#define AOFF_task_pidhash_pprev 0x00000094
+#define AOFF_task_pidhash_pprev 0x00000098
#define ASIZ_task_pidhash_pprev 0x00000004
-#define AOFF_task_wait_chldexit 0x00000098
+#define AOFF_task_wait_chldexit 0x0000009c
#define ASIZ_task_wait_chldexit 0x00000014
-#define AOFF_task_vfork_sem 0x000000ac
+#define AOFF_task_vfork_sem 0x000000b0
#define ASIZ_task_vfork_sem 0x00000004
-#define AOFF_task_rt_priority 0x000000b0
+#define AOFF_task_rt_priority 0x000000b4
#define ASIZ_task_rt_priority 0x00000004
-#define AOFF_task_it_real_value 0x000000b4
+#define AOFF_task_it_real_value 0x000000b8
#define ASIZ_task_it_real_value 0x00000004
-#define AOFF_task_it_prof_value 0x000000b8
+#define AOFF_task_it_prof_value 0x000000bc
#define ASIZ_task_it_prof_value 0x00000004
-#define AOFF_task_it_virt_value 0x000000bc
+#define AOFF_task_it_virt_value 0x000000c0
#define ASIZ_task_it_virt_value 0x00000004
-#define AOFF_task_it_real_incr 0x000000c0
+#define AOFF_task_it_real_incr 0x000000c4
#define ASIZ_task_it_real_incr 0x00000004
-#define AOFF_task_it_prof_incr 0x000000c4
+#define AOFF_task_it_prof_incr 0x000000c8
#define ASIZ_task_it_prof_incr 0x00000004
-#define AOFF_task_it_virt_incr 0x000000c8
+#define AOFF_task_it_virt_incr 0x000000cc
#define ASIZ_task_it_virt_incr 0x00000004
-#define AOFF_task_real_timer 0x000000cc
+#define AOFF_task_real_timer 0x000000d0
#define ASIZ_task_real_timer 0x00000018
-#define AOFF_task_times 0x000000e4
+#define AOFF_task_times 0x000000e8
#define ASIZ_task_times 0x00000010
-#define AOFF_task_start_time 0x000000f4
+#define AOFF_task_start_time 0x000000f8
#define ASIZ_task_start_time 0x00000004
-#define AOFF_task_per_cpu_utime 0x000000f8
+#define AOFF_task_per_cpu_utime 0x000000fc
#define ASIZ_task_per_cpu_utime 0x00000004
-#define AOFF_task_min_flt 0x00000100
+#define AOFF_task_min_flt 0x00000104
#define ASIZ_task_min_flt 0x00000004
-#define AOFF_task_maj_flt 0x00000104
+#define AOFF_task_maj_flt 0x00000108
#define ASIZ_task_maj_flt 0x00000004
-#define AOFF_task_nswap 0x00000108
+#define AOFF_task_nswap 0x0000010c
#define ASIZ_task_nswap 0x00000004
-#define AOFF_task_cmin_flt 0x0000010c
+#define AOFF_task_cmin_flt 0x00000110
#define ASIZ_task_cmin_flt 0x00000004
-#define AOFF_task_cmaj_flt 0x00000110
+#define AOFF_task_cmaj_flt 0x00000114
#define ASIZ_task_cmaj_flt 0x00000004
-#define AOFF_task_cnswap 0x00000114
+#define AOFF_task_cnswap 0x00000118
#define ASIZ_task_cnswap 0x00000004
-#define AOFF_task_uid 0x0000011c
+#define AOFF_task_uid 0x00000120
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x00000120
+#define AOFF_task_euid 0x00000124
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x00000124
+#define AOFF_task_suid 0x00000128
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000128
+#define AOFF_task_fsuid 0x0000012c
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x0000012c
+#define AOFF_task_gid 0x00000130
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000130
+#define AOFF_task_egid 0x00000134
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x00000134
+#define AOFF_task_sgid 0x00000138
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000138
+#define AOFF_task_fsgid 0x0000013c
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x0000013c
+#define AOFF_task_ngroups 0x00000140
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000140
+#define AOFF_task_groups 0x00000144
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x000001c0
+#define AOFF_task_cap_effective 0x000001c4
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x000001c4
+#define AOFF_task_cap_inheritable 0x000001c8
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000001c8
+#define AOFF_task_cap_permitted 0x000001cc
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000001d0
+#define AOFF_task_user 0x000001d4
#define ASIZ_task_user 0x00000004
-#define AOFF_task_rlim 0x000001d4
+#define AOFF_task_rlim 0x000001d8
#define ASIZ_task_rlim 0x00000050
-#define AOFF_task_used_math 0x00000224
+#define AOFF_task_used_math 0x00000228
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x00000226
+#define AOFF_task_comm 0x0000022a
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x00000238
+#define AOFF_task_link_count 0x0000023c
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x0000023c
+#define AOFF_task_tty 0x00000240
#define ASIZ_task_tty 0x00000004
-#define AOFF_task_semundo 0x00000240
+#define AOFF_task_semundo 0x00000244
#define ASIZ_task_semundo 0x00000004
-#define AOFF_task_semsleeping 0x00000244
+#define AOFF_task_semsleeping 0x00000248
#define ASIZ_task_semsleeping 0x00000004
-#define AOFF_task_thread 0x00000248
+#define AOFF_task_thread 0x00000250
#define ASIZ_task_thread 0x00000380
-#define AOFF_task_fs 0x000005c8
+#define AOFF_task_fs 0x000005d0
#define ASIZ_task_fs 0x00000004
-#define AOFF_task_files 0x000005cc
+#define AOFF_task_files 0x000005d4
#define ASIZ_task_files 0x00000004
-#define AOFF_task_sigmask_lock 0x000005d0
+#define AOFF_task_sigmask_lock 0x000005d8
#define ASIZ_task_sigmask_lock 0x00000004
-#define AOFF_task_sig 0x000005d4
+#define AOFF_task_sig 0x000005dc
#define ASIZ_task_sig 0x00000004
-#define AOFF_task_signal 0x000005d8
+#define AOFF_task_signal 0x000005e0
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x000005e0
+#define AOFF_task_blocked 0x000005e8
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x000005e8
+#define AOFF_task_sigqueue 0x000005f0
#define ASIZ_task_sigqueue 0x00000004
-#define AOFF_task_sigqueue_tail 0x000005ec
+#define AOFF_task_sigqueue_tail 0x000005f4
#define ASIZ_task_sigqueue_tail 0x00000004
-#define AOFF_task_sas_ss_sp 0x000005f0
+#define AOFF_task_sas_ss_sp 0x000005f8
#define ASIZ_task_sas_ss_sp 0x00000004
-#define AOFF_task_sas_ss_size 0x000005f4
+#define AOFF_task_sas_ss_size 0x000005fc
#define ASIZ_task_sas_ss_size 0x00000004
-#define AOFF_task_parent_exec_id 0x000005f8
+#define AOFF_task_parent_exec_id 0x00000600
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x000005fc
+#define AOFF_task_self_exec_id 0x00000604
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x00000600
+#define AOFF_task_alloc_lock 0x00000608
#define ASIZ_task_alloc_lock 0x00000004
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000004
@@ -317,127 +319,129 @@
#define ASIZ_task_has_cpu 0x00000004
#define AOFF_task_processor 0x00000038
#define ASIZ_task_processor 0x00000004
-#define AOFF_task_run_list 0x0000003c
+#define AOFF_task_ptrace 0x0000003c
+#define ASIZ_task_ptrace 0x00000004
+#define AOFF_task_run_list 0x00000040
#define ASIZ_task_run_list 0x00000008
-#define AOFF_task_next_task 0x00000044
+#define AOFF_task_next_task 0x00000048
#define ASIZ_task_next_task 0x00000004
-#define AOFF_task_prev_task 0x00000048
+#define AOFF_task_prev_task 0x0000004c
#define ASIZ_task_prev_task 0x00000004
-#define AOFF_task_last_processor 0x0000004c
+#define AOFF_task_last_processor 0x00000050
#define ASIZ_task_last_processor 0x00000004
-#define AOFF_task_binfmt 0x00000050
+#define AOFF_task_binfmt 0x00000054
#define ASIZ_task_binfmt 0x00000004
-#define AOFF_task_exit_code 0x00000054
+#define AOFF_task_exit_code 0x00000058
#define ASIZ_task_exit_code 0x00000004
-#define AOFF_task_exit_signal 0x00000058
+#define AOFF_task_exit_signal 0x0000005c
#define ASIZ_task_exit_signal 0x00000004
-#define AOFF_task_pdeath_signal 0x0000005c
+#define AOFF_task_pdeath_signal 0x00000060
#define ASIZ_task_pdeath_signal 0x00000004
-#define AOFF_task_personality 0x00000060
+#define AOFF_task_personality 0x00000064
#define ASIZ_task_personality 0x00000004
-#define AOFF_task_pid 0x00000068
+#define AOFF_task_pid 0x0000006c
#define ASIZ_task_pid 0x00000004
-#define AOFF_task_pgrp 0x0000006c
+#define AOFF_task_pgrp 0x00000070
#define ASIZ_task_pgrp 0x00000004
-#define AOFF_task_tty_old_pgrp 0x00000070
+#define AOFF_task_tty_old_pgrp 0x00000074
#define ASIZ_task_tty_old_pgrp 0x00000004
-#define AOFF_task_session 0x00000074
+#define AOFF_task_session 0x00000078
#define ASIZ_task_session 0x00000004
-#define AOFF_task_leader 0x00000078
+#define AOFF_task_leader 0x0000007c
#define ASIZ_task_leader 0x00000004
-#define AOFF_task_p_opptr 0x0000007c
+#define AOFF_task_p_opptr 0x00000080
#define ASIZ_task_p_opptr 0x00000004
-#define AOFF_task_p_pptr 0x00000080
+#define AOFF_task_p_pptr 0x00000084
#define ASIZ_task_p_pptr 0x00000004
-#define AOFF_task_p_cptr 0x00000084
+#define AOFF_task_p_cptr 0x00000088
#define ASIZ_task_p_cptr 0x00000004
-#define AOFF_task_p_ysptr 0x00000088
+#define AOFF_task_p_ysptr 0x0000008c
#define ASIZ_task_p_ysptr 0x00000004
-#define AOFF_task_p_osptr 0x0000008c
+#define AOFF_task_p_osptr 0x00000090
#define ASIZ_task_p_osptr 0x00000004
-#define AOFF_task_pidhash_next 0x00000090
+#define AOFF_task_pidhash_next 0x00000094
#define ASIZ_task_pidhash_next 0x00000004
-#define AOFF_task_pidhash_pprev 0x00000094
+#define AOFF_task_pidhash_pprev 0x00000098
#define ASIZ_task_pidhash_pprev 0x00000004
-#define AOFF_task_wait_chldexit 0x00000098
+#define AOFF_task_wait_chldexit 0x0000009c
#define ASIZ_task_wait_chldexit 0x00000018
-#define AOFF_task_vfork_sem 0x000000b0
+#define AOFF_task_vfork_sem 0x000000b4
#define ASIZ_task_vfork_sem 0x00000004
-#define AOFF_task_rt_priority 0x000000b4
+#define AOFF_task_rt_priority 0x000000b8
#define ASIZ_task_rt_priority 0x00000004
-#define AOFF_task_it_real_value 0x000000b8
+#define AOFF_task_it_real_value 0x000000bc
#define ASIZ_task_it_real_value 0x00000004
-#define AOFF_task_it_prof_value 0x000000bc
+#define AOFF_task_it_prof_value 0x000000c0
#define ASIZ_task_it_prof_value 0x00000004
-#define AOFF_task_it_virt_value 0x000000c0
+#define AOFF_task_it_virt_value 0x000000c4
#define ASIZ_task_it_virt_value 0x00000004
-#define AOFF_task_it_real_incr 0x000000c4
+#define AOFF_task_it_real_incr 0x000000c8
#define ASIZ_task_it_real_incr 0x00000004
-#define AOFF_task_it_prof_incr 0x000000c8
+#define AOFF_task_it_prof_incr 0x000000cc
#define ASIZ_task_it_prof_incr 0x00000004
-#define AOFF_task_it_virt_incr 0x000000cc
+#define AOFF_task_it_virt_incr 0x000000d0
#define ASIZ_task_it_virt_incr 0x00000004
-#define AOFF_task_real_timer 0x000000d0
+#define AOFF_task_real_timer 0x000000d4
#define ASIZ_task_real_timer 0x00000018
-#define AOFF_task_times 0x000000e8
+#define AOFF_task_times 0x000000ec
#define ASIZ_task_times 0x00000010
-#define AOFF_task_start_time 0x000000f8
+#define AOFF_task_start_time 0x000000fc
#define ASIZ_task_start_time 0x00000004
-#define AOFF_task_per_cpu_utime 0x000000fc
+#define AOFF_task_per_cpu_utime 0x00000100
#define ASIZ_task_per_cpu_utime 0x00000080
-#define AOFF_task_min_flt 0x000001fc
+#define AOFF_task_min_flt 0x00000200
#define ASIZ_task_min_flt 0x00000004
-#define AOFF_task_maj_flt 0x00000200
+#define AOFF_task_maj_flt 0x00000204
#define ASIZ_task_maj_flt 0x00000004
-#define AOFF_task_nswap 0x00000204
+#define AOFF_task_nswap 0x00000208
#define ASIZ_task_nswap 0x00000004
-#define AOFF_task_cmin_flt 0x00000208
+#define AOFF_task_cmin_flt 0x0000020c
#define ASIZ_task_cmin_flt 0x00000004
-#define AOFF_task_cmaj_flt 0x0000020c
+#define AOFF_task_cmaj_flt 0x00000210
#define ASIZ_task_cmaj_flt 0x00000004
-#define AOFF_task_cnswap 0x00000210
+#define AOFF_task_cnswap 0x00000214
#define ASIZ_task_cnswap 0x00000004
-#define AOFF_task_uid 0x00000218
+#define AOFF_task_uid 0x0000021c
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x0000021c
+#define AOFF_task_euid 0x00000220
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x00000220
+#define AOFF_task_suid 0x00000224
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000224
+#define AOFF_task_fsuid 0x00000228
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x00000228
+#define AOFF_task_gid 0x0000022c
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x0000022c
+#define AOFF_task_egid 0x00000230
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x00000230
+#define AOFF_task_sgid 0x00000234
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000234
+#define AOFF_task_fsgid 0x00000238
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x00000238
+#define AOFF_task_ngroups 0x0000023c
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x0000023c
+#define AOFF_task_groups 0x00000240
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x000002bc
+#define AOFF_task_cap_effective 0x000002c0
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x000002c0
+#define AOFF_task_cap_inheritable 0x000002c4
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000002c4
+#define AOFF_task_cap_permitted 0x000002c8
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000002cc
+#define AOFF_task_user 0x000002d0
#define ASIZ_task_user 0x00000004
-#define AOFF_task_rlim 0x000002d0
+#define AOFF_task_rlim 0x000002d4
#define ASIZ_task_rlim 0x00000050
-#define AOFF_task_used_math 0x00000320
+#define AOFF_task_used_math 0x00000324
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x00000322
+#define AOFF_task_comm 0x00000326
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x00000334
+#define AOFF_task_link_count 0x00000338
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000338
+#define AOFF_task_tty 0x0000033c
#define ASIZ_task_tty 0x00000004
-#define AOFF_task_semundo 0x0000033c
+#define AOFF_task_semundo 0x00000340
#define ASIZ_task_semundo 0x00000004
-#define AOFF_task_semsleeping 0x00000340
+#define AOFF_task_semsleeping 0x00000344
#define ASIZ_task_semsleeping 0x00000004
#define AOFF_task_thread 0x00000348
#define ASIZ_task_thread 0x00000380
diff --git a/include/asm-sparc/head.h b/include/asm-sparc/head.h
index b0f06a0bcf4303..f781635d68406c 100644
--- a/include/asm-sparc/head.h
+++ b/include/asm-sparc/head.h
@@ -1,4 +1,4 @@
-/* $Id: head.h,v 1.38 1999/12/01 23:52:04 davem Exp $ */
+/* $Id: head.h,v 1.39 2000/05/26 22:18:45 ecd Exp $ */
#ifndef __SPARC_HEAD_H
#define __SPARC_HEAD_H
@@ -95,7 +95,7 @@
/* The Get PSR software trap for userland. */
#define GETPSR_TRAP \
- mov %psr, %o0; jmpl %l2, %g0; rett %l2 + 4; nop;
+ mov %psr, %i0; jmp %l2; rett %l2 + 4; nop;
/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
* gets handled with another macro.
diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h
index aa0bcbfdbd723d..d4254fa1eeba3c 100644
--- a/include/asm-sparc/ide.h
+++ b/include/asm-sparc/ide.h
@@ -1,4 +1,4 @@
-/* $Id: ide.h,v 1.5 2000/05/22 07:29:43 davem Exp $
+/* $Id: ide.h,v 1.6 2000/05/27 00:49:37 davem Exp $
* ide.h: SPARC PCI specific IDE glue.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
diff --git a/include/asm-sparc/kdebug.h b/include/asm-sparc/kdebug.h
index 8a0fdfd512720e..3ea4916635ee62 100644
--- a/include/asm-sparc/kdebug.h
+++ b/include/asm-sparc/kdebug.h
@@ -1,4 +1,4 @@
-/* $Id: kdebug.h,v 1.10 1997/12/14 23:24:40 ecd Exp $
+/* $Id: kdebug.h,v 1.11 2000/06/04 06:23:53 anton Exp $
* kdebug.h: Defines and definitions for debugging the Linux kernel
* under various kernel debuggers.
*
@@ -8,13 +8,7 @@
#define _SPARC_KDEBUG_H
#include <asm/openprom.h>
-
-/* The debugger lives in 1MB of virtual address space right underneath
- * the boot prom.
- */
-
-#define DEBUG_FIRSTVADDR 0xffc00000
-#define DEBUG_LASTVADDR LINUX_OPPROM_BEGVM
+#include <asm/vaddrs.h>
/* Breakpoints are enter through trap table entry 126. So in sparc assembly
* if you want to drop into the debugger you do:
diff --git a/include/asm-sparc/mc146818rtc.h b/include/asm-sparc/mc146818rtc.h
new file mode 100644
index 00000000000000..9431df163779dd
--- /dev/null
+++ b/include/asm-sparc/mc146818rtc.h
@@ -0,0 +1,27 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_SPARC_MC146818RTC_H
+#define __ASM_SPARC_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* __ASM_SPARC_MC146818RTC_H */
diff --git a/include/asm-sparc/openprom.h b/include/asm-sparc/openprom.h
index c88dc02a175670..12929a20f53682 100644
--- a/include/asm-sparc/openprom.h
+++ b/include/asm-sparc/openprom.h
@@ -1,4 +1,4 @@
-/* $Id: openprom.h,v 1.23 1998/09/21 05:07:26 jj Exp $ */
+/* $Id: openprom.h,v 1.24 2000/06/04 06:23:53 anton Exp $ */
#ifndef __SPARC_OPENPROM_H
#define __SPARC_OPENPROM_H
@@ -8,10 +8,9 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <asm/vaddrs.h>
+
/* Empirical constants... */
-#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */
-#define LINUX_OPPROM_BEGVM 0xffd00000
-#define LINUX_OPPROM_ENDVM 0xfff00000
#define LINUX_OPPROM_MAGIC 0x10010407
#ifndef __ASSEMBLY__
diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h
index 379c8cc97ac533..c727c06d8a9e35 100644
--- a/include/asm-sparc/page.h
+++ b/include/asm-sparc/page.h
@@ -1,4 +1,4 @@
-/* $Id: page.h,v 1.52 2000/03/28 06:07:25 anton Exp $
+/* $Id: page.h,v 1.53 2000/06/04 08:36:33 anton Exp $
* page.h: Various defines and such for MMU operations on the Sparc for
* the Linux kernel.
*
@@ -32,7 +32,13 @@
#ifndef __ASSEMBLY__
-#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
+/*
+ * XXX I am hitting compiler bugs with __builtin_trap. This has
+ * hit me before and rusty was blaming his netfilter bugs on
+ * this so lets disable it. - Anton
+ */
+#if 0
+/* #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) */
/* We need the mb()'s so we don't trigger a compiler bug - Anton */
#define BUG() do { \
mb(); \
diff --git a/include/asm-sparc/pgalloc.h b/include/asm-sparc/pgalloc.h
index c0850c9a9f334e..71a03dc0207d6a 100644
--- a/include/asm-sparc/pgalloc.h
+++ b/include/asm-sparc/pgalloc.h
@@ -1,4 +1,4 @@
-/* $Id: pgalloc.h,v 1.4 2000/05/09 17:40:15 davem Exp $ */
+/* $Id: pgalloc.h,v 1.5 2000/06/04 06:23:53 anton Exp $ */
#ifndef _SPARC_PGALLOC_H
#define _SPARC_PGALLOC_H
@@ -103,23 +103,7 @@ extern struct pgtable_cache_struct {
#define pgtable_cache_size (pgt_quicklists.pgtable_cache_sz)
#define pgd_cache_size (pgt_quicklists.pgd_cache_sz)
-BTFIXUPDEF_CALL(pte_t *, get_pte_fast, void)
-BTFIXUPDEF_CALL(pgd_t *, get_pgd_fast, void)
-BTFIXUPDEF_CALL(void, free_pte_slow, pte_t *)
-BTFIXUPDEF_CALL(void, free_pgd_slow, pgd_t *)
BTFIXUPDEF_CALL(int, do_check_pgt_cache, int, int)
-
-#define get_pte_fast() BTFIXUP_CALL(get_pte_fast)()
-extern __inline__ pmd_t *get_pmd_fast(void)
-{
- return (pmd_t *)0;
-}
-#define get_pgd_fast() BTFIXUP_CALL(get_pgd_fast)()
-#define free_pte_slow(pte) BTFIXUP_CALL(free_pte_slow)(pte)
-extern __inline__ void free_pmd_slow(pmd_t *pmd)
-{
-}
-#define free_pgd_slow(pgd) BTFIXUP_CALL(free_pgd_slow)(pgd)
#define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high)
/*
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
index 04b34e5e92b225..a4a1ef3cea9dda 100644
--- a/include/asm-sparc/pgtable.h
+++ b/include/asm-sparc/pgtable.h
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.94 2000/03/28 06:07:25 anton Exp $ */
+/* $Id: pgtable.h,v 1.96 2000/06/05 06:08:46 anton Exp $ */
#ifndef _SPARC_PGTABLE_H
#define _SPARC_PGTABLE_H
@@ -52,19 +52,14 @@ BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct scatterlist *, int, struct s
/*
* mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
- * mmu_flush/inval belong to CPU. Valid on IIep.
*/
BTFIXUPDEF_CALL(void, mmu_map_dma_area, unsigned long va, __u32 addr, int len)
BTFIXUPDEF_CALL(unsigned long /*phys*/, mmu_translate_dvma, unsigned long busa)
BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, unsigned long busa, int len)
-BTFIXUPDEF_CALL(void, mmu_inval_dma_area, unsigned long virt, int len)
-BTFIXUPDEF_CALL(void, mmu_flush_dma_area, unsigned long virt, int len)
#define mmu_map_dma_area(va, ba,len) BTFIXUP_CALL(mmu_map_dma_area)(va,ba,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)
-#define mmu_inval_dma_area(va,len) BTFIXUP_CALL(mmu_inval_dma_area)(va,len)
-#define mmu_flush_dma_area(va,len) BTFIXUP_CALL(mmu_flush_dma_area)(va,len)
BTFIXUPDEF_SIMM13(pmd_shift)
BTFIXUPDEF_SETHI(pmd_size)
@@ -92,9 +87,6 @@ BTFIXUPDEF_SIMM13(ptrs_per_pgd)
BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-/* This is the same accross all platforms */
-#define VMALLOC_START (0xfe300000)
-#define VMALLOC_END ~0x0UL
#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
#define pte_ERROR(e) __builtin_trap()
diff --git a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
index fc569dcafd234a..d8f68c3fbc8d76 100644
--- a/include/asm-sparc/pgtsrmmu.h
+++ b/include/asm-sparc/pgtsrmmu.h
@@ -1,4 +1,4 @@
-/* $Id: pgtsrmmu.h,v 1.29 1998/07/26 03:05:42 davem Exp $
+/* $Id: pgtsrmmu.h,v 1.30 2000/06/05 06:08:46 anton Exp $
* pgtsrmmu.h: SRMMU page table defines and code.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -29,9 +29,6 @@
#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_VMALLOC_START (0xfe300000)
-#define SRMMU_VMALLOC_END ~0x0UL
-
/* Definition of the values in the ET field of PTD's and PTE's */
#define SRMMU_ET_MASK 0x3
#define SRMMU_ET_INVALID 0x0
diff --git a/include/asm-sparc/pgtsun4.h b/include/asm-sparc/pgtsun4.h
index d9d8afaa2bb15d..1c6efda336c7e9 100644
--- a/include/asm-sparc/pgtsun4.h
+++ b/include/asm-sparc/pgtsun4.h
@@ -1,4 +1,4 @@
-/* $Id: pgtsun4.h,v 1.4 1998/07/26 03:05:42 davem Exp $
+/* $Id: pgtsun4.h,v 1.5 2000/06/05 06:08:46 anton Exp $
* pgtsun4.h: Sun4 specific pgtable.h defines and code.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -43,13 +43,6 @@
#define SUN4C_PTRS_PER_PMD 1
#define SUN4C_PTRS_PER_PGD 1024
-/* On the sun4 the physical ram limit is 128MB. We set up our I/O
- * translations at KERNBASE + 128MB for 1MB, then we begin the VMALLOC
- * area, makes sense. This works out to the value below.
- */
-#define SUN4C_VMALLOC_START (0xfe300000)
-#define SUN4C_VMALLOC_END ~0x0UL
-
/*
* Sparc SUN4C pte fields.
*/
diff --git a/include/asm-sparc/pgtsun4c.h b/include/asm-sparc/pgtsun4c.h
index 197f4afcaa2bb2..0cc124655045c5 100644
--- a/include/asm-sparc/pgtsun4c.h
+++ b/include/asm-sparc/pgtsun4c.h
@@ -1,4 +1,4 @@
-/* $Id: pgtsun4c.h,v 1.36 1998/07/26 03:05:44 davem Exp $
+/* $Id: pgtsun4c.h,v 1.37 2000/06/05 06:08:46 anton Exp $
* pgtsun4c.h: Sun4c specific pgtable.h defines and code.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -42,13 +42,6 @@
#define SUN4C_PTRS_PER_PMD 1
#define SUN4C_PTRS_PER_PGD 1024
-/* On the sun4c the physical ram limit is 128MB. We set up our I/O
- * translations at KERNBASE + 128MB for 1MB, then we begin the VMALLOC
- * area, makes sense. This works out to the value below.
- */
-#define SUN4C_VMALLOC_START (0xfe300000)
-#define SUN4C_VMALLOC_END ~0x0UL
-
/*
* Sparc SUN4C pte fields.
*/
diff --git a/include/asm-sparc/siginfo.h b/include/asm-sparc/siginfo.h
index d8d3a4c27c97f1..61e4ef22fc9432 100644
--- a/include/asm-sparc/siginfo.h
+++ b/include/asm-sparc/siginfo.h
@@ -1,4 +1,4 @@
-/* $Id: siginfo.h,v 1.7 2000/01/29 07:41:51 davem Exp $
+/* $Id: siginfo.h,v 1.8 2000/05/27 00:49:37 davem Exp $
* siginfo.c:
*/
diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h
index f749e34451307d..cbcebff57f7aa0 100644
--- a/include/asm-sparc/socket.h
+++ b/include/asm-sparc/socket.h
@@ -1,4 +1,4 @@
-/* $Id: socket.h,v 1.13 2000/02/27 19:47:43 davem Exp $ */
+/* $Id: socket.h,v 1.14 2000/06/09 07:35:28 davem Exp $ */
#ifndef _ASM_SOCKET_H
#define _ASM_SOCKET_H
@@ -47,4 +47,19 @@
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
#define SO_SECURITY_ENCRYPTION_NETWORK 0x5004
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM 1 /* stream (connection) socket */
+#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
+#define SOCK_RAW 3 /* raw socket */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequential packet socket */
+#define SOCK_PACKET 10 /* linux specific way of */
+ /* getting packets at the dev */
+ /* level. For writing rarp and */
+ /* other similar things on the */
+ /* user level. */
+#endif
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-sparc/vaddrs.h b/include/asm-sparc/vaddrs.h
index 1c76a9b9d22ae6..5cbec82101707e 100644
--- a/include/asm-sparc/vaddrs.h
+++ b/include/asm-sparc/vaddrs.h
@@ -1,38 +1,27 @@
-/* $Id: vaddrs.h,v 1.23 2000/03/12 04:10:46 davem Exp $ */
+/* $Id: vaddrs.h,v 1.25 2000/06/05 06:08:46 anton Exp $ */
#ifndef _SPARC_VADDRS_H
#define _SPARC_VADDRS_H
#include <asm/head.h>
-/* asm-sparc/vaddrs.h: Here will be define the virtual addresses at
- * which important I/O addresses will be mapped.
- * For instance the timer register virtual address
- * is defined here.
+/*
+ * asm-sparc/vaddrs.h: Here we define the virtual addresses at
+ * which important things will be mapped.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
*/
-/* I can see only one reason why we should have statically defined
- * mappings for devices and is the speedup improvements of not loading
- * a pointer and then the value in the assembly code
- */
-#define IOBASE_VADDR 0xfe000000 /* Base for mapping pages */
-#define IOBASE_LEN 0x00300000 /* Length of the IO area */
-#define IOBASE_END 0xfe300000
-#define DVMA_VADDR 0xfff00000 /* Base area of the DVMA on suns */
-#define DVMA_LEN 0x000c0000 /* Size of the DVMA address space */
-#define DVMA_END 0xfffc0000
+#define SUN4M_IOBASE_VADDR 0xfd000000 /* Base for mapping pages */
+#define IOBASE_VADDR 0xfe000000
+#define IOBASE_END 0xfe300000
-/* IOMMU Mapping area, must be on a 16MB boundary! Note this
- * doesn't count the DVMA areas, the prom lives between the
- * iommu mapping area (for scsi transfer buffers) and the
- * dvma upper range (for lance packet ring buffers).
- */
-#define IOMMU_VADDR 0xff000000
-#define IOMMU_LEN 0x00c00000
-#define IOMMU_END 0xffc00000 /* KADB debugger vm starts here */
+#define VMALLOC_START 0xfe300000
+/* XXX Alter this when I get around to fixing sun4c - Anton */
+#define VMALLOC_END 0xffc00000
-/* On the sun4/4c we don't need an IOMMU area, but we need a place
+/*
+ * On the sun4/4c we need a place
* to reliably map locked down kernel data. This includes the
* task_struct and kernel stack pages of each process plus the
* scsi buffers during dvma IO transfers, also the floppy buffers
@@ -44,22 +33,18 @@
* careful if you change NR_TASKS or else there won't be enough
* room for it all.
*/
-#define SUN4C_LOCK_VADDR 0xff000000
-#define SUN4C_LOCK_LEN 0x00c00000
-#define SUN4C_LOCK_END 0xffc00000
+#define SUN4C_LOCK_VADDR 0xff000000
+#define SUN4C_LOCK_END 0xffc00000
-/* On sun4m machines we need per-cpu virtual areas */
-#define PERCPU_VADDR 0xffc00000 /* Base for per-cpu virtual mappings */
-#define PERCPU_ENTSIZE 0x00100000
-#define PERCPU_LEN ((PERCPU_ENTSIZE*SUN4M_NCPUS))
+#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */
+#define KADB_DEBUGGER_ENDVM 0xffd00000
+#define DEBUG_FIRSTVADDR KADB_DEBUGGER_BEGVM
+#define DEBUG_LASTVADDR KADB_DEBUGGER_ENDVM
-/* per-cpu offsets */
-#define PERCPU_TBR_OFFSET 0x00000 /* %tbr, mainly used for identification. */
-#define PERCPU_KSTACK_OFFSET 0x01000 /* Beginning of kernel stack for this cpu */
-#define PERCPU_MBOX_OFFSET 0x03000 /* Prom SMP Mailbox */
-#define PERCPU_CPUID_OFFSET 0x04000 /* Per-cpu ID number. */
-#define PERCPU_ISALIVE_OFFSET 0x04004 /* Has CPU been initted yet? */
-#define PERCPU_ISIDLING_OFFSET 0x04008 /* Is CPU in idle loop spinning? */
+#define LINUX_OPPROM_BEGVM 0xffd00000
+#define LINUX_OPPROM_ENDVM 0xfff00000
-#endif /* !(_SPARC_VADDRS_H) */
+#define DVMA_VADDR 0xfff00000 /* Base area of the DVMA on suns */
+#define DVMA_END 0xfffc0000
+#endif /* !(_SPARC_VADDRS_H) */
diff --git a/include/asm-sparc64/asm_offsets.h b/include/asm-sparc64/asm_offsets.h
index 4507a67168586b..70e1356fd86391 100644
--- a/include/asm-sparc64/asm_offsets.h
+++ b/include/asm-sparc64/asm_offsets.h
@@ -42,157 +42,159 @@
#define ASIZ_task_has_cpu 0x00000004
#define AOFF_task_processor 0x00000064
#define ASIZ_task_processor 0x00000004
-#define AOFF_task_run_list 0x00000068
+#define AOFF_task_ptrace 0x00000068
+#define ASIZ_task_ptrace 0x00000008
+#define AOFF_task_run_list 0x00000070
#define ASIZ_task_run_list 0x00000010
-#define AOFF_task_next_task 0x00000078
+#define AOFF_task_next_task 0x00000080
#define ASIZ_task_next_task 0x00000008
-#define AOFF_task_prev_task 0x00000080
+#define AOFF_task_prev_task 0x00000088
#define ASIZ_task_prev_task 0x00000008
-#define AOFF_task_last_processor 0x00000088
+#define AOFF_task_last_processor 0x00000090
#define ASIZ_task_last_processor 0x00000004
-#define AOFF_task_binfmt 0x00000090
+#define AOFF_task_binfmt 0x00000098
#define ASIZ_task_binfmt 0x00000008
-#define AOFF_task_exit_code 0x00000098
+#define AOFF_task_exit_code 0x000000a0
#define ASIZ_task_exit_code 0x00000004
-#define AOFF_task_exit_signal 0x0000009c
+#define AOFF_task_exit_signal 0x000000a4
#define ASIZ_task_exit_signal 0x00000004
-#define AOFF_task_pdeath_signal 0x000000a0
+#define AOFF_task_pdeath_signal 0x000000a8
#define ASIZ_task_pdeath_signal 0x00000004
-#define AOFF_task_personality 0x000000a8
+#define AOFF_task_personality 0x000000b0
#define ASIZ_task_personality 0x00000008
-#define AOFF_task_pid 0x000000b4
+#define AOFF_task_pid 0x000000bc
#define ASIZ_task_pid 0x00000004
-#define AOFF_task_pgrp 0x000000b8
+#define AOFF_task_pgrp 0x000000c0
#define ASIZ_task_pgrp 0x00000004
-#define AOFF_task_tty_old_pgrp 0x000000bc
+#define AOFF_task_tty_old_pgrp 0x000000c4
#define ASIZ_task_tty_old_pgrp 0x00000004
-#define AOFF_task_session 0x000000c0
+#define AOFF_task_session 0x000000c8
#define ASIZ_task_session 0x00000004
-#define AOFF_task_leader 0x000000c4
+#define AOFF_task_leader 0x000000cc
#define ASIZ_task_leader 0x00000004
-#define AOFF_task_p_opptr 0x000000c8
+#define AOFF_task_p_opptr 0x000000d0
#define ASIZ_task_p_opptr 0x00000008
-#define AOFF_task_p_pptr 0x000000d0
+#define AOFF_task_p_pptr 0x000000d8
#define ASIZ_task_p_pptr 0x00000008
-#define AOFF_task_p_cptr 0x000000d8
+#define AOFF_task_p_cptr 0x000000e0
#define ASIZ_task_p_cptr 0x00000008
-#define AOFF_task_p_ysptr 0x000000e0
+#define AOFF_task_p_ysptr 0x000000e8
#define ASIZ_task_p_ysptr 0x00000008
-#define AOFF_task_p_osptr 0x000000e8
+#define AOFF_task_p_osptr 0x000000f0
#define ASIZ_task_p_osptr 0x00000008
-#define AOFF_task_pidhash_next 0x000000f0
+#define AOFF_task_pidhash_next 0x000000f8
#define ASIZ_task_pidhash_next 0x00000008
-#define AOFF_task_pidhash_pprev 0x000000f8
+#define AOFF_task_pidhash_pprev 0x00000100
#define ASIZ_task_pidhash_pprev 0x00000008
-#define AOFF_task_wait_chldexit 0x00000100
+#define AOFF_task_wait_chldexit 0x00000108
#define ASIZ_task_wait_chldexit 0x00000028
-#define AOFF_task_vfork_sem 0x00000128
+#define AOFF_task_vfork_sem 0x00000130
#define ASIZ_task_vfork_sem 0x00000008
-#define AOFF_task_rt_priority 0x00000130
+#define AOFF_task_rt_priority 0x00000138
#define ASIZ_task_rt_priority 0x00000008
-#define AOFF_task_it_real_value 0x00000138
+#define AOFF_task_it_real_value 0x00000140
#define ASIZ_task_it_real_value 0x00000008
-#define AOFF_task_it_prof_value 0x00000140
+#define AOFF_task_it_prof_value 0x00000148
#define ASIZ_task_it_prof_value 0x00000008
-#define AOFF_task_it_virt_value 0x00000148
+#define AOFF_task_it_virt_value 0x00000150
#define ASIZ_task_it_virt_value 0x00000008
-#define AOFF_task_it_real_incr 0x00000150
+#define AOFF_task_it_real_incr 0x00000158
#define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000158
+#define AOFF_task_it_prof_incr 0x00000160
#define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000160
+#define AOFF_task_it_virt_incr 0x00000168
#define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer 0x00000168
+#define AOFF_task_real_timer 0x00000170
#define ASIZ_task_real_timer 0x00000030
-#define AOFF_task_times 0x00000198
+#define AOFF_task_times 0x000001a0
#define ASIZ_task_times 0x00000020
-#define AOFF_task_start_time 0x000001b8
+#define AOFF_task_start_time 0x000001c0
#define ASIZ_task_start_time 0x00000008
-#define AOFF_task_per_cpu_utime 0x000001c0
+#define AOFF_task_per_cpu_utime 0x000001c8
#define ASIZ_task_per_cpu_utime 0x00000008
-#define AOFF_task_min_flt 0x000001d0
+#define AOFF_task_min_flt 0x000001d8
#define ASIZ_task_min_flt 0x00000008
-#define AOFF_task_maj_flt 0x000001d8
+#define AOFF_task_maj_flt 0x000001e0
#define ASIZ_task_maj_flt 0x00000008
-#define AOFF_task_nswap 0x000001e0
+#define AOFF_task_nswap 0x000001e8
#define ASIZ_task_nswap 0x00000008
-#define AOFF_task_cmin_flt 0x000001e8
+#define AOFF_task_cmin_flt 0x000001f0
#define ASIZ_task_cmin_flt 0x00000008
-#define AOFF_task_cmaj_flt 0x000001f0
+#define AOFF_task_cmaj_flt 0x000001f8
#define ASIZ_task_cmaj_flt 0x00000008
-#define AOFF_task_cnswap 0x000001f8
+#define AOFF_task_cnswap 0x00000200
#define ASIZ_task_cnswap 0x00000008
-#define AOFF_task_uid 0x00000204
+#define AOFF_task_uid 0x0000020c
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x00000208
+#define AOFF_task_euid 0x00000210
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x0000020c
+#define AOFF_task_suid 0x00000214
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000210
+#define AOFF_task_fsuid 0x00000218
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x00000214
+#define AOFF_task_gid 0x0000021c
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000218
+#define AOFF_task_egid 0x00000220
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x0000021c
+#define AOFF_task_sgid 0x00000224
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000220
+#define AOFF_task_fsgid 0x00000228
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x00000224
+#define AOFF_task_ngroups 0x0000022c
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000228
+#define AOFF_task_groups 0x00000230
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x000002a8
+#define AOFF_task_cap_effective 0x000002b0
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x000002ac
+#define AOFF_task_cap_inheritable 0x000002b4
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000002b0
+#define AOFF_task_cap_permitted 0x000002b8
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000002b8
+#define AOFF_task_user 0x000002c0
#define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x000002c0
+#define AOFF_task_rlim 0x000002c8
#define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math 0x00000360
+#define AOFF_task_used_math 0x00000368
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x00000362
+#define AOFF_task_comm 0x0000036a
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x00000374
+#define AOFF_task_link_count 0x0000037c
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000378
+#define AOFF_task_tty 0x00000380
#define ASIZ_task_tty 0x00000008
-#define AOFF_task_semundo 0x00000380
+#define AOFF_task_semundo 0x00000388
#define ASIZ_task_semundo 0x00000008
-#define AOFF_task_semsleeping 0x00000388
+#define AOFF_task_semsleeping 0x00000390
#define ASIZ_task_semsleeping 0x00000008
-#define AOFF_task_thread 0x00000390
+#define AOFF_task_thread 0x000003a0
#define ASIZ_task_thread 0x00000450
-#define AOFF_task_fs 0x000007e0
+#define AOFF_task_fs 0x000007f0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000007e8
+#define AOFF_task_files 0x000007f8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000007f0
+#define AOFF_task_sigmask_lock 0x00000800
#define ASIZ_task_sigmask_lock 0x00000004
-#define AOFF_task_sig 0x000007f8
+#define AOFF_task_sig 0x00000808
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x00000800
+#define AOFF_task_signal 0x00000810
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x00000808
+#define AOFF_task_blocked 0x00000818
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000810
+#define AOFF_task_sigqueue 0x00000820
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000818
+#define AOFF_task_sigqueue_tail 0x00000828
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000820
+#define AOFF_task_sas_ss_sp 0x00000830
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000828
+#define AOFF_task_sas_ss_size 0x00000838
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000830
+#define AOFF_task_parent_exec_id 0x00000840
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000834
+#define AOFF_task_self_exec_id 0x00000844
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x00000838
+#define AOFF_task_alloc_lock 0x00000848
#define ASIZ_task_alloc_lock 0x00000004
-#define ASIZ_task 0x00000840
+#define ASIZ_task 0x00000850
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -336,157 +338,159 @@
#define ASIZ_task_has_cpu 0x00000004
#define AOFF_task_processor 0x00000064
#define ASIZ_task_processor 0x00000004
-#define AOFF_task_run_list 0x00000068
+#define AOFF_task_ptrace 0x00000068
+#define ASIZ_task_ptrace 0x00000008
+#define AOFF_task_run_list 0x00000070
#define ASIZ_task_run_list 0x00000010
-#define AOFF_task_next_task 0x00000078
+#define AOFF_task_next_task 0x00000080
#define ASIZ_task_next_task 0x00000008
-#define AOFF_task_prev_task 0x00000080
+#define AOFF_task_prev_task 0x00000088
#define ASIZ_task_prev_task 0x00000008
-#define AOFF_task_last_processor 0x00000088
+#define AOFF_task_last_processor 0x00000090
#define ASIZ_task_last_processor 0x00000004
-#define AOFF_task_binfmt 0x00000090
+#define AOFF_task_binfmt 0x00000098
#define ASIZ_task_binfmt 0x00000008
-#define AOFF_task_exit_code 0x00000098
+#define AOFF_task_exit_code 0x000000a0
#define ASIZ_task_exit_code 0x00000004
-#define AOFF_task_exit_signal 0x0000009c
+#define AOFF_task_exit_signal 0x000000a4
#define ASIZ_task_exit_signal 0x00000004
-#define AOFF_task_pdeath_signal 0x000000a0
+#define AOFF_task_pdeath_signal 0x000000a8
#define ASIZ_task_pdeath_signal 0x00000004
-#define AOFF_task_personality 0x000000a8
+#define AOFF_task_personality 0x000000b0
#define ASIZ_task_personality 0x00000008
-#define AOFF_task_pid 0x000000b4
+#define AOFF_task_pid 0x000000bc
#define ASIZ_task_pid 0x00000004
-#define AOFF_task_pgrp 0x000000b8
+#define AOFF_task_pgrp 0x000000c0
#define ASIZ_task_pgrp 0x00000004
-#define AOFF_task_tty_old_pgrp 0x000000bc
+#define AOFF_task_tty_old_pgrp 0x000000c4
#define ASIZ_task_tty_old_pgrp 0x00000004
-#define AOFF_task_session 0x000000c0
+#define AOFF_task_session 0x000000c8
#define ASIZ_task_session 0x00000004
-#define AOFF_task_leader 0x000000c4
+#define AOFF_task_leader 0x000000cc
#define ASIZ_task_leader 0x00000004
-#define AOFF_task_p_opptr 0x000000c8
+#define AOFF_task_p_opptr 0x000000d0
#define ASIZ_task_p_opptr 0x00000008
-#define AOFF_task_p_pptr 0x000000d0
+#define AOFF_task_p_pptr 0x000000d8
#define ASIZ_task_p_pptr 0x00000008
-#define AOFF_task_p_cptr 0x000000d8
+#define AOFF_task_p_cptr 0x000000e0
#define ASIZ_task_p_cptr 0x00000008
-#define AOFF_task_p_ysptr 0x000000e0
+#define AOFF_task_p_ysptr 0x000000e8
#define ASIZ_task_p_ysptr 0x00000008
-#define AOFF_task_p_osptr 0x000000e8
+#define AOFF_task_p_osptr 0x000000f0
#define ASIZ_task_p_osptr 0x00000008
-#define AOFF_task_pidhash_next 0x000000f0
+#define AOFF_task_pidhash_next 0x000000f8
#define ASIZ_task_pidhash_next 0x00000008
-#define AOFF_task_pidhash_pprev 0x000000f8
+#define AOFF_task_pidhash_pprev 0x00000100
#define ASIZ_task_pidhash_pprev 0x00000008
-#define AOFF_task_wait_chldexit 0x00000100
+#define AOFF_task_wait_chldexit 0x00000108
#define ASIZ_task_wait_chldexit 0x00000028
-#define AOFF_task_vfork_sem 0x00000128
+#define AOFF_task_vfork_sem 0x00000130
#define ASIZ_task_vfork_sem 0x00000008
-#define AOFF_task_rt_priority 0x00000130
+#define AOFF_task_rt_priority 0x00000138
#define ASIZ_task_rt_priority 0x00000008
-#define AOFF_task_it_real_value 0x00000138
+#define AOFF_task_it_real_value 0x00000140
#define ASIZ_task_it_real_value 0x00000008
-#define AOFF_task_it_prof_value 0x00000140
+#define AOFF_task_it_prof_value 0x00000148
#define ASIZ_task_it_prof_value 0x00000008
-#define AOFF_task_it_virt_value 0x00000148
+#define AOFF_task_it_virt_value 0x00000150
#define ASIZ_task_it_virt_value 0x00000008
-#define AOFF_task_it_real_incr 0x00000150
+#define AOFF_task_it_real_incr 0x00000158
#define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000158
+#define AOFF_task_it_prof_incr 0x00000160
#define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000160
+#define AOFF_task_it_virt_incr 0x00000168
#define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer 0x00000168
+#define AOFF_task_real_timer 0x00000170
#define ASIZ_task_real_timer 0x00000030
-#define AOFF_task_times 0x00000198
+#define AOFF_task_times 0x000001a0
#define ASIZ_task_times 0x00000020
-#define AOFF_task_start_time 0x000001b8
+#define AOFF_task_start_time 0x000001c0
#define ASIZ_task_start_time 0x00000008
-#define AOFF_task_per_cpu_utime 0x000001c0
+#define AOFF_task_per_cpu_utime 0x000001c8
#define ASIZ_task_per_cpu_utime 0x00000100
-#define AOFF_task_min_flt 0x000003c0
+#define AOFF_task_min_flt 0x000003c8
#define ASIZ_task_min_flt 0x00000008
-#define AOFF_task_maj_flt 0x000003c8
+#define AOFF_task_maj_flt 0x000003d0
#define ASIZ_task_maj_flt 0x00000008
-#define AOFF_task_nswap 0x000003d0
+#define AOFF_task_nswap 0x000003d8
#define ASIZ_task_nswap 0x00000008
-#define AOFF_task_cmin_flt 0x000003d8
+#define AOFF_task_cmin_flt 0x000003e0
#define ASIZ_task_cmin_flt 0x00000008
-#define AOFF_task_cmaj_flt 0x000003e0
+#define AOFF_task_cmaj_flt 0x000003e8
#define ASIZ_task_cmaj_flt 0x00000008
-#define AOFF_task_cnswap 0x000003e8
+#define AOFF_task_cnswap 0x000003f0
#define ASIZ_task_cnswap 0x00000008
-#define AOFF_task_uid 0x000003f4
+#define AOFF_task_uid 0x000003fc
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x000003f8
+#define AOFF_task_euid 0x00000400
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x000003fc
+#define AOFF_task_suid 0x00000404
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000400
+#define AOFF_task_fsuid 0x00000408
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x00000404
+#define AOFF_task_gid 0x0000040c
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000408
+#define AOFF_task_egid 0x00000410
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x0000040c
+#define AOFF_task_sgid 0x00000414
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000410
+#define AOFF_task_fsgid 0x00000418
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x00000414
+#define AOFF_task_ngroups 0x0000041c
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000418
+#define AOFF_task_groups 0x00000420
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x00000498
+#define AOFF_task_cap_effective 0x000004a0
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x0000049c
+#define AOFF_task_cap_inheritable 0x000004a4
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000004a0
+#define AOFF_task_cap_permitted 0x000004a8
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000004a8
+#define AOFF_task_user 0x000004b0
#define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x000004b0
+#define AOFF_task_rlim 0x000004b8
#define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math 0x00000550
+#define AOFF_task_used_math 0x00000558
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x00000552
+#define AOFF_task_comm 0x0000055a
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x00000564
+#define AOFF_task_link_count 0x0000056c
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000568
+#define AOFF_task_tty 0x00000570
#define ASIZ_task_tty 0x00000008
-#define AOFF_task_semundo 0x00000570
+#define AOFF_task_semundo 0x00000578
#define ASIZ_task_semundo 0x00000008
-#define AOFF_task_semsleeping 0x00000578
+#define AOFF_task_semsleeping 0x00000580
#define ASIZ_task_semsleeping 0x00000008
-#define AOFF_task_thread 0x00000580
+#define AOFF_task_thread 0x00000590
#define ASIZ_task_thread 0x00000450
-#define AOFF_task_fs 0x000009d0
+#define AOFF_task_fs 0x000009e0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000009d8
+#define AOFF_task_files 0x000009e8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000009e0
+#define AOFF_task_sigmask_lock 0x000009f0
#define ASIZ_task_sigmask_lock 0x00000001
-#define AOFF_task_sig 0x000009e8
+#define AOFF_task_sig 0x000009f8
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x000009f0
+#define AOFF_task_signal 0x00000a00
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x000009f8
+#define AOFF_task_blocked 0x00000a08
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000a00
+#define AOFF_task_sigqueue 0x00000a10
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000a08
+#define AOFF_task_sigqueue_tail 0x00000a18
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000a10
+#define AOFF_task_sas_ss_sp 0x00000a20
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000a18
+#define AOFF_task_sas_ss_size 0x00000a28
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000a20
+#define AOFF_task_parent_exec_id 0x00000a30
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000a24
+#define AOFF_task_self_exec_id 0x00000a34
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x00000a28
+#define AOFF_task_alloc_lock 0x00000a38
#define ASIZ_task_alloc_lock 0x00000001
-#define ASIZ_task 0x00000a30
+#define ASIZ_task 0x00000a40
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -628,127 +632,129 @@
#define ASIZ_task_has_cpu 0x00000004
#define AOFF_task_processor 0x00000064
#define ASIZ_task_processor 0x00000004
-#define AOFF_task_run_list 0x00000068
+#define AOFF_task_ptrace 0x00000068
+#define ASIZ_task_ptrace 0x00000008
+#define AOFF_task_run_list 0x00000070
#define ASIZ_task_run_list 0x00000010
-#define AOFF_task_next_task 0x00000078
+#define AOFF_task_next_task 0x00000080
#define ASIZ_task_next_task 0x00000008
-#define AOFF_task_prev_task 0x00000080
+#define AOFF_task_prev_task 0x00000088
#define ASIZ_task_prev_task 0x00000008
-#define AOFF_task_last_processor 0x00000088
+#define AOFF_task_last_processor 0x00000090
#define ASIZ_task_last_processor 0x00000004
-#define AOFF_task_binfmt 0x00000090
+#define AOFF_task_binfmt 0x00000098
#define ASIZ_task_binfmt 0x00000008
-#define AOFF_task_exit_code 0x00000098
+#define AOFF_task_exit_code 0x000000a0
#define ASIZ_task_exit_code 0x00000004
-#define AOFF_task_exit_signal 0x0000009c
+#define AOFF_task_exit_signal 0x000000a4
#define ASIZ_task_exit_signal 0x00000004
-#define AOFF_task_pdeath_signal 0x000000a0
+#define AOFF_task_pdeath_signal 0x000000a8
#define ASIZ_task_pdeath_signal 0x00000004
-#define AOFF_task_personality 0x000000a8
+#define AOFF_task_personality 0x000000b0
#define ASIZ_task_personality 0x00000008
-#define AOFF_task_pid 0x000000b4
+#define AOFF_task_pid 0x000000bc
#define ASIZ_task_pid 0x00000004
-#define AOFF_task_pgrp 0x000000b8
+#define AOFF_task_pgrp 0x000000c0
#define ASIZ_task_pgrp 0x00000004
-#define AOFF_task_tty_old_pgrp 0x000000bc
+#define AOFF_task_tty_old_pgrp 0x000000c4
#define ASIZ_task_tty_old_pgrp 0x00000004
-#define AOFF_task_session 0x000000c0
+#define AOFF_task_session 0x000000c8
#define ASIZ_task_session 0x00000004
-#define AOFF_task_leader 0x000000c4
+#define AOFF_task_leader 0x000000cc
#define ASIZ_task_leader 0x00000004
-#define AOFF_task_p_opptr 0x000000c8
+#define AOFF_task_p_opptr 0x000000d0
#define ASIZ_task_p_opptr 0x00000008
-#define AOFF_task_p_pptr 0x000000d0
+#define AOFF_task_p_pptr 0x000000d8
#define ASIZ_task_p_pptr 0x00000008
-#define AOFF_task_p_cptr 0x000000d8
+#define AOFF_task_p_cptr 0x000000e0
#define ASIZ_task_p_cptr 0x00000008
-#define AOFF_task_p_ysptr 0x000000e0
+#define AOFF_task_p_ysptr 0x000000e8
#define ASIZ_task_p_ysptr 0x00000008
-#define AOFF_task_p_osptr 0x000000e8
+#define AOFF_task_p_osptr 0x000000f0
#define ASIZ_task_p_osptr 0x00000008
-#define AOFF_task_pidhash_next 0x000000f0
+#define AOFF_task_pidhash_next 0x000000f8
#define ASIZ_task_pidhash_next 0x00000008
-#define AOFF_task_pidhash_pprev 0x000000f8
+#define AOFF_task_pidhash_pprev 0x00000100
#define ASIZ_task_pidhash_pprev 0x00000008
-#define AOFF_task_wait_chldexit 0x00000100
+#define AOFF_task_wait_chldexit 0x00000108
#define ASIZ_task_wait_chldexit 0x00000030
-#define AOFF_task_vfork_sem 0x00000130
+#define AOFF_task_vfork_sem 0x00000138
#define ASIZ_task_vfork_sem 0x00000008
-#define AOFF_task_rt_priority 0x00000138
+#define AOFF_task_rt_priority 0x00000140
#define ASIZ_task_rt_priority 0x00000008
-#define AOFF_task_it_real_value 0x00000140
+#define AOFF_task_it_real_value 0x00000148
#define ASIZ_task_it_real_value 0x00000008
-#define AOFF_task_it_prof_value 0x00000148
+#define AOFF_task_it_prof_value 0x00000150
#define ASIZ_task_it_prof_value 0x00000008
-#define AOFF_task_it_virt_value 0x00000150
+#define AOFF_task_it_virt_value 0x00000158
#define ASIZ_task_it_virt_value 0x00000008
-#define AOFF_task_it_real_incr 0x00000158
+#define AOFF_task_it_real_incr 0x00000160
#define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000160
+#define AOFF_task_it_prof_incr 0x00000168
#define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000168
+#define AOFF_task_it_virt_incr 0x00000170
#define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer 0x00000170
+#define AOFF_task_real_timer 0x00000178
#define ASIZ_task_real_timer 0x00000030
-#define AOFF_task_times 0x000001a0
+#define AOFF_task_times 0x000001a8
#define ASIZ_task_times 0x00000020
-#define AOFF_task_start_time 0x000001c0
+#define AOFF_task_start_time 0x000001c8
#define ASIZ_task_start_time 0x00000008
-#define AOFF_task_per_cpu_utime 0x000001c8
+#define AOFF_task_per_cpu_utime 0x000001d0
#define ASIZ_task_per_cpu_utime 0x00000100
-#define AOFF_task_min_flt 0x000003c8
+#define AOFF_task_min_flt 0x000003d0
#define ASIZ_task_min_flt 0x00000008
-#define AOFF_task_maj_flt 0x000003d0
+#define AOFF_task_maj_flt 0x000003d8
#define ASIZ_task_maj_flt 0x00000008
-#define AOFF_task_nswap 0x000003d8
+#define AOFF_task_nswap 0x000003e0
#define ASIZ_task_nswap 0x00000008
-#define AOFF_task_cmin_flt 0x000003e0
+#define AOFF_task_cmin_flt 0x000003e8
#define ASIZ_task_cmin_flt 0x00000008
-#define AOFF_task_cmaj_flt 0x000003e8
+#define AOFF_task_cmaj_flt 0x000003f0
#define ASIZ_task_cmaj_flt 0x00000008
-#define AOFF_task_cnswap 0x000003f0
+#define AOFF_task_cnswap 0x000003f8
#define ASIZ_task_cnswap 0x00000008
-#define AOFF_task_uid 0x000003fc
+#define AOFF_task_uid 0x00000404
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x00000400
+#define AOFF_task_euid 0x00000408
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x00000404
+#define AOFF_task_suid 0x0000040c
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000408
+#define AOFF_task_fsuid 0x00000410
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x0000040c
+#define AOFF_task_gid 0x00000414
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000410
+#define AOFF_task_egid 0x00000418
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x00000414
+#define AOFF_task_sgid 0x0000041c
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000418
+#define AOFF_task_fsgid 0x00000420
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x0000041c
+#define AOFF_task_ngroups 0x00000424
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000420
+#define AOFF_task_groups 0x00000428
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x000004a0
+#define AOFF_task_cap_effective 0x000004a8
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x000004a4
+#define AOFF_task_cap_inheritable 0x000004ac
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000004a8
+#define AOFF_task_cap_permitted 0x000004b0
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000004b0
+#define AOFF_task_user 0x000004b8
#define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x000004b8
+#define AOFF_task_rlim 0x000004c0
#define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math 0x00000558
+#define AOFF_task_used_math 0x00000560
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x0000055a
+#define AOFF_task_comm 0x00000562
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x0000056c
+#define AOFF_task_link_count 0x00000574
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000570
+#define AOFF_task_tty 0x00000578
#define ASIZ_task_tty 0x00000008
-#define AOFF_task_semundo 0x00000578
+#define AOFF_task_semundo 0x00000580
#define ASIZ_task_semundo 0x00000008
-#define AOFF_task_semsleeping 0x00000580
+#define AOFF_task_semsleeping 0x00000588
#define ASIZ_task_semsleeping 0x00000008
#define AOFF_task_thread 0x00000590
#define ASIZ_task_thread 0x00000450
diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
index 71bfa67ca7ce2b..4f621f2cb46341 100644
--- a/include/asm-sparc64/ide.h
+++ b/include/asm-sparc64/ide.h
@@ -1,4 +1,4 @@
-/* $Id: ide.h,v 1.18 2000/05/22 07:29:43 davem Exp $
+/* $Id: ide.h,v 1.19 2000/05/27 00:49:37 davem Exp $
* ide.h: Ultra/PCI specific IDE glue.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
diff --git a/include/asm-sparc64/mc146818rtc.h b/include/asm-sparc64/mc146818rtc.h
new file mode 100644
index 00000000000000..05c8ffd9714142
--- /dev/null
+++ b/include/asm-sparc64/mc146818rtc.h
@@ -0,0 +1,27 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_SPARC64_MC146818RTC_H
+#define __ASM_SPARC64_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* __ASM_SPARC64_MC146818RTC_H */
diff --git a/include/asm-sparc64/string.h b/include/asm-sparc64/string.h
index 31bbf32e72ec17..337b617843eb27 100644
--- a/include/asm-sparc64/string.h
+++ b/include/asm-sparc64/string.h
@@ -1,4 +1,4 @@
-/* $Id: string.h,v 1.16 2000/05/02 01:47:01 davem Exp $
+/* $Id: string.h,v 1.17 2000/06/19 06:24:58 davem Exp $
* string.h: External definitions for optimized assembly string
* routines for the Linux Kernel.
*
@@ -111,7 +111,7 @@ static inline void *__constant_memset(void *s, int c, __kernel_size_t count)
extern __kernel_size_t __strlen(const char *);
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
extern __kernel_size_t strlen(const char *);
#else /* !EGCS */
/* Ugly but it works around a bug in our original sparc64-linux-gcc. */
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 00303c23994413..257bca48d4036e 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.59 2000/05/09 17:40:15 davem Exp $ */
+/* $Id: system.h,v 1.60 2000/05/29 05:34:02 davem Exp $ */
#ifndef __SPARC64_SYSTEM_H
#define __SPARC64_SYSTEM_H
@@ -269,7 +269,8 @@ extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noret
extern __inline__ unsigned long
__cmpxchg_u32(volatile int *m, int old, int new)
{
- __asm__ __volatile__("cas [%2], %3, %0"
+ __asm__ __volatile__("cas [%2], %3, %0\n\t"
+ "membar #StoreStore | #StoreLoad"
: "=&r" (new)
: "0" (new), "r" (m), "r" (old)
: "memory");
@@ -280,7 +281,8 @@ __cmpxchg_u32(volatile int *m, int old, int new)
extern __inline__ unsigned long
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
{
- __asm__ __volatile__("casx [%2], %3, %0"
+ __asm__ __volatile__("casx [%2], %3, %0\n\t"
+ "membar #StoreStore | #StoreLoad"
: "=&r" (new)
: "0" (new), "r" (m), "r" (old)
: "memory");
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h
index 3c8c7e01ff7145..698a6f2629f478 100644
--- a/include/linux/agp_backend.h
+++ b/include/linux/agp_backend.h
@@ -45,6 +45,7 @@ enum chipset_type {
INTEL_BX,
INTEL_GX,
INTEL_I810,
+ INTEL_I840,
VIA_GENERIC,
VIA_VP3,
VIA_MVP3,
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index 00c3df0ccc3b8f..77808a7a3c0ba5 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -437,6 +437,7 @@ struct cdrom_generic_command
#define GPCMD_PAUSE_RESUME 0x4b
#define GPCMD_PLAY_AUDIO_10 0x45
#define GPCMD_PLAY_AUDIO_MSF 0x47
+#define GPCMD_PLAY_AUDIO_TI 0x48
#define GPCMD_PLAY_CD 0xbc
#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
#define GPCMD_READ_10 0x28
@@ -477,16 +478,11 @@ struct cdrom_generic_command
/* This seems to be a SCSI specific CD-ROM opcode
* to play data at track/index */
#define GPCMD_PLAYAUDIO_TI 0x48
-
-/* Is this really used by anything? I couldn't find these...*/
-#if 0
-/* MMC2/MTFuji Opcodes */
-#define ERASE 0x2c
-#define READ_BUFFER 0x3c
-#endif
-
-
-
+/*
+ * From MS Media Status Notification Support Specification. For
+ * older drives only.
+ */
+#define GPCMD_GET_MEDIA_STATUS 0xda
/* Mode page codes for mode sense/set */
#define GPMODE_R_W_ERROR_PAGE 0x01
@@ -998,6 +994,40 @@ typedef struct {
__u8 subhdr3;
} __attribute__((packed)) write_param_page;
+struct modesel_head
+{
+ __u8 reserved1;
+ __u8 medium;
+ __u8 reserved2;
+ __u8 block_desc_length;
+ __u8 density;
+ __u8 number_of_blocks_hi;
+ __u8 number_of_blocks_med;
+ __u8 number_of_blocks_lo;
+ __u8 reserved3;
+ __u8 block_length_hi;
+ __u8 block_length_med;
+ __u8 block_length_lo;
+};
+
+typedef struct {
+ __u16 report_key_length;
+ __u8 reserved1;
+ __u8 reserved2;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 type_code : 2;
+ __u8 vra : 3;
+ __u8 ucca : 3;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 ucca : 3;
+ __u8 vra : 3;
+ __u8 type_code : 2;
+#endif
+ __u8 region_mask;
+ __u8 rpc_scheme;
+ __u8 reserved3;
+} rpc_state_t;
+
#endif /* End of kernel only stuff */
#endif /* _LINUX_CDROM_H */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 733f7fb0051310..4147f05ad7f5ba 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -260,6 +260,7 @@ struct file;
struct fb_ops {
/* open/release and usage marking */
+ struct module *owner;
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
/* get non settable parameters */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e40c8fe2db51e1..2cf4508c2715f5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -705,6 +705,7 @@ struct block_device_operations {
* without the big kernel lock held in all filesystems.
*/
struct file_operations {
+ struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
@@ -789,6 +790,18 @@ struct file_system_type var = { \
#define DECLARE_FSTYPE_DEV(var,type,read) \
DECLARE_FSTYPE(var,type,read,FS_REQUIRES_DEV)
+/* Alas, no aliases. Too much hassle with bringing module.h everywhere */
+#define fops_get(fops) \
+ (((fops) && (fops)->owner) \
+ ? __MOD_INC_USE_COUNT((fops)->owner), (fops) \
+ : (fops))
+
+#define fops_put(fops) \
+do { \
+ if ((fops) && (fops)->owner) \
+ __MOD_DEC_USE_COUNT((fops)->owner); \
+} while(0)
+
extern int register_filesystem(struct file_system_type *);
extern int unregister_filesystem(struct file_system_type *);
extern struct vfsmount *kern_mount(struct file_system_type *);
diff --git a/include/linux/input.h b/include/linux/input.h
index d43d1e5a7ab01e..6d19fc2a9f66bc 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -2,9 +2,9 @@
#define _INPUT_H
/*
- * input.h Version 0.1
+ * $Id: input.h,v 1.13 2000/05/29 10:54:53 vojtech Exp $
*
- * Copyright (c) 1999 Vojtech Pavlik
+ * Copyright (c) 1999-2000 Vojtech Pavlik
*
* Sponsored by SuSE
*/
@@ -33,6 +33,7 @@
#include <linux/time.h>
#else
#include <sys/time.h>
+#include <sys/ioctl.h>
#endif
/*
@@ -47,16 +48,6 @@ struct input_event {
};
/*
- * The device ID structure;
- */
-
-struct input_id {
- __u16 bus;
- __u16 vendor;
- __u16 product;
-};
-
-/*
* Protocol version.
*/
@@ -66,14 +57,17 @@ struct input_id {
* IOCTLs (0x00 - 0x7f)
*/
-#define EVIOCGVERSION _IOR('E', 0x01, __u32) /* get driver version */
-#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
+#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
+#define EVIOCGID _IOR('E', 0x02, short[4]) /* get device ID */
#define EVIOCGREP _IOR('E', 0x03, int[2]) /* get repeat settings */
#define EVIOCSREP _IOW('E', 0x03, int[2]) /* get repeat settings */
-#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x03, len) /* get device name */
+#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */
+#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */
+#define EVIOCGKEY _IOR('E', 0x05, int[2]) /* get key value */
+#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
+
#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */
-#define EVIOCGABSLIM(num) _IOR('E', 0x40 + num, int[4]) /* get abs event limits */
-#define EVIOCGABS(num) _IOR('E', 0x80 + num, int) /* get abs value */
+#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, int[5]) /* get abs value/limits */
/*
* Event types
@@ -308,6 +302,7 @@ struct input_id {
#define BTN_BASE3 0x128
#define BTN_BASE4 0x129
#define BTN_BASE5 0x12a
+#define BTN_BASE6 0x12b
#define BTN_GAMEPAD 0x130
#define BTN_A 0x130
@@ -364,6 +359,8 @@ struct input_id {
#define ABS_RZ 0x05
#define ABS_THROTTLE 0x06
#define ABS_RUDDER 0x07
+#define ABS_TL 0x08
+#define ABS_TR 0x09
#define ABS_HAT0X 0x10
#define ABS_HAT0Y 0x11
#define ABS_HAT1X 0x12
@@ -406,6 +403,27 @@ struct input_id {
#define SND_BELL 0x01
#define SND_MAX 0x07
+/*
+ * IDs.
+ */
+
+#define ID_BUS 0
+#define ID_VENDOR 1
+#define ID_PRODUCT 2
+#define ID_VERSION 3
+
+#define BUS_PCI 0x01
+#define BUS_ISAPNP 0x02
+#define BUS_USB 0x03
+
+#define BUS_ISA 0x10
+#define BUS_I8042 0x11
+#define BUS_XTKBD 0x12
+#define BUS_RS232 0x13
+#define BUS_GAMEPORT 0x14
+#define BUS_PARPORT 0x15
+#define BUS_AMIGA 0x16
+
#ifdef __KERNEL__
/*
@@ -425,7 +443,10 @@ struct input_dev {
int number;
char *name;
- struct input_id id;
+ unsigned short idbus;
+ unsigned short idvendor;
+ unsigned short idproduct;
+ unsigned short idversion;
unsigned long evbit[NBITS(EV_MAX)];
unsigned long keybit[NBITS(KEY_MAX)];
@@ -434,7 +455,10 @@ struct input_dev {
unsigned long ledbit[NBITS(LED_MAX)];
unsigned long sndbit[NBITS(SND_MAX)];
- unsigned char *keycode;
+ unsigned int keycodemax;
+ unsigned int keycodesize;
+ void *keycode;
+
unsigned int repeat_key;
struct timer_list timer;
@@ -500,8 +524,7 @@ void input_unregister_minor(devfs_handle_t handle);
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_btn(a,b,c) input_event(a, EV_KEY, b, !!(c))
+#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)
diff --git a/include/linux/joystick.h b/include/linux/joystick.h
index 8cd5cbccb6c8e8..c0e14817150750 100644
--- a/include/linux/joystick.h
+++ b/include/linux/joystick.h
@@ -219,6 +219,7 @@ struct js_dev {
int num_buttons;
char *name;
devfs_handle_t devfs_handle;
+ struct module *owner;
};
struct js_list {
@@ -251,7 +252,7 @@ extern struct js_port *js_register_port(struct js_port *port, void *info,
extern struct js_port *js_unregister_port(struct js_port *port);
extern int js_register_device(struct js_port *port, int number, int axes,
- int buttons, char *name, js_ops_func open, js_ops_func close);
+ int buttons, char *name, struct module *owner, js_ops_func open, js_ops_func close);
extern void js_unregister_device(struct js_dev *dev);
/*
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 42faceaa08e7f9..56204946541f99 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -21,62 +21,15 @@ struct notifier_block
#ifdef __KERNEL__
+extern int notifier_chain_register(struct notifier_block **list, struct notifier_block *n);
+extern int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n);
+extern int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v);
+
#define NOTIFY_DONE 0x0000 /* Don't care */
#define NOTIFY_OK 0x0001 /* Suits me */
#define NOTIFY_STOP_MASK 0x8000 /* Don't call further */
#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) /* Bad/Veto action */
-extern __inline__ int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
-{
- while(*list)
- {
- if(n->priority > (*list)->priority)
- break;
- list= &((*list)->next);
- }
- n->next = *list;
- *list=n;
- return 0;
-}
-
-/*
- * Warning to any non GPL module writers out there.. these functions are
- * GPL'd
- */
-
-extern __inline__ int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
-{
- while((*nl)!=NULL)
- {
- if((*nl)==n)
- {
- *nl=n->next;
- return 0;
- }
- nl=&((*nl)->next);
- }
- return -ENOENT;
-}
-
-/*
- * This is one of these things that is generally shorter inline
- */
-
-extern __inline__ int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
-{
- int ret=NOTIFY_DONE;
- struct notifier_block *nb = *n;
- while(nb)
- {
- ret=nb->notifier_call(nb,val,v);
- if(ret&NOTIFY_STOP_MASK)
- return ret;
- nb=nb->next;
- }
- return ret;
-}
-
-
/*
* Declared notifiers so far. I can imagine quite a few more chains
* over time (eg laptop power reset chains, reboot chain (to clean
@@ -105,11 +58,5 @@ extern __inline__ int notifier_call_chain(struct notifier_block **n, unsigned lo
#define SYS_HALT 0x0002 /* Notify of system halt */
#define SYS_POWER_OFF 0x0003 /* Notify of system power off */
-/*
- * Publically visible notifier objects
- */
-
-extern struct notifier_block *boot_notifier_list;
-
-#endif
-#endif
+#endif /* __KERNEL__ */
+#endif /* _LINUX_NOTIFIER_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4497f6468a8ac2..35d786e15cb82c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -269,6 +269,7 @@ struct task_struct {
struct mm_struct *mm, *active_mm;
int has_cpu;
int processor;
+ unsigned long ptrace;
struct list_head run_list;
struct task_struct *next_task, *prev_task;
int last_processor;
@@ -356,8 +357,6 @@ struct task_struct {
/* Not implemented yet, only for 486*/
#define PF_STARTING 0x00000002 /* being created */
#define PF_EXITING 0x00000004 /* getting shut down */
-#define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called */
-#define PF_TRACESYS 0x00000020 /* tracing system calls */
#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */
#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* dumped core */
@@ -366,7 +365,14 @@ struct task_struct {
#define PF_VFORK 0x00001000 /* Wake up parent in mm_release */
#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */
-#define PF_DTRACE 0x00200000 /* delayed trace (used on m68k, i386) */
+
+/*
+ * Ptrace flags
+ */
+
+#define PT_PTRACED 0x00000001
+#define PT_TRACESYS 0x00000002
+#define PT_DTRACE 0x00000004 /* delayed trace (used on m68k, i386) */
/*
* Limit the stack by to some sane default: root can always
diff --git a/kernel/Makefile b/kernel/Makefile
index 2a4f548af3a39f..53606a35937dd8 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,11 +8,11 @@
# Note 2! The CFLAGS definitions are now in the main makefile...
O_TARGET := kernel.o
-O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \
+O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o info.o time.o softirq.o resource.o \
sysctl.o acct.o capability.o ptrace.o timer.o
-OX_OBJS += signal.o
+OX_OBJS += signal.o sys.o
ifeq ($(CONFIG_UID16),y)
O_OBJS += uid16.o
diff --git a/kernel/exit.c b/kernel/exit.c
index 96c7efb1dc2d97..b6e3e633bbfd99 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -391,7 +391,7 @@ static void exit_notify(void)
p = current->p_cptr;
current->p_cptr = p->p_osptr;
p->p_ysptr = NULL;
- p->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ p->ptrace = 0;
p->p_pptr = p->p_opptr;
p->p_osptr = p->p_pptr->p_cptr;
@@ -512,7 +512,7 @@ repeat:
case TASK_STOPPED:
if (!p->exit_code)
continue;
- if (!(options & WUNTRACED) && !(p->flags & PF_PTRACED))
+ if (!(options & WUNTRACED) && !(p->ptrace & PT_PTRACED))
continue;
read_unlock(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
diff --git a/kernel/fork.c b/kernel/fork.c
index 4300d242d23585..b441988aa1b77d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -602,7 +602,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
new_flags &= ~(PF_SUPERPRIV | PF_USEDFPU | PF_VFORK);
new_flags |= PF_FORKNOEXEC;
if (!(clone_flags & CLONE_PTRACE))
- new_flags &= ~(PF_PTRACED|PF_TRACESYS);
+ p->ptrace = 0;
if (clone_flags & CLONE_VFORK)
new_flags |= PF_VFORK;
p->flags = new_flags;
@@ -674,7 +674,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
if ((clone_flags & CLONE_VFORK) || !(clone_flags & CLONE_PARENT)) {
p->p_opptr = current;
- if (!(p->flags & PF_PTRACED))
+ if (!(p->ptrace & PT_PTRACED))
p->p_pptr = current;
}
p->p_cptr = NULL;
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 9946d8545da918..0da556aaed08ea 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -129,7 +129,6 @@ EXPORT_SYMBOL(highmem_start_page);
/* filesystem internal functions */
EXPORT_SYMBOL(def_blk_fops);
-EXPORT_SYMBOL(in_group_p);
EXPORT_SYMBOL(update_atime);
EXPORT_SYMBOL(get_super);
EXPORT_SYMBOL(get_empty_super);
@@ -444,8 +443,6 @@ EXPORT_SYMBOL(sys_call_table);
EXPORT_SYMBOL(machine_restart);
EXPORT_SYMBOL(machine_halt);
EXPORT_SYMBOL(machine_power_off);
-EXPORT_SYMBOL(register_reboot_notifier);
-EXPORT_SYMBOL(unregister_reboot_notifier);
EXPORT_SYMBOL(_ctype);
EXPORT_SYMBOL(secure_tcp_sequence_number);
EXPORT_SYMBOL(get_random_bytes);
diff --git a/kernel/signal.c b/kernel/signal.c
index ec8d00621837c7..51ad74b4d01751 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -247,7 +247,7 @@ static int ignored_signal(int sig, struct task_struct *t)
struct k_sigaction *ka;
/* Don't ignore traced or blocked signals */
- if ((t->flags & PF_PTRACED) || sigismember(&t->blocked, sig))
+ if ((t->ptrace & PT_PTRACED) || sigismember(&t->blocked, sig))
return 0;
signals = t->sig;
@@ -625,7 +625,7 @@ notify_parent(struct task_struct *tsk, int sig)
break;
case TASK_STOPPED:
/* FIXME -- can we deduce CLD_TRAPPED or CLD_CONTINUED? */
- if (tsk->flags & PF_PTRACED)
+ if (tsk->ptrace & PT_PTRACED)
why = CLD_TRAPPED;
else
why = CLD_STOPPED;
diff --git a/kernel/sys.c b/kernel/sys.c
index 35e8a7d6818140..43074271510d5f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -4,6 +4,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/mman.h>
@@ -46,13 +47,123 @@ int C_A_D = 1;
* and the like.
*/
-struct notifier_block *reboot_notifier_list = NULL;
+static struct notifier_block *reboot_notifier_list = NULL;
+rwlock_t notifier_lock = RW_LOCK_UNLOCKED;
+/**
+ * notifier_chain_register - Add notifier to a notifier chain
+ * @list: Pointer to root list pointer
+ * @n: New entry in notifier chain
+ *
+ * Adds a notifier to a notifier chain.
+ *
+ * Currently always returns zero.
+ */
+
+int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
+{
+ write_lock(&notifier_lock);
+ while(*list)
+ {
+ if(n->priority > (*list)->priority)
+ break;
+ list= &((*list)->next);
+ }
+ n->next = *list;
+ *list=n;
+ write_unlock(&notifier_lock);
+ return 0;
+}
+
+/**
+ * notifier_chain_unregister - Remove notifier from a notifier chain
+ * @nl: Pointer to root list pointer
+ * @n: New entry in notifier chain
+ *
+ * Removes a notifier from a notifier chain.
+ *
+ * Returns zero on success, or %-ENOENT on failure.
+ */
+
+int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
+{
+ write_lock(&notifier_lock);
+ while((*nl)!=NULL)
+ {
+ if((*nl)==n)
+ {
+ *nl=n->next;
+ write_unlock(&notifier_lock);
+ return 0;
+ }
+ nl=&((*nl)->next);
+ }
+ write_unlock(&notifier_lock);
+ return -ENOENT;
+}
+
+/**
+ * notifier_call_chain - Call functions in a notifier chain
+ * @n: Pointer to root pointer of notifier chain
+ * @val: Value passed unmodified to notifier function
+ * @v: Pointer passed unmodified to notifier function
+ *
+ * Calls each function in a notifier chain in turn.
+ *
+ * If the return value of the notifier can be and'd
+ * with %NOTIFY_STOP_MASK, then notifier_call_chain
+ * will return immediately, with the return value of
+ * the notifier function which halted execution.
+ * Otherwise, the return value is the return value
+ * of the last notifier function called.
+ */
+
+int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
+{
+ int ret=NOTIFY_DONE;
+ struct notifier_block *nb = *n;
+
+ read_lock(&notifier_lock);
+ while(nb)
+ {
+ ret=nb->notifier_call(nb,val,v);
+ if(ret&NOTIFY_STOP_MASK)
+ {
+ read_unlock(&notifier_lock);
+ return ret;
+ }
+ nb=nb->next;
+ }
+ read_unlock(&notifier_lock);
+ return ret;
+}
+
+/**
+ * register_reboot_notifier - Register function to be called at reboot time
+ * @nb: Info about notifier function to be called
+ *
+ * Registers a function with the list of functions
+ * to be called at reboot time.
+ *
+ * Currently always returns zero, as notifier_chain_register
+ * always returns zero.
+ */
+
int register_reboot_notifier(struct notifier_block * nb)
{
return notifier_chain_register(&reboot_notifier_list, nb);
}
+/**
+ * unregister_reboot_notifier - Unregister previously registered reboot notifier
+ * @nb: Hook to be unregistered
+ *
+ * Unregisters a previously registered reboot
+ * notifier function.
+ *
+ * Returns zero on success, or %-ENOENT on failure.
+ */
+
int unregister_reboot_notifier(struct notifier_block * nb)
{
return notifier_chain_unregister(&reboot_notifier_list, nb);
@@ -1102,3 +1213,10 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
return error;
}
+EXPORT_SYMBOL(notifier_chain_register);
+EXPORT_SYMBOL(notifier_chain_unregister);
+EXPORT_SYMBOL(notifier_call_chain);
+EXPORT_SYMBOL(register_reboot_notifier);
+EXPORT_SYMBOL(unregister_reboot_notifier);
+EXPORT_SYMBOL(in_group_p);
+EXPORT_SYMBOL(in_egroup_p);