]> git.neil.brown.name Git - history.git/commitdiff
v2.4.12 -> v2.4.12.1
authorLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:23:54 +0000 (20:23 -0800)
committerLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:23:54 +0000 (20:23 -0800)
  - Trond Myklebust: deadlock checking in lockd server
  - Tim Waugh: fix up parport wrong #define
  - Christoph Hellwig: i2c update, ext2 cleanup
  - Al Viro: fix partition handling sanity check.
  - Trond Myklebust: make NFS use SLAB_NOFS, and not play games with PF_MEMALLOC
  - Ben Fennema: UDF update
  - Alan Cox: continued merging
  - Chris Mason: get /proc buffer memory sizes right after buf-in-page-cache

405 files changed:
Documentation/README.nsp_cs.eng
Documentation/arm/README
Documentation/arm/SA1100/ADSBitsy [new file with mode: 0644]
Documentation/arm/SA1100/GraphicsMaster [new file with mode: 0644]
Documentation/arm/SA1100/Pangolin
Documentation/cciss.txt
Documentation/i2c/dev-interface
Documentation/i2c/summary
Documentation/i2c/writing-clients
Documentation/s390/CommonIO
Documentation/s390/chandev.8
Documentation/s390/s390dbf.txt
Documentation/sonypi.txt
Documentation/video4linux/README.buz [deleted file]
Documentation/video4linux/meye.txt
MAINTAINERS
Makefile
arch/arm/Makefile
arch/arm/boot/Makefile
arch/arm/boot/bootp/Makefile
arch/arm/boot/bootp/init.S
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head-sa1100.S
arch/arm/boot/compressed/setup-sa1100.S [deleted file]
arch/arm/config.in
arch/arm/kernel/Makefile
arch/arm/kernel/armksyms.c
arch/arm/kernel/bios32.c
arch/arm/kernel/compat.c
arch/arm/kernel/dma-isa.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/entry-header.S
arch/arm/kernel/head-armv.S
arch/arm/kernel/init_task.c
arch/arm/kernel/setup.c
arch/arm/kernel/signal.c
arch/arm/kernel/time.c
arch/arm/kernel/traps.c
arch/arm/lib/Makefile
arch/arm/lib/ashldi3.c [new file with mode: 0644]
arch/arm/lib/ashrdi3.c [new file with mode: 0644]
arch/arm/lib/gcclib.h [new file with mode: 0644]
arch/arm/lib/getuser.S [new file with mode: 0644]
arch/arm/lib/kbd.c [new file with mode: 0644]
arch/arm/lib/lib1funcs.S [new file with mode: 0644]
arch/arm/lib/longlong.h [new file with mode: 0644]
arch/arm/lib/lshrdi3.c [new file with mode: 0644]
arch/arm/lib/muldi3.c [new file with mode: 0644]
arch/arm/lib/putuser.S [new file with mode: 0644]
arch/arm/lib/ucmpdi2.c [new file with mode: 0644]
arch/arm/lib/udivdi3.c [new file with mode: 0644]
arch/arm/mach-ebsa110/io.c
arch/arm/mach-integrator/cpu.c
arch/arm/mach-integrator/dma.c
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-sa1100/Makefile
arch/arm/mach-sa1100/adsbitsy.c [new file with mode: 0644]
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/bitsy.c [deleted file]
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-sa1100/dma-sa1100.c
arch/arm/mach-sa1100/dma-sa1111.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/graphicsclient.c
arch/arm/mach-sa1100/graphicsmaster.c [new file with mode: 0644]
arch/arm/mach-sa1100/h3600.c [new file with mode: 0644]
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/leds-graphicsmaster.c [new file with mode: 0644]
arch/arm/mach-sa1100/leds.c
arch/arm/mach-sa1100/leds.h
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/pangolin.c
arch/arm/mach-sa1100/pfs168.c
arch/arm/mach-sa1100/sa1111-pcibuf.c
arch/arm/mach-sa1100/sa1111.c
arch/arm/mach-sa1100/sa1111.h
arch/arm/mach-sa1100/xp860.c
arch/arm/mm/extable.c
arch/arm/mm/fault-armv.c
arch/arm/mm/fault-common.c
arch/arm/mm/init.c
arch/arm/mm/mm-ftvpci.c [new file with mode: 0644]
arch/arm/mm/mm-nexuspci.c [deleted file]
arch/arm/mm/proc-arm720.S
arch/arm/tools/Makefile
arch/arm/tools/getconstants.c
arch/arm/tools/mach-types
arch/i386/kernel/bluesmoke.c
arch/i386/kernel/cpuid.c
arch/i386/kernel/dmi_scan.c
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/microcode.c
arch/i386/kernel/msr.c
arch/i386/kernel/mtrr.c
arch/ppc/Makefile
arch/ppc/amiga/config.c
arch/s390/Makefile
arch/s390/kernel/Makefile
arch/s390/kernel/debug.c
arch/s390/kernel/entry.S
arch/s390/kernel/gdb-stub.c
arch/s390/kernel/head.S
arch/s390/kernel/lowcore.S [deleted file]
arch/s390/kernel/process.c
arch/s390/kernel/s390_ksyms.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/s390/kernel/traps.c
arch/s390/math-emu/math.c
arch/s390/mm/extable.c
arch/s390/mm/fault.c
arch/s390/mm/init.c
arch/s390x/Makefile
arch/s390x/config.in
arch/s390x/defconfig
arch/s390x/kernel/Makefile
arch/s390x/kernel/cpcmd.c
arch/s390x/kernel/debug.c
arch/s390x/kernel/entry.S
arch/s390x/kernel/head.S
arch/s390x/kernel/ioctl32.c
arch/s390x/kernel/linux32.c
arch/s390x/kernel/linux32.h
arch/s390x/kernel/lowcore.S [deleted file]
arch/s390x/kernel/mathemu.c [deleted file]
arch/s390x/kernel/process.c
arch/s390x/kernel/s390_ksyms.c
arch/s390x/kernel/setup.c
arch/s390x/kernel/signal.c
arch/s390x/kernel/signal32.c
arch/s390x/kernel/smp.c
arch/s390x/kernel/time.c
arch/s390x/kernel/traps.c
arch/s390x/kernel/wrapper32.S
arch/s390x/mm/extable.c
arch/s390x/mm/fault.c
arch/s390x/mm/init.c
drivers/acorn/char/mouse_rpc.c
drivers/acorn/scsi/acornscsi.c
drivers/acorn/scsi/arxescsi.c
drivers/acorn/scsi/cumana_2.c
drivers/acorn/scsi/ecoscsi.c
drivers/acorn/scsi/eesox.c
drivers/acorn/scsi/fas216.c
drivers/acorn/scsi/msgqueue.c
drivers/acorn/scsi/oak.c
drivers/acorn/scsi/powertec.c
drivers/acorn/scsi/queue.c
drivers/acpi/ospm/thermal/tz_osl.c
drivers/block/nbd.c
drivers/block/paride/aten.c
drivers/block/paride/bpck.c
drivers/block/paride/comm.c
drivers/block/paride/dstr.c
drivers/block/paride/epat.c
drivers/block/paride/epia.c
drivers/block/paride/fit2.c
drivers/block/paride/fit3.c
drivers/block/paride/friq.c
drivers/block/paride/frpw.c
drivers/block/paride/kbic.c
drivers/block/paride/ktti.c
drivers/block/paride/on20.c
drivers/block/paride/on26.c
drivers/block/paride/paride.c
drivers/block/paride/pcd.c
drivers/block/paride/pd.c
drivers/block/paride/pf.c
drivers/block/paride/pg.c
drivers/block/paride/ppc6lnx.c
drivers/block/paride/pt.c
drivers/char/Config.in
drivers/char/Makefile
drivers/char/adbmouse.c
drivers/char/i810_rng.c
drivers/char/ib700wdt.c [new file with mode: 0644]
drivers/char/ip2main.c
drivers/char/istallion.c
drivers/char/mwave/mwavedd.c
drivers/char/sonypi.c
drivers/char/sonypi.h
drivers/char/toshiba.c
drivers/fc4/soc.c
drivers/fc4/socal.c
drivers/i2c/Config.in
drivers/i2c/Makefile
drivers/i2c/i2c-adap-ite.c
drivers/i2c/i2c-algo-bit.c
drivers/i2c/i2c-algo-ite.c
drivers/i2c/i2c-algo-pcf.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/i2c/i2c-elektor.c
drivers/i2c/i2c-elv.c
drivers/i2c/i2c-proc.c [new file with mode: 0644]
drivers/i2c/i2c-velleman.c
drivers/ide/hptraid.c
drivers/ide/hptraid.h
drivers/ide/ide-disk.c
drivers/ide/ide-floppy.c
drivers/ide/ide-probe.c
drivers/ide/ide.c
drivers/ide/rapide.c
drivers/input/keybdev.c
drivers/media/video/bw-qcam.c
drivers/media/video/planb.c
drivers/media/video/saa7110.c
drivers/media/video/videodev.c
drivers/message/fusion/isense.c
drivers/mtd/Config.in
drivers/net/Config.in
drivers/net/ppp_generic.c
drivers/net/ppp_synctty.c
drivers/nubus/nubus_syms.c
drivers/parport/ieee1284_ops.c
drivers/parport/parport_amiga.c
drivers/parport/parport_atari.c
drivers/parport/parport_pc.c
drivers/pci/gen-devlist.c
drivers/pci/pci.ids
drivers/pcmcia/Makefile
drivers/pcmcia/cs.c
drivers/pcmcia/sa1100.h [new file with mode: 0644]
drivers/pcmcia/sa1100_adsbitsy.c [new file with mode: 0644]
drivers/pcmcia/sa1100_assabet.c [new file with mode: 0644]
drivers/pcmcia/sa1100_cerf.c [new file with mode: 0644]
drivers/pcmcia/sa1100_flexanet.c [new file with mode: 0644]
drivers/pcmcia/sa1100_freebird.c [new file with mode: 0644]
drivers/pcmcia/sa1100_generic.c [new file with mode: 0644]
drivers/pcmcia/sa1100_graphicsclient.c [new file with mode: 0644]
drivers/pcmcia/sa1100_graphicsmaster.c [new file with mode: 0644]
drivers/pcmcia/sa1100_h3600.c [new file with mode: 0644]
drivers/pcmcia/sa1100_jornada720.c [new file with mode: 0644]
drivers/pcmcia/sa1100_neponset.c [new file with mode: 0644]
drivers/pcmcia/sa1100_pangolin.c [new file with mode: 0644]
drivers/pcmcia/sa1100_pfs168.c [new file with mode: 0644]
drivers/pcmcia/sa1100_simpad.c [new file with mode: 0644]
drivers/pcmcia/sa1100_stork.c [new file with mode: 0644]
drivers/pcmcia/sa1100_xp860.c [new file with mode: 0644]
drivers/pcmcia/sa1100_yopy.c [new file with mode: 0644]
drivers/pnp/isapnp.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_3990_erp.c
drivers/s390/char/Makefile
drivers/s390/char/hwc_cpi.c
drivers/s390/char/tape34xx.c
drivers/s390/char/tapechar.c
drivers/s390/char/tuball.c
drivers/s390/char/tubtty.c
drivers/s390/net/ctcmain.c
drivers/s390/net/iucv.c
drivers/s390/net/netiucv.c
drivers/sbus/audio/amd7930.c
drivers/sbus/char/bpp.c
drivers/scsi/53c700.c
drivers/scsi/53c700.h
drivers/scsi/Config.in
drivers/scsi/README.53c700
drivers/scsi/aha152x.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/dpt_i2o.c
drivers/scsi/i60uscsi.h
drivers/scsi/i91uscsi.h
drivers/scsi/ini9100u.h
drivers/scsi/inia100.h
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_cs.h
drivers/scsi/pcmcia/nsp_debug.c
drivers/scsi/pcmcia/nsp_io.h
drivers/scsi/pcmcia/nsp_message.c
drivers/scsi/scsi_scan.c
drivers/scsi/sd.c
drivers/sgi/char/graphics.c
drivers/sound/cmpci.c
drivers/sound/ite8172.c
drivers/sound/maestro3.c
drivers/sound/nec_vrc5477.c
drivers/sound/opl3sa2.c
drivers/sound/sb_card.c
drivers/sound/trident.c
drivers/sound/vidc.c
drivers/tc/tc.c
drivers/usb/uhci.c
drivers/video/acornfb.c
drivers/video/cyber2000fb.c
drivers/video/cyber2000fb.h
fs/attr.c
fs/block_dev.c
fs/devfs/util.c
fs/ext2/Makefile
fs/ext2/acl.c [deleted file]
fs/ext2/file.c
fs/ext2/inode.c
fs/freevxfs/vxfs_super.c
fs/lockd/clntproc.c
fs/lockd/svclock.c
fs/lockd/svcproc.c
fs/locks.c
fs/nfs/read.c
fs/nfs/write.c
fs/nfsd/nfsxdr.c
fs/partitions/check.c
fs/partitions/msdos.c
fs/proc/array.c
fs/proc/proc_misc.c
fs/udf/balloc.c
fs/udf/dir.c
fs/udf/file.c
fs/udf/ialloc.c
fs/udf/inode.c
fs/udf/namei.c
fs/udf/super.c
fs/udf/truncate.c
fs/udf/udfdecl.h
include/asm-arm/a.out.h
include/asm-arm/arch-sa1100/SA-1111.h
include/asm-arm/arch-sa1100/adsbitsy.h [new file with mode: 0644]
include/asm-arm/arch-sa1100/assabet.h
include/asm-arm/arch-sa1100/bitsy.h [deleted file]
include/asm-arm/arch-sa1100/dma.h
include/asm-arm/arch-sa1100/graphicsmaster.h [new file with mode: 0644]
include/asm-arm/arch-sa1100/h3600.h [new file with mode: 0644]
include/asm-arm/arch-sa1100/hardware.h
include/asm-arm/arch-sa1100/irqs.h
include/asm-arm/arch-sa1100/keyboard.h
include/asm-arm/arch-sa1100/pangolin.h
include/asm-arm/arch-sa1100/uncompress.h
include/asm-arm/atomic.h
include/asm-arm/cpu-multi32.h
include/asm-arm/cpu-single.h
include/asm-arm/hardirq.h
include/asm-arm/hardware/pci_v3.h
include/asm-arm/io.h
include/asm-arm/mach/arch.h
include/asm-arm/param.h
include/asm-arm/pci.h
include/asm-arm/pgtable.h
include/asm-arm/processor.h
include/asm-arm/setup.h
include/asm-arm/signal.h
include/asm-arm/uaccess.h
include/asm-i386/system.h
include/asm-s390/chandev.h
include/asm-s390/current.h
include/asm-s390/dasd.h
include/asm-s390/debug.h
include/asm-s390/gdb-stub.h
include/asm-s390/lowcore.h
include/asm-s390/pgalloc.h
include/asm-s390/pgtable.h
include/asm-s390/ptrace.h
include/asm-s390/sigp.h
include/asm-s390/smp.h
include/asm-s390/softirq.h
include/asm-s390/spinlock.h
include/asm-s390/uaccess.h
include/asm-s390/ucontext.h
include/asm-s390/unistd.h
include/asm-s390/vtoc.h
include/asm-s390x/chandev.h
include/asm-s390x/current.h
include/asm-s390x/dasd.h
include/asm-s390x/debug.h
include/asm-s390x/lowcore.h
include/asm-s390x/mathemu.h [deleted file]
include/asm-s390x/page.h
include/asm-s390x/param.h
include/asm-s390x/pgtable.h
include/asm-s390x/sigp.h
include/asm-s390x/smp.h
include/asm-s390x/softirq.h
include/asm-s390x/spinlock.h
include/asm-s390x/ucontext.h
include/asm-s390x/unistd.h
include/linux/b1lli.h
include/linux/b1pcmcia.h
include/linux/blkdev.h
include/linux/console_struct.h
include/linux/ext2_fs.h
include/linux/fs.h
include/linux/i2c-dev.h
include/linux/i2c-elektor.h
include/linux/i2c-id.h
include/linux/i2c-proc.h [new file with mode: 0644]
include/linux/i2c.h
include/linux/i2o-dev.h
include/linux/i2o.h
include/linux/pci_ids.h
include/linux/sonypi.h
include/linux/spinlock.h
include/linux/udf_fs.h
include/linux/udf_fs_sb.h
include/linux/videodev.h
include/pcmcia/cs_types.h
include/pcmcia/ss.h
kernel/context.c
kernel/ksyms.c
lib/vsprintf.c
mm/filemap.c
net/ipv4/ipconfig.c
net/sunrpc/sched.c
net/sunrpc/stats.c

index d4cfb5bb812d21148a0c97794c9739c06ad24a5f..041780f428acefa250e82a58d292f4567513df70 100644 (file)
@@ -8,9 +8,9 @@
 for Linux.
 
 2. My Linux environment
-Linux kernel: 2.4.0 / 2.2.18
-pcmcia-cs:    3.1.24
-gcc:          gcc-2.95.2
+Linux kernel: 2.4.7 / 2.2.19
+pcmcia-cs:    3.1.27
+gcc:          gcc-2.95.4
 PC card:      I-O data PCSC-F (NinjaSCSI-3)
               I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi)
 SCSI device:  I-O data CDPS-PX24 (CD-ROM drive)
@@ -55,6 +55,8 @@ $ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz
 [4] Extract this driver's archive somewhere, and edit Makefile, then do make.
 $ tar -zxvf nsp_cs-x.x.tar.gz
 $ cd nsp_cs-x.x
+$ emacs Makefile
+...
 $ make
 
 [5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
@@ -95,7 +97,7 @@ card "WorkBit NinjaSCSI-32Bi (16bit) / KME-4"
   bind "nsp_cs"
 -------------------------------------
 
-[7] Boot (or reboot) pcmcia-cs.
+[7] Start (or restart) pcmcia-cs.
 # /etc/rc.d/rc.pcmcia start        (BSD style)
 or
 # /etc/init.d/pcmcia start         (SYSV style)
@@ -111,7 +113,8 @@ your computer, you encount some *BAD* error like disk crash.
 your data. Please backup your data when you use this driver.
 
 6. Known Bugs
- Some write error occurs when you use slow device.
+ In 2.4 kernel, you can't use 640MB Optical disk. This error comes from
+high level SCSI driver.
 
 7. Testing
  Please send me some reports(bug reports etc..) of this software.
@@ -124,4 +127,4 @@ When you send report, please tell me these or more.
  See GPL.
 
 
-2001/02/01 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
+2001/08/08 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
index cbd05537e3465cc7b4b79c4cf050a8338e32cfeb..2f45ddd6781acdb8a3888d5fb8f5629375b1a091 100644 (file)
@@ -162,7 +162,7 @@ Kernel entry (head-armv.S)
     <description of your architecture>
 
   Please follow this format - it is an automated system.  You should
-  receive a reply within one day.
+  receive a reply in short order.
 
 ---
 Russell King (26/01/2001)
diff --git a/Documentation/arm/SA1100/ADSBitsy b/Documentation/arm/SA1100/ADSBitsy
new file mode 100644 (file)
index 0000000..ab47c38
--- /dev/null
@@ -0,0 +1,43 @@
+ADS Bitsy Single Board Computer
+(It is different from Bitsy(iPAQ) of Compaq)
+
+For more details, contact Applied Data Systems or see
+http://www.applieddata.net/products.html
+
+The Linux support for this product has been provided by
+Woojung Huh <whuh@applieddata.net>
+
+Use 'make adsbitsy_config' before any 'make config'.
+This will set up defaults for ADS Bitsy support.
+
+The kernel zImage is linked to be loaded and executed at 0xc0400000.
+
+Linux can  be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+
+Supported peripherals:
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- SA1111 USB Master
+- SA1100 serial port
+- pcmcia, compact flash
+- touchscreen(ucb1200)
+- console on LCD screen
+- serial ports (ttyS[0-2])
+  - ttyS0 is default for serial console
+
+To do:
+- everything else!  :-)
+
+Notes:
+
+- The flash on board is divided into 3 partitions.
+  You should be careful to use flash on board.
+  It's partition is different from GraphicsClient Plus and GraphicsMaster
+
+- 16bpp mode requires a different cable than what ships with the board.
+  Contact ADS or look through the manual to wire your own. Currently,
+  if you compile with 16bit mode support and switch into a lower bpp
+  mode, the timing is off so the image is corrupted.  This will be
+  fixed soon.
+
+Any contribution can be sent to nico@cam.org and will be greatly welcome!
diff --git a/Documentation/arm/SA1100/GraphicsMaster b/Documentation/arm/SA1100/GraphicsMaster
new file mode 100644 (file)
index 0000000..dd28745
--- /dev/null
@@ -0,0 +1,53 @@
+ADS GraphicsMaster Single Board Computer
+
+For more details, contact Applied Data Systems or see
+http://www.applieddata.net/products.html
+
+The original Linux support for this product has been provided by
+Nicolas Pitre <nico@cam.org>. Continued development work by
+Woojung Huh <whuh@applieddata.net>
+
+Use 'make graphicsmaster_config' before any 'make config'.
+This will set up defaults for GraphicsMaster support.
+
+The kernel zImage is linked to be loaded and executed at 0xc0400000.
+
+Linux can  be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+
+Supported peripherals:
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- SA1111 USB Master
+- on-board SMC 92C96 ethernet NIC
+- SA1100 serial port
+- flash memory access (MTD/JFFS)
+- pcmcia, compact flash
+- touchscreen(ucb1200)
+- ps/2 keyboard
+- console on LCD screen
+- serial ports (ttyS[0-2])
+  - ttyS0 is default for serial console
+- Smart I/O (ADC, keypad, digital inputs, etc)
+  See http://www.applieddata.com/developers/linux for IOCTL documentation
+  and example user space code. ps/2 keybd is multiplexed through this driver
+
+To do:
+- everything else!  :-)
+
+Notes:
+
+- The flash on board is divided into 3 partitions.  mtd0 is where
+  the zImage is stored.  It's been marked as read-only to keep you
+  from blasting over the bootloader. :)  mtd1 is
+  for the ramdisk.gz image.  mtd2 is user flash space and can be
+  utilized for either JFFS or if you're feeling crazy, running ext2
+  on top of it. If you're not using the ADS bootloader, you're
+  welcome to blast over the mtd1 partition also.
+
+- 16bpp mode requires a different cable than what ships with the board.
+  Contact ADS or look through the manual to wire your own. Currently,
+  if you compile with 16bit mode support and switch into a lower bpp
+  mode, the timing is off so the image is corrupted.  This will be
+  fixed soon.
+
+Any contribution can be sent to nico@cam.org and will be greatly welcome!
index 6fa266765c74a577b4ad2b45fb17d9c33d11ade1..e885a6b4bb244e0cf572f92be49c5fadd8ca9ebc 100644 (file)
@@ -2,7 +2,7 @@ Pangolin is a StrongARM 1110-based evaluation platform produced
 by Dialogue Technology (http://www.dialogue.com.tw/).
 It has EISA slots for ease of configuration with SDRAM/Flash
 memory card, USB/Serial/Audio card, Compact Flash card,
-and TFT-LCD card.
+PCMCIA/IDE card and TFT-LCD card.
 
 To compile for Pangolin, you must issue the following commands:
 
@@ -18,3 +18,7 @@ Supported peripherals:
 - UDA1341 sound driver
 - SA1100 LCD controller for 800x600 16bpp TFT-LCD
 - MQ-200 driver for 800x600 16bpp TFT-LCD
+- Penmount(touch panel) driver
+- PCMCIA driver
+- SMC91C94 LAN driver
+- IDE driver (experimental)
index 0f748f8ef90d2df152ad06769a2337bcfe3ff90c..d8c95d57910636c77c74f731c2fd58d1dd0ef043 100644 (file)
@@ -8,8 +8,9 @@ This driver is known to work with the following cards:
        * SA 5300
        * SA 5i 
        * SA 532
+       * SA 5312
 
-If notes are not already created in the /dev/cciss directory
+If nodes are not already created in the /dev/cciss directory
 
 # mkdev.cciss [ctlrs]
 
@@ -47,3 +48,78 @@ The suggested device naming scheme is:
 /dev/cciss/c1d1p1              Controller 1, disk 1, partition 1
 /dev/cciss/c1d1p2              Controller 1, disk 1, partition 2
 /dev/cciss/c1d1p3              Controller 1, disk 1, partition 3
+
+SCSI tape drive and medium changer support
+------------------------------------------
+
+SCSI sequential access devices and medium changer devices are supported and 
+appropriate device nodes are automatically created.  (e.g.  
+/dev/st0, /dev/st1, etc.  See the "st" man page for more details.) 
+You must enable "SCSI tape drive support for Smart Array 5xxx" and 
+"SCSI support" in your kernel configuration to be able to use SCSI
+tape drives with your Smart Array 5xxx controller.
+
+Additionally, note that the driver will not engage the SCSI core at init 
+time.  The driver must be directed to dynamically engage the SCSI core via 
+the /proc filesystem entry which the "block" side of the driver creates as 
+/proc/driver/cciss/cciss* at runtime.  This is because at driver init time, 
+the SCSI core may not yet be initialized (because the driver is a block 
+driver) and attempting to register it with the SCSI core in such a case 
+would cause a hang.  This is best done via an initialization script 
+(typically in /etc/init.d, but could vary depending on distibution). 
+For example:
+
+       for x in /proc/driver/cciss/cciss[0-9]*
+       do
+               echo "engage scsi" > $x
+       done
+
+Once the SCSI core is engaged by the driver, it cannot be disengaged 
+(except by unloading the driver, if it happens to be linked as a module.)
+
+Note also that if no sequential access devices or medium changers are
+detected, the SCSI core will not be engaged by the action of the above
+script.
+
+Hot plug support for SCSI tape drives
+-------------------------------------
+
+Hot plugging of SCSI tape drives is supported, with some caveats.
+The cciss driver must be informed that changes to the SCSI bus
+have been made, in addition to and prior to informing the the SCSI 
+mid layer.  This may be done via the /proc filesystem.  For example:
+
+       echo "rescan" > /proc/scsi/cciss0/1
+
+This causes the adapter to query the adapter about changes to the 
+physical SCSI buses and/or fibre channel arbitrated loop and the 
+driver to make note of any new or removed sequential access devices
+or medium changers.  The driver will output messages indicating what 
+devices have been added or removed and the controller, bus, target and 
+lun used to address the device.  Once this is done, the SCSI mid layer 
+can be informed of changes to the virtual SCSI bus which the driver 
+presents to it in the usual way. For example: 
+
+       echo add-single-device 3 2 1 0 > /proc/scsi/scsi
+to add a device on controller 3, bus 2, target 1, lun 0.   Note that
+the driver makes an effort to preserve the devices positions
+in the virtual SCSI bus, so if you are only moving tape drives 
+around on the same adapter and not adding or removing tape drives 
+from the adapter, informing the SCSI mid layer may not be necessary.
+
+Note that the naming convention of the /proc filesystem entries 
+contains a number in addition to the driver name.  (E.g. "cciss0" 
+instead of just "cciss" which you might expect.)   This is because 
+of changes to the 2.4 kernel PCI interface related to PCI hot plug
+that imply the driver must register with the SCSI mid layer once per
+adapter instance rather than once per driver.
+
+Note: ONLY sequential access devices and medium changers are presented 
+as SCSI devices to the SCSI mid layer by the cciss driver.  Specifically, 
+physical SCSI disk drives are NOT presented to the SCSI mid layer.  The 
+physical SCSI disk drives are controlled directly by the array controller 
+hardware and it is important to prevent the OS from attempting to directly 
+access these devices too, as if the array controller were merely a SCSI 
+controller in the same way that we are allowing it to access SCSI tape drives.
+
index 03b5836f49ff29a8142b5a3bd538055a9c29f470..3c9aeb610ba0e7005f25a6591c6a36d55e8d907e 100644 (file)
@@ -70,6 +70,9 @@ the device supports them. Both are illustrated below.
     /* buf[0] contains the read byte */
   }
 
+IMPORTANT: because of the use of inline functions, you *have* to use
+'-O' or some variation when you compile your program!
+
 
 Full interface description
 ==========================
index a6db1b5e5dbdc33f729507c96b2de377c3a44e90..6fe0213858c3b7a1fb34b91ae19289020398b285 100644 (file)
@@ -1,9 +1,9 @@
-This is an explanation of what i2c is, and what is supported.
+This is an explanation of what i2c is, and what is supported in this package.
 
 I2C and SMBus
 =============
 
-I2C (pronounce: I square C) is a protocol developed by Philips. It is a 
+I2C (pronounce: I squared C) is a protocol developed by Philips. It is a 
 slow two-wire protocol (10-100 kHz), but it suffices for many types of 
 devices.
 
@@ -25,6 +25,7 @@ When we talk about I2C, we use the following terms:
             Adapter
   Device -> Driver
             Client
+
 An Algorithm driver contains general code that can be used for a whole class
 of I2C adapters. Each specific adapter driver depends on one algorithm
 driver.
@@ -35,29 +36,40 @@ integrated than Algorithm and Adapter.
 
 For a given configuration, you will need a driver for your I2C bus (usually
 a separate Adapter and Algorithm driver), and drivers for your I2C devices
-(usually one driver for each device).
+(usually one driver for each device). There are no I2C device drivers
+in this package. See the lm_sensors project http://www.lm-sensors.nu
+for device drivers.
+
 
+Included Bus Drivers
+====================
+Note that not only stable drivers are patched into the kernel by 'mkpatch'.
 
-Included Drivers
-================
 
 Base modules
 ------------
 
 i2c-core: The basic I2C code, including the /proc interface
 i2c-dev:  The /dev interface
+i2c-proc: The /proc interface for device (client) drivers
 
 Algorithm drivers
 -----------------
 
-i2c-algo-bit: A bit-banging algorithm
-i2c-algo-pcf: A PCF 8584 style algorithm
+i2c-algo-8xx:    An algorithm for CPM's I2C device in Motorola 8xx processors (NOT BUILT BY DEFAULT)
+i2c-algo-bit:    A bit-banging algorithm
+i2c-algo-pcf:    A PCF 8584 style algorithm
+i2c-algo-ppc405: An algorithm for the I2C device in IBM 405xx processors (NOT BUILT BY DEFAULT)
 
 Adapter drivers
 ---------------
 
 i2c-elektor:     Elektor ISA card (uses i2c-algo-pcf)
 i2c-elv:         ELV parallel port adapter (uses i2c-algo-bit)
+i2c-pcf-epp:     PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (BROKEN - missing i2c-pcf-epp.h)
 i2c-philips-par: Philips style parallel port adapter (uses i2c-algo-bit)
+i2c-ppc405:      IBM 405xx processor I2C device (uses i2c-algo-ppc405) (NOT BUILT BY DEFAULT)
+i2c-pport:       Primitive parallel port adapter (uses i2c-algo-bit)
+i2c-rpx:         RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT)
 i2c-velleman:    Velleman K9000 parallel port adapter (uses i2c-algo-bit)
 
index a66debc0ff24e634bc53869418c81b753de5831d..8606aa6a625e8a6eea359ab795d83cf78f8e9067 100644 (file)
@@ -33,7 +33,7 @@ address.
     /* detach_client  */  &foo_detach_client,
     /* command        */  &foo_command,   /* May be NULL */
     /* inc_use        */  &foo_inc_use,   /* May be NULL */
-    /* dec_use        */  &foo_dev_use    /* May be NULL */
+    /* dec_use        */  &foo_dec_use    /* May be NULL */
   }
  
 The name can be chosen freely, and may be upto 40 characters long. Please
@@ -190,7 +190,7 @@ are defined in i2c.h to help you support them, as well as a generic
 detection algorithm.
 
 You do not have to use this parameter interface; but don't try to use
-function i2c_probe() (or sensors_detect()) if you don't.
+function i2c_probe() (or i2c_detect()) if you don't.
 
 NOTE: If you want to write a `sensors' driver, the interface is slightly
       different! See below.
@@ -344,17 +344,17 @@ detected at a specific address, another callback is called.
     return i2c_probe(adapter,&addr_data,&foo_detect_client);
   }
 
-For `sensors' drivers, use the sensors_detect function instead:
+For `sensors' drivers, use the i2c_detect function instead:
   
   int foo_attach_adapter(struct i2c_adapter *adapter)
   { 
-    return sensors_detect(adapter,&addr_data,&foo_detect_client);
+    return i2c_detect(adapter,&addr_data,&foo_detect_client);
   }
 
 Remember, structure `addr_data' is defined by the macros explained above,
 so you do not have to define it yourself.
 
-The i2c_probe or sensors_detect function will call the foo_detect_client
+The i2c_probe or i2c_detect function will call the foo_detect_client
 function only for those i2c addresses that actually have a device on
 them (unless a `force' parameter was used). In addition, addresses that
 are already in use (by some other registered client) are skipped.
@@ -363,9 +363,9 @@ are already in use (by some other registered client) are skipped.
 The detect client function
 --------------------------
 
-The detect client function is called by i2c_probe or sensors_detect.
+The detect client function is called by i2c_probe or i2c_detect.
 The `kind' parameter contains 0 if this call is due to a `force'
-parameter, and 0 otherwise (for sensors_detect, it contains 0 if
+parameter, and 0 otherwise (for i2c_detect, it contains 0 if
 this call is due to the generic `force' parameter, and the chip type
 number if it is due to a specific `force' parameter).
 
@@ -530,7 +530,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
     /* SENSORS ONLY BEGIN */
     /* Register a new directory entry with module sensors. See below for
        the `template' structure. */
-    if ((i = sensors_register_entry(new_client, type_name,
+    if ((i = i2c_register_entry(new_client, type_name,
                                     foo_dir_table_template,THIS_MODULE)) < 0) {
       err = i;
       goto ERROR4;
@@ -574,8 +574,8 @@ much simpler than the attachment code, fortunately!
     int err,i;
 
     /* SENSORS ONLY START */
-    /* Deregister with the `sensors' module. */
-    sensors_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
+    /* Deregister with the `i2c-proc' module. */
+    i2c_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
     /* SENSORS ONLY END */
 
     /* Try to detach the client from i2c space */
@@ -772,12 +772,12 @@ you call sensors_register_entry.
 
 First, I will give an example definition.
   static ctl_table foo_dir_table_template[] = {
-    { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &sensors_proc_real,
-      &sensors_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &sensors_proc_real,
-      &sensors_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &sensors_proc_real,
-      &sensors_sysctl_real,NULL,&foo_data },
+    { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &i2c_proc_real,
+      &i2c_sysctl_real,NULL,&foo_func },
+    { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &i2c_proc_real,
+      &i2c_sysctl_real,NULL,&foo_func },
+    { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &i2c_proc_real,
+      &i2c_sysctl_real,NULL,&foo_data },
     { 0 }
   };
 
@@ -791,8 +791,8 @@ The third, sixth and ninth parameters should always be NULL, and the
 fourth should always be 0. The fifth is the mode of the /proc file;
 0644 is safe, as the file will be owned by root:root. 
 
-The seventh and eighth parameters should be &sensors_proc_real and
-&sensors_sysctl_real if you want to export lists of reals (scaled
+The seventh and eighth parameters should be &i2c_proc_real and
+&i2c_sysctl_real if you want to export lists of reals (scaled
 integers). You can also use your own function for them, as usual.
 Finally, the last parameter is the call-back to gather the data
 (see below) if you use the *_proc_real functions. 
index a11b29d69ce13ebd4ef2430e6953acf39dffebf7..43ce32a92d3c30845438f229d43bb2dfc6fc953f 100644 (file)
@@ -101,6 +101,17 @@ Command line parameters
   the device driver will be notified if possible, so the device will become
   available to the system.
 
+  You can also add ranges of devices to be ignored by piping to 
+  /proc/cio_ignore; "add <devnorange>, <devnorange>, ..." will ignore the 
+  specified devices.
+
+  Note: Already known devices cannot be ignored; this also applies to devices
+        which are gone after a machine check.
+
+  For example, if device abcd is already known and all other devices a000-afff 
+  are not known, "echo add 0xa000-0xaccc, 0xaf00-0xafff > /proc/cio_ignore" 
+  will add af00-afff to the list of ignored devices and skip a000-accc.
+
 
 * /proc/s390dbf/cio_*/ (S/390 debug feature)
 
@@ -122,3 +133,7 @@ Command line parameters
   /proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on
   the S/390 debug feature (Documentation/s390/s390dbf.txt) for details.
 
+* /proc/irq_count
+
+  This entry counts how many times s390_process_IRQ has been called for each 
+  CPU. This info is in /proc/interrupts on other architectures.
index 6499cdf5d4e2931132700e3fb633f40053fef093..f6febfc2e7b981e08558d4ec760a0c5fb13cc1e4 100644 (file)
@@ -124,17 +124,16 @@ force list: is a term specific to channel device layer describing a range of dev
 .B (ctc|escon|lcs|osad|qeth)<devif_num>, 
 read_devno,write_devno,<data_devno,memory_usage_in_k,port_no/protocol_no,checksum_received_ip_pkts,use_hw_stats>
 .It
-devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type.
-The data_devno field is only valid for qeth devices when not forcing a range of devices.
-all parameters after & including memory_usage_in_k can be set optionally if not set they
+devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type, qeth devices can't be forced as a range as it makes no sense for them.
+The data_devno field is only valid for qeth devices, all parameters including & after memory_usage_in_k can be set optionally, if not set they
 go to default values. memory_usage_in_k ( 0 the default ) means let the driver choose,checksum_received_ip_pkts & use_hw_stats are set to false
 .It
 e.g. ctc0,0x7c00,0x7c01
 .It
 Tells the channel layer to force ctc0 if detected to use cuu's 7c00 & 7c01 port,port_no is the relative adapter no on lcs, on ctc/escon this field is the ctc/escon protocol number ( default 0 ), don't do checksumming on received ip packets & as ctc doesn't have hardware stats so it ignores this parameter. This can be used for instance to force a device if it presents bad sense data to the IO layer & thus autodetection fails.
 .It
-qeth,0x7c00,0x7d00,-1,4096
-All devices between 0x7c00 & 7d00 should be detected as gigabit ethernet, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
+lcs,0x7c00,0x7d00,-1,4096
+All devices between 0x7c00 & 7d00 should be detected as lcs, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
 .It
 qeth1,0x7c00,0x7c01,0x7c02
 .It
@@ -368,6 +367,12 @@ Don't automatically read /etc/chandev.conf on boot.
 Force drivers modules to stay loaded even if no device is found,
 this is useful for debugging & one wishes to examine debug entries in 
 /proc/s390dbf/ to find out why a module failed to load.
+.It
+e.g.
+.It
+persist,-1 forces all devices to persist.
+.It
+persist,0 forces all channel devices to be non persistent.
 .El
 
 .It
index 2b6ec3981fe28befc6bb56f90797c8b0b6450c74..d7ae2d1fde81996314e01ffd11f409c3cadb99b1 100644 (file)
@@ -336,7 +336,7 @@ proc-files:
 Example:
 
 > ls /proc/s390dbf/dasd
-hex_ascii  level      raw
+flush  hex_ascii  level      raw 
 > cat /proc/s390dbf/dasd/hex_ascii | sort +1
 00 00974733272:680099 2 - 02 0006ad7e  07 ea 4a 90 | ....
 00 00974733272:682210 2 - 02 0006ade6  46 52 45 45 | FREE
@@ -363,6 +363,20 @@ Example:
 > cat /proc/s390dbf/dasd/level
 5
 
+Flushing debug areas
+--------------------
+Debug areas can be flushed with piping the number of the desired
+area (0...n) to the proc file "flush". When using "-" all debug areas
+are flushed.
+
+Examples:
+
+1. Flush debug area 0:
+> echo "0" > /proc/s390dbf/dasd/flush  
+
+2. Flush all debug areas:
+> echo "-" > /proc/s390dbf/dasd/flush
+
 lcrash Interface
 ----------------
 It is planned that the dump analysis tool lcrash gets an additional command
index 0812e90b6e4a9ae04b5e51d6135d092752864626..aab71c083b5989f25521e3aed674a2728cbdc886 100644 (file)
@@ -15,6 +15,8 @@ generate, like:
        - capture button events (only on Vaio Picturebook series)
        - Fn keys
        - bluetooth button (only on C1VR model)
+       - back button (PCG-GR7/K model)
+       - lid open/close events (Z600NE model)
 
 Those events (see linux/sonypi.h) can be polled using the character device node
 /dev/sonypi (major 10, minor auto allocated or specified as a option).
@@ -36,6 +38,14 @@ specs for its laptops. If someone convinces them to do so, drop me a note.
 Module options:
 ---------------
 
+Several options can be passed to the sonypi driver, either by adding them
+to /etc/modules.conf file, when the driver is compiled as a module or by
+adding the following to the kernel command line (in your bootloader):
+
+       sonypi=minor[[[[,camera],fnkeyinit],verbose],compat]
+
+where:
+
        minor:          minor number of the misc device /dev/sonypi, 
                        default is -1 (automatic allocation, see /proc/misc
                        or kernel logs)
@@ -49,6 +59,11 @@ Module options:
 
        verbose:        print unknown events from the sonypi device
 
+       compat:         uses some compatibility code for enabling the sonypi
+                       events. If the driver worked for you in the past
+                       (prior to version 1.5) and does not work anymore,
+                       add this option and report to the author.
+
 Module use:
 -----------
 
diff --git a/Documentation/video4linux/README.buz b/Documentation/video4linux/README.buz
deleted file mode 100644 (file)
index 5eaf517..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-Iomega Buz Driver for Linux
-===========================
-
-by Rainer Johanni <Rainer@Johanni.de>
-
-Compiling and Loading the Driver
-================================
-
-You must run a 2.2.x kernel in order to use this driver.
-
-To compile the driver, just type make.
-
-Besides the files in this directory, the driver needs the
-'videodev' and the 'i2c' module from the Linux kernel.
-In order to get these modules available, enable module support
-for VIDEODEV and BTTV (which implies i2c) in your kernel
-configuration. You find these devices in the menu
-"Character Devices" in your Kernel Configuration.
-
-Before you load the driver you must have a video device
-at major device node 81. If you don't have it yet, do the
-following (as root!):
-
-cd /dev
-mknod video0 c 81 0
-ln -s video0 video
-
-Edit the 'update' script if you want to give the driver
-special options and then type (as root)
-
-./update
-
-to insert all the necessary modules into the kernel.
-
-If you want to make full use of the Video for Linux uncompressed
-grabbing facilities, you must either
-
-- obtain and install the "big_physarea patch" for your kernel and
-  set aside the necessary memory during boot time.
-  There seem to be several versions of this patch against
-  various kernel versions floating around in the net,
-  you may obtain one e.g. from:
-  http://www.polyware.nl/~middelin/patch/bigphysarea-2.2.1.tar.gz
-  You also have to compile your driver AFTER installing that patch
-  in order to get it working
-
-  or
-
-- start your kernel with the mem=xxx option, where xxx is your
-  real memory minus the memory needed for the buffers.
-  For doing this add an entry in lilo.conf (if you use lilo):
-    append "mem=xxxM"
-  or add a line in your linux.par file (if you use loadlin):
-    mem=xxxM
-
-The second method is by far easier, however it is dangerous
-if more than one driver at a time has the idea to use the memory
-leftover by setting the mem=xxx parameter below the actual
-memory size.
-
-Read also below how to use this memory!
-
-
-
-Driver Options
-==============
-
-You are able to customize the behavior of the driver by giving
-it some options at start time.
-
-default_input, default_norm
----------------------------
-
-As soon as the driver is loaded, the Buz samples video signals
-from one of its input ports and displays it on its output.
-The driver uses the Composite Input and the video norm PAL for this.
-If you want to change this default behavior, set default_input=1
-(for S-VHS input) or default_norm=1 for NTSC.
-
-v4l_nbufs, v4l_bufsize
-----------------------
-
-In order to make to make full use of the Video for Linux picture
-grabbing facilities of the driver (which are needed by many
-Video for Linux applications), the driver needs a set of
-physically contiguous buffers for grabbing. These parameters
-determine how many buffers of which size the driver will
-allocate at open (the open will fail if it is unable to do so!).
-
-These values do not affect the MJPEG grabbing facilities of the driver,
-they are needed for uncompressed image grabbing only!!!
-
-v4l_nbufs is the number of buffers to allocate, a value of 2 (the default)
-should be sufficient in almost all cases. Only special applications
-(streaming captures) will need more buffers and then mostly the
-MJPEG capturing features of the Buz will be more appropriate.
-So leave this parameter at it's default unless you know what you do.
-
-The things for v4l_bufsize are more complicated:
-v4l_bufsize is set by default to 128 [KB] which is the maximum
-amount of physically contiguous memory Linux is able to allocate
-without kernel changes. This is sufficient for grabbing 24 bit color images
-up to sizes of approx. 240x180 pixels (240*180*3 = 129600, 128 KB = 131072).
-
-In order to be able to capture bigger images you have either to
-- obtain and install the "big_physarea patch" and set aside
-  the necessary memory during boot time or
-- start your kernel with the mem=xxx option, where xxx is your
-  real memory minus the memory needed for the buffers.
-In that case, useful settings for v4l_bufsize are
-- 1296 [Kb] for grabbing 24 bit images of max size 768*576
-- 1728 [Kb] for 32bit images of same size (4*768*576 = 1728 Kb!)
-You may reduce these numbers accordingly if you know you are only
-grabbing 720 pixels wide images or NTSC images (max height 480).
-
-In some cases it may happen that Linux isn't even able to obtain
-the default 128 KB buffers. If you don't need uncompressed image
-grabbing at all, set v4l_bufsize to an arbitrary small value (e.g. 4)
-in order to be able to open the video device.
-
-vidmem
-------
-
-The video mem address of the video card.
-The driver has a little database for some videocards
-to determine it from there. If your video card is not in there
-you have either to give it to the driver as a parameter
-or set in in a VIDIOCSFBUF ioctl
-
-The videocard database is contained in the file "videocards.h"
-Gernot Ziegler wants to keep an actual version of that file.
-If your card is not contained in that file, look at
-http://www.lysator.liu.se/~gz/buz/ for an actual version of
-"videocards.h".
-
-triton, natoma
---------------
-
-The driver tries to detect if you have a triton or natome chipset
-in order to take special measures for these chipsets.
-If this detection fails but you are sure you have such a chipset,
-set the corresponding variable to 1.
-This is a very special option and may go away in the future.
-
-
-
-Programming interface
-=====================
-
-This driver should be fully compliant to Video for Linux, so all
-tools working with Video for Linux should work with (hopefully)
-no problems.
-
-A description of the Video for Linux programming interface can be found at:
-http://roadrunner.swansea.linux.org.uk/v4lapi.shtml
-
-Besides the Video for Linux interface, the driver has a "proprietary"
-interface for accessing the Buz's MJPEG capture and playback facilities.
-
-The ioctls for that interface are as follows:
-
-BUZIOC_G_PARAMS
-BUZIOC_S_PARAMS
-
-Get and set the parameters of the buz. The user should always
-do a BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
-settings, change what he likes and then make a BUZIOC_S_PARAMS call.
-A typical application should at least set the members
-input, norm and decimation of the struct buz_params.
-For a full description of all members see "buz.h"
-
-BUZIOC_REQBUFS
-
-Before being able to capture/playback, the user has to request
-the buffers he is wanting to use. Fill the structure
-buz_requestbuffers with the size (recommended: 256*1024) and
-the number (recommended 32 up to 256). There are no such restrictions
-as for the Video for Linux buffers, you should LEAVE SUFFICIENT
-MEMORY for your system however, else strange things will happen ....
-On return, the buz_requestbuffers structure contains number and
-size of the actually allocated buffers.
-You should use these numbers for doing a mmap of the buffers
-into the user space.
-The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
-maps the MJPEG buffer instead of the V4L buffers.
-
-BUZIOC_QBUF_CAPT
-BUZIOC_QBUF_PLAY
-
-Queue a buffer for capture or playback. The first call also starts
-streaming capture. When streaming capture is going on, you may
-only queue further buffers or issue syncs until streaming
-capture is switched off again with a argument of -1 to
-a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
-
-BUZIOC_SYNC
-
-Issue this ioctl when all buffers are queued. This ioctl will
-block until the first buffer becomes free for saving its
-data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
-
-BUZIOC_G_STATUS
-
-Get the status of the input lines (video source connected/norm).
-This ioctl may be subject to change.
-
-
-
-
-
-See the examples directory delivered with this driver
-for actual coding examples!
index 0001c32e4bdba9fc72491891da153bd745715cf5..a861041bf6b0491ca9a0801888aec7ce4ebc276b 100644 (file)
@@ -4,7 +4,10 @@ Vaio Picturebook Motion Eye Camera Driver Readme
        Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
 
 This driver enable the use of video4linux compatible applications with the
-Motion Eye camera.
+Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O 
+Control Device" driver (which can be found in the "Character drivers" 
+section of the kernel configuration utility) to be compiled and installed
+(using its "camera=1" parameter).
 
 It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
 
index f012fb9c21cbb01555c8542a15ad9fd16c0c29f2..cce4a64295ba5fbe3f14519fa6a33296c4e52027 100644 (file)
@@ -1053,6 +1053,12 @@ M:     Andreas Mohr <100.30936@germany.net>
 L:     linux-net@vger.kernel.org
 S:     Maintained
 
+NINJA SCSI-3 / NINJA SCSI-32Bi PCMCIA SCSI HOST ADAPTER DRIVER
+P:     YOKOTA Hiroshi
+M:     yokota@netlab.is.tsukuba.ac.jp
+W:     http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/
+S:     Maintained
+
 NON-IDE/NON-SCSI CDROM DRIVERS [GENERAL] (come on, crew - mark your responsibility)
 P:     Eberhard Moenkeberg
 M:     emoenke@gwdg.de
@@ -1399,6 +1405,13 @@ L:       linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
 
+TOSHIBA SMM DRIVER
+P:     Jonathan Buzzard
+M:     jonathan@buzzard.org.uk
+L:     tlinux-users@tce.toshiba-dme.co.jp
+W:     http://www.buzzard.org.uk/toshiba/
+S:     Maintained
+
 TRIDENT 4DWAVE/SIS 7018 PCI AUDIO CORE
 P:      Ollie Lho  
 M:      ollie@sis.com.tw
index 09842c8bb95e60e62c656fb2b6f18db0f7bb0e5b..c153a0de3619df168329b07d3ad21a94cdc0d39a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 12
-EXTRAVERSION =
+SUBLEVEL = 13
+EXTRAVERSION =-pre1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
index 9867ad4450a46b230f3c525a5be82eccadf6f49c..687a0de2ddd60ca554242c93166639c291cda7ae 100644 (file)
@@ -45,8 +45,6 @@ tune-$(CONFIG_CPU_SA1100)     :=-mtune=strongarm1100
 CFLAGS         +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
 AFLAGS         +=$(apcs-y) $(arch-y) -mno-fpu
 
-LIBGCC         := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
-
 ifeq ($(CONFIG_CPU_26),y)
 PROCESSOR       = armo
   ifeq ($(CONFIG_ROM_KERNEL),y)
@@ -123,7 +121,7 @@ MACHINE              = integrator
 endif
 
 ifeq ($(CONFIG_ARCH_CLPS711X),y)
-TEXTADDR        = 0xc0018000
+TEXTADDR        = 0xc0028000
 MACHINE                 = clps711x
 endif
 
@@ -131,7 +129,7 @@ ifeq ($(CONFIG_ARCH_ANAKIN),y)
 MACHINE                 = anakin
 endif
 
-export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
+export MACHINE PROCESSOR TEXTADDR GZFLAGS
 
 # Only set INCDIR if its not already defined above
 # Grr, ?= doesn't work as all the other assignment operators do.  Make bug?
@@ -155,7 +153,7 @@ HEAD                := arch/arm/kernel/head-$(PROCESSOR).o \
 SUBDIRS                += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe \
                   arch/arm/fastfpe
 CORE_FILES     := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
-LIBS           := arch/arm/lib/lib.a $(LIBS) $(LIBGCC)
+LIBS           := arch/arm/lib/lib.a $(LIBS)
 
 ifeq ($(CONFIG_FPE_NWFPE),y)
 LIBS           := arch/arm/nwfpe/math-emu.o $(LIBS)
index 4dc9ec85ae5487f0d587b6e885c8c2d4be9167fb..dc257329b13ea7ebd8eaa4811c46d8457da3d583 100644 (file)
@@ -69,12 +69,21 @@ ZRELADDR     = 0xf0008000
 ZBSSADDR        = 0xf03e0000
 endif
 
-ifeq ($(CONFIG_ARCH_P720T),y)
-ZTEXTADDR       = 0xc0018000
+# The standard locations for stuff on CLPS711x type processors
+ifeq ($(CONFIG_ARCH_CLPS711X),y)
+ZTEXTADDR       = 0xc0028000
 PARAMS_PHYS     = 0xc0000100
+endif
+
+# Should probably have some agreement on these...
+ifeq ($(CONFIG_ARCH_P720T),y)
 INITRD_PHYS     = 0xc0400000
 INITRD_VIRT     = 0xc0400000
 endif
+ifeq ($(CONFIG_ARCH_CDB89712),y)
+INITRD_PHYS     = 0x00700000
+INITRD_VIRT     = 0xc0300000
+endif
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
 ZTEXTADDR       = 0xc0008000
@@ -90,6 +99,12 @@ endif
 ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
   ZTEXTADDR     = 0xC0200000
 endif
+ifeq ($(CONFIG_SA1100_GRAPHICSMASTER),y)
+  ZTEXTADDR     = 0xC0400000
+endif
+ifeq ($(CONFIG_SA1100_ADSBITSY),y)
+  ZTEXTADDR     = 0xC0400000
+endif
 ifeq ($(CONFIG_SA1100_YOPY),y)
   ZTEXTADDR      = 0x00080000
   ZBSSADDR       = 0xc0200000
index adeeeddc5b03e22e87a190c526a850145673588f..dcb579d062cc59bd3a928b0736c7e713d97eeae2 100644 (file)
@@ -3,7 +3,6 @@
 #
 
 ZSYSTEM                =$(TOPDIR)/arch/arm/boot/zImage
-INITRD         =$(ZSYSTEM)
 ZLDFLAGS       =-p -X -T bootp.lds \
                 --defsym initrd_addr=$(INITRD_PHYS) \
                 --defsym initrd_virt=$(INITRD_VIRT) \
index 9963fbc2b2be3d28158459aa8cb2de912e3be4a2..fc209bfa3502df4aee611ecf043bad18a3193af1 100644 (file)
@@ -39,7 +39,7 @@ splitify:     adr     r13, data
  * method by looking at the first word; this should either indicate a page
  * size of 4K, 16K or 32K.
  */
-               ldmia   r13, {r5-r8}            @ get size and addr of initrd
+               ldmia   r13, {r4-r8}            @ get size and addr of initrd
                                                @ r5 = ATAG_INITRD
                                                @ r6 = initrd start
                                                @ r7 = initrd end
@@ -48,10 +48,25 @@ splitify:   adr     r13, data
                teq     r9, #0x1000             @ 4K?
                teqne   r9, #0x4000             @ 16K?
                teqne   r9, #0x8000             @ 32K?
-               beq     no_taglist
+               beq     param_struct
+
+               ldr     r9, [r8, #4]            @ get first tag
+               teq     r9, r4
+               bne     taglist                 @ ok, we have a tag list
+
+/*
+ * We didn't find a valid tag list - create one.
+ */
+               str     r4, [r8, #4]
+               mov     r4, #8
+               str     r4, [r8, #0]
+               mov     r4, #0
+               str     r4, [r8, #8]
 
 /*
  * find the end of the tag list, and then add an INITRD tag on the end.
+ * If there is already an INITRD tag, then we ignore it; the last INITRD
+ * tag takes precidence.
  */
 taglist:       ldr     r9, [r8, #0]            @ tag length
                teq     r9, #0                  @ last tag?
@@ -63,7 +78,10 @@ taglist:     ldr     r9, [r8, #0]            @ tag length
                stmia   r8, {r4, r5, r6, r7, r9}
                mov     pc, r12                 @ call kernel
 
-no_taglist:    add     r8, r8, #16*4
+/*
+ * We found a param struct.  Modify the param struct for the initrd
+ */
+param_struct:  add     r8, r8, #16*4
                stmia   r8, {r6,r7}             @ save in param_struct
                mov     pc, r12                 @ call kernel
 
@@ -83,6 +101,7 @@ data:                .word   initrd_start
                .word   kernel_addr
                .word   kernel_len
 
+               .word   0x54410001              @ r4 = ATAG_CORE
                .word   0x54410005              @ r5 = ATAG_INITRD
                .word   initrd_virt             @ r6
                .word   initrd_len              @ r7
index d61994c5a8ed3919837dcbba16410523918de672..3d7abdb9e3b565b73a182f0fa111c76779f0b609 100644 (file)
@@ -51,7 +51,7 @@ OBJS          += head-sa1100.o
 endif
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
-OBJS           += head-sa1100.o setup-sa1100.o
+OBJS           += head-sa1100.o
 ifeq ($(CONFIG_SA1100_NANOENGINE),y)
   OBJS += hw-bse.o
 endif
@@ -65,6 +65,8 @@ else
 SEDFLAGS       += s/BSS_START/ALIGN(4)/
 endif
 
+LIBGCC         := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
+
 all:           vmlinux
 
 vmlinux:       $(HEAD) $(OBJS) piggy.o vmlinux.lds
index f49ceb5e64b7daff3aaf918edbe1c8f1e6c9a952..b0dd98d1fedb0fb24f0072ffcfaa41b452567873 100644 (file)
@@ -17,6 +17,24 @@ __SA1100_start:
 
                @ Preserve r8/r7 i.e. kernel entry values
 
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) && !defined(CONFIG_ANGELBOOT)
+               mov     r7, #MACH_TYPE_GRAPHICSCLIENT
+               mov     r8, #0
+#endif
+#if defined(CONFIG_SA1100_GRAPHICSMASTER) && !defined(CONFIG_ANGELBOOT)
+               mov     r7, #MACH_TYPE_GRAPHICSMASTER
+               mov     r8, #0
+#endif
+#if defined(CONFIG_SA1100_ADSBITSY) && !defined(CONFIG_ANGELBOOT)
+               mov     r7, #MACH_TYPE_ADSBITSY
+               mov     r8, #0
+#endif
+
+#ifdef CONFIG_SA1100_PFS168
+               @ REVISIT_PFS168: Temporary until firmware updated to use assigned machine number
+               mov     r7, #MACH_TYPE_PFS168
+#endif
+
 #ifdef CONFIG_SA1100_VICTOR
                teq     r7, #MACH_TYPE_VICTOR
                bne     10f
@@ -51,7 +69,6 @@ __SA1100_start:
                bic     r0, r0, #0x1000         @ clear Icache
                mcr     p15, 0, r0, c1, c0, 0
 
-#ifdef CONFIG_ANGELBOOT
 /*
  * Pause for a short time so that we give enough time
  * for the host to start a terminal up.
@@ -59,5 +76,4 @@ __SA1100_start:
                mov     r0, #0x00200000
 1:             subs    r0, r0, #1
                bne     1b
-#endif
 
diff --git a/arch/arm/boot/compressed/setup-sa1100.S b/arch/arm/boot/compressed/setup-sa1100.S
deleted file mode 100644 (file)
index 87a25b6..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/setup-sa1100.S
- *
- * Copyright (C) 2000 Nicolas Pitre <nico@cam.org>
- *
- * SA1100 setup routines, to be used after BSS has been cleared.
- *
- * John G Dorsey <john+@cs.cmu.edu>  2000/05/25 :
- *  Runtime test for Neponset added.
- */
-
-#include <linux/linkage.h>
-#include <linux/config.h>
-#include <asm/mach-types.h>
-
-               .text
-
-GPIO_BASE:     .long   0x90040000
-#define GPLR           0x00
-#define GPDR           0x04
-#define GPSR           0x08
-#define GAFR           0x1c
-
-PPC_BASE:      .long   0x90060000
-#define PPAR           0x08
-
-IC_BASE:       .long   0x90050000
-#define ICMR           0x04
-
-UART1_BASE:    .long   0x80010000
-UART3_BASE:    .long   0x80050000
-#define UTCR0           0x00
-#define UTCR1           0x04
-#define UTCR2           0x08
-#define UTCR3           0x0c
-#define UTSR0           0x1c
-#define UTSR1           0x20
-
-#ifndef CONFIG_SA1100_DEFAULT_BAUDRATE
-#define CONFIG_SA1100_DEFAULT_BAUDRATE 9600
-#endif
-
-#define BAUD_DIV       ((230400/CONFIG_SA1100_DEFAULT_BAUDRATE)-1)
-
-SCR_loc:       .long   SYMBOL_NAME(SCR_value)
-#define GPIO_2_9       0x3fc
-
-
-/*
- * void sa1100_setup( int arch_id );
- *
- * This is called from decompress_kernel() with the arch_decomp_setup() macro.
- */
-
-ENTRY(sa1100_setup)
-               mov     r3, r0                  @ keep machine type in r3
-
-               @ Clear all interrupt sources
-               ldr     r0, IC_BASE
-               mov     r1, #0
-               str     r1, [r0, #ICMR]
-
-@ Read System Configuration "Register" for Assabet.
-@ (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
-@ User's Guide," p.4-9)
-
-               teq     r3, #MACH_TYPE_ASSABET
-               bne     skip_SCR
-
-               ldr     r0, GPIO_BASE
-               ldr     r1, [r0, #GPDR]
-               and     r1, r1, #GPIO_2_9
-               str     r1, [r0, #GPDR]
-               mov     r1, #GPIO_2_9
-               str     r1, [r0, #GPSR]
-               ldr     r1, [r0, #GPDR]
-               bic     r1, r1, #GPIO_2_9
-               str     r1, [r0, #GPDR]
-
-               mov     r2, #100
-1:             ldr     r1, [r0, #GPLR]
-               subs    r2, r2, #1
-               bne     1b
-
-               and     r2, r1, #GPIO_2_9
-               ldr     r1, SCR_loc
-               str     r2, [r1]
-
-               ldr     r1, [r0, #GPDR]
-               and     r1, r1, #GPIO_2_9
-               str     r1, [r0, #GPDR]
-
-skip_SCR:
-
-               @ Initialize UART (if bootloader has not done it yet)...
-               teq     r3, #MACH_TYPE_BRUTUS
-               teqne   r3, #MACH_TYPE_ASSABET
-               teqne   r3, #MACH_TYPE_ITSY
-               teqne   r3, #MACH_TYPE_OMNIMETER
-               teqne   r3, #MACH_TYPE_JORNADA720
-               teqne   r3, #MACH_TYPE_GRAPHICSCLIENT
-               teqne   r3, #MACH_TYPE_FLEXANET
-               bne     skip_uart
-
-               @ UART3 if Assabet is used with Neponset
-               teq     r3, #MACH_TYPE_ASSABET  @ if Assabet 
-               tsteq   r2, #(1 << 9)           @ ... and Neponset present
-               ldreq   r0, UART3_BASE
-               beq     uart_init
-
-               @ UART3 on GraphicsClient
-               teq     r3, #MACH_TYPE_GRAPHICSCLIENT
-               ldreq   r0, UART3_BASE
-               beq     uart_init
-
-               @ At least for Brutus, the UART1 is used through
-               @ the alternate GPIO function...
-               teq     r3, #MACH_TYPE_BRUTUS
-               bne     uart1
-
-alt_GPIO_uart: ldr     r0, GPIO_BASE
-               ldr     r1, [r0, #GPDR]
-               bic     r1, r1, #1<<15
-               orr     r1, r1, #1<<14
-               str     r1, [r0, #GPDR]
-               ldr     r1, [r0, #GAFR]
-               orr     r1, r1, #(1<<15)|(1<<14)
-               str     r1, [r0, #GAFR]
-               ldr     r0, PPC_BASE
-               ldr     r1, [r0, #PPAR]
-               orr     r1, r1, #1<<12
-               str     r1, [r0, #PPAR]
-
-uart1:         ldr     r0, UART1_BASE
-
-uart_init:
-1:             ldr     r1, [r0, #UTSR1]
-               tst     r1, #1<<0               @ TBY
-               bne     1b
-               mov     r1, #0
-               str     r1, [r0, #UTCR3]
-               mov     r1, #0x08               @ 8N1
-               str     r1, [r0, #UTCR0]
-               mov     r1, #BAUD_DIV
-               str     r1, [r0, #UTCR2]
-               mov     r1, r1, lsr #8
-               str     r1, [r0, #UTCR1]
-               mov     r1, #0x03               @ RXE + TXE
-               str     r1, [r0, #UTCR3]
-               mov     r1, #0xff               @ flush status reg
-               str     r1, [r0, #UTSR0]
-skip_uart:
-
-               @ Extra specific setup calls
-               @ The machine type is passed in r0
-               mov     r0, r3
-#ifdef CONFIG_SA1100_NANOENGINE
-               teq     r0, #MACH_TYPE_NANOENGINE
-               beq     SYMBOL_NAME(bse_setup)
-#endif
-
-out:           mov     pc, lr
-
index 9197447e1f97202a65a2692f477ad13c4d7ca326..3cef171769d1ac354fc892628c8d766a99ba8f2d 100644 (file)
@@ -11,6 +11,7 @@ define_bool CONFIG_MCA n
 define_bool CONFIG_UID16 y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
 
 
 mainmenu_option next_comment
@@ -68,12 +69,13 @@ mainmenu_option next_comment
 comment 'SA11x0 Implementations'
 dep_bool '  Assabet' CONFIG_SA1100_ASSABET $CONFIG_ARCH_SA1100
 dep_bool '    Include support for Neponset' CONFIG_ASSABET_NEPONSET $CONFIG_SA1100_ASSABET
+dep_bool '  ADS Bitsy' CONFIG_SA1100_ADSBITSY $CONFIG_ARCH_SA1100
 dep_bool '  Brutus' CONFIG_SA1100_BRUTUS $CONFIG_ARCH_SA1100
 dep_bool '  CerfBoard' CONFIG_SA1100_CERF $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_CERF" = "y" ]; then
    bool '    32MB Cerf support' CONFIG_SA1100_CERF_32MB
 fi
-dep_bool '  Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY $CONFIG_ARCH_SA1100
+dep_bool '  Compaq iPAQ H3600' CONFIG_SA1100_H3600 $CONFIG_ARCH_SA1100
 #dep_bool '  Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
 dep_bool '  Extenex HandHeld Theater (Squashtail)' CONFIG_SA1100_EXTENEX1 $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_EXTENEX1" = "y" ]; then
@@ -82,6 +84,7 @@ fi
 dep_bool '  FlexaNet' CONFIG_SA1100_FLEXANET $CONFIG_ARCH_SA1100
 dep_bool '  FreeBird-v1.1' CONFIG_SA1100_FREEBIRD $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsClient Plus' CONFIG_SA1100_GRAPHICSCLIENT $CONFIG_ARCH_SA1100
+dep_bool '  GraphicsMaster' CONFIG_SA1100_GRAPHICSMASTER $CONFIG_ARCH_SA1100
 dep_bool '  HP Jornada 720' CONFIG_SA1100_JORNADA720 $CONFIG_ARCH_SA1100
 dep_bool '  HuW WebPanel' CONFIG_SA1100_HUW_WEBPANEL $CONFIG_ARCH_SA1100
 dep_bool '  Itsy' CONFIG_SA1100_ITSY $CONFIG_ARCH_SA1100
@@ -101,14 +104,38 @@ dep_bool '  Yopy' CONFIG_SA1100_YOPY $CONFIG_ARCH_SA1100
 if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
      "$CONFIG_SA1100_JORNADA720" = "y" -o \
      "$CONFIG_SA1100_PFS168" = "y" -o \
-     "$CONFIG_SA1100_XP860" = "y" ]; then
+     "$CONFIG_SA1100_XP860" = "y" -o \
+     "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
+     "$CONFIG_SA1100_ADSBITSY" = "y" ]; then
    define_bool CONFIG_SA1111 y
+   define_int CONFIG_FORCE_MAX_ZONEORDER 9
 fi
 endmenu
 
 mainmenu_option next_comment
 comment 'CLPS711X/EP721X Implementations'
+dep_bool '  CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
+dep_bool '  CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X
+dep_bool '  EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X
 dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
+
+# XXX Maybe these should indicate register compatibility
+# instead of being mutually exclusive.
+if [ "$CONFIG_ARCH_EDB7211" = "y" ]; then
+   define_bool CONFIG_ARCH_EP7211 y
+else
+   define_bool CONFIG_ARCH_EP7211 n
+fi
+if [ "$CONFIG_ARCH_P720T" = "y" ]; then
+   define_bool CONFIG_ARCH_EP7212 y
+else
+   define_bool CONFIG_ARCH_EP7212 n
+fi
+
+if [ "$CONFIG_ARCH_EP7211" = "y" -o \
+     "$CONFIG_ARCH_EP7212" = "y" ]; then
+   bool '  EP72xx ROM boot' CONFIG_EP72XX_ROM_BOOT
+fi
 endmenu
 
 # Definitions to make life easier
@@ -196,7 +223,9 @@ else
 fi
 
 # ARM720T
-if [ "$CONFIG_ARCH_CLPS711X" = "y" -o "$CONFIG_ARCH_L7200" = "y" ]; then
+if [ "$CONFIG_ARCH_CLPS711X" = "y" -o \
+     "$CONFIG_ARCH_L7200"    = "y" -o \
+     "$CONFIG_ARCH_CDB89712" = "y" ]; then
    define_bool CONFIG_CPU_ARM720T y
 else
    if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
@@ -255,12 +284,13 @@ else
    define_bool CONFIG_CPU_SA1100 n
 fi
 
-#if [ "$CONFIG_CPU_32" = "y" ]; then
-#   bool 'Support Thumb instructions' CONFIG_ARM_THUMB
-#fi
+if [ "$CONFIG_CPU_32" = "y" ]; then
+   dep_bool 'Support Thumb instructions (experimental)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
+fi
 
 # Select various configuration options depending on the machine type
-if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+if [ "$CONFIG_ARCH_EDB7211" = "y" -o \
+     "$CONFIG_ARCH_SA1100" = "y" ]; then
    define_bool CONFIG_DISCONTIGMEM y
 else
    define_bool CONFIG_DISCONTIGMEM n
@@ -289,6 +319,8 @@ if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
      "$CONFIG_ARCH_EBSA110" = "y" -o \
+     "$CONFIG_ARCH_CDB89712" = "y" -o \
+     "$CONFIG_ARCH_EDB7211" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" ]; then
    define_bool CONFIG_ISA y
 else
@@ -318,6 +350,7 @@ bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+comment 'At least one math emulation must be selected'
 tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE
 dep_tristate 'FastFPE math emulation (experimental)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL
 choice 'Kernel core (/proc/kcore) format' \
@@ -335,6 +368,7 @@ if [ "$CONFIG_ARCH_EBSA110" = "y" -o         \
      "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
      "$CONFIG_ARCH_CATS" = "y" -o            \
      "$CONFIG_ARCH_P720T" = "y" -o          \
+     "$CONFIG_ARCH_CDB89712" = "y" -o       \
      "$CONFIG_ARCH_ANAKIN" = "y" ]; then
    string 'Default kernel command string' CONFIG_CMDLINE ""
 fi
@@ -346,6 +380,7 @@ if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
      "$CONFIG_ARCH_CO285" = "y" -o      \
      "$CONFIG_ARCH_SA1100" = "y" -o     \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+     "$CONFIG_ARCH_CDB89712" = "y" -o   \
      "$CONFIG_ARCH_P720T" = "y" ]; then
    bool 'Timer and CPU usage LEDs' CONFIG_LEDS
    if [ "$CONFIG_LEDS" = "y" ]; then
@@ -429,7 +464,7 @@ fi
 
 source drivers/ieee1394/Config.in
 
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
@@ -510,6 +545,8 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -o \
    endmenu
 fi
 
+source drivers/misc/Config.in
+
 source drivers/usb/Config.in
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
index e9416ed4e812de1d7e370a54802fa6ca1f0aaba2..ef3485e95553ef72f5904ab726e4b4b30d0ea68e 100644 (file)
@@ -41,7 +41,7 @@ obj-          :=
 export-objs    := armksyms.o dma.o ecard.o fiq.o io.o oldlatches.o time.o
 
 no-irq-arch    := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
-                  $(CONFIG_ARCH_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
+                  $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
                   $(CONFIG_ARCH_SA1100)
 
 ifneq ($(findstring y,$(no-irq-arch)),y)
index 891c8752b9f728dbf52e11111171c0d82a6f6ea9..fc9cc15a9d089b9ae9c4b34fe6babed11c507db1 100644 (file)
@@ -54,22 +54,16 @@ extern int sys_exit(int);
  * compiler...  (prototypes are not correct though, but that
  * doesn't really matter since they're not versioned).
  */
-extern void __gcc_bcmp(void);
 extern void __ashldi3(void);
 extern void __ashrdi3(void);
-extern void __cmpdi2(void);
-extern void __divdi3(void);
 extern void __divsi3(void);
 extern void __lshrdi3(void);
-extern void __moddi3(void);
 extern void __modsi3(void);
 extern void __muldi3(void);
-extern void __negdi2(void);
 extern void __ucmpdi2(void);
 extern void __udivdi3(void);
 extern void __udivmoddi4(void);
 extern void __udivsi3(void);
-extern void __umoddi3(void);
 extern void __umodsi3(void);
 
 extern void ret_from_exception(void);
@@ -213,23 +207,27 @@ EXPORT_SYMBOL(uaccess_kernel);
 EXPORT_SYMBOL(uaccess_user);
 #endif
 
+EXPORT_SYMBOL_NOVERS(__get_user_1);
+EXPORT_SYMBOL_NOVERS(__get_user_2);
+EXPORT_SYMBOL_NOVERS(__get_user_4);
+EXPORT_SYMBOL_NOVERS(__get_user_8);
+
+EXPORT_SYMBOL_NOVERS(__put_user_1);
+EXPORT_SYMBOL_NOVERS(__put_user_2);
+EXPORT_SYMBOL_NOVERS(__put_user_4);
+EXPORT_SYMBOL_NOVERS(__put_user_8);
+
        /* gcc lib functions */
-EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
 EXPORT_SYMBOL_NOVERS(__ashldi3);
 EXPORT_SYMBOL_NOVERS(__ashrdi3);
-EXPORT_SYMBOL_NOVERS(__cmpdi2);
-EXPORT_SYMBOL_NOVERS(__divdi3);
 EXPORT_SYMBOL_NOVERS(__divsi3);
 EXPORT_SYMBOL_NOVERS(__lshrdi3);
-EXPORT_SYMBOL_NOVERS(__moddi3);
 EXPORT_SYMBOL_NOVERS(__modsi3);
 EXPORT_SYMBOL_NOVERS(__muldi3);
-EXPORT_SYMBOL_NOVERS(__negdi2);
 EXPORT_SYMBOL_NOVERS(__ucmpdi2);
 EXPORT_SYMBOL_NOVERS(__udivdi3);
 EXPORT_SYMBOL_NOVERS(__udivmoddi4);
 EXPORT_SYMBOL_NOVERS(__udivsi3);
-EXPORT_SYMBOL_NOVERS(__umoddi3);
 EXPORT_SYMBOL_NOVERS(__umodsi3);
 
        /* bitops */
index d8e95edcb822e5a5ab80f170f1de94fa83a3d670..5da4d39ba06ceb217e140383abd65e8d1050c2dc 100644 (file)
@@ -288,8 +288,11 @@ pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
 
        if (dev) {
                for (i = 0; i < 3; i++) {
-                       bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
-                       bus->resource[i]->name  = bus->name;
+                       if(root->resource[i]) {
+                               bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+                               bus->resource[i]->end  = root->resource[i]->end;
+                               bus->resource[i]->name = bus->name;
+                       }
                }
                bus->resource[0]->flags |= pci_bridge_check_io(dev);
                bus->resource[1]->flags |= IORESOURCE_MEM;
index a76a6b1599985f6dec1349ae45a8e475e1608a72..676febed1ad4e5b7cf3874753a65a0e50de62df2 100644 (file)
@@ -8,7 +8,7 @@
  * published by the Free Software Foundation.
  *
  * We keep the old params compatibility cruft in one place (here)
- * so we don't end up with lots of 
+ * so we don't end up with lots of mess around other places.
  */
 #include <linux/config.h>
 #include <linux/types.h>
index b3a1ea06d5b61f1af7ca54e2f5155542c7cb3c81..4a055a12501cfa8a5be89230d6404dc8880ee702 100644 (file)
@@ -148,17 +148,22 @@ static struct resource dma_resources[] = {
 
 void __init isa_init_dma(dma_t *dma)
 {
-       int dmac_found;
-
+       /*
+        * Try to autodetect presence of an ISA DMA controller.
+        * We do some minimal initialisation, and check that
+        * channel 0's DMA address registers are writeable.
+        */
        outb(0xff, 0x0d);
        outb(0xff, 0xda);
 
+       /*
+        * Write high and low address, and then read them back
+        * in the same order.
+        */
        outb(0x55, 0x00);
        outb(0xaa, 0x00);
 
-       dmac_found = inb(0x00) == 0x55 && inb(0x00) == 0xaa;
-
-       if (dmac_found) {
+       if (inb(0) == 0x55 && inb(0) == 0xaa) {
                int channel, i;
 
                for (channel = 0; channel < 8; channel++) {
index a5bfa404c341e46e1129411c9a267819cad3352c..65c12f4d08988dc975c7d4d615fb25f12521fafe 100644 (file)
@@ -404,6 +404,7 @@ ENTRY(soft_irq_mask)
                .endm
 
 #elif defined(CONFIG_ARCH_L7200)
+#include <asm/hardware.h>
        
                .equ    irq_base_addr,  IO_BASE_2
 
@@ -625,8 +626,8 @@ __dabt_svc: sub     sp, sp, #S_FRAME_SIZE
  * This routine must not corrupt r9
  */
 #ifdef MULTI_CPU
-               ldr     r2, .LCprocfns
-               mov     lr, pc
+               ldr     r2, .LCprocfns                  @ pass r0, r3 to
+               mov     lr, pc                          @ processor code
                ldr     pc, [r2]                        @ call processor specific code
 #else
                bl      cpu_data_abort
@@ -722,16 +723,16 @@ __pabt_svc:       sub     sp, sp, #S_FRAME_SIZE
                .align  5
 __dabt_usr:    sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
                stmia   sp, {r0 - r12}                  @ save r0 - r12
-               ldr     r4, .LCabt
-               add     r3, sp, #S_PC
-               ldmia   r4, {r0 - r2}                   @ Get USR pc, cpsr
-               stmia   r3, {r0 - r2}                   @ Save USR pc, cpsr, old_r0
-               stmdb   r3, {sp, lr}^
-               alignment_trap r4, r7, __temp_abt
+               ldr     r7, .LCabt
+               add     r5, sp, #S_PC
+               ldmia   r7, {r0, r3, r4}                @ Get USR pc, cpsr
+               stmia   r5, {r0, r3, r4}                @ Save USR pc, cpsr, old_r0
+               stmdb   r5, {sp, lr}^
+               alignment_trap r7, r7, __temp_abt
                zero_fp
 #ifdef MULTI_CPU
-               ldr     r2, .LCprocfns
-               mov     lr, pc
+               ldr     r2, .LCprocfns                  @ pass r0, r3 to
+               mov     lr, pc                          @ processor code
                ldr     pc, [r2]                        @ call processor specific code
 #else
                bl      cpu_data_abort
index 09f3f133ba64819985ceb5f94dbd9332fa5f2ecd..5f645f0c4ffc9a91cd9dfc7809c0e2ff27086d92 100644 (file)
@@ -123,9 +123,8 @@ ENTRY(ret_from_fork)
        .align  5
 ENTRY(vector_swi)
        save_user_regs
-       mask_pc lr, lr
        zero_fp
-       ldr     scno, [lr, #-4]                 @ get SWI instruction
+       get_scno
        arm710_bug_check scno, ip
 
 #ifdef CONFIG_ALIGNMENT_TRAP
index 5b9986bcc5a1f7ab14c05a292860304b4d8198e2..c9c457dbfcd4121306c35066c01de1e40863a280 100644 (file)
@@ -75,9 +75,9 @@
                stmia   sp, {r0 - r12}                  @ Calling r0 - r12
                add     r8, sp, #S_PC
                stmdb   r8, {sp, lr}^                   @ Calling sp, lr
-               mrs     r7, spsr
+               mrs     r8, spsr                        @ called from non-FIQ mode, so ok.
                str     lr, [sp, #S_PC]                 @ Save calling PC
-               str     r7, [sp, #S_PSR]                @ Save CPSR
+               str     r8, [sp, #S_PSR]                @ Save CPSR
                str     r0, [sp, #S_OLD_R0]             @ Save OLD_R0
                .endm
 
 
 #endif
 
+
 /*
  * These are the registers used in the syscall handler, and allow us to
- * have in theory up to 7 arguments to a function.  Note that tbl == why
- * is intentional.
+ * have in theory up to 7 arguments to a function - r0 to r6.
+ *
+ * r7 is reserved for the system call number for thumb mode.
+ *
+ * Note that tbl == why is intentional.
  *
  * We must set at least "tsk" and "why" when calling ret_with_reschedule.
  */
-scno   .req    r9                              @ syscall number
+scno   .req    r7                              @ syscall number
 tbl    .req    r8                              @ syscall table pointer
 why    .req    r8                              @ Linux syscall (!= 0)
-tsk    .req    r7                              @ current task
+tsk    .req    r9                              @ current task
+
+/*
+ * Get the system call number.
+ */
+       .macro  get_scno
+#ifdef CONFIG_ARM_THUMB
+       tst     r8, #T_BIT              @ this is SPSR from save_user_regs
+       addne   scno, r7, #OS_NUMBER << 20 @ put OS number in
+       ldreq   scno, [lr, #-4]
 
+#else
+       mask_pc lr, lr
+       ldr     scno, [lr, #-4]         @ get SWI instruction
+#endif
+       .endm
 
index 54190abbb6a6e879731271b84de6b0b5d2f385f3..36e7f142049b3a4dd34545407387713336572471 100644 (file)
@@ -418,5 +418,4 @@ __lookup_architecture_type:
                mov     r7, #0                          @ unknown architecture
                mov     pc, lr
 2:             ldmib   r4, {r5, r6, r7}                @ found, get results
-               mov     r7, r7, lsr #18                 @ pagetable byte offset
                mov     pc, lr
index 7245a45b0ab77dae863b8375ba0b935d3437396c..480c025fba9b6e2b247a53bbd43201432a1b3f87 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
+static struct vm_area_struct init_mmap = INIT_MMAP;
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
index 3de571421deb7c329b2d3389e397c97ec485e9de..9fee22468ccac26016300eac068ffd318ea73434 100644 (file)
@@ -260,10 +260,10 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
        struct resource *res;
        int i;
 
-       kernel_code.start  = __virt_to_bus(init_mm.start_code);
-       kernel_code.end    = __virt_to_bus(init_mm.end_code - 1);
-       kernel_data.start  = __virt_to_bus(init_mm.end_code);
-       kernel_data.end    = __virt_to_bus(init_mm.brk - 1);
+       kernel_code.start  = __virt_to_phys(init_mm.start_code);
+       kernel_code.end    = __virt_to_phys(init_mm.end_code - 1);
+       kernel_data.start  = __virt_to_phys(init_mm.end_code);
+       kernel_data.end    = __virt_to_phys(init_mm.brk - 1);
 
        for (i = 0; i < mi->nr_banks; i++) {
                unsigned long virt_start, virt_end;
@@ -520,9 +520,44 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
-int get_cpuinfo(char * buffer)
+static const char *hwcap_str[] = {
+       "swp",
+       "half",
+       "thumb",
+       "26bit",
+       "fastmult",
+       "fpa",
+       "vfp",
+       "edsp",
+       NULL
+};
+
+/*
+ * get_cpuinfo - Get information on one CPU for use by the procfs.
+ *
+ *     Prints info on the next CPU into buffer.  Beware, doesn't check for
+ *     buffer overflow.  Current implementation of procfs assumes that the
+ *     resulting data is <= 1K.
+ *
+ * Args:
+ *     buffer  -- you guessed it, the data buffer
+ *     cpu_np  -- Input: next cpu to get (start at 0).  Output: Updated.
+ *
+ *     Returns number of bytes written to buffer.
+ */
+
+int get_cpuinfo(char *buffer, unsigned *cpu_np)
 {
        char *p = buffer;
+       unsigned n;
+       int i;
+
+       /* No SMP at the moment, so just toggle 0/1 */
+       n = *cpu_np;
+       *cpu_np = 1;
+       if (n != 0) {
+               return (0);
+       }
 
        p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n",
                     proc_info.manufacturer, proc_info.cpu_name,
@@ -532,6 +567,15 @@ int get_cpuinfo(char * buffer)
                     loops_per_jiffy / (500000/HZ),
                     (loops_per_jiffy / (5000/HZ)) % 100);
 
+       /* dump out the processor features */
+       p += sprintf(p, "Features\t: ");
+
+       for (i = 0; hwcap_str[i]; i++)
+               if (elf_hwcap & (1 << i))
+                       p += sprintf(p, "%s ", hwcap_str[i]);
+
+       p += sprintf(p, "\n\n");
+
        p += sprintf(p, "Hardware\t: %s\n", machine_name);
 
        p += sprintf(p, "Revision\t: %04x\n",
index 77fe145f2ad00f84d8a266ca3ca4c5793b815293..0d5bc71aed7dee8bf7469c05defff733cb8dbc0b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/kernel/signal.c
  *
- *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 1995-2001 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,7 +19,9 @@
 #include <linux/ptrace.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
+#include <linux/personality.h>
 #include <linux/tty.h>
+#include <linux/elf.h>
 
 #include <asm/pgalloc.h>
 #include <asm/ucontext.h>
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn))
-#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn))
+/*
+ * For ARM syscalls, we encode the syscall number into the instruction.
+ */
+#define SWI_SYS_SIGRETURN      (0xef000000|(__NR_sigreturn))
+#define SWI_SYS_RT_SIGRETURN   (0xef000000|(__NR_rt_sigreturn))
+
+/*
+ * For Thumb syscalls, we pass the syscall number via r7.  We therefore
+ * need two 16-bit instructions.
+ */
+#define SWI_THUMB_SIGRETURN    (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
+#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
+
+static const unsigned long retcodes[4] = {
+       SWI_SYS_SIGRETURN,      SWI_THUMB_SIGRETURN,
+       SWI_SYS_RT_SIGRETURN,   SWI_THUMB_RT_SIGRETURN
+};
 
 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
 
@@ -208,11 +225,11 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
        sigset_t set;
 
        /*
-        * Since we stacked the signal on a word boundary,
+        * Since we stacked the signal on a 64-bit boundary,
         * then 'sp' should be word aligned here.  If it's
         * not, then the user is trying to mess with us.
         */
-       if (regs->ARM_sp & 3)
+       if (regs->ARM_sp & 7)
                goto badframe;
 
        frame = (struct sigframe *)regs->ARM_sp;
@@ -251,11 +268,11 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
        sigset_t set;
 
        /*
-        * Since we stacked the signal on a word boundary,
+        * Since we stacked the signal on a 64-bit boundary,
         * then 'sp' should be word aligned here.  If it's
         * not, then the user is trying to mess with us.
         */
-       if (regs->ARM_sp & 3)
+       if (regs->ARM_sp & 7)
                goto badframe;
 
        frame = (struct rt_sigframe *)regs->ARM_sp;
@@ -319,8 +336,8 @@ setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/
        return err;
 }
 
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-                                unsigned long framesize)
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
 {
        unsigned long sp = regs->ARM_sp;
 
@@ -331,77 +348,103 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
                sp = current->sas_ss_sp + current->sas_ss_size;
 
        /*
-        * No matter what happens, 'sp' must be word
-        * aligned otherwise nasty things could happen
+        * ATPCS B01 mandates 8-byte alignment
         */
-       /* ATPCS B01 mandates 8-byte alignment */
        return (void *)((sp - framesize) & ~7);
 }
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs *regs)
+static int
+setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+            unsigned long *rc, void *frame, int usig)
 {
-       struct sigframe *frame;
+       unsigned long handler = (unsigned long)ka->sa.sa_handler;
        unsigned long retcode;
-       int err = 0;
-
-       frame = get_sigframe(ka, regs, sizeof(*frame));
-
-       if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-               goto segv_and_exit;
-
-       err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
+       int thumb = 0;
+#ifdef CONFIG_CPU_32
+       unsigned long cpsr = regs->ARM_cpsr;
 
-       if (_NSIG_WORDS > 1) {
-               err |= __copy_to_user(frame->extramask, &set->sig[1],
-                                     sizeof(frame->extramask));
+       /*
+        * Maybe we need to deliver a 32-bit signal to a 26-bit task.
+        */
+       if (ka->sa.sa_flags & SA_THIRTYTWO)
+               cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
+
+#ifdef CONFIG_ARM_THUMB
+       if (elf_hwcap & HWCAP_THUMB) {
+               /*
+                * The LSB of the handler determines if we're going to
+                * be using THUMB or ARM mode for this signal handler.
+                */
+               thumb = handler & 1;
+
+               if (thumb)
+                       cpsr |= T_BIT;
+               else
+                       cpsr &= ~T_BIT;
        }
+#endif
+#endif
 
-       /* Set up to return from userspace.  If provided, use a stub
-          already in userspace.  */
        if (ka->sa.sa_flags & SA_RESTORER) {
                retcode = (unsigned long)ka->sa.sa_restorer;
        } else {
-               retcode = (unsigned long)&frame->retcode;
-               __put_user_error(SWI_SYS_SIGRETURN, &frame->retcode, err);
-               flush_icache_range(retcode, retcode + 4);
-       }
+               unsigned int idx = thumb;
 
-       if (err)
-               goto segv_and_exit;
+               if (ka->sa.sa_flags & SA_SIGINFO)
+                       idx += 2;
 
-       if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
-               regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
-       else
-               regs->ARM_r0 = sig;
+               if (__put_user(retcodes[idx], rc))
+                       return 1;
+
+               flush_icache_range((unsigned long)rc,
+                                  (unsigned long)(rc + 1));
+
+               retcode = ((unsigned long)rc) + thumb;
+       }
+
+       regs->ARM_r0 = usig;
        regs->ARM_sp = (unsigned long)frame;
        regs->ARM_lr = retcode;
-       regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
-#if defined(CONFIG_CPU_32)
-       /* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
-       if (ka->sa.sa_flags & SA_THIRTYTWO)
-               regs->ARM_cpsr = USR_MODE;
+       regs->ARM_pc = handler & (thumb ? ~1 : ~3);
+
+#ifdef CONFIG_CPU_32
+       regs->ARM_cpsr = cpsr;
 #endif
-       if (valid_user_regs(regs))
-               return;
 
-segv_and_exit:
-       if (sig == SIGSEGV)
-               ka->sa.sa_handler = SIG_DFL;
-       force_sig(SIGSEGV, current);
+       return 0;
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs *regs)
+static int
+setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs)
 {
-       struct rt_sigframe *frame;
-       unsigned long retcode;
+       struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+       if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+               return 1;
+
+       err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
+
+       if (_NSIG_WORDS > 1) {
+               err |= __copy_to_user(frame->extramask, &set->sig[1],
+                                     sizeof(frame->extramask));
+       }
+
+       if (err == 0)
+               err = setup_return(regs, ka, &frame->retcode, frame, usig);
+
+       return err;
+}
+
+static int
+setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
+              sigset_t *set, struct pt_regs *regs)
+{
+       struct rt_sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
+       int err = 0;
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-               goto segv_and_exit;
+               return 1;
 
        __put_user_error(&frame->info, &frame->pinfo, err);
        __put_user_error(&frame->uc, &frame->puc, err);
@@ -414,47 +457,20 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                                regs, set->sig[0]);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
-       /* Set up to return from userspace.  If provided, use a stub
-          already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               retcode = (unsigned long)ka->sa.sa_restorer;
-       } else {
-               retcode = (unsigned long)&frame->retcode;
-               __put_user_error(SWI_SYS_RT_SIGRETURN, &frame->retcode, err);
-               flush_icache_range(retcode, retcode + 4);
+       if (err == 0)
+               err = setup_return(regs, ka, &frame->retcode, frame, usig);
+
+       if (err == 0) {
+               /*
+                * For realtime signals we must also set the second and third
+                * arguments for the signal handler.
+                *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
+                */
+               regs->ARM_r1 = (unsigned long)frame->pinfo;
+               regs->ARM_r2 = (unsigned long)frame->puc;
        }
 
-       if (err)
-               goto segv_and_exit;
-
-       if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
-               regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
-       else
-               regs->ARM_r0 = sig;
-
-       /*
-        * For realtime signals we must also set the second and third
-        * arguments for the signal handler.
-        *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
-        */
-       regs->ARM_r1 = (unsigned long)frame->pinfo;
-       regs->ARM_r2 = (unsigned long)frame->puc;
-
-       regs->ARM_sp = (unsigned long)frame;
-       regs->ARM_lr = retcode;
-       regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
-#if defined(CONFIG_CPU_32)
-       /* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
-       if (ka->sa.sa_flags & SA_THIRTYTWO)
-               regs->ARM_cpsr = USR_MODE;
-#endif
-       if (valid_user_regs(regs))
-               return;
-
-segv_and_exit:
-       if (sig == SIGSEGV)
-               ka->sa.sa_handler = SIG_DFL;
-       force_sig(SIGSEGV, current);
+       return err;
 }
 
 /*
@@ -464,22 +480,47 @@ static void
 handle_signal(unsigned long sig, struct k_sigaction *ka,
              siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
-       /* Set up the stack frame */
+       struct task_struct *tsk = current;
+       int usig = sig;
+       int ret;
+
+       /*
+        * translate the signal
+        */
+       if (usig < 32 && tsk->exec_domain && tsk->exec_domain->signal_invmap)
+               usig = tsk->exec_domain->signal_invmap[usig];
+
+       /*
+        * Set up the stack frame
+        */
        if (ka->sa.sa_flags & SA_SIGINFO)
-               setup_rt_frame(sig, ka, info, oldset, regs);
+               ret = setup_rt_frame(usig, ka, info, oldset, regs);
        else
-               setup_frame(sig, ka, oldset, regs);
-
-       if (ka->sa.sa_flags & SA_ONESHOT)
-               ka->sa.sa_handler = SIG_DFL;
+               ret = setup_frame(usig, ka, oldset, regs);
 
-       if (!(ka->sa.sa_flags & SA_NODEFER)) {
-               spin_lock_irq(&current->sigmask_lock);
-               sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-               sigaddset(&current->blocked,sig);
-               recalc_sigpending(current);
-               spin_unlock_irq(&current->sigmask_lock);
+       /*
+        * Check that the resulting registers are actually sane.
+        */
+       ret |= !valid_user_regs(regs);
+
+       if (ret == 0) {
+               if (ka->sa.sa_flags & SA_ONESHOT)
+                       ka->sa.sa_handler = SIG_DFL;
+
+               if (!(ka->sa.sa_flags & SA_NODEFER)) {
+                       spin_lock_irq(&tsk->sigmask_lock);
+                       sigorsets(&tsk->blocked, &tsk->blocked,
+                                 &ka->sa.sa_mask);
+                       sigaddset(&tsk->blocked, sig);
+                       recalc_sigpending(tsk);
+                       spin_unlock_irq(&tsk->sigmask_lock);
+               }
+               return;
        }
+
+       if (sig == SIGSEGV)
+               ka->sa.sa_handler = SIG_DFL;
+       force_sig(SIGSEGV, tsk);
 }
 
 /*
index be24bdcfcde548254dc3b5e565aec98d6cd17aac..2d4cbd91644abe9c9699d1b050bd49a44d5a2f29 100644 (file)
@@ -33,7 +33,6 @@
 #include <asm/hardware.h>
 
 extern int setup_arm_irq(int, struct irqaction *);
-extern void setup_timer(void);
 extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 
index a45b4542842bbf213c4435a40ee46bf69f967504..1b36af10f32b2ac6a59e51e6d78f62e35b19e073 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/personality.h>
 #include <linux/ptrace.h>
 #include <linux/elf.h>
+#include <linux/interrupt.h>
 #include <linux/init.h>
 
 #include <asm/atomic.h>
@@ -176,7 +177,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
        printk("Process %s (pid: %d, stackpage=%08lx)\n",
                current->comm, current->pid, 4096+(unsigned long)tsk);
 
-       if (!user_mode(regs)) {
+       if (!user_mode(regs) || in_interrupt()) {
                mm_segment_t fs;
 
                /*
@@ -209,7 +210,7 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err)
 
 asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
 {
-       unsigned long addr;
+       unsigned long *pc;
        siginfo_t info;
 
        /*
@@ -217,11 +218,11 @@ asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
         * whether we're in Thumb mode or not.
         */
        regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
-       addr = instruction_pointer(regs);
+       pc = (unsigned long *)instruction_pointer(regs);
 
 #ifdef CONFIG_DEBUG_USER
-       printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
-               current->comm, current->pid, addr);
+       printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
+               current->comm, current->pid, pc);
        dump_instr(regs);
 #endif
 
@@ -231,7 +232,7 @@ asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
        info.si_signo = SIGILL;
        info.si_errno = 0;
        info.si_code  = ILL_ILLOPC;
-       info.si_addr  = (void *)addr;
+       info.si_addr  = pc;
 
        force_sig_info(SIGILL, &info, current);
 
index e47f170f3bedbbe64361661ebb64079c630cdccf..d591be3de9f591c237e36de6f635ee107e4c262a 100644 (file)
@@ -13,15 +13,20 @@ obj-y               := backtrace.o changebit.o csumipv6.o csumpartial.o   \
                   copy_page.o delay.o findbit.o memchr.o memcpy.o    \
                   memset.o memzero.o setbit.o strncpy_from_user.o    \
                   strnlen_user.o strchr.o strrchr.o testchangebit.o  \
-                  testclearbit.o testsetbit.o uaccess.o
+                  testclearbit.o testsetbit.o uaccess.o getuser.o    \
+                  putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o   \
+                  ucmpdi2.o udivdi3.o lib1funcs.o
 obj-m          :=
 obj-n          :=
 
+obj-$(CONFIG_VT)+= kbd.o
+
 obj-arc                := ecard.o io-acorn.o floppydma.o
 obj-rpc                := ecard.o io-acorn.o floppydma.o
 obj-clps7500   := io-acorn.o
 obj-l7200      := io-acorn.o
 obj-shark      := io-shark.o
+obj-edb7211    := io-acorn.o
 
 obj-y          += $(obj-$(MACHINE))
 
diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
new file mode 100644 (file)
index 0000000..130f5a8
--- /dev/null
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton    29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.low = 0;
+      w.s.high = (USItype)uu.s.low << -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.low >> bm;
+      w.s.low = (USItype)uu.s.low << b;
+      w.s.high = ((USItype)uu.s.high << b) | carries;
+    }
+
+  return w.ll;
+}
+
diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
new file mode 100644 (file)
index 0000000..71625d2
--- /dev/null
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
new file mode 100644 (file)
index 0000000..ad70b93
--- /dev/null
@@ -0,0 +1,25 @@
+/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#define BITS_PER_UNIT  8
+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+
+typedef unsigned int UQItype    __attribute__ ((mode (QI)));
+typedef          int SItype     __attribute__ ((mode (SI)));
+typedef unsigned int USItype    __attribute__ ((mode (SI)));
+typedef          int DItype     __attribute__ ((mode (DI)));
+typedef          int word_type         __attribute__ ((mode (__word__)));
+typedef unsigned int UDItype    __attribute__ ((mode (DI)));
+
+#if 0 /* FIXME: endian test here!!! */
+  struct DIstruct {SItype high, low;};
+#else
+  struct DIstruct {SItype low, high;};
+#endif
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
new file mode 100644 (file)
index 0000000..578cebb
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *  linux/arch/arm/lib/getuser.S
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make them more
+ * efficient, especially as they return an error value in addition to
+ * the "real" return value.
+ *
+ * __get_user_X
+ *
+ * Inputs:     r0 contains the address
+ * Outputs:    r0 is the error code
+ *             r1, r2 contains the zero-extended value
+ *             lr corrupted
+ *
+ * No other registers must be altered.  (see include/asm-arm/uaccess.h
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000.
+ * Note also that it is intended that __get_user_bad is not global.
+ */
+#include <asm/constants.h>
+
+       .global __get_user_1
+__get_user_1:
+       bic     r1, sp, #0x1f00
+       bic     r1, r1, #0x00ff
+       ldr     r1, [r1, #TSK_ADDR_LIMIT]
+       sub     r1, r1, #1
+       cmp     r0, r1
+1:     ldrlsbt r1, [r0]
+       movls   r0, #0
+       movls   pc, lr
+       b       __get_user_bad
+
+       .global __get_user_2
+__get_user_2:
+       bic     r2, sp, #0x1f00
+       bic     r2, r2, #0x00ff
+       ldr     r2, [r2, #TSK_ADDR_LIMIT]
+       sub     r2, r2, #2
+       cmp     r0, r2
+2:     ldrlsbt r1, [r0], #1
+3:     ldrlsbt r2, [r0]
+       orrls   r1, r1, r2, lsl #8
+       movls   r0, #0
+       movls   pc, lr
+       b       __get_user_bad
+
+       .global __get_user_4
+__get_user_4:
+       bic     r1, sp, #0x1f00
+       bic     r1, r1, #0x00ff
+       ldr     r1, [r1, #TSK_ADDR_LIMIT]
+       sub     r1, r1, #4
+       cmp     r0, r1
+4:     ldrlst  r1, [r0]
+       movls   r0, #0
+       movls   pc, lr
+       b       __get_user_bad
+
+       .global __get_user_8
+__get_user_8:
+       bic     r2, sp, #0x1f00
+       bic     r2, r2, #0x00ff
+       ldr     r2, [r2, #TSK_ADDR_LIMIT]
+       sub     r2, r2, #8
+       cmp     r0, r2
+5:     ldrlst  r1, [r0], #4
+6:     ldrlst  r2, [r0]
+       movls   r0, #0
+       movls   pc, lr
+
+       /* fall through */
+
+__get_user_bad:
+       mov     r2, #0
+       mov     r1, #0
+       mov     r0, #-14
+       mov     pc, lr
+
+.section __ex_table, "a"
+       .long   1b, __get_user_bad
+       .long   2b, __get_user_bad
+       .long   3b, __get_user_bad
+       .long   4b, __get_user_bad
+       .long   5b, __get_user_bad
+       .long   6b, __get_user_bad
+.previous
diff --git a/arch/arm/lib/kbd.c b/arch/arm/lib/kbd.c
new file mode 100644 (file)
index 0000000..25ee8a5
--- /dev/null
@@ -0,0 +1,13 @@
+#include <linux/config.h>
+#include <linux/kd.h>
+
+int  (*k_setkeycode)(unsigned int, unsigned int);
+int  (*k_getkeycode)(unsigned int);
+int  (*k_translate)(unsigned char, unsigned char *, char);
+char (*k_unexpected_up)(unsigned char);
+void (*k_leds)(unsigned char);
+
+#ifdef CONFIG_MAGIC_SYSRQ
+int k_sysrq_key;
+unsigned char *k_sysrq_xlate;
+#endif
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
new file mode 100644 (file)
index 0000000..f25c317
--- /dev/null
@@ -0,0 +1,320 @@
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+
+/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+
+This file 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file.  (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file 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; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+/* This code is derived from gcc 2.95.3 */
+/* I Molton     29/07/01 */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_CPU_26
+#define RET    movs
+#define RETc(x)        mov##x##s
+#define RETCOND ^
+#else
+#define RET    mov
+#define RETc(x)        mov##x
+#define RETCOND
+#endif
+
+dividend       .req    r0
+divisor                .req    r1
+result         .req    r2
+overdone        .req    r2
+curbit         .req    r3
+ip             .req    r12
+sp             .req    r13
+lr             .req    r14
+pc             .req    r15
+       
+ENTRY(__udivsi3)
+       cmp     divisor, #0
+       beq     Ldiv0
+       mov     curbit, #1
+       mov     result, #0
+       cmp     dividend, divisor
+       bcc     Lgot_result_udivsi3
+1:
+       @ Unless the divisor is very big, shift it up in multiples of
+       @ four bits, since this is the amount of unwinding in the main
+       @ division loop.  Continue shifting until the divisor is 
+       @ larger than the dividend.
+       cmp     divisor, #0x10000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #4
+       movcc   curbit, curbit, lsl #4
+       bcc     1b
+
+2:
+       @ For very big divisors, we must shift it a bit at a time, or
+       @ we will be in danger of overflowing.
+       cmp     divisor, #0x80000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #1
+       movcc   curbit, curbit, lsl #1
+       bcc     2b
+
+3:
+       @ Test for possible subtractions, and note which bits
+       @ are done in the result.  On the final pass, this may subtract
+       @ too much from the dividend, but the result will be ok, since the
+       @ "bit" will have been shifted out at the bottom.
+       cmp     dividend, divisor
+       subcs   dividend, dividend, divisor
+       orrcs   result, result, curbit
+       cmp     dividend, divisor, lsr #1
+       subcs   dividend, dividend, divisor, lsr #1
+       orrcs   result, result, curbit, lsr #1
+       cmp     dividend, divisor, lsr #2
+       subcs   dividend, dividend, divisor, lsr #2
+       orrcs   result, result, curbit, lsr #2
+       cmp     dividend, divisor, lsr #3
+       subcs   dividend, dividend, divisor, lsr #3
+       orrcs   result, result, curbit, lsr #3
+       cmp     dividend, #0                    @ Early termination?
+       movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
+       movne   divisor, divisor, lsr #4
+       bne     3b
+Lgot_result_udivsi3:
+       mov     r0, result
+       RET     pc, lr
+
+Ldiv0:
+       str     lr, [sp, #-4]!
+       bl      __div0
+       mov     r0, #0                  @ about as wrong as it could be
+       ldmia   sp!, {pc}RETCOND
+
+/* __umodsi3 ----------------------- */
+
+ENTRY(__umodsi3)
+       cmp     divisor, #0
+       beq     Ldiv0
+       mov     curbit, #1
+       cmp     dividend, divisor
+       RETc(cc)        pc, lr
+1:
+       @ Unless the divisor is very big, shift it up in multiples of
+       @ four bits, since this is the amount of unwinding in the main
+       @ division loop.  Continue shifting until the divisor is 
+       @ larger than the dividend.
+       cmp     divisor, #0x10000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #4
+       movcc   curbit, curbit, lsl #4
+       bcc     1b
+
+2:
+       @ For very big divisors, we must shift it a bit at a time, or
+       @ we will be in danger of overflowing.
+       cmp     divisor, #0x80000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #1
+       movcc   curbit, curbit, lsl #1
+       bcc     2b
+
+3:
+       @ Test for possible subtractions.  On the final pass, this may 
+       @ subtract too much from the dividend, so keep track of which
+       @ subtractions are done, we can fix them up afterwards...
+       mov     overdone, #0
+       cmp     dividend, divisor
+       subcs   dividend, dividend, divisor
+       cmp     dividend, divisor, lsr #1
+       subcs   dividend, dividend, divisor, lsr #1
+       orrcs   overdone, overdone, curbit, ror #1
+       cmp     dividend, divisor, lsr #2
+       subcs   dividend, dividend, divisor, lsr #2
+       orrcs   overdone, overdone, curbit, ror #2
+       cmp     dividend, divisor, lsr #3
+       subcs   dividend, dividend, divisor, lsr #3
+       orrcs   overdone, overdone, curbit, ror #3
+       mov     ip, curbit
+       cmp     dividend, #0                    @ Early termination?
+       movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
+       movne   divisor, divisor, lsr #4
+       bne     3b
+
+       @ Any subtractions that we should not have done will be recorded in
+       @ the top three bits of "overdone".  Exactly which were not needed
+       @ are governed by the position of the bit, stored in ip.
+       @ If we terminated early, because dividend became zero,
+       @ then none of the below will match, since the bit in ip will not be
+       @ in the bottom nibble.
+       ands    overdone, overdone, #0xe0000000
+       RETc(eq)        pc, lr                          @ No fixups needed
+       tst     overdone, ip, ror #3
+       addne   dividend, dividend, divisor, lsr #3
+       tst     overdone, ip, ror #2
+       addne   dividend, dividend, divisor, lsr #2
+       tst     overdone, ip, ror #1
+       addne   dividend, dividend, divisor, lsr #1
+       RET     pc, lr
+
+ENTRY(__divsi3)
+       eor     ip, dividend, divisor           @ Save the sign of the result.
+       mov     curbit, #1
+       mov     result, #0
+       cmp     divisor, #0
+       rsbmi   divisor, divisor, #0            @ Loops below use unsigned.
+       beq     Ldiv0
+       cmp     dividend, #0
+       rsbmi   dividend, dividend, #0
+       cmp     dividend, divisor
+       bcc     Lgot_result_divsi3
+
+1:
+       @ Unless the divisor is very big, shift it up in multiples of
+       @ four bits, since this is the amount of unwinding in the main
+       @ division loop.  Continue shifting until the divisor is 
+       @ larger than the dividend.
+       cmp     divisor, #0x10000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #4
+       movcc   curbit, curbit, lsl #4
+       bcc     1b
+
+2:
+       @ For very big divisors, we must shift it a bit at a time, or
+       @ we will be in danger of overflowing.
+       cmp     divisor, #0x80000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #1
+       movcc   curbit, curbit, lsl #1
+       bcc     2b
+
+3:
+       @ Test for possible subtractions, and note which bits
+       @ are done in the result.  On the final pass, this may subtract
+       @ too much from the dividend, but the result will be ok, since the
+       @ "bit" will have been shifted out at the bottom.
+       cmp     dividend, divisor
+       subcs   dividend, dividend, divisor
+       orrcs   result, result, curbit
+       cmp     dividend, divisor, lsr #1
+       subcs   dividend, dividend, divisor, lsr #1
+       orrcs   result, result, curbit, lsr #1
+       cmp     dividend, divisor, lsr #2
+       subcs   dividend, dividend, divisor, lsr #2
+       orrcs   result, result, curbit, lsr #2
+       cmp     dividend, divisor, lsr #3
+       subcs   dividend, dividend, divisor, lsr #3
+       orrcs   result, result, curbit, lsr #3
+       cmp     dividend, #0                    @ Early termination?
+       movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
+       movne   divisor, divisor, lsr #4
+       bne     3b
+Lgot_result_divsi3:
+       mov     r0, result
+       cmp     ip, #0
+       rsbmi   r0, r0, #0
+       RET     pc, lr
+
+ENTRY(__modsi3)
+       mov     curbit, #1
+       cmp     divisor, #0
+       rsbmi   divisor, divisor, #0            @ Loops below use unsigned.
+       beq     Ldiv0
+       @ Need to save the sign of the dividend, unfortunately, we need
+       @ ip later on; this is faster than pushing lr and using that.
+       str     dividend, [sp, #-4]!
+       cmp     dividend, #0
+       rsbmi   dividend, dividend, #0
+       cmp     dividend, divisor
+       bcc     Lgot_result_modsi3
+
+1:
+       @ Unless the divisor is very big, shift it up in multiples of
+       @ four bits, since this is the amount of unwinding in the main
+       @ division loop.  Continue shifting until the divisor is 
+       @ larger than the dividend.
+       cmp     divisor, #0x10000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #4
+       movcc   curbit, curbit, lsl #4
+       bcc     1b
+
+2:
+       @ For very big divisors, we must shift it a bit at a time, or
+       @ we will be in danger of overflowing.
+       cmp     divisor, #0x80000000
+       cmpcc   divisor, dividend
+       movcc   divisor, divisor, lsl #1
+       movcc   curbit, curbit, lsl #1
+       bcc     2b
+
+3:
+       @ Test for possible subtractions.  On the final pass, this may 
+       @ subtract too much from the dividend, so keep track of which
+       @ subtractions are done, we can fix them up afterwards...
+       mov     overdone, #0
+       cmp     dividend, divisor
+       subcs   dividend, dividend, divisor
+       cmp     dividend, divisor, lsr #1
+       subcs   dividend, dividend, divisor, lsr #1
+       orrcs   overdone, overdone, curbit, ror #1
+       cmp     dividend, divisor, lsr #2
+       subcs   dividend, dividend, divisor, lsr #2
+       orrcs   overdone, overdone, curbit, ror #2
+       cmp     dividend, divisor, lsr #3
+       subcs   dividend, dividend, divisor, lsr #3
+       orrcs   overdone, overdone, curbit, ror #3
+       mov     ip, curbit
+       cmp     dividend, #0                    @ Early termination?
+       movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
+       movne   divisor, divisor, lsr #4
+       bne     3b
+
+       @ Any subtractions that we should not have done will be recorded in
+       @ the top three bits of "overdone".  Exactly which were not needed
+       @ are governed by the position of the bit, stored in ip.
+       @ If we terminated early, because dividend became zero,
+       @ then none of the below will match, since the bit in ip will not be
+       @ in the bottom nibble.
+       ands    overdone, overdone, #0xe0000000
+       beq     Lgot_result_modsi3
+       tst     overdone, ip, ror #3
+       addne   dividend, dividend, divisor, lsr #3
+       tst     overdone, ip, ror #2
+       addne   dividend, dividend, divisor, lsr #2
+       tst     overdone, ip, ror #1
+       addne   dividend, dividend, divisor, lsr #1
+Lgot_result_modsi3:
+       ldr     ip, [sp], #4
+       cmp     ip, #0
+       rsbmi   dividend, dividend, #0
+       RET     pc, lr
diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
new file mode 100644 (file)
index 0000000..d0f9b11
--- /dev/null
@@ -0,0 +1,184 @@
+/* longlong.h -- based on code from gcc-2.95.3
+
+   definitions for mixed size 32/64 bit arithmetic.
+   Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+   This definition file 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, or (at your option) any later version.
+
+   This definition file 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.  */
+
+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
+
+#ifndef SI_TYPE_SIZE
+#define SI_TYPE_SIZE 32
+#endif
+
+#define __BITS4 (SI_TYPE_SIZE / 4)
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+
+/* Define auxiliary asm macros.
+
+   1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
+   multiplies two USItype integers MULTIPLER and MULTIPLICAND,
+   and generates a two-part USItype product in HIGH_PROD and
+   LOW_PROD.
+
+   2) __umulsidi3(a,b) multiplies two USItype integers A and B,
+   and returns a UDItype product.  This is just a variant of umul_ppmm.
+
+   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator) divides a two-word unsigned integer, composed by the
+   integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
+   places the quotient in QUOTIENT and the remainder in REMAINDER.
+   HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
+   If, in addition, the most significant bit of DENOMINATOR must be 1,
+   then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator).  Like udiv_qrnnd but the numbers are signed.  The
+   quotient is rounded towards 0.
+
+   5) count_leading_zeros(count, x) counts the number of zero-bits from
+   the msb to the first non-zero bit.  This is the number of steps X
+   needs to be shifted left to set the msb.  Undefined for X == 0.
+
+   6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+   high_addend_2, low_addend_2) adds two two-word unsigned integers,
+   composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
+   LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
+   LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
+   lost.
+
+   7) sub_ddmmss(high_difference, low_difference, high_minuend,
+   low_minuend, high_subtrahend, low_subtrahend) subtracts two
+   two-word unsigned integers, composed by HIGH_MINUEND_1 and
+   LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
+   respectively.  The result is placed in HIGH_DIFFERENCE and
+   LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
+   and is lost.
+
+   If any of these macros are left undefined for a particular CPU,
+   C macros are used.  */
+
+#if defined (__arm__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("adds       %1, %4, %5
+       adc     %0, %2, %3"                                             \
+          : "=r" ((USItype) (sh)),                                     \
+            "=&r" ((USItype) (sl))                                     \
+          : "%r" ((USItype) (ah)),                                     \
+            "rI" ((USItype) (bh)),                                     \
+            "%r" ((USItype) (al)),                                     \
+            "rI" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subs       %1, %4, %5
+       sbc     %0, %2, %3"                                             \
+          : "=r" ((USItype) (sh)),                                     \
+            "=&r" ((USItype) (sl))                                     \
+          : "r" ((USItype) (ah)),                                      \
+            "rI" ((USItype) (bh)),                                     \
+            "r" ((USItype) (al)),                                      \
+            "rI" ((USItype) (bl)))
+#define umul_ppmm(xh, xl, a, b) \
+{register USItype __t0, __t1, __t2;                                    \
+  __asm__ ("%@ Inlined umul_ppmm
+       mov     %2, %5, lsr #16
+       mov     %0, %6, lsr #16
+       bic     %3, %5, %2, lsl #16
+       bic     %4, %6, %0, lsl #16
+       mul     %1, %3, %4
+       mul     %4, %2, %4
+       mul     %3, %0, %3
+       mul     %0, %2, %0
+       adds    %3, %4, %3
+       addcs   %0, %0, #65536
+       adds    %1, %1, %3, lsl #16
+       adc     %0, %0, %3, lsr #16"                                    \
+          : "=&r" ((USItype) (xh)),                                    \
+            "=r" ((USItype) (xl)),                                     \
+            "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
+          : "r" ((USItype) (a)),                                       \
+            "r" ((USItype) (b)));}
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;                                                       \
+    umul_ppmm (__w.s.high, __w.s.low, u, v);                           \
+    __w.ll; })
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+  do {                                                                 \
+    USItype __d1, __d0, __q1, __q0;                                    \
+    USItype __r1, __r0, __m;                                           \
+    __d1 = __ll_highpart (d);                                          \
+    __d0 = __ll_lowpart (d);                                           \
+                                                                       \
+    __r1 = (n1) % __d1;                                                        \
+    __q1 = (n1) / __d1;                                                        \
+    __m = (USItype) __q1 * __d0;                                       \
+    __r1 = __r1 * __ll_B | __ll_highpart (n0);                         \
+    if (__r1 < __m)                                                    \
+      {                                                                        \
+       __q1--, __r1 += (d);                                            \
+       if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+         if (__r1 < __m)                                               \
+           __q1--, __r1 += (d);                                        \
+      }                                                                        \
+    __r1 -= __m;                                                       \
+                                                                       \
+    __r0 = __r1 % __d1;                                                        \
+    __q0 = __r1 / __d1;                                                        \
+    __m = (USItype) __q0 * __d0;                                       \
+    __r0 = __r0 * __ll_B | __ll_lowpart (n0);                          \
+    if (__r0 < __m)                                                    \
+      {                                                                        \
+       __q0--, __r0 += (d);                                            \
+       if (__r0 >= (d))                                                \
+         if (__r0 < __m)                                               \
+           __q0--, __r0 += (d);                                        \
+      }                                                                        \
+    __r0 -= __m;                                                       \
+                                                                       \
+    (q) = (USItype) __q1 * __ll_B | __q0;                              \
+    (r) = __r0;                                                                \
+  } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+
+extern const UQItype __clz_tab[];
+#define count_leading_zeros(count, x) \
+  do {                                                                 \
+    USItype __xr = (x);                                                        \
+    USItype __a;                                                       \
+                                                                       \
+    if (SI_TYPE_SIZE <= 32)                                            \
+      {                                                                        \
+       __a = __xr < ((USItype)1<<2*__BITS4)                            \
+         ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4)                \
+         : (__xr < ((USItype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);  \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)                 \
+         if (((__xr >> __a) & 0xff) != 0)                              \
+           break;                                                      \
+      }                                                                        \
+                                                                       \
+    (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);           \
+  } while (0)
diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
new file mode 100644 (file)
index 0000000..b666f1b
--- /dev/null
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__lshrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.high = 0;
+      w.s.low = (USItype)uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = (USItype)uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
+
diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
new file mode 100644 (file)
index 0000000..3b5aa51
--- /dev/null
@@ -0,0 +1,77 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+#define umul_ppmm(xh, xl, a, b) \
+{register USItype __t0, __t1, __t2;                                     \
+  __asm__ ("%@ Inlined umul_ppmm
+        mov     %2, %5, lsr #16
+        mov     %0, %6, lsr #16
+        bic     %3, %5, %2, lsl #16
+        bic     %4, %6, %0, lsl #16
+        mul     %1, %3, %4
+        mul     %4, %2, %4
+        mul     %3, %0, %3
+        mul     %0, %2, %0
+        adds    %3, %4, %3
+        addcs   %0, %0, #65536
+        adds    %1, %1, %3, lsl #16
+        adc     %0, %0, %3, lsr #16"                                    \
+           : "=&r" ((USItype) (xh)),                                    \
+             "=r" ((USItype) (xl)),                                     \
+             "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
+           : "r" ((USItype) (a)),                                       \
+             "r" ((USItype) (b)));}
+
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;                                                        \
+    umul_ppmm (__w.s.high, __w.s.low, u, v);                            \
+    __w.ll; })
+
+
+DItype
+__muldi3 (DItype u, DItype v)
+{
+  DIunion w;
+  DIunion uu, vv;
+
+  uu.ll = u,
+  vv.ll = v;
+
+  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
+  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+               + (USItype) uu.s.high * (USItype) vv.s.low);
+
+  return w.ll;
+}
+
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
new file mode 100644 (file)
index 0000000..0ba85e0
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *  linux/arch/arm/lib/putuser.S
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make
+ * them more efficient, especially as they return an error
+ * value in addition to the "real" return value.
+ *
+ * __put_user_X
+ *
+ * Inputs:     r0 contains the address
+ *             r1, r2 contains the value
+ * Outputs:    r0 is the error code
+ *             lr corrupted
+ *
+ * No other registers must be altered.  (see include/asm-arm/uaccess.h
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000
+ * Note also that it is intended that __put_user_bad is not global.
+ */
+#include <asm/constants.h>
+
+       .global __put_user_1
+__put_user_1:
+       bic     r2, sp, #0x1f00
+       bic     r2, r2, #0x00ff
+       ldr     r2, [r2, #TSK_ADDR_LIMIT]
+       sub     r2, r2, #1
+       cmp     r0, r2
+1:     strlsbt r1, [r0]
+       movls   r0, #0
+       movls   pc, lr
+       b       __put_user_bad
+
+       .global __put_user_2
+__put_user_2:
+       bic     r2, sp, #0x1f00
+       bic     r2, r2, #0x00ff
+       ldr     r2, [r2, #TSK_ADDR_LIMIT]
+       sub     r2, r2, #2
+       cmp     r0, r2
+2:     strlsbt r1, [r0], #1
+       movls   r1, r1, lsr #8
+3:     strlsbt r1, [r0]
+       movls   r0, #0
+       movls   pc, lr
+       b       __put_user_bad
+
+       .global __put_user_4
+__put_user_4:
+       bic     r2, sp, #0x1f00
+       bic     r2, r2, #0x00ff
+       ldr     r2, [r2, #TSK_ADDR_LIMIT]
+       sub     r2, r2, #4
+       cmp     r0, r2
+4:     strlst  r1, [r0]
+       movls   r0, #0
+       movls   pc, lr
+       b       __put_user_bad
+
+       .global __put_user_8
+__put_user_8:
+       bic     ip, sp, #0x1f00
+       bic     ip, ip, #0x00ff
+       ldr     ip, [ip, #TSK_ADDR_LIMIT]
+       sub     ip, ip, #8
+       cmp     r0, ip
+5:     strlst  r1, [r0], #4
+6:     strlst  r2, [r0]
+       movls   r0, #0
+       movls   pc, lr
+
+       /* fall through */
+
+__put_user_bad:
+       mov     r0, #-14
+       mov     pc, lr
+
+.section __ex_table, "a"
+       .long   1b, __put_user_bad
+       .long   2b, __put_user_bad
+       .long   3b, __put_user_bad
+       .long   4b, __put_user_bad
+       .long   5b, __put_user_bad
+       .long   6b, __put_user_bad
+.previous
diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
new file mode 100644 (file)
index 0000000..6c6ae63
--- /dev/null
@@ -0,0 +1,51 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+word_type
+__ucmpdi2 (DItype a, DItype b)
+{
+  DIunion au, bu;
+
+  au.ll = a, bu.ll = b;
+
+  if ((USItype) au.s.high < (USItype) bu.s.high)
+    return 0;
+  else if ((USItype) au.s.high > (USItype) bu.s.high)
+    return 2;
+  if ((USItype) au.s.low < (USItype) bu.s.low)
+    return 0;
+  else if ((USItype) au.s.low > (USItype) bu.s.low)
+    return 2;
+  return 1;
+}
+
diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c
new file mode 100644 (file)
index 0000000..d3f05b4
--- /dev/null
@@ -0,0 +1,231 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+#include "longlong.h"
+
+static const UQItype __clz_tab[] =
+{
+  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+
+UDItype
+__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
+{
+  DIunion ww;
+  DIunion nn, dd;
+  DIunion rr;
+  USItype d0, d1, n0, n1, n2;
+  USItype q0, q1;
+  USItype b, bm;
+
+  nn.ll = n;
+  dd.ll = d;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+        {
+          /* 0q = nn / 0D */
+
+          count_leading_zeros (bm, d0);
+
+          if (bm != 0)
+            {
+              /* Normalize, i.e. make the most significant bit of the
+                 denominator set.  */
+
+              d0 = d0 << bm;
+              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
+              n0 = n0 << bm;
+            }
+
+          udiv_qrnnd (q0, n0, n1, n0, d0);
+          q1 = 0;
+
+          /* Remainder in n0 >> bm.  */
+        }
+      else
+        {
+          /* qq = NN / 0d */
+
+          if (d0 == 0)
+            d0 = 1 / d0;        /* Divide intentionally by zero.  */
+
+          count_leading_zeros (bm, d0);
+
+          if (bm == 0)
+            {
+              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+                 conclude (the most significant bit of n1 is set) /\ (the
+                 leading quotient digit q1 = 1).
+
+                 This special case is necessary, not an optimization.
+                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
+
+              n1 -= d0;
+              q1 = 1;
+            }
+          else
+            {
+              /* Normalize.  */
+
+              b = SI_TYPE_SIZE - bm;
+
+              d0 = d0 << bm;
+              n2 = n1 >> b;
+              n1 = (n1 << bm) | (n0 >> b);
+              n0 = n0 << bm;
+
+              udiv_qrnnd (q1, n1, n2, n1, d0);
+            }
+
+          /* n1 != d0...  */
+
+          udiv_qrnnd (q0, n0, n1, n0, d0);
+
+          /* Remainder in n0 >> bm.  */
+        }
+
+      if (rp != 0)
+        {
+          rr.s.low = n0 >> bm;
+          rr.s.high = 0;
+          *rp = rr.ll;
+        }
+    }
+  else
+    {
+      if (d1 > n1)
+        {
+          /* 00 = nn / DD */
+
+          q0 = 0;
+          q1 = 0;
+
+          /* Remainder in n1n0.  */
+          if (rp != 0)
+            {
+              rr.s.low = n0;
+              rr.s.high = n1;
+              *rp = rr.ll;
+            }
+        }
+      else
+        {
+          /* 0q = NN / dd */
+
+          count_leading_zeros (bm, d1);
+          if (bm == 0)
+            {
+              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+                 conclude (the most significant bit of n1 is set) /\ (the
+                 quotient digit q0 = 0 or 1).
+
+                 This special case is necessary, not an optimization.  */
+
+              /* The condition on the next line takes advantage of that
+                 n1 >= d1 (true due to program flow).  */
+              if (n1 > d1 || n0 >= d0)
+                {
+                  q0 = 1;
+                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+                }
+              else
+                q0 = 0;
+
+              q1 = 0;
+
+              if (rp != 0)
+                {
+                  rr.s.low = n0;
+                  rr.s.high = n1;
+                  *rp = rr.ll;
+                }
+            }
+          else
+            {
+              USItype m1, m0;
+              /* Normalize.  */
+
+              b = SI_TYPE_SIZE - bm;
+
+              d1 = (d1 << bm) | (d0 >> b);
+              d0 = d0 << bm;
+              n2 = n1 >> b;
+              n1 = (n1 << bm) | (n0 >> b);
+              n0 = n0 << bm;
+
+              udiv_qrnnd (q0, n1, n2, n1, d1);
+              umul_ppmm (m1, m0, q0, d0);
+
+              if (m1 > n1 || (m1 == n1 && m0 > n0))
+                {
+                  q0--;
+                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+                }
+
+              q1 = 0;
+
+              /* Remainder in (n1n0 - m1m0) >> bm.  */
+              if (rp != 0)
+                {
+                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+                  rr.s.low = (n1 << b) | (n0 >> bm);
+                  rr.s.high = n1 >> bm;
+                  *rp = rr.ll;
+                }
+            }
+        }
+    }
+
+  ww.s.low = q0;
+  ww.s.high = q1;
+  return ww.ll;
+}
+
+UDItype
+__udivdi3 (UDItype n, UDItype d)
+{
+  return __udivmoddi4 (n, d, (UDItype *) 0);
+}
index 1d47b27a60191d02db37f70f5d3e9a0831fb88cc..0ebc07a2998bbea150a2437a2c845476674f8650 100644 (file)
@@ -279,6 +279,9 @@ void insb(unsigned int port, void *from, int len)
        __raw_readsb(ISAIO_BASE + off, from, len);
 }
 
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(insb);
+
 void outsw(unsigned int port, const void *from, int len)
 {
        u32 off;
@@ -309,6 +312,9 @@ void insw(unsigned int port, void *from, int len)
        __raw_readsw(ISAIO_BASE + off, from, len);
 }
 
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(insw);
+
 void outsl(unsigned int port, const void *from, int len)
 {
        panic("outsl not supported on this architecture");
index c1c1952b672b82f235ead6aa9cc59943414fa4d0..56e615a9dc9fdb2af2a2fce054b1012c282c7578 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
  *
- *  $Id: cpu.c,v 1.1 2001/06/17 10:12:37 rmk Exp $
+ *  $Id: cpu.c,v 1.2 2001/09/22 12:11:17 rmk Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -70,7 +70,7 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor)
  * Validate the speed in khz.  If it is outside our
  * range, then return the lowest.
  */
-unsigned int cpufreq_validatespeed(unsigned int freq_khz)
+unsigned int integrator_validatespeed(unsigned int freq_khz)
 {
        struct vco vco;
 
@@ -87,7 +87,7 @@ unsigned int cpufreq_validatespeed(unsigned int freq_khz)
        return vco_to_freq(vco, 1);
 }
 
-void cpufreq_setspeed(unsigned int freq_khz)
+void integrator_setspeed(unsigned int freq_khz)
 {
        struct vco vco = freq_to_vco(freq_khz, 1);
        u_int cm_osc;
@@ -122,6 +122,7 @@ static int __init cpu_init(void)
 
 #ifdef CONFIG_CPU_FREQ
        cpufreq_init(cpu_freq_khz);
+       cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed);
 #endif
 
        cm_stat = __raw_readl(CM_STAT);
index aa5ba5a4372f5ad30c1ef3d56ada38adbe40308a..a53feed419d2c55c827b4410cdb1d306b2bcccff 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/init.h>
 
index edff275d961e3f5a99020b716f091706e2c2fea7..8dee8740e8b21367b35858059fa52858481da6c9 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/ptrace.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
index 56d377e48c0bb1605d79e628d2e06e93fd37f984..515a2b49e910ee83f2952925aeb853a199d5b558 100644 (file)
@@ -14,31 +14,38 @@ obj-m :=
 obj-n :=
 obj-  :=
 
-export-objs := assabet.o bitsy.o freebird.o huw_webpanel.o yopy.o \
+export-objs := assabet.o h3600.o freebird.o huw_webpanel.o yopy.o \
                generic.o hwtimer.o irq.o usb_ctl.o usb_recv.o usb_send.o \
-               dma-sa1100.o dma-sa1111.o pcipool.o
+               dma-sa1100.o dma-sa1111.o pcipool.o sa1111-pcibuf.o
 
 # Common support (must be linked before board specific support)
 obj-y += generic.o irq.o dma-sa1100.o
-obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o sa1111-pcibuf.o pcipool.o
 
 # This needs to be cleaned up.  We probably need to have SA1100
 # and SA1110 config symbols.
+#
+# We link the CPU support next, so that RAM timings can be tuned.
 ifeq ($(CONFIG_CPU_FREQ),y)
 obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
 endif
 
+# Next, the SA1111 stuff.
+obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o
+obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o
+
 # Specific board support
+obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
 obj-$(CONFIG_SA1100_ASSABET) += assabet.o
 obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
-obj-$(CONFIG_SA1100_BITSY) += bitsy.o
 obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
 obj-$(CONFIG_SA1100_CERF) += cerf.o
 obj-$(CONFIG_SA1100_EMPEG) += empeg.o
 obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
 obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
 obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
+obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
+obj-$(CONFIG_SA1100_H3600) += h3600.o
 obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o
 obj-$(CONFIG_SA1100_ITSY) += itsy.o
 obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
@@ -63,6 +70,7 @@ leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o
 leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
 leds-$(CONFIG_SA1100_LART) += leds-lart.o
 leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
+leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
 obj-$(CONFIG_LEDS) += $(leds-y)
 
 include $(TOPDIR)/Rules.make
diff --git a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c
new file mode 100644 (file)
index 0000000..8ccb694
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/arm/mach-sa1100/adsbitsy.c
+ *
+ * Author: Woojung Huh
+ *
+ * Pieces specific to the ADS Bitsy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init adsbitsy_init(void)
+{
+       int ret;
+
+       if (!machine_is_adsbitsy())
+               return -ENODEV;
+
+       /*
+        * Ensure that the memory bus request/grant signals are setup,
+        * and the grant is held in its inactive state
+        */
+       sa1110_mb_disable();
+
+       /*
+        * Reset SA1111
+        */
+       GPCR |= GPIO_GPIO26;
+       udelay(1000);
+       GPSR |= GPIO_GPIO26;
+
+       /*
+        * Probe for SA1111.
+        */
+       ret = sa1111_probe();
+       if (ret < 0)
+               return ret;
+
+       /*
+        * We found it.  Wake the chip up.
+        */
+       sa1111_wake();
+
+       /*
+        * The SDRAM configuration of the SA1110 and the SA1111 must
+        * match.  This is very important to ensure that SA1111 accesses
+        * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+        * MBGNT signal, so we must have called sa1110_mb_disable()
+        * beforehand.
+        */
+       sa1111_configure_smc(1,
+                            FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+                            FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+       /*
+        * Enable PWM control for LCD
+        */
+       SKPCR |= SKPCR_PWMCLKEN;
+       SKPWM0 = 0x7F;                          // VEE
+       SKPEN0 = 1;
+       SKPWM1 = 0x01;                          // Backlight
+       SKPEN1 = 1;
+
+       /*
+        * We only need to turn on DCLK whenever we want to use the
+        * DMA.  It can otherwise be held firmly in the off position.
+        */
+       SKPCR |= SKPCR_DCLKEN;
+
+       /*
+        * Enable the SA1110 memory bus request and grant signals.
+        */
+       sa1110_mb_enable();
+
+       set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
+       sa1111_init_irq(SA1100_GPIO_TO_IRQ(0));
+
+       return 0;
+}
+
+__initcall(adsbitsy_init);
+
+static void __init adsbitsy_init_irq(void)
+{
+       /* First the standard SA1100 IRQs */
+       sa1100_init_irq();
+}
+
+
+/*
+ * Initialization fixup
+ */
+
+static void __init
+fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params,
+                    char **cmdline, struct meminfo *mi)
+{
+       SET_BANK( 0, 0xc0000000, 32*1024*1024 );
+       mi->nr_banks = 1;
+
+       ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+       setup_ramdisk( 1, 0, 0, 8192 );
+       setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+}
+
+static struct map_desc adsbitsy_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA1111 */
+  LAST_DESC
+};
+
+static int adsbitsy_uart_open(struct uart_port *port, struct uart_info *info)
+{
+       if (port->mapbase == _Ser1UTCR0) {
+               Ser1SDCR0 |= SDCR0_UART;
+               // Set RTS Output and High (should be done in the set_mctrl fn)
+               GPDR |= GPIO_GPIO15;
+               GPCR |= GPIO_GPIO15;
+               // Set CTS Input
+               GPDR &= ~GPIO_GPIO14;
+       } else if (port->mapbase == _Ser2UTCR0) {
+               Ser2UTCR4 = Ser2HSCR0 = 0;
+               // Set RTS Output and High (should be done in the set_mctrl fn)
+               GPDR |= GPIO_GPIO17;
+               GPCR |= GPIO_GPIO17;
+               // Set CTS Input
+               GPDR &= ~GPIO_GPIO16;
+       } else if (port->mapbase == _Ser2UTCR0) {
+               // Set RTS Output and High (should be done in the set_mctrl fn)
+               GPDR |= GPIO_GPIO19;
+               GPCR |= GPIO_GPIO19;
+               // Set CTS Input
+               GPDR &= ~GPIO_GPIO18;
+       }
+       return 0;
+}
+
+static struct sa1100_port_fns adsbitsy_port_fns __initdata = {
+       open:   adsbitsy_uart_open,
+};
+
+static void __init adsbitsy_map_io(void)
+{
+       sa1100_map_io();
+       iotable_init(adsbitsy_io_desc);
+
+       sa1110_register_uart_fns(&adsbitsy_port_fns);
+       sa1100_register_uart(0, 3);
+       sa1100_register_uart(1, 1);
+       sa1100_register_uart(2, 2);
+}
+
+MACHINE_START(ADSBITSY, "ADS Bitsy")
+       BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+       FIXUP(fixup_adsbitsy)
+       MAPIO(adsbitsy_map_io)
+       INITIRQ(adsbitsy_init_irq)
+MACHINE_END
index 9d6d8299477d118592db509a544588736f9dee58..d31fcc8a7b29d32778fe8c8c58514524bc3acb88 100644 (file)
@@ -47,6 +47,7 @@ static int __init assabet_init(void)
                 * or BCR_clear().
                 */
                BCR = BCR_value = BCR_DB1111;
+               NCR_0 = 0;
 
 #ifndef CONFIG_ASSABET_NEPONSET
                printk( "Warning: Neponset detected but full support "
@@ -101,6 +102,8 @@ static void __init get_assabet_scr(void)
        SCR_value = scr;
 }
 
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
 static void __init
 fixup_assabet(struct machine_desc *desc, struct param_struct *params,
              char **cmdline, struct meminfo *mi)
@@ -114,6 +117,12 @@ fixup_assabet(struct machine_desc *desc, struct param_struct *params,
        if (machine_has_neponset())
                printk("Neponset expansion board detected\n");
 
+       /*
+        * Apparantly bootldr uses a param_struct.  Groan.
+        */
+       if (t->hdr.tag != ATAG_CORE)
+               convert_to_tag_list(params, 1);
+
        if (t->hdr.tag != ATAG_CORE) {
                t->hdr.tag = ATAG_CORE;
                t->hdr.size = tag_size(tag_core);
@@ -265,7 +274,6 @@ static void __init assabet_map_io(void)
        neponset_map_io();
 #endif
 
-       sa1100_register_uart(1, 2);
        if (machine_has_neponset()) {
                /*
                 * When Neponset is attached, the first UART should be
@@ -295,7 +303,7 @@ static void __init assabet_map_io(void)
         * excessive power drain.  --rmk
         */
        GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
-       GPCR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+       GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
 }
 
 
diff --git a/arch/arm/mach-sa1100/bitsy.c b/arch/arm/mach-sa1100/bitsy.c
deleted file mode 100644 (file)
index ebb8710..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/bitsy.c
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/setup.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
-#include <linux/serial_core.h>
-
-#include "generic.h"
-
-
-/*
- * Bitsy has extended, write-only memory-mapped GPIO's
- */
-
-static int bitsy_egpio = EGPIO_BITSY_RS232_ON;
-
-void clr_bitsy_egpio(unsigned long x)
-{
-       bitsy_egpio &= ~x;
-       BITSY_EGPIO = bitsy_egpio;
-}
-
-void set_bitsy_egpio(unsigned long x)
-{
-       bitsy_egpio |= x;
-       BITSY_EGPIO = bitsy_egpio;
-}
-
-EXPORT_SYMBOL(clr_bitsy_egpio);
-EXPORT_SYMBOL(set_bitsy_egpio);
-
-
-/*
- * low-level UART features
- */
-
-static void bitsy_uart_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-       if (port->mapbase == _Ser3UTCR0) {
-               if (mctrl & TIOCM_RTS)
-                       GPCR = GPIO_BITSY_COM_RTS;
-               else
-                       GPSR = GPIO_BITSY_COM_RTS;
-       }
-}
-
-static int bitsy_uart_get_mctrl(struct uart_port *port)
-{
-       int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
-       if (port->mapbase == _Ser3UTCR0) {
-               int gplr = GPLR;
-               if (gplr & GPIO_BITSY_COM_DCD)
-                       ret &= ~TIOCM_CD;
-               if (gplr & GPIO_BITSY_COM_CTS)
-                       ret &= ~TIOCM_CTS;
-       }
-
-       return ret;
-}
-
-static void bitsy_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct uart_info *info = dev_id;
-       /* Note: should only call this if something has changed */
-       uart_handle_dcd_change(info, GPLR & GPIO_BITSY_COM_DCD);
-}
-
-static void bitsy_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct uart_info *info = dev_id;
-       /* Note: should only call this if something has changed */
-       uart_handle_cts_change(info, GPLR & GPIO_BITSY_COM_CTS);
-}
-
-static void bitsy_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
-{
-       if (port->mapbase == _Ser2UTCR0) {
-               if (state == 0) {
-                       set_bitsy_egpio(EGPIO_BITSY_IR_ON);
-               } else {
-                       clr_bitsy_egpio(EGPIO_BITSY_IR_ON);
-               }
-       } else if (port->mapbase == _Ser3UTCR0) {
-               if (state == 0) {
-                       set_bitsy_egpio(EGPIO_BITSY_RS232_ON);
-               } else {
-                       clr_bitsy_egpio(EGPIO_BITSY_RS232_ON);
-               }
-       }
-}
-
-static int bitsy_uart_open(struct uart_port *port, struct uart_info *info)
-{
-       int ret = 0;
-
-       if (port->mapbase == _Ser2UTCR0) {
-               Ser2UTCR4 = UTCR4_HSE;
-               Ser2HSCR0 = 0;
-               Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR |
-                           HSSR0_RAB | HSSR0_FRE;
-       } else if (port->mapbase == _Ser3UTCR0) {
-               GPDR &= ~(GPIO_BITSY_COM_DCD|GPIO_BITSY_COM_CTS);
-               GPDR |= GPIO_BITSY_COM_RTS;
-               set_GPIO_IRQ_edge(GPIO_BITSY_COM_DCD|GPIO_BITSY_COM_CTS,
-                                 GPIO_BOTH_EDGES);
-
-               ret = request_irq(IRQ_GPIO_BITSY_COM_DCD, bitsy_dcd_intr,
-                                 0, "RS232 DCD", info);
-               if (ret)
-                       return ret;
-
-               ret = request_irq(IRQ_GPIO_BITSY_COM_CTS, bitsy_cts_intr,
-                                 0, "RS232 CTS", info);
-               if (ret)
-                       free_irq(IRQ_GPIO_BITSY_COM_DCD, info);
-       }
-       return ret;
-}
-
-static void bitsy_uart_close(struct uart_port *port, struct uart_info *info)
-{
-       if (port->mapbase == _Ser3UTCR0) {
-               free_irq(IRQ_GPIO_BITSY_COM_DCD, info);
-               free_irq(IRQ_GPIO_BITSY_COM_CTS, info);
-       }
-}
-
-static struct sa1100_port_fns bitsy_port_fns __initdata = {
-       set_mctrl:      bitsy_uart_set_mctrl,
-       get_mctrl:      bitsy_uart_get_mctrl,
-       pm:             bitsy_uart_pm,
-       open:           bitsy_uart_open,
-       close:          bitsy_uart_close,
-};
-
-static struct map_desc bitsy_io_desc[] __initdata = {
- /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x49000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
-  { 0xf1000000, 0x10000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
-  { 0xf3000000, 0x40000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
-  LAST_DESC
-};
-
-static void __init bitsy_map_io(void)
-{
-       sa1100_map_io();
-       iotable_init(bitsy_io_desc);
-
-       sa1100_register_uart_fns(&bitsy_port_fns);
-       sa1100_register_uart(0, 3);
-       sa1100_register_uart(1, 1); /* isn't this one driven elsewhere? */
-       sa1100_register_uart(2, 2);
-}
-
-MACHINE_START(BITSY, "Compaq iPAQ")
-       BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-       BOOT_PARAMS(0xc0000100)
-       MAPIO(bitsy_map_io)
-       INITIRQ(sa1100_init_irq)
-MACHINE_END
index b236133e437e01642d5eed8d7e09b3e71f7110c2..56d9c0ad217018a75468cd1765e34cc7758e9e9d 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001 Russell King
  *
- *  $Id: cpu-sa1110.c,v 1.3 2001/08/12 15:41:53 rmk Exp $
+ *  $Id: cpu-sa1110.c,v 1.5 2001/09/10 13:25:58 rmk Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -258,14 +258,13 @@ static int __init sa1110_sdram_init(void)
 {
        struct sdram_params *sdram = NULL;
        unsigned int cur_freq = cpufreq_get(smp_processor_id());
-       int ret = -ENODEV;
 
        if (machine_is_assabet())
                sdram = &tc59sm716_cl3_params;
 
        if (sdram) {
                printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
-                       " twr: %d refresh: %d cas_latency: %d",
+                       " twr: %d refresh: %d cas_latency: %d\n",
                        sdram->tck, sdram->trcd, sdram->trp,
                        sdram->twr, sdram->refresh, sdram->cas_latency);
 
index b69656de7e17feeaffdd1ac013513e1008e78d38..39f6dbd18f5c22087c08f8f02e585ae3d81ee5a9 100644 (file)
@@ -68,26 +68,30 @@ static inline int start_sa1100_dma(sa1100_dma_t * dma, dma_addr_t dma_ptr, int s
 {
        dma_regs_t *regs = dma->regs;
        int status;
-       int use_bufa;
 
        status = regs->RdDCSR;
 
        /* If both DMA buffers are started, there's nothing else we can do. */
-       if ((status & DCSR_STRTA) && (status & DCSR_STRTB)) {
+       if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
                DPRINTK("start: st %#x busy\n", status);
                return -EBUSY;
        }
 
-       use_bufa = (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
-                   (!(status & DCSR_BIU) && !(status & DCSR_STRTA)));
-       if (use_bufa) {
-               regs->ClrDCSR = DCSR_DONEA | DCSR_STRTA;
+       if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
+           (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
+               if (status & DCSR_DONEA) {
+                       /* give a chance for the interrupt to be processed */
+                       goto irq_pending;
+               }
                regs->DBSA = dma_ptr;
                regs->DBTA = size;
                regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
                DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
        } else {
-               regs->ClrDCSR = DCSR_DONEB | DCSR_STRTB;
+               if (status & DCSR_DONEB) {
+                       /* give a chance for the interrupt to be processed */
+                       goto irq_pending;
+               }
                regs->DBSB = dma_ptr;
                regs->DBTB = size;
                regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
@@ -95,6 +99,9 @@ static inline int start_sa1100_dma(sa1100_dma_t * dma, dma_addr_t dma_ptr, int s
        }
 
        return 0;
+
+irq_pending:
+       return -EAGAIN;
 }
 
 
@@ -204,11 +211,16 @@ static void dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 
        DPRINTK("IRQ: b=%#x st=%#x\n", (int) dma->curr->id, status);
 
-       dma->regs->ClrDCSR = DCSR_ERROR | DCSR_DONEA | DCSR_DONEB;
-       if (!(status & (DCSR_DONEA | DCSR_DONEB)))
-               return;
+       if (status & (DCSR_ERROR)) {
+               printk(KERN_ERR "DMA on \"%s\" caused an error\n", dma->device_id);
+               dma->regs->ClrDCSR = DCSR_ERROR;
+       }
 
-       sa1100_dma_done (dma);
+       dma->regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
+       if (status & DCSR_DONEA)
+               sa1100_dma_done (dma);
+       if (status & DCSR_DONEB)
+               sa1100_dma_done (dma);
 }
 
 
@@ -435,7 +447,7 @@ int sa1100_dma_stop(dmach_t channel)
                dma->curr = NULL;
        }
        dma->spin_ref = 0;
-       dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB;
+       dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_DONEA|DCSR_DONEB;
        process_dma(dma);
        local_irq_restore(flags);
        return 0;
@@ -455,7 +467,6 @@ int sa1100_dma_resume(dmach_t channel)
        if (dma->stopped) {
                int flags;
                save_flags_cli(flags);
-               dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_RUN|DCSR_IE;
                dma->stopped = 0;
                dma->spin_ref = 0;
                process_dma(dma);
@@ -478,7 +489,7 @@ int sa1100_dma_flush_all(dmach_t channel)
        if (channel_is_sa1111_sac(channel))
                sa1111_reset_sac_dma(channel);
        else
-               dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_RUN|DCSR_IE;
+               dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_DONEA|DCSR_DONEB|DCSR_RUN|DCSR_IE;
        buf = dma->curr;
        if (!buf)
                buf = dma->tail;
index 23cfef671f902cad4ae3bbf8136c21efaf193661..ff6d18e770ccb86ffbf3597edbccdd405474113b 100644 (file)
@@ -314,7 +314,7 @@ int sa1111_check_dma_bug(dma_addr_t addr){
        if(physaddr<(1<<20))
                return 0;
 
-       switch(FExtr(SMCR, SMCR_DRAC)){
+       switch(FExtr(SBI_SMCR, SMCR_DRAC)){
        case 01: /* 10 row + bank address bits, A<20> must not be set */
                if(physaddr & (1<<20))
                        return -1;
@@ -341,7 +341,7 @@ int sa1111_check_dma_bug(dma_addr_t addr){
                break;
        default:
                printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%o\n",
-                      __FUNCTION__, FExtr(SMCR, SMCR_DRAC));
+                      __FUNCTION__, FExtr(SBI_SMCR, SMCR_DRAC));
                return -1;
        }
 
index 08ac54616c0a61b085cef958975bac6901221003..0df112c1e8c0cdc267fe66b4c1b6998c1dae0688 100644 (file)
@@ -69,7 +69,7 @@ EXPORT_SYMBOL(get_cclk_frequency);
  * Validate the speed in khz.  If we can't generate the precise
  * frequency requested, round it down (to be on the safe side).
  */
-unsigned int cpufreq_validatespeed(unsigned int khz)
+unsigned int sa1100_validatespeed(unsigned int khz)
 {
        int i;
 
@@ -87,7 +87,7 @@ unsigned int cpufreq_validatespeed(unsigned int khz)
  * above, we can match for an exact frequency.  If we don't find
  * an exact match, we will to set the lowest frequency to be safe.
  */
-void cpufreq_setspeed(unsigned int khz)
+void sa1100_setspeed(unsigned int khz)
 {
        int i;
 
@@ -103,6 +103,7 @@ void cpufreq_setspeed(unsigned int khz)
 static int __init sa1100_init_clock(void)
 {
        cpufreq_init(get_cclk_frequency() * 100);
+       cpufreq_setfunctions(sa1100_validatespeed, sa1100_setspeed);
        return 0;
 }
 
index 3ed9ba5c69541c3d2b6eb8565b76aa9448f8158c..dca3be2f024dd6f52786dcb7a97e1c6a9992c282 100644 (file)
@@ -131,14 +131,15 @@ fixup_graphicsclient(struct machine_desc *desc, struct param_struct *params,
        mi->nr_banks = 2;
 
        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-       setup_ramdisk( 1, 0, 0, 4096 );
+       setup_ramdisk( 1, 0, 0, 8192 );
        setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
 }
 
 static struct map_desc graphicsclient_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
   { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+  { 0xf1000000, 0x18000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CAN */
   LAST_DESC
 };
 
diff --git a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c
new file mode 100644 (file)
index 0000000..b41f9a6
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * linux/arch/arm/mach-sa1100/graphicsmaster.c
+ *
+ * Pieces specific to the GraphicsMaster board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init graphicsmaster_init(void)
+{
+       int ret;
+
+       if (!machine_is_graphicsmaster())
+               return -ENODEV;
+
+       /*
+        * Ensure that the memory bus request/grant signals are setup,
+        * and the grant is held in its inactive state
+        */
+       sa1110_mb_disable();
+
+       /*
+        * Probe for SA1111.
+        */
+       ret = sa1111_probe();
+       if (ret < 0)
+               return ret;
+
+       /*
+        * We found it.  Wake the chip up.
+        */
+       sa1111_wake();
+
+       /*
+        * The SDRAM configuration of the SA1110 and the SA1111 must
+        * match.  This is very important to ensure that SA1111 accesses
+        * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+        * MBGNT signal, so we must have called sa1110_mb_disable()
+        * beforehand.
+        */
+       sa1111_configure_smc(1,
+                            FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+                            FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+       /*
+        * Enable PWM control for LCD
+        */
+       SKPCR |= SKPCR_PWMCLKEN;
+       SKPWM0 = 0x7F;                          // VEE
+       SKPEN0 = 1;
+       SKPWM1 = 0x01;                          // Backlight
+       SKPEN1 = 1;
+
+       /*
+        * We only need to turn on DCLK whenever we want to use the
+        * DMA.  It can otherwise be held firmly in the off position.
+        */
+       SKPCR |= SKPCR_DCLKEN;
+
+       /*
+        * Enable the SA1110 memory bus request and grant signals.
+        */
+       sa1110_mb_enable();
+
+       sa1111_init_irq(ADS_EXT_IRQ(0));
+
+       return 0;
+}
+
+__initcall(graphicsmaster_init);
+
+/*
+ * Handlers for GraphicsMaster's external IRQ logic
+ */
+
+static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
+{
+       int i;
+
+       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 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)
+{
+       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)));
+}
+
+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)));
+}
+
+static void __init graphicsmaster_init_irq(void)
+{
+       int irq;
+
+       /* First the standard SA1100 IRQs */
+       sa1100_init_irq();
+
+       /* 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 );
+}
+
+
+/*
+ * Initialization fixup
+ */
+
+static void __init
+fixup_graphicsmaster(struct machine_desc *desc, struct param_struct *params,
+                    char **cmdline, struct meminfo *mi)
+{
+       SET_BANK( 0, 0xc0000000, 16*1024*1024 );
+       mi->nr_banks = 1;
+       SET_BANK( 1, 0xc8000000, 16*1024*1024 );
+       mi->nr_banks = 2;
+
+       ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+       setup_ramdisk( 1, 0, 0, 8192 );
+       setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+}
+
+static struct map_desc graphicsmaster_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CPLD */
+  { 0xf1000000, 0x40000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CAN */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+  LAST_DESC
+};
+
+static void __init graphicsmaster_map_io(void)
+{
+       sa1100_map_io();
+       iotable_init(graphicsmaster_io_desc);
+
+       sa1100_register_uart(0, 3);
+       sa1100_register_uart(1, 1);
+       sa1100_register_uart(2, 2);
+}
+
+MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
+       BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+       FIXUP(fixup_graphicsmaster)
+       MAPIO(graphicsmaster_map_io)
+       INITIRQ(graphicsmaster_init_irq)
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
new file mode 100644 (file)
index 0000000..3f221de
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-sa1100/h3600.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <linux/serial_core.h>
+
+#include "generic.h"
+
+
+/*
+ * Bitsy has extended, write-only memory-mapped GPIO's
+ */
+
+static int h3600_egpio = EGPIO_H3600_RS232_ON;
+
+void clr_h3600_egpio(unsigned long x)
+{
+       h3600_egpio &= ~x;
+       H3600_EGPIO = h3600_egpio;
+}
+
+void set_h3600_egpio(unsigned long x)
+{
+       h3600_egpio |= x;
+       H3600_EGPIO = h3600_egpio;
+}
+
+EXPORT_SYMBOL(clr_h3600_egpio);
+EXPORT_SYMBOL(set_h3600_egpio);
+
+
+/*
+ * Low-level UART features.
+ *
+ * Note that RTS, CTS and DCD are all active low.
+ */
+
+static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+       if (port->mapbase == _Ser3UTCR0) {
+               if (mctrl & TIOCM_RTS)
+                       GPCR = GPIO_H3600_COM_RTS;
+               else
+                       GPSR = GPIO_H3600_COM_RTS;
+       }
+}
+
+static int h3600_uart_get_mctrl(struct uart_port *port)
+{
+       int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+       if (port->mapbase == _Ser3UTCR0) {
+               int gplr = GPLR;
+               if (gplr & GPIO_H3600_COM_DCD)
+                       ret &= ~TIOCM_CD;
+               if (gplr & GPIO_H3600_COM_CTS)
+                       ret &= ~TIOCM_CTS;
+       }
+
+       return ret;
+}
+
+static void h3600_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct uart_info *info = dev_id;
+       /* Note: should only call this if something has changed */
+       uart_handle_dcd_change(info, !(GPLR & GPIO_H3600_COM_DCD));
+}
+
+static void h3600_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct uart_info *info = dev_id;
+       /* Note: should only call this if something has changed */
+       uart_handle_cts_change(info, !(GPLR & GPIO_H3600_COM_CTS));
+}
+
+static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+       if (port->mapbase == _Ser2UTCR0) {
+               if (state == 0) {
+                       set_h3600_egpio(EGPIO_H3600_IR_ON);
+               } else {
+                       clr_h3600_egpio(EGPIO_H3600_IR_ON);
+               }
+       } else if (port->mapbase == _Ser3UTCR0) {
+               if (state == 0) {
+                       set_h3600_egpio(EGPIO_H3600_RS232_ON);
+               } else {
+                       clr_h3600_egpio(EGPIO_H3600_RS232_ON);
+               }
+       }
+}
+
+static int h3600_uart_open(struct uart_port *port, struct uart_info *info)
+{
+       int ret = 0;
+
+       if (port->mapbase == _Ser2UTCR0) {
+               Ser2UTCR4 = UTCR4_HSE;
+               Ser2HSCR0 = 0;
+               Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR |
+                           HSSR0_RAB | HSSR0_FRE;
+       } else if (port->mapbase == _Ser3UTCR0) {
+               GPDR &= ~(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS);
+               GPDR |= GPIO_H3600_COM_RTS;
+               set_GPIO_IRQ_edge(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS,
+                                 GPIO_BOTH_EDGES);
+
+               ret = request_irq(IRQ_GPIO_H3600_COM_DCD, h3600_dcd_intr,
+                                 0, "RS232 DCD", info);
+               if (ret)
+                       return ret;
+
+               ret = request_irq(IRQ_GPIO_H3600_COM_CTS, h3600_cts_intr,
+                                 0, "RS232 CTS", info);
+               if (ret)
+                       free_irq(IRQ_GPIO_H3600_COM_DCD, info);
+       }
+       return ret;
+}
+
+static void h3600_uart_close(struct uart_port *port, struct uart_info *info)
+{
+       if (port->mapbase == _Ser3UTCR0) {
+               free_irq(IRQ_GPIO_H3600_COM_DCD, info);
+               free_irq(IRQ_GPIO_H3600_COM_CTS, info);
+       }
+}
+
+static struct sa1100_port_fns h3600_port_fns __initdata = {
+       set_mctrl:      h3600_uart_set_mctrl,
+       get_mctrl:      h3600_uart_get_mctrl,
+       pm:             h3600_uart_pm,
+       open:           h3600_uart_open,
+       close:          h3600_uart_close,
+};
+
+static struct map_desc h3600_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x49000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
+  { 0xf1000000, 0x10000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
+  { 0xf3000000, 0x40000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
+  LAST_DESC
+};
+
+static void __init h3600_map_io(void)
+{
+       sa1100_map_io();
+       iotable_init(h3600_io_desc);
+
+       sa1100_register_uart_fns(&h3600_port_fns);
+       sa1100_register_uart(0, 3);
+       sa1100_register_uart(1, 1); /* isn't this one driven elsewhere? */
+       sa1100_register_uart(2, 2);
+
+       /*
+        * Default GPIO settings.
+        */
+       GPCR = 0x0fffffff;
+       GPDR = 0x0401f3fc;
+
+       /*
+        * Ensure those pins are outputs and driving low.
+        */
+       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+}
+
+MACHINE_START(H3600, "Compaq iPAQ")
+       BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+       BOOT_PARAMS(0xc0000100)
+       MAPIO(h3600_map_io)
+       INITIRQ(sa1100_init_irq)
+MACHINE_END
index 68b7e23b52b2c50a6c515f61dd9b3ed96bd20594..243ea20ec5f49ac35f20429f83b62d580a7e4dd9 100644 (file)
@@ -46,7 +46,8 @@ static int __init jornada720_init(void)
        PPDR |= PPC_LDD3 | PPC_LDD4;
 
        /* initialize extra IRQs */
-       sa1111_init_irq(1);     /* chained on GPIO 1 */
+       set_GPIO_IRQ_edge(GPIO_GPIO(1), GPIO_RISING_EDGE);
+       sa1111_init_irq(SA1100_GPIO_TO_IRQ(1)); /* chained on GPIO 1 */
 
        sa1100_register_uart(0, 3);
        sa1100_register_uart(1, 1);
diff --git a/arch/arm/mach-sa1100/leds-graphicsmaster.c b/arch/arm/mach-sa1100/leds-graphicsmaster.c
new file mode 100644 (file)
index 0000000..b900167
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  linux/arch/arm/mach-sa1100/leds-graphicsmaster.c
+ *
+ * GraphicsClient Plus LEDs support
+ * Woojung Huh, Feb 13, 2001
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED      1
+#define LED_STATE_CLAIMED      2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_TIMER       ADS_LED0  /* green heartbeat */
+#define LED_USER        ADS_LED1  /* amber, boots to on */
+#define LED_IDLE        ADS_LED2  /* red has the idle led, if any */
+
+#define LED_MASK       (ADS_LED0|ADS_LED1|ADS_LED2)
+
+void graphicsmaster_leds_event(led_event_t evt)
+{
+       unsigned long flags;
+
+       save_flags_cli(flags);
+
+       switch (evt) {
+       case led_start:
+               hw_led_state = 0;        /* gc leds are positive logic */
+               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_TIMER;
+               break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+       case led_idle_start:
+               if (!(led_state & LED_STATE_CLAIMED))
+                       hw_led_state &= ~LED_IDLE;
+               break;
+
+       case led_idle_end:
+               if (!(led_state & LED_STATE_CLAIMED))
+                       hw_led_state |= LED_IDLE;
+               break;
+#endif
+
+       case led_green_on:
+               break;
+
+       case led_green_off:
+               break;
+
+       case led_amber_on:
+               hw_led_state |= LED_USER;
+               break;
+
+       case led_amber_off:
+               hw_led_state &= ~LED_USER;
+               break;
+
+       case led_red_on:
+               break;
+
+       case led_red_off:
+               break;
+
+       default:
+               break;
+       }
+
+       if  (led_state & LED_STATE_ENABLED) {
+               GPSR = hw_led_state;
+               GPCR = hw_led_state ^ LED_MASK;
+       }
+
+       restore_flags(flags);
+}
index 0e6534dbabe80605851f7358e9eacb3b12a698d4..dfabcfd96907987d05f5a54a04d8e8f8616f5488 100644 (file)
@@ -30,6 +30,8 @@ sa1100_leds_init(void)
                leds_event = lart_leds_event;
        if (machine_is_pfs168())
                leds_event = pfs168_leds_event;
+       if (machine_is_graphicsmaster())
+               leds_event = graphicsmaster_leds_event;
 
        leds_event(led_start);
        return 0;
index 44b91bf807b24673ab328d22313957b6f1ae7469..15b0f647f0a5682ef164db5cb6bb8438fcee8b95 100644 (file)
@@ -5,4 +5,4 @@ extern void flexanet_leds_event(led_event_t evt);
 extern void graphicsclient_leds_event(led_event_t evt);
 extern void lart_leds_event(led_event_t evt);
 extern void pfs168_leds_event(led_event_t evt);
-
+extern void graphicsmaster_leds_event(led_event_t evt);
index f5da3a28f6fe09e35591f155d1d641563de649b4..2923e12dd03f5986295e687a97702e2307d6cc6b 100644 (file)
@@ -74,36 +74,73 @@ static void __init neponset_init_irq(void)
 
 static int __init neponset_init(void)
 {
-       /* only on assabet */
+       int ret;
+
+       /*
+        * The Neponset is only present on the Assabet machine type.
+        */
        if (!machine_is_assabet())
-               return 0;
-
-       if (machine_has_neponset()) {
-               LEDS = WHOAMI;
-
-               if (sa1111_init() < 0)
-                       return -EINVAL;
-               /*
-                * Assabet is populated by default with two Samsung
-                * KM416S8030T-G8
-                * 128Mb SDRAMs, which are organized as 12-bit (row addr) x
-                * 9-bit
-                * (column addr), according to the data sheet. Apparently, the
-                * bank selects factor into the row address, as Angel sets up
-                * the
-                * SA-1110 to use 14x9 addresses. The SDRAM datasheet specifies
-                * that when running at 100-125MHz, the CAS latency for -8
-                * parts
-                * is 3 cycles, which is consistent with Angel.
-                */
-               SMCR = (SMCR_DTIM | SMCR_MBGE |
-                       FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
-                       ((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
-               SKPCR |= SKPCR_DCLKEN;
-
-               neponset_init_irq();
-       } else
-               printk("Neponset expansion board not present\n");
+               return -ENODEV;
+
+       /*
+        * Ensure that the memory bus request/grant signals are setup,
+        * and the grant is held in its inactive state, whether or not
+        * we actually have a Neponset attached.
+        */
+       sa1110_mb_disable();
+
+       if (!machine_has_neponset()) {
+               printk(KERN_DEBUG "Neponset expansion board not present\n");
+               return -ENODEV;
+       }
+
+       if (WHOAMI != 0x11) {
+               printk(KERN_WARNING "Neponset board detected, but "
+                       "wrong ID: %02x\n", WHOAMI);
+               return -ENODEV;
+       }
+
+       /*
+        * Neponset has SA1111 connected to CS4.  We know that after
+        * reset the chip will be configured for variable latency IO.
+        */
+       /* FIXME: setup MSC2 */
+
+       /*
+        * Probe for a SA1111.
+        */
+       ret = sa1111_probe();
+       if (ret < 0)
+               return ret;
+
+       /*
+        * We found it.  Wake the chip up.
+        */
+       sa1111_wake();
+
+       /*
+        * The SDRAM configuration of the SA1110 and the SA1111 must
+        * match.  This is very important to ensure that SA1111 accesses
+        * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+        * MBGNT signal, so we must have called sa1110_mb_disable()
+        * beforehand.
+        */
+       sa1111_configure_smc(1,
+                            FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+                            FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+       /*
+        * We only need to turn on DCLK whenever we want to use the
+        * DMA.  It can otherwise be held firmly in the off position.
+        */
+       SKPCR |= SKPCR_DCLKEN;
+
+       /*
+        * Enable the SA1110 memory bus request and grant signals.
+        */
+       sa1110_mb_enable();
+
+       neponset_init_irq();
 
        return 0;
 }
index 1efaf58f5f9c83ea23eabc5d7c7970da39578add..99128a49f09ae0e1adfa8d4bcec10da3e0375bd9 100644 (file)
@@ -20,7 +20,7 @@ static void __init
 fixup_pangolin(struct machine_desc *desc, struct param_struct *params,
               char **cmdline, struct meminfo *mi)
 {
-       SET_BANK( 0, 0xc0000000, 64*1024*1024 );
+       SET_BANK( 0, 0xc0000000, 128*1024*1024 );
        mi->nr_banks = 1;
 
        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
index acf3615d9713f2c87e9c4caaaa90c6f82606af11..cfe3a1d428a120b964c19b5275de6337c7bf96ac 100644 (file)
 
 static int __init pfs168_init(void)
 {
-       if (sa1111_init() < 0)
-               return -EINVAL;
-       SMCR = (SMCR_DTIM | SMCR_MBGE |
-               FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
-               ((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
+       int ret;
+
+       if (!machine_is_pfs168())
+               return -ENODEV;
+
+       /*
+        * Ensure that the memory bus request/grant signals are setup,
+        * and the grant is held in its inactive state
+        */
+       sa1110_mb_disable();
+
+       /*
+        * Probe for SA1111.
+        */
+       ret = sa1111_probe();
+       if (ret < 0)
+               return ret;
+
+       /*
+        * We found it.  Wake the chip up.
+        */
+       sa1111_wake();
+
+       /*
+        * The SDRAM configuration of the SA1110 and the SA1111 must
+        * match.  This is very important to ensure that SA1111 accesses
+        * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+        * MBGNT signal, so we must have called sa1110_mb_disable()
+        * beforehand.
+        */
+       sa1111_configure_smc(1,
+                            FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+                            FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+       /*
+        * We only need to turn on DCLK whenever we want to use the
+        * DMA.  It can otherwise be held firmly in the off position.
+        */
        SKPCR |= SKPCR_DCLKEN;
 
-       sa1111_init_irq(25);    /* SA1111 IRQ on GPIO 25 */
+       /*
+        * Enable the SA1110 memory bus request and grant signals.
+        */
+       sa1110_mb_enable();
+
+       set_GPIO_IRQ_edge(GPIO_GPIO(25), GPIO_RISING_EDGE);
+       sa1111_init_irq(SA1100_GPIO_TO_IRQ(25));        /* SA1111 IRQ on GPIO 25 */
 
        return 0;
 }
index a9f2c6ad40add9159301c8559e7829234e1d3333..2863c19338cf3519b21a59eeac65f05b9a207fe2 100644 (file)
@@ -13,7 +13,6 @@
  *
  *  06/13/2001 - created.
  */
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -64,13 +63,6 @@ init_safe_buffers(struct pci_dev *dev)
        return 0;
 }
 
-static void
-free_safe_buffers(void)
-{
-       pci_pool_destroy(small_buffer_cache);
-       pci_pool_destroy(large_buffer_cache);
-}
-
 /* allocate a 'safe' buffer and keep track of it */
 static char *
 alloc_safe_buffer(char *unsafe, int size, dma_addr_t *pbus)
@@ -183,17 +175,11 @@ free_safe_buffer(char *buf)
  * we assume calls to map_single are symmetric with calls to unmap_single...
  */
 dma_addr_t
-pci_map_single(struct pci_dev *hwdev, void *virtptr,
+sa1111_map_single(struct pci_dev *hwdev, void *virtptr,
               size_t size, int direction)
 {
        dma_addr_t busptr;
 
-       /* hack; usb-ohci.c never sends hwdev==NULL, all others do */
-       if (hwdev == NULL) {
-               consistent_sync(virtptr, size, direction);
-               return virt_to_bus(virtptr);
-       }
-
        mapped_alloc_size += size;
 
        if (0) printk("pci_map_single(hwdev=%p,ptr=%p,size=%d,dir=%x) "
@@ -235,7 +221,7 @@ pci_map_single(struct pci_dev *hwdev, void *virtptr,
  * (basically return things back to the way they should be)
  */
 void
-pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+sa1111_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
                 size_t size, int direction)
 {
        char *safe, *unsafe;
@@ -267,13 +253,21 @@ pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
        }
 }
 
-EXPORT_SYMBOL(pci_map_single);
-EXPORT_SYMBOL(pci_unmap_single);
+EXPORT_SYMBOL(sa1111_map_single);
+EXPORT_SYMBOL(sa1111_unmap_single);
 
-static void __init sa1111_init_safe_buffers(void)
+static int __init sa1111_init_safe_buffers(void)
 {
        printk("Initializing SA1111 buffer pool for DMA workaround\n");
        init_safe_buffers(NULL);
+       return 0;
+}
+
+static void free_safe_buffers(void)
+{
+       pci_pool_destroy(small_buffer_cache);
+       pci_pool_destroy(large_buffer_cache);
 }
 
-__initcall(sa1111_init_safe_buffers);
+module_init(sa1111_init_safe_buffers);
+module_exit(free_safe_buffers);
index f9eeeb6ae4e158a6e52fd96d1fbfe6b949a13ea8..394e3fe74af11478646b64b787e192ddb469b58b 100644 (file)
@@ -15,7 +15,6 @@
  * All initialization functions provided here are intended to be called
  * from machine specific code with proper arguments when required.
  */
-
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
@@ -23,8 +22,6 @@
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 
 #include "sa1111.h"
 
-static int sa1111_ohci_hcd_init(void);
-
-/*
- * SA1111 initialization
- */
-
-int __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 %lx, metal revision %lx\n",
-                       (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
-       else {
-               printk(KERN_ERR "Could not detect SA-1111!\n");
-               return -EINVAL;
-       }
-
-       /*
-        * 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_32_768kHz;
-       GPDR |= GPIO_32_768kHz;
-       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.
-        */
-
-       /*
-        * If the system is going to use the SA-1111 DMA engines, set up
-        * the memory bus request/grant pins. Also configure the shared
-        * memory controller on the SA-1111 (SA-1111 Developer's Manual,
-        * section 3.2.3) and power up the DMA bus clock:
-        */
-       GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
-       GPDR |= GPIO_MBGNT;
-       GPDR &= ~GPIO_MBREQ;
-       TUCR |= TUCR_MR;
-
-#ifdef CONFIG_USB_OHCI
-       /* setup up sa1111 usb host controller h/w */
-       sa1111_ohci_hcd_init();
-#endif
-
-       return 0;
-}
-
-
 /*
  * SA1111  Interrupt support
  */
@@ -159,7 +98,7 @@ static void sa1111_unmask_highirq(unsigned int irq)
        INTEN1 |= 1 << ((irq - SA1111_IRQ(32)));
 }
 
-void __init sa1111_init_irq(int gpio_nr)
+void __init sa1111_init_irq(int irq_nr)
 {
        int irq;
 
@@ -181,144 +120,146 @@ void __init sa1111_init_irq(int gpio_nr)
 
        for (irq = SA1111_IRQ(0); irq <= SA1111_IRQ(26); irq++) {
                irq_desc[irq].valid     = 1;
-               irq_desc[irq].probe_ok  = 1;
+               irq_desc[irq].probe_ok  = 0;
                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].probe_ok  = 0;
                irq_desc[irq].mask_ack  = sa1111_mask_and_ack_highirq;
                irq_desc[irq].mask      = sa1111_mask_highirq;
                irq_desc[irq].unmask    = sa1111_unmask_highirq;
        }
 
-       /* Not every machines has the SA1111 interrupt routed to a GPIO */
-       if (gpio_nr >= 0) {
-               set_GPIO_IRQ_edge (GPIO_GPIO(gpio_nr), GPIO_RISING_EDGE);
-               setup_arm_irq (SA1100_GPIO_TO_IRQ(gpio_nr), &sa1111_irq);
-       }
+       /* Register SA1111 interrupt */
+       if (irq_nr >= 0)
+               setup_arm_irq(irq_nr, &sa1111_irq);
 }
 
-/* ----------------- */
-
-#ifdef CONFIG_USB_OHCI
-
-#if defined(CONFIG_SA1100_XP860) || defined(CONFIG_ASSABET_NEPONSET) || defined(CONFIG_SA1100_PFS168)
-#define PwrSensePolLow  1
-#define PwrCtrlPolLow   1
-#else
-#define PwrSensePolLow  0
-#define PwrCtrlPolLow   0
-#endif
-
 /*
- * The SA-1111 errata says that the DMA hardware needs to be exercised
- * before the clocks are turned on to work properly.  This code does
- * a tiny dma transfer to prime to hardware.
+ * Probe for a SA1111 chip.
  */
-static void __init sa1111_dma_setup(void)
-{
-       dma_addr_t vbuf;
-       void * pbuf;
-
-       /* DMA init & setup */
-
-       /* WARNING: The SA-1111 L3 function is used as part of this
-        * SA-1111 DMA errata workaround.
-        *
-        * N.B., When the L3 function is enabled, it uses GPIO_B<4:5>
-        * and takes precedence over the PS/2 mouse and GPIO_B
-        * functions. Refer to "Intel StrongARM SA-1111 Microprocessor
-        * Companion Chip, Sect 10.2" for details.  So this "fix" may
-        * "break" support of either PS/2 mouse or GPIO_B if
-        * precautions are not taken to avoid collisions in
-        * configuration and use of these pins. AFAIK, no precautions
-        * are taken at this time. So it is likely that the action
-        * taken here may cause problems in PS/2 mouse and/or GPIO_B
-        * pin use elsewhere.
-        *
-        * But wait, there's more... What we're doing here is
-        * obviously altogether a bad idea. We're indiscrimanately bit
-        * flipping config for a few different functions here which
-        * are "owned" by other drivers. This needs to be handled
-        * better than it is being done here at this time.  */
-
-       /* prime the dma engine with a tiny dma */
-       SKPCR |= SKPCR_I2SCLKEN;
-       SKAUD |= SKPCR_L3CLKEN | SKPCR_SCLKEN;
-
-       SACR0 |= 0x00003305;
-       SACR1 = 0x00000000;
-
-       /* we need memory below 1mb */
-       pbuf = consistent_alloc(GFP_KERNEL | GFP_DMA, 4, &vbuf);
-
-       SADTSA = (unsigned long)pbuf;
-       SADTCA = 4;
-
-       SADTCS |= 0x00000011;
-       SKPCR |= SKPCR_DCLKEN;
-
-       /* wait */
-       udelay(100);
-
-       SACR0 &= ~(0x00000002);
-       SACR0 &= ~(0x00000001);
-
-       /* */
-       SACR0 |= 0x00000004;
-       SACR0 &= ~(0x00000004);
 
-       SKAUD &= ~(SKPCR_L3CLKEN | SKPCR_SCLKEN);
+int __init sa1111_probe(void)
+{
+       unsigned long id = SBI_SKID;
+       int ret = -ENODEV;
 
-       SKPCR &= ~SKPCR_I2SCLKEN;
+       if ((id & SKID_ID_MASK) == SKID_SA1111_ID) {
+               printk(KERN_INFO "SA-1111 Microprocessor Companion Chip: "
+                       "silicon revision %lx, metal revision %lx\n",
+                       (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
+               ret = 0;
+       } else {
+               printk(KERN_DEBUG "SA-1111 not detected: ID = %08lx\n", id);
+       }
 
-       consistent_free(pbuf, 4, vbuf);
+       return ret;
 }
 
-#ifdef CONFIG_USB_OHCI
 /*
- * reset the SA-1111 usb controller and turn on it's clocks
+ * Bring the SA1111 out of reset.  This requires a set procedure:
+ *  1. nRESET asserted (by hardware)
+ *  2. CLK turned on from SA1110
+ *  3. nRESET deasserted
+ *  4. VCO turned on, PLL_BYPASS turned off
+ *  5. Wait lock time, then assert RCLKEn
+ *  7. PCR set to allow clocking of individual functions
+ *
+ * Until we've done this, the only registers we can access are:
+ *   SBI_SKCR
+ *   SBI_SMCR
+ *   SBI_SKID
  */
-static int __init sa1111_ohci_hcd_init(void)
+void sa1111_wake(void)
 {
-       volatile unsigned long *Reset = (void *)SA1111_p2v(_SA1111(0x051c));
-       volatile unsigned long *Status = (void *)SA1111_p2v(_SA1111(0x0518));
+       /*
+        * 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_32_768kHz;
+       GPDR |= GPIO_32_768kHz;
+       TUCR = TUCR_3_6864MHz;
 
-       /* turn on clocks */
-       SKPCR |= SKPCR_UCLKEN;
-       udelay(100);
+       /*
+        * Turn VCO on, and disable PLL Bypass.
+        */
+       SBI_SKCR &= ~SKCR_VCO_OFF;
+       SBI_SKCR |= SKCR_PLL_BYPASS | SKCR_OE_EN;
 
-       /* force a reset */
-       *Reset = 0x01;
-       *Reset |= 0x02;
+       /*
+        * Wait lock time.  SA1111 manual _doesn't_
+        * specify a figure for this!  We choose 100us.
+        */
        udelay(100);
 
-       *Reset = 0;
+       /*
+        * Enable RCLK.  We also ensure that RDYEN is set.
+        */
+       SBI_SKCR |= SKCR_RCLKEN | SKCR_RDYEN;
 
-       /* take out of reset */
-       /* set power sense and control lines (this from the diags code) */
-        *Reset = ( PwrSensePolLow << 6 )
-               | ( PwrCtrlPolLow << 7 );
+       /*
+        * Wait 14 RCLK cycles for the chip to finish coming out
+        * of reset. (RCLK=24MHz).  This is 590ns.
+        */
+       udelay(1);
 
-       *Status = 0;
+       /*
+        * Ensure all clocks are initially off.
+        */
+       SKPCR = 0;
+}
+
+void sa1111_doze(void)
+{
+       if (SKPCR & SKPCR_UCLKEN) {
+               printk("SA1111 doze mode refused\n");
+               return;
+       }
+       SBI_SKCR &= ~SKCR_RCLKEN;
+}
 
-       udelay(10);
+/*
+ * Configure the SA1111 shared memory controller.
+ */
+void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency)
+{
+       unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
 
-       /* compensate for dma bug */
-       sa1111_dma_setup();
+       if (cas_latency == 3)
+               smcr |= SMCR_CLAT;
 
-       return 0;
+       SBI_SMCR = smcr;
 }
 
-void sa1111_ohci_hcd_cleanup(void)
+/*
+ * Disable the memory bus request/grant signals on the SA1110 to
+ * ensure that we don't receive spurious memory requests.  We set
+ * the MBGNT signal false to ensure the SA1111 doesn't own the
+ * SDRAM bus.
+ */
+void __init sa1110_mb_disable(void)
 {
-       /* turn the USB clock off */
-       SKPCR &= ~SKPCR_UCLKEN;
+       PGSR &= ~GPIO_MBGNT;
+       GPCR = GPIO_MBGNT;
+       GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+
+       GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ);
+
 }
-#endif
 
+/*
+ * If the system is going to use the SA-1111 DMA engines, set up
+ * the memory bus request/grant pins.
+ */
+void __init sa1110_mb_enable(void)
+{
+       PGSR &= ~GPIO_MBGNT;
+       GPCR = GPIO_MBGNT;
+       GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
 
-#endif /* CONFIG_USB_OHCI */
+       GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+       TUCR |= TUCR_MR;
+}
index d14e0b0d990e3f9d93a249c250e5f98e91c85e42..c2603477121848ee2595c601cc6fd0bbbc0f000e 100644 (file)
@@ -2,7 +2,33 @@
  * linux/arch/arm/mach-sa1100/sa1111.h
  */
 
-extern int __init sa1111_init(void);
-extern void __init sa1111_init_irq(int gpio_nr);
+/*
+ * These two don't really belong in here.
+ */
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
+
+/*
+ * Probe for a SA1111 chip.
+ */
+extern int sa1111_probe(void);
+
+/*
+ * Wake up a SA1111 chip.
+ */
+extern void sa1111_wake(void);
+
+/*
+ * Doze the SA1111 chip.
+ */
+extern void sa1111_doze(void);
+
+/*
+ * Configure the SA1111 shared memory controller.
+ */
+extern void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency);
+
+
+extern void sa1111_init_irq(int irq_nr);
 extern void sa1111_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs );
 
index f4f0730dde7b9d6987f5abc0650a01040d6cf4b7..89d54d7c0681aa4ad9e0afb6496eb4350cdf1065 100644 (file)
@@ -28,10 +28,27 @@ static void xp860_power_off(void)
        while(1);
 }
 
+/*
+ * Note: I replaced the sa1111_init() without the full SA1111 initialisation
+ * because this machine doesn't appear to use the DMA features.  If this is
+ * wrong, please look at neponset.c to fix it properly.
+ */
 static int __init xp860_init(void)
 {
        pm_power_off = xp860_power_off;
-       sa1111_init();
+
+       /*
+        * Probe for SA1111.
+        */
+       ret = sa1111_probe();
+       if (ret < 0)
+               return ret;
+
+       /*
+        * We found it.  Wake the chip up.
+        */
+       sa1111_wake();
+
        return 0;
 }
 
index e32d40c8eeb8744d2d352af4f1a6628e4ed90c7c..b5be8b8106ffe861acea6974b99097cc90dc7a15 100644 (file)
@@ -30,6 +30,8 @@ search_one_table(const struct exception_table_entry *first,
         return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
@@ -38,18 +40,24 @@ search_exception_table(unsigned long addr)
 #ifndef CONFIG_MODULES
        /* There is only the kernel to search.  */
        ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-       if (ret) return ret;
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
+       unsigned long flags;
        struct module *mp;
+
+       ret = 0;
+       spin_lock_irqsave(&modlist_lock, flags);
        for (mp = module_list; mp != NULL; mp = mp->next) {
-               if (mp->ex_table_start == NULL)
+               if (mp->ex_table_start == NULL ||
+                   !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return ret;
+               if (ret)
+                       break;
        }
+       spin_unlock_irqrestore(&modlist_lock, flags);
 #endif
 
-       return 0;
+       return ret;
 }
index 2ce96db0a047f8e04cd4db9dfa299544cb2b062f..f8f2abf8131cf455871ad80ea171a34d90402d90 100644 (file)
@@ -599,10 +599,10 @@ do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
        if (!inf->fn(addr, error_code, regs))
                return;
 bad:
-       force_sig(inf->sig, current);
        printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
                inf->name, fsr, addr);
        show_pte(current->mm, addr);
+       force_sig(inf->sig, current);
        die_if_kernel("Oops", regs, 0);
        return;
 
index d41557363e38fef27527336a98927c199db50bc3..b633a5597b5b26d0154f8b1b2ef29d9beb457e9c 100644 (file)
@@ -301,6 +301,10 @@ do_sigbus:
        tsk->thread.error_code = error_code;
        tsk->thread.trap_no = 14;
        force_sig(SIGBUS, tsk);
+#ifdef CONFIG_DEBUG_USER
+       printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n",
+               current->comm, addr, instruction_pointer(regs));
+#endif
 
        /* Kernel mode? Handle exceptions or die */
        if (user_mode(regs))
@@ -339,13 +343,10 @@ int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *reg
        if (addr < TASK_SIZE)
                return do_page_fault(addr, error_code, regs);
 
-       tsk = current;
-       mm  = tsk->active_mm;
-
        offset = __pgd_offset(addr);
 
+       pgd = cpu_get_pgd() + offset;
        pgd_k = init_mm.pgd + offset;
-       pgd   = mm->pgd + offset;
 
        if (pgd_none(*pgd_k))
                goto bad_area;
@@ -365,6 +366,9 @@ int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *reg
        return 0;
 
 bad_area:
+       tsk = current;
+       mm  = tsk->active_mm;
+
        do_bad_area(tsk, mm, addr, error_code, regs);
        return 0;
 }
index be3bb61ef17d56b823e9e2af7483988e5cc3f0b1..b2fcc416756f6639bce39781eceaf8fde0450662 100644 (file)
@@ -96,10 +96,22 @@ int do_check_pgt_cache(int low, int high)
 }
 #endif
 
+/* This is currently broken
+ * PG_skip is used on sparc/sparc64 architectures to "skip" certain
+ * parts of the address space.
+ *
+ * #define PG_skip     10
+ * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
+ *                     if (PageSkip(page)) {
+ *                             page = page->next_hash;
+ *                             if (page == NULL)
+ *                                     break;
+ *                     }
+ */
 void show_mem(void)
 {
        int free = 0, total = 0, reserved = 0;
-       int shared = 0, cached = 0, node;
+       int shared = 0, cached = 0, slab = 0, node;
 
        printk("Mem-info:\n");
        show_free_areas();
@@ -112,23 +124,13 @@ void show_mem(void)
                end  = page + NODE_DATA(node)->node_size;
 
                do {
-/* This is currently broken
- * PG_skip is used on sparc/sparc64 architectures to "skip" certain
- * parts of the address space.
- *
- * #define PG_skip     10
- * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
- *                     if (PageSkip(page)) {
- *                             page = page->next_hash;
- *                             if (page == NULL)
- *                                     break;
- *                     }
- */
                        total++;
                        if (PageReserved(page))
                                reserved++;
                        else if (PageSwapCache(page))
                                cached++;
+                       else if (PageSlab(page))
+                               slab++;
                        else if (!page_count(page))
                                free++;
                        else
@@ -140,6 +142,7 @@ void show_mem(void)
        printk("%d pages of RAM\n", total);
        printk("%d free pages\n", free);
        printk("%d reserved pages\n", reserved);
+       printk("%d slab pages\n", slab);
        printk("%d pages shared\n", shared);
        printk("%d pages swap cached\n", cached);
 #ifndef CONFIG_NO_PGT_CACHE
@@ -375,6 +378,8 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot
         */
        if (machine_is_archimedes() || machine_is_a5k())
                reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
+       if (machine_is_edb7211())
+               reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000);
        if (machine_is_p720t())
                reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000);
 #ifdef CONFIG_SA1111
@@ -471,6 +476,7 @@ void __init bootmem_init(struct meminfo *mi)
 
        if (map_pg != bootmap_pfn + bootmap_pages)
                BUG();
+
 }
 
 /*
@@ -527,6 +533,12 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
                zone_size[0] = bdata->node_low_pfn -
                                (bdata->node_boot_start >> PAGE_SHIFT);
 
+               /*
+                * If this zone has zero size, skip it.
+                */
+               if (!zone_size[0])
+                       continue;
+
                /*
                 * For each bank in this node, calculate the size of the
                 * holes.  holes = node_size - sum(bank_sizes_in_node)
@@ -598,8 +610,12 @@ void __init mem_init(void)
                create_memmap_holes(&meminfo);
 
        /* this will put all unused low memory onto the freelists */
-       for (node = 0; node < numnodes; node++)
-               totalram_pages += free_all_bootmem_node(NODE_DATA(node));
+       for (node = 0; node < numnodes; node++) {
+               pg_data_t *pgdat = NODE_DATA(node);
+
+               if (pgdat->node_size != 0)
+                       totalram_pages += free_all_bootmem_node(pgdat);
+       }
 
 #ifdef CONFIG_SA1111
        /* now that our DMA memory is actually so designated, we can free it */
diff --git a/arch/arm/mm/mm-ftvpci.c b/arch/arm/mm/mm-ftvpci.c
new file mode 100644 (file)
index 0000000..31d6194
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  linux/arch/arm/mm/mm-nexuspci.c
+ *   from linux/arch/arm/mm/mm-ebsa110.c
+ *
+ *  Copyright (C) 1998-1999 Phil Blundell
+ *  Copyright (C) 1998-1999 Russell King
+ *
+ *  Extra MM routines for the FTV/PCI architecture
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+#include <asm/mach/map.h>
+
+static struct map_desc nexuspci_io_desc[] __initdata = {
+       { INTCONT_BASE, INTCONT_START,  0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+       { PLX_BASE,     PLX_START,      0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+       { PCIO_BASE,    PLX_IO_START,   0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
+       { DUART_BASE,   DUART_START,    0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+       { STATUS_BASE,  STATUS_START,   0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+       LAST_DESC
+};
+
+void __init nexuspci_map_io(void)
+{
+       iotable_init(nexuspci_io_desc);
+}
diff --git a/arch/arm/mm/mm-nexuspci.c b/arch/arm/mm/mm-nexuspci.c
deleted file mode 100644 (file)
index 31d6194..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  linux/arch/arm/mm/mm-nexuspci.c
- *   from linux/arch/arm/mm/mm-ebsa110.c
- *
- *  Copyright (C) 1998-1999 Phil Blundell
- *  Copyright (C) 1998-1999 Russell King
- *
- *  Extra MM routines for the FTV/PCI architecture
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-
-#include <asm/mach/map.h>
-
-static struct map_desc nexuspci_io_desc[] __initdata = {
-       { INTCONT_BASE, INTCONT_START,  0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-       { PLX_BASE,     PLX_START,      0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-       { PCIO_BASE,    PLX_IO_START,   0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
-       { DUART_BASE,   DUART_START,    0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-       { STATUS_BASE,  STATUS_START,   0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-       LAST_DESC
-};
-
-void __init nexuspci_map_io(void)
-{
-       iotable_init(nexuspci_io_desc);
-}
index 8d68ebbe0215059ace74763b002ea38694341f3e..5c96ce32426368629ab586447b87a3fabf343ed2 100644 (file)
@@ -108,6 +108,7 @@ ENTRY(cpu_arm720_tlb_invalidate_page)
  * Function: arm720_data_abort ()
  *
  * Params  : r0 = address of aborted instruction
+ *         : r3 = saved SPSR
  *
  * Purpose : obtain information about current aborted instruction
  *
@@ -143,6 +144,8 @@ Ldata_simple:       mrc     p15, 0, r0, c6, c0, 0           @ get FAR
                mov     pc, lr
 
 ENTRY(cpu_arm720_data_abort)
+               tst     r3, #T_BIT
+               bne     .data_thumb_abort
                ldr     r4, [r0]                        @ read instruction causing problem
                tst     r4, r4, lsr #21                 @ C = bit 20
                sbc     r1, r1, r1                      @ r1 = C - 1
@@ -169,7 +172,7 @@ ENTRY(cpu_arm720_data_abort)
 Ldata_unknown: @ Part of jumptable
                mov     r0, r2
                mov     r1, r4
-               mov     r2, r3
+               mov     r2, sp
                bl      baddataabort
                b       ret_from_exception
 
@@ -255,6 +258,77 @@ Ldata_lateldrpostreg:
                addeq   r7, r0, r2
                b       Ldata_saver7
 
+.data_thumb_abort:
+               ldrh    r4, [r0]                        @ read instruction
+               tst     r4, r4, lsr #12                 @ C = bit 11
+               sbc     r1, r1, r1                      @ r1 = C - 1
+               and     r2, r4, #15 << 12
+               add     pc, pc, r2, lsr #10             @ lookup in table
+               nop
+
+/* 0 */                b       Ldata_unknown
+/* 1 */                b       Ldata_unknown
+/* 2 */                b       Ldata_unknown
+/* 3 */                b       Ldata_unknown
+/* 4 */                b       Ldata_unknown
+/* 5 */                b       .data_thumb_reg
+/* 6 */                b       Ldata_simple
+/* 7 */                b       Ldata_simple
+/* 8 */                b       Ldata_simple
+/* 9 */                b       Ldata_simple
+/* A */                b       Ldata_unknown
+/* B */                b       .data_thumb_pushpop
+/* C */                b       .data_thumb_ldmstm
+/* D */                b       Ldata_unknown
+/* E */                b       Ldata_unknown
+/* F */                b       Ldata_unknown
+
+.data_thumb_reg:
+               tst     r4, #1 << 9
+               beq     Ldata_simple
+               tst     r4, #1 << 10            @ If 'S' (signed) bit is set
+               movne   r1, #0                  @ it must be a load instr
+               b       Ldata_simple
+
+.data_thumb_pushpop:
+               tst     r4, #1 << 10
+               beq     Ldata_unknown
+               mov     r7, #0x11
+               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 #4
+               and     r2, r4, #0x0100                 @ catch 'R' bit for push/pop
+               add     r0, r0, r2, lsr #8
+               and     r0, r0, #15                     @ number of regs to transfer
+               ldr     r7, [sp, #13 << 2]
+               tst     r4, #1 << 11
+               addne   r7, r7, r0, lsl #2              @ increment SP if PUSH
+               subeq   r7, r7, r0, lsr #2              @ decrement SP if POP
+               str     r7, [sp, #13 << 2]
+               b       Ldata_simple
+
+.data_thumb_ldmstm:
+               mov     r7, #0x11
+               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 #4
+               and     r0, r0, #15                     @ number of regs to transfer
+               and     r5, r4, #7 << 8
+               ldr     r7, [sp, r5, lsr #6]
+               sub     r7, r7, r0, lsr #2              @ always decrement
+               str     r7, [sp, r5, lsr #6]
+               b       Ldata_simple
+
 /*
  * Function: arm720_check_bugs (void)
  *        : arm720_proc_init (void)
@@ -437,7 +511,7 @@ cpu_elf_name:       .asciz  "v4"
                .align
 
 /*
- * See /include/asm-arm for a definition of this structure.
+ * See linux/include/asm-arm/procinfo.h for a definition of this structure.
  */
        
                .section ".proc.info", #alloc, #execinstr
@@ -450,7 +524,7 @@ __arm720_proc_info:
                b       __arm720_setup                          @ cpu_flush
                .long   cpu_arch_name                           @ arch_name
                .long   cpu_elf_name                            @ elf_name
-               .long   HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT    @ elf_hwcap
+               .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT      @ elf_hwcap
                .long   cpu_arm720_info                         @ info
                .long   arm720_processor_functions
                .size   __arm720_proc_info, . - __arm720_proc_info
index 79a87f34bfa59058e1ac7fd1ebb3bc126ed6209e..4c9c0312093915633747e3d714cf1c5c68e07bf7 100644 (file)
@@ -12,13 +12,15 @@ $(TOPDIR)/include/asm-arm/mach-types.h: mach-types gen-mach-types
 
 # Generate the constants.h header file using the compiler.  We get
 # the compiler to spit out assembly code, and then mundge it into
-# what we want.
+# what we want.  We do this in several stages so make picks up on
+# any errors that occur along the way.
 
 $(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c
-       $(CC) $(CFLAGS) -S -o - getconstants.c | \
-        sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' | \
-        cat constants-hdr - > $@.tmp
-       cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp
+       $(CC) $(CFLAGS) -S -o - getconstants.c > $@.tmp.1
+       sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' $@.tmp.1 > $@.tmp.2
+       cat constants-hdr $@.tmp.2 > $@.tmp
+       cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@
+       $(RM) $@.tmp*
 
 # Build our dependencies, and then generate the constants and
 # mach-types header files.  If we do it now, mkdep will pick
index 15c762f5371d26e15f30edd718299ccf9e8bbb97..2cdbb8b9d679950dd3f22307d9abe9e6d979d86f 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 
-#ifndef __APCS_32__
-#error APCS-32 required
+/*
+ * Make sure that the compiler and target are compatible.
+ */
+#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
+#error Your compiler targets APCS-32 but this kernel requires APCS-26
+#endif
+#if defined(__APCS_26__) && defined(CONFIG_CPU_32)
+#error Your compiler targets APCS-26 but this kernel requires APCS-32
 #endif
 
 #define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
index 4903916c292569908f021202ff065e8ab4a43071..f349dd1d049d5cdde7870952031c07e35b11258d 100644 (file)
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Thu Aug 23 12:38:13 2001
+# Last update: Fri Oct 5 18:40:53 2001
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -71,7 +71,7 @@ mvi                   SA1100_MVI              MVI                     58
 jupiter                        SA1100_JUPITER          JUPITER                 59
 psionw                 ARCH_PSIONW             PSIONW                  60
 aln                    SA1100_ALN              ALN                     61
-camelot                        ARCH_CAMELOT            CAMELOT                 62
+epxa10db               ARCH_CAMELOT            CAMELOT                 62
 gds2200                        SA1100_GDS2200          GDS2200                 63
 psion_series7          SA1100_PSION_SERIES7    PSION_SERIES7           64
 xfile                  SA1100_XFILE            XFILE                   65
@@ -114,7 +114,7 @@ sa1100_elf          SA1100_SA1100_ELF       SA1100_ELF              102
 gator                  SA1100_GATOR            GATOR                   103
 granite                        ARCH_GRANITE            GRANITE                 104
 consus                 SA1100_CONSUS           CONSUS                  105
-aaec2000_aaed20                ARCH_AAEC2000_AAED2000  AAEC2000_AAED2000       106
+agilent_aaed2000       ARCH_AAEC2000_AAED2000  AAEC2000_AAED2000       106
 cdb89712               ARCH_CDB89712           CDB89712                107
 graphicsmaster         SA1100_GRAPHICSMASTER   GRAPHICSMASTER          108
 adsbitsy               SA1100_ADSBITSY         ADSBITSY                109
@@ -122,3 +122,12 @@ cotulla_idp                ARCH_COTULLA_IDP        COTULLA_IDP             110
 plce                   ARCH_PLCE               PLCE                    111
 pt_system3             SA1100_PT_SYSTEM3       PT_SYSTEM3              112
 medalb                 ARCH_MEDALB             MEDALB                  113
+eagle                  ARCH_EAGLE              EAGLE                   114
+dsc21                  ARCH_DSC21              DSC21                   115
+dsc24                  ARCH_DSC24              DSC24                   116
+ti5472                 ARCH_TI5472             TI5472                  117
+autcpu12               ARCH_AUTCPU12           AUTCPU12                118
+uengine                        ARCH_UENGINE            UENGINE                 119
+bluestem               SA1100_BLUESTEM         BLUESTEM                120
+xingu8                 ARCH_XINGU8             XINGU8                  121
+bushstb                        ARCH_BUSHSTB            BUSHSTB                 122
index 365437a082585ab3740d8328c6c90415b4c9be45..07531b806e310c5550b0a68c91f8fa7355d68eef 100644 (file)
@@ -6,6 +6,8 @@
 #include <asm/processor.h> 
 #include <asm/msr.h>
 
+static int mce_disabled __initdata = 0;
+
 /*
  *     Machine Check Handler For PII/PIII
  */
@@ -111,7 +113,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
  *     Set up machine check reporting for Intel processors
  */
 
-void __init intel_mcheck_init(struct cpuinfo_x86 *c)
+static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
@@ -130,6 +132,9 @@ void __init intel_mcheck_init(struct cpuinfo_x86 *c)
        
        if(c->x86 == 5)
        {
+               /* Default P5 to off as its often misconnected */
+               if(mce_disabled != -1)
+                       return;
                machine_check_vector = pentium_machine_check;
                wmb();
                /* Read registers before enabling */
@@ -137,11 +142,8 @@ void __init intel_mcheck_init(struct cpuinfo_x86 *c)
                rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
                if(done==0)
                        printk(KERN_INFO "Intel old style machine check architecture supported.\n");
-               /* Enable MCE */                
-               __asm__ __volatile__ (
-                       "movl %%cr4, %%eax\n\t"
-                       "orl $0x40, %%eax\n\t"
-                       "movl %%eax, %%cr4\n\t" : : : "eax");
+               /* Enable MCE */
+               set_in_cr4(X86_CR4_MCE);
                printk(KERN_INFO "Intel old style machine check reporting enabled on CPU#%d.\n", smp_processor_id());
                return;
        }
@@ -195,10 +197,7 @@ static void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
        lo|= (1<<2);    /* Enable EIERRINT (int 18 MCE) */
        lo&= ~(1<<4);   /* Enable MCE */
        wrmsr(MSR_IDT_FCR1, lo, hi);
-       __asm__ __volatile__ (
-               "movl %%cr4, %%eax\n\t"
-               "orl $0x40, %%eax\n\t"
-               "movl %%eax, %%cr4\n\t" : : : "eax");
+       set_in_cr4(X86_CR4_MCE);
        printk(KERN_INFO "Winchip machine check reporting enabled on CPU#%d.\n", smp_processor_id());
 }
 
@@ -208,11 +207,10 @@ static void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
  */
 
 
-static int mce_disabled = 0;
 
 void __init mcheck_init(struct cpuinfo_x86 *c)
 {
-       if(mce_disabled)
+       if(mce_disabled==1)
                return;
                
        switch(c->x86_vendor)
@@ -230,6 +228,8 @@ void __init mcheck_init(struct cpuinfo_x86 *c)
                case X86_VENDOR_CENTAUR:
                        winchip_mcheck_init(c);
                        break;
+               default:
+                       break;
        }
 }
 
@@ -238,4 +238,12 @@ static int __init mcheck_disable(char *str)
        mce_disabled = 1;
        return 0;
 }
+
+static int __init mcheck_enable(char *str)
+{
+       mce_disabled = -1;
+       return 0;
+}
+
 __setup("nomce", mcheck_disable);
+__setup("mce", mcheck_enable);
index 7763dc8f23af35b8c97b7b75a954e167ea7cb5a2..6fb3f91728f861ae84ad3f3daae89ab054cac8a7 100644 (file)
@@ -163,3 +163,4 @@ EXPORT_NO_SYMBOLS;
 
 MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
 MODULE_DESCRIPTION("x86 generic CPUID driver");
+MODULE_LICENSE("GPL");
index fb47c8a968f7e1a61b589c8303e39ffa2b8da402..7d0f7516d273406e771e9879a1ce7e6ec2e52815 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/keyboard.h>
 #include <asm/keyboard.h>
 
+int is_sony_vaio_laptop;
+
 struct dmi_header
 {
        u8      type;
@@ -322,8 +324,6 @@ static __init int broken_apm_power(struct dmi_blacklist *d)
  * This one isn't a bug detect for those who asked, we simply want to
  * activate Sony specific goodies like the camera and jogdial..
  */
-int is_sony_vaio_laptop;
-
 static __init int sony_vaio_laptop(struct dmi_blacklist *d)
 {
        if (is_sony_vaio_laptop == 0)
index b4f342bb521f8979895552d8105dd2a37c76f3f6..ad4adf1a8dbaa181eaf16998effe4407c497e9f8 100644 (file)
@@ -170,8 +170,5 @@ EXPORT_SYMBOL(atomic_dec_and_lock);
 EXPORT_SYMBOL(do_BUG);
 #endif
 
-#if defined(CONFIG_SONYPI) || defined(CONFIG_SONYPI_MODULE)
 extern int is_sony_vaio_laptop;
 EXPORT_SYMBOL(is_sony_vaio_laptop);
-#endif
-
index 1ac22ad542e304feef1b379e767b81ddfadc0809..3045ec13d06940586aa5b5b4c661ba32d13403d5 100644 (file)
@@ -65,6 +65,7 @@
 
 MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
+MODULE_LICENSE("GPL");
 EXPORT_NO_SYMBOLS;
 
 #define MICRO_DEBUG 0
index 3bccd43a3d387373c914f43450b4fe2c8e607c8f..feee5b67eaae5447d9e114d9bcc79df8855b250c 100644 (file)
@@ -271,3 +271,4 @@ EXPORT_NO_SYMBOLS;
 
 MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
 MODULE_DESCRIPTION("x86 generic MSR driver");
+MODULE_LICENSE("GPL");
index cfce778e51aa9003e2b18086e5ec177ddb442738..d88c7d53dfd9a60bdff6d64ad533dce93e3876eb 100644 (file)
@@ -1253,7 +1253,8 @@ int mtrr_add_page(unsigned long base, unsigned long size, unsigned int type, cha
        break;
 
     case MTRR_IF_INTEL:
-       /*  For Intel PPro stepping <= 7, must be 4 MiB aligned  */
+       /*  For Intel PPro stepping <= 7, must be 4 MiB aligned 
+           and not touch 0x70000000->0x7003FFFF */
        if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
             boot_cpu_data.x86 == 6 &&
             boot_cpu_data.x86_model == 1 &&
@@ -1264,6 +1265,12 @@ int mtrr_add_page(unsigned long base, unsigned long size, unsigned int type, cha
                printk (KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
                return -EINVAL;
            }
+           if (!(base + size < 0x70000000 || base > 0x7003FFFF) &&
+                (type == MTRR_TYPE_WRCOMB || type == MTRR_TYPE_WRBACK))
+           {
+               printk (KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
+               return -EINVAL;
+           }
        }
        /* Fall through */
        
index 0ace879ab6332cfbb0d169f0829d7d3db34680de..b1e26817642313f61f7dc2b02a4e73f6771214c8 100644 (file)
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.21 08/19/01 20:06:47 paulus
+# BK Id: SCCS/s.Makefile 1.23 09/18/01 11:19:05 paulus
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
index 9e12f97eac875f492f769532ce3312ef7f9617a7..34ac4047af826c4f15350ea8b30b5ef5bf986eb2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.config.c 1.7 05/21/01 00:48:24 cort
+ * BK Id: SCCS/s.config.c 1.12 09/18/01 11:19:06 paulus
  */
 #define m68k_debug_device debug_device
 
index b01587153c645ed8a54745acd9a80a40d0c6b4e9..b8ff918a8e1995d7db05e484ce6297a0310a5ffe 100644 (file)
@@ -55,16 +55,6 @@ drivers/s390: dummy
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
-MAKESILO = $(MAKE) -C arch/$(ARCH)/tools/silo
-
-MAKEDASDFMT = $(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
-silo:
-       @$(MAKESILO) silo
-
-dasdfmt:
-       @$(MAKEDASDFMT) dasdfmt
-
 image: vmlinux 
        @$(MAKEBOOT) image
 
index 942cec488f166f5972fbc801044a6cd1283790ee..e141521dcdebaa8ca46e0fef3eb64aa66028eddc 100644 (file)
@@ -15,7 +15,7 @@ all: kernel.o head.o init_task.o
 O_TARGET := kernel.o
 
 export-objs    := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o
-obj-y  := lowcore.o entry.o bitmap.o traps.o time.o process.o irq.o \
+obj-y  := entry.o bitmap.o traps.o time.o process.o irq.o \
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
             semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
 
index 4f0f67e351fa1bccd2c1710abbe6b3a82bccffc0..f013a5c1f99247a31a3cfefad17a28660610c874 100644 (file)
@@ -83,6 +83,9 @@ static int debug_prolog_level_fn(debug_info_t * id,
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
                                struct file *file, const char *user_buf,
                                size_t user_buf_size, loff_t * offset);
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t user_buf_size, loff_t * offset);
 static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
                                 char *out_buf, const char *in_buf);
 static int debug_raw_format_fn(debug_info_t * id,
@@ -123,6 +126,15 @@ struct debug_view debug_level_view = {
        NULL
 };
 
+struct debug_view debug_flush_view = {
+        "flush",
+        NULL,
+        NULL,
+        NULL,
+        &debug_input_flush_fn,
+        NULL
+};
+
 struct debug_view debug_sprintf_view = {
        "sprintf",
        NULL,
@@ -664,6 +676,7 @@ debug_info_t *debug_register
        if(!rc) 
                goto out;
        debug_register_view(rc, &debug_level_view);
+        debug_register_view(rc, &debug_flush_view);
        printk(KERN_INFO
               "debug: reserved %d areas of %d pages for debugging %s\n",
               nr_areas, 1 << page_order, rc->name);
@@ -1029,6 +1042,73 @@ static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
        return rc;              /* number of input characters */
 }
 
+
+/*
+ * flushes debug areas
+ */
+void debug_flush(debug_info_t* id, int area)
+{
+        unsigned long flags;
+        int i;
+
+        if(!id)
+                return;
+        spin_lock_irqsave(&id->lock,flags);
+        if(area == DEBUG_FLUSH_ALL){
+                id->active_area = 0;
+                memset(id->active_entry, 0, id->nr_areas * sizeof(int));
+                for (i = 0; i < id->nr_areas; i++) 
+                        memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
+        } else if(area >= 0 && area < id->nr_areas) {
+                id->active_entry[area] = 0;
+                memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO
+                        "debug: %s: area %i has been flushed\n",
+                        id->name, area);
+        } else {
+                printk(KERN_INFO
+                        "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
+                        id->name, area, 0, id->nr_areas-1);
+        }
+        spin_unlock_irqrestore(&id->lock,flags);
+}
+
+/*
+ * view function: flushes debug areas 
+ */
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t in_buf_size, loff_t * offset)
+{
+        char input_buf[1];
+        int rc = in_buf_size;
+        if (*offset != 0)
+                goto out;
+        if (copy_from_user(input_buf, user_buf, 1)){
+                rc = -EFAULT;
+                goto out;
+        }
+        if(input_buf[0] == '-') { 
+                debug_flush(id, DEBUG_FLUSH_ALL);
+                goto out;
+        }
+        if (isdigit(input_buf[0])) {
+                int area = ((int) input_buf[0] - (int) '0');
+                debug_flush(id, area);
+                goto out;
+        }
+
+        printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
+
+      out:
+        *offset += in_buf_size;
+        return rc;              /* number of input characters */
+}
+
 /*
  * prints debug header in raw format
  */
index e97338a3404182bce2441672f1d53b7d1daace91..f4beccc0894189893f6dc91cd5c6fd5143096192 100644 (file)
@@ -97,17 +97,27 @@ entry_base:
  *    R15 - kernel stack pointer
  */
 
-        .macro  SAVE_ALL psworg           # system entry macro
+        .macro  SAVE_ALL psworg,sync      # system entry macro
         stm     %r13,%r15,__LC_SAVE_AREA
-        stam    %a2,%a4,__LC_SAVE_AREA+12
         basr    %r13,0                    #  temp base pointer
         l       %r13,.Lentry_base-.(%r13) # load &entry_base to %r13 
         tm      \psworg+1,0x01            # test problem state bit
-        bz      BASED(.+12)               # skip stack setup save
-        l       %r15,__LC_KERNEL_STACK    # problem state -> load ksp
-        lam     %a2,%a4,BASED(.Lc_ac)     # set ac.reg. 2 to primary space
-                                          # and access reg. 4 to home space
-0:      s       %r15,BASED(.Lc_spsize)    # make room for registers & psw
+        stam    %a2,%a4,__LC_SAVE_AREA+12
+       .if     \sync
+        bz      BASED(1f)                 # skip stack setup save
+       .else
+        bnz     BASED(0f)                 # from user -> load kernel stack
+       l       %r14,__LC_ASYNC_STACK     # are we already on the async stack ?
+       slr     %r14,%r15
+       sra     %r14,13
+       be      BASED(1f)
+        l       %r15,__LC_ASYNC_STACK     # load async. stack
+       b       BASED(1f)
+       .endif
+0:      l       %r15,__LC_KERNEL_STACK    # problem state -> load ksp
+       lam     %a2,%a4,BASED(.Lc_ac)     # set ac.reg. 2 to primary space
+                                         # and ac.reg. 4 to home space
+1:      s       %r15,BASED(.Lc_spsize)    # make room for registers & psw
         n       %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
         stm     %r0,%r12,SP_R0(%r15)      # store gprs 0-12 to kernel stack
         st      %r2,SP_ORIG_R2(%r15)      # store original content of gpr 2
@@ -120,7 +130,7 @@ entry_base:
         xc      0(4,%r15),0(%r15)         # clear back chain
         .endm
 
-        .macro  RESTORE_ALL               # system exit macro
+        .macro  RESTORE_ALL sync          # system exit macro
         mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)  # move user PSW to lowcore
         lam     %a0,%a15,SP_AREGS(%r15)   # load the access registers
         lm      %r0,%r15,SP_R0(%r15)      # load gprs 0-15 of user
@@ -129,8 +139,8 @@ entry_base:
         .endm
 
         .macro  GET_CURRENT
-        lr      %r9,%r15                  # load pointer to task_struct to %r9
-        n       %r9,BASED(.Lc0xffffe000)
+       l       %r9,BASED(.Lc0xffffe000)  # load pointer to task_struct to %r9
+       al      %r9,__LC_KERNEL_STACK
         .endm
 
 
@@ -170,6 +180,28 @@ resume_noper:
         lm      %r6,%r15,24(%r15)       # load resume registers of next task
         br      %r14
 
+/*
+ * do_softirq calling function. We want to run the softirq functions on the
+ * asynchronous interrupt stack.
+ */
+       .global do_call_softirq
+do_call_softirq:
+       stm     %r12,%r15,24(%r15)
+       lr      %r12,%r15
+        basr    %r13,0
+do_call_base:
+       l       %r0,__LC_ASYNC_STACK
+       slr     %r0,%r15
+       sra     %r0,13
+       be      0f-do_call_base(%r13)
+       l       %r15,__LC_ASYNC_STACK
+0:     sl      %r15,.Lc_overhead-do_call_base(%r13)
+        st     %r12,0(%r15)    # store backchain
+       l       %r1,.Ldo_softirq-do_call_base(%r13)
+       basr    %r14,%r1
+       lm      %r12,%r15,24(%r12)
+       br      %r14
+       
 /*
  * SVC interrupt handler routine. System calls are synchronous events and
  * are executed with interrupts enabled.
@@ -177,7 +209,7 @@ resume_noper:
 
        .globl  system_call
 system_call:
-        SAVE_ALL __LC_SVC_OLD_PSW
+        SAVE_ALL __LC_SVC_OLD_PSW,1
        mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
 pgm_system_call:       
         GET_CURRENT               # load pointer to task_struct to R9
@@ -207,7 +239,7 @@ sysc_leave:
        tm      SP_PGM_OLD_ILC(%r15),0xff
         bz      BASED(pgm_svcret)
        stnsm   24(%r15),0xfc            # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 1
 
 #
 # call do_signal before return
@@ -557,7 +589,10 @@ sys_call_table:
         .long  sys_madvise
        .long  sys_getdents64            /* 220 */
         .long  sys_fcntl64 
-       .rept  255-221
+       .long  sys_ni_syscall            /* 222 - reserved for posix_acl */
+       .long  sys_ni_syscall            /* 223 - reserved for posix_acl */
+       .long  sys_ni_syscall            /* 224 - reserved for posix_acl */
+       .rept  255-224
        .long  sys_ni_syscall
        .endr
 
@@ -581,10 +616,10 @@ pgm_check_handler:
  * for LPSW?).
  */
        stm     %r13,%r15,__LC_SAVE_AREA
-       stam    %a2,%a4,__LC_SAVE_AREA+12
        basr    %r13,0                   # temp base pointer
        l       %r13,.Lentry_base-.(%r13)# load &entry_base to %r13
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
+       stam    %a2,%a4,__LC_SAVE_AREA+12
         bz      BASED(pgm_sv)            # skip if not
         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
         bnz     BASED(pgm_sv)            # skip if it is
@@ -677,7 +712,7 @@ pgm_return:
 
         .globl io_int_handler
 io_int_handler:
-        SAVE_ALL __LC_IO_OLD_PSW
+        SAVE_ALL __LC_IO_OLD_PSW,0
         GET_CURRENT               # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15) # address of register-save area
         sr      %r3,%r3
@@ -710,7 +745,7 @@ io_return_bh:
         bnz     BASED(io_signal_return)
 io_leave:
         stnsm   24(%r15),0xfc            # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #
 # call do_softirq
@@ -744,7 +779,7 @@ io_signal_return:
 
         .globl  ext_int_handler
 ext_int_handler:
-        SAVE_ALL __LC_EXT_OLD_PSW
+        SAVE_ALL __LC_EXT_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
         lh      %r3,__LC_EXT_INT_CODE  # error code
@@ -772,11 +807,11 @@ ext_int_found:
 
         .globl mcck_int_handler
 mcck_int_handler:
-        SAVE_ALL __LC_MCK_OLD_PSW
+        SAVE_ALL __LC_MCK_OLD_PSW,0
        l       %r1,BASED(.Ls390_mcck)
        basr    %r14,%r1          # call machine check handler
 mcck_return:
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #ifdef CONFIG_SMP
 /*
@@ -784,7 +819,7 @@ mcck_return:
  */
         .globl restart_int_handler
 restart_int_handler:
-        l       %r15,__LC_KERNEL_STACK # load ksp
+        l       %r15,__LC_SAVE_AREA+60 # load ksp
         lctl    %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
         lam     %a0,%a15,__LC_AREGS_SAVE_AREA
         stosm   0(%r15),0x04           # now we can turn dat on
@@ -817,6 +852,7 @@ restart_go:
 .Lc0xffffe000: .long  -8192        # to round stack pointer to &task_struct
 .Lc8191:       .long  8191
 .Lc_spsize:    .long  SP_SIZE
+.Lc_overhead:  .long  STACK_FRAME_OVERHEAD
 .Lc_ac:        .long  0,0,1
 .Lc_ENOSYS:    .long  -ENOSYS
 .Lc4:          .long  4
index 06e3adbb069ba314f78fb7835f30fed7709c27be..b82c6717692807e2aee541fd89201730f363f92f 100644 (file)
@@ -65,7 +65,8 @@
  * $m0,10#2a               +$00010203040506070809101112131415#42
  *
  */
-
+#define TRUE 1
+#define FALSE 0
 #include <asm/gdb-stub.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
+#include <linux/stddef.h>
 
+#define S390_REGS_COMMON_SIZE offsetof(struct gdb_pt_regs,orig_gpr2)
 
 /*
  * external low-level support routines
  */
 
-extern int putDebugChar(char c);    /* write a single character      */
-extern char getDebugChar(void);     /* read and return a single char */
+
 extern void fltr_set_mem_err(void);
 extern void trap_low(void);
 
@@ -247,8 +249,10 @@ static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
 
        while (count-- > 0) {
                ch = *(mem++);
+#if 0
                if (mem_err)
                        return 0;
+#endif
                *buf++ = hexchars[ch >> 4];
                *buf++ = hexchars[ch & 0xf];
        }
@@ -276,8 +280,10 @@ static char *hex2mem(char *buf, char *mem, int count, int may_fault)
                ch = hex(*buf++) << 4;
                ch |= hex(*buf++);
                *(mem++) = ch;
+#if 0
                if (mem_err)
                        return 0;
+#endif
        }
 
 /*     set_mem_fault_trap(0); */
@@ -349,7 +355,7 @@ static int hexToInt(char **ptr, int *intValue)
        return (numChars);
 }
 
-void gdb_stub_get_non_pt_regs(gdb_pt_regs *regs)
+void gdb_stub_get_non_pt_regs(struct gdb_pt_regs *regs)
 {
        s390_fp_regs *fpregs=&regs->fp_regs;
        int has_ieee=save_fp_regs1(fpregs);
@@ -365,7 +371,7 @@ void gdb_stub_get_non_pt_regs(gdb_pt_regs *regs)
        }
 }
 
-void gdb_stub_set_non_pt_regs(gdb_pt_regs *regs)
+void gdb_stub_set_non_pt_regs(struct gdb_pt_regs *regs)
 {
        restore_fp_regs1(&regs->fp_regs);
 }
@@ -390,7 +396,7 @@ void gdb_stub_send_signal(int sigval)
  * returns 1 if you should skip the instruction at the trap address, 0
  * otherwise.
  */
-void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
+void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval)
 {
        int trap;                       /* Trap type */
        int addr;
@@ -402,19 +408,23 @@ void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
        /*
         * reply to host that an exception has occurred
         */
+#if 0
        send_signal(sigval);
-
+#endif
        /*
         * Wait for input from remote GDB
         */
-       while (1) {
+       while (1) 
+       {
                output_buffer[0] = 0;
                getpacket(input_buffer);
 
                switch (input_buffer[0])
                {
                case '?':
+#if 0
                        send_signal(sigval);
+#endif
                        continue;
 
                case 'd':
@@ -427,9 +437,9 @@ void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
                case 'g':
                        gdb_stub_get_non_pt_regs(regs);
                        ptr = output_buffer;
-                       ptr=  mem2hex((char *)regs,ptr,sizeof(s390_regs_common),FALSE);
+                       ptr=  mem2hex((char *)regs,ptr,S390_REGS_COMMON_SIZE,FALSE);
                        ptr=  mem2hex((char *)&regs->crs[0],ptr,NUM_CRS*CR_SIZE,FALSE);
-                       ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs));
+                       ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs),FALSE);
                        break;
          
                /*
@@ -438,11 +448,11 @@ void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
                 */
                case 'G':
                        ptr=input_buffer;
-                       hex2mem (ptr, (char *)regs,sizeof(s390_regs_common), FALSE);
-                       ptr+=sizeof(s390_regs_common)*2;
+                       hex2mem (ptr, (char *)regs,S390_REGS_COMMON_SIZE, FALSE);
+                       ptr+=S390_REGS_COMMON_SIZE*2;
                        hex2mem (ptr, (char *)regs->crs[0],NUM_CRS*CR_SIZE, FALSE);
                        ptr+=NUM_CRS*CR_SIZE*2;
-                       hex2mem (ptr, (char *)regs->fp_regs,sizeof(s390_fp_regs), FALSE);
+                       hex2mem (ptr, (char *)&regs->fp_regs,sizeof(s390_fp_regs), FALSE);
                        gdb_stub_set_non_pt_regs(regs);
                        strcpy(output_buffer,"OK");
                break;
@@ -472,7 +482,8 @@ void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
                        if (hexToInt(&ptr, &addr)
                                && *ptr++ == ','
                                && hexToInt(&ptr, &length)
-                               && *ptr++ == ':') {
+                               && *ptr++ == ':') 
+                       {
                                if (hex2mem(ptr, (char *)addr, length, 1))
                                        strcpy(output_buffer, "OK");
                                else
@@ -490,8 +501,7 @@ void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
 
                        ptr = &input_buffer[1];
                        if (hexToInt(&ptr, &addr))
-                               regs->cp0_epc = addr;
-         
+                               regs->psw.addr = addr;
                        /*
                         * Need to flush the instruction cache here, as we may
                         * have deposited a breakpoint, and the icache probably
@@ -529,22 +539,22 @@ void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
                         * There is no single step insn in the MIPS ISA, so we
                         * use breakpoints and continue, instead.
                         */
+#if 0
                        single_step(regs);
+#endif
                        flush_cache_all();
                        return;
                        /* NOTREACHED */
+                       break;
 
-               }
-               break;
-
-               }                       /* switch */
-
-               /*
-                * reply to the request
-                */
+               }      /* switch */
 
+       /*
+        * reply to the request
+        */
+       
                putpacket(output_buffer);
-
+       
        } /* while */
 }
 
@@ -558,13 +568,9 @@ void breakpoint(void)
 {
        if (!gdb_stub_initialised)
                return;
-       __asm__ __volatile__(
-                       ".globl breakinst\n"
-                       "breakinst:\t.word   %0\n\t"
-                       :
-                       : "i" (S390_BREAKPOINT_U16)
-                               :
-                               );
+       asm volatile (".globl   breakinst\n"
+               "breakinst:\t.word   %0"
+               : : "i" (S390_BREAKPOINT_U16) );
 }
 
 
index 746e4a0cefb661a53504cfdaa2c8dd15c85cffaf..21f035d4195daa2e0a6f42c1595af160e206cd15 100644 (file)
@@ -461,28 +461,52 @@ start:
         .org  0x10000
 startup:basr  %r13,0                     # get base
 .LPG1:  lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
-       la    %r12,parmarea-.LPG1(%r13)  # pointer to parameter area
+       la    %r12,_pstart-.LPG1(%r13)   # pointer to parameter area
                                         # move IPL device to lowcore
         mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
        
 #
-# find out memory size.
+# find memory chunks.
 #
        mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
-        lhi   %r2,1
-        sll   %r2,17                     # test in increments of 128KB
-       lr    %r1,%r2
-       ahi   %r1,-4                     # test last word in the segment
-.Lloop:        
-       l     %r0,0(%r1)                 # test 128KB segment
-       st    %r0,0(%r1)
-       ar    %r1,%r2                    # add 128KB
-       bnm   .Lloop-.LPG1(%r13)         # r1 < 0x80000000 -> loop
-.Lchkmem:
-       n     %r1,.L4malign-.LPG1(%r13)  # align to multiples of 4M
-        l     %r2,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
-       st    %r1,0(%r2)                 # store memory size
-
+       la    %r1,1                      # test in increments of 128KB
+       sll   %r1,17
+       l     %r3,.Lmchunk-.LPG1(%r13)   # get pointer to memory_chunk array
+       slr   %r4,%r4                    # set start of chunk to zero
+       slr   %r5,%r5                    # set end of chunk to zero
+       slr   %r6,%r6                    # set access code to zero
+.Lloop:
+       tprot 0(%r5),0                   # test protection of first byte
+       ipm   %r7
+       srl   %r7,28
+       clr   %r6,%r7                    # compare cc with last access code
+       be    .Lsame-.LPG1(%r13)
+       clr   %r4,%r5                    # chunk size > 0?
+       be    .Lsize0-.LPG1(%r13)
+       st    %r4,0(%r3)                 # store start address of chunk
+       lr    %r0,%r5
+       slr   %r0,%r4
+       st    %r0,4(%r3)                 # store size of chunk
+       st    %r6,8(%r3)                 # store type of chunk
+       la    %r3,12(%r3)
+       lr    %r4,%r5                    # set start to end
+.Lsize0:
+       lr    %r6,%r7                    # set access code to last cc
+.Lsame:
+       ar    %r5,%r1                    # add 128KB to end of chunk
+       bno   .Lloop-.LPG1(%r13)         # r1 < 0x80000000 -> loop
+.Lchkmem:                               # > 2GB or tprot got a program check
+       clr   %r4,%r5                    # chunk size > 0?
+       be    .Ldonemem-.LPG1(%r13)
+       st    %r4,0(%r3)                 # store start address of chunk
+       lr    %r0,%r5
+       slr   %r0,%r4
+       st    %r0,4(%r3)                 # store size of chunk
+       st    %r6,8(%r3)                 # store type of chunk
+.Ldonemem:             
+        l     %r1,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
+       st    %r5,0(%r1)                 # store last end to memory size
+       
         l      %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
 #
 # find out if we are running under VM
@@ -534,7 +558,7 @@ startup:basr  %r13,0                     # get base
 .Lentry:.long  0x00080000,0x80000000 + _stext
 .Lctl:  .long  0x04b50002               # cr0: various things
         .long  0                        # cr1: primary space segment table
-        .long  0                        # cr2: access register translation
+        .long  .Lduct                   # cr2: dispatchable unit control table
         .long  0                        # cr3: instruction authorization
         .long  0                        # cr4: instruction authorization
         .long  0                        # cr5:  various things
@@ -552,47 +576,50 @@ startup:basr  %r13,0                     # get base
 .Lpcfpu:.long  0x00080000,0x80000000 + .Lchkfpu
 .Lpccsp:.long  0x00080000,0x80000000 + .Lchkcsp
 .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
-.L4malign:.long 0xffc00000
 .Lmemsize:.long memory_size
+.Lmchunk:.long memory_chunk
 .Lmflags:.long machine_flags
 
+       .org PARMAREA-64
+.Lduct:        .long 0,0,0,0,0,0,0,0
+       .long 0,0,0,0,0,0,0,0
+
 #
 # params at 10400 (setup.h)
 #
        .org   PARMAREA
-parmarea:      
+       .global _pstart
+_pstart:       
         .long  0,0                      # IPL_DEVICE
         .long  0,RAMDISK_ORIGIN         # INITRD_START
-        .long  0,0x800000               # INITRD_SIZE
+        .long  0,RAMDISK_SIZE           # INITRD_SIZE
 
         .org   COMMAND_LINE
        .byte  "root=/dev/ram0 ro"
         .byte  0
+       .org   0x11000
+       .global _pend
+_pend: 
 
-#
-# startup-code, running in virtual mode
-#
 #ifdef CONFIG_SHARED_KERNEL
        .org   0x100000
-#else
-        .org   0x10800
 #endif
+
+#
+# startup-code, running in virtual mode
+#
         .globl _stext
 _stext:        basr  %r13,0                    # get base
 .LPG2:
 #
-# Setup lowcore
+# Setup stack
 #
-        l     %r1,__LC_IPLDEV           # load ipl device number
-        spx   .Lprefix-.LPG2(%r13)      # set prefix to linux lowcore
-        st    %r1,__LC_IPLDEV           # store ipl device number
         l     %r15,.Linittu-.LPG2(%r13)
-        ahi   %r15,8192                 # init_task_union + 8191
+        ahi   %r15,8192                 # init_task_union + 8192
         st    %r15,__LC_KERNEL_STACK    # set end of kernel stack
         ahi   %r15,-96
         xc    0(4,%r15),0(%r15)         # set backchain to zero
-        lhi   %r0,-1
-        st    %r0,__LC_KERNEL_LEVEL     # set interrupt count to -1
+
 #
 # clear bss memory
 #
@@ -622,7 +649,6 @@ _stext:     basr  %r13,0                    # get base
 #
             .align 8
 .Ldw:      .long  0x000a0000,0x00000000
-.Lprefix:   .long  init_S390_lowcore   
 .Linittu:   .long  init_task_union
 .Lstart:    .long  start_kernel
 .Lbss_bgn:  .long  __bss_start
diff --git a/arch/s390/kernel/lowcore.S b/arch/s390/kernel/lowcore.S
deleted file mode 100644 (file)
index b5c1c6b..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  arch/s390/kernel/lowcore.S
- *    S390 lowcore definition.
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hp@de.ibm.com)
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- */
-
-#include <asm/lowcore.h>
-         .align 4096
-         .globl init_S390_lowcore
-init_S390_lowcore:      
-         .long  _RESTART_PSW_MASK
-         .long  restart_int_handler + _ADDR_31
-         .long  0,0
-         .long  0,0
-EXT_OLD: .long  0,0
-SVC_OLD: .long  0,0
-PGM_OLD: .long  0,0
-MCCK_OLD:.long  0,0
-IO_OLD:  .long  0,0
-         .long  0,0,0,0,0,0
-#
-# new psws need all to be physical
-# because we start with dat off
-#
-EXT_PSW: .long  _EXT_PSW_MASK
-         .long  ext_int_handler + _ADDR_31
-#
-SVC_PSW: .long  _SVC_PSW_MASK
-         .long  system_call + _ADDR_31
-#
-PGM_PSW: .long  _PGM_PSW_MASK
-         .long  pgm_check_handler + _ADDR_31
-#
-MCCK_PSW:.long  _MCCK_PSW_MASK
-         .long  mcck_int_handler + _ADDR_31
-#
-IO_PSW:  .long  _IO_PSW_MASK
-         .long  io_int_handler + _ADDR_31
-#
-#
-#
-EXTERNAL_PARAMETER:     .long  0
-CPU_ADDRESS:            .word 0
-EXT_INTERRUPT_CODE:     .word 0
-SVC_ILC:                .word 0
-SVC_CODE:               .word 0
-PGM_ILC:                .word 0
-PGM_CODE:               .word 0
-TRANS_EXC_ADDR:         .long  0                         # 090
-                        .fill 0xC00-0x094,1,0
-SAVE_AREA:              .fill 0x40,1,0                   # C00
-KERNEL_STACK:           .long 0                          # C40
-KERNEL_LEVEL:           .long 0                          # C44
-CPUID:                  .long 0,0                        # C48
-                        .fill 0x1000-0xC50,1,0
-
index 368ed1da536ebb23ab57e850097fec49d5811946..13f9ab1f270954de84fcddd53273bf1bdccb8636 100644 (file)
@@ -44,8 +44,6 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
-
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 /*
@@ -209,7 +207,7 @@ static int sprintf_regs(int line, char *buff, struct task_struct *task, struct p
 void show_regs(struct pt_regs *regs)
 {
        char buff[80];
-       int line;
+       int i, line;
 
         printk("CPU:    %d\n",smp_processor_id());
         printk("Process %s (pid: %d, stackpage=%08X)\n",
@@ -217,6 +215,17 @@ void show_regs(struct pt_regs *regs)
        
        for (line = 0; sprintf_regs(line, buff, current, regs); line++)
                printk(buff);
+
+       if (regs->psw.mask & PSW_PROBLEM_STATE)
+       {
+               printk("User Code:\n");
+               memset(buff, 0, 20);
+               copy_from_user(buff,
+                              (char *) (regs->psw.addr & PSW_ADDR_MASK), 20);
+               for (i = 0; i < 20; i++)
+                       printk("%02x ", buff[i]);
+               printk("\n");
+       }
 }
 
 char *task_show_regs(struct task_struct *task, char *buffer)
@@ -324,28 +333,19 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
 
 asmlinkage int sys_fork(struct pt_regs regs)
 {
-        int ret;
-
-        lock_kernel();
-        ret = do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
 }
 
 asmlinkage int sys_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-        int ret;
 
-        lock_kernel();
         clone_flags = regs.gprs[3];
         newsp = regs.orig_gpr2;
         if (!newsp)
                 newsp = regs.gprs[15];
-        ret = do_fork(clone_flags, newsp, &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(clone_flags, newsp, &regs, 0);
 }
 
 /*
index 0cc338382e03797d6a2065eae4168ca3794b72b4..3cc63c67f509d1e323edc77391f0936a6eafcf50 100644 (file)
 /*
  * memory management
  */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(__copy_from_user_fixup);
-EXPORT_SYMBOL(__copy_to_user_fixup);
+EXPORT_SYMBOL_NOVERS(_oi_bitmap);
+EXPORT_SYMBOL_NOVERS(_ni_bitmap);
+EXPORT_SYMBOL_NOVERS(_zb_findmap);
+EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup);
+EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);
 
 /*
  * semaphore ops
@@ -56,10 +56,7 @@ EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(csum_fold);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
+EXPORT_SYMBOL_NOVERS(do_call_softirq);
 
-#if CONFIG_IP_MULTICAST
-/* Required for lcs gigabit ethernet multicast support */
-EXPORT_SYMBOL(arp_mc_map);
-#endif
 
 
index 82eacdd3911a887418ddb69a6c0fb7edbe40e8be..981027de04bfe5ced2d44b2e4deabc73a37b05d0 100644 (file)
@@ -47,6 +47,9 @@ unsigned int console_mode = 0;
 unsigned int console_device = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
+struct { unsigned long addr, size, type; } memory_chunk[16];
+#define CHUNK_READ_WRITE 0
+#define CHUNK_READ_ONLY 1
 __u16 boot_cpu_addr;
 int cpus_initialized = 0;
 unsigned long cpu_initialized = 0;
@@ -258,6 +261,8 @@ void machine_power_off(void)
  * Setup function called from init/main.c just after the banner
  * was printed.
  */
+extern char _pstart, _pend, _stext;
+
 void __init setup_arch(char **cmdline_p)
 {
         unsigned long bootmap_size;
@@ -267,18 +272,13 @@ void __init setup_arch(char **cmdline_p)
        unsigned long start_pfn, end_pfn;
         static unsigned int smptrap=0;
         unsigned long delay = 0;
+       struct _lowcore *lowcore;
+       int i;
 
         if (smptrap)
                 return;
         smptrap=1;
 
-        /*
-         * Setup lowcore information for boot cpu
-         */
-        cpu_init();
-        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-        __cpu_logical_map[0] = boot_cpu_addr;
-
         /*
          * print what head.S has found out about the machine 
          */
@@ -291,7 +291,7 @@ void __init setup_arch(char **cmdline_p)
 
         ROOT_DEV = to_kdev_t(0x0100);
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
-       memory_end = memory_size;
+       memory_end = memory_size & ~0x400000UL;  /* align memory end to 4MB */
         /*
          * We need some free virtual space to be able to do vmalloc.
          * On a machine with 2GB memory we make sure that we have at
@@ -373,10 +373,25 @@ void __init setup_arch(char **cmdline_p)
        bootmap_size = init_bootmem(start_pfn, end_pfn);
 
        /*
-        * Register RAM pages with the bootmem allocator.
+        * Register RAM areas with the bootmem allocator.
         */
-       free_bootmem(start_pfn << PAGE_SHIFT, 
-                    (end_pfn - start_pfn) << PAGE_SHIFT);
+       for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+               unsigned long start_chunk, end_chunk;
+
+               if (memory_chunk[i].type != CHUNK_READ_WRITE)
+                       continue;
+               start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1);
+               start_chunk >>= PAGE_SHIFT;
+               end_chunk = (memory_chunk[i].addr + memory_chunk[i].size);
+               end_chunk >>= PAGE_SHIFT;
+               if (start_chunk < start_pfn)
+                       start_chunk = start_pfn;
+               if (end_chunk > end_pfn)
+                       end_chunk = end_pfn;
+               if (start_chunk < end_chunk)
+                       free_bootmem(start_chunk << PAGE_SHIFT,
+                                    (end_chunk - start_chunk) << PAGE_SHIFT);
+       }
 
         /*
          * Reserve the bootmem bitmap itself as well. We do this in two
@@ -401,6 +416,36 @@ void __init setup_arch(char **cmdline_p)
         }
 #endif
 
+        /*
+         * Setup lowcore for boot cpu
+         */
+       lowcore = (struct _lowcore *)
+               __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+       memset(lowcore, 0, PAGE_SIZE);
+       lowcore->restart_psw.mask = _RESTART_PSW_MASK;
+       lowcore->restart_psw.addr = _ADDR_31 + (addr_t) &restart_int_handler;
+       lowcore->external_new_psw.mask = _EXT_PSW_MASK;
+       lowcore->external_new_psw.addr = _ADDR_31 + (addr_t) &ext_int_handler;
+       lowcore->svc_new_psw.mask = _SVC_PSW_MASK;
+       lowcore->svc_new_psw.addr = _ADDR_31 + (addr_t) &system_call;
+       lowcore->program_new_psw.mask = _PGM_PSW_MASK;
+       lowcore->program_new_psw.addr = _ADDR_31 + (addr_t) &pgm_check_handler;
+        lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK;
+       lowcore->mcck_new_psw.addr = _ADDR_31 + (addr_t) &mcck_int_handler;
+       lowcore->io_new_psw.mask = _IO_PSW_MASK;
+       lowcore->io_new_psw.addr = _ADDR_31 + (addr_t) &io_int_handler;
+       lowcore->ipl_device = S390_lowcore.ipl_device;
+       lowcore->kernel_stack = ((__u32) &init_task_union) + 8192;
+       lowcore->async_stack = (__u32)
+               __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0) + 8192;
+       set_prefix((__u32) lowcore);
+        cpu_init();
+        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+        __cpu_logical_map[0] = boot_cpu_addr;
+
+       /*
+        * Create kernel page tables and switch to virtual addressing.
+        */
         paging_init();
 
        res = alloc_bootmem_low(sizeof(struct resource));
@@ -433,30 +478,49 @@ void print_cpu_info(struct cpuinfo_S390 *cpuinfo)
 }
 
 /*
- *     Get CPU information for use by the procfs.
+ * get_cpuinfo - Get information on one CPU for use by procfs.
+ *
+ *     Prints info on the next CPU into buffer.  Beware, doesn't check for
+ *     buffer overflow.  Current implementation of procfs assumes that the
+ *     resulting data is <= 1K.
+ *
+ * Args:
+ *     buffer  -- you guessed it, the data buffer
+ *     cpu_np  -- Input: next cpu to get (start at 0).  Output: Updated.
+ *
+ *     Returns number of bytes written to buffer.
  */
 
-int get_cpuinfo(char * buffer)
+int get_cpuinfo(char *buffer, unsigned *cpu_np)
 {
         struct cpuinfo_S390 *cpuinfo;
         char *p = buffer;
-        int i;
-
-        p += sprintf(p,"vendor_id       : IBM/S390\n"
-                       "# processors    : %i\n"
-                       "bogomips per cpu: %lu.%02lu\n",
-                       smp_num_cpus, loops_per_jiffy/(500000/HZ),
-                       (loops_per_jiffy/(5000/HZ))%100);
-        for (i = 0; i < smp_num_cpus; i++) {
-                cpuinfo = &safe_get_cpu_lowcore(i).cpu_data;
-                p += sprintf(p,"processor %i: "
-                               "version = %02X,  "
-                               "identification = %06X,  "
-                               "machine = %04X\n",
-                               i, cpuinfo->cpu_id.version,
-                               cpuinfo->cpu_id.ident,
-                               cpuinfo->cpu_id.machine);
-        }
+       unsigned n;
+
+       n = *cpu_np;
+       while (n < NR_CPUS && (cpu_online_map & (1 << n)) == 0)
+               n++;
+       if (n >= NR_CPUS) {
+               *cpu_np = NR_CPUS;
+               return (0);
+       }
+       *cpu_np = n + 1;
+
+       if (n == 0) {
+               p += sprintf(p,"vendor_id       : IBM/S390\n"
+                              "# processors    : %i\n"
+                              "bogomips per cpu: %lu.%02lu\n",
+                              smp_num_cpus, loops_per_jiffy/(500000/HZ),
+                              (loops_per_jiffy/(5000/HZ))%100);
+       }
+       cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
+       p += sprintf(p,"processor %i: "
+                      "version = %02X,  "
+                      "identification = %06X,  "
+                      "machine = %04X\n",
+                      n, cpuinfo->cpu_id.version,
+                      cpuinfo->cpu_id.ident,
+                      cpuinfo->cpu_id.machine);
         return p - buffer;
 }
 
index e9068cb91ff475990bd116e71599f7aeee82b175..3d2d8f88923d29445a5dc1d60d99e0b1dc5ada1a 100644 (file)
@@ -12,6 +12,7 @@
  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
+#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 
-#define DEBUG_SIG 0
-
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/* pretcode & sig are used to store the return addr on Intel
-   & the signal no as the first parameter we do this differently
-   using gpr14 & gpr2. */
-
-#define SIGFRAME_COMMON \
-__u8     callee_used_stack[__SIGNAL_FRAMESIZE]; \
-struct sigcontext sc; \
-_sigregs sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
 
 typedef struct 
 {
-       SIGFRAME_COMMON
+       __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+       struct sigcontext sc;
+       _sigregs sregs;
+       __u8 retcode[S390_SYSCALL_SIZE];
 } sigframe;
 
 typedef struct 
 {
-       SIGFRAME_COMMON
+       __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+       __u8 retcode[S390_SYSCALL_SIZE];
        struct siginfo info;
        struct ucontext uc;
 } rt_sigframe;
@@ -205,7 +200,7 @@ static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs)
        err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
        if(!err)
        {
-               regs->orig_gpr2 = -1;           /* disable syscall checks */
+               regs->trap = -1;                /* disable syscall checks */
                regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
                (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
                regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
@@ -217,53 +212,51 @@ static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs)
        return(err);
 }
 
-static int
-restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
-                _sigregs *sregs,sigset_t *set)
-{
-       unsigned int err;
-
-       err=restore_sigregs(regs,sregs);
-       if(!err)
-               err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE);
-               return(err);
-}
-
-int sigreturn_common(struct pt_regs *regs,int framesize)
+asmlinkage long sys_sigreturn(struct pt_regs *regs)
 {
        sigframe *frame = (sigframe *)regs->gprs[15];
        sigset_t set;
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-               return -1;
-       if (restore_sigcontext(&frame->sc,regs,&frame->sregs,&set))
-               return -1;
+               goto badframe;
+       if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
+               goto badframe;
+
        sigdelsetmask(&set, ~_BLOCKABLE);
        spin_lock_irq(&current->sigmask_lock);
        current->blocked = set;
        recalc_sigpending(current);
        spin_unlock_irq(&current->sigmask_lock);
-       return 0;
-}
-
-asmlinkage int sys_sigreturn(struct pt_regs *regs)
-{
 
-       if (sigreturn_common(regs,sizeof(sigframe)))
+       if (restore_sigregs(regs, &frame->sregs))
                goto badframe;
+
        return regs->gprs[2];
 
 badframe:
        force_sig(SIGSEGV, current);
        return 0;
-}      
+}
 
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 {
        rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+       sigset_t set;
 
-       if (sigreturn_common(regs,sizeof(rt_sigframe)))
+       if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
+       if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
+               goto badframe;
+
+       sigdelsetmask(&set, ~_BLOCKABLE);
+       spin_lock_irq(&current->sigmask_lock);
+       current->blocked = set;
+       recalc_sigpending(current);
+       spin_unlock_irq(&current->sigmask_lock);
+
+       if (restore_sigregs(regs, &frame->uc.uc_mcontext))
+               goto badframe;
+
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
        do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);
@@ -272,7 +265,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
 badframe:
        force_sig(SIGSEGV, current);
        return 0;
-}      
+}
 
 /*
  * Set up a signal frame.
@@ -306,58 +299,48 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
        return (void *)((sp - frame_size) & -8ul);
 }
 
-static void *setup_frame_common(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs,
-                               int frame_size,u16 retcode)
+static inline int map_signal(int sig)
 {
-       sigframe *frame;
-       int err;
+       if (current->exec_domain
+           && current->exec_domain->signal_invmap
+           && sig < 32)
+               return current->exec_domain->signal_invmap[sig];
+       else
+               return sig;
+}
 
-       frame = get_sigframe(ka, regs,frame_size);
-       if (!access_ok(VERIFY_WRITE, frame,frame_size))
-               return 0;
-       err = save_sigregs(regs,&frame->sregs);
-       if(!err)
-               err=__put_user(&frame->sregs,&frame->sc.sregs);
-       if(!err)
+static void setup_frame(int sig, struct k_sigaction *ka,
+                       sigset_t *set, struct pt_regs * regs)
+{
+       sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
+               goto give_sigsegv;
+
+       if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
+               goto give_sigsegv;
+
+       if (save_sigregs(regs, &frame->sregs))
+               goto give_sigsegv;
+       if (__put_user(&frame->sregs, &frame->sc.sregs))
+               goto give_sigsegv;
 
-               err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE);
-       if(!err)
-       {
-               regs->gprs[2]=(current->exec_domain
-                          && current->exec_domain->signal_invmap
-                          && sig < 32
-                          ? current->exec_domain->signal_invmap[sig]
-                          : sig);
-               /* Set up registers for signal handler */
-               regs->gprs[15] = (addr_t)frame;
-               regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
-               regs->psw.mask = _USER_PSW_MASK;
-       }
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
        if (ka->sa.sa_flags & SA_RESTORER) {
                 regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
        } else {
                 regs->gprs[14] = FIX_PSW(frame->retcode);
-               err |= __put_user(retcode, (u16 *)(frame->retcode));
+               if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, 
+                              (u16 *)(frame->retcode)))
+                       goto give_sigsegv;
        }
-       return(err ? 0:frame);
-}
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs)
-{
-       sigframe *frame;
+       /* Set up registers for signal handler */
+       regs->gprs[15] = (addr_t)frame;
+       regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+       regs->psw.mask = _USER_PSW_MASK;
 
-       if((frame=setup_frame_common(sig,ka,set,regs,sizeof(sigframe),
-                   (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
-               goto give_sigsegv;
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-       /* Martin wants this for pthreads */
+       regs->gprs[2] = map_signal(sig);
        regs->gprs[3] = (addr_t)&frame->sc;
 
        /* We forgot to include these in the sigcontext.
@@ -375,34 +358,44 @@ give_sigsegv:
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
 {
-       rt_sigframe *frame;
-       addr_t      orig_sp=regs->gprs[15];
-       int err;
+       int err = 0;
+       rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
+               goto give_sigsegv;
 
-       if((frame=setup_frame_common(sig,ka,set,regs,sizeof(rt_sigframe),
-                   (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+       if (copy_siginfo_to_user(&frame->info, info))
                goto give_sigsegv;
-       
-       err = copy_siginfo_to_user(&frame->info, info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-       err |= __put_user(sas_ss_flags(orig_sp),
+       err |= __put_user(sas_ss_flags(regs->gprs[15]),
                          &frame->uc.uc_stack.ss_flags);
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-       err |= __put_user(&frame->sc,&frame->uc.sc);
-       regs->gprs[3] = (addr_t)&frame->info;
-       regs->gprs[4] = (addr_t)&frame->uc;
-
+       err |= save_sigregs(regs, &frame->uc.uc_mcontext);
+       err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
                goto give_sigsegv;
 
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+       /* Set up to return from userspace.  If provided, use a stub
+          already in userspace.  */
+       if (ka->sa.sa_flags & SA_RESTORER) {
+                regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+       } else {
+                regs->gprs[14] = FIX_PSW(frame->retcode);
+               err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 
+                                 (u16 *)(frame->retcode));
+       }
+
+       /* Set up registers for signal handler */
+       regs->gprs[15] = (addr_t)frame;
+       regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+       regs->psw.mask = _USER_PSW_MASK;
+
+       regs->gprs[2] = map_signal(sig);
+       regs->gprs[3] = (addr_t)&frame->info;
+       regs->gprs[4] = (addr_t)&frame->uc;
        return;
 
 give_sigsegv:
@@ -551,13 +544,16 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                                        continue;
                                /* FALLTHRU */
 
-                       case SIGSTOP:
+                       case SIGSTOP: {
+                               struct signal_struct *sig;
                                set_current_state(TASK_STOPPED);
                                current->exit_code = signr;
-                               if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+                               sig = current->p_pptr->sig;
+                               if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
                                        notify_parent(current, SIGCHLD);
                                schedule();
                                continue;
+                       }
 
                        case SIGQUIT: case SIGILL: case SIGTRAP:
                        case SIGABRT: case SIGFPE: case SIGSEGV:
index 22aaeec63e532d43be64fba57c6341c2f3c880d0..a7e6c959c7e51d6e3c63409c6359c751b5749c20 100644 (file)
@@ -57,6 +57,8 @@ static atomic_t  smp_commenced = ATOMIC_INIT(0);
 
 spinlock_t       kernel_flag = SPIN_LOCK_UNLOCKED;
 
+unsigned long   cpu_online_map;
+
 /*
  *      Setup routine for controlling SMP activation
  *
@@ -92,6 +94,95 @@ extern char vmpoff_cmd[];
 
 extern void reipl(unsigned long devno);
 
+static sigp_ccode smp_ext_bitcall(int, ec_bit_sig);
+static void smp_ext_bitcall_others(ec_bit_sig);
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+struct call_data_struct {
+       void (*func) (void *info);
+       void *info;
+       atomic_t started;
+       atomic_t finished;
+       int wait;
+};
+
+static struct call_data_struct * call_data;
+
+/*
+ * 'Call function' interrupt callback
+ */
+static void do_call_function(void)
+{
+       void (*func) (void *info) = call_data->func;
+       void *info = call_data->info;
+       int wait = call_data->wait;
+
+       atomic_inc(&call_data->started);
+       (*func)(info);
+       if (wait)
+               atomic_inc(&call_data->finished);
+}
+
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+                       int wait)
+/*
+ * [SUMMARY] Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <nonatomic> currently unused.
+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute <<func>> or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler, you may call it from a bottom half handler.
+ */
+{
+       struct call_data_struct data;
+       int cpus = smp_num_cpus-1;
+
+       if (!cpus || !atomic_read(&smp_commenced))
+               return 0;
+
+       data.func = func;
+       data.info = info;
+       atomic_set(&data.started, 0);
+       data.wait = wait;
+       if (wait)
+               atomic_set(&data.finished, 0);
+
+       spin_lock_bh(&call_lock);
+       call_data = &data;
+       /* Send a message to all other CPUs and wait for them to respond */
+        smp_ext_bitcall_others(ec_call_function);
+
+       /* Wait for response */
+       while (atomic_read(&data.started) != cpus)
+               barrier();
+
+       if (wait)
+               while (atomic_read(&data.finished) != cpus)
+                       barrier();
+       spin_unlock_bh(&call_lock);
+
+       return 0;
+}
+
+
+/*
+ * Various special callbacks
+ */
+
 void do_machine_restart(void)
 {
         smp_send_stop();
@@ -148,7 +239,6 @@ void machine_power_off(void)
 
 void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
 {
-        ec_ext_call *ec, *next;
         int bits;
 
         /*
@@ -169,131 +259,15 @@ void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
                do_machine_halt();
         if (test_bit(ec_power_off, &bits))
                do_machine_power_off();
-       if (test_bit(ec_ptlb, &bits))
-               local_flush_tlb();
-
-        /*
-         * Handle external call commands with a parameter area
-         */
-        do {
-                ec = (ec_ext_call *) atomic_read(&S390_lowcore.ext_call_queue);
-        } while (atomic_compare_and_swap((int) ec, 0,
-                                         &S390_lowcore.ext_call_queue));
-        if (ec == NULL)
-                return;   /* no command signals */
-
-        /* Make a fifo out of the lifo */
-        next = ec->next;
-        ec->next = NULL;
-        while (next != NULL) {
-                ec_ext_call *tmp = next->next;
-                next->next = ec;
-                ec = next;
-                next = tmp;
-        }
-
-        /* Execute every sigp command on the queue */
-        while (ec != NULL) {
-                switch (ec->cmd) {
-                case ec_callback_async: {
-                        void (*func)(void *info);
-                        void *info;
-
-                        func = ec->func;
-                        info = ec->info;
-                        atomic_set(&ec->status,ec_executing);
-                        (func)(info);
-                        return;
-                }
-                case ec_callback_sync:
-                        atomic_set(&ec->status,ec_executing);
-                        (ec->func)(ec->info);
-                        atomic_set(&ec->status,ec_done);
-                        return;
-                default:
-                }
-                ec = ec->next;
-        }
-}
-
-/*
- * Send a callback sigp to another cpu.
- */
-sigp_ccode
-smp_ext_call(int cpu, void (*func)(void *info), void *info, int wait)
-{
-        struct _lowcore *lowcore = &get_cpu_lowcore(cpu);
-        sigp_ccode ccode;
-        ec_ext_call ec;
-
-        ec.cmd = wait ? ec_callback_sync : ec_callback_async;
-        atomic_set(&ec.status, ec_pending);
-       ec.func = func;
-        ec.info = info;
-        do {
-                ec.next = (ec_ext_call*) atomic_read(&lowcore->ext_call_queue);
-        } while (atomic_compare_and_swap((int) ec.next, (int)(&ec),
-                                         &lowcore->ext_call_queue));
-        /*
-         * We try once to deliver the signal. There are four possible
-         * return codes:
-         * 0) Order code accepted - can't show up on an external call
-         * 1) Status stored - fine, wait for completion.
-         * 2) Busy - there is another signal pending. Thats fine too, because
-         *    do_ext_call from the pending signal will execute all signals on
-         *    the queue. We wait for completion.
-         * 3) Not operational - something very bad has happened to the cpu.
-         *    do not wait for completion.
-         */
-        ccode = signal_processor(cpu, sigp_external_call);
-
-        if (ccode != sigp_not_operational)
-                /* wait for completion, FIXME: possible seed of a deadlock */
-                while (atomic_read(&ec.status) != (wait?ec_done:ec_executing));
-
-        return ccode;
-}
-
-/*
- * Send a callback sigp to every other cpu in the system.
- */
-void smp_ext_call_others(void (*func)(void *info), void *info, int wait)
-{
-        struct _lowcore *lowcore;
-        ec_ext_call ec[NR_CPUS];
-        sigp_ccode ccode;
-        int i;
-
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-                lowcore = &get_cpu_lowcore(i);
-               ec[i].cmd = wait ? ec_callback_sync : ec_callback_async;
-               atomic_set(&ec[i].status, ec_pending);
-               ec[i].func = func;
-               ec[i].info = info;
-                do {
-                        ec[i].next = (ec_ext_call *)
-                                        atomic_read(&lowcore->ext_call_queue);
-                } while (atomic_compare_and_swap((int) ec[i].next, (int)(ec+i),
-                                                 &lowcore->ext_call_queue));
-                ccode = signal_processor(i, sigp_external_call);
-        }
-
-        /* wait for completion, FIXME: possible seed of a deadlock */
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-                while (atomic_read(&ec[i].status) != 
-                      (wait ? ec_done:ec_executing));
-        }
+       if (test_bit(ec_call_function, &bits)) 
+               do_call_function();
 }
 
 /*
  * Send an external call sigp to another cpu and return without waiting
  * for its completion.
  */
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
+static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
 {
         struct _lowcore *lowcore = &get_cpu_lowcore(cpu);
         sigp_ccode ccode;
@@ -310,7 +284,7 @@ sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
  * Send an external call sigp to every other cpu in the system and
  * return without waiting for its completion.
  */
-void smp_ext_bitcall_others(ec_bit_sig sig)
+static void smp_ext_bitcall_others(ec_bit_sig sig)
 {
         struct _lowcore *lowcore;
         sigp_ccode ccode;
@@ -328,51 +302,6 @@ void smp_ext_bitcall_others(ec_bit_sig sig)
         }
 }
 
-/*
- * cycles through all the cpus,
- * returns early if info is not NULL & the processor has something
- * of intrest to report in the info structure.
- * it returns the next cpu to check if it returns early.
- * i.e. it should be used as follows if you wish to receive info.
- * next_cpu=0;
- * do
- * {
- *    info->cpu=next_cpu;
- *    next_cpu=smp_signal_others(order_code,parameter,1,info);
- *    ... check info here
- * } while(next_cpu<=smp_num_cpus)
- *
- *  if you are lazy just use it like
- * smp_signal_others(order_code,parameter,0,1,NULL);
- */
-int smp_signal_others(sigp_order_code order_code, u32 parameter,
-                      int spin, sigp_info *info)
-{
-        sigp_ccode   ccode;
-        u32          dummy;
-        u16          i;
-
-        if (info)
-                info->intresting = 0;
-        for (i = (info ? info->cpu : 0); i < smp_num_cpus; i++) {
-                if (smp_processor_id() != i) {
-                        do {
-                                ccode = signal_processor_ps(
-                                        (info ? &info->status : &dummy),
-                                        parameter, i, order_code);
-                        } while(spin && ccode == sigp_busy);
-                        if (info && ccode != sigp_order_code_accepted) {
-                                info->intresting = 1;
-                                info->cpu = i;
-                                info->ccode = ccode;
-                                i++;
-                                break;
-                        }
-                }
-        }
-        return i;
-}
-
 /*
  * this function sends a 'stop' sigp to all other CPUs in the system.
  * it goes straight through.
@@ -390,7 +319,18 @@ void smp_send_stop(void)
 
         /* stop all processors */
 
-        smp_signal_others(sigp_stop, 0, 1, NULL);
+        for (i =  0; i < smp_num_cpus; i++) {
+                if (smp_processor_id() != i) {
+                        int ccode;
+                        do {
+                                ccode = signal_processor_ps(
+                                   &dummy,
+                                   0,
+                                   i,
+                                   sigp_stop);
+                        } while(ccode == sigp_busy);
+                }
+        }
 
         /* store status of all processors in their lowcores (real 0) */
 
@@ -419,7 +359,7 @@ void smp_ptlb_callback(void *info)
 
 void smp_ptlb_all(void)
 {
-        smp_ext_call_others(smp_ptlb_callback, NULL, 1);
+        smp_call_function(smp_ptlb_callback, NULL, 0, 1);
        local_flush_tlb();
 }
 
@@ -482,7 +422,7 @@ void smp_ctl_set_bit(int cr, int bit) {
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 1 << bit;
                 parms.andvals[cr] = 0xFFFFFFFF;
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_set_bit(cr, bit);
 }
@@ -498,35 +438,11 @@ void smp_ctl_clear_bit(int cr, int bit) {
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 0x00000000;
                 parms.andvals[cr] = ~(1 << bit);
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_clear_bit(cr, bit);
 }
 
-/*
- * Call a function on all other processors
- */
-
-int
-smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
-/*
- * [SUMMARY] Run a function on all other CPUs.
- * <func> The function to run. This must be fast and non-blocking.
- * <info> An arbitrary pointer to pass to the function.
- * <retry> currently unused.
- * <wait> If true, wait (atomically) until function has completed on other CPUs.
- * [RETURNS] 0 on success, else a negative status code. Does not return until
- * remote CPUs are nearly ready to execute <<func>> or are or have executed.
- *
- * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler, you may call it from a bottom half handler.
- */
-{
-        if (atomic_read(&smp_commenced) != 0)
-                smp_ext_call_others(func, info, wait);
-        return 0;
-}
-
 /*
  * Lets check how many CPUs we have.
  */
@@ -537,6 +453,7 @@ void smp_count_cpus(void)
 
         current->processor = 0;
         smp_num_cpus = 1;
+       cpu_online_map = 1;
         for (curr_cpu = 0;
              curr_cpu <= 65535 && smp_num_cpus < max_cpus; curr_cpu++) {
                 if ((__u16) curr_cpu == boot_cpu_addr)
@@ -556,6 +473,7 @@ void smp_count_cpus(void)
  *      Activate a secondary processor.
  */
 extern void init_100hz_timer(void);
+extern int pfault_init(void);
 extern int pfault_token(void);
 
 int __init start_secondary(void *cpuvoid)
@@ -620,15 +538,20 @@ static void __init do_boot_cpu(int cpu)
         init_tasks[cpu] = idle;
 
         cpu_lowcore=&get_cpu_lowcore(cpu);
-        cpu_lowcore->kernel_stack=idle->thread.ksp;
-        __asm__ __volatile__("stctl 0,15,%0\n\t"
-                             "stam  0,15,%1"
+       cpu_lowcore->save_area[15] = idle->thread.ksp;
+       cpu_lowcore->kernel_stack = (idle->thread.ksp | 8191) + 1;
+        __asm__ __volatile__("la    1,%0\n\t"
+                            "stctl 0,15,0(1)\n\t"
+                            "la    1,%1\n\t"
+                             "stam  0,15,0(1)"
                              : "=m" (cpu_lowcore->cregs_save_area[0]),
                                "=m" (cpu_lowcore->access_regs_save_area[0])
-                             : : "memory");
+                             : : "1", "memory");
 
         eieio();
         signal_processor(cpu,sigp_restart);
+       /* Mark this cpu as online */
+       set_bit(cpu, &cpu_online_map);
 }
 
 /*
@@ -650,12 +573,12 @@ void __init smp_commence(void)
 }
 
 /*
- *     Cycle through the processors sending APIC IPIs to boot each.
+ *     Cycle through the processors sending sigp_restart to boot each.
  */
 
 void __init smp_boot_cpus(void)
 {
-        struct _lowcore *curr_lowcore;
+       unsigned long async_stack;
         sigp_ccode   ccode;
         int i;
 
@@ -680,34 +603,37 @@ void __init smp_boot_cpus(void)
 
         for(i = 0; i < smp_num_cpus; i++)
         {
-                curr_lowcore = (struct _lowcore *)
-                                    __get_free_page(GFP_KERNEL|GFP_DMA);
-                if (curr_lowcore == NULL) {
-                        printk("smp_boot_cpus failed to allocate prefix memory\n");
-                        break;
-                }
-                lowcore_ptr[i] = curr_lowcore;
-                memcpy(curr_lowcore, &S390_lowcore, sizeof(struct _lowcore));
+               lowcore_ptr[i] = (struct _lowcore *)
+                       __get_free_page(GFP_KERNEL|GFP_DMA);
+                if (lowcore_ptr[i] == NULL)
+                        panic("smp_boot_cpus failed to "
+                             "allocate prefix memory\n");
+               async_stack = __get_free_pages(GFP_KERNEL,1);
+               if (async_stack == 0)
+                       panic("smp_boot_cpus failed to allocate "
+                             "asyncronous interrupt stack\n");
+
+                memcpy(lowcore_ptr[i], &S390_lowcore, sizeof(struct _lowcore));
+               lowcore_ptr[i]->async_stack = async_stack + (2 * PAGE_SIZE);
                 /*
                  * Most of the parameters are set up when the cpu is
                  * started up.
                  */
-                if (smp_processor_id() == i)
-                        set_prefix((u32) curr_lowcore);
-                else {
-                        ccode = signal_processor_p((u32)(curr_lowcore),
-                                                   i, sigp_set_prefix);
-                        if(ccode) {
-                                /* if this gets troublesome I'll have to do
-                                 * something about it. */
-                                printk("ccode %d for cpu %d  returned when "
-                                       "setting prefix in smp_boot_cpus not good.\n",
-                                       (int) ccode, (int) i);
-                        }
-                        else
-                                do_boot_cpu(i);
-                }
-        }
+               if (smp_processor_id() == i)
+                       set_prefix((u32) lowcore_ptr[i]);
+               else {
+                       ccode = signal_processor_p((u32)(lowcore_ptr[i]),
+                                                  i, sigp_set_prefix);
+                       if (ccode)
+                               /* if this gets troublesome I'll have to do
+                                * something about it. */
+                               printk("ccode %d for cpu %d  returned when "
+                                      "setting prefix in smp_boot_cpus not good.\n",
+                                      (int) ccode, (int) i);
+                       else
+                               do_boot_cpu(i);
+               }
+       }
 }
 
 /*
@@ -746,8 +672,6 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
                 s390_do_profile(regs->psw.addr);
 
         if (!--prof_counter[cpu]) {
-                int system = 1-user;
-                struct task_struct * p = current;
 
                 /*
                  * The multiplier may have changed since the last time we got
@@ -771,9 +695,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
                  * WrongThing (tm) to do.
                  */
 
-                irq_enter(cpu, 0);
                update_process_times(user);
-                irq_exit(cpu, 0);
         }
 }
 
index d3568efcf2657566bd80fd6b4c3c9691f7d5a639..7f0967d1de30c38f3f21d4cadd072c73f36cc4cf 100644 (file)
@@ -151,15 +151,14 @@ extern __u16 boot_cpu_addr;
 
 void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        unsigned long flags;
+       int cpu = smp_processor_id();
+
+       irq_enter(cpu, 0);
 
         /*
          * reset timer to 10ms minus time already elapsed
          * since timer-interrupt pending
          */
-        save_flags(flags);
-        cli();
 #ifdef CONFIG_SMP
        if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
                write_lock(&xtime_lock);
@@ -195,8 +194,8 @@ void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
                write_unlock(&xtime_lock);
 #endif
        }
-        restore_flags(flags);
 
+       irq_exit(cpu, 0);
 }
 
 /*
@@ -250,4 +249,7 @@ void __init time_init(void)
         init_timer_cc -= 0x8126d60e46000000LL -
                          (0x3c26700LL*1000000*4096);
         tod_to_timeval(init_timer_cc, &xtime);
+
+       /* Set do_get_fast_time function pointer.  */
+       do_get_fast_time = do_gettimeofday;
 }
index b73cb69f4a9a7ebc1439d66dea7c8fedf3d4ec82..4bffad069c04e79c4e72d0ab8dae889b526b8844 100644 (file)
@@ -60,14 +60,16 @@ extern void pfault_fini(void);
 extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
 #endif
 
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
         console_verbose();
         spin_lock_irq(&die_lock);
+       bust_spinlocks(1);
         printk("%s: %04lx\n", str, err & 0xffff);
         show_regs(regs);
+       bust_spinlocks(0);
         spin_unlock_irq(&die_lock);
         do_exit(SIGSEGV);
 }
@@ -135,7 +137,7 @@ int do_debugger_trap(struct pt_regs *regs,int signal)
 #if CONFIG_REMOTE_DEBUG
                if(gdb_stub_initialised)
                {
-                       gdb_stub_handle_exception((gdb_pt_regs *)regs,signal);
+                       gdb_stub_handle_exception((struct gdb_pt_regs *)regs,signal);
                        return 0;
                }
 #endif
@@ -211,7 +213,7 @@ asmlinkage void
 specification_exception(struct pt_regs * regs, long interruption_code)
 {
         __u8 opcode[6];
-       __u16 *location;
+       __u16 *location = NULL;
        int signal = 0;
 
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
index efc3a8f44dca2aab761fca0ebbeeed51322df399..997e1b4a813ba03266ad24c869bffed0a22db94f 100644 (file)
@@ -1471,20 +1471,98 @@ static int emu_seb (int rx, float *val) {
 }
 
 /* Test data class long double */
-static int emu_tcxb (int rx, double *val) {
-        display_emulation_not_implemented("tcxb");
+static int emu_tcxb (int rx, long val) {
+        FP_DECL_Q(QA);
+       mathemu_ldcv cvt;
+       int bit;
+
+        cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
+        cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
+        FP_UNPACK_RAW_QP(QA, &cvt.ld);
+       switch (QA_e) {
+       default:
+               bit = 8;                /* normalized number */
+               break;
+       case 0:
+               if (_FP_FRAC_ZEROP_4(QA))
+                       bit = 10;       /* zero */
+               else
+                       bit = 6;        /* denormalized number */
+               break;
+       case _FP_EXPMAX_Q:
+               if (_FP_FRAC_ZEROP_4(QA))
+                       bit = 4;        /* infinity */
+               else if (_FP_FRAC_HIGH_RAW_Q(QA) & _FP_QNANBIT_Q)
+                       bit = 2;        /* quiet NAN */
+               else
+                       bit = 0;        /* signaling NAN */
+               break;
+       }
+       if (!QA_s)
+               bit++;
+       emu_set_CC(((__u32) val >> bit) & 1);
         return 0;
 }
 
 /* Test data class double */
-static int emu_tcdb (int rx, double *val) {
-        display_emulation_not_implemented("tcdb");
+static int emu_tcdb (int rx, long val) {
+        FP_DECL_D(DA);
+       int bit;
+
+        FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
+       switch (DA_e) {
+       default:
+               bit = 8;                /* normalized number */
+               break;
+       case 0:
+               if (_FP_FRAC_ZEROP_2(DA))
+                       bit = 10;       /* zero */
+               else
+                       bit = 6;        /* denormalized number */
+               break;
+       case _FP_EXPMAX_D:
+               if (_FP_FRAC_ZEROP_2(DA))
+                       bit = 4;        /* infinity */
+               else if (_FP_FRAC_HIGH_RAW_D(DA) & _FP_QNANBIT_D)
+                       bit = 2;        /* quiet NAN */
+               else
+                       bit = 0;        /* signaling NAN */
+               break;
+       }
+       if (!DA_s)
+               bit++;
+       emu_set_CC(((__u32) val >> bit) & 1);
         return 0;
 }
 
 /* Test data class float */
-static int emu_tceb (int rx, __u32 val) {
-        display_emulation_not_implemented("tceb");
+static int emu_tceb (int rx, long val) {
+        FP_DECL_S(SA);
+       int bit;
+
+        FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
+       switch (SA_e) {
+       default:
+               bit = 8;                /* normalized number */
+               break;
+       case 0:
+               if (_FP_FRAC_ZEROP_1(SA))
+                       bit = 10;       /* zero */
+               else
+                       bit = 6;        /* denormalized number */
+               break;
+       case _FP_EXPMAX_S:
+               if (_FP_FRAC_ZEROP_1(SA))
+                       bit = 4;        /* infinity */
+               else if (_FP_FRAC_HIGH_RAW_S(SA) & _FP_QNANBIT_S)
+                       bit = 2;        /* quiet NAN */
+               else
+                       bit = 0;        /* signaling NAN */
+               break;
+       }
+       if (!SA_s)
+               bit++;
+       emu_set_CC(((__u32) val >> bit) & 1);
         return 0;
 }
 
@@ -1796,13 +1874,13 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
         int _fex = 0;
 
         static const __u8 format_table[256] = {
-                [0x04] = 0x08,[0x05] = 0x07,[0x06] = 0x09,[0x07] = 0x07,
-               [0x08] = 0x03,[0x09] = 0x03,[0x0a] = 0x03,[0x0b] = 0x03,
-               [0x0c] = 0x08,[0x0d] = 0x03,[0x0e] = 0x06,[0x0f] = 0x06,
-                [0x10] = 0x03,[0x11] = 0x02,[0x12] = 0x01,[0x14] = 0x03,
-               [0x15] = 0x02,[0x17] = 0x03,[0x18] = 0x02,[0x19] = 0x02,
-               [0x1a] = 0x02,[0x1b] = 0x02,[0x1c] = 0x02,[0x1d] = 0x02,
-                [0x1e] = 0x05,[0x1f] = 0x05,
+                [0x04] = 0x06,[0x05] = 0x05,[0x06] = 0x07,[0x07] = 0x05,
+               [0x08] = 0x02,[0x09] = 0x02,[0x0a] = 0x02,[0x0b] = 0x02,
+               [0x0c] = 0x06,[0x0d] = 0x02,[0x0e] = 0x04,[0x0f] = 0x04,
+                [0x10] = 0x08,[0x11] = 0x09,[0x12] = 0x0a,[0x14] = 0x02,
+               [0x15] = 0x01,[0x17] = 0x02,[0x18] = 0x01,[0x19] = 0x01,
+               [0x1a] = 0x01,[0x1b] = 0x01,[0x1c] = 0x01,[0x1d] = 0x01,
+                [0x1e] = 0x03,[0x1f] = 0x03,
         };
         static const void *jump_table[]= {
                 [0x04] = emu_ldeb,[0x05] = emu_lxdb,[0x06] = emu_lxeb,
@@ -1817,25 +1895,7 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
         };
 
         switch (format_table[opcode[5]]) {
-        case 1: /* RXE format, long double constant */ {
-                __u64 *dxb, temp[2];
-                __u32 opc;
-
-                if ((opcode[1] >> 4) & 2)
-                       return SIGILL;
-                emu_store_regd((opcode[1] >> 4) & 15);
-                emu_store_regd(((opcode[1] >> 4) & 15) + 2);
-                opc = *((__u32 *) opcode);
-                dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
-                mathemu_copy_from_user(&temp, dxb, 16);
-                /* call the emulation function */
-                _fex = ((int (*)(int, long double *)) jump_table[opcode[5]])
-                        (opcode[1] >> 4, (long double *) &temp);
-                emu_load_regd((opcode[1] >> 4) & 15);
-                emu_load_regd(((opcode[1] >> 4) & 15) + 2);
-                break;
-        }
-        case 2: /* RXE format, double constant */ {
+        case 1: /* RXE format, double constant */ {
                 __u64 *dxb, temp;
                 __u32 opc;
 
@@ -1849,7 +1909,7 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
                 emu_load_regd((opcode[1] >> 4) & 15);
                 break;
         }
-        case 3: /* RXE format, float constant */ {
+        case 2: /* RXE format, float constant */ {
                 __u32 *dxb, temp;
                 __u32 opc;
 
@@ -1863,27 +1923,7 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
                 emu_load_rege((opcode[1] >> 4) & 15);
                 break;
         }
-        case 4: /* RXF format, long double constant */ {
-                __u64 *dxb, temp[2];
-                __u32 opc;
-
-                if (((opcode[1] >> 4) & 0x20) || ((opcode[4] >> 4) & 0x20))
-                       return SIGILL;
-                emu_store_regd((opcode[1] >> 4) & 15);
-                emu_store_regd(((opcode[1] >> 4) & 15) + 2);
-                emu_store_regd((opcode[4] >> 4) & 15);
-                emu_store_regd(((opcode[4] >> 4) & 15) + 2);
-                opc = *((__u32 *) opcode);
-                dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
-                mathemu_copy_from_user(&temp, dxb, 16);
-                /* call the emulation function */
-                _fex = ((int (*)(int,long double *,int)) jump_table[opcode[5]])
-                        (opcode[1] >> 4, (double *) &temp, opcode[4] >> 4);
-                emu_load_regd((opcode[1] >> 4) & 15);
-                emu_load_regd(((opcode[1] >> 4) & 15) + 2);
-                break;
-        }
-        case 5: /* RXF format, double constant */ {
+        case 3: /* RXF format, double constant */ {
                 __u64 *dxb, temp;
                 __u32 opc;
 
@@ -1898,7 +1938,7 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
                 emu_load_regd((opcode[1] >> 4) & 15);
                 break;
         }
-        case 6: /* RXF format, float constant */ {
+        case 4: /* RXF format, float constant */ {
                 __u32 *dxb, temp;
                 __u32 opc;
 
@@ -1913,7 +1953,7 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
                 emu_load_rege((opcode[4] >> 4) & 15);
                 break;
         }
-        case 7: /* RXE format, double constant */
+        case 5: /* RXE format, double constant */
                 /* store double and load long double */ 
         {
                 __u64 *dxb, temp;
@@ -1931,7 +1971,7 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
                 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
                 break;
         }
-        case 8: /* RXE format, float constant */
+        case 6: /* RXE format, float constant */
                 /* store float and load double */ 
         {
                 __u32 *dxb, temp;
@@ -1946,7 +1986,7 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
                 emu_load_regd((opcode[1] >> 4) & 15);
                 break;
         }
-        case 9: /* RXE format, float constant */
+        case 7: /* RXE format, float constant */
                 /* store float and load long double */ 
         {
                 __u32 *dxb, temp;
@@ -1964,6 +2004,45 @@ int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
                 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
                 break;
         }
+        case 8: /* RXE format, RX address used as int value */ {
+                __u64 dxb;
+                __u32 opc;
+
+                emu_store_rege((opcode[1] >> 4) & 15);
+                opc = *((__u32 *) opcode);
+                dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+                /* call the emulation function */
+                _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+                        (opcode[1] >> 4, dxb);
+                break;
+        }
+        case 9: /* RXE format, RX address used as int value */ {
+                __u64 dxb;
+                __u32 opc;
+
+                emu_store_regd((opcode[1] >> 4) & 15);
+                opc = *((__u32 *) opcode);
+                dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+                /* call the emulation function */
+                _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+                        (opcode[1] >> 4, dxb);
+                break;
+        }
+        case 10: /* RXE format, RX address used as int value */ {
+                __u64 dxb;
+                __u32 opc;
+
+                if ((opcode[1] >> 4) & 2)
+                       return SIGILL;
+                emu_store_regd((opcode[1] >> 4) & 15);
+                emu_store_regd(((opcode[1] >> 4) & 15) + 2);
+                opc = *((__u32 *) opcode);
+                dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+                /* call the emulation function */
+                _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+                        (opcode[1] >> 4, dxb);
+                break;
+        }
         default: /* invalid operation */
                 return SIGILL;
         }
index 2aac12c9753d080a9b39b7b6285b817d7b859157..ff507aa2554c866be5887dc9ece26f968b35f24b 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 extern const struct exception_table_entry __start___ex_table[];
@@ -36,28 +37,37 @@ search_one_table(const struct exception_table_entry *first,
         return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
-       unsigned long ret;
+       unsigned long ret = 0;
+       unsigned long flags;
 
 #ifndef CONFIG_MODULES
         addr &= 0x7fffffff;  /* remove amode bit from address */
        /* There is only the kernel to search.  */
        ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-       if (ret) return FIX_PSW(ret);
+       if (ret) ret = FIX_PSW(ret);
+       return ret;
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
         addr &= 0x7fffffff;  /* remove amode bit from address */
+
+       spin_lock_irqsave(&modlist_lock, flags);
        for (mp = module_list; mp != NULL; mp = mp->next) {
-               if (mp->ex_table_start == NULL)
+               if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return FIX_PSW(ret);
+               if (ret) {
+                       ret = FIX_PSW(ret);
+                       break;
+               }
        }
+       spin_unlock_irqrestore(&modlist_lock, flags);
+       return ret;
 #endif
-
-       return 0;
 }
index 81daf0c1e3497b5bf5265d8a45f07537741ed588..e19c7897356e2b7fa9cfa44e20639793f6a2292a 100644 (file)
@@ -4,6 +4,7 @@
  *  S390 version
  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Hartmut Penner (hp@de.ibm.com)
+ *               Ulrich Weigand (uweigand@de.ibm.com)
  *
  *  Derived from "arch/i386/mm/fault.c"
  *    Copyright (C) 1995  Linus Torvalds
@@ -23,6 +24,7 @@
 #include <linux/smp_lock.h>
 #include <linux/compatmac.h>
 #include <linux/init.h>
+#include <linux/console.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -34,6 +36,34 @@ extern int sysctl_userprocess_debug;
 #endif
 
 extern void die(const char *,struct pt_regs *,long);
+static void force_sigsegv(struct task_struct *tsk, int code, void *address);
+
+extern spinlock_t timerlist_lock;
+
+/*
+ * Unlock any spinlocks which will prevent us from getting the
+ * message out (timerlist_lock is acquired through the
+ * console unblank code)
+ */
+void bust_spinlocks(int yes)
+{
+       spin_lock_init(&timerlist_lock);
+       if (yes) {
+               oops_in_progress = 1;
+       } else {
+               int loglevel_save = console_loglevel;
+               oops_in_progress = 0;
+               console_unblank();
+               /*
+                * OK, the message is on the console.  Now we call printk()
+                * without oops_in_progress set so that printk will give klogd
+                * a poke.  Hold onto your hats...
+                */
+               console_loglevel = 15;
+               printk(" ");
+               console_loglevel = loglevel_save;
+       }
+}
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -56,18 +86,36 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
        int si_code = SEGV_MAPERR;
        int kernel_address = 0;
 
+        tsk = current;
+        mm = tsk->mm;
+       
+       /* 
+         * Check for low-address protection.  This needs to be treated
+        * as a special case because the translation exception code 
+        * field is not guaranteed to contain valid data in this case.
+        */
+       if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+
+               /* Low-address protection hit in kernel mode means 
+                  NULL pointer write access in kernel mode.  */
+               if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
+                       address = 0;
+                       kernel_address = 1;
+                       goto no_context;
+               }
+
+               /* Low-address protection hit in user mode 'cannot happen'.  */
+               die ("Low-address protection", regs, error_code);
+               do_exit(SIGKILL);
+       }
+
         /* 
          * get the failing address 
          * more specific the segment and page table portion of 
          * the address 
          */
-        address = S390_lowcore.trans_exc_code&0x7ffff000;
 
-        tsk = current;
-        mm = tsk->mm;
-
-        if (in_interrupt() || !mm)
-                goto no_context;
+        address = S390_lowcore.trans_exc_code&0x7ffff000;
 
 
        /*
@@ -99,6 +147,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                        }
                }
                die("page fault via unknown access register", regs, error_code);
+               do_exit(SIGKILL);
                break;
 
        case 2: /* Secondary Segment Table Descriptor */
@@ -107,6 +156,11 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                break;
        }
 
+       /*
+        * Check whether we have a user MM in the first place.
+        */
+        if (in_interrupt() || !mm)
+                goto no_context;
 
        /*
         * When we get here, the fault happened in the current
@@ -146,6 +200,7 @@ good_area:
                        goto bad_area;
         }
 
+ survive:
        /*
         * If for any reason at all we couldn't handle the fault,
         * make sure we exit gracefully rather than endlessly redo
@@ -176,7 +231,6 @@ bad_area:
 
         /* User mode accesses just cause a SIGSEGV */
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
-               struct siginfo si;
                 tsk->thread.prot_addr = address;
                 tsk->thread.trap_no = error_code;
 #ifndef CONFIG_SYSCTL
@@ -193,10 +247,8 @@ bad_area:
                        show_regs(regs);
                }
 #endif
-               si.si_signo = SIGSEGV;
-               si.si_code = si_code;
-               si.si_addr = (void*) address;
-               force_sig_info(SIGSEGV, &si, tsk);
+
+               force_sigsegv(tsk, si_code, (void *)address);
                 return;
        }
 
@@ -218,9 +270,6 @@ no_context:
         else
                 printk(KERN_ALERT "Unable to handle kernel paging request"
                       " at virtual user address %08lx\n", address);
-/*
- * need to define, which information is useful here
- */
 
         die("Oops", regs, error_code);
         do_exit(SIGKILL);
@@ -232,6 +281,12 @@ no_context:
 */
 out_of_memory:
        up_read(&mm->mmap_sem);
+       if (tsk->pid == 1) {
+               tsk->policy |= SCHED_YIELD;
+               schedule();
+               down_read(&mm->mmap_sem);
+               goto survive;
+       }
        printk("VM: killing process %s\n", tsk->comm);
        if (regs->psw.mask & PSW_PROBLEM_STATE)
                do_exit(SIGKILL);
@@ -253,6 +308,18 @@ do_sigbus:
                goto no_context;
 }
 
+/*
+ * Send SIGSEGV to task.  This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+{
+       struct siginfo si;
+       si.si_signo = SIGSEGV;
+       si.si_code = code;
+       si.si_addr = address;
+       force_sig_info(SIGSEGV, &si, tsk);
+}
 
 typedef struct _pseudo_wait_t {
        struct _pseudo_wait_t *next;
@@ -434,7 +501,6 @@ void pfault_fini(void)
 asmlinkage void
 pfault_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        DECLARE_WAITQUEUE(wait, current);
        struct task_struct *tsk;
        wait_queue_head_t queue;
        wait_queue_head_t *qp;
@@ -447,7 +513,7 @@ pfault_interrupt(struct pt_regs *regs, __u16 error_code)
          * external interrupt. 
         */
        subcode = S390_lowcore.cpu_addr;
-       if ((subcode & 0xff00) != 0x06)
+       if ((subcode & 0xff00) != 0x0600)
                return;
 
        /*
index bcf24b4451ee063433313e67c8c4dd27408022c2..a7d35f5477240b086a36fd78ee0c986e64bfd723 100644 (file)
@@ -44,44 +44,23 @@ static unsigned long totalram_pages;
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
-static int test_access(unsigned long loc)
-{
-       static const int ssm_mask = 0x07000000L;
-       int rc, i;
-
-        rc = 0;
-       for (i=0; i<4; i++) {
-               __asm__ __volatile__(
-                        "    slr   %0,%0\n"
-                       "    ssm   %1\n"
-                       "    tprot 0(%2),0\n"
-                       "0:  jne   1f\n"
-                       "    lhi   %0,1\n"
-                       "1:  ssm   %3\n"
-                        ".section __ex_table,\"a\"\n"
-                        "   .align 4\n"
-                        "   .long  0b,1b\n"
-                        ".previous"
-                       : "+&d" (rc) : "i" (0), "a" (loc), "m" (ssm_mask)
-                       : "cc");
-               if (rc == 0)
-                       break;
-               loc += 0x100000;
-       }
-       return rc;
-}
-
 int do_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 += 2;
-                        if(pmd_quicklist)
-                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0)), freed++;
-                        if(pte_quicklist)
-                                pte_free_slow(pte_alloc_one_fast(NULL, 0)), freed++;
+                        if(pgd_quicklist) {
+                                free_pgd_slow(get_pgd_fast());
+                               freed += 2;
+                       }
+                        if(pmd_quicklist) {
+                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+                               freed++;
+                       }
+                        if(pte_quicklist) {
+                                pte_free_slow(pte_alloc_one_fast(NULL, 0));
+                               freed++;
+                       }
                 } while(pgtable_cache_size > low);
         }
         return freed;
@@ -200,7 +179,6 @@ void __init paging_init(void)
 void __init mem_init(void)
 {
        int codesize, reservedpages, datasize, initsize;
-        int tmp;
 
         max_mapnr = num_physpages = max_low_pfn;
         high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
@@ -211,24 +189,7 @@ void __init mem_init(void)
        /* this will put all low memory onto the freelists */
        totalram_pages += free_all_bootmem();
 
-        /* mark usable pages in the mem_map[] and count reserved pages */
        reservedpages = 0;
-       tmp = 0;
-       do {
-               if (tmp && (tmp & 0x3ff) == 0 && 
-                    test_access(tmp * PAGE_SIZE) == 0) {
-                        printk("4M Segment %lX not available\n",tmp*PAGE_SIZE);
-                       do {
-                                set_bit(PG_reserved, &mem_map[tmp].flags);
-                               reservedpages++;
-                               tmp++;
-                       } while (tmp < max_low_pfn && (tmp & 0x3ff));
-               } else {
-                       if (PageReserved(mem_map+tmp))
-                               reservedpages++;
-                       tmp++;
-               }
-       } while (tmp < max_low_pfn);
 
        codesize =  (unsigned long) &_etext - (unsigned long) &_text;
        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
index d68843b4ff68f1704e847dfab85354c4d2f6f654..91758f55b96c62026c77086c117ea89848bac763 100644 (file)
@@ -52,16 +52,6 @@ drivers/s390: dummy
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
-MAKESILO = $(MAKE) -C arch/$(ARCH)/tools/silo
-
-MAKEDASDFMT = $(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
-silo:
-       @$(MAKE) -C arch/$(ARCH)/tools/silo
-
-dasdfmt:
-       @$(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
 image: vmlinux 
        @$(MAKEBOOT) image
 
index 8228e9cb5dfb934fc25f8846aa58bedef2c99758..5a9c5b68908075f1469db2ff3857b31cc8036a05 100644 (file)
@@ -8,6 +8,7 @@ define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
 
 mainmenu_name "Linux Kernel Configuration"
 define_bool CONFIG_ARCH_S390 y
index a56d6f978f2a93af241538f62c7877ba2c25e5f3..eaffc7492c4203c0a4ae1ec8e0e0e0988c549127 100644 (file)
@@ -6,6 +6,7 @@
 # CONFIG_MCA is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_BUST_SPINLOCK=n
 CONFIG_ARCH_S390=y
 CONFIG_ARCH_S390X=y
 
@@ -72,6 +73,7 @@ CONFIG_BLK_DEV_MD=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 CONFIG_MD_RAID5=m
+# CONFIG_MD_MULTIPATH is not set
 CONFIG_BLK_DEV_LVM=m
 
 #
@@ -247,6 +249,7 @@ CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 # CONFIG_MAC_PARTITION is not set
 # CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
index 2aae8d5f6213a130d2af5a4c19128ae774da3262..957db6724bc2c6020ecce36df4b7013d214ee388 100644 (file)
 
 all: kernel.o head.o init_task.o
 
-O_TARGET := kernel.o
+O_TARGET       := kernel.o
 
-export-objs    := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o
-obj-y  := lowcore.o entry.o bitmap.o traps.o time.o process.o irq.o \
-            setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
-            semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
+export-objs    := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o \
+                  exec32.o
+
+obj-y          := entry.o bitmap.o traps.o time.o process.o irq.o \
+                  setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
+                  semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
 
 obj-$(CONFIG_MODULES)          += s390_ksyms.o
 obj-$(CONFIG_SMP)              += smp.o
index b020cb2b6fc36afb8f6deffb8fca12c8b6265131..f2ec75b981e064a498dd327c598f514425020baf 100644 (file)
@@ -6,21 +6,25 @@
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  */
 
-#include <linux/stddef.h>
-#include <linux/kernel.h>
 #include <linux/string.h>
-#include <asm/ebcdic.h>
+#include <linux/spinlock.h>
 #include <asm/cpcmd.h>
+#include <asm/ebcdic.h>
+#include <asm/system.h>
+
+static spinlock_t cpcmd_lock = SPIN_LOCK_UNLOCKED;
+static char cpcmd_buf[128];
 
 void cpcmd(char *cmd, char *response, int rlen)
 {
         const int mask = 0x40000000L;
-        char obuffer[128];
-        int olen;
+       unsigned long flags;
+        int cmdlen;
 
-        olen = strlen(cmd);
-        strcpy(obuffer, cmd);
-        ASCEBC(obuffer,olen);
+       spin_lock_irqsave(&cpcmd_lock, flags);
+        cmdlen = strlen(cmd);
+        strcpy(cpcmd_buf, cmd);
+        ASCEBC(cpcmd_buf, cmdlen);
 
         if (response != NULL && rlen > 0) {
                 asm volatile ("   lrag  2,0(%0)\n"
@@ -32,7 +36,7 @@ void cpcmd(char *cmd, char *response, int rlen)
                               "   .long 0x83240008 # Diagnose 83\n"
                               "   sam64"
                               : /* no output */
-                              : "a" (obuffer), "d" (olen),
+                              : "a" (cpcmd_buf), "d" (cmdlen),
                                 "a" (response), "d" (rlen), "m" (mask)
                               : "2", "3", "4", "5" );
                 EBCASC(response, rlen);
@@ -43,8 +47,9 @@ void cpcmd(char *cmd, char *response, int rlen)
                               "   .long 0x83230008 # Diagnose 83\n"
                               "   sam64"
                               : /* no output */
-                              : "a" (obuffer), "d" (olen)
+                              : "a" (cpcmd_buf), "d" (cmdlen)
                               : "2", "3"  );
         }
+       spin_unlock_irqrestore(&cpcmd_lock, flags);
 }
 
index 4f0f67e351fa1bccd2c1710abbe6b3a82bccffc0..f013a5c1f99247a31a3cfefad17a28660610c874 100644 (file)
@@ -83,6 +83,9 @@ static int debug_prolog_level_fn(debug_info_t * id,
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
                                struct file *file, const char *user_buf,
                                size_t user_buf_size, loff_t * offset);
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t user_buf_size, loff_t * offset);
 static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
                                 char *out_buf, const char *in_buf);
 static int debug_raw_format_fn(debug_info_t * id,
@@ -123,6 +126,15 @@ struct debug_view debug_level_view = {
        NULL
 };
 
+struct debug_view debug_flush_view = {
+        "flush",
+        NULL,
+        NULL,
+        NULL,
+        &debug_input_flush_fn,
+        NULL
+};
+
 struct debug_view debug_sprintf_view = {
        "sprintf",
        NULL,
@@ -664,6 +676,7 @@ debug_info_t *debug_register
        if(!rc) 
                goto out;
        debug_register_view(rc, &debug_level_view);
+        debug_register_view(rc, &debug_flush_view);
        printk(KERN_INFO
               "debug: reserved %d areas of %d pages for debugging %s\n",
               nr_areas, 1 << page_order, rc->name);
@@ -1029,6 +1042,73 @@ static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
        return rc;              /* number of input characters */
 }
 
+
+/*
+ * flushes debug areas
+ */
+void debug_flush(debug_info_t* id, int area)
+{
+        unsigned long flags;
+        int i;
+
+        if(!id)
+                return;
+        spin_lock_irqsave(&id->lock,flags);
+        if(area == DEBUG_FLUSH_ALL){
+                id->active_area = 0;
+                memset(id->active_entry, 0, id->nr_areas * sizeof(int));
+                for (i = 0; i < id->nr_areas; i++) 
+                        memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
+        } else if(area >= 0 && area < id->nr_areas) {
+                id->active_entry[area] = 0;
+                memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO
+                        "debug: %s: area %i has been flushed\n",
+                        id->name, area);
+        } else {
+                printk(KERN_INFO
+                        "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
+                        id->name, area, 0, id->nr_areas-1);
+        }
+        spin_unlock_irqrestore(&id->lock,flags);
+}
+
+/*
+ * view function: flushes debug areas 
+ */
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t in_buf_size, loff_t * offset)
+{
+        char input_buf[1];
+        int rc = in_buf_size;
+        if (*offset != 0)
+                goto out;
+        if (copy_from_user(input_buf, user_buf, 1)){
+                rc = -EFAULT;
+                goto out;
+        }
+        if(input_buf[0] == '-') { 
+                debug_flush(id, DEBUG_FLUSH_ALL);
+                goto out;
+        }
+        if (isdigit(input_buf[0])) {
+                int area = ((int) input_buf[0] - (int) '0');
+                debug_flush(id, area);
+                goto out;
+        }
+
+        printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
+
+      out:
+        *offset += in_buf_size;
+        return rc;              /* number of input characters */
+}
+
 /*
  * prints debug header in raw format
  */
index 8f4f2384cd116c313d319af574ece0ab0a322d7b..16006eda0435ea105e8e3e35fcb43e3a74fbb605 100644 (file)
@@ -89,17 +89,25 @@ processor    = 92
  *    R15 - kernel stack pointer
  */
 
-        .macro  SAVE_ALL psworg          # system entry macro
+        .macro  SAVE_ALL psworg,sync     # system entry macro
         stmg    %r14,%r15,__LC_SAVE_AREA
-        stam    %a2,%a4,__LC_SAVE_AREA+16
         tm      \psworg+1,0x01           # test problem state bit
-        jz      0f                       # skip stack setup save
-        lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
-        slr     %r14,%r14
-        sar     %a2,%r14                 # set ac.reg. 2 to primary space
-        lhi     %r14,1
-        sar     %a4,%r14                 # set access reg. 4 to home space
-0:      aghi    %r15,-SP_SIZE            # make room for registers & psw
+       stam    %a2,%a4,__LC_SAVE_AREA+16
+       .if     \sync
+        jz      1f                       # skip stack setup save
+       .else
+       jnz     0f                       # from user -> load kernel stack
+       lg      %r14,__LC_ASYNC_STACK    # are we already on the async. stack ?
+       slgr    %r14,%r15
+       srag    %r14,%r14,14
+       jz      1f
+       lg      %r15,__LC_ASYNC_STACK    # load async. stack
+       j       1f
+       .endif
+0:     lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
+       larl    %r14,.Lc_ac
+       lam     %a2,%a4,0(%r14)
+1:      aghi    %r15,-SP_SIZE            # make room for registers & psw
         nill    %r15,0xfff8              # align stack pointer to 8
         stmg    %r0,%r14,SP_R0(%r15)     # store gprs 0-14 to kernel stack
         stg     %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
@@ -112,7 +120,7 @@ processor    = 92
         xc      0(8,%r15),0(%r15)        # clear back chain
         .endm
 
-        .macro  RESTORE_ALL              # system exit macro
+        .macro  RESTORE_ALL sync         # system exit macro
         mvc     __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore
         lam     %a0,%a15,SP_AREGS(%r15)  # load the access registers
         lmg     %r0,%r15,SP_R0(%r15)     # load gprs 0-15 of user
@@ -121,8 +129,8 @@ processor    = 92
         .endm
 
         .macro  GET_CURRENT
-        lghi    %r9,-16384               # load pointer to task_struct to %r9
-        ngr     %r9,15
+       lg      %r9,__LC_KERNEL_STACK    # load pointer to task_struct to %r9
+       aghi    %r9,-16384
         .endm
 
 
@@ -160,6 +168,25 @@ resume_noper:
         lmg     %r6,%r15,48(%r15)       # load resume registers of next task
         br      %r14
 
+/*
+ * do_softirq calling function. We want to run the softirq functions on the
+ * asynchronous interrupt stack.
+ */
+       .global do_call_softirq
+do_call_softirq:
+       stmg    %r12,%r15,48(%r15)
+       lgr     %r12,%r15
+       lg      %r0,__LC_ASYNC_STACK
+       slgr    %r0,%r15
+       srag    %r0,%r0,14
+       je      0f
+       lg      %r15,__LC_ASYNC_STACK
+0:     aghi    %r15,-STACK_FRAME_OVERHEAD
+       stg     %r12,0(%r15)            # store back chain
+       brasl   %r14,do_softirq
+       lmg     %r12,%r15,48(%r12)
+       br      %r14
+       
 /*
  * SVC interrupt handler routine. System calls are synchronous events and
  * are executed with interrupts enabled.
@@ -167,7 +194,7 @@ resume_noper:
 
        .globl  system_call
 system_call:
-        SAVE_ALL __LC_SVC_OLD_PSW
+        SAVE_ALL __LC_SVC_OLD_PSW,1
        mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
 pgm_system_call:
         GET_CURRENT               # load pointer to task_struct to R9
@@ -202,7 +229,7 @@ sysc_leave:
         tm      SP_PGM_OLD_ILC(%r15),0xff
         jz      pgm_svcret
        stnsm   48(%r15),0xfc         # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 1
 
 #
 # call do_signal before return
@@ -565,9 +592,9 @@ sys_call_table:
        .long  SYSCALL(sys_mmap2,sys32_mmap2_wrapper)
        .long  SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper)
-        .long  SYSCALL(sys_ni_syscall,sys32_stat64)     /* 195 */
-        .long  SYSCALL(sys_ni_syscall,sys32_lstat64)   
-        .long  SYSCALL(sys_ni_syscall,sys32_fstat64)    
+        .long  SYSCALL(sys_ni_syscall,sys32_stat64_wrapper)     /* 195 */
+        .long  SYSCALL(sys_ni_syscall,sys32_lstat64_wrapper)   
+        .long  SYSCALL(sys_ni_syscall,sys32_fstat64_wrapper)    
        .long  SYSCALL(sys_lchown,sys32_lchown_wrapper)
        .long  SYSCALL(sys_getuid,sys_getuid)
        .long  SYSCALL(sys_getgid,sys_getgid)         /* 200 */
@@ -592,7 +619,10 @@ sys_call_table:
         .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
        .long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
        .long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-        .rept  255-221
+       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 222 - reserved for posix_acl */
+       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 223 - reserved for posix_acl */
+       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */
+        .rept  255-224
        .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
        .endr
 
@@ -626,7 +656,7 @@ pgm_check_handler:
        lpswe   __LC_PGM_OLD_PSW
 # it was a single stepped SVC that is causing all the trouble
 pgm_svcper:
-       SAVE_ALL __LC_SVC_OLD_PSW
+       SAVE_ALL __LC_SVC_OLD_PSW,1
         mvc     SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
         j       pgm_system_call          # now do the svc
 pgm_svcret:
@@ -636,7 +666,7 @@ pgm_svcret:
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
        j       pgm_no_sv
 pgm_sv:
-       SAVE_ALL __LC_PGM_OLD_PSW
+       SAVE_ALL __LC_PGM_OLD_PSW,1
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
         llgh    %r7,__LC_PGM_ILC         # load instruction length
        GET_CURRENT
@@ -668,7 +698,7 @@ pgm_dn: nill    %r8,0x80          # check for per exception
  */
         .globl io_int_handler
 io_int_handler:
-        SAVE_ALL __LC_IO_OLD_PSW
+        SAVE_ALL __LC_IO_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
        llgh    %r3,__LC_SUBCHANNEL_NR # load subchannel number
@@ -701,7 +731,7 @@ io_return_bh:
         jnz     io_signal_return
 io_leave:
         stnsm   48(%r15),0xfc          # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #
 # call do_softirq and return from syscall, if interrupt-level
@@ -732,7 +762,7 @@ io_signal_return:
  */
         .globl  ext_int_handler
 ext_int_handler:
-        SAVE_ALL __LC_EXT_OLD_PSW
+        SAVE_ALL __LC_EXT_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
         llgh    %r3,__LC_EXT_INT_CODE  # error code
@@ -760,10 +790,10 @@ ext_int_found:
  */
         .globl mcck_int_handler
 mcck_int_handler:
-        SAVE_ALL __LC_MCK_OLD_PSW
+        SAVE_ALL __LC_MCK_OLD_PSW,0
        brasl   %r14,s390_do_machine_check
 mcck_return:
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #ifdef CONFIG_SMP
 /*
@@ -771,10 +801,10 @@ mcck_return:
  */
         .globl restart_int_handler
 restart_int_handler:
-        lg      %r15,__LC_KERNEL_STACK # load ksp
-        lhi     %r10,__LC_CREGS_SAVE_AREA
+        lg      %r15,__LC_SAVE_AREA+120 # load ksp
+        lghi    %r10,__LC_CREGS_SAVE_AREA
         lctlg   %c0,%c15,0(%r10) # get new ctl regs
-        lhi     %r10,__LC_AREGS_SAVE_AREA
+        lghi    %r10,__LC_AREGS_SAVE_AREA
         lam     %a0,%a15,0(%r10)
         stosm   0(%r15),0x04           # now we can turn dat on
         lmg     %r6,%r15,48(%r15)      # load registers from clone
@@ -794,3 +824,8 @@ restart_crash:
 restart_go:
 #endif
 
+/*
+ * Integer constants
+ */
+               .align 4
+.Lc_ac:        .long  0,0,1
index e1dc4403e69f42684118527cf753ea6834a10796..189f4880326421a6048cde91eeb235de25c83587 100644 (file)
@@ -261,7 +261,7 @@ iplstart:
        l     %r1,0xb8                         # load ipl subchannel number
         la    %r2,IPL_BS                       # load start address
         bas   %r14,.Lloader                    # load rest of ipl image
-        larl  %r12,parmarea                    # pointer to parameter area
+        larl  %r12,_pstart                     # pointer to parameter area
         st    %r1,IPL_DEVICE+4-PARMAREA(%r12)  # store ipl device number
 
 #
@@ -464,7 +464,7 @@ startup:basr  %r13,0                     # get base
         sigp  %r1,%r0,0x12               # switch to esame mode
        sam64                            # switch to 64 bit mode
        lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
-       larl  %r12,parmarea              # pointer to parameter area
+       larl  %r12,_pstart               # pointer to parameter area
                                         # move IPL device to lowcore
         mvc   __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
                                         # set program check new psw mask
@@ -472,42 +472,64 @@ startup:basr  %r13,0                     # get base
 
 
 #
-# find out memory size.
+# find memory chunks.
 #
-       la    %r1,1f-.LPG1(%r13)         # set program check address
+       larl  %r1,.Lchkmem               # set program check address
        stg   %r1,__LC_PGM_NEW_PSW+8
-        lghi  %r2,1
-        sllg  %r2,%r2,17                 # test in increments of 128KB
-       lgr   %r1,%r2
-       aghi  %r1,-8                     # test last word in the segment
-0:     lg    %r0,0(%r1)                 # test 128KB segment
-        stg   %r0,0(%r1)
-       algr  %r1,%r2                    # add 128KB
-       bc    12,0b-.LPG1(%r13)          # r1 < 2^64 -> loop
-1:     ng    %r1,.L4malign-.LPG1(%r13)  # align to multiples of 4M
-       larl  %r3,memory_size-.
-       stg   %r1,0(%r3)                 # store memory size
-#
-# find out memory size part 2. Running native the HSA is located at
-# 2GB and we will get an addressing exception trying to access it.
-# We have to restart the scan at 2GB to find out if the machine has
-# more than 2GB of storage.
-#
-       la    %r1,1f-.LPG1(%r13)         # set program check address
-       stg   %r1,__LC_PGM_NEW_PSW+8
-       lg    %r1,.Lscan2g-.LPG1(%r13)   # restart scanning @ 2GB + 128K - 8
-0:     lg    %r0,0(%r1)                 # test 128KB segment
-       stg   %r0,0(%r1)
-       algr  %r1,%r2                    # add 128 KB
-       bc    12,0b-.LPG1(%r13)          # r1 < 2^64 -> loop
-1:     clg   %r1,.Lscan2g-.LPG1(%r13)   # program check @ 2GB + 128K - 8 ?
-       be    2f-.LPG1(%r13)
-       ng    %r1,.L4malign-.LPG1(%r13)  # align to multiples of 4M
-       larl  %r3,memory_size-.
-       stg   %r1,0(%r3)                 # store memory size
-2:
-
-       larl  %r12,machine_flags-.
+       la    %r1,1                      # test in increments of 128KB
+       sllg  %r1,%r1,17
+       larl  %r3,memory_chunk
+       slgr  %r4,%r4                    # set start of chunk to zero
+       slgr  %r5,%r5                    # set end of chunk to zero
+       slr  %r6,%r6                     # set access code to zero
+.Lloop:
+       tprot 0(%r5),0                   # test protection of first byte
+       ipm   %r7
+       srl   %r7,28
+       clr   %r6,%r7                    # compare cc with last access code
+       je    .Lsame
+       clgr  %r4,%r5                    # chunk size > 0?
+       je    .Lsize0
+       stg   %r4,0(%r3)                 # store start address of chunk
+       lgr   %r0,%r5
+       slgr  %r0,%r4
+       stg   %r0,8(%r3)                 # store size of chunk
+       st    %r6,20(%r3)                # store type of chunk
+       la    %r3,24(%r3)
+       lgr   %r4,%r5                    # set start to end
+       larl  %r8,memory_size
+       stg   %r5,0(%r8)                 # store memory size
+.Lsize0:
+       lr    %r6,%r7                    # set access code to last cc
+.Lsame:
+       algr  %r5,%r1                    # add 128KB to end of chunk
+       brc   12,.Lloop
+.Lchkmem:                               # > 16EB or tprot got a program check
+       clgr  %r4,%r5                    # chunk size > 0?
+       je    .Ldonemem
+       stg   %r4,0(%r3)                 # store start address of chunk
+       lgr   %r0,%r5
+       slgr  %r0,%r4
+       stg   %r0,8(%r3)                 # store size of chunk
+       st    %r6,20(%r3)                # store type of chunk
+       la    %r3,24(%r3)
+       lgr   %r4,%r5
+       larl  %r8,memory_size
+       stg   %r5,0(%r8)                 # store memory size
+#
+# Running native the HSA is located at 2GB and we will get an
+# addressing exception trying to access it. We have to restart
+# the scan at 2GB to find out if the machine has more than 2GB.
+#
+       lghi  %r4,1
+       sllg  %r4,%r4,31
+       clgr  %r5,%r4
+       jhe   .Ldonemem
+       lgr   %r5,%r4
+       j     .Lloop
+.Ldonemem:             
+
+       larl  %r12,machine_flags
 #
 # find out if we are running under VM
 #
@@ -539,7 +561,7 @@ startup:basr  %r13,0                     # get base
 .Lentry:.quad  0x0000000180000000,_stext
 .Lctl:  .quad  0x04b50002               # cr0: various things
         .quad  0                        # cr1: primary space segment table
-        .quad  0                        # cr2: access register translation
+        .quad  .Lduct                   # cr2: dispatchable unit control table
         .quad  0                        # cr3: instruction authorization
         .quad  0                        # cr4: instruction authorization
         .quad  0                        # cr5:  various things
@@ -557,11 +579,16 @@ startup:basr  %r13,0                     # get base
 .L4malign:.quad 0xffffffffffc00000
 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
 
+       .org PARMAREA-64
+.Lduct:        .long 0,0,0,0,0,0,0,0
+       .long 0,0,0,0,0,0,0,0
+
 #
 # params at 10400 (setup.h)
 #
        .org   PARMAREA
-parmarea:
+       .global _pstart
+_pstart:
        .quad  0                        # IPL_DEVICE
         .quad  RAMDISK_ORIGIN           # INITRD_START
         .quad  RAMDISK_SIZE             # INITRD_SIZE
@@ -569,31 +596,28 @@ parmarea:
         .org   COMMAND_LINE
        .byte  "root=/dev/ram0 ro"
         .byte  0
+       .org   0x11000
+       .global _pend
+_pend: 
 
-#
-# startup-code, running in virtual mode
-#
 #ifdef CONFIG_SHARED_KERNEL
        .org   0x100000
-#else
-        .org   0x10800
 #endif
+       
+#
+# startup-code, running in virtual mode
+#
         .globl _stext
 _stext:        basr  %r13,0                    # get base
 .LPG2:
 #
-# Setup lowcore
+# Setup stack
 #
-        l     %r1,__LC_IPLDEV           # load ipl device number
-        spx   .Lprefix-.LPG2(%r13)      # set prefix to linux lowcore
-        st    %r1,__LC_IPLDEV           # store ipl device number
        larl  %r15,init_task_union
         aghi  %r15,16384                # init_task_union + 16384
         stg   %r15,__LC_KERNEL_STACK    # set end of kernel stack
         aghi  %r15,-160
         xc    0(8,%r15),0(%r15)         # set backchain to zero
-        lghi  %r0,-1
-        stg   %r0,__LC_KERNEL_LEVEL     # set interrupt count to -1
 #
 # clear bss memory
 #
@@ -621,6 +645,5 @@ _stext:     basr  %r13,0                    # get base
 #
             .align 8
 .Ldw:       .quad  0x0002000180000000,0x0000000000000000
-.Lprefix:   .long  init_S390_lowcore   
 .Laregs:    .long  0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0
 
index 86c284572828557c2f14728fd411be3d258b9675..34fa4bd33c571b75b0ecb58e29498e950b1c86fb 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/dasd.h>
+#include <asm/sockios.h>
 
 #include "linux32.h"
 
@@ -452,6 +453,8 @@ static struct ioctl32_list ioctl32_handler_table[] = {
        IOCTL32_DEFAULT(VT_LOCKSWITCH),
        IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
 
+       IOCTL32_DEFAULT(SIOCGSTAMP),
+
        IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
        IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
        IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
index 539abd69ede2636337c51de787d5c08bc36ac166..6f85af23b6c185e1b3c709a454697194bde7a09d 100644 (file)
@@ -2884,7 +2884,7 @@ static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
                        err = copy_from_user(kaddr + offset, (char *)A(str),
                                             bytes_to_copy);
                        flush_page_to_ram(page);
-                       kunmap((unsigned long)kaddr);
+                       kunmap(page);
 
                        if (err)
                                return -EFAULT;
@@ -4038,57 +4038,55 @@ extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
 }
 
 struct stat64_emu31 {
-        unsigned short  st_dev;
-        unsigned char   __pad0[6];
-
-        long long      st_ino;
-        unsigned int    st_mode;
-        unsigned int    st_nlink;
-
-        __u32          st_uid;
-        __u32          st_gid;
-
-        unsigned short  st_rdev;
-        unsigned char   __pad3[10];
-
-        long long       st_size;
-        __u32          st_blksize;
-
-        __u32          st_blocks;      /* Number 512-byte blocks allocated. */
-        __u32          __pad4;         /* future possible st_blocks high bits */
-
-        __u32          st_atime;
-        __u32          __pad5;
-
-        __u32          st_mtime;
-        __u32          __pad6;
-
-        __u32          st_ctime;
-        __u32          __pad7;         /* will be high 32 bits of ctime someday */
-
-        __u32          __unused1;
-        __u32          __unused2;
-};
+       unsigned char   __pad0[6];
+       unsigned short  st_dev;
+       unsigned int    __pad1;
+#define STAT64_HAS_BROKEN_ST_INO        1
+       u32             __st_ino;
+       unsigned int    st_mode;
+       unsigned int    st_nlink;
+       u32             st_uid;
+       u32             st_gid;
+       unsigned char   __pad2[6];
+       unsigned short  st_rdev;
+       unsigned int    __pad3;
+       long            st_size;
+       u32             st_blksize;
+       unsigned char   __pad4[4];
+       u32             __pad5;     /* future possible st_blocks high bits */
+       u32             st_blocks;  /* Number 512-byte blocks allocated. */
+       u32             st_atime;
+       u32             __pad6;
+       u32             st_mtime;
+       u32             __pad7;
+       u32             st_ctime;
+       u32             __pad8;     /* will be high 32 bits of ctime someday */
+       unsigned long   st_ino;
+};     
 
 static inline int
 putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
 {
-    int err;
-    
-    err = put_user (kbuf->st_dev, &ubuf->st_dev);
-    err |= __put_user (kbuf->st_ino, &ubuf->st_ino);
-    err |= __put_user (kbuf->st_mode, &ubuf->st_mode);
-    err |= __put_user (kbuf->st_nlink, &ubuf->st_nlink);
-    err |= __put_user (kbuf->st_uid, &ubuf->st_uid);
-    err |= __put_user (kbuf->st_gid, &ubuf->st_gid);
-    err |= __put_user (kbuf->st_rdev, &ubuf->st_rdev);
-    err |= __put_user (kbuf->st_size, &ubuf->st_size);
-    err |= __put_user (kbuf->st_blksize, &ubuf->st_blksize);
-    err |= __put_user (kbuf->st_blocks, &ubuf->st_blocks);
-    err |= __put_user (kbuf->st_atime, &ubuf->st_atime);
-    err |= __put_user (kbuf->st_mtime, &ubuf->st_mtime);
-    err |= __put_user (kbuf->st_ctime, &ubuf->st_ctime);
-    return err;
+    struct stat64_emu31 tmp;
+   
+    memset(&tmp, 0, sizeof(tmp));
+
+    tmp.st_dev = (unsigned short)kbuf->st_dev;
+    tmp.st_ino = kbuf->st_ino;
+    tmp.__st_ino = (u32)kbuf->st_ino;
+    tmp.st_mode = kbuf->st_mode;
+    tmp.st_nlink = (unsigned int)kbuf->st_nlink;
+    tmp.st_uid = kbuf->st_uid;
+    tmp.st_gid = kbuf->st_gid;
+    tmp.st_rdev = (unsigned short)kbuf->st_rdev;
+    tmp.st_size = kbuf->st_size;
+    tmp.st_blksize = (u32)kbuf->st_blksize;
+    tmp.st_blocks = (u32)kbuf->st_blocks;
+    tmp.st_atime = (u32)kbuf->st_atime;
+    tmp.st_mtime = (u32)kbuf->st_mtime;
+    tmp.st_ctime = (u32)kbuf->st_ctime;
+
+    return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
 }
 
 extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
@@ -4131,7 +4129,7 @@ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf, lo
            return err;
 
     set_fs (KERNEL_DS);
-    ret = sys_newstat(tmp, &s);
+    ret = sys_newlstat(tmp, &s);
     set_fs (old_fs);
     putname(tmp);
     if (putstat64 (statbuf, &s)) 
index c3641b0a0b156e0af1f0ce89cde72180c7ba419e..7d16fff6355384fb4da2e8d2c398497071efd61c 100644 (file)
@@ -237,8 +237,8 @@ struct ucontext32 {
        __u32                   uc_flags;
        __u32                   uc_link;        /* pointer */   
        stack_t32               uc_stack;
+       _sigregs32              uc_mcontext;
        sigset_t32              uc_sigmask;     /* mask last for extensibility */
-       __u32                   sc;             /* pointer */
 };
 
 #endif /* !CONFIG_S390_SUPPORT */
diff --git a/arch/s390x/kernel/lowcore.S b/arch/s390x/kernel/lowcore.S
deleted file mode 100644 (file)
index 4cf3bf8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  arch/s390/kernel/lowcore.S
- *    S390 lowcore definition.
- *
- *  S390 64 bit Version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hpenner@de.ibm.com)
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- */
-#include <asm/lowcore.h>
-       
-         .align 8192
-         .globl init_S390_lowcore
-init_S390_lowcore:      
-         .fill 0x1a0-0x000,1,0 
-         .quad  _RESTART_PSW_MASK
-         .quad  restart_int_handler 
-         .quad  _EXT_PSW_MASK
-         .quad  ext_int_handler 
-         .quad  _SVC_PSW_MASK
-         .quad  system_call
-         .quad  _PGM_PSW_MASK
-         .quad  pgm_check_handler 
-         .quad  _MCCK_PSW_MASK
-         .quad  mcck_int_handler 
-EXT_PSW: .quad  _IO_PSW_MASK
-         .quad  io_int_handler
-        .fill  0x2000-0x200,1,0
diff --git a/arch/s390x/kernel/mathemu.c b/arch/s390x/kernel/mathemu.c
deleted file mode 100644 (file)
index db6dc94..0000000
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- *  arch/s390/kernel/mathemu.c
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *
- * 'mathemu.c' handles IEEE instructions on a S390 processor
- * that does not have the IEEE fpu
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-
-#include <asm/uaccess.h>
-#include <asm/mathemu.h>
-
-#ifdef CONFIG_SYSCTL
-int sysctl_ieee_emulation_warnings=1;
-#endif
-
-static void display_emulation_not_implemented(char *instr)
-{
-       struct pt_regs *regs;
-       __u16 *location;
-       
-#if CONFIG_SYSCTL
-       if(sysctl_ieee_emulation_warnings)
-#endif
-       {
-               regs=current->thread.regs;
-               location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
-               printk("%s ieee fpu instruction not emulated process name: %s pid: %d \n",
-                      instr,
-                      current->comm, current->pid);
-               printk("%s's PSW:    %08lx %08lx\n",instr,
-                      (unsigned long) regs->psw.mask,
-                      (unsigned long) location);
-       }
-}
-
-
-static void set_CC_df(__u64 val1,__u64 val2) {
-        int rc;
-        rc = __cmpdf2(val1,val2);
-        current->thread.regs->psw.mask &= 0xFFFFCFFFFFFFFFFFL;
-        switch (rc) {
-                case -1:
-                        current->thread.regs->psw.mask |= 0x0000100000000000L;
-                        break;
-                case 1:
-                        current->thread.regs->psw.mask |= 0x0000200000000000L;
-                        break;
-        }
-}
-
-static void set_CC_sf(__u32 val1,__u32 val2) {
-        int rc;
-        rc = __cmpsf2(val1,val2);
-        current->thread.regs->psw.mask &= 0xFFFFCFFFFFFFFFFF;
-        switch (rc) {
-                case -1:
-                        current->thread.regs->psw.mask |= 0x0000100000000000L;
-                        break;
-                case 1:
-                        current->thread.regs->psw.mask |= 0x0000200000000000L;
-                        break;
-        }
-}
-
-
-static void emu_adb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __adddf3(current->thread.fp_regs.fprs[rx].d,val);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_adbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __adddf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_aeb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __addsf3(current->thread.fp_regs.fprs[rx].f,val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_aebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __addsf3(current->thread.fp_regs.fprs[rx].f,
-                                        current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_axbr (int rx, int ry) {
-        display_emulation_not_implemented("axbr");
-}
-
-static void emu_cdb (int rx, __u64 val) {
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,val);
-}
-
-static void emu_cdbr (int rx, int ry) {
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,current->thread.fp_regs.fprs[ry].d);
-}
-
-static void emu_cdfbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d =
-                     __floatsidf(current->thread.regs->gprs[ry]);
-}
-
-static void emu_ceb (int rx, __u32 val) {
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,val);
-}
-
-static void emu_cebr (int rx, int ry) {
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_cefbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f =
-                     __floatsisf(current->thread.regs->gprs[ry]);
-}
-
-static void emu_cfdbr (int rx, int ry, int mask) {
-        current->thread.regs->gprs[rx] =
-                     __fixdfsi(current->thread.fp_regs.fprs[ry].d);
-}
-
-static void emu_cfebr (int rx, int ry, int mask) {
-        current->thread.regs->gprs[rx] =
-                     __fixsfsi(current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_cfxbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("cfxbr");
-}
-
-static void emu_cxbr (int rx, int ry) {
-        display_emulation_not_implemented("cxbr");
-}
-
-static void emu_cxfbr (int rx, int ry) {
-        display_emulation_not_implemented("cxfbr");
-}
-
-static void emu_ddb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __divdf3(current->thread.fp_regs.fprs[rx].d,val);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_ddbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __divdf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_deb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __divsf3(current->thread.fp_regs.fprs[rx].f,val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_debr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __divsf3(current->thread.fp_regs.fprs[rx].f,
-                                         current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_didbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("didbr");
-}
-
-static void emu_diebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("diebr");
-}
-
-static void emu_dxbr (int rx, int ry) {
-        display_emulation_not_implemented("dxbr");
-}
-
-static void emu_efpc (int rx, int ry) {
-        display_emulation_not_implemented("efpc");
-}
-
-static void emu_fidbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("fidbr");
-}
-
-static void emu_fiebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("fiebr");
-}
-
-static void emu_fixbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("fixbr");
-}
-
-static void emu_kdb (int rx, __u64 val) {
-        display_emulation_not_implemented("kdb");
-}
-
-static void emu_kdbr (int rx, int ry) {
-        display_emulation_not_implemented("kdbr");
-}
-
-static void emu_keb (int rx, __u32 val) {
-        display_emulation_not_implemented("keb");
-}
-
-static void emu_kebr (int rx, int ry) {
-        display_emulation_not_implemented("kebr");
-}
-
-static void emu_kxbr (int rx, int ry) {
-        display_emulation_not_implemented("kxbr");
-}
-
-static void emu_lcdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d =
-        __negdf2(current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_lcebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f =
-        __negsf2(current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lcxbr (int rx, int ry) {
-        display_emulation_not_implemented("lcxbr");
-}
-
-static void emu_ldeb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].d = __extendsfdf2(val);
-}
-
-static void emu_ldebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d =
-        __extendsfdf2(current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_ldxbr (int rx, int ry) {
-        display_emulation_not_implemented("ldxbr");
-}
-
-static void emu_ledbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __truncdfsf2(current->thread.fp_regs.fprs[ry].d);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lexbr (int rx, int ry) {
-        display_emulation_not_implemented("lexbr");
-}
-
-static void emu_lndbr (int rx, int ry) {
-        display_emulation_not_implemented("lndbr");
-}
-
-static void emu_lnebr (int rx, int ry) {
-        display_emulation_not_implemented("lnebr");
-}
-
-static void emu_lnxbr (int rx, int ry) {
-        display_emulation_not_implemented("lnxbr");
-}
-
-static void emu_lpdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __absdf2(current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0);
-}
-
-static void emu_lpebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __abssf2(current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lpxbr (int rx, int ry) {
-        display_emulation_not_implemented("lpxbr");
-}
-
-static void emu_ltdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = current->thread.fp_regs.fprs[ry].d;
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_ltebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = current->thread.fp_regs.fprs[ry].f;
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_ltxbr (int rx, int ry) {
-        display_emulation_not_implemented("ltxbr");
-}
-
-static void emu_lxdb (int rx, __u64 val) {
-        display_emulation_not_implemented("lxdb");
-}
-
-static void emu_lxdbr (int rx, int ry) {
-        display_emulation_not_implemented("lxdbr");
-}
-
-static void emu_lxeb (int rx, __u32 val) {
-        display_emulation_not_implemented("lxeb");
-}
-
-static void emu_lxebr (int rx, int ry) {
-        display_emulation_not_implemented("lxebr");
-}
-
-static void emu_madb (int rx, __u64 val, int mask) {
-        display_emulation_not_implemented("madb");
-}
-
-static void emu_madbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("madbr");
-}
-
-static void emu_maeb (int rx, __u32 val, int mask) {
-        display_emulation_not_implemented("maeb");
-}
-
-static void emu_maebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("maebr");
-}
-
-static void emu_mdb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __muldf3(current->thread.fp_regs.fprs[rx].d,val);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_mdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __muldf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_mdeb (int rx, __u32 val) {
-        display_emulation_not_implemented("mdeb");
-}
-
-static void emu_mdebr (int rx, int ry) {
-        display_emulation_not_implemented("mdebr");
-}
-
-static void emu_meeb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __mulsf3(current->thread.fp_regs.fprs[rx].f,
-                                         val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_meebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __mulsf3(current->thread.fp_regs.fprs[rx].f,
-                                         current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_msdb (int rx, __u64 val, int mask) {
-        display_emulation_not_implemented("msdb");
-}
-
-static void emu_msdbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("msdbr");
-}
-
-static void emu_mseb (int rx, __u32 val, int mask) {
-        display_emulation_not_implemented("mseb");
-}
-
-static void emu_msebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("msebr");
-}
-
-static void emu_mxbr (int rx, int ry) {
-        display_emulation_not_implemented("mxbr");
-}
-
-static void emu_mxdb (int rx, __u64 val) {
-        display_emulation_not_implemented("mxdb");
-}
-
-static void emu_mxdbr (int rx, int ry) {
-        display_emulation_not_implemented("mxdbr");
-}
-
-static void emu_sdb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __subdf3(current->thread.fp_regs.fprs[rx].d,
-                                         val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_sdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __subdf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_seb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __subsf3(current->thread.fp_regs.fprs[rx].f,
-                                         val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_sebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __subsf3(current->thread.fp_regs.fprs[rx].f,
-                                         current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_sfpc (int rx, int ry) {
-        display_emulation_not_implemented("sfpc");
-}
-
-static void emu_sqdb (int rx, __u64 val) {
-        display_emulation_not_implemented("sqdb");
-}
-
-static void emu_sqdbr (int rx, int ry) {
-        display_emulation_not_implemented("sqdbr");
-}
-
-static void emu_sqeb (int rx, __u32 val) {
-        display_emulation_not_implemented("sqeb");
-}
-
-static void emu_sqebr (int rx, int ry) {
-        display_emulation_not_implemented("sqebr");
-}
-
-static void emu_sqxbr (int rx, int ry) {
-        display_emulation_not_implemented("sqxbr");
-}
-
-static void emu_sxbr (int rx, int ry) {
-        display_emulation_not_implemented("sxbr");
-}
-
-static void emu_tcdb (int rx, __u64 val) {
-        display_emulation_not_implemented("tcdb");
-}
-
-static void emu_tceb (int rx, __u32 val) {
-        display_emulation_not_implemented("tceb");
-}
-
-static void emu_tcxb (int rx, __u64 val) {
-        display_emulation_not_implemented("tcxb");
-}
-
-
-static inline void emu_load_regd(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* load reg from fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     ld    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
-                        : "1" );
-        }
-}
-
-static inline void emu_load_rege(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* load reg from fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     le    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
-                        : "1" );
-        }
-}
-
-static inline void emu_store_regd(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* store reg to fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     std   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
-                        : "1" );
-        }
-}
-
-
-static inline void emu_store_rege(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* store reg to fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     ste   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
-                        : "1" );
-        }
-}
-
-int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
-        static const __u8 format_table[] = {
-                2, 2, 2, 2, 9, 1, 2, 1, 2, 2, 2, 2, 9, 2, 4, 4,
-                1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 3,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                1, 1, 1, 1,10, 1, 1, 3, 1, 1, 1, 1, 1, 1, 0, 0,
-                0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 3,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
-                0, 0, 0, 0, 5, 6, 6, 0, 7, 8, 8, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        };
-        static const void *jump_table[]= {
-                emu_lpebr, emu_lnebr, emu_ltebr, emu_lcebr,
-                emu_ldebr, emu_lxdbr, emu_lxebr, emu_mxdbr,
-                emu_kebr,  emu_cebr,  emu_aebr,  emu_sebr,
-                emu_mdebr, emu_debr,  emu_maebr, emu_msebr,
-                emu_lpdbr, emu_lndbr, emu_ltdbr, emu_lcdbr,
-                emu_sqebr, emu_sqdbr, emu_sqxbr, emu_meebr,
-                emu_kdbr,  emu_cdbr,  emu_adbr,  emu_sdbr,
-                emu_mdbr,  emu_ddbr,  emu_madbr, emu_msdbr,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_lpxbr, emu_lnxbr, emu_ltxbr, emu_lcxbr,
-                emu_ledbr, emu_ldxbr, emu_lexbr, emu_fixbr,
-                emu_kxbr,  emu_cxbr,  emu_axbr,  emu_sxbr,
-                emu_mxbr,  emu_dxbr,  NULL,      NULL,
-                NULL,      NULL,      NULL,      emu_diebr,
-                NULL,      NULL,      NULL,      emu_fiebr,
-                NULL,      NULL,      NULL,      emu_didbr,
-                NULL,      NULL,      NULL,      emu_fidbr,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_sfpc,  NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_efpc,  NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_cefbr, emu_cdfbr, emu_cxfbr, NULL,
-                emu_cfebr, emu_cfdbr, emu_cfxbr
-        };
-
-        switch (format_table[opcode[1]]) {
-        case 1: /* RRE format, double operation */
-                emu_store_regd((opcode[3]>>4)&15);
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_regd((opcode[3]>>4)&15);
-                emu_load_regd(opcode[3]&15);
-                return 0;
-        case 2: /* RRE format, float operation */
-                emu_store_rege((opcode[3]>>4)&15);
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_rege((opcode[3]>>4)&15);
-                emu_load_rege(opcode[3]&15);
-                return 0;
-        case 3: /* RRF format, double operation */
-                emu_store_regd((opcode[3]>>4)&15);
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                emu_load_regd((opcode[3]>>4)&15);
-                emu_load_regd(opcode[3]&15);
-                return 0;
-        case 4: /* RRF format, float operation */
-                emu_store_rege((opcode[3]>>4)&15);
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                emu_load_rege((opcode[3]>>4)&15);
-                emu_load_rege(opcode[3]&15);
-                return 0;
-        case 5: /* RRE format, cefbr instruction */
-                emu_store_rege((opcode[3]>>4)&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_rege((opcode[3]>>4)&15);
-                return 0;
-        case 6: /* RRE format, cdfbr & cxfbr instruction */
-                emu_store_regd((opcode[3]>>4)&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_regd((opcode[3]>>4)&15);
-                return 0;
-                /* FIXME !! */
-                return 0;
-        case 7: /* RRF format, cfebr instruction */
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                return 0;
-        case 8: /* RRF format, cfdbr & cfxbr instruction */
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                return 0;
-       case 9: /* RRE format, ldebr & mdebr instruction */
-               /* float store but double load */
-                emu_store_rege((opcode[3]>>4)&15);
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_regd((opcode[3]>>4)&15);
-                return 0;
-        case 10: /* RRE format, ledbr instruction */
-               /* double store but float load */
-                emu_store_regd((opcode[3]>>4)&15);
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_rege((opcode[3]>>4)&15);
-                return 0;
-        default:
-                return 1;
-        }
-}
-
-static void* calc_addr(struct pt_regs *regs,int rx,int rb,int disp)
-{
-  rx &= 0xf;
-  rb &= 0xf;
-  disp &= 0xfff;
-  return (void*) ((rx != 0 ? regs->gprs[rx] : 0)  + /* index */   
-         (rb != 0 ? regs->gprs[rb] : 0)  + /* base */
-         disp);
-}
-    
-int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
-        static const __u8 format_table[] = {
-                0, 0, 0, 0, 5, 1, 2, 1, 2, 2, 2, 2, 5, 2, 4, 4,
-                2, 1, 1, 0, 2, 1, 0, 2, 1, 1, 1, 1, 1, 1, 3, 3,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        };
-        static const void *jump_table[]= {
-                NULL,     NULL,     NULL,     NULL,
-                emu_ldeb, emu_lxdb, emu_lxeb, emu_mxdb,
-                emu_keb,  emu_ceb,  emu_aeb,  emu_seb,
-                emu_mdeb, emu_deb,  emu_maeb, emu_mseb,
-                emu_tceb, emu_tcdb, emu_tcxb, NULL,
-                emu_sqeb, emu_sqdb, NULL,     emu_meeb,
-                emu_kdb,  emu_cdb,  emu_adb,  emu_sdb,
-                emu_mdb,  emu_ddb,  emu_madb, emu_msdb
-        };
-
-        switch (format_table[opcode[5]]) {
-        case 1: /* RXE format, __u64 constant */ {
-                __u64 *dxb, temp;
-                __u32 opc;
-
-                emu_store_regd((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if copy_from_user fails ? */
-                copy_from_user(&temp, dxb, 8);
-                /* call the emulation function */
-                ((void (*)(int, __u64))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp);
-                emu_load_regd((opcode[1]>>4)&15);
-                return 0;
-        }
-        case 2: /* RXE format, __u32 constant */ {
-                __u32 *dxb, temp;
-                __u32 opc;
-
-                emu_store_rege((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if get_user fails ? */
-                get_user(temp, dxb);
-                /* call the emulation function */
-                ((void (*)(int, __u32))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp);
-                emu_load_rege((opcode[1]>>4)&15);
-                return 0;
-        }
-        case 3: /* RXF format, __u64 constant */ {
-                __u32 *dxb, temp;
-                __u32 opc;
-
-                emu_store_regd((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if copy_from_user fails ? */
-                copy_from_user(&temp, dxb, 8);
-                /* call the emulation function */
-                ((void (*)(int, __u32, int))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp,opcode[4]>>4);
-                emu_load_regd((opcode[1]>>4)&15);
-                return 0;
-        }
-        case 4: /* RXF format, __u32 constant */ {
-                __u32 *dxb, temp;
-                __u32 opc;
-
-                emu_store_rege((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if get_user fails ? */
-                get_user(temp, dxb);
-                /* call the emulation function */
-                ((void (*)(int, __u32, int))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp,opcode[4]>>4);
-                emu_load_rege((opcode[1]>>4)&15);
-                return 0;
-        }
-       case 5: /* RXE format, __u32 constant */
-                /* store_rege and load_regd */ 
-               {
-                __u32 *dxb, temp;
-                __u32 opc;
-                emu_store_rege((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if get_user fails ? */
-                get_user(temp, dxb);
-                /* call the emulation function */
-                ((void (*)(int, __u32))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp);
-                emu_load_regd((opcode[1]>>4)&15);
-                return 0;
-        }
-        default:
-                return 1;
-        }
-}
-
-/*
- * Emulate LDR Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
- */
-void math_emu_ldr(__u8 *opcode) {
-        __u16 opc = *((__u16 *) opcode);
-
-        if ((opc & 0x0090) == 0) {         /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
-                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
-                        "     bras  1,0f\n"
-                        "     ld    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (opc&0x00f0),
-                          "a" (&current->thread.fp_regs.fprs[opc&0x000f].d)
-                        : "1" );
-        } else if ((opc & 0x0009) == 0) {  /* test if ry in {0,2,4,6} */
-                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
-                        "     bras  1,0f\n"
-                        "     std   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" ((opc&0x000f)<<4),
-                          "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].d)
-                        : "1" );
-        } else {                          /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
-                current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =
-                        current->thread.fp_regs.fprs[opc&0x000f];
-        }
-}
-
-/*
- * Emulate LER Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
- */
-void math_emu_ler(__u8 *opcode) {
-        __u16 opc = *((__u16 *) opcode);
-
-        if ((opc & 0x0090) == 0) {         /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
-                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
-                        "     bras  1,0f\n"
-                        "     le    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (opc&0x00f0),
-                          "a" (&current->thread.fp_regs.fprs[opc&0x000f].f)
-                        : "1" );
-        } else if ((opc & 0x0009) == 0) {  /* test if ry in {0,2,4,6} */
-                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
-                        "     bras  1,0f\n"
-                        "     ste   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" ((opc&0x000f)<<4),
-                          "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].f)
-                        : "1" );
-        } else {                          /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
-                current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =
-                        current->thread.fp_regs.fprs[opc&0x000f];
-        }
-}
-
-/*
- * Emulate LD R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_ld(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u64 *dxb;
-
-        dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if copy_from_user fails ? */
-        copy_from_user(&current->thread.fp_regs.fprs[(opc>>20)&15].d, dxb, 8);
-}
-
-/*
- * Emulate LE R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_le(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u32 *mem, *dxb;
-
-        dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if get_user fails ? */
-        mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);
-        get_user(mem[0], dxb);
-}
-
-/*
- * Emulate STD R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_std(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u64 *dxb;
-        dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if copy_to_user fails ? */
-        copy_to_user(dxb, &current->thread.fp_regs.fprs[(opc>>20)&15].d, 8);
-}
-
-/*
- * Emulate STE R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_ste(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u32 *mem, *dxb;
-        dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if put_user fails ? */
-        mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);
-        put_user(mem[0], dxb);
-}
-
-/*
- * Emulate LFPC D(B)
- */
-int math_emu_lfpc(__u8 *opcode, struct pt_regs *regs) {
-        /* FIXME: how to do that ?!? */
-        return 0;
-}
-
-/*
- * Emulate STFPC D(B)
- */
-int math_emu_stfpc(__u8 *opcode, struct pt_regs *regs) {
-        /* FIXME: how to do that ?!? */
-        return 0;
-}
-
-/*
- * Emulate SRNM D(B)
- */
-int math_emu_srnm(__u8 *opcode, struct pt_regs *regs) {
-        /* FIXME: how to do that ?!? */
-        return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
index f0f504a834f1b0d81de948d344a58949c0ebe5da..07e216330b1f044d5d4d4535a72d5489396170f8 100644 (file)
@@ -44,8 +44,6 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
-
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 /*
@@ -210,7 +208,7 @@ static int sprintf_regs(int line, char *buff, struct task_struct *task, struct p
 void show_regs(struct pt_regs *regs)
 {
        char buff[80];
-       int line;
+       int i, line;
 
         printk("CPU:    %d\n",smp_processor_id());
         printk("Process %s (pid: %d, stackpage=%016lX)\n",
@@ -218,6 +216,17 @@ void show_regs(struct pt_regs *regs)
        
        for (line = 0; sprintf_regs(line, buff, current, regs); line++)
                printk(buff);
+
+       if (regs->psw.mask & PSW_PROBLEM_STATE)
+       {
+               printk("User Code:\n");
+               memset(buff, 0, 20);
+               copy_from_user(buff,
+                              (char *) (regs->psw.addr & PSW_ADDR_MASK), 20);
+               for (i = 0; i < 20; i++)
+                       printk("%02x ", buff[i]);
+               printk("\n");
+       }
 }
 
 char *task_show_regs(struct task_struct *task, char *buffer)
@@ -323,28 +332,19 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
 
 asmlinkage int sys_fork(struct pt_regs regs)
 {
-        int ret;
-
-        lock_kernel();
-        ret = do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
 }
 
 asmlinkage int sys_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-        int ret;
 
-        lock_kernel();
         clone_flags = regs.gprs[3];
         newsp = regs.orig_gpr2;
         if (!newsp)
                 newsp = regs.gprs[15];
-        ret = do_fork(clone_flags, newsp, &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(clone_flags, newsp, &regs, 0);
 }
 
 /*
index e1f64338c108485eaa97eef263e7ca0fbbd0bc66..5b9415126e79632b04150889d92f5c7c39eec346 100644 (file)
 /*
  * memory management
  */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(__copy_from_user_fixup);
-EXPORT_SYMBOL(__copy_to_user_fixup);
+EXPORT_SYMBOL_NOVERS(_oi_bitmap);
+EXPORT_SYMBOL_NOVERS(_ni_bitmap);
+EXPORT_SYMBOL_NOVERS(_zb_findmap);
+EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup);
+EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);
 
 /*
  * semaphore ops
@@ -41,12 +41,12 @@ EXPORT_SYMBOL_NOVERS(memmove);
 EXPORT_SYMBOL_NOVERS(strlen);
 EXPORT_SYMBOL_NOVERS(strchr);
 EXPORT_SYMBOL_NOVERS(strcmp);
-EXPORT_SYMBOL_NOVERS(strcat);
 EXPORT_SYMBOL_NOVERS(strncat);
 EXPORT_SYMBOL_NOVERS(strncmp);
 EXPORT_SYMBOL_NOVERS(strncpy);
 EXPORT_SYMBOL_NOVERS(strnlen);
 EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strstr);
 EXPORT_SYMBOL_NOVERS(strtok);
 EXPORT_SYMBOL_NOVERS(strpbrk);
 
@@ -66,8 +66,5 @@ EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
+EXPORT_SYMBOL_NOVERS(do_call_softirq);
 
-#if CONFIG_IP_MULTICAST
-/* Required for lcs gigibit ethernet multicast support */
-EXPORT_SYMBOL(arp_mc_map);
-#endif
index 397f8d358eea810a80a2d008f22949751176c69d..f2731a24b3dac5859c72953b94a4cb831837c66f 100644 (file)
@@ -47,6 +47,9 @@ unsigned int console_mode = 0;
 unsigned int console_device = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
+struct { unsigned long addr, size, type; } memory_chunk[16];
+#define CHUNK_READ_WRITE 0
+#define CHUNK_READ_ONLY 1
 __u16 boot_cpu_addr;
 int cpus_initialized = 0;
 unsigned long cpu_initialized = 0;
@@ -257,6 +260,8 @@ void machine_power_off(void)
  * Setup function called from init/main.c just after the banner
  * was printed.
  */
+extern char _pstart, _pend, _stext;
+
 void __init setup_arch(char **cmdline_p)
 {
         unsigned long bootmap_size;
@@ -266,18 +271,13 @@ void __init setup_arch(char **cmdline_p)
        unsigned long start_pfn, end_pfn;
         static unsigned int smptrap=0;
         unsigned long delay = 0;
+       struct _lowcore *lowcore;
+       int i;
 
         if (smptrap)
                 return;
         smptrap=1;
 
-        /*
-         * Setup lowcore information for boot cpu
-         */
-        cpu_init();
-        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-        __cpu_logical_map[0] = boot_cpu_addr;
-
         /*
          * print what head.S has found out about the machine 
          */
@@ -287,7 +287,7 @@ void __init setup_arch(char **cmdline_p)
 
         ROOT_DEV = to_kdev_t(0x0100);
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
-       memory_end = memory_size;                /* detected in head.s */
+       memory_end = memory_size & ~0x200000UL;  /* detected in head.s */
         init_mm.start_code = PAGE_OFFSET;
         init_mm.end_code = (unsigned long) &_etext;
         init_mm.end_data = (unsigned long) &_edata;
@@ -362,11 +362,26 @@ void __init setup_arch(char **cmdline_p)
        bootmap_size = init_bootmem(start_pfn, end_pfn);
 
        /*
-        * Register RAM pages with the bootmem allocator.
+        * Register RAM areas with the bootmem allocator.
         */
-       free_bootmem(start_pfn << PAGE_SHIFT, 
-                    (end_pfn - start_pfn) << PAGE_SHIFT);
-
+       for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+               unsigned long start_chunk, end_chunk;
+
+               if (memory_chunk[i].type != CHUNK_READ_WRITE)
+                       continue;
+               start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1);
+               start_chunk >>= PAGE_SHIFT;
+               end_chunk = (memory_chunk[i].addr + memory_chunk[i].size);
+               end_chunk >>= PAGE_SHIFT;
+               if (start_chunk < start_pfn)
+                       start_chunk = start_pfn;
+               if (end_chunk > end_pfn)
+                       end_chunk = end_pfn;
+               if (start_chunk < end_chunk)
+                       free_bootmem(start_chunk << PAGE_SHIFT,
+                                    (end_chunk - start_chunk) << PAGE_SHIFT);
+       }
+       
         /*
          * Reserve the bootmem bitmap itself as well. We do this in two
          * steps (first step was init_bootmem()) because this catches
@@ -390,6 +405,36 @@ void __init setup_arch(char **cmdline_p)
         }
 #endif
 
+        /*
+         * Setup lowcore for boot cpu
+         */
+       lowcore = (struct _lowcore *) 
+               __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0);
+       memset(lowcore, 0, 2*PAGE_SIZE);
+       lowcore->restart_psw.mask = _RESTART_PSW_MASK;
+       lowcore->restart_psw.addr = (addr_t) &restart_int_handler;
+       lowcore->external_new_psw.mask = _EXT_PSW_MASK;
+       lowcore->external_new_psw.addr = (addr_t) &ext_int_handler;
+       lowcore->svc_new_psw.mask = _SVC_PSW_MASK;
+       lowcore->svc_new_psw.addr = (addr_t) &system_call;
+       lowcore->program_new_psw.mask = _PGM_PSW_MASK;
+       lowcore->program_new_psw.addr = (addr_t) &pgm_check_handler;
+       lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK;
+       lowcore->mcck_new_psw.addr = (addr_t) &mcck_int_handler;
+       lowcore->io_new_psw.mask = _IO_PSW_MASK;
+       lowcore->io_new_psw.addr = (addr_t) &io_int_handler;
+       lowcore->ipl_device = S390_lowcore.ipl_device;
+       lowcore->kernel_stack = ((__u32) &init_task_union) + 16384;
+       lowcore->async_stack = (__u64)
+               __alloc_bootmem(4*PAGE_SIZE, 4*PAGE_SIZE, 0) + 16384;
+       set_prefix((__u32)(__u64) lowcore);
+        cpu_init();
+        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+        __cpu_logical_map[0] = boot_cpu_addr;
+
+       /*
+        * Create kernel page tables and switch to virtual addressing.
+        */
         paging_init();
 
        res = alloc_bootmem_low(sizeof(struct resource));
@@ -422,30 +467,49 @@ void print_cpu_info(struct cpuinfo_S390 *cpuinfo)
 }
 
 /*
- *     Get CPU information for use by the procfs.
+ * get_cpuinfo - Get information on one CPU for use by procfs.
+ *
+ *     Prints info on the next CPU into buffer.  Beware, doesn't check for
+ *     buffer overflow.  Current implementation of procfs assumes that the
+ *     resulting data is <= 1K.
+ *
+ * Args:
+ *     buffer  -- you guessed it, the data buffer
+ *     cpu_np  -- Input: next cpu to get (start at 0).  Output: Updated.
+ *
+ *     Returns number of bytes written to buffer.
  */
 
-int get_cpuinfo(char * buffer)
+int get_cpuinfo(char *buffer, unsigned *cpu_np)
 {
         struct cpuinfo_S390 *cpuinfo;
         char *p = buffer;
-        int i;
-
-        p += sprintf(p,"vendor_id       : IBM/S390\n"
-                       "# processors    : %i\n"
-                       "bogomips per cpu: %lu.%02lu\n",
-                       smp_num_cpus, loops_per_jiffy/(500000/HZ),
-                       (loops_per_jiffy/(5000/HZ))%100);
-        for (i = 0; i < smp_num_cpus; i++) {
-                cpuinfo = &safe_get_cpu_lowcore(i).cpu_data;
-                p += sprintf(p,"processor %i: "
-                               "version = %02X,  "
-                               "identification = %06X,  "
-                               "machine = %04X\n",
-                               i, cpuinfo->cpu_id.version,
-                               cpuinfo->cpu_id.ident,
-                               cpuinfo->cpu_id.machine);
-        }
+       unsigned n;
+
+       n = *cpu_np;
+       while (n < NR_CPUS && (cpu_online_map & (1 << n)) == 0)
+               n++;
+       if (n >= NR_CPUS) {
+               *cpu_np = NR_CPUS;
+               return (0);
+       }
+       *cpu_np = n + 1;
+
+       if (n == 0) {
+               p += sprintf(p, "vendor_id       : IBM/S390\n"
+                               "# processors    : %i\n"
+                               "bogomips per cpu: %lu.%02lu\n",
+                               smp_num_cpus, loops_per_jiffy/(500000/HZ),
+                               (loops_per_jiffy/(5000/HZ))%100);
+       }
+       cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
+       p += sprintf(p, "processor %i: "
+                       "version = %02X,  "
+                       "identification = %06X,  "
+                       "machine = %04X\n",
+                       n, cpuinfo->cpu_id.version,
+                       cpuinfo->cpu_id.ident,
+                       cpuinfo->cpu_id.machine);
         return p - buffer;
 }
 
index 8f04e9e956bd9d9242348758844653dbf0c85e27..74ec0561ffc962eebdab4733b6c7c85144b84379 100644 (file)
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
+#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 
-#define DEBUG_SIG 0
-
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/* pretcode & sig are used to store the return addr on Intel
-   & the signal no as the first parameter we do this differently
-   using gpr14 & gpr2. */
-
-#define SIGFRAME_COMMON \
-__u8     callee_used_stack[__SIGNAL_FRAMESIZE]; \
-struct sigcontext sc; \
-_sigregs sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
 
 typedef struct 
 {
-       SIGFRAME_COMMON
+       __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+       struct sigcontext sc;
+       _sigregs sregs;
+       __u8 retcode[S390_SYSCALL_SIZE];
 } sigframe;
 
 typedef struct 
 {
-       SIGFRAME_COMMON
+       __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+       __u8 retcode[S390_SYSCALL_SIZE];
        struct siginfo info;
        struct ucontext uc;
 } rt_sigframe;
@@ -206,7 +200,7 @@ static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs)
        err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
        if(!err)
        {
-               regs->orig_gpr2 = -1;           /* disable syscall checks */
+               regs->trap = -1;                /* disable syscall checks */
                regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
                (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
                regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
@@ -218,53 +212,51 @@ static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs)
        return(err);
 }
 
-static int
-restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
-                _sigregs *sregs,sigset_t *set)
-{
-       unsigned int err;
-
-       err=restore_sigregs(regs,sregs);
-       if(!err)
-               err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE);
-               return(err);
-}
-
-int sigreturn_common(struct pt_regs *regs,int framesize)
+asmlinkage long sys_sigreturn(struct pt_regs *regs)
 {
        sigframe *frame = (sigframe *)regs->gprs[15];
        sigset_t set;
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-               return -1;
-       if (restore_sigcontext(&frame->sc,regs,&frame->sregs,&set))
-               return -1;
+               goto badframe;
+       if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
+               goto badframe;
+
        sigdelsetmask(&set, ~_BLOCKABLE);
        spin_lock_irq(&current->sigmask_lock);
        current->blocked = set;
        recalc_sigpending(current);
        spin_unlock_irq(&current->sigmask_lock);
-       return 0;
-}
 
-asmlinkage long sys_sigreturn(struct pt_regs *regs)
-{
-
-       if (sigreturn_common(regs,sizeof(sigframe)))
+       if (restore_sigregs(regs, &frame->sregs))
                goto badframe;
+
        return regs->gprs[2];
 
 badframe:
        force_sig(SIGSEGV, current);
        return 0;
-}      
+}
 
 asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 {
        rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+       sigset_t set;
+
+       if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+               goto badframe;
+       if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+               goto badframe;
+
+       sigdelsetmask(&set, ~_BLOCKABLE);
+       spin_lock_irq(&current->sigmask_lock);
+       current->blocked = set;
+       recalc_sigpending(current);
+       spin_unlock_irq(&current->sigmask_lock);
 
-       if (sigreturn_common(regs,sizeof(rt_sigframe)))
+       if (restore_sigregs(regs, &frame->uc.uc_mcontext))
                goto badframe;
+
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
        do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);
@@ -273,7 +265,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 badframe:
        force_sig(SIGSEGV, current);
        return 0;
-}      
+}
 
 /*
  * Set up a signal frame.
@@ -307,58 +299,48 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
        return (void *)((sp - frame_size) & -8ul);
 }
 
-static void *setup_frame_common(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs,
-                               int frame_size,u16 retcode)
+static inline int map_signal(int sig)
 {
-       sigframe *frame;
-       int err;
+       if (current->exec_domain
+           && current->exec_domain->signal_invmap
+           && sig < 32)
+               return current->exec_domain->signal_invmap[sig];
+       else
+               return sig;
+}
 
-       frame = get_sigframe(ka, regs,frame_size);
-       if (!access_ok(VERIFY_WRITE, frame,frame_size))
-               return 0;
-       err = save_sigregs(regs,&frame->sregs);
-       if(!err)
-               err=__put_user(&frame->sregs,&frame->sc.sregs);
-       if(!err)
+static void setup_frame(int sig, struct k_sigaction *ka,
+                       sigset_t *set, struct pt_regs * regs)
+{
+       sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
+               goto give_sigsegv;
+
+       if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
+               goto give_sigsegv;
+
+       if (save_sigregs(regs, &frame->sregs))
+               goto give_sigsegv;
+       if (__put_user(&frame->sregs, &frame->sc.sregs))
+               goto give_sigsegv;
 
-               err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE);
-       if(!err)
-       {
-               regs->gprs[2]=(current->exec_domain
-                          && current->exec_domain->signal_invmap
-                          && sig < 32
-                          ? current->exec_domain->signal_invmap[sig]
-                          : sig);
-               /* Set up registers for signal handler */
-               regs->gprs[15] = (addr_t)frame;
-               regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
-               regs->psw.mask = _USER_PSW_MASK;
-       }
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
        if (ka->sa.sa_flags & SA_RESTORER) {
                 regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
        } else {
                 regs->gprs[14] = FIX_PSW(frame->retcode);
-               err |= __put_user(retcode, (u16 *)(frame->retcode));
+               if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, 
+                              (u16 *)(frame->retcode)))
+                       goto give_sigsegv;
        }
-       return(err ? 0:frame);
-}
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs)
-{
-       sigframe *frame;
+       /* Set up registers for signal handler */
+       regs->gprs[15] = (addr_t)frame;
+       regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+       regs->psw.mask = _USER_PSW_MASK;
 
-       if((frame=setup_frame_common(sig,ka,set,regs,sizeof(sigframe),
-                   (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
-               goto give_sigsegv;
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-       /* Martin wants this for pthreads */
+       regs->gprs[2] = map_signal(sig);
        regs->gprs[3] = (addr_t)&frame->sc;
 
        /* We forgot to include these in the sigcontext.
@@ -376,34 +358,44 @@ give_sigsegv:
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
 {
-       rt_sigframe *frame;
-       addr_t      orig_sp=regs->gprs[15];
-       int err;
+       int err = 0;
+       rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
+               goto give_sigsegv;
 
-       if((frame=setup_frame_common(sig,ka,set,regs,sizeof(rt_sigframe),
-                   (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+       if (copy_siginfo_to_user(&frame->info, info))
                goto give_sigsegv;
-       
-       err = copy_siginfo_to_user(&frame->info, info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-       err |= __put_user(sas_ss_flags(orig_sp),
+       err |= __put_user(sas_ss_flags(regs->gprs[15]),
                          &frame->uc.uc_stack.ss_flags);
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-       err |= __put_user(&frame->sc,&frame->uc.sc);
-       regs->gprs[3] = (addr_t)&frame->info;
-       regs->gprs[4] = (addr_t)&frame->uc;
-
+       err |= save_sigregs(regs, &frame->uc.uc_mcontext);
+       err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
                goto give_sigsegv;
 
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+       /* Set up to return from userspace.  If provided, use a stub
+          already in userspace.  */
+       if (ka->sa.sa_flags & SA_RESTORER) {
+                regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+       } else {
+                regs->gprs[14] = FIX_PSW(frame->retcode);
+               err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 
+                                 (u16 *)(frame->retcode));
+       }
+
+       /* Set up registers for signal handler */
+       regs->gprs[15] = (addr_t)frame;
+       regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+       regs->psw.mask = _USER_PSW_MASK;
+
+       regs->gprs[2] = map_signal(sig);
+       regs->gprs[3] = (addr_t)&frame->info;
+       regs->gprs[4] = (addr_t)&frame->uc;
        return;
 
 give_sigsegv:
@@ -558,13 +550,16 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                                        continue;
                                /* FALLTHRU */
 
-                       case SIGSTOP:
+                       case SIGSTOP: {
+                               struct signal_struct *sig;
                                set_current_state(TASK_STOPPED);
                                current->exit_code = signr;
-                               if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+                               sig = current->p_pptr->sig;
+                               if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
                                        notify_parent(current, SIGCHLD);
                                schedule();
                                continue;
+                       }
 
                        case SIGQUIT: case SIGILL: case SIGTRAP:
                        case SIGABRT: case SIGFPE: case SIGSEGV:
index a4b908bbe1688a15a752b068481b2b58ed71f98c..4b44690897a0e696504f1a4edff806586934b3a1 100644 (file)
@@ -11,6 +11,7 @@
  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
+#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include "linux32.h"
 
-#define DEBUG_SIG 0
-
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/* pretcode & sig are used to store the return addr on Intel
-   & the signal no as the first parameter we do this differently
-   using gpr14 & gpr2. */
-
-#define SIGFRAME_COMMON32 \
-__u8     callee_used_stack[__SIGNAL_FRAMESIZE32]; \
-struct sigcontext32 sc; \
-_sigregs32 sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
+#define _USER_PSW_MASK32 0x0701C00080000000
 
 typedef struct 
 {
-       SIGFRAME_COMMON32
+       __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
+       struct sigcontext32 sc;
+       _sigregs32 sregs;
+       __u8 retcode[S390_SYSCALL_SIZE];
 } sigframe32;
 
 typedef struct 
 {
-       SIGFRAME_COMMON32
+       __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
+       __u8 retcode[S390_SYSCALL_SIZE];
        struct siginfo32 info;
        struct ucontext32 uc;
 } rt_sigframe32;
@@ -328,7 +324,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
 
        if(!err)
        {
-               regs->orig_gpr2 = -1;           /* disable syscall checks */
+               regs->trap = -1;                /* disable syscall checks */
                regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
                (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
                regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
@@ -342,40 +338,25 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
        return(err);
 }
 
-static int
-restore_sigcontext32(struct sigcontext32 *sc, struct pt_regs *regs,
-                _sigregs32 *sregs,sigset_t *set)
-{
-       unsigned int err;
-
-       err=restore_sigregs32(regs,sregs);
-       if(!err)
-               err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE32);
-       return(err);
-}
-
-int sigreturn_common32(struct pt_regs *regs)
+asmlinkage long sys32_sigreturn(struct pt_regs *regs)
 {
        sigframe32 *frame = (sigframe32 *)regs->gprs[15];
        sigset_t set;
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-               return -1;
-       if (restore_sigcontext32(&frame->sc,regs,&frame->sregs,&set))
-               return -1;
+               goto badframe;
+       if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
+               goto badframe;
+
        sigdelsetmask(&set, ~_BLOCKABLE);
        spin_lock_irq(&current->sigmask_lock);
        current->blocked = set;
        recalc_sigpending(current);
        spin_unlock_irq(&current->sigmask_lock);
-       return 0;
-}
 
-asmlinkage long sys32_sigreturn(struct pt_regs *regs)
-{
-
-       if (sigreturn_common32(regs))
+       if (restore_sigregs32(regs, &frame->sregs))
                goto badframe;
+
        return regs->gprs[2];
 
 badframe:
@@ -386,11 +367,23 @@ badframe:
 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
 {
        rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15];
+       sigset_t set;
        stack_t st;
        int err;
        mm_segment_t old_fs = get_fs();
 
-       if (sigreturn_common32(regs))
+       if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+               goto badframe;
+       if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+               goto badframe;
+
+       sigdelsetmask(&set, ~_BLOCKABLE);
+       spin_lock_irq(&current->sigmask_lock);
+       current->blocked = set;
+       recalc_sigpending(current);
+       spin_unlock_irq(&current->sigmask_lock);
+
+       if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
                goto badframe;
 
        err = __get_user(st.ss_sp, &frame->uc.uc_stack.ss_sp);
@@ -399,17 +392,18 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
        err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
        if (err)
                goto badframe; 
-       set_fs (KERNEL_DS);   
+
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
+       set_fs (KERNEL_DS);   
        do_sigaltstack(&st, NULL, regs->gprs[15]);
        set_fs (old_fs);
 
        return regs->gprs[2];
 
 badframe:
-       force_sig(SIGSEGV, current);
-       return 0;
+        force_sig(SIGSEGV, current);
+        return 0;
 }      
 
 /*
@@ -444,58 +438,54 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
        return (void *)((sp - frame_size) & -8ul);
 }
 
-static void *setup_frame_common32(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs,
-                               int frame_size,u16 retcode)
+static inline int map_signal(int sig)
 {
-       sigframe32 *frame;
-       int err;
+       if (current->exec_domain
+           && current->exec_domain->signal_invmap
+           && sig < 32)
+               return current->exec_domain->signal_invmap[sig];
+        else
+               return sig;
+}
 
-       frame = get_sigframe(ka, regs,frame_size);
-       if (!access_ok(VERIFY_WRITE, frame,frame_size))
-               return 0;
-       err = save_sigregs32(regs,&frame->sregs);
-       if(!err)
-               err=__put_user(&frame->sregs,&frame->sc.sregs);
-       if(!err)
+static void setup_frame32(int sig, struct k_sigaction *ka,
+                       sigset_t *set, struct pt_regs * regs)
+{
+       sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32));
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
+               goto give_sigsegv;
+
+       if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
+               goto give_sigsegv;
+
+       if (save_sigregs32(regs, &frame->sregs))
+               goto give_sigsegv;
+       if (__put_user(&frame->sregs, &frame->sc.sregs))
+               goto give_sigsegv;
 
-               err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE32);
-       if(!err)
-       {
-               regs->gprs[2]=(current->exec_domain
-                          && current->exec_domain->signal_invmap
-                          && sig < 32
-                          ? current->exec_domain->signal_invmap[sig]
-                          : sig);
-               /* Set up registers for signal handler */
-               regs->gprs[15] = (addr_t)frame;
-               regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
-       }
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
        if (ka->sa.sa_flags & SA_RESTORER) {
-                regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+               regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
        } else {
-                regs->gprs[14] = FIX_PSW(frame->retcode);
-               err |= __put_user(retcode, (u16 *)(frame->retcode));
-       }
-       return(err ? 0:frame);
-}
+               regs->gprs[14] = FIX_PSW(frame->retcode);
+               if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
+                              (u16 *)(frame->retcode)))
+                       goto give_sigsegv;
+        }
 
-static void setup_frame32(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs)
-{
-       sigframe32 *frame;
-         
-       if((frame=setup_frame_common32(sig,ka,set,regs,sizeof(sigframe32),
-                   (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
-               goto give_sigsegv;
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-        /* Martin wants this for pthreads */
-       regs->gprs[3] = (addr_t)&frame->sc;   
+       /* Set up registers for signal handler */
+       regs->gprs[15] = (addr_t)frame;
+       regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+       regs->psw.mask = _USER_PSW_MASK32;
+
+       regs->gprs[2] = map_signal(sig);
+       regs->gprs[3] = (addr_t)&frame->sc;
+
+       /* We forgot to include these in the sigcontext.
+          To avoid breaking binary compatibility, they are passed as args. */
+       regs->gprs[4] = current->thread.trap_no;
+       regs->gprs[5] = current->thread.prot_addr;
        return;
 
 give_sigsegv:
@@ -507,33 +497,44 @@ give_sigsegv:
 static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
 {
-       rt_sigframe32 *frame;
-       addr_t      orig_sp=regs->gprs[15];
-       int err;
+       int err = 0;
+       rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
+               goto give_sigsegv;
 
-       if((frame=setup_frame_common32(sig,ka,set,regs,sizeof(rt_sigframe32),
-                   (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+       if (copy_siginfo_to_user32(&frame->info, info))
                goto give_sigsegv;
-       
-       err = copy_siginfo_to_user32(&frame->info, info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-       err |= __put_user(sas_ss_flags(orig_sp),
-                         &frame->uc.uc_stack.ss_flags);
+       err |= __put_user(sas_ss_flags(regs->gprs[15]),
+                         &frame->uc.uc_stack.ss_flags);
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-       regs->gprs[3] = (addr_t)&frame->info;
-       regs->gprs[4] = (addr_t)&frame->uc;
-
+       err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
+       err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
                goto give_sigsegv;
 
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+       /* Set up to return from userspace.  If provided, use a stub
+          already in userspace.  */
+       if (ka->sa.sa_flags & SA_RESTORER) {
+               regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+       } else {
+               regs->gprs[14] = FIX_PSW(frame->retcode);
+               err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
+                                 (u16 *)(frame->retcode));
+       }
+
+       /* Set up registers for signal handler */
+       regs->gprs[15] = (addr_t)frame;
+       regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+       regs->psw.mask = _USER_PSW_MASK32;
+
+       regs->gprs[2] = map_signal(sig);
+       regs->gprs[3] = (addr_t)&frame->info;
+       regs->gprs[4] = (addr_t)&frame->uc;
        return;
 
 give_sigsegv:
@@ -551,7 +552,7 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka,
              siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
        /* Are we from a system call? */
-       if (regs->orig_gpr2 >= 0) {
+       if (regs->trap == __LC_SVC_OLD_PSW) {
                /* If so, check system call restarting.. */
                switch (regs->gprs[2]) {
                        case -ERESTARTNOHAND:
@@ -692,12 +693,12 @@ int do_signal32(struct pt_regs *regs, sigset_t *oldset)
 
                        case SIGQUIT: case SIGILL: case SIGTRAP:
                        case SIGABRT: case SIGFPE: case SIGSEGV:
+                       case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
                                 if (do_coredump(signr, regs))
                                         exit_code |= 0x80;
                                 /* FALLTHRU */
 
                        default:
-                               lock_kernel();
                                sigaddset(&current->pending.signal, signr);
                                recalc_sigpending(current);
                                current->flags |= PF_SIGNALED;
@@ -712,7 +713,7 @@ int do_signal32(struct pt_regs *regs, sigset_t *oldset)
        }
 
        /* Did we come from a system call? */
-       if ( regs->trap ==  __LC_SVC_OLD_PSW /* System Call! */ ) {
+       if ( regs->trap == __LC_SVC_OLD_PSW /* System Call! */ ) {
                /* Restart the system call - no handlers present */
                if (regs->gprs[2] == -ERESTARTNOHAND ||
                    regs->gprs[2] == -ERESTARTSYS ||
index 0cc7a4395200387961df391e95e3f64c8fbd9ff7..0232aedbbc6a2bbbb0679825e9cb14d00940f40c 100644 (file)
@@ -57,6 +57,8 @@ static atomic_t  smp_commenced = ATOMIC_INIT(0);
 
 spinlock_t       kernel_flag = SPIN_LOCK_UNLOCKED;
 
+unsigned long   cpu_online_map;
+
 /*
  *      Setup routine for controlling SMP activation
  *
@@ -92,6 +94,95 @@ extern char vmpoff_cmd[];
 
 extern void reipl(unsigned long devno);
 
+static sigp_ccode smp_ext_bitcall(int, ec_bit_sig);
+static void smp_ext_bitcall_others(ec_bit_sig);
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+struct call_data_struct {
+       void (*func) (void *info);
+       void *info;
+       atomic_t started;
+       atomic_t finished;
+       int wait;
+};
+
+static struct call_data_struct * call_data;
+
+/*
+ * 'Call function' interrupt callback
+ */
+static void do_call_function(void)
+{
+       void (*func) (void *info) = call_data->func;
+       void *info = call_data->info;
+       int wait = call_data->wait;
+
+       atomic_inc(&call_data->started);
+       (*func)(info);
+       if (wait)
+               atomic_inc(&call_data->finished);
+}
+
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+                       int wait)
+/*
+ * [SUMMARY] Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <nonatomic> currently unused.
+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute <<func>> or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler, you may call it from a bottom half handler.
+ */
+{
+       struct call_data_struct data;
+       int cpus = smp_num_cpus-1;
+
+       if (!cpus || !atomic_read(&smp_commenced))
+               return 0;
+
+       data.func = func;
+       data.info = info;
+       atomic_set(&data.started, 0);
+       data.wait = wait;
+       if (wait)
+               atomic_set(&data.finished, 0);
+
+       spin_lock_bh(&call_lock);
+       call_data = &data;
+       /* Send a message to all other CPUs and wait for them to respond */
+        smp_ext_bitcall_others(ec_call_function);
+
+       /* Wait for response */
+       while (atomic_read(&data.started) != cpus)
+               barrier();
+
+       if (wait)
+               while (atomic_read(&data.finished) != cpus)
+                       barrier();
+       spin_unlock_bh(&call_lock);
+
+       return 0;
+}
+
+
+/*
+ * Various special callbacks
+ */
+
 void do_machine_restart(void)
 {
         smp_send_stop();
@@ -148,7 +239,6 @@ void machine_power_off(void)
 
 void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
 {
-        ec_ext_call *ec, *next;
         unsigned long bits;
 
         /*
@@ -167,138 +257,15 @@ void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
                do_machine_halt();
         if (test_bit(ec_power_off, &bits))
                do_machine_power_off();
-
-        /*
-         * Handle external call commands with a parameter area
-         */
-       ec = (ec_ext_call *) xchg(&S390_lowcore.ext_call_queue, 0);
-        if (ec == NULL)
-                return;   /* no command signals */
-
-        /* Make a fifo out of the lifo */
-        next = ec->next;
-        ec->next = NULL;
-        while (next != NULL) {
-                ec_ext_call *tmp = next->next;
-                next->next = ec;
-                ec = next;
-                next = tmp;
-        }
-
-        /* Execute every sigp command on the queue */
-        while (ec != NULL) {
-                switch (ec->cmd) {
-                case ec_callback_async: {
-                        void (*func)(void *info);
-                        void *info;
-
-                        func = ec->func;
-                        info = ec->info;
-                        atomic_set(&ec->status,ec_executing);
-                        (func)(info);
-                        return;
-                }
-                case ec_callback_sync:
-                        atomic_set(&ec->status,ec_executing);
-                        (ec->func)(ec->info);
-                        atomic_set(&ec->status,ec_done);
-                        return;
-                default:
-                }
-                ec = ec->next;
-        }
-}
-
-/*
- * Swap in a new request to external call queue 
- */
-static inline void smp_add_ext_call(ec_ext_call *ec, struct _lowcore *lowcore)
-{
-       int success;
-
-       while (1) {
-               ec->next = (ec_ext_call*) lowcore->ext_call_queue;
-               __asm__ __volatile__ (
-                        "   lgr 0,%2\n"
-                       "   csg 0,%3,%1\n"
-                       "   ipm %0\n"
-                       "   srl %0,28\n"
-                       : "=d" (success), "+m" (lowcore->ext_call_queue)
-                       : "d" (ec->next), "d" (ec)
-                       : "cc", "0" );
-               if (success == 0) break;
-       }
-}
-
-/*
- * Send an external call sigp to another cpu and wait for its completion.
- */
-sigp_ccode
-smp_ext_call(int cpu, void (*func)(void *info), void *info, int wait)
-{
-        sigp_ccode ccode;
-        ec_ext_call ec;
-
-        ec.cmd = wait ? ec_callback_sync:ec_callback_async;
-        atomic_set(&ec.status, ec_pending);
-        ec.func = func;
-       ec.info = info;
-       /* swap in new request to external call queue */
-       smp_add_ext_call(&ec, &get_cpu_lowcore(cpu));
-        /*
-         * We try once to deliver the signal. There are four possible
-         * return codes:
-         * 0) Order code accepted - can't show up on an external call
-         * 1) Status stored - fine, wait for completion.
-         * 2) Busy - there is another signal pending. Thats fine too, because
-         *    do_ext_call from the pending signal will execute all signals on
-         *    the queue. We wait for completion.
-         * 3) Not operational - something very bad has happened to the cpu.
-         *    do not wait for completion.
-         */
-        ccode = signal_processor(cpu, sigp_external_call);
-
-        if (ccode != sigp_not_operational)
-                /* wait for completion, FIXME: possible seed of a deadlock */
-                while (atomic_read(&ec.status) != (wait?ec_done:ec_executing));
-
-        return ccode;
-}
-
-/*
- * Send a callback sigp to every other cpu in the system.
- */
-void smp_ext_call_others(void (*func)(void *info), void *info, int wait)
-{
-        ec_ext_call ec[NR_CPUS];
-        sigp_ccode ccode;
-        int i;
-
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-               ec[i].cmd = wait ? ec_callback_sync : ec_callback_async;
-               atomic_set(&ec[i].status, ec_pending);
-               ec[i].func = func;
-               ec[i].info = info;
-               smp_add_ext_call(ec+i, &get_cpu_lowcore(i));
-                ccode = signal_processor(i, sigp_external_call);
-        }
-
-        /* wait for completion, FIXME: possible seed of a deadlock */
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-                while (atomic_read(&ec[i].status) != 
-                      (wait ? ec_done:ec_executing));
-        }
+        if (test_bit(ec_call_function, &bits))
+               do_call_function();
 }
 
 /*
  * Send an external call sigp to another cpu and return without waiting
  * for its completion.
  */
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
+static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
 {
         sigp_ccode ccode;
 
@@ -314,7 +281,7 @@ sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
  * Send an external call sigp to every other cpu in the system and
  * return without waiting for its completion.
  */
-void smp_ext_bitcall_others(ec_bit_sig sig)
+static void smp_ext_bitcall_others(ec_bit_sig sig)
 {
         sigp_ccode ccode;
         int i;
@@ -330,51 +297,6 @@ void smp_ext_bitcall_others(ec_bit_sig sig)
         }
 }
 
-/*
- * cycles through all the cpus,
- * returns early if info is not NULL & the processor has something
- * of intrest to report in the info structure.
- * it returns the next cpu to check if it returns early.
- * i.e. it should be used as follows if you wish to receive info.
- * next_cpu=0;
- * do
- * {
- *    info->cpu=next_cpu;
- *    next_cpu=smp_signal_others(order_code,parameter,1,info);
- *    ... check info here
- * } while(next_cpu<=smp_num_cpus)
- *
- *  if you are lazy just use it like
- * smp_signal_others(order_code,parameter,0,1,NULL);
- */
-int smp_signal_others(sigp_order_code order_code, u32 parameter,
-                      int spin, sigp_info *info)
-{
-        sigp_ccode   ccode;
-        u32          dummy;
-        u16          i;
-
-        if (info)
-                info->intresting = 0;
-        for (i = (info ? info->cpu : 0); i < smp_num_cpus; i++) {
-                if (smp_processor_id() != i) {
-                        do {
-                                ccode = signal_processor_ps(
-                                        (info ? &info->status : &dummy),
-                                        parameter, i, order_code);
-                        } while(spin && ccode == sigp_busy);
-                        if (info && ccode != sigp_order_code_accepted) {
-                                info->intresting = 1;
-                                info->cpu = i;
-                                info->ccode = ccode;
-                                i++;
-                                break;
-                        }
-                }
-        }
-        return i;
-}
-
 /*
  * this function sends a 'stop' sigp to all other CPUs in the system.
  * it goes straight through.
@@ -392,7 +314,18 @@ void smp_send_stop(void)
 
         /* stop all processors */
 
-        smp_signal_others(sigp_stop, 0, 1, NULL);
+        for (i =  0; i < smp_num_cpus; i++) {
+                if (smp_processor_id() != i) {
+                        int ccode;
+                        do {
+                                ccode = signal_processor_ps(
+                                   &dummy,
+                                   0,
+                                   i,
+                                   sigp_stop);
+                        } while(ccode == sigp_busy);
+                }
+        }
 
         /* store status of all processors in their lowcores (real 0) */
 
@@ -469,7 +402,7 @@ void smp_ctl_set_bit(int cr, int bit) {
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 1 << bit;
                 parms.andvals[cr] = -1L;
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_set_bit(cr, bit);
 }
@@ -485,34 +418,11 @@ void smp_ctl_clear_bit(int cr, int bit) {
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 0;
                 parms.andvals[cr] = ~(1L << bit);
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_clear_bit(cr, bit);
 }
 
-/*
- * Call a function on all other processors
- */
-
-int
-smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
-/*
- * [SUMMARY] Run a function on all other CPUs.
- * <func> The function to run. This must be fast and non-blocking.
- * <info> An arbitrary pointer to pass to the function.
- * <retry> currently unused.
- * <wait> If true, wait (atomically) until function has completed on other CPUs.
- * [RETURNS] 0 on success, else a negative status code. Does not return until
- * remote CPUs are nearly ready to execute <<func>> or are or have executed.
- *
- * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler, you may call it from a bottom half handler.
- */
-{
-        if (atomic_read(&smp_commenced) != 0)
-                smp_ext_call_others(func, info, wait);
-        return 0;
-}
 
 /*
  * Lets check how many CPUs we have.
@@ -607,15 +517,20 @@ static void __init do_boot_cpu(int cpu)
         init_tasks[cpu] = idle;
 
         cpu_lowcore=&get_cpu_lowcore(cpu);
-        cpu_lowcore->kernel_stack=idle->thread.ksp;
-        __asm__ __volatile__("stctg 0,15,%0\n\t"
-                             "stam  0,15,%1"
+       cpu_lowcore->save_area[15] = idle->thread.ksp;
+       cpu_lowcore->kernel_stack = (idle->thread.ksp | 16383) + 1;
+        __asm__ __volatile__("la    1,%0\n\t"
+                            "stctg 0,15,0(1)\n\t"
+                            "la    1,%1\n\t"
+                             "stam  0,15,0(1)"
                              : "=m" (cpu_lowcore->cregs_save_area[0]),
                                "=m" (cpu_lowcore->access_regs_save_area[0])
-                             : : "memory");
+                             : : "1", "memory");
 
         eieio();
         signal_processor(cpu,sigp_restart);
+       /* Mark this cpu as online. */
+       set_bit(cpu, &cpu_online_map);
 }
 
 /*
@@ -643,6 +558,7 @@ void __init smp_commence(void)
 void __init smp_boot_cpus(void)
 {
         struct _lowcore *curr_lowcore;
+       unsigned long async_stack;
         sigp_ccode   ccode;
         int i;
 
@@ -673,8 +589,16 @@ void __init smp_boot_cpus(void)
                         printk("smp_boot_cpus failed to allocate prefix memory\n");
                         break;
                 }
+               async_stack = __get_free_pages(GFP_KERNEL,2);
+               if (async_stack == 0) {
+                       printk("smp_boot_cpus failed to allocate asyncronous"
+                              " interrupt stack\n");
+                       free_page((unsigned long) curr_lowcore);
+                       break;
+               }
                 lowcore_ptr[i] = curr_lowcore;
                 memcpy(curr_lowcore, &S390_lowcore, sizeof(struct _lowcore));
+               curr_lowcore->async_stack = async_stack + (4 * PAGE_SIZE);
                 /*
                  * Most of the parameters are set up when the cpu is
                  * started up.
@@ -733,8 +657,6 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
                 s390_do_profile(regs->psw.addr);
 
         if (!--prof_counter[cpu]) {
-                int system = 1-user;
-                struct task_struct * p = current;
 
                 /*
                  * The multiplier may have changed since the last time we got
@@ -756,9 +678,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
                  * WrongThing (tm) to do.
                  */
 
-                irq_enter(cpu, 0);
                update_process_times(user);
-                irq_exit(cpu, 0);
         }
 }
 
index bc5f24bd80e9ef64e5e8b3786ea828923b9a164b..0371537ecd0d8cc303e2cd5e78a481e97fe3aaf4 100644 (file)
@@ -155,17 +155,16 @@ void do_settimeofday(struct timeval *tv)
 extern __u16 boot_cpu_addr;
 #endif
 
-void do_timer_interrupt(struct pt_regs *regs,int error_code)
+void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        unsigned long flags;
+       int cpu = smp_processor_id();
+
+       irq_enter(cpu, 0);
 
         /*
          * reset timer to 10ms minus time already elapsed
          * since timer-interrupt pending
          */
-        save_flags(flags);
-        cli();
 #ifdef CONFIG_SMP
        if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
                write_lock(&xtime_lock);
@@ -201,8 +200,8 @@ void do_timer_interrupt(struct pt_regs *regs,int error_code)
                write_unlock(&xtime_lock);
 #endif
        }
-        restore_flags(flags);
 
+       irq_exit(cpu, 0);
 }
 
 /*
@@ -256,4 +255,7 @@ void __init time_init(void)
         init_timer_cc -= 0x8126d60e46000000LL -
                          (0x3c26700LL*1000000*4096);
         tod_to_timeval(init_timer_cc, &xtime);
+
+       /* Set do_get_fast_time function pointer.  */
+       do_get_fast_time = do_gettimeofday;
 }
index 0d3b2c4ab1014ccbfbf62b236400711bff56089e..3eaed7e25f24eb49d00605c2e69bec6b9b4c7c55 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
-#include <asm/mathemu.h>
 #if CONFIG_REMOTE_DEBUG
 #include <asm/gdb-stub.h>
 #endif
@@ -59,14 +58,16 @@ extern void pfault_fini(void);
 extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
 #endif
 
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
         console_verbose();
         spin_lock_irq(&die_lock);
+       bust_spinlocks(1);
         printk("%s: %04lx\n", str, err & 0xffff);
         show_regs(regs);
+       bust_spinlocks(0);
         spin_unlock_irq(&die_lock);
         do_exit(SIGSEGV);
 }
index 2cc5cb6cf92ef685b763077bee13eaffbe5d6e23..38576550a5cec5f87221849179c60ea52be8866b 100644 (file)
@@ -1069,3 +1069,23 @@ sys32_fcntl64_wrapper:
        llgfr   %r4,%r4                 # unsigned long
        jg      sys32_fcntl64           # branch to system call
 
+       .globl  sys32_stat64_wrapper
+sys32_stat64_wrapper:
+       llgtr   %r2,%r2                 # char *
+       llgtr   %r3,%r3                 # struct stat64 *
+       llgfr   %r4,%r4                 # long
+       jg      sys32_stat64            # branch to system call
+
+       .globl  sys32_lstat64_wrapper
+sys32_lstat64_wrapper:
+       llgtr   %r2,%r2                 # char *
+       llgtr   %r3,%r3                 # struct stat64 *
+       llgfr   %r4,%r4                 # long
+       jg      sys32_lstat64           # branch to system call
+
+       .globl  sys32_fstat64_wrapper
+sys32_fstat64_wrapper:
+       llgfr   %r2,%r2                 # unsigned long
+       llgtr   %r3,%r3                 # struct stat64 *
+       llgfr   %r4,%r4                 # long
+       jg      sys32_fstat64           # branch to system call
index 774e868541c46bb9c4fa748c10bb919c53544c89..4192273998c3d8de8bb9d8db910b3279028a5a89 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 extern const struct exception_table_entry __start___ex_table[];
@@ -36,26 +37,32 @@ search_one_table(const struct exception_table_entry *first,
         return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
-       unsigned long ret;
+       unsigned long ret = 0;
+       unsigned long flags;
 
 #ifndef CONFIG_MODULES
        /* There is only the kernel to search.  */
        ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-       if (ret) return FIX_PSW(ret);
+       return ret;
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+
+       spin_lock_irqsave(&modlist_lock, flags);
        for (mp = module_list; mp != NULL; mp = mp->next) {
-               if (mp->ex_table_start == NULL)
+               if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return FIX_PSW(ret);
+               if (ret) 
+                       break;
        }
+       spin_unlock_irqrestore(&modlist_lock, flags);
+       return ret;
 #endif
-
-       return 0;
 }
index 68bd74eb6101b2a915d0b492180638d9e8c31754..c4f0180e611dd55fd94cd8cb80b160e3cd075778 100644 (file)
@@ -4,6 +4,7 @@
  *  S390 version
  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Hartmut Penner (hp@de.ibm.com)
+ *               Ulrich Weigand (uweigand@de.ibm.com)
  *
  *  Derived from "arch/i386/mm/fault.c"
  *    Copyright (C) 1995  Linus Torvalds
@@ -22,6 +23,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/console.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -33,33 +35,33 @@ extern int sysctl_userprocess_debug;
 #endif
 
 extern void die(const char *,struct pt_regs *,long);
+static void force_sigsegv(struct task_struct *tsk, int code, void *address);
 
 extern spinlock_t timerlist_lock;
 
 /*
  * Unlock any spinlocks which will prevent us from getting the
- * message out
+ * message out (timerlist_lock is acquired through the
+ * console unblank code)
  */
 void bust_spinlocks(int yes)
 {
-        spin_lock_init(&timerlist_lock);
-        if (yes) {
-                oops_in_progress = 1;
-#ifdef CONFIG_SMP
-                atomic_set(&global_irq_lock,0);
-#endif
-        } else {
-                int loglevel_save = console_loglevel;
-                oops_in_progress = 0;
-                /*
-                 * OK, the message is on the console.  Now we call printk()
-                 * without oops_in_progress set so that printk will give klogd
-                 * a poke.  Hold onto your hats...
-                 */
-                console_loglevel = 15;          /* NMI oopser may have shut the console up */
-                printk(" ");
-                console_loglevel = loglevel_save;
-        }
+       spin_lock_init(&timerlist_lock);
+       if (yes) {
+               oops_in_progress = 1;
+       } else {
+               int loglevel_save = console_loglevel;
+               oops_in_progress = 0;
+               console_unblank();
+               /*
+                * OK, the message is on the console.  Now we call printk()
+                * without oops_in_progress set so that printk will give klogd
+                * a poke.  Hold onto your hats...
+                */
+               console_loglevel = 15;
+               printk(" ");
+               console_loglevel = loglevel_save;
+       }
 }
 
 /*
@@ -84,6 +86,29 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
        int si_code = SEGV_MAPERR;
        int kernel_address = 0;
 
+        tsk = current;
+        mm = tsk->mm;
+       
+       /* 
+         * Check for low-address protection.  This needs to be treated
+        * as a special case because the translation exception code 
+        * field is not guaranteed to contain valid data in this case.
+        */
+       if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+
+               /* Low-address protection hit in kernel mode means 
+                  NULL pointer write access in kernel mode.  */
+               if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
+                       address = 0;
+                       kernel_address = 1;
+                       goto no_context;
+               }
+
+               /* Low-address protection hit in user mode 'cannot happen'.  */
+               die ("Low-address protection", regs, error_code);
+               do_exit(SIGKILL);
+       }
+
         /* 
          * get the failing address 
          * more specific the segment and page table portion of 
@@ -92,11 +117,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
 
         address = S390_lowcore.trans_exc_code&-4096L;
 
-        tsk = current;
-        mm = tsk->mm;
-
-        if (in_interrupt() || !mm)
-                goto no_context;
 
        /*
         * Check which address space the address belongs to
@@ -127,6 +147,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                        }
                }
                die("page fault via unknown access register", regs, error_code);
+               do_exit(SIGKILL);
                break;
 
        case 2: /* Secondary Segment Table Descriptor */
@@ -135,6 +156,11 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                break;
        }
 
+       /*
+        * Check whether we have a user MM in the first place.
+        */
+        if (in_interrupt() || !mm)
+                goto no_context;
 
        /*
         * When we get here, the fault happened in the current
@@ -144,10 +170,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
         down_read(&mm->mmap_sem);
 
         vma = find_vma(mm, address);
-        if (!vma) {
-               printk("no vma for address %lX\n",address);
+        if (!vma)
                 goto bad_area;
-        }
         if (vma->vm_start <= address) 
                 goto good_area;
         if (!(vma->vm_flags & VM_GROWSDOWN))
@@ -177,6 +201,7 @@ good_area:
                        goto bad_area;
         }
 
+ survive:
        /*
         * If for any reason at all we couldn't handle the fault,
         * make sure we exit gracefully rather than endlessly redo
@@ -207,7 +232,6 @@ bad_area:
 
         /* User mode accesses just cause a SIGSEGV */
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
-               struct siginfo si;
                 tsk->thread.prot_addr = address;
                 tsk->thread.trap_no = error_code;
 #ifndef CONFIG_SYSCTL
@@ -224,10 +248,8 @@ bad_area:
                        show_regs(regs);
                }
 #endif
-               si.si_signo = SIGSEGV;
-               si.si_code = si_code;
-               si.si_addr = (void*) address;
-               force_sig_info(SIGSEGV, &si, tsk);
+
+               force_sigsegv(tsk, si_code, (void *)address);
                 return;
        }
 
@@ -242,6 +264,7 @@ no_context:
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
  */
+
         if (kernel_address)
                 printk(KERN_ALERT "Unable to handle kernel pointer dereference"
                       " at virtual kernel address %016lx\n", address);
@@ -249,10 +272,6 @@ no_context:
                 printk(KERN_ALERT "Unable to handle kernel paging request"
                       " at virtual user address %016lx\n", address);
 
-/*
- * need to define, which information is useful here
- */
-
         die("Oops", regs, error_code);
         do_exit(SIGKILL);
 
@@ -263,6 +282,12 @@ no_context:
 */
 out_of_memory:
        up_read(&mm->mmap_sem);
+       if (tsk->pid == 1) {
+               tsk->policy |= SCHED_YIELD;
+               schedule();
+               down_read(&mm->mmap_sem);
+               goto survive;
+       }
        printk("VM: killing process %s\n", tsk->comm);
        if (regs->psw.mask & PSW_PROBLEM_STATE)
                do_exit(SIGKILL);
@@ -284,6 +309,20 @@ do_sigbus:
                goto no_context;
 }
 
+/*
+ * Send SIGSEGV to task.  This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+{
+       struct siginfo si;
+       si.si_signo = SIGSEGV;
+       si.si_code = code;
+       si.si_addr = address;
+       force_sig_info(SIGSEGV, &si, tsk);
+}
+
+
 #ifdef CONFIG_PFAULT
 /*
  * 'pfault' pseudo page faults routines.
@@ -316,13 +355,11 @@ typedef struct _pseudo_wait_t {
        int resolved;
 } pseudo_wait_t;
 
-static pseudo_wait_t *pseudo_lock_queue = NULL;
-static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
-
 int pfault_init(void)
 {
        pfault_refbk_t refbk =
-       { 0x258, 0, 5, 2, __LC_KERNEL_STACK, 1ULL << 48, 1ULL << 48, 0ULL };
+       { 0x258, 0, 5, 2, __LC_KERNEL_STACK, 1ULL << 48, 1ULL << 48,
+          0x8000000000000000ULL };
         int rc;
 
        if (pfault_disable)
@@ -362,7 +399,6 @@ void pfault_fini(void)
 asmlinkage void
 pfault_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        DECLARE_WAITQUEUE(wait, current);
        struct task_struct *tsk;
        wait_queue_head_t queue;
        wait_queue_head_t *qp;
@@ -375,7 +411,7 @@ pfault_interrupt(struct pt_regs *regs, __u16 error_code)
          * external interrupt. 
         */
        subcode = S390_lowcore.cpu_addr;
-       if ((subcode & 0xff00) != 0x06)
+       if ((subcode & 0xff00) != 0x0600)
                return;
 
        /*
index 695ea0d0219293ad266332d7f2107016949c78a7..b6675a3dfce9537ddd3a25119a6763971011d0fb 100644 (file)
@@ -36,7 +36,7 @@
 #include <asm/dma.h>
 #include <asm/lowcore.h>
 #include <asm/tlb.h>
+
 mmu_gather_t mmu_gathers[NR_CPUS];
 
 static unsigned long totalram_pages;
@@ -44,44 +44,23 @@ static unsigned long totalram_pages;
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
-static int test_access(unsigned long loc)
-{
-       static const int ssm_mask = 0x07000000L;
-       int rc, i;
-
-        rc = 0;
-       for (i=0; i<2; i++) {
-               __asm__ __volatile__(
-                        "    slgr  %0,%0\n"
-                       "    ssm   %1\n"
-                       "    tprot 0(%2),0\n"
-                       "0:  jne   1f\n"
-                       "    lghi  %0,1\n"
-                       "1:  ssm   %3\n"
-                        ".section __ex_table,\"a\"\n"
-                        "   .align 8\n"
-                        "   .quad  0b,1b\n"
-                        ".previous"
-                       : "+&d" (rc) : "i" (0), "a" (loc), "m" (ssm_mask)
-                       : "cc");
-               if (rc == 0)
-                       break;
-               loc += 0x100000;
-       }
-       return rc;
-}
-
 int do_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 += 4;
-                        if(pmd_quicklist)
-                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0)), freed += 4;
-                        if(pte_quicklist)
-                                pte_free_slow(pte_alloc_one_fast(NULL, 0)), freed++;
+                        if(pgd_quicklist) {
+                               free_pgd_slow(get_pgd_fast());
+                               freed += 4;
+                       }
+                        if(pmd_quicklist) {
+                               pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+                               freed += 4;
+                       }
+                        if(pte_quicklist) {
+                               pte_free_slow(pte_alloc_one_fast(NULL, 0));
+                               freed += 4;
+                       }
                 } while(pgtable_cache_size > low);
         }
         return freed;
@@ -139,7 +118,7 @@ void __init paging_init(void)
        int     i,j,k;
         unsigned long address=0;
         unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) |
-          _REGION_TABLE;
+          _KERN_REGION_TABLE;
        unsigned long end_mem = (unsigned long) __va(max_low_pfn*PAGE_SIZE);
        static const int ssm_mask = 0x04000000L;
 
@@ -212,7 +191,6 @@ void __init paging_init(void)
 void __init mem_init(void)
 {
        unsigned long codesize, reservedpages, datasize, initsize;
-        unsigned long tmp;
 
         max_mapnr = num_physpages = max_low_pfn;
         high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
@@ -223,25 +201,7 @@ void __init mem_init(void)
        /* this will put all low memory onto the freelists */
        totalram_pages += free_all_bootmem();
 
-        /* mark usable pages in the mem_map[] and count reserved pages */
        reservedpages = 0;
-       tmp = 0;
-       do {
-               if (tmp && (tmp & 0x1ff) == 0 && 
-                    test_access(tmp * PAGE_SIZE) == 0) {
-                        printk("2M Segment 0x%016lX not available\n",
-                               tmp * PAGE_SIZE);
-                       do {
-                                set_bit(PG_reserved, &mem_map[tmp].flags);
-                               reservedpages++;
-                               tmp++;
-                       } while (tmp < max_low_pfn && (tmp & 0x1ff));
-               } else {
-                       if (PageReserved(mem_map+tmp))
-                               reservedpages++;
-                       tmp++;
-               }
-       } while (tmp < max_low_pfn);
 
        codesize =  (unsigned long) &_etext - (unsigned long) &_text;
        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
index 812a7821b6244dc23328afc4438bd3ec6936ee13..dbfea910b07836e0f96e65684f45a42483b603d9 100644 (file)
@@ -83,3 +83,8 @@ static void __exit mouse_rpc_exit(void)
 
 module_init(mouse_rpc_init);
 module_exit(mouse_rpc_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("RiscPC mouse driver");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 33dfc86765079b83c6ae5c45736fc86c1ac8ce8c..6149d73ef03b11e35f22a70985a538fa34ab538b 100644 (file)
@@ -3159,5 +3159,7 @@ static void __exit acornscsi_exit(void)
 module_init(acornscsi_init);
 module_exit(acornscsi_exit);
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("AcornSCSI driver");
 MODULE_LICENSE("GPL");
 EXPORT_NO_SYMBOLS;
index 60c773a8108cd37c4435581ea81791a78aaf6722..7874cad48700e54093729efed87d940db8d96cd3 100644 (file)
@@ -439,4 +439,7 @@ static void __exit exit_arxe_scsi_driver(void)
 module_init(init_arxe_scsi_driver);
 module_exit(exit_arxe_scsi_driver);
 
+MODULE_AUTHOR("Stefan Hanske");
+MODULE_DESCRIPTION("ARXESCSI driver for Acorn machines");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 22e93cebfed7aa8aece768197871b4d4e7e56cbc..24b59ca93ac06fd041b41f7851cf4bbaa703f747 100644 (file)
 
 static struct expansion_card *ecs[MAX_ECARDS];
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Cumana SCSI II driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-MODULE_LICENSE("GPL");
-
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
  */
@@ -600,3 +594,10 @@ static void __exit cumanascsi2_exit(void)
 
 module_init(cumanascsi2_init);
 module_exit(cumanascsi2_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Cumana SCSI-2 driver for Acorn machines");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 14cdd2552df95055e22a241ba12c125911fbbf62..f8c87df51957fe6c68c8ed3a9119be439fd0b6f6 100644 (file)
@@ -293,5 +293,7 @@ static void __exit ecoscsi_exit(void)
 module_init(ecoscsi_init);
 module_exit(ecoscsi_exit);
 
-EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Econet-SCSI driver for Acorn machines");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 7fb82f7d69998e254520df23f37915e692e61e63..19fb20ef59bd6f91647bf372df288417ae7a2d32 100644 (file)
 
 static struct expansion_card *ecs[MAX_ECARDS];
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("EESOX SCSI driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
  */
@@ -602,5 +597,9 @@ static void __exit eesox_exit(void)
 module_init(eesox_init);
 module_exit(eesox_exit);
 
-EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("EESOX 'Fast' SCSI driver for Acorn machines");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index beacb43e3574df1a0066c65a112bc0ae82e2ab63..7dadf915a47274717704e03f329954c44d293612 100644 (file)
@@ -60,9 +60,6 @@
 #include "../../scsi/hosts.h"
 #include "fas216.h"
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver");
-
 #define VER_MAJOR      0
 #define VER_MINOR      0
 #define VER_PATCH      5
@@ -2767,15 +2764,6 @@ EXPORT_SYMBOL(fas216_print_host);
 EXPORT_SYMBOL(fas216_print_stats);
 EXPORT_SYMBOL(fas216_print_device);
 
-#ifdef MODULE
-int __init init_module(void)
-{
-       return 0;
-}
-
-void __exit cleanup_module(void)
-{
-}
-#endif
-
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
 MODULE_LICENSE("GPL");
index 0528fc8b3690218d9b4ff6362b7e43df4d2f3993..7c95c7582b2963542d3f2edbb07241db5c23cb85 100644 (file)
 
 #include "msgqueue.h"
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("SCSI message queue handling");
-MODULE_LICENSE("GPL");
-
 /*
  * Function: struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
  * Purpose : Allocate a message queue entry
@@ -170,13 +166,6 @@ EXPORT_SYMBOL(msgqueue_getmsg);
 EXPORT_SYMBOL(msgqueue_addmsg);
 EXPORT_SYMBOL(msgqueue_flush);
 
-#ifdef MODULE
-int __init init_module(void)
-{
-       return 0;
-}
-
-void __exit cleanup_module(void)
-{
-}
-#endif
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI message queue handling");
+MODULE_LICENSE("GPL");
index c87a814367c3287bffb6eb48644d46a6b0445f37..c53a8352150048a23a250bde895bb7e3dc3b18d6 100644 (file)
@@ -286,5 +286,7 @@ static void __exit oakscsi_exit(void)
 module_init(oakscsi_init);
 module_exit(oakscsi_exit);
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Oak SCSI driver");
 MODULE_LICENSE("GPL");
 EXPORT_NO_SYMBOLS;
index 4bddecf048e057e786f534f1ea6fffcad209d3a6..dc61d3ce54b3f8fee903ce31d74123987295fc79 100644 (file)
 #define VER_MINOR      0
 #define VER_PATCH      5
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Powertec SCSI driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-MODULE_LICENSE("GPL");
-
 static struct expansion_card *ecs[MAX_ECARDS];
 
 /*
@@ -502,3 +496,10 @@ static void __exit powertecscsi_exit(void)
 
 module_init(powertecscsi_init);
 module_exit(powertecscsi_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Powertec SCSI driver");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index a151482914eaf3be5bec02842c15eb5dd5154f76..127bbb59f9faa666c5d6848f26908ea7a55e0505 100644 (file)
 
 #include "../../scsi/scsi.h"
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("SCSI command queueing");
-MODULE_LICENSE("GPL");
-
 #define DEBUG
 
 typedef struct queue_entry {
@@ -296,13 +292,6 @@ EXPORT_SYMBOL(queue_remove_tgtluntag);
 EXPORT_SYMBOL(queue_remove_cmd);
 EXPORT_SYMBOL(queue_probetgtlun);
 
-#ifdef MODULE
-int __init init_module (void)
-{
-       return 0;
-}
-
-void __exit cleanup_module (void)
-{
-}
-#endif
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI command queueing");
+MODULE_LICENSE("GPL");
index 88c7cdf4100a4958452de7a51394315ff0c8b8df..0cdc26f7d2c9c75089d85eba5ee9cfc35a6333f0 100644 (file)
@@ -177,7 +177,7 @@ acpi_status
 tz_osl_add_device(
        TZ_CONTEXT              *thermal_zone)
 {
-       struct proc_dir_entry   *proc_entry = NULL;
+       struct proc_dir_entry   *proc_entry = NULL, *proc;
 
        if (!thermal_zone) {
                return(AE_BAD_PARAMETER);
@@ -186,15 +186,18 @@ tz_osl_add_device(
        printk("Thermal Zone: found\n");
 
        proc_entry = proc_mkdir(thermal_zone->uid, tz_proc_root);
-       if (!proc_entry) {
+       if (!proc_entry)
                return(AE_ERROR);
-       }
 
-       create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO,
+       proc = create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO,
                proc_entry, tz_osl_proc_read_status, (void*)thermal_zone);
+       if (!proc)
+               return(AE_ERROR);
 
-       create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO,
+       proc = create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO,
                proc_entry, tz_osl_proc_read_info, (void*)thermal_zone);
+       if (!proc)
+               return(AE_ERROR);
 
        return(AE_OK);
 }
index 09ca5dcd89e1d2aa522001c4230683e7432b5e25..cc8d7c0aa382e3b5e65d0a42227a7fac9a38f5d9 100644 (file)
@@ -542,4 +542,6 @@ module_init(nbd_init);
 module_exit(nbd_cleanup);
 
 MODULE_DESCRIPTION("Network Block Device");
+MODULE_LICENSE("GPL");
+
 
index ad8c384cd00c6d613bdabf2a499e4965bf900c85..b22d34da348a00cff3b4ad54542476d111d0b009 100644 (file)
@@ -171,3 +171,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of aten.c */
+MODULE_LICENSE("GPL");
index 5881a5f11572a5634aaddae9e0b2390afb0e39ca..3e20e6b7054a5809b9f308f8251b850eb369e156 100644 (file)
@@ -482,3 +482,4 @@ void        cleanup_module(void)
 #endif
 
 /* end of bpck.c */
+MODULE_LICENSE("GPL");
index b41b0aee928206b8f54772c4513dd1b582ea9494..058a7d68572ce1e8ddef222733a28f4b4a7c4577 100644 (file)
@@ -227,3 +227,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of comm.c */
+MODULE_LICENSE("GPL");
index dd9e6872fa503db6dbcbb190098077e4625a771c..438735b6ce1087dbc5d8cafcf9d96f78a319c299 100644 (file)
@@ -242,3 +242,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of dstr.c */
+MODULE_LICENSE("GPL");
index 28915705bb8ac78a226eb183c73979c0b154921b..ba5ba04ac857df6deb28628c18024fb69f90afb2 100644 (file)
@@ -320,3 +320,4 @@ void        cleanup_module(void)
 #endif
 
 /* end of epat.c */
+MODULE_LICENSE("GPL");
index 988d6a1f59eb9d4e13156a940249cdbcdff50907..c27edd64ecc16da67859f81c95c55a99d086cea3 100644 (file)
@@ -325,3 +325,4 @@ void    cleanup_module(void)
 
 /* end of epia.c */
 
+MODULE_LICENSE("GPL");
index 086cad36d70fb773a6d24a3bc6ecb4e4ed5c6b8c..7f45529c80b11a56a3a416c9be10516783e6e668 100644 (file)
@@ -160,3 +160,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of fit2.c */
+MODULE_LICENSE("GPL");
index aee5f328d146a2ba72612fad6b1b2d024fb051a5..8b5ad4bd5ad0e1a1627ea81f2e6cb7f79ef90e9f 100644 (file)
@@ -220,3 +220,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of fit3.c */
+MODULE_LICENSE("GPL");
index ef64a613c5542bd7b83641ed48c139807e00b140..74b2eaab1c19096e4daf0af371f8671dafbd4f61 100644 (file)
@@ -281,3 +281,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of friq.c */
+MODULE_LICENSE("GPL");
index 8b529834d4d3ed719debd16a14576836b482694f..817004a3f7dcbf43f66e016afc3c02060fbbc3e1 100644 (file)
@@ -322,3 +322,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of frpw.c */
+MODULE_LICENSE("GPL");
index 9e3a5950fb07c729b143a7bbec18064872d063f4..2f20c9b0fa4e2450d8c391a1c3b53d46f692b7d9 100644 (file)
@@ -310,3 +310,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of kbic.c */
+MODULE_LICENSE("GPL");
index 99f86cee37c755a9e6cef88d24e0ddcae65fb956..60778192e0c1e3684dcf1da6483542ea19404d18 100644 (file)
@@ -137,3 +137,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of ktti.c */
+MODULE_LICENSE("GPL");
index 6d0cb7f536c1283e41371fe655c09e0bd7366ff8..b3c8d3d325e0d80edbc776be3002f061a132c1b4 100644 (file)
@@ -162,3 +162,4 @@ void    cleanup_module(void)
 #endif
 
 /* end of on20.c */
+MODULE_LICENSE("GPL");
index b1607a78161440a67bc932abc03260090c2dd8be..0688c631797204b604fa1a508a74480cc83a4e78 100644 (file)
@@ -328,3 +328,4 @@ void    cleanup_module(void)
 
 /* end of on26.c */
 
+MODULE_LICENSE("GPL");
index 8e6fff5c5ec08aa304f0e2c96f8518dccb24bad8..6b17d805343a475af11c9fc8d193434da5ea144b 100644 (file)
@@ -547,3 +547,4 @@ void        paride_init( void )
 #endif
 
 /* end of paride.c */
+MODULE_LICENSE("GPL");
index bc01c1d2ae59cf10ac39e11f612f66c609dae64a..a3375bffd3bfc58596c71244e8edffd2eeaba954 100644 (file)
@@ -948,3 +948,4 @@ static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 
 /* end of pcd.c */
 
+MODULE_LICENSE("GPL");
index 0ace2dee0d4e2629ce9fe908d63ceaae40788fc1..58d9397dff9f058543756aeb42ef440e7c8fae07 100644 (file)
@@ -586,8 +586,7 @@ int     init_module(void)
 }
 
 void    cleanup_module(void)
-
-{       struct gendisk **gdp;
+{
        int unit;
 
         devfs_unregister_blkdev(MAJOR_NR,name);
@@ -1069,3 +1068,4 @@ static void do_pd_write_done( void )
 
 /* end of pd.c */
 
+MODULE_LICENSE("GPL");
index 952631012021cd42288dc5d5702caffe4706561a..ab961ae51ae7c4307bc316c28bcab0bc86bb2087 100644 (file)
@@ -1111,3 +1111,4 @@ static void do_pf_write_done( void )
 
 /* end of pf.c */
 
+MODULE_LICENSE("GPL");
index 916cfb7470fcef9ec91881f93fc23e0bd712a4a1..96ef0c3a111527f7278b5b15a51310e7197a6b59 100644 (file)
@@ -694,3 +694,4 @@ static ssize_t pg_read(struct file * filp, char * buf,
 
 /* end of pg.c */
 
+MODULE_LICENSE("GPL");
index 829c9c515a9cd0bd9cbd398ede2a0ee5608204d2..b98766f8822f5712460ba668dc62c96d8024c739 100644 (file)
@@ -724,3 +724,4 @@ static void ppc6_close(PPC *ppc)
 
 //***************************************************************************
 
+MODULE_LICENSE("GPL");
index cf8c4c066b6e6eb0ada3b679246c5a062ac32c8f..e5bdcd73a3679687f414a1e4001afc3a40da43fc 100644 (file)
@@ -964,3 +964,4 @@ static ssize_t pt_write(struct file * filp, const char * buf,
 
 /* end of pt.c */
 
+MODULE_LICENSE("GPL");
index d4d3a19dc57fbc72952914ec19ea1cdb595de46c..c8e0dd4df72db44e8c3ad3f892cee57773beef6c 100644 (file)
@@ -155,6 +155,7 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
    tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
    tristate '  Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
    tristate '  Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT
+   tristate '  IB700 SBC Watchdog Timer' CONFIG_IB700_WDT
    tristate '  SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
    tristate '  W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT
    tristate '  Mixcom Watchdog' CONFIG_MIXCOMWD 
@@ -191,7 +192,7 @@ fi
 tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
 tristate 'Siemens R3964 line discipline' CONFIG_R3964
 tristate 'Applicom intelligent fieldbus card support' CONFIG_APPLICOM
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_X86" = "y" ]; then
    dep_tristate 'Sony Vaio Programmable I/O Control Device support' CONFIG_SONYPI $CONFIG_PCI
 fi
 
index eaa0d5568778f4e258b0c697c1e5c88118efaa5f..081f82a0cdc978ab779066c1a08ab5798457ae26 100644 (file)
@@ -220,6 +220,7 @@ obj-$(CONFIG_NWFLASH) += nwflash.o
 obj-$(CONFIG_PCWATCHDOG) += pcwd.o
 obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
+obj-$(CONFIG_IB700_WDT) += ib700wdt.o
 obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
 obj-$(CONFIG_WDT) += wdt.o
index 46960b39cb25a7a02be6d296b012b82859cf8840..d817fa57b0a064b5a7143b97ac9821866e340987 100644 (file)
@@ -206,4 +206,4 @@ static void __exit adb_mouse_cleanup(void)
 module_init(adb_mouse_init);
 module_exit(adb_mouse_cleanup);
 
-MODULE_LICENSE("GPL"):
+MODULE_LICENSE("GPL");
index a9ad070aec7ee31f69c7e635c48cc6de407a36bf..72ee3ef7173e9443a29837715875a5006578ccd3 100644 (file)
@@ -342,6 +342,7 @@ MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
 
 MODULE_AUTHOR("Jeff Garzik, Philipp Rumpf, Matt Sottek");
 MODULE_DESCRIPTION("Intel i8xx chipset Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");
 
 
 /*
diff --git a/drivers/char/ib700wdt.c b/drivers/char/ib700wdt.c
new file mode 100644 (file)
index 0000000..51d8fde
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ *     IB700 Single Board Computer WDT driver for Linux 2.4.x
+ *
+ *     (c) Copyright 2001 Charles Howes <chowes@vsol.net>
+ *
+ *      Based on advantechwdt.c which is based on acquirewdt.c which
+ *       is based on wdt.c.
+ *
+ *     (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
+ *
+ *     Based on acquirewdt.c which is based on wdt.c.
+ *     Original copyright messages:
+ *
+ *     (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *                             http://www.redhat.com
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ *
+ *     Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *     warranty for any of this software. This material is provided
+ *     "AS-IS" and at no charge.
+ *
+ *     (c) Copyright 1995    Alan Cox <alan@redhat.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+
+static int ibwdt_is_open;
+static spinlock_t ibwdt_lock;
+
+/*
+ *
+ * Watchdog Timer Configuration
+ *
+ * The function of the watchdog timer is to reset the system
+ * automatically and is defined at I/O port 0443H.  To enable the
+ * watchdog timer and allow the system to reset, write I/O port 0443H.
+ * To disable the timer, write I/O port 0441H for the system to stop the
+ * watchdog function.  The timer has a tolerance of 20% for its
+ * intervals.
+ *
+ * The following describes how the timer should be programmed.
+ *
+ * Enabling Watchdog:
+ * MOV AX,000FH (Choose the values from 0 to F)
+ * MOV DX,0443H
+ * OUT DX,AX
+ *
+ * Disabling Watchdog:
+ * MOV AX,000FH (Any value is fine.)
+ * MOV DX,0441H
+ * OUT DX,AX
+ *
+ * Watchdog timer control table:
+ * Level   Value  Time/sec | Level Value Time/sec
+ *   1       F       0     |   9     7      16
+ *   2       E       2     |   10    6      18
+ *   3       D       4     |   11    5      20
+ *   4       C       6     |   12    4      22
+ *   5       B       8     |   13    3      24
+ *   6       A       10    |   14    2      26
+ *   7       9       12    |   15    1      28
+ *   8       8       14    |   16    0      30
+ *
+ */
+
+#define WDT_STOP 0x441
+#define WDT_START 0x443
+
+#define WD_TIMO 0              /* 30 seconds +/- 20%, from table */
+
+/*
+ *     Kernel methods.
+ */
+
+static void
+ibwdt_ping(void)
+{
+       /* Write a watchdog value */
+       outb_p(WD_TIMO, WDT_START);
+}
+
+static ssize_t
+ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+       /*  Can't seek (pwrite) on this device  */
+       if (ppos != &file->f_pos)
+               return -ESPIPE;
+
+       if (count) {
+               ibwdt_ping();
+               return 1;
+       }
+       return 0;
+}
+
+static ssize_t
+ibwdt_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+       return -EINVAL;
+}
+
+static int
+ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+         unsigned long arg)
+{
+       static struct watchdog_info ident = {
+               WDIOF_KEEPALIVEPING, 1, "IB700 WDT"
+       };
+
+       switch (cmd) {
+       case WDIOC_GETSUPPORT:
+         if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+           return -EFAULT;
+         break;
+
+       case WDIOC_GETSTATUS:
+         if (copy_to_user((int *)arg, &ibwdt_is_open,  sizeof(int)))
+           return -EFAULT;
+         break;
+
+       case WDIOC_KEEPALIVE:
+         ibwdt_ping();
+         break;
+
+       default:
+         return -ENOTTY;
+       }
+       return 0;
+}
+
+static int
+ibwdt_open(struct inode *inode, struct file *file)
+{
+       switch (MINOR(inode->i_rdev)) {
+               case WATCHDOG_MINOR:
+                       spin_lock(&ibwdt_lock);
+                       if (ibwdt_is_open) {
+                               spin_unlock(&ibwdt_lock);
+                               return -EBUSY;
+                       }
+                       /*
+                        *      Activate
+                        */
+
+                       ibwdt_is_open = 1;
+                       ibwdt_ping();
+                       spin_unlock(&ibwdt_lock);
+                       return 0;
+               default:
+                       return -ENODEV;
+       }
+}
+
+static int
+ibwdt_close(struct inode *inode, struct file *file)
+{
+       lock_kernel();
+       if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
+               spin_lock(&ibwdt_lock);
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+               outb_p(WD_TIMO, WDT_STOP);
+#endif
+               ibwdt_is_open = 0;
+               spin_unlock(&ibwdt_lock);
+       }
+       unlock_kernel();
+       return 0;
+}
+
+/*
+ *     Notifier for system down
+ */
+
+static int
+ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
+       void *unused)
+{
+       if (code == SYS_DOWN || code == SYS_HALT) {
+               /* Turn the WDT off */
+               outb_p(WD_TIMO, WDT_STOP);
+       }
+       return NOTIFY_DONE;
+}
+
+/*
+ *     Kernel Interfaces
+ */
+
+static struct file_operations ibwdt_fops = {
+       owner:          THIS_MODULE,
+       read:           ibwdt_read,
+       write:          ibwdt_write,
+       ioctl:          ibwdt_ioctl,
+       open:           ibwdt_open,
+       release:        ibwdt_close,
+};
+
+static struct miscdevice ibwdt_miscdev = {
+       WATCHDOG_MINOR,
+       "watchdog",
+       &ibwdt_fops
+};
+
+/*
+ *     The WDT needs to learn about soft shutdowns in order to
+ *     turn the timebomb registers off.
+ */
+
+static struct notifier_block ibwdt_notifier = {
+       ibwdt_notify_sys,
+       NULL,
+       0
+};
+
+static int __init
+ibwdt_init(void)
+{
+       printk("WDT driver for IB700 single board computer initialising.\n");
+
+       spin_lock_init(&ibwdt_lock);
+       misc_register(&ibwdt_miscdev);
+#if WDT_START != WDT_STOP
+       request_region(WDT_STOP, 1, "IB700 WDT");
+#endif
+       request_region(WDT_START, 1, "IB700 WDT");
+       register_reboot_notifier(&ibwdt_notifier);
+       return 0;
+}
+
+static void __exit
+ibwdt_exit(void)
+{
+       misc_deregister(&ibwdt_miscdev);
+       unregister_reboot_notifier(&ibwdt_notifier);
+#if WDT_START != WDT_STOP
+       release_region(WDT_STOP,1);
+#endif
+       release_region(WDT_START,1);
+}
+
+module_init(ibwdt_init);
+module_exit(ibwdt_exit);
+
+MODULE_AUTHOR("Charles Howes <chowes@vsol.net>");
+MODULE_DESCRIPTION("IB700 SBC watchdog driver");
+MODULE_LICENSE("GPL");
+
+/* end of ib700wdt.c */
index 1d09acd8264f2fccaabf332e209591a7b2ed2505..7e9f3085765be519ba5e4394a7245334187678e8 100644 (file)
@@ -3458,3 +3458,4 @@ ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned lo
 }
 
 
+MODULE_LICENSE("GPL");
index d4527cde417667e820c899950a5e0ff6bbef39c9..75a3878f6f40d533959012858725ec175c75aa64 100644 (file)
@@ -386,6 +386,8 @@ static stlibrdtype_t        stli_brdstr[] = {
  */
 MODULE_AUTHOR("Greg Ungerer");
 MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(board0, "1-3s");
 MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");
index 839904342781ecc6e9a0cf56b6e2023761cdff9b..9ca09941ce9f65788133645957073e9776d50cbf 100644 (file)
 #define __exit
 #endif
 
+MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
+MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
+MODULE_LICENSE("GPL");
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static int mwave_get_info(char *buf, char **start, off_t offset, int len);
 #else
index 41ae0a4ad33fd67846960a048a59db74ebc526de..4c671f7dce065510d3eb182c4b2f10c5fde02f18 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <asm/system.h>
 
 #include "sonypi.h"
 #include <linux/sonypi.h>
@@ -48,7 +49,7 @@ static int minor = -1;
 static int verbose; /* = 0 */
 static int fnkeyinit; /* = 0 */
 static int camera; /* = 0 */
-extern int is_sony_vaio_laptop; /* set in DMI table parse routines */
+static int compat; /* = 0 */
 
 /* Inits the queue */
 static inline void sonypi_initq(void) {
@@ -110,27 +111,27 @@ static inline int sonypi_emptyq(void) {
 
 static void sonypi_ecrset(u16 addr, u16 value) {
 
-       wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
+       wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3);
        outw_p(0x81, SONYPI_CST_IOPORT);
-       wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+       wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
        outw_p(addr, SONYPI_DATA_IOPORT);
-       wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+       wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
        outw_p(value, SONYPI_DATA_IOPORT);
-       wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+       wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
 }
 
 static u16 sonypi_ecrget(u16 addr) {
 
-       wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
+       wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3);
        outw_p(0x80, SONYPI_CST_IOPORT);
-       wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+       wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
        outw_p(addr, SONYPI_DATA_IOPORT);
-       wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+       wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
        return inw_p(SONYPI_DATA_IOPORT);
 }
 
 /* Initializes the device - this comes from the AML code in the ACPI bios */
-static void __devinit sonypi_normal_srs(void) {
+static void __devinit sonypi_type1_srs(void) {
        u32 v;
 
        pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
@@ -152,7 +153,7 @@ static void __devinit sonypi_normal_srs(void) {
        pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
 }
 
-static void __devinit sonypi_r505_srs(void) {
+static void __devinit sonypi_type2_srs(void) {
        sonypi_ecrset(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8);
        sonypi_ecrset(SONYPI_SLOB,  sonypi_device.ioport1 & 0x00FF);
        sonypi_ecrset(SONYPI_SIRQ,  sonypi_device.bits);
@@ -160,7 +161,7 @@ static void __devinit sonypi_r505_srs(void) {
 }
 
 /* Disables the device - this comes from the AML code in the ACPI bios */
-static void __devexit sonypi_normal_dis(void) {
+static void __devexit sonypi_type1_dis(void) {
        u32 v;
 
        pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
@@ -172,7 +173,7 @@ static void __devexit sonypi_normal_dis(void) {
        outl(v, SONYPI_IRQ_PORT);
 }
 
-static void __devexit sonypi_r505_dis(void) {
+static void __devexit sonypi_type2_dis(void) {
        sonypi_ecrset(SONYPI_SHIB, 0);
        sonypi_ecrset(SONYPI_SLOB, 0);
        sonypi_ecrset(SONYPI_SIRQ, 0);
@@ -181,7 +182,7 @@ static void __devexit sonypi_r505_dis(void) {
 static u8 sonypi_call1(u8 dev) {
        u8 v1, v2;
 
-       wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+       wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
        outb(dev, sonypi_device.ioport2);
        v1 = inb_p(sonypi_device.ioport2);
        v2 = inb_p(sonypi_device.ioport1);
@@ -191,9 +192,9 @@ static u8 sonypi_call1(u8 dev) {
 static u8 sonypi_call2(u8 dev, u8 fn) {
        u8 v1;
 
-       wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+       wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
        outb(dev, sonypi_device.ioport2);
-       wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+       wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
        outb(fn, sonypi_device.ioport1);
        v1 = inb_p(sonypi_device.ioport1);
        return v1;
@@ -202,11 +203,11 @@ static u8 sonypi_call2(u8 dev, u8 fn) {
 static u8 sonypi_call3(u8 dev, u8 fn, u8 v) {
        u8 v1;
 
-       wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+       wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
        outb(dev, sonypi_device.ioport2);
-       wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+       wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
        outb(fn, sonypi_device.ioport1);
-       wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+       wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
        outb(v, sonypi_device.ioport1);
        v1 = inb_p(sonypi_device.ioport1);
        return v1;
@@ -228,7 +229,7 @@ static u8 sonypi_read(u8 fn) {
 /* Set brightness, hue etc */
 static void sonypi_set(u8 fn, u8 v) {
        
-       wait_on_command(sonypi_call3(0x90, fn, v));
+       wait_on_command(0, sonypi_call3(0x90, fn, v));
 }
 
 /* Tests if the camera is ready */
@@ -291,19 +292,19 @@ void sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) {
        int i;
        u8 sonypi_jogger_ev, sonypi_fnkey_ev;
 
-       if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505) {
-               sonypi_jogger_ev = SONYPI_R505_JOGGER_EV;
-               sonypi_fnkey_ev = SONYPI_R505_FNKEY_EV;
+       if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
+               sonypi_jogger_ev = SONYPI_TYPE2_JOGGER_EV;
+               sonypi_fnkey_ev = SONYPI_TYPE2_FNKEY_EV;
        }
        else {
-               sonypi_jogger_ev = SONYPI_NORMAL_JOGGER_EV;
-               sonypi_fnkey_ev = SONYPI_NORMAL_FNKEY_EV;
+               sonypi_jogger_ev = SONYPI_TYPE1_JOGGER_EV;
+               sonypi_fnkey_ev = SONYPI_TYPE1_FNKEY_EV;
        }
 
        v1 = inb_p(sonypi_device.ioport1);
        v2 = inb_p(sonypi_device.ioport2);
 
-       if ((v2 & SONYPI_NORMAL_PKEY_EV) == SONYPI_NORMAL_PKEY_EV) {
+       if ((v2 & SONYPI_TYPE1_PKEY_EV) == SONYPI_TYPE1_PKEY_EV) {
                for (i = 0; sonypi_pkeyev[i].event; i++)
                        if (sonypi_pkeyev[i].data == v1) {
                                event = sonypi_pkeyev[i].event;
@@ -338,9 +339,23 @@ void sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) {
                                goto found;
                        }
        }
+       if ((v2 & SONYPI_BACK_EV) == SONYPI_BACK_EV) {
+               for (i = 0; sonypi_backev[i].event; i++)
+                       if (sonypi_backev[i].data == v1) {
+                               event = sonypi_backev[i].event;
+                               goto found;
+                       }
+       }
+       if ((v2 & SONYPI_LID_EV) == SONYPI_LID_EV) {
+               for (i = 0; sonypi_lidev[i].event; i++)
+                       if (sonypi_lidev[i].data == v1) {
+                               event = sonypi_lidev[i].event;
+                               goto found;
+                       }
+       }
        if (verbose)
                printk(KERN_WARNING 
-                      "sonypi: unknown event port1=0x%x,port2=0x%x\n",v1,v2);
+                      "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",v1,v2);
        return;
 
 found:
@@ -564,15 +579,15 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev,
                goto out1;
        }
 
-       if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505) {
-               ioport_list = sonypi_r505_ioport_list;
-               sonypi_device.region_size = SONYPI_R505_REGION_SIZE;
-               irq_list = sonypi_r505_irq_list;
+       if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
+               ioport_list = sonypi_type2_ioport_list;
+               sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
+               irq_list = sonypi_type2_irq_list;
        }
        else {
-               ioport_list = sonypi_normal_ioport_list;
-               sonypi_device.region_size = SONYPI_NORMAL_REGION_SIZE;
-               irq_list = sonypi_normal_irq_list;
+               ioport_list = sonypi_type1_ioport_list;
+               sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
+               irq_list = sonypi_type1_irq_list;
        }
 
        for (i = 0; ioport_list[i].port1; i++) {
@@ -608,22 +623,28 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev,
        if (fnkeyinit)
                outb(0xf0, 0xb2);
 
-       if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505)
-               sonypi_r505_srs();
+       if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+               sonypi_type2_srs();
        else
-               sonypi_normal_srs();
+               sonypi_type1_srs();
 
        sonypi_call1(0x82);
        sonypi_call2(0x81, 0xff);
-       sonypi_call1(0x92); 
+       if (compat)
+               sonypi_call1(0x92); 
+       else
+               sonypi_call1(0x82);
 
        printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver v%d.%d.\n",
               SONYPI_DRIVER_MAJORVERSION,
               SONYPI_DRIVER_MINORVERSION);
-       printk(KERN_INFO "sonypi: detected %s model, camera = %s\n",
-              (sonypi_device.model == SONYPI_DEVICE_MODEL_NORMAL) ?
-              "normal" : "R505",
-              camera ? "on" : "off");
+       printk(KERN_INFO "sonypi: detected %s model (%04x:%04x), "
+              "camera = %s, compat = %s\n",
+              (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
+                       "type1" : "type2",
+              sonypi_device.dev->vendor, sonypi_device.dev->device,
+              camera ? "on" : "off",
+              compat ? "on" : "off");
        printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
               sonypi_device.irq, 
               sonypi_device.ioport1, sonypi_device.ioport2);
@@ -645,10 +666,10 @@ static void __devexit sonypi_remove(struct pci_dev *pcidev) {
        sonypi_call2(0x81, 0); /* make sure we don't get any more events */
        if (camera)
                sonypi_camera_off();
-       if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505)
-               sonypi_r505_dis();
+       if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+               sonypi_type2_dis();
        else
-               sonypi_normal_dis();
+               sonypi_type1_dis();
        free_irq(sonypi_device.irq, sonypi_irq);
        release_region(sonypi_device.ioport1, sonypi_device.region_size);
        misc_deregister(&sonypi_misc_device);
@@ -658,10 +679,13 @@ static void __devexit sonypi_remove(struct pci_dev *pcidev) {
 static struct pci_device_id sonypi_id_tbl[] __devinitdata = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, 
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-         (unsigned long) SONYPI_DEVICE_MODEL_NORMAL },
+         (unsigned long) SONYPI_DEVICE_MODEL_TYPE1 },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-         (unsigned long) SONYPI_DEVICE_MODEL_R505 },
+         (unsigned long) SONYPI_DEVICE_MODEL_TYPE2 },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+         (unsigned long) SONYPI_DEVICE_MODEL_TYPE2 },
        { }
 };
 
@@ -685,6 +709,33 @@ static void __exit sonypi_cleanup_module(void) {
        pci_unregister_driver(&sonypi_driver);
 }
 
+#ifndef MODULE
+static int __init sonypi_setup(char *str)  {
+       int ints[6];
+
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       if (ints[0] <= 0) 
+               goto out;
+       minor = ints[1];
+       if (ints[0] == 1)
+               goto out;
+       verbose = ints[2];
+       if (ints[0] == 2)
+               goto out;
+       fnkeyinit = ints[3];
+       if (ints[0] == 3)
+               goto out;
+       camera = ints[4];
+       if (ints[0] == 4)
+               goto out;
+       compat = ints[5];
+out:
+       return 1;
+}
+
+__setup("sonypi=", sonypi_setup);
+#endif /* !MODULE */
+       
 /* Module entry points */
 module_init(sonypi_init_module);
 module_exit(sonypi_cleanup_module);
@@ -702,5 +753,7 @@ MODULE_PARM(fnkeyinit,"i");
 MODULE_PARM_DESC(fnkeyinit, "set this if your Fn keys do not generate any event");
 MODULE_PARM(camera,"i");
 MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)");
+MODULE_PARM(compat,"i");
+MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode");
 
 EXPORT_SYMBOL(sonypi_camera_command);
index 023ae15d2ea69e4092167350041c0b591c994b31..e927a5cf342e780fcba2dd7bc0fd120cad4defea 100644 (file)
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION     1
-#define SONYPI_DRIVER_MINORVERSION     5
+#define SONYPI_DRIVER_MINORVERSION     6
 
 #include <linux/types.h>
 #include <linux/pci.h>
 #include "linux/sonypi.h"
 
-/* Normal models use those */
+/* type1 models use those */
 #define SONYPI_IRQ_PORT                        0x8034
 #define SONYPI_IRQ_SHIFT               22
 #define SONYPI_BASE                    0x50
 #define SONYPI_G10A                    (SONYPI_BASE+0x14)
-#define SONYPI_NORMAL_REGION_SIZE      0x08
+#define SONYPI_TYPE1_REGION_SIZE       0x08
 
-/* R505 series specifics */
-#define SONYPI_SIRQ            0x9b
-#define SONYPI_SLOB            0x9c
-#define SONYPI_SHIB            0x9d
-#define SONYPI_R505_REGION_SIZE        0x20
+/* type2 series specifics */
+#define SONYPI_SIRQ                    0x9b
+#define SONYPI_SLOB                    0x9c
+#define SONYPI_SHIB                    0x9d
+#define SONYPI_TYPE2_REGION_SIZE       0x20
 
-/* ioports used for brightness and R505 events */
+/* ioports used for brightness and type2 events */
 #define SONYPI_DATA_IOPORT     0x62
 #define SONYPI_CST_IOPORT      0x66
 
@@ -64,7 +64,7 @@ struct sonypi_ioport_list {
        u16     port2;
 };
 
-static struct sonypi_ioport_list sonypi_normal_ioport_list[] = {
+static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
        { 0x10c0, 0x10c4 },     /* looks like the default on C1Vx */
        { 0x1080, 0x1084 },
        { 0x1090, 0x1094 },
@@ -73,7 +73,7 @@ static struct sonypi_ioport_list sonypi_normal_ioport_list[] = {
        { 0x0, 0x0 }
 };
 
-static struct sonypi_ioport_list sonypi_r505_ioport_list[] = {
+static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
        { 0x1080, 0x1084 },
        { 0x10a0, 0x10a4 },
        { 0x10c0, 0x10c4 },
@@ -87,14 +87,14 @@ struct sonypi_irq_list {
        u16     bits;
 };
 
-static struct sonypi_irq_list sonypi_normal_irq_list[] = {
+static struct sonypi_irq_list sonypi_type1_irq_list[] = {
        { 11, 0x2 },    /* IRQ 11, GO22=0,GO23=1 in AML */
        { 10, 0x1 },    /* IRQ 10, GO22=1,GO23=0 in AML */
        {  5, 0x0 },    /* IRQ  5, GO22=0,GO23=0 in AML */
        {  0, 0x3 }     /* no IRQ, GO22=1,GO23=1 in AML */
 };
 
-static struct sonypi_irq_list sonypi_r505_irq_list[] = {
+static struct sonypi_irq_list sonypi_type2_irq_list[] = {
        { 11, 0x80 },   /* IRQ 11, 0x80 in SIRQ in AML */
        { 10, 0x40 },   /* IRQ 10, 0x40 in SIRQ in AML */
        {  9, 0x20 },   /* IRQ  9, 0x20 in SIRQ in AML */
@@ -132,13 +132,15 @@ static struct sonypi_irq_list sonypi_r505_irq_list[] = {
 #define SONYPI_CAMERA_ROMVERSION               9
 
 /* key press event data (ioport2) */
-#define SONYPI_NORMAL_JOGGER_EV        0x10
-#define SONYPI_R505_JOGGER_EV  0x08
+#define SONYPI_TYPE1_JOGGER_EV 0x10
+#define SONYPI_TYPE2_JOGGER_EV 0x08
 #define SONYPI_CAPTURE_EV      0x60
-#define SONYPI_NORMAL_FNKEY_EV 0x20
-#define SONYPI_R505_FNKEY_EV   0x08
+#define SONYPI_TYPE1_FNKEY_EV  0x20
+#define SONYPI_TYPE2_FNKEY_EV  0x08
 #define SONYPI_BLUETOOTH_EV    0x30
-#define SONYPI_NORMAL_PKEY_EV  0x40
+#define SONYPI_TYPE1_PKEY_EV   0x40
+#define SONYPI_BACK_EV         0x08
+#define SONYPI_LID_EV          0x38
 
 struct sonypi_event {
        u8      data;
@@ -204,6 +206,19 @@ static struct sonypi_event sonypi_blueev[] = {
        { 0x00, 0x00 }
 };
 
+/* The set of possible back button events */
+static struct sonypi_event sonypi_backev[] = {
+       { 0x20, SONYPI_EVENT_BACK_PRESSED },
+       { 0x00, 0x00 }
+};
+
+/* The set of possible lid events */
+static struct sonypi_event sonypi_lidev[] = {
+       { 0x51, SONYPI_EVENT_LID_CLOSED },
+       { 0x50, SONYPI_EVENT_LID_OPENED },
+       { 0x00, 0x00 }
+};
+
 #define SONYPI_BUF_SIZE        128
 struct sonypi_queue {
        unsigned long head;
@@ -215,8 +230,8 @@ struct sonypi_queue {
        unsigned char buf[SONYPI_BUF_SIZE];
 };
 
-#define SONYPI_DEVICE_MODEL_NORMAL     1
-#define SONYPI_DEVICE_MODEL_R505       2
+#define SONYPI_DEVICE_MODEL_TYPE1      1
+#define SONYPI_DEVICE_MODEL_TYPE2      2
 
 struct sonypi_device {
        struct pci_dev *dev;
@@ -232,11 +247,11 @@ struct sonypi_device {
        int model;
 };
 
-#define wait_on_command(command) { \
+#define wait_on_command(quiet, command) { \
        unsigned int n = 10000; \
        while (--n && (command)) \
                udelay(1); \
-       if (!n) \
+       if (!n && (verbose || !quiet)) \
                printk(KERN_WARNING "sonypi command failed at " __FILE__ " : " __FUNCTION__ "(line %d)\n", __LINE__); \
 }
 
index 0081542f538c5e1277fd3bea7ccf088388734a6d..60c5d71b88fabfba13dbe6e42a36781fe11709bd 100644 (file)
@@ -17,7 +17,9 @@
  *     0xfc15: Tom May <tom@you-bastards.com>
  *     0xfc17: Dave Konrad <konrad@xenia.it>
  *     0xfc1a: George Betzos <betzos@engr.colostate.edu>
+ *     0xfc1b: Munemasa Wada <munemasa@jnovel.co.jp>
  *     0xfc1d: Arthur Liu <armie@slap.mine.nu>
+ *     0xfc5a: Jacques L'helgoualc'h <lhh@free.fr>
  *     0xfcd1: Mr. Dave Konrad <konrad@xenia.it>
  *
  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -51,7 +53,7 @@
  *
  */
 
-#define TOSH_VERSION "1.9 22/3/2001"
+#define TOSH_VERSION "1.11 26/9/2001"
 #define TOSH_DEBUG 0
 
 #include <linux/module.h>
@@ -264,7 +266,7 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        if (!arg)
                return -EINVAL;
 
-       if(copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
+       if (copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
                return -EFAULT;
 
        switch (cmd) {
@@ -288,7 +290,7 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        return -EINVAL;
        }
 
-        if(copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
+        if (copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
                return -EFAULT;
 
        return (err==0) ? 0:-EINVAL;
@@ -335,7 +337,8 @@ static void tosh_set_fn_port(void)
 {
        switch (tosh_id) {
                case 0xfc02: case 0xfc04: case 0xfc09: case 0xfc0a: case 0xfc10:
-               case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a:
+               case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a: case 0xfc1b:
+               case 0xfc5a:
                        tosh_fn = 0x62;
                        break;
                case 0xfc08: case 0xfc17: case 0xfc1d: case 0xfcd1: case 0xfce0:
@@ -412,9 +415,20 @@ static int tosh_get_machine_id(void)
  */
 int tosh_probe(void)
 {
-       int major,minor,day,year,month,flag;
+       int i,major,minor,day,year,month,flag;
+       unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 };
        SMMRegisters regs;
 
+       /* extra sanity check for the string "TOSHIBA" in the BIOS because
+          some machines that are not Toshiba's pass the next test */
+
+       for (i=0;i<7;i++) {
+               if (isa_readb(0xfe010+i)!=signature[i]) {
+                       printk("toshiba: not a supported Toshiba laptop\n");
+                       return -ENODEV;
+               }
+       }
+
        /* call the Toshiba SCI support check routine */
        
        regs.eax = 0xf0f0;
index 16162d78ffabb13dd3c68140b90214971e14e9c5..924de1cb7eb054dbf126fff3b92714bd38440904 100644 (file)
@@ -764,3 +764,4 @@ EXPORT_NO_SYMBOLS;
 
 module_init(soc_probe);
 module_exit(soc_cleanup);
+MODULE_LICENSE("GPL");
index c52305f7117b580f5ec5adfa34833b6c59b97107..bec5167335861cc6be7e8af5891eb78697238c1a 100644 (file)
@@ -904,3 +904,4 @@ EXPORT_NO_SYMBOLS;
 
 module_init(socal_probe);
 module_exit(socal_cleanup);
+MODULE_LICENSE("GPL");
index 8b6cbf67a90034efb0e68ca6782e653d992f3a6d..a07c3f209be31a69d2d907247a32d09853d2ac63 100644 (file)
@@ -26,11 +26,24 @@ if [ "$CONFIG_I2C" != "n" ]; then
          dep_tristate '  ITE I2C Adapter' CONFIG_ITE_I2C_ADAP $CONFIG_ITE_I2C_ALGO
       fi
    fi
+   if [ "$CONFIG_8xx" = "y" ]; then
+      dep_tristate 'MPC8xx CPM I2C interface' CONFIG_I2C_ALGO8XX $CONFIG_I2C
+      if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then
+         dep_tristate '  Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX
+      fi
+   fi
+   if [ "$CONFIG_405" = "y" ]; then
+      dep_tristate 'PPC 405 I2C Algorithm' CONFIG_I2C_PPC405_ALGO $CONFIG_I2C
+      if [ "$CONFIG_I2C_PPC405_ALGO" != "n" ]; then
+         dep_tristate '  PPC 405 I2C Adapter' CONFIG_I2C_PPC405_ADAP $CONFIG_I2C_PPC405_ALGO
+      fi
+   fi
 
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
 
    dep_tristate 'I2C device interface' CONFIG_I2C_CHARDEV $CONFIG_I2C
+   dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C
 
 fi
 endmenu
index d25ed14f36e2b2811f8075bcd953e4b35d7cd05e..5bd254afd23ed18ece2860a90bd78fd2977b9aa4 100644 (file)
@@ -4,7 +4,8 @@
 
 O_TARGET := i2c.o
 
-export-objs    := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o
+export-objs    := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \
+                  i2c-algo-ite.o i2c-proc.o
 
 obj-$(CONFIG_I2C)              += i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)      += i2c-dev.o
@@ -14,6 +15,9 @@ obj-$(CONFIG_I2C_ELV)         += i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)     += i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)      += i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
+obj-$(CONFIG_ITE_I2C_ALGO)     += i2c-algo-ite.o
+obj-$(CONFIG_ITE_I2C_ADAP)     += i2c-adap-ite.o
+obj-$(CONFIG_I2C_PROC)         += i2c-proc.o
 
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
index ee1fc803785ade533221f38492537bfa470873e0..624decd1a0c00c4fe65192b8704b5501e926a112 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/init.h>
 #include <asm/irq.h>
index a26a6e16f7cb21e7b986f0ddbf94e6c3941814eb..7e968759a635975735718e71d07b72dea488421e 100644 (file)
@@ -21,7 +21,7 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-algo-bit.c,v 1.27 2000/07/09 15:16:16 frodo Exp $ */
+/* $Id: i2c-algo-bit.c,v 1.30 2001/07/29 02:44:25 mds Exp $ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
index 8c417ddc2ae90b4b3b6eed82aca807d815dd09fd..59170078f0776d2e77e636153a6690efefbf959e 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
index dd0ad032bdc8b5b6a7f6782abe91f484e7bb76a9..3cce04d6a702d23a9e20239f1ff0d7fcbf7c72ac 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ------------------------------------------------------------------------- */
 /* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters                */
 /* ------------------------------------------------------------------------- */
@@ -24,7 +23,9 @@
    Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
    <mbailey@littlefeet-inc.com> */
 
-/* $Id: i2c-algo-pcf.c,v 1.25 2000/11/10 13:43:32 frodo Exp $ */
+/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
+   messages, proper stop/repstart signaling during receive,
+   added detect code */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
        /* debug the protocol by showing transferred bits */
 #define DEF_TIMEOUT 16
 
-/* debugging - slow down transfer to have a look at the data ..        */
-/* I use this with two leds&resistors, each one connected to sda,scl   */
-/* respectively. This makes sure that the algorithm works. Some chips   */
-/* might not like this, as they have an internal timeout of some mils  */
-/*
-#define SLO_IO      jif=jiffies;while(jiffies<=jif+i2c_table[minor].veryslow)\
-                        if (need_resched) schedule();
-*/
-
-
-/* ----- global variables ---------------------------------------------        */
-
-#ifdef SLO_IO
-       int jif;
-#endif
-
 /* module parameters:
  */
-static int i2c_debug=1;
-static int pcf_test=0; /* see if the line-setting functions work       */
+static int i2c_debug=0;
 static int pcf_scan=0; /* have a look at what's hanging 'round         */
 
 /* --- setting states on the bus with the right timing: ---------------        */
@@ -80,7 +64,6 @@ static int pcf_scan=0;        /* have a look at what's hanging 'round         */
 #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
 #define i2c_inb(adap) adap->getpcf(adap->data, 0)
 
-
 /* --- other auxiliary functions --------------------------------------        */
 
 static void i2c_start(struct i2c_algo_pcf_data *adap) 
@@ -111,16 +94,15 @@ static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
        status = get_pcf(adap, 1);
 #ifndef STUB_I2C
        while (timeout-- && !(status & I2C_PCF_BB)) {
-               udelay(1000); /* How much is this? */
+               udelay(100); /* wait for 100 us */
                status = get_pcf(adap, 1);
        }
 #endif
-       if (timeout<=0)
+       if (timeout <= 0) {
                printk("Timeout waiting for Bus Busy\n");
-       /*
-       set_pcf(adap, 1, I2C_PCF_STOP);
-       */
-       return(timeout<=0);
+       }
+       
+       return (timeout<=0);
 }
 
 
@@ -147,7 +129,6 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
                return(0);
 }
 
-
 /* 
  * This should perform the 'PCF8584 initialization sequence' as described
  * in the Philips IC12 data book (1995, Aug 29).
@@ -156,111 +137,64 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
  * There should be a delay at the end equal to the longest I2C message
  * to synchronize the BB-bit (in multimaster systems). How long is
  * this? I assume 1 second is always long enough.
+ *
+ * vdovikin: added detect code for PCF8584
  */
 static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
 {
+       unsigned char temp;
+
+       DEB3(printk("i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
 
-       /* S1=0x80: S0 selected, serial interface off                   */
+       /* S1=0x80: S0 selected, serial interface off */
        set_pcf(adap, 1, I2C_PCF_PIN);
+       /* check to see S1 now used as R/W ctrl -
+          PCF8584 does that when ESO is zero */
+       /* PCF also resets PIN bit */
+       if ((temp = get_pcf(adap, 1)) != (0)) {
+               DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
+               return -ENXIO; /* definetly not PCF8584 */
+       }
 
        /* load own address in S0, effective address is (own << 1)      */
        i2c_outb(adap, get_own(adap));
+       /* check it's realy writen */
+       if ((temp = i2c_inb(adap)) != get_own(adap)) {
+               DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
+               return -ENXIO;
+       }
 
        /* S1=0xA0, next byte in S2                                     */
        set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
+       /* check to see S2 now selected */
+       if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) {
+               DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
+               return -ENXIO;
+       }
 
        /* load clock register S2                                       */
        i2c_outb(adap, get_clock(adap));
+       /* check it's realy writen, the only 5 lowest bits does matter */
+       if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
+               DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
+               return -ENXIO;
+       }
 
        /* Enable serial interface, idle, S0 selected                   */
        set_pcf(adap, 1, I2C_PCF_IDLE);
 
-       DEB2(printk("i2c-algo-pcf.o: irq: Initialized 8584.\n"));
-       return 0;
-}
-
-
-/*
- * Sanity check for the adapter hardware - check the reaction of
- * the bus lines only if it seems to be idle.
- */
-static int test_bus(struct i2c_algo_pcf_data *adap, char *name) {
-#if 0
-       int scl,sda;
-       sda=getsda(adap);
-       if (adap->getscl==NULL) {
-               printk("i2c-algo-pcf.o: Warning: Adapter can't read from clock line - skipping test.\n");
-               return 0;               
-       }
-       scl=getscl(adap);
-       printk("i2c-algo-pcf.o: Adapter: %s scl: %d  sda: %d -- testing...\n",
-       name,getscl(adap),getsda(adap));
-       if (!scl || !sda ) {
-               printk("i2c-algo-pcf.o: %s seems to be busy.\n",adap->name);
-               goto bailout;
+       /* check to see PCF is realy idled and we can access status register */
+       if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
+               DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
+               return -ENXIO;
        }
-       sdalo(adap);
-       printk("i2c-algo-pcf.o:1 scl: %d  sda: %d \n",getscl(adap),
-              getsda(adap));
-       if ( 0 != getsda(adap) ) {
-               printk("i2c-algo-pcf.o: %s SDA stuck high!\n",name);
-               sdahi(adap);
-               goto bailout;
-       }
-       if ( 0 == getscl(adap) ) {
-               printk("i2c-algo-pcf.o: %s SCL unexpected low while pulling SDA low!\n",
-                       name);
-               goto bailout;
-       }               
-       sdahi(adap);
-       printk("i2c-algo-pcf.o:2 scl: %d  sda: %d \n",getscl(adap),
-              getsda(adap));
-       if ( 0 == getsda(adap) ) {
-               printk("i2c-algo-pcf.o: %s SDA stuck low!\n",name);
-               sdahi(adap);
-               goto bailout;
-       }
-       if ( 0 == getscl(adap) ) {
-               printk("i2c-algo-pcf.o: %s SCL unexpected low while SDA high!\n",
-                      adap->name);
-       goto bailout;
-       }
-       scllo(adap);
-       printk("i2c-algo-pcf.o:3 scl: %d  sda: %d \n",getscl(adap),
-              getsda(adap));
-       if ( 0 != getscl(adap) ) {
-               printk("i2c-algo-pcf.o: %s SCL stuck high!\n",name);
-               sclhi(adap);
-               goto bailout;
-       }
-       if ( 0 == getsda(adap) ) {
-               printk("i2c-algo-pcf.o: %s SDA unexpected low while pulling SCL low!\n",
-                       name);
-               goto bailout;
-       }
-       sclhi(adap);
-       printk("i2c-algo-pcf.o:4 scl: %d  sda: %d \n",getscl(adap),
-              getsda(adap));
-       if ( 0 == getscl(adap) ) {
-               printk("i2c-algo-pcf.o: %s SCL stuck low!\n",name);
-               sclhi(adap);
-               goto bailout;
-       }
-       if ( 0 == getsda(adap) ) {
-               printk("i2c-algo-pcf.o: %s SDA unexpected low while SCL high!\n",
-                       name);
-               goto bailout;
-       }
-       printk("i2c-algo-pcf.o: %s passed test.\n",name);
+       
+       printk("i2c-algo-pcf.o: deteted and initialized PCF8584.\n");
+
        return 0;
-bailout:
-       sdahi(adap);
-       sclhi(adap);
-       return -ENODEV;
-#endif
-       return (0);
 }
 
+
 /* ----- Utility functions
  */
 
@@ -287,8 +221,8 @@ static inline int try_address(struct i2c_algo_pcf_data *adap,
 }
 
 
-static int pcf_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
-                         int count)
+static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
+                         int count, int last)
 {
        struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
        int wrcount, status, timeout;
@@ -313,58 +247,59 @@ static int pcf_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
                }
 #endif
        }
-       i2c_stop(adap);
+       if (last) {
+               i2c_stop(adap);
+       }
+       else {
+               i2c_repstart(adap);
+       }
+
        return (wrcount);
 }
 
 
-static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
+static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
+                         int count, int last)
 {
-       int rdcount=0, i, status, timeout, dummy=1;
+       int i, status;
        struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
-    
-       for (i=0; i<count; ++i) {
-               buf[rdcount] = i2c_inb(adap);
-               if (dummy) {
-                       dummy = 0;
-               } else {
-                       rdcount++;
-               }
-               timeout = wait_for_pin(adap, &status);
-               if (timeout) {
+
+       /* increment number of bytes to read by one -- read dummy byte */
+       for (i = 0; i <= count; i++) {
+
+               if (wait_for_pin(adap, &status)) {
                        i2c_stop(adap);
-                       printk("i2c-algo-pcf.o: i2c_read: "
-                              "i2c_inb timed out.\n");
+                       printk("i2c-algo-pcf.o: pcf_readbytes timed out.\n");
                        return (-1);
                }
+
 #ifndef STUB_I2C
-               if (status & I2C_PCF_LRB) {
+               if ((status & I2C_PCF_LRB) && (i != count)) {
                        i2c_stop(adap);
                        printk("i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n");
                        return (-1);
                }
 #endif
-       }
-       set_pcf(adap, 1, I2C_PCF_ESO);
-       buf[rdcount] = i2c_inb(adap);
-       if (dummy) {
-               dummy = 0;
-       } else {
-               rdcount++;
-       }
-       timeout = wait_for_pin(adap, &status);
-       if (timeout) {
-               i2c_stop(adap);
-               printk("i2c-algo-pcf.o: i2c_read: i2c_inb timed out.\n");
-               return (-1);
-       }
-    
-       i2c_stop(adap);
+               
+               if (i == count - 1) {
+                       set_pcf(adap, 1, I2C_PCF_ESO);
+               } else 
+               if (i == count) {
+                       if (last) {
+                               i2c_stop(adap);
+                       } else {
+                               i2c_repstart(adap);
+                       }
+               };
 
-       /* Read final byte from S0 register */
-       buf[rdcount++] = i2c_inb(adap);
+               if (i) {
+                       buf[i - 1] = i2c_inb(adap);
+               } else {
+                       i2c_inb(adap); /* dummy read */
+               }
+       }
 
-       return (rdcount);
+       return (i - 1);
 }
 
 
@@ -418,16 +353,10 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
 {
        struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
        struct i2c_msg *pmsg;
-       int i = 0;
-       int ret, timeout, status;
-    
-       pmsg = &msgs[i];
-    
-       /* Send address here if Read */
-       if (pmsg->flags & I2C_M_RD) {
-               ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
-       }
+       int i;
+       int ret=0, timeout, status;
     
+
        /* Check for bus busy */
        timeout = wait_for_bb(adap);
        if (timeout) {
@@ -435,60 +364,68 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
                            "Timeout waiting for BB in pcf_xfer\n");)
                return -EIO;
        }
+       
+       for (i = 0;ret >= 0 && i < num; i++) {
+               pmsg = &msgs[i];
+
+               DEB2(printk("i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
+                    pmsg->flags & I2C_M_RD ? "read" : "write",
+                     pmsg->len, pmsg->addr, i + 1, num);)
     
-       /* Send address here if Write */
-       if (!(pmsg->flags & I2C_M_RD)) {
                ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
-       }
-       /* Send START */
-       i2c_start(adap);
+
+               /* Send START */
+               if (i == 0) {
+                       i2c_start(adap); 
+               }
     
-       /* Wait for PIN (pending interrupt NOT) */
-       timeout = wait_for_pin(adap, &status);
-       if (timeout) {
-               i2c_stop(adap);
-               DEB2(printk("i2c-algo-pcf.o: Timeout waiting "
-                           "for PIN(1) in pcf_xfer\n");)
-               return (-EREMOTEIO);
-       }
+               /* Wait for PIN (pending interrupt NOT) */
+               timeout = wait_for_pin(adap, &status);
+               if (timeout) {
+                       i2c_stop(adap);
+                       DEB2(printk("i2c-algo-pcf.o: Timeout waiting "
+                                   "for PIN(1) in pcf_xfer\n");)
+                       return (-EREMOTEIO);
+               }
     
 #ifndef STUB_I2C
-       /* Check LRB (last rcvd bit - slave ack) */
-       if (status & I2C_PCF_LRB) {
-               i2c_stop(adap);
-               DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
-               return (-EREMOTEIO);
-       }
+               /* Check LRB (last rcvd bit - slave ack) */
+               if (status & I2C_PCF_LRB) {
+                       i2c_stop(adap);
+                       DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
+                       return (-EREMOTEIO);
+               }
 #endif
     
-       DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
-                   i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
+               DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
+                           i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
     
-       /* Read */
-       if (pmsg->flags & I2C_M_RD) {
-        
-               /* read bytes into buffer*/
-               ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len);
-        
-               if (ret != pmsg->len) {
-                       DEB2(printk("i2c-algo-pcf.o: fail: "
-                                   "only read %d bytes.\n",ret));
-               } else {
-                       DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));
-               }
-       } else { /* Write */
+               /* Read */
+               if (pmsg->flags & I2C_M_RD) {
+                       /* read bytes into buffer*/
+                       ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
+                                            (i + 1 == num));
         
-        /* Write bytes from buffer */
-               ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len);
+                       if (ret != pmsg->len) {
+                               DEB2(printk("i2c-algo-pcf.o: fail: "
+                                           "only read %d bytes.\n",ret));
+                       } else {
+                               DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));
+                       }
+               } else { /* Write */
+                       ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
+                                            (i + 1 == num));
         
-               if (ret != pmsg->len) {
-                       DEB2(printk("i2c-algo-pcf.o: fail: "
-                                   "only wrote %d bytes.\n",ret));
-               } else {
-                       DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));
+                       if (ret != pmsg->len) {
+                               DEB2(printk("i2c-algo-pcf.o: fail: "
+                                           "only wrote %d bytes.\n",ret));
+                       } else {
+                               DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));
+                       }
                }
        }
-       return (num);
+
+       return (i);
 }
 
 static int algo_control(struct i2c_adapter *adapter, 
@@ -524,12 +461,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
        int i, status;
        struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
 
-       if (pcf_test) {
-               int ret = test_bus(pcf_adap, adap->name);
-               if (ret<0)
-                       return -ENODEV;
-       }
-
        DEB2(printk("i2c-algo-pcf.o: hw routines for %s registered.\n",
                    adap->name));
 
@@ -538,21 +469,29 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
        adap->id |= pcf_algo.id;
        adap->algo = &pcf_algo;
 
-       adap->timeout = 100;    /* default values, should       */
+       adap->timeout = 100;            /* default values, should       */
        adap->retries = 3;              /* be replaced by defines       */
 
+       if ((i = pcf_init_8584(pcf_adap))) {
+               return i;
+       }
+
 #ifdef MODULE
        MOD_INC_USE_COUNT;
 #endif
 
        i2c_add_adapter(adap);
-       pcf_init_8584(pcf_adap);
 
        /* scan bus */
        if (pcf_scan) {
                printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s.\n",
                       adap->name);
                for (i = 0x00; i < 0xff; i+=2) {
+                       if (wait_for_bb(pcf_adap)) {
+                       printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s - TIMEOUTed.\n",
+                          adap->name);
+                           break;
+                       }
                        i2c_outb(pcf_adap, i);
                        i2c_start(pcf_adap);
                        if ((wait_for_pin(pcf_adap, &status) >= 0) && 
@@ -598,11 +537,9 @@ MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
 MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(pcf_test, "i");
 MODULE_PARM(pcf_scan, "i");
 MODULE_PARM(i2c_debug,"i");
 
-MODULE_PARM_DESC(pcf_test, "Test if the I2C bus is available");
 MODULE_PARM_DESC(pcf_scan, "Scan for active chips on the bus");
 MODULE_PARM_DESC(i2c_debug,
         "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
index 1e0f15552d7056076cafa18d09753265c983455e..01cb077f8cd3d1cd6cf344a7558320e286c26e5e 100644 (file)
@@ -20,7 +20,7 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
    All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-core.c,v 1.58 2000/10/29 22:57:38 frodo Exp $ */
+/* $Id: i2c-core.c,v 1.64 2001/08/13 01:35:56 mds Exp $ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -248,7 +248,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
                     */
                        if ((res=client->driver->detach_client(client))) {
                                printk("i2c-core.o: adapter %s not "
-                                       "unregisted, because client at "
+                                       "unregistered, because client at "
                                        "address %02x can't be detached. ",
                                        adap->name, client->addr);
                                goto ERROR0;
@@ -563,6 +563,7 @@ struct i2c_client *i2c_get_client(int driver_id, int adapter_id,
                        if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE)       
                                return adapters[j]->clients[i];
                }
+               i = 0;
        }
 
        return 0;
@@ -658,7 +659,7 @@ ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
        int i,j,k,order_nr,len=0,len_total;
        int order[I2C_CLIENT_MAX];
 
-       if (count 0)
+       if (count > 4000)
                return -EINVAL; 
        len_total = file->f_pos + count;
        /* Too bad if this gets longer (unlikely) */
@@ -1277,14 +1278,41 @@ static int __init i2c_init(void)
 }
 
 #ifndef MODULE
+#ifdef CONFIG_I2C_CHARDEV
        extern int i2c_dev_init(void);
+#endif
+#ifdef CONFIG_I2C_ALGOBIT
        extern int i2c_algo_bit_init(void);
+#endif
+#ifdef CONFIG_I2C_CONFIG_I2C_PHILIPSPAR
        extern int i2c_bitlp_init(void);
+#endif
+#ifdef CONFIG_I2C_ELV
        extern int i2c_bitelv_init(void);
+#endif
+#ifdef CONFIG_I2C_VELLEMAN
        extern int i2c_bitvelle_init(void);
+#endif
+#ifdef CONFIG_I2C_BITVIA
        extern int i2c_bitvia_init(void);
+#endif
+
+#ifdef CONFIG_I2C_ALGOPCF
        extern int i2c_algo_pcf_init(void);     
+#endif
+#ifdef CONFIG_I2C_ELEKTOR
        extern int i2c_pcfisa_init(void);
+#endif
+
+#ifdef CONFIG_I2C_ALGO8XX
+       extern int i2c_algo_8xx_init(void);
+#endif
+#ifdef CONFIG_I2C_RPXLITE
+       extern int i2c_rpx_init(void);
+#endif
+#ifdef CONFIG_I2C_PROC
+       extern int sensors_init(void);
+#endif
 
 /* This is needed for automatic patch generation: sensors code starts here */
 /* This is needed for automatic patch generation: sensors code ends here   */
@@ -1318,6 +1346,19 @@ int __init i2c_init_all(void)
 #ifdef CONFIG_I2C_ELEKTOR
        i2c_pcfisa_init();
 #endif
+
+       /* --------------------- 8xx -------- */
+#ifdef CONFIG_I2C_ALGO8XX
+       i2c_algo_8xx_init();
+#endif
+#ifdef CONFIG_I2C_RPXLITE
+       i2c_rpx_init();
+#endif
+
+       /* -------------- proc interface ---- */
+#ifdef CONFIG_I2C_PROC
+       sensors_init();
+#endif
 /* This is needed for automatic patch generation: sensors code starts here */
 /* This is needed for automatic patch generation: sensors code ends here */
 
index b5659bc7defdf4d015b5c39b2197668433c296bd..a7b80f932f63dc5a667cf909db5235ee58f84d7a 100644 (file)
@@ -28,7 +28,7 @@
 /* The devfs code is contributed by Philipp Matthias Hahn 
    <pmhahn@titan.lahn.de> */
 
-/* $Id: i2c-dev.c,v 1.36 2000/09/22 02:19:35 mds Exp $ */
+/* $Id: i2c-dev.c,v 1.40 2001/08/25 01:28:01 mds Exp $ */
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -60,6 +60,9 @@ extern int cleanup_module(void);
 
 /* struct file_operations changed too often in the 2.1 series for nice code */
 
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin);
+#endif
 static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, 
                             loff_t *offset);
 static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, 
@@ -88,7 +91,11 @@ static struct file_operations i2cdev_fops = {
 #if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
        owner:          THIS_MODULE,
 #endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+       llseek:         i2cdev_lseek,
+#else
        llseek:         no_llseek,
+#endif
        read:           i2cdev_read,
        write:          i2cdev_write,
        ioctl:          i2cdev_ioctl,
@@ -126,6 +133,20 @@ static struct i2c_client i2cdev_client_template = {
 
 static int i2cdev_initialized;
 
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+/* Note that the lseek function is called llseek in 2.1 kernels. But things
+   are complicated enough as is. */
+loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin)
+{
+#ifdef DEBUG
+       struct inode *inode = file->f_dentry->d_inode;
+       printk("i2c-dev.o: i2c-%d lseek to %ld bytes relative to %d.\n",
+              MINOR(inode->i_rdev),(long) offset,origin);
+#endif /* DEBUG */
+       return -ESPIPE;
+}
+#endif
+
 static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
                             loff_t *offset)
 {
@@ -227,9 +248,6 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
                                   sizeof(rdwr_arg)))
                        return -EFAULT;
 
-               if(rdwr_arg.nmsgs > 2048)
-                       return -EINVAL;
-                       
                rdwr_pa = (struct i2c_msg *)
                        kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), 
                        GFP_KERNEL);
@@ -505,7 +523,7 @@ int i2cdev_cleanup(void)
                               "module not removed.\n");
                        return res;
                }
-       i2cdev_initialized ++;
+       i2cdev_initialized --;
        }
 
        if (i2cdev_initialized >= 1) {
index 31cfa966dfe46d9448ac51b193603a5d25ef8d5e..ccefaac80769601b28242a443a49d283e5039b1f 100644 (file)
@@ -22,7 +22,8 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elektor.c,v 1.19 2000/07/25 23:52:17 frodo Exp $ */
+/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
+   for Alpha Processor Inc. UP-2000(+) boards */
 
 #include <linux/kernel.h>
 #include <linux/ioport.h>
@@ -31,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/init.h>
+#include <linux/pci.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
 #include <linux/i2c-elektor.h>
 #include "i2c-pcf8584.h"
 
-#define DEFAULT_BASE 0x300
-#define DEFAULT_IRQ      0
-#define DEFAULT_CLOCK 0x1c
-#define DEFAULT_OWN   0x55
-
-static int base  = 0;
-static int irq   = 0;
-static int clock = 0;
-static int own   = 0;
-static int i2c_debug=0;
-static struct i2c_pcf_isa gpi;
+#define DEFAULT_BASE 0x330
+
+static int base   = 0;
+static int irq    = 0;
+static int clock  = 0x1c;
+static int own    = 0x55;
+static int mmapped = 0;
+static int i2c_debug = 0;
+
+/* vdovikin: removed static struct i2c_pcf_isa gpi; code - 
+  this module in real supports only one device, due to missing arguments
+  in some functions, called from the algo-pcf module. Sometimes it's
+  need to be rewriten - but for now just remove this for simpler reading */
+
 #if (LINUX_VERSION_CODE < 0x020301)
 static struct wait_queue *pcf_wait = NULL;
 #else
@@ -63,81 +68,63 @@ static int pcf_pending;
 #define DEB3(x) if (i2c_debug>=3) x
 #define DEBE(x)        x       /* error messages                               */
 
-
-/* --- Convenience defines for the i2c port:                   */
-#define BASE   ((struct i2c_pcf_isa *)(data))->pi_base
-#define DATA   BASE                    /* Adapter data port            */
-#define CTRL   (BASE+1)                /* Adapter control port         */
-
 /* ----- local functions ----------------------------------------------        */
 
 static void pcf_isa_setbyte(void *data, int ctl, int val)
 {
-        unsigned long j = jiffies + 10;
-
-        if (ctl) {
-               if (gpi.pi_irq > 0) {
-                       DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n",
-                            val|I2C_PCF_ENI));
-                        DEB3({while (jiffies < j) schedule();})
-                       outb(val | I2C_PCF_ENI, CTRL);
-               } else {
-                        DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n", val|I2C_PCF_ENI));
-                         DEB3({while (jiffies < j) schedule();})
-                        outb(val|I2C_PCF_ENI, CTRL);
-               }
-       } else {
-               DEB3(printk("i2c-elektor.o: Write Data 0x%02X\n", val&0xff));
-                DEB3({while (jiffies < j) schedule();})
-               outb(val, DATA);
+       int address = ctl ? (base + 1) : base;
+
+       if (ctl && irq) {
+               val |= I2C_PCF_ENI;
+       }
+
+       DEB3(printk("i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+
+       switch (mmapped) {
+       case 0: /* regular I/O */
+               outb(val, address);
+               break;
+       case 2: /* double mapped I/O needed for UP2000 board,
+                   I don't know why this... */
+               writeb(val, address);
+               /* fall */
+       case 1: /* memory mapped I/O */
+               writeb(val, address);
+               break;
        }
 }
 
 static int pcf_isa_getbyte(void *data, int ctl)
 {
-       int val;
+       int address = ctl ? (base + 1) : base;
+       int val = mmapped ? readb(address) : inb(address);
+
+       DEB3(printk("i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
 
-       if (ctl) {
-               val = inb(CTRL);
-               DEB3(printk("i2c-elektor.o: Read Ctrl 0x%02X\n", val));
-       } else {
-               val = inb(DATA);
-               DEB3(printk("i2c-elektor.o: Read Data 0x%02X\n", val));
-       }
        return (val);
 }
 
 static int pcf_isa_getown(void *data)
 {
-       return (gpi.pi_own);
+       return (own);
 }
 
 
 static int pcf_isa_getclock(void *data)
 {
-       return (gpi.pi_clock);
-}
-
-
-
-#if 0
-static void pcf_isa_sleep(unsigned long timeout)
-{
-       schedule_timeout( timeout * HZ);
+       return (clock);
 }
-#endif
-
 
 static void pcf_isa_waitforpin(void) {
 
        int timeout = 2;
 
-       if (gpi.pi_irq > 0) {
+       if (irq > 0) {
                cli();
-       if (pcf_pending == 0) {
-               interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
-       } else
-               pcf_pending = 0;
+               if (pcf_pending == 0) {
+                       interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
+               } else
+                       pcf_pending = 0;
                sti();
        } else {
                udelay(100);
@@ -153,30 +140,34 @@ static void pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
 
 static int pcf_isa_init(void)
 {
-       if (check_region(gpi.pi_base, 2) < 0 ) {
-               return -ENODEV;
-       } else {
-               request_region(gpi.pi_base, 2, "i2c (isa bus adapter)");
+       if (!mmapped) {
+               if (check_region(base, 2) < 0 ) {
+                       printk("i2c-elektor.o: requested I/O region (0x%X:2) is in use.\n", base);
+                       return -ENODEV;
+               } else {
+                       request_region(base, 2, "i2c (isa bus adapter)");
+               }
        }
-       if (gpi.pi_irq > 0) {
-               if (request_irq(gpi.pi_irq, pcf_isa_handler, 0, "PCF8584", 0)
-                   < 0) {
-               printk("i2c-elektor.o: Request irq%d failed\n", gpi.pi_irq);
-               gpi.pi_irq = 0;
-       } else
-               enable_irq(gpi.pi_irq);
+       if (irq > 0) {
+               if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
+                       printk("i2c-elektor.o: Request irq%d failed\n", irq);
+                       irq = 0;
+               } else
+                       enable_irq(irq);
        }
        return 0;
 }
 
 
-static void pcf_isa_exit(void)
+static void __exit pcf_isa_exit(void)
 {
-       if (gpi.pi_irq > 0) {
-               disable_irq(gpi.pi_irq);
-               free_irq(gpi.pi_irq, 0);
+       if (irq > 0) {
+               disable_irq(irq);
+               free_irq(irq, 0);
+       }
+       if (!mmapped) {
+               release_region(base , 2);
        }
-       release_region(gpi.pi_base , 2);
 }
 
 
@@ -217,7 +208,7 @@ static struct i2c_algo_pcf_data pcf_isa_data = {
        pcf_isa_getown,
        pcf_isa_getclock,
        pcf_isa_waitforpin,
-       80, 80, 100,            /*      waits, timeout */
+       10, 10, 100,            /*      waits, timeout */
 };
 
 static struct i2c_adapter pcf_isa_ops = {
@@ -233,31 +224,61 @@ static struct i2c_adapter pcf_isa_ops = {
 
 int __init i2c_pcfisa_init(void) 
 {
+#ifdef __alpha__
+       /* check to see we have memory mapped PCF8584 connected to the 
+       Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
+       if ((base == 0) && pci_present()) {
+               
+               struct pci_dev *cy693_dev =
+                    pci_find_device(PCI_VENDOR_ID_CONTAQ, 
+                                   PCI_DEVICE_ID_CONTAQ_82C693, NULL);
+
+               if (cy693_dev) {
+                       char config;
+                       /* yeap, we've found cypress, let's check config */
+                       if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
+                               
+                               DEB3(printk("i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+
+                               /* UP2000 board has this register set to 0xe1,
+                                   but the most significant bit as seems can be 
+                                  reset during the proper initialisation
+                                   sequence if guys from API decides to do that
+                                   (so, we can even enable Tsunami Pchip
+                                   window for the upper 1 Gb) */
+
+                               /* so just check for ROMCS at 0xe0000,
+                                   ROMCS enabled for writes
+                                  and external XD Bus buffer in use. */
+                               if ((config & 0x7f) == 0x61) {
+                                       /* seems to be UP2000 like board */
+                                       base = 0xe0000;
+                                        /* I don't know why we need to
+                                           write twice */
+                                       mmapped = 2;
+                                        /* UP2000 drives ISA with
+                                          8.25 MHz (PCI/4) clock
+                                          (this can be read from cypress) */
+                                       clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
+                                       printk("i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+                               }
+                       }
+               }
+       }
+#endif
 
-       struct i2c_pcf_isa *pisa = &gpi;
+       /* sanity checks for mmapped I/O */
+       if (mmapped && base < 0xc8000) {
+               printk("i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+               return -ENODEV;
+       }
 
        printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n");
-       if (base == 0)
-               pisa->pi_base = DEFAULT_BASE;
-       else
-               pisa->pi_base = base;
-
-       if (irq == 0)
-               pisa->pi_irq = DEFAULT_IRQ;
-       else
-               pisa->pi_irq = irq;
-
-       if (clock == 0)
-               pisa->pi_clock = DEFAULT_CLOCK;
-       else
-               pisa->pi_clock = clock;
-
-       if (own == 0)
-               pisa->pi_own = DEFAULT_OWN;
-       else
-               pisa->pi_own = own;
-
-       pcf_isa_data.data = (void *)pisa;
+
+       if (base == 0) {
+               base = DEFAULT_BASE;
+       }
+
 #if (LINUX_VERSION_CODE >= 0x020301)
        init_waitqueue_head(&pcf_wait);
 #endif
@@ -267,7 +288,9 @@ int __init i2c_pcfisa_init(void)
        } else {
                return -ENODEV;
        }
-       printk("i2c-elektor.o: found device at %#x.\n", pisa->pi_base);
+       
+       printk("i2c-elektor.o: found device at %#x.\n", base);
+
        return 0;
 }
 
@@ -283,7 +306,8 @@ MODULE_PARM(base, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM(clock, "i");
 MODULE_PARM(own, "i");
-MODULE_PARM(i2c_debug,"i");
+MODULE_PARM(mmapped, "i");
+MODULE_PARM(i2c_debug, "i");
 
 int init_module(void) 
 {
index 4968f694f7ec485192f57c61b3e941182eb819e2..c820420419b2e577266e30826f705ec94d2a8cba 100644 (file)
@@ -21,7 +21,7 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elv.c,v 1.16 2000/01/18 23:54:07 frodo Exp $ */
+/* $Id: i2c-elv.c,v 1.17 2001/07/29 02:44:25 mds Exp $ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -115,7 +115,7 @@ static int bit_elv_init(void)
        return 0;
 }
 
-static void bit_elv_exit(void)
+static void __exit bit_elv_exit(void)
 {
        release_region( base , (base == 0x3bc)? 3 : 8 );
 }
diff --git a/drivers/i2c/i2c-proc.c b/drivers/i2c/i2c-proc.c
new file mode 100644 (file)
index 0000000..0145f77
--- /dev/null
@@ -0,0 +1,906 @@
+/*
+    i2c-proc.c - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+    Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl> and
+    Mark D. Studebaker <mdsxyz123@yahoo.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+    This driver puts entries in /proc/sys/dev/sensors for each I2C device
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-proc.h>
+
+#include <linux/init.h>
+
+/* FIXME need i2c versioning */
+#define LM_DATE "20010825"
+#define LM_VERSION "2.6.1"
+
+#ifndef THIS_MODULE
+#define THIS_MODULE NULL
+#endif
+
+static int i2c_create_name(char **name, const char *prefix,
+                              struct i2c_adapter *adapter, int addr);
+static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
+                              long *results, int magnitude);
+static int i2c_write_reals(int nrels, void *buffer, int *bufsize,
+                              long *results, int magnitude);
+static int i2c_proc_chips(ctl_table * ctl, int write,
+                             struct file *filp, void *buffer,
+                             size_t * lenp);
+static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
+                               void *oldval, size_t * oldlenp,
+                               void *newval, size_t newlen,
+                               void **context);
+
+int __init sensors_init(void);
+
+#define SENSORS_ENTRY_MAX 20
+static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
+
+static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX];
+static unsigned short i2c_inodes[SENSORS_ENTRY_MAX];
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
+static void i2c_fill_inode(struct inode *inode, int fill);
+static void i2c_dir_fill_inode(struct inode *inode, int fill);
+#endif                 /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) */
+
+static ctl_table sysctl_table[] = {
+       {CTL_DEV, "dev", NULL, 0, 0555},
+       {0},
+       {DEV_SENSORS, "sensors", NULL, 0, 0555},
+       {0},
+       {0, NULL, NULL, 0, 0555},
+       {0}
+};
+
+static ctl_table i2c_proc_dev_sensors[] = {
+       {SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips,
+        &i2c_sysctl_chips},
+       {0}
+};
+
+static ctl_table i2c_proc_dev[] = {
+       {DEV_SENSORS, "sensors", NULL, 0, 0555, i2c_proc_dev_sensors},
+       {0},
+};
+
+
+static ctl_table i2c_proc[] = {
+       {CTL_DEV, "dev", NULL, 0, 0555, i2c_proc_dev},
+       {0}
+};
+
+
+static struct ctl_table_header *i2c_proc_header;
+static int i2c_initialized;
+
+/* This returns a nice name for a new directory; for example lm78-isa-0310
+   (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
+   a LM75 chip on the third i2c bus at address 0x4e).  
+   name is allocated first. */
+int i2c_create_name(char **name, const char *prefix,
+                       struct i2c_adapter *adapter, int addr)
+{
+       char name_buffer[50];
+       int id;
+       if (i2c_is_isa_adapter(adapter))
+               sprintf(name_buffer, "%s-isa-%04x", prefix, addr);
+       else {
+               if ((id = i2c_adapter_id(adapter)) < 0)
+                       return -ENOENT;
+               sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr);
+       }
+       *name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
+       strcpy(*name, name_buffer);
+       return 0;
+}
+
+/* This rather complex function must be called when you want to add an entry
+   to /proc/sys/dev/sensors/chips. It also creates a new directory within 
+   /proc/sys/dev/sensors/.
+   ctl_template should be a template of the newly created directory. It is
+   copied in memory. The extra2 field of each file is set to point to client.
+   If any driver wants subdirectories within the newly created directory,
+   this function must be updated! 
+   controlling_mod is the controlling module. It should usually be
+   THIS_MODULE when calling. Note that this symbol is not defined in
+   kernels before 2.3.13; define it to NULL in that case. We will not use it
+   for anything older than 2.3.27 anyway. */
+int i2c_register_entry(struct i2c_client *client, const char *prefix,
+                          ctl_table * ctl_template,
+                          struct module *controlling_mod)
+{
+       int i, res, len, id;
+       ctl_table *new_table;
+       char *name;
+       struct ctl_table_header *new_header;
+
+       if ((res = i2c_create_name(&name, prefix, client->adapter,
+                                      client->addr))) return res;
+
+       for (id = 0; id < SENSORS_ENTRY_MAX; id++)
+               if (!i2c_entries[id]) {
+                       break;
+               }
+       if (id == SENSORS_ENTRY_MAX) {
+               kfree(name);
+               return -ENOMEM;
+       }
+       id += 256;
+
+       len = 0;
+       while (ctl_template[len].procname)
+               len++;
+       len += 7;
+       if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) {
+               kfree(name);
+               return -ENOMEM;
+       }
+
+       memcpy(new_table, sysctl_table, 6 * sizeof(ctl_table));
+       new_table[0].child = &new_table[2];
+       new_table[2].child = &new_table[4];
+       new_table[4].child = &new_table[6];
+       new_table[4].procname = name;
+       new_table[4].ctl_name = id;
+       memcpy(new_table + 6, ctl_template, (len - 6) * sizeof(ctl_table));
+       for (i = 6; i < len; i++)
+               new_table[i].extra2 = client;
+
+       if (!(new_header = register_sysctl_table(new_table, 0))) {
+               kfree(new_table);
+               kfree(name);
+               return -ENOMEM;
+       }
+
+       i2c_entries[id - 256] = new_header;
+
+       i2c_clients[id - 256] = client;
+#ifdef DEBUG
+       if (!new_header || !new_header->ctl_table ||
+           !new_header->ctl_table->child ||
+           !new_header->ctl_table->child->child ||
+           !new_header->ctl_table->child->child->de) {
+               printk
+                   ("i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n");
+               return id;
+       }
+#endif                         /* DEBUG */
+       i2c_inodes[id - 256] =
+           new_header->ctl_table->child->child->de->low_ino;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
+       new_header->ctl_table->child->child->de->owner = controlling_mod;
+#else
+       new_header->ctl_table->child->child->de->fill_inode =
+           &i2c_dir_fill_inode;
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */
+
+       return id;
+}
+
+void i2c_deregister_entry(int id)
+{
+       ctl_table *table;
+       char *temp;
+       id -= 256;
+       if (i2c_entries[id]) {
+               table = i2c_entries[id]->ctl_table;
+               unregister_sysctl_table(i2c_entries[id]);
+               /* 2-step kfree needed to keep gcc happy about const points */
+               (const char *) temp = table[4].procname;
+               kfree(temp);
+               kfree(table);
+               i2c_entries[id] = NULL;
+               i2c_clients[id] = NULL;
+       }
+}
+
+/* Monitor access for /proc/sys/dev/sensors; make unloading i2c-proc.o 
+   impossible if some process still uses it or some file in it */
+void i2c_fill_inode(struct inode *inode, int fill)
+{
+       if (fill)
+               MOD_INC_USE_COUNT;
+       else
+               MOD_DEC_USE_COUNT;
+}
+
+/* Monitor access for /proc/sys/dev/sensors/ directories; make unloading
+   the corresponding module impossible if some process still uses it or
+   some file in it */
+void i2c_dir_fill_inode(struct inode *inode, int fill)
+{
+       int i;
+       struct i2c_client *client;
+
+#ifdef DEBUG
+       if (!inode) {
+               printk("i2c-proc.o: Warning: inode NULL in fill_inode()\n");
+               return;
+       }
+#endif                         /* def DEBUG */
+
+       for (i = 0; i < SENSORS_ENTRY_MAX; i++)
+               if (i2c_clients[i]
+                   && (i2c_inodes[i] == inode->i_ino)) break;
+#ifdef DEBUG
+       if (i == SENSORS_ENTRY_MAX) {
+               printk
+                   ("i2c-proc.o: Warning: inode (%ld) not found in fill_inode()\n",
+                    inode->i_ino);
+               return;
+       }
+#endif                         /* def DEBUG */
+       client = i2c_clients[i];
+       if (fill)
+               client->driver->inc_use(client);
+       else
+               client->driver->dec_use(client);
+}
+
+int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp,
+                      void *buffer, size_t * lenp)
+{
+       char BUF[SENSORS_PREFIX_MAX + 30];
+       int buflen, curbufsize, i;
+       struct ctl_table *client_tbl;
+
+       if (write)
+               return 0;
+
+       /* If buffer is size 0, or we try to read when not at the start, we
+          return nothing. Note that I think writing when not at the start
+          does not work either, but anyway, this is straight from the kernel
+          sources. */
+       if (!*lenp || (filp->f_pos && !write)) {
+               *lenp = 0;
+               return 0;
+       }
+       curbufsize = 0;
+       for (i = 0; i < SENSORS_ENTRY_MAX; i++)
+               if (i2c_entries[i]) {
+                       client_tbl =
+                           i2c_entries[i]->ctl_table->child->child;
+                       buflen =
+                           sprintf(BUF, "%d\t%s\n", client_tbl->ctl_name,
+                                   client_tbl->procname);
+                       if (buflen + curbufsize > *lenp)
+                               buflen = *lenp - curbufsize;
+                       if(copy_to_user(buffer, BUF, buflen))
+                               return -EFAULT;
+                       curbufsize += buflen;
+                       (char *) buffer += buflen;
+               }
+       *lenp = curbufsize;
+       filp->f_pos += curbufsize;
+       return 0;
+}
+
+int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
+                        void *oldval, size_t * oldlenp, void *newval,
+                        size_t newlen, void **context)
+{
+       struct i2c_chips_data data;
+       int i, oldlen, nrels, maxels,ret=0;
+       struct ctl_table *client_tbl;
+
+       if (oldval && oldlenp && !((ret = get_user(oldlen, oldlenp))) && 
+           oldlen) {
+               maxels = oldlen / sizeof(struct i2c_chips_data);
+               nrels = 0;
+               for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels);
+                    i++)
+                       if (i2c_entries[i]) {
+                               client_tbl =
+                                   i2c_entries[i]->ctl_table->child->
+                                   child;
+                               data.sysctl_id = client_tbl->ctl_name;
+                               strcpy(data.name, client_tbl->procname);
+                               if(copy_to_user(oldval, &data,
+                                            sizeof(struct
+                                                   i2c_chips_data)))
+                                       return -EFAULT;
+                               (char *) oldval +=
+                                   sizeof(struct i2c_chips_data);
+                               nrels++;
+                       }
+               oldlen = nrels * sizeof(struct i2c_chips_data);
+               if(put_user(oldlen, oldlenp))
+                       return -EFAULT;
+       }
+       return ret;
+}
+
+
+/* This funcion reads or writes a 'real' value (encoded by the combination
+   of an integer and a magnitude, the last is the power of ten the value
+   should be divided with) to a /proc/sys directory. To use this function,
+   you must (before registering the ctl_table) set the extra2 field to the
+   client, and the extra1 field to a function of the form:
+      void func(struct i2c_client *client, int operation, int ctl_name,
+                int *nrels_mag, long *results)
+   This function can be called for three values of operation. If operation
+   equals SENSORS_PROC_REAL_INFO, the magnitude should be returned in 
+   nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
+   be read into results. nrels_mag should return the number of elements
+   read; the maximum number is put in it on entry. Finally, if operation
+   equals SENSORS_PROC_REAL_WRITE, the values in results should be
+   written to the chip. nrels_mag contains on entry the number of elements
+   found.
+   In all cases, client points to the client we wish to interact with,
+   and ctl_name is the SYSCTL id of the file we are accessing. */
+int i2c_proc_real(ctl_table * ctl, int write, struct file *filp,
+                     void *buffer, size_t * lenp)
+{
+#define MAX_RESULTS 32
+       int mag, nrels = MAX_RESULTS;
+       long results[MAX_RESULTS];
+       i2c_real_callback callback = ctl->extra1;
+       struct i2c_client *client = ctl->extra2;
+       int res;
+
+       /* If buffer is size 0, or we try to read when not at the start, we
+          return nothing. Note that I think writing when not at the start
+          does not work either, but anyway, this is straight from the kernel
+          sources. */
+       if (!*lenp || (filp->f_pos && !write)) {
+               *lenp = 0;
+               return 0;
+       }
+
+       /* Get the magnitude */
+       callback(client, SENSORS_PROC_REAL_INFO, ctl->ctl_name, &mag,
+                NULL);
+
+       if (write) {
+               /* Read the complete input into results, converting to longs */
+               res = i2c_parse_reals(&nrels, buffer, *lenp, results, mag);
+               if (res)
+                       return res;
+
+               if (!nrels)
+                       return 0;
+
+               /* Now feed this information back to the client */
+               callback(client, SENSORS_PROC_REAL_WRITE, ctl->ctl_name,
+                        &nrels, results);
+
+               filp->f_pos += *lenp;
+               return 0;
+       } else {                /* read */
+               /* Get the information from the client into results */
+               callback(client, SENSORS_PROC_REAL_READ, ctl->ctl_name,
+                        &nrels, results);
+
+               /* And write them to buffer, converting to reals */
+               res = i2c_write_reals(nrels, buffer, lenp, results, mag);
+               if (res)
+                       return res;
+               filp->f_pos += *lenp;
+               return 0;
+       }
+}
+
+/* This function is equivalent to i2c_proc_real, only it interacts with
+   the sysctl(2) syscall, and returns no reals, but integers */
+int i2c_sysctl_real(ctl_table * table, int *name, int nlen,
+                       void *oldval, size_t * oldlenp, void *newval,
+                       size_t newlen, void **context)
+{
+       long results[MAX_RESULTS];
+       int oldlen, nrels = MAX_RESULTS,ret=0;
+       i2c_real_callback callback = table->extra1;
+       struct i2c_client *client = table->extra2;
+
+       /* Check if we need to output the old values */
+       if (oldval && oldlenp && !((ret=get_user(oldlen, oldlenp))) && oldlen) {
+               callback(client, SENSORS_PROC_REAL_READ, table->ctl_name,
+                        &nrels, results);
+
+               /* Note the rounding factor! */
+               if (nrels * sizeof(long) < oldlen)
+                       oldlen = nrels * sizeof(long);
+               oldlen = (oldlen / sizeof(long)) * sizeof(long);
+               if(copy_to_user(oldval, results, oldlen))
+                       return -EFAULT;
+               if(put_user(oldlen, oldlenp))
+                       return -EFAULT;
+       }
+
+       if (newval && newlen) {
+               /* Note the rounding factor! */
+               newlen -= newlen % sizeof(long);
+               nrels = newlen / sizeof(long);
+               if(copy_from_user(results, newval, newlen))
+                       return -EFAULT;
+
+               /* Get the new values back to the client */
+               callback(client, SENSORS_PROC_REAL_WRITE, table->ctl_name,
+                        &nrels, results);
+       }
+       return ret;
+}
+
+
+/* nrels contains initially the maximum number of elements which can be
+   put in results, and finally the number of elements actually put there.
+   A magnitude of 1 will multiply everything with 10; etc.
+   buffer, bufsize is the character buffer we read from and its length.
+   results will finally contain the parsed integers. 
+
+   Buffer should contain several reals, separated by whitespace. A real
+   has the following syntax:
+     [ Minus ] Digit* [ Dot Digit* ] 
+   (everything between [] is optional; * means zero or more).
+   When the next character is unparsable, everything is skipped until the
+   next whitespace.
+
+   WARNING! This is tricky code. I have tested it, but there may still be
+            hidden bugs in it, even leading to crashes and things!
+*/
+int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
+                        long *results, int magnitude)
+{
+       int maxels, min, mag;
+       long res,ret=0;
+       char nextchar = 0;
+
+       maxels = *nrels;
+       *nrels = 0;
+
+       while (bufsize && (*nrels < maxels)) {
+
+               /* Skip spaces at the start */
+               while (bufsize && 
+                      !((ret=get_user(nextchar, (char *) buffer))) &&
+                      isspace((int) nextchar)) {
+                       bufsize--;
+                       ((char *) buffer)++;
+               }
+
+               if (ret)
+                       return -EFAULT; 
+               /* Well, we may be done now */
+               if (!bufsize)
+                       return 0;
+
+               /* New defaults for our result */
+               min = 0;
+               res = 0;
+               mag = magnitude;
+
+               /* Check for a minus */
+               if (!((ret=get_user(nextchar, (char *) buffer)))
+                   && (nextchar == '-')) {
+                       min = 1;
+                       bufsize--;
+                       ((char *) buffer)++;
+               }
+               if (ret)
+                       return -EFAULT;
+
+               /* Digits before a decimal dot */
+               while (bufsize && 
+                      !((ret=get_user(nextchar, (char *) buffer))) &&
+                      isdigit((int) nextchar)) {
+                       res = res * 10 + nextchar - '0';
+                       bufsize--;
+                       ((char *) buffer)++;
+               }
+               if (ret)
+                       return -EFAULT;
+
+               /* If mag < 0, we must actually divide here! */
+               while (mag < 0) {
+                       res = res / 10;
+                       mag++;
+               }
+
+               if (bufsize && (nextchar == '.')) {
+                       /* Skip the dot */
+                       bufsize--;
+                       ((char *) buffer)++;
+
+                       /* Read digits while they are significant */
+                       while (bufsize && (mag > 0) &&
+                              !((ret=get_user(nextchar, (char *) buffer))) &&
+                              isdigit((int) nextchar)) {
+                               res = res * 10 + nextchar - '0';
+                               mag--;
+                               bufsize--;
+                               ((char *) buffer)++;
+                       }
+                       if (ret)
+                               return -EFAULT;
+               }
+               /* If we are out of data, but mag > 0, we need to scale here */
+               while (mag > 0) {
+                       res = res * 10;
+                       mag--;
+               }
+
+               /* Skip everything until we hit whitespace */
+               while (bufsize && 
+                      !((ret=get_user(nextchar, (char *) buffer))) &&
+                      isspace((int) nextchar)) {
+                       bufsize--;
+                       ((char *) buffer)++;
+               }
+               if (ret)
+                       return -EFAULT;
+
+               /* Put res in results */
+               results[*nrels] = (min ? -1 : 1) * res;
+               (*nrels)++;
+       }
+
+       /* Well, there may be more in the buffer, but we need no more data. 
+          Ignore anything that is left. */
+       return 0;
+}
+
+int i2c_write_reals(int nrels, void *buffer, int *bufsize,
+                        long *results, int magnitude)
+{
+#define BUFLEN 20
+       char BUF[BUFLEN + 1];   /* An individual representation should fit! */
+       char printfstr[10];
+       int nr = 0;
+       int buflen, mag, times;
+       int curbufsize = 0;
+
+       while ((nr < nrels) && (curbufsize < *bufsize)) {
+               mag = magnitude;
+
+               if (nr != 0) {
+                       if(put_user(' ', (char *) buffer))
+                               return -EFAULT;
+                       curbufsize++;
+                       ((char *) buffer)++;
+               }
+
+               /* Fill BUF with the representation of the next string */
+               if (mag <= 0) {
+                       buflen = sprintf(BUF, "%ld", results[nr]);
+                       if (buflen < 0) {       /* Oops, a sprintf error! */
+                               *bufsize = 0;
+                               return -EINVAL;
+                       }
+                       while ((mag < 0) && (buflen < BUFLEN)) {
+                               BUF[buflen++] = '0';
+                               mag++;
+                       }
+                       BUF[buflen] = 0;
+               } else {
+                       times = 1;
+                       for (times = 1; mag-- > 0; times *= 10);
+                       if (results[nr] < 0) {
+                               BUF[0] = '-';
+                               buflen = 1;
+                       } else
+                               buflen = 0;
+                       strcpy(printfstr, "%ld.%0Xld");
+                       printfstr[6] = magnitude + '0';
+                       buflen +=
+                           sprintf(BUF + buflen, printfstr,
+                                   abs(results[nr]) / times,
+                                   abs(results[nr]) % times);
+                       if (buflen < 0) {       /* Oops, a sprintf error! */
+                               *bufsize = 0;
+                               return -EINVAL;
+                       }
+               }
+
+               /* Now copy it to the user-space buffer */
+               if (buflen + curbufsize > *bufsize)
+                       buflen = *bufsize - curbufsize;
+               if(copy_to_user(buffer, BUF, buflen))
+                       return -EFAULT;
+               curbufsize += buflen;
+               (char *) buffer += buflen;
+
+               nr++;
+       }
+       if (curbufsize < *bufsize) {
+               if(put_user('\n', (char *) buffer))
+                       return -EFAULT;
+               curbufsize++;
+       }
+       *bufsize = curbufsize;
+       return 0;
+}
+
+
+/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */
+int i2c_detect(struct i2c_adapter *adapter,
+                  struct i2c_address_data *address_data,
+                  i2c_found_addr_proc * found_proc)
+{
+       int addr, i, found, j, err;
+       struct i2c_force_data *this_force;
+       int is_isa = i2c_is_isa_adapter(adapter);
+       int adapter_id =
+           is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter);
+
+       /* Forget it if we can't probe using SMBUS_QUICK */
+       if ((!is_isa)
+           && !i2c_check_functionality(adapter,
+                                       I2C_FUNC_SMBUS_QUICK)) return -1;
+
+       for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
+               if ((is_isa && check_region(addr, 1)) ||
+                   (!is_isa && i2c_check_addr(adapter, addr)))
+                       continue;
+
+               /* If it is in one of the force entries, we don't do any
+                  detection at all */
+               found = 0;
+               for (i = 0;
+                    !found
+                    && (this_force =
+                        address_data->forces + i, this_force->force); i++) {
+                       for (j = 0;
+                            !found
+                            && (this_force->force[j] != SENSORS_I2C_END);
+                            j += 2) {
+                               if (
+                                   ((adapter_id == this_force->force[j])
+                                    ||
+                                    ((this_force->
+                                      force[j] == SENSORS_ANY_I2C_BUS)
+                                     && !is_isa))
+                                   && (addr == this_force->force[j + 1])) {
+#ifdef DEBUG
+                                       printk
+                                           ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n",
+                                            adapter_id, addr);
+#endif
+                                       if (
+                                           (err =
+                                            found_proc(adapter, addr, 0,
+                                                       this_force->
+                                                       kind))) return err;
+                                       found = 1;
+                               }
+                       }
+               }
+               if (found)
+                       continue;
+
+               /* If this address is in one of the ignores, we can forget about it
+                  right now */
+               for (i = 0;
+                    !found
+                    && (address_data->ignore[i] != SENSORS_I2C_END);
+                    i += 2) {
+                       if (
+                           ((adapter_id == address_data->ignore[i])
+                            ||
+                            ((address_data->
+                              ignore[i] == SENSORS_ANY_I2C_BUS)
+                             && !is_isa))
+                           && (addr == address_data->ignore[i + 1])) {
+#ifdef DEBUG
+                               printk
+                                   ("i2c-proc.o: found ignore parameter for adapter %d, "
+                                    "addr %04x\n", adapter_id, addr);
+#endif
+                               found = 1;
+                       }
+               }
+               for (i = 0;
+                    !found
+                    && (address_data->ignore_range[i] != SENSORS_I2C_END);
+                    i += 3) {
+                       if (
+                           ((adapter_id == address_data->ignore_range[i])
+                            ||
+                            ((address_data->
+                              ignore_range[i] ==
+                              SENSORS_ANY_I2C_BUS) & !is_isa))
+                           && (addr >= address_data->ignore_range[i + 1])
+                           && (addr <= address_data->ignore_range[i + 2])) {
+#ifdef DEBUG
+                               printk
+                                   ("i2c-proc.o: found ignore_range parameter for adapter %d, "
+                                    "addr %04x\n", adapter_id, addr);
+#endif
+                               found = 1;
+                       }
+               }
+               if (found)
+                       continue;
+
+               /* Now, we will do a detection, but only if it is in the normal or 
+                  probe entries */
+               if (is_isa) {
+                       for (i = 0;
+                            !found
+                            && (address_data->normal_isa[i] !=
+                                SENSORS_ISA_END); i += 1) {
+                               if (addr == address_data->normal_isa[i]) {
+#ifdef DEBUG
+                                       printk
+                                           ("i2c-proc.o: found normal isa entry for adapter %d, "
+                                            "addr %04x\n", adapter_id,
+                                            addr);
+#endif
+                                       found = 1;
+                               }
+                       }
+                       for (i = 0;
+                            !found
+                            && (address_data->normal_isa_range[i] !=
+                                SENSORS_ISA_END); i += 3) {
+                               if ((addr >=
+                                    address_data->normal_isa_range[i])
+                                   && (addr <=
+                                       address_data->normal_isa_range[i + 1])
+                                   &&
+                                   ((addr -
+                                     address_data->normal_isa_range[i]) %
+                                    address_data->normal_isa_range[i + 2] ==
+                                    0)) {
+#ifdef DEBUG
+                                       printk
+                                           ("i2c-proc.o: found normal isa_range entry for adapter %d, "
+                                            "addr %04x", adapter_id, addr);
+#endif
+                                       found = 1;
+                               }
+                       }
+               } else {
+                       for (i = 0;
+                            !found && (address_data->normal_i2c[i] !=
+                                SENSORS_I2C_END); i += 1) {
+                               if (addr == address_data->normal_i2c[i]) {
+                                       found = 1;
+#ifdef DEBUG
+                                       printk
+                                           ("i2c-proc.o: found normal i2c entry for adapter %d, "
+                                            "addr %02x", adapter_id, addr);
+#endif
+                               }
+                       }
+                       for (i = 0;
+                            !found
+                            && (address_data->normal_i2c_range[i] !=
+                                SENSORS_I2C_END); i += 2) {
+                               if ((addr >=
+                                    address_data->normal_i2c_range[i])
+                                   && (addr <=
+                                       address_data->normal_i2c_range[i + 1]))
+                               {
+#ifdef DEBUG
+                                       printk
+                                           ("i2c-proc.o: found normal i2c_range entry for adapter %d, "
+                                            "addr %04x\n", adapter_id, addr);
+#endif
+                                       found = 1;
+                               }
+                       }
+               }
+
+               for (i = 0;
+                    !found && (address_data->probe[i] != SENSORS_I2C_END);
+                    i += 2) {
+                       if (((adapter_id == address_data->probe[i]) ||
+                            ((address_data->
+                              probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa))
+                           && (addr == address_data->probe[i + 1])) {
+#ifdef DEBUG
+                               printk
+                                   ("i2c-proc.o: found probe parameter for adapter %d, "
+                                    "addr %04x\n", adapter_id, addr);
+#endif
+                               found = 1;
+                       }
+               }
+               for (i = 0; !found &&
+                          (address_data->probe_range[i] != SENSORS_I2C_END);
+                    i += 3) {
+                       if (
+                           ((adapter_id == address_data->probe_range[i])
+                            ||
+                            ((address_data->probe_range[i] ==
+                              SENSORS_ANY_I2C_BUS) & !is_isa))
+                           && (addr >= address_data->probe_range[i + 1])
+                           && (addr <= address_data->probe_range[i + 2])) {
+                               found = 1;
+#ifdef DEBUG
+                               printk
+                                   ("i2c-proc.o: found probe_range parameter for adapter %d, "
+                                    "addr %04x\n", adapter_id, addr);
+#endif
+                       }
+               }
+               if (!found)
+                       continue;
+
+               /* OK, so we really should examine this address. First check
+                  whether there is some client here at all! */
+               if (is_isa ||
+                   (i2c_smbus_xfer
+                    (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0))
+                       if ((err = found_proc(adapter, addr, 0, -1)))
+                               return err;
+       }
+       return 0;
+}
+
+int __init sensors_init(void)
+{
+       printk("i2c-proc.o version %s (%s)\n", LM_VERSION, LM_DATE);
+       i2c_initialized = 0;
+       if (!
+           (i2c_proc_header =
+            register_sysctl_table(i2c_proc, 0))) return -ENOMEM;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1))
+       i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE;
+#else
+       i2c_proc_header->ctl_table->child->de->fill_inode =
+           &i2c_fill_inode;
+#endif                 /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) */
+       i2c_initialized++;
+       return 0;
+}
+
+EXPORT_SYMBOL(i2c_deregister_entry);
+EXPORT_SYMBOL(i2c_detect);
+EXPORT_SYMBOL(i2c_proc_real);
+EXPORT_SYMBOL(i2c_register_entry);
+EXPORT_SYMBOL(i2c_sysctl_real);
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("i2c-proc driver");
+MODULE_LICENSE("GPL");
+
+int i2c_cleanup(void)
+{
+       if (i2c_initialized >= 1) {
+               unregister_sysctl_table(i2c_proc_header);
+               i2c_initialized--;
+       }
+       return 0;
+}
+
+int init_module(void)
+{
+       return sensors_init();
+}
+
+int cleanup_module(void)
+{
+       return i2c_cleanup();
+}
+#endif                         /* MODULE */
index 3f553591d9007bc29aa7bdb25aa2b501b6c7daf8..0c16c470485084f2b7ad9545ab6be6cf6dcc4520 100644 (file)
@@ -103,7 +103,7 @@ static int bit_velle_init(void)
        return 0;
 }
 
-static void bit_velle_exit(void)
+static void __exit bit_velle_exit(void)
 {      
        release_region( base , (base == 0x3bc)? 3 : 8 );
 }
index 5738ff1cbf9b266a85bcd79cb61ae3353f8a6201..bab0f67bf4b9a6c0d93ffabc50e2937c1a93e5b0 100644 (file)
@@ -15,6 +15,8 @@
    Based on work
        Copyleft  (C) 2001 by Wilfried Weissmann <wweissmann@gmx.at>
        Copyright (C) 1994-96 Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
+   Based on work done by Søren Schmidt for FreeBSD
+
    
 */
 
index 757e7b88686089211a722451ec904ea3d6cd8662..59f71b84a2c70d7b166a631c0a3f1db1ec5837b0 100644 (file)
@@ -1,4 +1,32 @@
-
+/*-
+ * Copyright (c) 2000,2001 Søren Schmidt <sos@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+                            
 struct highpoint_raid_conf
 {
        int8_t  filler1[32];
index b6863cfa38d3ca3730cb261752c96a651b49e509..4c1214eb5ec91e4b952350e72c27ab5dde7c2c2a 100644 (file)
@@ -890,3 +890,4 @@ int idedisk_init (void)
 
 module_init(idedisk_init);
 module_exit(idedisk_exit);
+MODULE_LICENSE("GPL");
index cddd0bbd2d4772834dce8f8a734ccf472f423798..15bac64f982c016037463b8698b49a5a4decdbc5 100644 (file)
@@ -2116,3 +2116,4 @@ int idefloppy_init (void)
 
 module_init(idefloppy_init);
 module_exit(idefloppy_exit);
+MODULE_LICENSE("GPL");
index ce9489746d225b29d05f9f84614a52f37d6efa57..0dbd052c088fe2f15b8afb7d3ff1f2c9029480a7 100644 (file)
@@ -928,4 +928,5 @@ void cleanup_module (void)
 {
        ide_probe = NULL;
 }
+MODULE_LICENSE("GPL");
 #endif /* MODULE */
index 0a0ddd09a2fca160f2975275fe83f3902f3f7285..ff5fcc019b3be0c0511ea98fe7aeeea5bf4b078a 100644 (file)
@@ -3749,6 +3749,7 @@ int __init ide_init (void)
 #ifdef MODULE
 char *options = NULL;
 MODULE_PARM(options,"s");
+MODULE_LICENSE("GPL");
 
 static void __init parse_options (char *line)
 {
index bb6d84dcebf5e4b6fc674fbcff67236e890682f6..b11c0d346c70d569dab25942cdb3a979f4a3781e 100644 (file)
@@ -69,6 +69,7 @@ int __init rapide_init(void)
 }
 
 #ifdef MODULE
+MODULE_LICENSE("GPL");
 
 int init_module (void)
 {
index e8f31fab6da6ddc5ac2a971b6e7e80689aa59497..a437ac103e704dbbdaa87ebe66ca351e7e292fc3 100644 (file)
@@ -246,3 +246,4 @@ module_exit(keybdev_exit);
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Input driver to keyboard driver binding");
 MODULE_PARM(jp_kbd_109, "i");
+MODULE_LICENSE("GPL");
index 56f1ceafcebeb12c2cd30c2816824208a667386f..0e0f26f169e1b7588562a1bebff7a6e3ff136e9c 100644 (file)
@@ -1,8 +1,6 @@
 /*
  *    QuickCam Driver For Video4Linux.
  *
- *     This version only works as a module.
- *
  *     Video4Linux conversion work by Alan Cox.
  *     Parport compatibility by Phil Blundell.
  *     Busy loop avoidance by Mark Cooke.
@@ -991,11 +989,20 @@ static char *parport[MAX_CAMS] = { NULL, };
 MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
 #endif
 
-#ifdef MODULE
-int init_module(void)
+static void __exit exit_bw_qcams(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_cams; i++)
+               close_bwqcam(qcams[i]);
+}
+
+static int __init init_bw_qcams(void)
 {
        struct parport *port;
+#ifdef MODULE
        int n;
+       
        if(parport[0] && strncmp(parport[0], "auto", 4)){
                /* user gave parport parameters */
                for(n=0; parport[n] && n<MAX_CAMS; n++){
@@ -1033,22 +1040,14 @@ int init_module(void)
        }
 
        return (num_cams)?0:-ENODEV;
-}
-
-void cleanup_module(void)
-{
-       unsigned int i;
-       for (i = 0; i < num_cams; i++)
-               close_bwqcam(qcams[i]);
-}
 #else
-int __init init_bw_qcams(struct video_init *unused)
-{
-       struct parport *port;
-
        for (port = parport_enumerate(); port; port=port->next)
                init_bwqcam(port);
        return 0;
-}
 #endif
+}
+
+module_init(init_bw_qcams);
+module_exit(exit_bw_qcams);
+
 MODULE_LICENSE("GPL");
index c148ba78522121d7ff2cb9f05fce9c5ebfa16d11..ea764f9f0522b5b6fc0c0ad8eeaac5d88625229d 100644 (file)
 #include "planb.h"
 #include "saa7196.h"
 
-
 /* Would you mind for some ugly debugging? */
-//#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
-#define DEBUG(x...)            /* Don't debug driver */        
-//#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
+#if 0
+#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
+#else
+#define DEBUG(x...)            /* Don't debug driver */
+#endif
+
+#if 0
+#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
+#endif
 #define IDEBUG(x...)           /* Don't debug interrupt part */
+#endif
 
 /* Ever seen a Mac with more than 1 of these? */
 #define PLANB_MAX 1
@@ -2271,14 +2277,8 @@ static void release_planb(void)
        }
 }
 
-#ifdef MODULE
-
-int init_module(void)
-{
-#else
-int __init init_planbs(struct video_init *unused)
+static int __init init_planbs(void)
 {
-#endif
        int i;
   
        if (find_planb()<=0)
@@ -2296,11 +2296,10 @@ int __init init_planbs(struct video_init *unused)
        return 0;
 }
 
-#ifdef MODULE
-
-void cleanup_module(void)
+static void __exit exit_planbs(void)
 {
        release_planb();
 }
 
-#endif
+module_init(init_planbs);
+module_exit(exit_planbs);
index 5e0a680ebaff3540d130740d51ba7d1d44118711..390937636bf362655e4bc589e55b22cfa1d98e65 100644 (file)
@@ -306,7 +306,7 @@ int saa7110_command(struct i2c_device *device, unsigned int cmd, void *arg)
                                saa7110_write(decoder, 0x0D, 0x06);
                                saa7110_write(decoder, 0x11, 0x2C);
                                saa7110_write(decoder, 0x30, 0x81);
-saa7110_write(decoder, 0x2A, 0xDF);
+                               saa7110_write(decoder, 0x2A, 0xDF);
                                break;
                         case VIDEO_MODE_PAL:
                                saa7110_write(decoder, 0x0D, 0x06);
index c556d031f26de63950475f65c0e86d524b2073ca..c6b0e1868d45bbe9c3f242dc8de766236c9438e2 100644 (file)
@@ -63,29 +63,6 @@ LIST_HEAD(videodev_proc_list);
 #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
 
 
-#ifdef CONFIG_VIDEO_BWQCAM
-extern int init_bw_qcams(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_CPIA
-extern int cpia_init(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_PLANB
-extern int init_planbs(struct video_init *);
-#endif
-
-static struct video_init video_init_list[]={
-#ifdef CONFIG_VIDEO_BWQCAM
-       {"bw-qcam", init_bw_qcams},
-#endif 
-#ifdef CONFIG_VIDEO_CPIA
-       {"cpia", cpia_init},
-#endif 
-#ifdef CONFIG_VIDEO_PLANB
-       {"planb", init_planbs},
-#endif
-       {"end", NULL}
-};
-
 /*
  *     Read will do some smarts later on. Buffer pin etc.
  */
@@ -118,7 +95,7 @@ static ssize_t video_write(struct file *file, const char *buf,
 
 /*
  *     Poll to see if we're readable, can probably be used for timing on incoming
- *  frames, etc..
+ *     frames, etc..
  */
 
 static unsigned int video_poll(struct file *file, poll_table * wait)
@@ -222,8 +199,7 @@ static int video_ioctl(struct inode *inode, struct file *file,
 /*
  *     We need to do MMAP support
  */
+  
 int video_mmap(struct file *file, struct vm_area_struct *vma)
 {
        int ret = -EINVAL;
@@ -548,8 +524,6 @@ static struct file_operations video_fops=
  
 static int __init videodev_init(void)
 {
-       struct video_init *vfli = video_init_list;
-       
        printk(KERN_INFO "Linux video capture interface: v1.00\n");
        if(devfs_register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops))
        {
@@ -557,19 +531,10 @@ static int __init videodev_init(void)
                return -EIO;
        }
 
-       /*
-        *      Init kernel installed video drivers
-        */
-               
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
        videodev_proc_create ();
 #endif
        
-       while(vfli->init!=NULL)
-       {
-               vfli->init(vfli);
-               vfli++;
-       }
        return 0;
 }
 
index 457c3e819a77f9cb8f6b9b66fb1331f2262dbfee..f6b931bd94459073449202d5034f9d77915b6e80 100644 (file)
@@ -87,6 +87,7 @@
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 int __init isense_init(void)
index b1c771762f8b1576c1c2711d4ef053b81eb10ff9..797f796678442079b063dee62479a737e3aaa6a7 100644 (file)
@@ -13,10 +13,10 @@ if [ "$CONFIG_MTD" = "y" -o "$CONFIG_MTD" = "m" ]; then
    fi
    dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
    dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
-if [ "$CONFIG_ARM" = "y" ]; then
-   dep_tristate '  Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
-   dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
-fi
+   if [ "$CONFIG_ARM" = "y" ]; then
+      dep_tristate '  Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
+      dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
+   fi
 
 comment 'User Modules And Translation Layers'
    dep_tristate '  Direct char device access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
index d4ae78eeb714cd64c44211246c7ebaa844dc3d21..d13174813b4a12b78d6a1a6b355c15516300de13 100644 (file)
@@ -191,7 +191,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
       if [ "$CONFIG_OBSOLETE" = "y" ]; then
         dep_bool '    Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET $CONFIG_ISA
       fi
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_MIPS" = "y" ]; then
         bool '    Philips SAA9730 Ethernet support (EXPERIMENTAL)' CONFIG_LAN_SAA9730
       fi
    fi
index c74dac6ca6b9f46a1b81dea9b87d02aeb56e917a..c1bbdd30b1308d726e614c81c83429945ce47f44 100644 (file)
@@ -2481,3 +2481,4 @@ EXPORT_SYMBOL(ppp_register_compressor);
 EXPORT_SYMBOL(ppp_unregister_compressor);
 EXPORT_SYMBOL(all_ppp_units); /* for debugging */
 EXPORT_SYMBOL(all_channels); /* for debugging */
+MODULE_LICENSE("GPL");
index f941f4f50e7198e556a617a8549e3ab7a9437dce..20c566425dd872be5be577d3fb0658f1bd5abb5e 100644 (file)
 #include <linux/init.h>
 #include <asm/uaccess.h>
 
-#ifndef spin_trylock_bh
-#define spin_trylock_bh(lock)  ({ int __r; local_bh_disable(); \
-                                  __r = spin_trylock(lock);    \
-                                  if (!__r) local_bh_enable(); \
-                                  __r; })
-#endif
-
 #define PPP_VERSION    "2.4.1"
 
 /* Structure for storing local state. */
@@ -708,3 +701,4 @@ ppp_sync_cleanup(void)
 
 module_init(ppp_sync_init);
 module_exit(ppp_sync_cleanup);
+MODULE_LICENSE("GPL");
index cd9de65f03952a6334ee2f51a2527539b330dafa..22c1dc9f87b3362892fe899b398ad759d0caf1e8 100644 (file)
@@ -12,6 +12,8 @@ EXPORT_SYMBOL(nubus_proc_attach_device);
 EXPORT_SYMBOL(nubus_proc_detach_device);
 #endif
 
+MODULE_LICENSE("GPL");
+
 EXPORT_SYMBOL(nubus_find_device);
 EXPORT_SYMBOL(nubus_find_type);
 EXPORT_SYMBOL(nubus_find_slot);
index b5c802c889a7c887652784d28269e8991fbccfbd..5b89a707502adc4fdac8dc1e4450a00678fac798 100644 (file)
@@ -362,7 +362,7 @@ int ecp_forward_to_reverse (struct parport *port)
        } else {
                DPRINTK (KERN_DEBUG "%s: ECP direction: failed to reverse\n",
                         port->name);
-               port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
+               port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
        }
 
        return retval;
@@ -394,7 +394,7 @@ int ecp_reverse_to_forward (struct parport *port)
                DPRINTK (KERN_DEBUG
                         "%s: ECP direction: failed to switch forward\n",
                         port->name);
-               port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
+               port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
        }
 
 
index ea26b4797f175136987d25a75cec8fb4221ff415..b09e1f2d5441e323924643812797f7cd7a61aec2 100644 (file)
@@ -298,6 +298,7 @@ void __exit parport_amiga_exit(void)
 MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
 MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
 MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
+MODULE_LICENSE("GPL");
 
 module_init(parport_amiga_init)
 module_exit(parport_amiga_exit)
index c6ee0ac4ba1fd3e2b1e32d6671c22b326b15e742..ae831176b7b185607074aebc6342b12d8eea1bf8 100644 (file)
@@ -249,6 +249,7 @@ parport_atari_init(void)
 MODULE_AUTHOR("Andreas Schwab");
 MODULE_DESCRIPTION("Parport Driver for Atari builtin Port");
 MODULE_SUPPORTED_DEVICE("Atari builtin Parallel Port");
+MODULE_LICENSE("GPL");
 
 int
 init_module(void)
index 349d1bc6454bc8736a6d372fde92027281388bc2..85ea27eb1f2910c129ff2f7ebd8f29f5fe6aad75 100644 (file)
@@ -2884,6 +2884,8 @@ static const char *dma[PARPORT_PC_MAX_PORTS] = { NULL, };
 
 MODULE_AUTHOR("Phil Blundell, Tim Waugh, others");
 MODULE_DESCRIPTION("PC-style parallel port driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
 MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i");
 MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)");
index 586ef3d2d9df39339746b2546465a49aca402340..4481a14d5a1869b73ded3ca377c015f8d7fd4bfb 100644 (file)
@@ -68,6 +68,7 @@ main(void)
                                                        bra[-1] = 0;
                                                if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
                                                        fprintf(stderr, "Line %d: Device name too long\n", lino);
+                                                       fprintf(stderr, "%s\n", c);
                                                        return 1;
                                                }
                                        }
index 45966f06cb69c56c434b0211eea04f03fcf08698..b566eb0e03a16f52ddd25eba352d7134b7079079 100644 (file)
        0396  SDRAM controller
        0397  BIOS scratchpad
 127a  Rockwell International
-       1002  HCF 56k V90 FaxModem
-               127a 1002  HCF 56k V90 Modem
-       1003  HCF 56k V90 FaxModem
-               127a 1003  PCI56RX Modem
-               13df 1003  PCI56RX Modem
-       1004  HCF 56k V90 FaxModem
-       1005  HCF 56k V90 FaxModem
-               122d 4008  MDP3858SP-A SVD Modem
-               127a 1005  PCI56RVP Modem 
-               13df 1005  PCI56RVP Modem 
-               1436 1005  WS-5614PS3G
-       1025  HCF 56k PCI Modem
-               127a 1025  HCF 56k PCI Modem
+       1002  HCF 56k Data/Fax Modem
+               122d 4002  HPG / MDP3858-U # Aztech
+               122d 4005  MDP3858-E # Aztech
+               122d 4007  MDP3858-A/-NZ # Aztech
+               122d 4012  MDP3858-SA # Aztech
+               122d 4017  MDP3858-W # Aztech
+               122d 4018  MDP3858-W # Aztech
+       1003  HCF 56k Data/Fax Modem
+               0e11 b0bc  229-DF Zephyr # Compaq
+               0e11 b114  229-DF Cheetah # Compaq
+               1033 802b  229-DF # NEC
+               13df 1003  PCI56RX Modem # E-Tech Inc
+               13e0 0117  IBM # GVC
+               13e0 0147  IBM # GVC
+               13e0 0197  IBM # GVC
+               13e0 01c7  IBM # GVC
+               13e0 01f7  IBM # GVC
+               1436 1003  IBM # CIS
+               1436 1103  IBM # CIS
+               1436 1602  Compaq 229-DF Ducati
+       1004  HCF 56k Data/Fax/Voice Modem
+               10cf 1059  Fujitsu 229-DFRT
+       1005  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+               1033 8029  229-DFSV # NEC
+               1033 8054  Modem # NEC
+               10cf 103c  Fujitsu
+               10cf 1055  Fujitsu 229-DFSV
+               10cf 1056  Fujitsu 229-DFSV
+               122d 4003  MDP3858SP-U # Aztech
+               122d 4006  Packard Bell MDP3858V-E # Aztech
+               122d 4008  MDP3858SP-A/SP-NZ # Aztech
+               122d 4009  MDP3858SP-E # Aztech
+               122d 4010  MDP3858V-U # Aztech
+               122d 4011  MDP3858SP-SA # Aztech
+               122d 4013  MDP3858V-A/V-NZ # Aztech
+               122d 4015  MDP3858SP-W # Aztech
+               122d 4016  MDP3858V-W # Aztech
+               122d 4019  MDP3858V-SA # Aztech
+               13df 1005  PCI56RVP Modem  # E-Tech Inc
+               13e0 0187  IBM # GVC
+               13e0 01a7  IBM # GVC
+               13e0 01b7  IBM # GVC
+               13e0 01d7  IBM # GVC
+               1436 1005  IBM # CIS
+               1436 1105  IBM # CIS
+       1023  HCF 56k Data/Fax Modem
+               122d 4020  Packard Bell MDP3858-WE # Aztech
+               122d 4023  MDP3858-UE # Aztech
+               13e0 0247  IBM # GVC
+               13e0 0297  IBM # GVC
+               13e0 02c7  IBM # GVC
+               1436 1203  IBM # CIS
+               1436 1303  IBM # CIS
+       1024  HCF 56k Data/Fax/Voice Modem
+       1025  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+               10cf 106a  Fujitsu 235-DFSV
+               122d 4021  Packard Bell MDP3858V-WE # Aztech
+               122d 4022  MDP3858SP-WE # Aztech
+               122d 4024  MDP3858V-UE # Aztech
+               122d 4025  MDP3858SP-UE # Aztech
        1026  HCF 56k PCI Speakerphone Modem
-               127a 1026  HCF 56k PCI Speakerphone Modem
        1035  HCF 56k PCI Speakerphone Modem
-               127a 1035  HCF 56k PCI Speakerphone Modem
-       1085  Volcano HCF 56k PCI Modem
-               127a 1085  Volcano HCF 56k PCI Modem
-       2005  HCF 56k V90 FaxModem
-               127a 2005  Conexant SoftK56 Speakerphone Modem
-       2015  Conexant SoftK56 Speakerphone Modem
-               127a 2015  Conexant SoftK56 Speakerphone Modem
-               14c8 2115  Conexant SoftK56 Speakerphone Modem
+       1085  HCF 56k Volcano PCI Modem
+       2005  HCF 56k Data/Fax Modem
+               104d 8044  229-DFSV # Sony
+               104d 8045  229-DFSV # Sony
+               104d 8055  PBE/Aztech 235W-DFSV # Sony
+               104d 8056  235-DFSV # Sony
+               104d 805a  Modem # Sony
+               104d 805f  Modem # Sony
+               104d 8074  Modem # Sony
+       2013  HSF 56k Data/Fax Modem
+               1179 0001  Modem # Toshiba
+               1179 ff00  Modem # Toshiba
+       2014  HSF 56k Data/Fax/Voice Modem
+               10cf 1057  Fujitsu Citicorp III
+               122d 4050  MSP3880-U # Aztech
+               122d 4055  MSP3880-W # Aztech
+       2015  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+               10cf 1063  Fujitsu
+               10cf 1064  Fujitsu
+               1468 2015  Fujitsu
+       2016  HSF 56k Data/Fax/Voice/Spkp Modem
+               122d 4051  MSP3880V-W # Aztech
+               122d 4052  MSP3880SP-W # Aztech
+               122d 4054  MSP3880V-U # Aztech
+               122d 4056  MSP3880SP-U # Aztech
+               122d 4057  MSP3880SP-A # Aztech
+       4311  Riptide HSF 56k PCI Modem
+               127a 4311  Ring Modular? Riptide HSF RT HP Dom
+               13e0 0210  HP-GVC
        4320  Riptide PCI Audio Controller
                1235 4320  Riptide PCI Audio Controller
        4321  Riptide HCF 56k PCI Modem
-               1235 4321  Riptide HCF 56k PCI Modem
+               1235 4321  Hewlett Packard DF
+               1235 4324  Hewlett Packard DF
+               13e0 0210  Hewlett Packard DF
+               144d 2321  Riptide # Samsung
        4322  Riptide PCI Game Controller
                1235 4322  Riptide PCI Game Controller
        8234  RapidFire 616X ATM155 Adapter
 148b  INNOMEDIALOGIC Inc.
 148c  C.P. Technology Co. Ltd
 148d  DIGICOM Systems, Inc.
+       1003  HCF 56k Data/Fax Modem
 148e  OSI Plus Corporation
 148f  Plant Equipment, Inc.
 1490  Stone Microsystems PTY Ltd.
 14ee  MASPRO KENKOH Corp
 14ef  CARRY Computer ENG. CO Ltd
 14f0  CANON RESEACH CENTRE FRANCE
-14f1  CONEXANT
-       1033  56K Winmodem
-               13e0 02b0  56K Winmodem
-       1035  PCI Modem Enumerator
-       2003  SoftK56 Winmodem
-               14f1 2003  SoftK56 Winmodem
-       2004  SoftK56 RemoteTAM Winmodem
-               14f1 2004  SoftK56 RemoteTAM Winmodem
-       2005  SoftK56 Speakerphone Winmodem
-               14f1 2005  SoftK56 Speakerphone Winmodem
-       2006  SoftK56 Speakerphone Winmodem
-               14f1 2006  SoftK56 Speakerphone Winmodem
-       2013  HSP MicroModem 56K
-               14f1 2013  SoftK56 Winmodem
-       2014  SoftK56 RemoteTAM Winmodem
-               144f 101c  SoftK56 RemoteTAM Winmodem
-               144f 2014  SoftK56 RemoteTAM Winmodem
-       2015  SoftK56 Speakerphone Winmodem
-               14c8 2115  SoftK56 Speakerphone Winmodem
-               14f1 2015  SoftK56 Speakerphone Winmodem
-       2016  SoftK56 Speakerphone Winmodem
-               14f1 2016  SoftK56 Speakerphone Winmodem
-       2443  SoftK56 Speakerphone Winmodem
-               14f1 2443  SoftK56 Speakerphone Winmodem
+14f1  Conexant
+       1033  HCF 56k Data/Fax Modem
+               1033 8077  NEC
+               122d 4027  Dell Zeus - MDP3880-W(B) Data Fax Modem # Aztech
+               122d 4030  Dell Mercury - MDP3880-U(B) Data Fax Modem # Aztech
+               122d 4034  Dell Thor - MDP3880-W(U) Data Fax Modem # Aztech
+               13e0 020d  Dell Copper
+               13e0 020e  Dell Silver
+               13e0 0261  IBM # GVC
+               13e0 0290  Compaq Goldwing
+               13e0 02a0  IBM # GVC
+               13e0 02b0  IBM # GVC
+               13e0 02c0  Compaq Scooter
+               13e0 02d0  IBM # GVC
+               144f 1500  IBM P85-DF # Askey
+               144f 1501  IBM P85-DF # Askey
+               144f 150a  IBM P85-DF # Askey
+               144f 150b  IBM P85-DF Low Profile # Askey
+               144f 1510  IBM P85-DF Low Profile # Askey
+       1034  HCF 56k Data/Fax/Voice Modem
+       1035  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+               10cf 1098  Fujitsu P85-DFSV
+       1036  HCF 56k Data/Fax/Voice/Spkp Modem
+               122d 4029  MDP3880SP-W # Aztech
+               122d 4031  MDP3880SP-U # Aztech
+               13e0 0209  Dell Titanium
+               13e0 020a  Dell Graphite
+               13e0 0260  Gateway Red Owl
+               13e0 0270  Gateway White Horse
+       1052  HCF 56k Data/Fax Modem (Worldwide)
+       1053  HCF 56k Data/Fax Modem (Worldwide)
+       1054  HCF 56k Data/Fax/Voice Modem (Worldwide)
+       1055  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
+       1056  HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+       1057  HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+       1059  HCF 56k Data/Fax/Voice Modem (Worldwide)
+       1063  HCF 56k Data/Fax Modem
+       1064  HCF 56k Data/Fax/Voice Modem
+       1065  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+       1066  HCF 56k Data/Fax/Voice/Spkp Modem
+               122d 4033  Dell Athena - MDP3900V-U # Aztech
+       1433  HCF 56k Data/Fax Modem
+       1434  HCF 56k Data/Fax/Voice Modem
+       1435  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+       1436  HCF 56k Data/Fax Modem
+       1453  HCF 56k Data/Fax Modem
+               13e0 0240  IBM # GVC
+               13e0 0250  IBM # GVC
+               144f 1502  IBM P95-DF # Askey
+               144f 1503  IBM P95-DF # Askey
+       1454  HCF 56k Data/Fax/Voice Modem
+       1455  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+       1456  HCF 56k Data/Fax/Voice/Spkp Modem
+               122d 4035  Dell Europa - MDP3900V-W # Aztech
+               122d 4302  MP3930V-W(C) MiniPCI # Aztech
+       1803  HCF 56k Modem
+               0e11 0023 623-LAN Grizzly # Compaq
+               0e11 0043 623-LAN Yogi # Compaq
+       1815  HCF 56k Modem
+               0e11 0022  Grizzly # Compaq
+               0e11 0042  Yogi # Compaq
+       2003  HSF 56k Data/Fax Modem
+       2004  HSF 56k Data/Fax/Voice Modem
+       2005  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+       2006  HSF 56k Data/Fax/Voice/Spkp Modem
+       2013  HSF 56k Data/Fax Modem
+               0e11 b195  Bear # Compaq
+               0e11 b196  Seminole 1 # Compaq
+               0e11 b1be  Seminole 2 # Compaq
+               1025 8013  Acer
+               1033 809d  NEC
+               1033 80bc  NEC
+               155d 6793  HP
+               155d 8850  E Machines
+       2014  HSF 56k Data/Fax/Voice Modem
+       2015  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+       2016  HSF 56k Data/Fax/Voice/Spkp Modem
+       2043  HSF 56k Data/Fax Modem (Worldwide SmartDAA)
+       2044  HSF 56k Data/Fax/Voice Modem (Worldwide SmartDAA)
+       2045  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide SmartDAA)
+       2046  HSF 56k Data/Fax/Voice/Spkp Modem (Worldwide SmartDAA)
+       2063  HSF 56k Data/Fax Modem (SmartDAA)
+       2064  HSF 56k Data/Fax/Voice Modem (SmartDAA)
+       2065  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
+       2066  HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
+       2093  HSF 56k Modem
+               155d 2f07  Legend
+       2143  HSF 56k Data/Fax/Cell Modem (Mobile Worldwide SmartDAA)
+       2144  HSF 56k Data/Fax/Voice/Cell Modem (Mobile Worldwide SmartDAA)
+       2145  HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WW SmartDAA)
+       2146  HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mobile Worldwide SmartDAA)
+       2163  HSF 56k Data/Fax/Cell Modem (Mobile SmartDAA)
+       2164  HSF 56k Data/Fax/Voice/Cell Modem (Mobile SmartDAA)
+       2165  HSF 56k Data/Fax/Voice/Spkp (w/Handset)/Cell Modem (Mobile SmartDAA)
+       2166  HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mobile SmartDAA)
+       2343  HSF 56k Data/Fax CardBus Modem (Mobile Worldwide SmartDAA)
+       2344  HSF 56k Data/Fax/Voice CardBus Modem (Mobile Worldwide SmartDAA)
+       2345  HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WW SmartDAA)
+       2346  HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mobile Worldwide SmartDAA)
+       2363  HSF 56k Data/Fax CardBus Modem (Mobile SmartDAA)
+       2364  HSF 56k Data/Fax/Voice CardBus Modem (Mobile SmartDAA)
+       2365  HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
+       2366  HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mobile SmartDAA)
+       2443  HSF 56k Data/Fax Modem (Mobile Worldwide SmartDAA)
+               104d 8075  Modem # Sony
+               104d 8083  Modem # Sony
+               104d 8097  Modem # Sony
+       2444  HSF 56k Data/Fax/Voice Modem (Mobile Worldwide SmartDAA)
+       2445  HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mobile WW SmartDAA)
+       2446  HSF 56k Data/Fax/Voice/Spkp Modem (Mobile Worldwide SmartDAA)
+       2463  HSF 56k Data/Fax Modem (Mobile SmartDAA)
+       2464  HSF 56k Data/Fax/Voice Modem (Mobile SmartDAA)
+       2465  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Mobile SmartDAA)
+       2466  HSF 56k Data/Fax/Voice/Spkp Modem (Mobile SmartDAA)
+       2f00  HSF 56k HSFi Modem
+               13e0 8d84  IBM HSFi V.90
+               13e0 8d85  Compaq Stinger
 14f2  MOBILITY Electronics
 14f3  BROADLOGIC
 14f4  TOKYO Electronic Industry CO Ltd
index 6468ab04daa04a03265fb957e83b648cbccfa498..391ba048dd3cbb9c5d9f70302e4702f3db88ac75 100644 (file)
@@ -53,10 +53,33 @@ else
   endif
 endif
 
+obj-$(CONFIG_PCMCIA_SA1100)    += sa1100_cs.o
+
+sa1100_cs-objs-y                               := sa1100_generic.o
+sa1100_cs-objs-$(CONFIG_SA1100_ASSABET)                += sa1100_assabet.o
+sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET)      += sa1100_neponset.o
+sa1100_cs-objs-$(CONFIG_SA1100_H3600)          += sa1100_h3600.o
+sa1100_cs-objs-$(CONFIG_SA1100_CERF)           += sa1100_cerf.o
+sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT) += sa1100_graphicsclient.o
+sa1100_cs-objs-$(CONFIG_SA1100_XP860)          += sa1100_xp860.o
+sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN)       += sa1100_pangolin.o
+sa1100_cs-objs-$(CONFIG_SA1100_YOPY)           += sa1100_yopy.o
+sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD)       += sa1100_freebird.o
+sa1100_cs-objs-$(CONFIG_SA1100_PFS168)         += sa1100_pfs168.o
+sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720)     += sa1100_jornada720.o
+sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET)       += sa1100_flexanet.o
+sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD)         += sa1100_simpad.o
+sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o
+sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)       += sa1100_adsbitsy.o
+sa1100_cs-objs-$(CONFIG_SA1100_STORK)          += sa1100_stork.o
+
 include $(TOPDIR)/Rules.make
 
 pcmcia_core.o:  $(pcmcia_core-objs)
        $(LD) $(LD_RFLAG) -r -o $@ $(pcmcia_core-objs)
 
+sa1100_cs.o: $(sa1100_cs-objs-y)
+       $(LD) -r -o $@ $(sa1100_cs-objs-y)
+
 yenta_socket.o: $(yenta_socket-objs)
        $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs)
index c9d8b5313fc4a6698c2fe24db00b5342fe547e71..3e1775c1021d45e4eeb42855720786900f01cb2b 100644 (file)
@@ -789,6 +789,10 @@ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
              *base, align);
        align = 0;
     }
+    if ((s->cap.features & SS_CAP_STATIC_MAP) && s->cap.io_offset) {
+       *base = s->cap.io_offset | (*base & 0x0fff);
+       return 0;
+    }
     /* Check for an already-allocated window that must conflict with
        what was asked for.  It is a hack because it does not catch all
        potential conflicts, just the most obvious ones. */
@@ -833,7 +837,8 @@ static void release_io_space(socket_info_t *s, ioaddr_t base,
                             ioaddr_t num)
 {
     int i;
-    release_region(base, num);
+    if(!(s->cap.features & SS_CAP_STATIC_MAP))
+       release_region(base, num);
     for (i = 0; i < MAX_IO_WIN; i++) {
        if ((s->io[i].BasePort <= base) &&
            (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
@@ -1623,7 +1628,8 @@ int pcmcia_release_window(window_handle_t win)
     s->state &= ~SOCKET_WIN_REQ(win->index);
 
     /* Release system memory */
-    release_mem_region(win->base, win->size);
+    if(!(s->cap.features & SS_CAP_STATIC_MAP))
+       release_mem_region(win->base, win->size);
     win->handle->state &= ~CLIENT_WIN_REQ(win->index);
 
     win->magic = 0;
diff --git a/drivers/pcmcia/sa1100.h b/drivers/pcmcia/sa1100.h
new file mode 100644 (file)
index 0000000..eda4f6d
--- /dev/null
@@ -0,0 +1,202 @@
+/*======================================================================
+
+    Device driver for the PCMCIA control functionality of StrongARM
+    SA-1100 microprocessors.
+
+    The contents of this file are subject to the Mozilla Public
+    License Version 1.1 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a copy of
+    the License at http://www.mozilla.org/MPL/
+
+    Software distributed under the License is distributed on an "AS
+    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+    implied. See the License for the specific language governing
+    rights and limitations under the License.
+
+    The initial developer of the original code is John G. Dorsey
+    <john+@cs.cmu.edu>.  Portions created by John G. Dorsey are
+    Copyright (C) 1999 John G. Dorsey.  All Rights Reserved.
+
+    Alternatively, the contents of this file may be used under the
+    terms of the GNU Public License version 2 (the "GPL"), in which
+    case the provisions of the GPL are applicable instead of the
+    above.  If you wish to allow the use of your version of this file
+    only under the terms of the GPL and not to allow others to use
+    your version of this file under the MPL, indicate your decision
+    by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL.  If you do not delete
+    the provisions above, a recipient may use your version of this
+    file under either the MPL or the GPL.
+    
+======================================================================*/
+
+#if !defined(_PCMCIA_SA1100_H)
+# define _PCMCIA_SA1100_H
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+#include <asm/arch/pcmcia.h>
+
+
+/* MECR: Expansion Memory Configuration Register
+ * (SA-1100 Developers Manual, p.10-13; SA-1110 Developers Manual, p.10-24)
+ *
+ * MECR layout is:  
+ *
+ *   FAST1 BSM1<4:0> BSA1<4:0> BSIO1<4:0> FAST0 BSM0<4:0> BSA0<4:0> BSIO0<4:0>
+ *
+ * (This layout is actually true only for the SA-1110; the FASTn bits are
+ * reserved on the SA-1100.)
+ */
+
+#define MECR_SOCKET_0_SHIFT (0)
+#define MECR_SOCKET_1_SHIFT (16)
+
+#define MECR_BS_MASK        (0x1f)
+#define MECR_FAST_MODE_MASK (0x01)
+
+#define MECR_BSIO_SHIFT (0)
+#define MECR_BSA_SHIFT  (5)
+#define MECR_BSM_SHIFT  (10)
+#define MECR_FAST_SHIFT (15)
+
+#define MECR_SET(mecr, sock, shift, mask, bs) \
+((mecr)=((mecr)&~(((mask)<<(shift))<<\
+                  ((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))|\
+        (((bs)<<(shift))<<((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))
+
+#define MECR_GET(mecr, sock, shift, mask) \
+((((mecr)>>(((sock)==0)?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT))>>\
+ (shift))&(mask))
+
+#define MECR_BSIO_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSIO_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK)
+
+#define MECR_BSA_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSA_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK)
+
+#define MECR_BSM_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSM_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK)
+
+#define MECR_FAST_SET(mecr, sock, fast) \
+MECR_SET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK, (fast))
+
+#define MECR_FAST_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK)
+
+
+/* This function implements the BS value calculation for setting the MECR
+ * using integer arithmetic:
+ */
+static inline unsigned int sa1100_pcmcia_mecr_bs(unsigned int pcmcia_cycle_ns,
+                                                unsigned int cpu_clock_khz){
+  unsigned int t = ((pcmcia_cycle_ns * cpu_clock_khz) / 6) - 1000000;
+  return (t / 1000000) + (((t % 1000000) == 0) ? 0 : 1);
+}
+
+/* This function returns the (approxmiate) command assertion period, in
+ * nanoseconds, for a given CPU clock frequency and MECR BS value:
+ */
+static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
+                                                 unsigned int pcmcia_mecr_bs){
+  return (((10000000 * 2) / cpu_clock_khz) * (3 * (pcmcia_mecr_bs + 1))) / 10;
+}
+
+
+/* SA-1100 PCMCIA Memory and I/O timing
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * The SA-1110 Developer's Manual, section 10.2.5, says the following:
+ *
+ *  "To calculate the recommended BS_xx value for each address space:
+ *   divide the command width time (the greater of twIOWR and twIORD,
+ *   or the greater of twWE and twOE) by processor cycle time; divide
+ *   by 2; divide again by 3 (number of BCLK's per command assertion);
+ *   round up to the next whole number; and subtract 1."
+ *
+ * The PC Card Standard, Release 7, section 4.13.4, says that twIORD
+ * has a minimum value of 165ns. Section 4.13.5 says that twIOWR has
+ * a minimum value of 165ns, as well. Section 4.7.2 (describing
+ * common and attribute memory write timing) says that twWE has a
+ * minimum value of 150ns for a 250ns cycle time (for 5V operation;
+ * see section 4.7.4), or 300ns for a 600ns cycle time (for 3.3V
+ * operation, also section 4.7.4). Section 4.7.3 says that taOE
+ * has a maximum value of 150ns for a 300ns cycle time (for 5V
+ * operation), or 300ns for a 600ns cycle time (for 3.3V operation).
+ *
+ * When configuring memory maps, Card Services appears to adopt the policy
+ * that a memory access time of "0" means "use the default." The default
+ * PCMCIA I/O command width time is 165ns. The default PCMCIA 5V attribute
+ * and memory command width time is 150ns; the PCMCIA 3.3V attribute and
+ * memory command width time is 300ns.
+ */
+#define SA1100_PCMCIA_IO_ACCESS      (165)
+#define SA1100_PCMCIA_5V_MEM_ACCESS  (150)
+#define SA1100_PCMCIA_3V_MEM_ACCESS  (300)
+
+
+/* The socket driver actually works nicely in interrupt-driven form,
+ * so the (relatively infrequent) polling is "just to be sure."
+ */
+#define SA1100_PCMCIA_POLL_PERIOD    (2*HZ)
+
+
+/* This structure encapsulates per-socket state which we might need to
+ * use when responding to a Card Services query of some kind.
+ */
+struct sa1100_pcmcia_socket {
+  socket_state_t        cs_state;
+  struct pcmcia_state   k_state;
+  unsigned int          irq;
+  void                  (*handler)(void *, unsigned int);
+  void                  *handler_info;
+  pccard_io_map         io_map[MAX_IO_WIN];
+  pccard_mem_map        mem_map[MAX_WIN];
+  ioaddr_t              virt_io, phys_attr, phys_mem;
+  unsigned short        speed_io, speed_attr, speed_mem;
+};
+
+
+/* I/O pins replacing memory pins
+ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
+ *
+ * These signals change meaning when going from memory-only to 
+ * memory-or-I/O interface:
+ */
+#define iostschg bvd1
+#define iospkr   bvd2
+
+
+/*
+ * Declaration for all implementation specific low_level operations.
+ */
+extern struct pcmcia_low_level assabet_pcmcia_ops;
+extern struct pcmcia_low_level neponset_pcmcia_ops;
+extern struct pcmcia_low_level h3600_pcmcia_ops;
+extern struct pcmcia_low_level cerf_pcmcia_ops;
+extern struct pcmcia_low_level gcplus_pcmcia_ops;
+extern struct pcmcia_low_level xp860_pcmcia_ops;
+extern struct pcmcia_low_level yopy_pcmcia_ops;
+extern struct pcmcia_low_level pangolin_pcmcia_ops;
+extern struct pcmcia_low_level freebird_pcmcia_ops;
+extern struct pcmcia_low_level pfs168_pcmcia_ops;
+extern struct pcmcia_low_level jornada720_pcmcia_ops;
+extern struct pcmcia_low_level flexanet_pcmcia_ops;
+extern struct pcmcia_low_level simpad_pcmcia_ops;
+extern struct pcmcia_low_level graphicsmaster_pcmcia_ops;
+extern struct pcmcia_low_level adsbitsy_pcmcia_ops;
+extern struct pcmcia_low_level stork_pcmcia_ops;
+
+#endif  /* !defined(_PCMCIA_SA1100_H) */
diff --git a/drivers/pcmcia/sa1100_adsbitsy.c b/drivers/pcmcia/sa1100_adsbitsy.c
new file mode 100644 (file)
index 0000000..1793f24
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * drivers/pcmcia/sa1100_adsbitsy.c
+ *
+ * PCMCIA implementation routines for ADS Bitsy
+ *
+ * 9/18/01 Woojung
+ *         Fixed wrong PCMCIA voltage setting
+ *
+ * 7/5/01 Woojung Huh <whuh@applieddata.net>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int adsbitsy_pcmcia_init(struct pcmcia_init *init)
+{
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  /* Disable Power 3.3V/5V for PCMCIA/CF */
+  PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
+
+  INTPOL1 |= (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+                        (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+                (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+                (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+                (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+                (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+                         "GC Master PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+                         "GC Master CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "GC Master PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "GC Master CF (1) BVD1", NULL);
+
+  MECR = 0x09430943;
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int adsbitsy_pcmcia_shutdown(void)
+{
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+                          (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+                  (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+                  (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int adsbitsy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int adsbitsy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+  switch(configure->sock){
+  case 0:
+
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio |= GPIO_GPIO0 | GPIO_GPIO1;
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+         gpio &= ~GPIO_GPIO0;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+         gpio |= GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+         gpio |= GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+         gpio |= GPIO_GPIO3;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+            configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level adsbitsy_pcmcia_ops = {
+  adsbitsy_pcmcia_init,
+  adsbitsy_pcmcia_shutdown,
+  adsbitsy_pcmcia_socket_state,
+  adsbitsy_pcmcia_get_irq_info,
+  adsbitsy_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
new file mode 100644 (file)
index 0000000..2cb7800
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * drivers/pcmcia/sa1100_assabet.c
+ *
+ * PCMCIA implementation routines for Assabet
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int assabet_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable CF bus: */
+  BCR_clear(BCR_CF_BUS_OFF);
+
+  /* All those are inputs */
+  GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD2;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD1;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %u failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int assabet_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_CF_CD, NULL );
+  free_irq( IRQ_GPIO_CF_BVD2, NULL );
+  free_irq( IRQ_GPIO_CF_BVD1, NULL );
+  
+  /* Disable CF bus: */
+  BCR_set(BCR_CF_BUS_OFF);
+
+  return 0;
+}
+
+static int assabet_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+  state_array->state[1].bvd1=(levels & GPIO_CF_BVD1)?1:0;
+
+  state_array->state[1].bvd2=(levels & GPIO_CF_BVD2)?1:0;
+
+  state_array->state[1].wrprot=0; /* Not available on Assabet. */
+
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
+
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==1)
+    info->irq=IRQ_GPIO_CF_IRQ;
+
+  return 0;
+}
+
+static int assabet_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==0) return 0;
+
+  save_flags_cli(flags);
+
+  value = BCR_value;
+
+  switch(configure->vcc){
+  case 0:
+    value &= ~BCR_CF_PWR;
+    break;
+
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+          __FUNCTION__);
+
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+    value |= BCR_CF_PWR;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+          configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  value = (configure->reset) ? (value | BCR_CF_RST) : (value & ~BCR_CF_RST);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  BCR = BCR_value = value;
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level assabet_pcmcia_ops = { 
+  assabet_pcmcia_init,
+  assabet_pcmcia_shutdown,
+  assabet_pcmcia_socket_state,
+  assabet_pcmcia_get_irq_info,
+  assabet_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
new file mode 100644 (file)
index 0000000..4182764
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * drivers/pcmcia/sa1100_cerf.c
+ *
+ * PCMCIA implementation routines for CerfBoard
+ * Based off the Assabet.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int cerf_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable CF bus: */
+//  BCR_clear(BCR_CF_BUS_OFF);
+
+  /* All those are inputs */
+  GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD2;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD1;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int cerf_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_CF_CD, NULL );
+  free_irq( IRQ_GPIO_CF_BVD2, NULL );
+  free_irq( IRQ_GPIO_CF_BVD1, NULL );
+  
+  /* Disable CF bus: */
+//  BCR_set(BCR_CF_BUS_OFF);
+
+  return 0;
+}
+
+static int cerf_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+  state_array->state[1].bvd1=(levels & GPIO_CF_BVD1)?1:0;
+
+  state_array->state[1].bvd2=(levels & GPIO_CF_BVD2)?1:0;
+
+  state_array->state[1].wrprot=0; /* Not available on Assabet. */
+
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
+
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==1)
+    info->irq=IRQ_GPIO_CF_IRQ;
+
+  return 0;
+}
+
+static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==0) return 0;
+
+  save_flags_cli(flags);
+
+//  value = BCR_value;
+
+  switch(configure->vcc){
+  case 0:
+//    value &= ~BCR_CF_PWR;
+    break;
+
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+          __FUNCTION__);
+
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+//    value |= BCR_CF_PWR;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+          configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+//  value = (configure->reset) ? (value | BCR_CF_RST) : (value & ~BCR_CF_RST);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+//  BCR = BCR_value = value;
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level cerf_pcmcia_ops = { 
+  cerf_pcmcia_init,
+  cerf_pcmcia_shutdown,
+  cerf_pcmcia_socket_state,
+  cerf_pcmcia_get_irq_info,
+  cerf_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_flexanet.c b/drivers/pcmcia/sa1100_flexanet.c
new file mode 100644 (file)
index 0000000..14f94bc
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * drivers/pcmcia/sa1100_flexanet.c
+ *
+ * PCMCIA implementation routines for Flexanet.
+ * by Jordi Colomer, 09/05/2001
+ *
+ * Yet to be defined.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+/*
+ * Socket initialization.
+ *
+ * Called by sa1100_pcmcia_driver_init on startup.
+ * Must return the number of slots.
+ *
+ */
+static int flexanet_pcmcia_init(struct pcmcia_init *init){
+
+  return 0;
+}
+
+
+/*
+ * Socket shutdown
+ *
+ */
+static int flexanet_pcmcia_shutdown(void)
+{
+  return 0;
+}
+
+
+/*
+ * Get the state of the sockets.
+ *
+ *  Sockets in Flexanet are 3.3V only, without BVD2.
+ *
+ */
+static int flexanet_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array){
+  return -1;
+}
+
+
+/*
+ * Return the IRQ information for a given socket number (the IRQ number)
+ *
+ */
+static int flexanet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  return -1;
+}
+
+
+/*
+ *
+ */
+static int flexanet_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  return -1;
+}
+
+
+/*
+ * The set of socket operations
+ *
+ */
+struct pcmcia_low_level flexanet_pcmcia_ops = {
+  flexanet_pcmcia_init,
+  flexanet_pcmcia_shutdown,
+  flexanet_pcmcia_socket_state,
+  flexanet_pcmcia_get_irq_info,
+  flexanet_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_freebird.c b/drivers/pcmcia/sa1100_freebird.c
new file mode 100644 (file)
index 0000000..f47bd57
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * drivers/pcmcia/sa1100_freebird.c
+ *
+ * Created by Eric Peng <ericpeng@coventive.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int freebird_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable Linkup CF card */
+  LINKUP_PRC = 0xc0;
+  mdelay(100);
+  LINKUP_PRC = 0xc1;
+  mdelay(100);
+  LINKUP_PRC = 0xd1;
+  mdelay(100);
+  LINKUP_PRC = 0xd1;
+  mdelay(100);
+  LINKUP_PRC = 0xc0;
+
+  /* All those are inputs */
+  ////GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+  GPDR &= ~(GPIO_FREEBIRD_CF_CD | GPIO_FREEBIRD_CF_IRQ | GPIO_FREEBIRD_CF_BVD);
+
+  /* Set transition detect */
+  //set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+  //set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_CD|GPIO_FREEBIRD_CF_BVD,GPIO_BOTH_EDGES);
+  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_IRQ, GPIO_FALLING_EDGE);
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_FREEBIRD_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_FREEBIRD_CF_BVD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int freebird_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_FREEBIRD_CF_CD, NULL );
+  free_irq( IRQ_GPIO_FREEBIRD_CF_BVD, NULL );
+
+  /* Disable CF card */
+  LINKUP_PRC = 0x40;  /* SSP=1   SOE=0 */
+  mdelay(100);
+
+  return 0;
+}
+
+static int freebird_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels = LINKUP_PRS;
+//printk("LINKUP_PRS=%x \n",levels);
+
+  state_array->state[0].detect=
+    ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
+
+  state_array->state[0].ready=(levels & LINKUP_RDY)?1:0;
+
+  state_array->state[0].bvd1=(levels & LINKUP_BVD1)?1:0;
+
+  state_array->state[0].bvd2=(levels & LINKUP_BVD2)?1:0;
+
+  state_array->state[0].wrprot=0; /* Not available on Assabet. */
+
+  state_array->state[0].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
+
+  state_array->state[0].vs_Xv=0;
+
+  return 1;
+}
+
+static int freebird_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==0)
+    info->irq=IRQ_GPIO_FREEBIRD_CF_IRQ;
+
+  return 0;
+}
+
+static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==1) return 0;
+
+  save_flags_cli(flags);
+
+  value = 0xc0;   /* SSP=1  SOE=1  CFE=1 */
+
+  switch(configure->vcc){
+  case 0:
+
+    break;
+
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+          __FUNCTION__);
+
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+    value |= LINKUP_S1;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+          configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  if (configure->reset)
+  value = (configure->reset) ? (value | LINKUP_RESET) : (value & ~LINKUP_RESET);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  LINKUP_PRC = value;
+//printk("LINKUP_PRC=%x\n",value);
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level freebird_pcmcia_ops = {
+  freebird_pcmcia_init,
+  freebird_pcmcia_shutdown,
+  freebird_pcmcia_socket_state,
+  freebird_pcmcia_get_irq_info,
+  freebird_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
new file mode 100644 (file)
index 0000000..85352ee
--- /dev/null
@@ -0,0 +1,1168 @@
+/*======================================================================
+
+    Device driver for the PCMCIA control functionality of StrongARM
+    SA-1100 microprocessors.
+
+    The contents of this file are subject to the Mozilla Public
+    License Version 1.1 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a copy of
+    the License at http://www.mozilla.org/MPL/
+
+    Software distributed under the License is distributed on an "AS
+    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+    implied. See the License for the specific language governing
+    rights and limitations under the License.
+
+    The initial developer of the original code is John G. Dorsey
+    <john+@cs.cmu.edu>.  Portions created by John G. Dorsey are
+    Copyright (C) 1999 John G. Dorsey.  All Rights Reserved.
+
+    Alternatively, the contents of this file may be used under the
+    terms of the GNU Public License version 2 (the "GPL"), in which
+    case the provisions of the GPL are applicable instead of the
+    above.  If you wish to allow the use of your version of this file
+    only under the terms of the GPL and not to allow others to use
+    your version of this file under the MPL, indicate your decision
+    by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL.  If you do not delete
+    the provisions above, a recipient may use your version of this
+    file under either the MPL or the GPL.
+    
+======================================================================*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/notifier.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bus_ops.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "sa1100.h"
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug;
+#endif
+
+MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-1100 Socket Controller");
+
+/* This structure maintains housekeeping state for each socket, such
+ * as the last known values of the card detect pins, or the Card Services
+ * callback value associated with the socket:
+ */
+static struct sa1100_pcmcia_socket 
+sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK];
+
+static int sa1100_pcmcia_socket_count;
+
+
+/* Returned by the low-level PCMCIA interface: */
+static struct pcmcia_low_level *pcmcia_low_level;
+
+/* Event poll timer structure */
+static struct timer_list poll_timer;
+
+
+/* Prototypes for routines which are used internally: */
+
+static int  sa1100_pcmcia_driver_init(void);
+static void sa1100_pcmcia_driver_shutdown(void);
+static void sa1100_pcmcia_task_handler(void *data);
+static void sa1100_pcmcia_poll_event(unsigned long data);
+static void sa1100_pcmcia_interrupt(int irq, void *dev,
+                                   struct pt_regs *regs);
+static struct tq_struct sa1100_pcmcia_task;
+
+#ifdef CONFIG_PROC_FS
+static int  sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
+                                     int count, int *eof, void *data);
+#endif
+
+
+/* Prototypes for operations which are exported to the
+ * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
+ */
+
+static int sa1100_pcmcia_init(unsigned int sock);
+static int sa1100_pcmcia_suspend(unsigned int sock);
+static int sa1100_pcmcia_register_callback(unsigned int sock,
+                                          void (*handler)(void *, 
+                                                          unsigned int),
+                                          void *info);
+static int sa1100_pcmcia_inquire_socket(unsigned int sock, 
+                                       socket_cap_t *cap);
+static int sa1100_pcmcia_get_status(unsigned int sock, u_int *value);
+static int sa1100_pcmcia_get_socket(unsigned int sock, 
+                                   socket_state_t *state);
+static int sa1100_pcmcia_set_socket(unsigned int sock,
+                                   socket_state_t *state);
+static int sa1100_pcmcia_get_io_map(unsigned int sock,
+                                   struct pccard_io_map *io);
+static int sa1100_pcmcia_set_io_map(unsigned int sock,
+                                   struct pccard_io_map *io);
+static int sa1100_pcmcia_get_mem_map(unsigned int sock,
+                                    struct pccard_mem_map *mem);
+static int sa1100_pcmcia_set_mem_map(unsigned int sock,
+                                    struct pccard_mem_map *mem);
+#ifdef CONFIG_PROC_FS
+static void sa1100_pcmcia_proc_setup(unsigned int sock,
+                                    struct proc_dir_entry *base);
+#endif
+
+static struct pccard_operations sa1100_pcmcia_operations = {
+  sa1100_pcmcia_init,
+  sa1100_pcmcia_suspend,
+  sa1100_pcmcia_register_callback,
+  sa1100_pcmcia_inquire_socket,
+  sa1100_pcmcia_get_status,
+  sa1100_pcmcia_get_socket,
+  sa1100_pcmcia_set_socket,
+  sa1100_pcmcia_get_io_map,
+  sa1100_pcmcia_set_io_map,
+  sa1100_pcmcia_get_mem_map,
+  sa1100_pcmcia_set_mem_map,
+#ifdef CONFIG_PROC_FS
+  sa1100_pcmcia_proc_setup
+#endif
+};
+
+#ifdef CONFIG_CPU_FREQ
+/* forward declaration */
+static struct notifier_block sa1100_pcmcia_notifier_block;
+#endif
+
+
+/* sa1100_pcmcia_driver_init()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *
+ * This routine performs a basic sanity check to ensure that this
+ * kernel has been built with the appropriate board-specific low-level
+ * PCMCIA support, performs low-level PCMCIA initialization, registers
+ * this socket driver with Card Services, and then spawns the daemon
+ * thread which is the real workhorse of the socket driver.
+ *
+ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
+ * on the low-level kernel interface.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int __init sa1100_pcmcia_driver_init(void){
+  servinfo_t info;
+  struct pcmcia_init pcmcia_init;
+  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+  struct pcmcia_state_array state_array;
+  unsigned int i, clock;
+  unsigned long mecr;
+
+  printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);
+
+  CardServices(GetCardServicesInfo, &info);
+
+  if(info.Revision!=CS_RELEASE_CODE){
+    printk(KERN_ERR "Card Services release codes do not match\n");
+    return -1;
+  }
+
+  if(machine_is_assabet()){
+#ifdef CONFIG_SA1100_ASSABET
+    if(machine_has_neponset()){
+#ifdef CONFIG_ASSABET_NEPONSET
+      pcmcia_low_level=&neponset_pcmcia_ops;
+#else
+      printk(KERN_ERR "Card Services disabled: missing Neponset support\n");
+      return -1;
+#endif
+    }else{
+      pcmcia_low_level=&assabet_pcmcia_ops;
+    }
+#endif
+  } else if (machine_is_freebird()) {
+#ifdef CONFIG_SA1100_FREEBIRD
+    pcmcia_low_level = &freebird_pcmcia_ops;
+#endif
+  } else if (machine_is_h3600()) {
+#ifdef CONFIG_SA1100_H3600
+    pcmcia_low_level = &h3600_pcmcia_ops;
+#endif    
+  } else if (machine_is_cerf()) {
+#ifdef CONFIG_SA1100_CERF
+    pcmcia_low_level = &cerf_pcmcia_ops;
+#endif
+  } else if (machine_is_graphicsclient()) {
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+    pcmcia_low_level = &gcplus_pcmcia_ops;
+#endif
+  } else if (machine_is_xp860()) {
+#ifdef CONFIG_SA1100_XP860
+    pcmcia_low_level = &xp860_pcmcia_ops;
+#endif
+  } else if (machine_is_yopy()) {
+#ifdef CONFIG_SA1100_YOPY
+    pcmcia_low_level = &yopy_pcmcia_ops;
+#endif
+  } else if (machine_is_pangolin()) {
+#ifdef CONFIG_SA1100_PANGOLIN
+    pcmcia_low_level = &pangolin_pcmcia_ops;
+#endif
+  } else if (machine_is_jornada720()) {
+#ifdef CONFIG_SA1100_JORNADA720
+    pcmcia_low_level = &jornada720_pcmcia_ops;
+#endif
+  } else if(machine_is_pfs168()){
+#ifdef CONFIG_SA1100_PFS168
+    pcmcia_low_level=&pfs168_pcmcia_ops;
+#endif
+  } else if(machine_is_flexanet()){
+#ifdef CONFIG_SA1100_FLEXANET
+    pcmcia_low_level=&flexanet_pcmcia_ops;
+#endif
+ } else if(machine_is_simpad()){
+#ifdef CONFIG_SA1100_SIMPAD
+    pcmcia_low_level=&simpad_pcmcia_ops;
+#endif
+  } else if(machine_is_graphicsmaster()) {
+#ifdef CONFIG_SA1100_GRAPHICSMASTER
+    pcmcia_low_level=&graphicsmaster_pcmcia_ops;
+#endif
+  } else if(machine_is_adsbitsy()) {
+#ifdef CONFIG_SA1100_ADSBITSY
+    pcmcia_low_level=&adsbitsy_pcmcia_ops;
+#endif
+  } else if(machine_is_stork()) {
+#ifdef CONFIG_SA1100_STORK
+    pcmcia_low_level=&stork_pcmcia_ops;
+#endif
+  }
+
+  if (!pcmcia_low_level) {
+    printk(KERN_ERR "This hardware is not supported by the SA1100 Card Service driver\n");
+    return -ENODEV;
+  }
+
+  pcmcia_init.handler=sa1100_pcmcia_interrupt;
+
+  if((sa1100_pcmcia_socket_count=pcmcia_low_level->init(&pcmcia_init))<0){
+    printk(KERN_ERR "Unable to initialize kernel PCMCIA service.\n");
+    return -EIO;
+  }
+
+  state_array.size=sa1100_pcmcia_socket_count;
+  state_array.state=state;
+
+  if(pcmcia_low_level->socket_state(&state_array)<0){
+    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+    return -EIO;
+  }
+
+  /* We initialize the MECR to default values here, because we are
+   * not guaranteed to see a SetIOMap operation at runtime.
+   */
+  mecr=0;
+
+  clock = get_cclk_frequency() * 100;
+
+  for(i=0; i<sa1100_pcmcia_socket_count; ++i){
+    sa1100_pcmcia_socket[i].k_state=state[i];
+
+    /* This is an interim fix. Apparently, SetSocket is no longer
+     * called to initialize each socket (prior to the first detect
+     * event). For now, we'll just manually set up the mask.
+     */
+    sa1100_pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
+
+    sa1100_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE;
+    sa1100_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i);
+    sa1100_pcmcia_socket[i].phys_mem=_PCMCIAMem(i);
+
+    MECR_FAST_SET(mecr, i, 0);
+    MECR_BSIO_SET(mecr, i,
+                 sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_IO_ACCESS, clock));
+    MECR_BSA_SET(mecr, i,
+                sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
+    MECR_BSM_SET(mecr, i,
+                sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
+
+    sa1100_pcmcia_socket[i].speed_io=SA1100_PCMCIA_IO_ACCESS;
+    sa1100_pcmcia_socket[i].speed_attr=SA1100_PCMCIA_5V_MEM_ACCESS;
+    sa1100_pcmcia_socket[i].speed_mem=SA1100_PCMCIA_5V_MEM_ACCESS;
+  }
+
+  MECR=mecr;
+
+#ifdef CONFIG_CPU_FREQ
+  if(cpufreq_register_notifier(&sa1100_pcmcia_notifier_block) < 0){
+    printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
+    return -ENXIO;
+  }
+#endif
+
+  /* Only advertise as many sockets as we can detect: */
+  if(register_ss_entry(sa1100_pcmcia_socket_count, 
+                      &sa1100_pcmcia_operations)<0){
+    printk(KERN_ERR "Unable to register socket service routine\n");
+    return -ENXIO;
+  }
+
+  /* Start the event poll timer.  It will reschedule by itself afterwards. */
+  sa1100_pcmcia_poll_event(0);
+
+  DEBUG(1, "sa1100: initialization complete\n");
+
+  return 0;
+
+}  /* sa1100_pcmcia_driver_init() */
+
+module_init(sa1100_pcmcia_driver_init);
+
+
+/* sa1100_pcmcia_driver_shutdown()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Invokes the low-level kernel service to free IRQs associated with this
+ * socket controller and reset GPIO edge detection.
+ */
+static void __exit sa1100_pcmcia_driver_shutdown(void){
+
+  del_timer_sync(&poll_timer);
+  unregister_ss_entry(&sa1100_pcmcia_operations);
+#ifdef CONFIG_CPU_FREQ
+  cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block);
+#endif
+  pcmcia_low_level->shutdown();
+  flush_scheduled_tasks();
+
+  DEBUG(1, "sa1100: shutdown complete\n");
+}
+
+module_exit(sa1100_pcmcia_driver_shutdown);
+
+
+/* sa1100_pcmcia_init()
+ * ^^^^^^^^^^^^^^^^^^^^
+ * We perform all of the interesting initialization tasks in 
+ * sa1100_pcmcia_driver_init().
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_init(unsigned int sock){
+  
+  DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, sock);
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_suspend()
+ * ^^^^^^^^^^^^^^^^^^^^^^^
+ * We don't currently perform any actions on a suspend.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_suspend(unsigned int sock){
+
+  DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, sock);
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_events()
+ * ^^^^^^^^^^^^^^^^^^^^^^
+ * Helper routine to generate a Card Services event mask based on
+ * state information obtained from the kernel low-level PCMCIA layer
+ * in a recent (and previous) sampling. Updates `prev_state'.
+ *
+ * Returns: an event mask for the given socket state.
+ */
+static inline unsigned sa1100_pcmcia_events(struct pcmcia_state *state,
+                                           struct pcmcia_state *prev_state,
+                                           unsigned int mask,
+                                           unsigned int flags){
+  unsigned int events=0;
+
+  if(state->detect!=prev_state->detect){
+
+    DEBUG(2, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
+
+    events|=mask&SS_DETECT;
+  }
+
+  if(state->ready!=prev_state->ready){
+
+    DEBUG(2, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
+
+    events|=mask&((flags&SS_IOCARD)?0:SS_READY);
+  }
+
+  if(state->bvd1!=prev_state->bvd1){
+
+    DEBUG(2, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
+
+    events|=mask&(flags&SS_IOCARD)?SS_STSCHG:SS_BATDEAD;
+  }
+
+  if(state->bvd2!=prev_state->bvd2){
+
+    DEBUG(2, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
+
+    events|=mask&(flags&SS_IOCARD)?0:SS_BATWARN;
+  }
+
+  DEBUG(2, "events: %s%s%s%s%s%s\n",
+       (events==0)?"<NONE>":"",
+       (events&SS_DETECT)?"DETECT ":"",
+       (events&SS_READY)?"READY ":"",
+       (events&SS_BATDEAD)?"BATDEAD ":"",
+       (events&SS_BATWARN)?"BATWARN ":"",
+       (events&SS_STSCHG)?"STSCHG ":"");
+
+  *prev_state=*state;
+
+  return events;
+
+}  /* sa1100_pcmcia_events() */
+
+
+/* sa1100_pcmcia_task_handler()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Processes serviceable socket events using the "eventd" thread context.
+ *
+ * Event processing (specifically, the invocation of the Card Services event
+ * callback) occurs in this thread rather than in the actual interrupt
+ * handler due to the use of scheduling operations in the PCMCIA core.
+ */
+static void sa1100_pcmcia_task_handler(void *data) {
+  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+  struct pcmcia_state_array state_array;
+  int i, events, all_events, irq_status;
+
+  DEBUG(2, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
+
+  state_array.size=sa1100_pcmcia_socket_count;
+  state_array.state=state;
+
+  do {
+
+    DEBUG(3, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
+
+    if((irq_status=pcmcia_low_level->socket_state(&state_array))<0)
+      printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
+
+    all_events=0;
+
+    if(irq_status>0){
+
+      for(i=0; i<state_array.size; ++i, all_events|=events)
+       if((events=
+           sa1100_pcmcia_events(&state[i],
+                                &sa1100_pcmcia_socket[i].k_state,
+                                sa1100_pcmcia_socket[i].cs_state.csc_mask,
+                                sa1100_pcmcia_socket[i].cs_state.flags)))
+         if(sa1100_pcmcia_socket[i].handler!=NULL)
+           sa1100_pcmcia_socket[i].handler(sa1100_pcmcia_socket[i].handler_info,
+                                           events);
+    }
+
+  } while(all_events);
+}  /* sa1100_pcmcia_task_handler() */
+
+static struct tq_struct sa1100_pcmcia_task = {
+       routine: sa1100_pcmcia_task_handler
+};
+
+
+/* sa1100_pcmcia_poll_event()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Let's poll for events in addition to IRQs since IRQ only is unreliable...
+ */
+static void sa1100_pcmcia_poll_event(unsigned long dummy)
+{
+  DEBUG(3, "%s(): polling for events\n", __FUNCTION__);
+  poll_timer.function = sa1100_pcmcia_poll_event;
+  poll_timer.expires = jiffies + SA1100_PCMCIA_POLL_PERIOD;
+  add_timer(&poll_timer);
+  schedule_task(&sa1100_pcmcia_task);
+}
+
+
+/* sa1100_pcmcia_interrupt()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Service routine for socket driver interrupts (requested by the
+ * low-level PCMCIA init() operation via sa1100_pcmcia_thread()).
+ * The actual interrupt-servicing work is performed by
+ * sa1100_pcmcia_thread(), largely because the Card Services event-
+ * handling code performs scheduling operations which cannot be
+ * executed from within an interrupt context.
+ */
+static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs){
+  DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
+  schedule_task(&sa1100_pcmcia_task);
+}
+
+
+/* sa1100_pcmcia_register_callback()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the register_callback() operation for the in-kernel
+ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If 
+ * the function pointer `handler' is not NULL, remember the callback 
+ * location in the state for `sock', and increment the usage counter 
+ * for the driver module. (The callback is invoked from the interrupt
+ * service routine, sa1100_pcmcia_interrupt(), to notify Card Services
+ * of interesting events.) Otherwise, clear the callback pointer in the
+ * socket state and decrement the module usage count.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_register_callback(unsigned int sock,
+                                          void (*handler)(void *,
+                                                          unsigned int),
+                                          void *info){
+  if(handler==NULL){
+    sa1100_pcmcia_socket[sock].handler=NULL;
+    MOD_DEC_USE_COUNT;
+  } else {
+    MOD_INC_USE_COUNT;
+    sa1100_pcmcia_socket[sock].handler=handler;
+    sa1100_pcmcia_socket[sock].handler_info=info;
+  }
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_inquire_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the inquire_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_InquireSocket in Card Services). Of note is
+ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
+ * `cap' to "trick" Card Services into tolerating large "I/O memory" 
+ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
+ * resource database check. (Mapped memory is set up within the socket
+ * driver itself.)
+ *
+ * In conjunction with the STATIC_MAP capability is a new field,
+ * `io_offset', recommended by David Hinds. Rather than go through
+ * the SetIOMap interface (which is not quite suited for communicating
+ * window locations up from the socket driver), we just pass up
+ * an offset which is applied to client-requested base I/O addresses
+ * in alloc_io_space().
+ *
+ * Returns: 0 on success, -1 if no pin has been configured for `sock'
+ */
+static int sa1100_pcmcia_inquire_socket(unsigned int sock,
+                                       socket_cap_t *cap){
+  struct pcmcia_irq_info irq_info;
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if(sock>=sa1100_pcmcia_socket_count){
+    printk(KERN_ERR "sa1100: socket %u not configured\n", sock);
+    return -1;
+  }
+
+  /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
+   *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
+   *   general, the mapped * addresses of the PCMCIA memory regions
+   *   will not be within 0xffff, setting force_low would be
+   *   undesirable.
+   *
+   * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
+   *   resource database; we instead pass up physical address ranges
+   *   and allow other parts of Card Services to deal with remapping.
+   *
+   * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
+   *   not 32-bit CardBus devices.
+   */
+  cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
+
+  irq_info.sock=sock;
+  irq_info.irq=-1;
+
+  if(pcmcia_low_level->get_irq_info(&irq_info)<0){
+    printk(KERN_ERR "Error obtaining IRQ info from kernel for socket %u\n",
+          sock);
+    return -1;
+  }
+
+  cap->irq_mask=0;
+  cap->map_size=PAGE_SIZE;
+  cap->pci_irq=irq_info.irq;
+  cap->io_offset=sa1100_pcmcia_socket[sock].virt_io;
+
+  return 0;
+
+}  /* sa1100_pcmcia_inquire_socket() */
+
+
+/* sa1100_pcmcia_get_status()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_status() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetStatus in Card Services). Essentially just
+ * fills in bits in `status' according to internal driver state or
+ * the value of the voltage detect chipselect register.
+ *
+ * As a debugging note, during card startup, the PCMCIA core issues
+ * three set_socket() commands in a row the first with RESET deasserted,
+ * the second with RESET asserted, and the last with RESET deasserted
+ * again. Following the third set_socket(), a get_status() command will
+ * be issued. The kernel is looking for the SS_READY flag (see
+ * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_get_status(unsigned int sock,
+                                   unsigned int *status){
+  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+  struct pcmcia_state_array state_array;
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  state_array.size=sa1100_pcmcia_socket_count;
+  state_array.state=state;
+
+  if((pcmcia_low_level->socket_state(&state_array))<0){
+    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+    return -1;
+  }
+
+  sa1100_pcmcia_socket[sock].k_state=state[sock];
+
+  *status=state[sock].detect?SS_DETECT:0;
+
+  *status|=state[sock].ready?SS_READY:0;
+
+  /* The power status of individual sockets is not available
+   * explicitly from the hardware, so we just remember the state
+   * and regurgitate it upon request:
+   */
+  *status|=sa1100_pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
+
+  if(sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
+    *status|=state[sock].bvd1?SS_STSCHG:0;
+  else {
+    if(state[sock].bvd1==0)
+      *status|=SS_BATDEAD;
+    else if(state[sock].bvd2==0)
+      *status|=SS_BATWARN;
+  }
+
+  *status|=state[sock].vs_3v?SS_3VCARD:0;
+
+  *status|=state[sock].vs_Xv?SS_XVCARD:0;
+
+  DEBUG(3, "\tstatus: %s%s%s%s%s%s%s%s\n",
+       (*status&SS_DETECT)?"DETECT ":"",
+       (*status&SS_READY)?"READY ":"", 
+       (*status&SS_BATDEAD)?"BATDEAD ":"",
+       (*status&SS_BATWARN)?"BATWARN ":"",
+       (*status&SS_POWERON)?"POWERON ":"",
+       (*status&SS_STSCHG)?"STSCHG ":"",
+       (*status&SS_3VCARD)?"3VCARD ":"",
+       (*status&SS_XVCARD)?"XVCARD ":"");
+
+  return 0;
+
+}  /* sa1100_pcmcia_get_status() */
+
+
+/* sa1100_pcmcia_get_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetSocket in Card Services). Not a very 
+ * exciting routine.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_get_socket(unsigned int sock,
+                                   socket_state_t *state){
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  /* This information was given to us in an earlier call to set_socket(),
+   * so we're just regurgitating it here:
+   */
+  *state=sa1100_pcmcia_socket[sock].cs_state;
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_set_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetSocket in Card Services). We more or
+ * less punt all of this work and let the kernel handle the details
+ * of power configuration, reset, &c. We also record the value of
+ * `state' in order to regurgitate it to the PCMCIA core later.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_set_socket(unsigned int sock,
+                                   socket_state_t *state){
+  struct pcmcia_configure configure;
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  DEBUG(3, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
+       "\tVcc %d  Vpp %d  irq %d\n",
+       (state->csc_mask==0)?"<NONE>":"",
+       (state->csc_mask&SS_DETECT)?"DETECT ":"",
+       (state->csc_mask&SS_READY)?"READY ":"",
+       (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
+       (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
+       (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
+       (state->flags==0)?"<NONE>":"",
+       (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
+       (state->flags&SS_IOCARD)?"IOCARD ":"",
+       (state->flags&SS_RESET)?"RESET ":"",
+       (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
+       (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+       state->Vcc, state->Vpp, state->io_irq);
+
+  configure.sock=sock;
+  configure.vcc=state->Vcc;
+  configure.vpp=state->Vpp;
+  configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
+  configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
+  configure.reset=(state->flags&SS_RESET)?1:0;
+
+  if(pcmcia_low_level->configure_socket(&configure)<0){
+    printk(KERN_ERR "Unable to configure socket %u\n", sock);
+    return -1;
+  }
+
+  sa1100_pcmcia_socket[sock].cs_state=*state;
+  
+  return 0;
+
+}  /* sa1100_pcmcia_set_socket() */
+
+
+/* sa1100_pcmcia_get_io_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetIOMap in Card Services). Just returns an
+ * I/O map descriptor which was assigned earlier by a set_io_map().
+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */
+static int sa1100_pcmcia_get_io_map(unsigned int sock,
+                                   struct pccard_io_map *map){
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if(map->map>=MAX_IO_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+          map->map);
+    return -1;
+  }
+
+  *map=sa1100_pcmcia_socket[sock].io_map[map->map];
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_set_io_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetIOMap in Card Services). We configure
+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int sa1100_pcmcia_set_io_map(unsigned int sock,
+                                   struct pccard_io_map *map){
+  unsigned int clock, speed;
+  unsigned long mecr, start;
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  DEBUG(4, "\tmap %u  speed %u\n\tstart 0x%08lx  stop 0x%08lx\n"
+       "\tflags: %s%s%s%s%s%s%s%s\n",
+       map->map, map->speed, map->start, map->stop,
+       (map->flags==0)?"<NONE>":"",
+       (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
+       (map->flags&MAP_16BIT)?"16BIT ":"",
+       (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
+       (map->flags&MAP_0WS)?"0WS ":"",
+       (map->flags&MAP_WRPROT)?"WRPROT ":"",
+       (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
+       (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
+
+  if(map->map>=MAX_IO_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+          map->map);
+    return -1;
+  }
+
+  if(map->flags&MAP_ACTIVE){
+
+    speed=(map->speed>0)?map->speed:SA1100_PCMCIA_IO_ACCESS;
+
+    clock = get_cclk_frequency() * 100;
+
+    mecr=MECR;
+
+    MECR_BSIO_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+
+    sa1100_pcmcia_socket[sock].speed_io=speed;
+
+    DEBUG(4, "%s(): FAST%u %lx  BSM%u %lx  BSA%u %lx  BSIO%u %lx\n",
+         __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
+         MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock), 
+         sock, MECR_BSIO_GET(mecr, sock));
+
+    MECR=mecr;
+
+  }
+
+  start=map->start;
+
+  if(map->stop==1)
+    map->stop=PAGE_SIZE-1;
+
+  map->start=sa1100_pcmcia_socket[sock].virt_io;
+  map->stop=map->start+(map->stop-start);
+
+  sa1100_pcmcia_socket[sock].io_map[map->map]=*map;
+
+  return 0;
+
+}  /* sa1100_pcmcia_set_io_map() */
+
+
+/* sa1100_pcmcia_get_mem_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetMemMap in Card Services). Just returns a
+ *  memory map descriptor which was assigned earlier by a
+ *  set_mem_map() request.
+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */
+static int sa1100_pcmcia_get_mem_map(unsigned int sock,
+                                    struct pccard_mem_map *map){
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if(map->map>=MAX_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+          map->map);
+    return -1;
+  }
+
+  *map=sa1100_pcmcia_socket[sock].mem_map[map->map];
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_set_mem_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetMemMap in Card Services). We configure
+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int sa1100_pcmcia_set_mem_map(unsigned int sock,
+                                    struct pccard_mem_map *map){
+  unsigned int clock, speed;
+  unsigned long mecr, start;
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  DEBUG(4, "\tmap %u  speed %u\n\tsys_start  %#lx\n"
+       "\tsys_stop   %#lx\n\tcard_start %#x\n"
+       "\tflags: %s%s%s%s%s%s%s%s\n",
+       map->map, map->speed, map->sys_start, map->sys_stop,
+       map->card_start, (map->flags==0)?"<NONE>":"",
+       (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
+       (map->flags&MAP_16BIT)?"16BIT ":"",
+       (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
+       (map->flags&MAP_0WS)?"0WS ":"",
+       (map->flags&MAP_WRPROT)?"WRPROT ":"",
+       (map->flags&MAP_ATTRIB)?"ATTRIB ":"",
+       (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
+
+  if(map->map>=MAX_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+          map->map);
+    return -1;
+  }
+
+  if(map->flags&MAP_ACTIVE){
+
+    /* When clients issue RequestMap, the access speed is not always
+     * properly configured:
+     */
+    if(map->speed > 0)
+      speed = map->speed;
+    else
+      switch(sa1100_pcmcia_socket[sock].cs_state.Vcc){
+      case 33:
+       speed = SA1100_PCMCIA_3V_MEM_ACCESS;
+       break;
+      default:
+       speed = SA1100_PCMCIA_5V_MEM_ACCESS;
+      }
+
+    clock = get_cclk_frequency() * 100;
+    
+    mecr=MECR;
+    
+    if(map->flags&MAP_ATTRIB){
+
+      MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+      sa1100_pcmcia_socket[sock].speed_attr=speed;
+
+    } else {
+
+      MECR_BSM_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+      sa1100_pcmcia_socket[sock].speed_mem=speed;
+
+    }
+    
+    DEBUG(4, "%s(): FAST%u %lx  BSM%u %lx  BSA%u %lx  BSIO%u %lx\n",
+         __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
+         MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock), 
+         sock, MECR_BSIO_GET(mecr, sock));
+    
+    MECR=mecr;
+
+  }
+
+  start=map->sys_start;
+
+  if(map->sys_stop==0)
+    map->sys_stop=PAGE_SIZE-1;
+
+  map->sys_start=(map->flags & MAP_ATTRIB)?\
+    sa1100_pcmcia_socket[sock].phys_attr:\
+    sa1100_pcmcia_socket[sock].phys_mem;
+
+  map->sys_stop=map->sys_start+(map->sys_stop-start);
+
+  sa1100_pcmcia_socket[sock].mem_map[map->map]=*map;
+
+  return 0;
+
+}  /* sa1100_pcmcia_set_mem_map() */
+
+
+#if defined(CONFIG_PROC_FS)
+
+/* sa1100_pcmcia_proc_setup()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the proc_setup() operation for the in-kernel PCMCIA
+ * service (formerly SS_ProcSetup in Card Services).
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static void sa1100_pcmcia_proc_setup(unsigned int sock,
+                                    struct proc_dir_entry *base){
+  struct proc_dir_entry *entry;
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if((entry=create_proc_entry("status", 0, base))==NULL){
+    printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
+    return;
+  }
+
+  entry->read_proc=sa1100_pcmcia_proc_status;
+  entry->data=(void *)sock;
+}
+
+
+/* sa1100_pcmcia_proc_status()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the /proc/bus/pccard/??/status file.
+ *
+ * Returns: the number of characters added to the buffer
+ */
+static int sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
+                                    int count, int *eof, void *data){
+  char *p=buf;
+  unsigned int sock=(unsigned int)data;
+  unsigned int clock = get_cclk_frequency() * 100;
+  unsigned long mecr = MECR;
+
+  p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
+            sa1100_pcmcia_socket[sock].k_state.detect?"detect ":"",
+            sa1100_pcmcia_socket[sock].k_state.ready?"ready ":"",
+            sa1100_pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
+            sa1100_pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
+            sa1100_pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
+            sa1100_pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
+            sa1100_pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
+
+  p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
+            sa1100_pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
+            sa1100_pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
+            sa1100_pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
+            sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+            "SS_IOCARD ":"",
+            (sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
+             sa1100_pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
+            ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+             (sa1100_pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
+            ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+             (sa1100_pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
+            sa1100_pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
+            sa1100_pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
+
+  p+=sprintf(p, "mask     : %s%s%s%s%s\n",
+            sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
+            "SS_DETECT ":"",
+            sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
+            "SS_READY ":"",
+            sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
+            "SS_BATDEAD ":"",
+            sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
+            "SS_BATWARN ":"",
+            sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
+            "SS_STSCHG ":"");
+
+  p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
+            sa1100_pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
+            "SS_PWR_AUTO ":"",
+            sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+            "SS_IOCARD ":"",
+            sa1100_pcmcia_socket[sock].cs_state.flags&SS_RESET?\
+            "SS_RESET ":"",
+            sa1100_pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
+            "SS_SPKR_ENA ":"",
+            sa1100_pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
+            "SS_OUTPUT_ENA ":"");
+
+  p+=sprintf(p, "Vcc      : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vcc);
+
+  p+=sprintf(p, "Vpp      : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vpp);
+
+  p+=sprintf(p, "irq      : %d\n", sa1100_pcmcia_socket[sock].cs_state.io_irq);
+
+  p+=sprintf(p, "I/O      : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_io,
+            sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, sock)));
+
+  p+=sprintf(p, "attribute: %u (%u)\n", sa1100_pcmcia_socket[sock].speed_attr,
+            sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, sock)));
+
+  p+=sprintf(p, "common   : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_mem,
+            sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, sock)));
+
+  return p-buf;
+}
+
+#endif  /* defined(CONFIG_PROC_FS) */
+
+
+#ifdef CONFIG_CPU_FREQ
+
+/* sa1100_pcmcia_update_mecr()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * When sa1100_pcmcia_notifier() decides that a MECR adjustment (due
+ * to a core clock frequency change) is needed, this routine establishes
+ * new BS_xx values consistent with the clock speed `clock'.
+ */
+static void sa1100_pcmcia_update_mecr(unsigned int clock){
+  unsigned int sock;
+  unsigned long mecr = MECR;
+
+  for(sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock){
+
+    MECR_BSIO_SET(mecr, sock,
+                 sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_io,
+                                       clock));
+    MECR_BSA_SET(mecr, sock,
+                sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_attr,
+                                      clock));
+    MECR_BSM_SET(mecr, sock,
+                sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_mem,
+                                      clock));
+  }
+
+  MECR = mecr;
+
+}
+
+/* sa1100_pcmcia_notifier()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^
+ * When changing the processor core clock frequency, it is necessary
+ * to adjust the MECR timings accordingly. We've recorded the timings
+ * requested by Card Services, so this is just a matter of finding
+ * out what our current speed is, and then recomputing the new MECR
+ * values.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int sa1100_pcmcia_notifier(struct notifier_block *nb,
+                                 unsigned long val, void *data){
+  struct cpufreq_info *ci = data;
+
+  switch(val){
+  case CPUFREQ_MINMAX:
+
+    break;
+
+  case CPUFREQ_PRECHANGE:
+
+    if(ci->new_freq > ci->old_freq){
+      DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating\n",
+           __FUNCTION__,
+           ci->new_freq / 1000, (ci->new_freq / 100) % 10,
+           ci->old_freq / 1000, (ci->old_freq / 100) % 10);
+      sa1100_pcmcia_update_mecr(ci->new_freq);
+    }
+
+    break;
+
+  case CPUFREQ_POSTCHANGE:
+
+    if(ci->new_freq < ci->old_freq){
+      DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating\n",
+           __FUNCTION__,
+           ci->new_freq / 1000, (ci->new_freq / 100) % 10,
+           ci->old_freq / 1000, (ci->old_freq / 100) % 10);
+      sa1100_pcmcia_update_mecr(ci->new_freq);
+    }
+
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unknown CPU frequency event %lx\n", __FUNCTION__,
+          val);
+    return -1;
+
+  }
+
+  return 0;
+
+}
+
+static struct notifier_block sa1100_pcmcia_notifier_block = {
+  notifier_call: sa1100_pcmcia_notifier
+};
+
+#endif
+
diff --git a/drivers/pcmcia/sa1100_graphicsclient.c b/drivers/pcmcia/sa1100_graphicsclient.c
new file mode 100644 (file)
index 0000000..0320d5c
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * drivers/pcmcia/sa1100_graphicsclient.c
+ *
+ * PCMCIA implementation routines for Graphics Client Plus
+ *
+ * 9/12/01   Woojung
+ *    Turn power OFF at startup
+ * 1/31/2001 Woojung Huh
+ *    Fix for GC Plus PCMCIA Reset Problem
+ * 2/27/2001 Woojung Huh [whuh@applieddata.net]
+ *    Fix
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+#define        S0_CD_IRQ               60                              // Socket 0 Card Detect IRQ
+#define        S0_STS_IRQ              55                              // Socket 0 PCMCIA IRQ
+
+static volatile unsigned long *PCMCIA_Status = 
+               ((volatile unsigned long *) ADS_p2v(_ADS_CS_STATUS));
+
+static volatile unsigned long *PCMCIA_Power = 
+               ((volatile unsigned long *) ADS_p2v(_ADS_CS_PR));
+
+static int gcplus_pcmcia_init(struct pcmcia_init *init)
+{
+  int irq, res;
+
+  // Reset PCMCIA
+  // Reset Timing for CPLD(U2) version 8001E or later
+  *PCMCIA_Power &= ~ ADS_CS_PR_A_RESET;
+  udelay(12);                  // 12 uSec
+
+  *PCMCIA_Power |= ADS_CS_PR_A_RESET;
+  mdelay(30);                  // 30 mSec
+
+  // Turn off 5V
+  *PCMCIA_Power &= ~0x03;
+
+  /* Register interrupts */
+  irq = S0_CD_IRQ;
+  res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
+  if (res < 0) {
+         printk(KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq);
+         return        -1;
+  }
+
+  return 1;                    // 1 PCMCIA Slot
+}
+
+static int gcplus_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( S0_CD_IRQ, NULL);
+  
+  /* Shutdown PCMCIA power */
+  mdelay(2);                                           // 2msec
+  *PCMCIA_Power &= ~0x03;
+
+  return 0;
+}
+
+static int gcplus_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array){
+  unsigned long levels;
+
+  if(state_array->size<1) return -1;
+
+  memset(state_array->state, 0, 
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=*PCMCIA_Status;
+
+  state_array->state[0].detect=(levels & ADS_CS_ST_A_CD)?1:0;
+  state_array->state[0].ready=(levels & ADS_CS_ST_A_READY)?1:0;
+  state_array->state[0].bvd1= 0;
+  state_array->state[0].bvd2= 0;
+  state_array->state[0].wrprot=0;
+  state_array->state[0].vs_3v=0;
+  state_array->state[0].vs_Xv=0;
+
+  return 1;
+}
+
+static int gcplus_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+       if (info->sock > 1)
+               return -1;
+
+       if (info->sock == 0)
+               info->irq = S0_STS_IRQ;
+
+       return 0;
+}
+
+static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  unsigned long flags;
+
+  if(configure->sock>1) return -1;
+
+  save_flags_cli(flags);
+
+  switch (configure->vcc) {
+  case 0:
+         *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+    break;
+
+  case 50:
+         *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+         *PCMCIA_Power |= ADS_CS_PR_A_5V_POWER;
+       break;
+
+  case 33:
+         *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+         *PCMCIA_Power |= ADS_CS_PR_A_3V_POWER;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+          configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  // Reset PCMCIA
+  *PCMCIA_Power &= ~ ADS_CS_PR_A_RESET;
+  udelay(12);
+
+  *PCMCIA_Power |= ADS_CS_PR_A_RESET;
+  mdelay(30);
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level gcplus_pcmcia_ops = { 
+  gcplus_pcmcia_init,
+  gcplus_pcmcia_shutdown,
+  gcplus_pcmcia_socket_state,
+  gcplus_pcmcia_get_irq_info,
+  gcplus_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_graphicsmaster.c b/drivers/pcmcia/sa1100_graphicsmaster.c
new file mode 100644 (file)
index 0000000..637be9d
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * drivers/pcmcia/sa1100_graphicsmaster.c
+ *
+ * PCMCIA implementation routines for GraphicsMaster
+ *
+ * 9/18/01 Woojung
+ *         Fixed wrong PCMCIA voltage setting
+ * 7/5/01 Woojung Huh <whuh@applieddata.net>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int graphicsmaster_pcmcia_init(struct pcmcia_init *init)
+{
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  /* Disable Power 3.3V/5V for PCMCIA/CF */
+  PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
+
+  INTPOL1 |= (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+                        (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+                (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+                (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+                (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+                (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+                         "GC Master PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+                         "GC Master CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "GC Master PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "GC Master CF (1) BVD1", NULL);
+
+  MECR = 0x09430943;
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int graphicsmaster_pcmcia_shutdown(void)
+{
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+                          (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+                  (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+                  (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int graphicsmaster_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int graphicsmaster_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int graphicsmaster_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+  switch(configure->sock){
+  case 0:
+
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio |= GPIO_GPIO0 | GPIO_GPIO1;
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+         gpio &= ~GPIO_GPIO0;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+         gpio |= GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      gpio |= GPIO_GPIO2 | GPIO_GPIO3;
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+         gpio &= ~GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+         gpio |= GPIO_GPIO2;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+            configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level graphicsmaster_pcmcia_ops = {
+  graphicsmaster_pcmcia_init,
+  graphicsmaster_pcmcia_shutdown,
+  graphicsmaster_pcmcia_socket_state,
+  graphicsmaster_pcmcia_get_irq_info,
+  graphicsmaster_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
new file mode 100644 (file)
index 0000000..b897776
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * drivers/pcmcia/sa1100_h3600.c
+ *
+ * PCMCIA implementation routines for H3600
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int h3600_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable CF bus: */
+  set_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON);
+  clr_h3600_egpio(EGPIO_H3600_OPT_RESET);
+
+  /* All those are inputs */
+  GPDR &= ~(GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1 | GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_H3600_PCMCIA_CD0;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_H3600_PCMCIA_CD1;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  return 2;
+
+irq_err:
+  printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
+  return -1;
+}
+
+static int h3600_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_H3600_PCMCIA_CD0, NULL );
+  free_irq( IRQ_GPIO_H3600_PCMCIA_CD1, NULL );
+  
+  /* Disable CF bus: */
+  clr_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON|EGPIO_H3600_OPT_ON);
+  set_h3600_egpio(EGPIO_H3600_OPT_RESET);
+
+  return 0;
+}
+
+static int h3600_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[0].detect=((levels & GPIO_H3600_PCMCIA_CD0)==0)?1:0;
+  state_array->state[0].ready=(levels & GPIO_H3600_PCMCIA_IRQ0)?1:0;
+  state_array->state[0].bvd1= 0;
+  state_array->state[0].bvd2= 0;
+  state_array->state[0].wrprot=0; /* Not available on H3600. */
+  state_array->state[0].vs_3v=0;
+  state_array->state[0].vs_Xv=0;
+
+  state_array->state[1].detect=((levels & GPIO_H3600_PCMCIA_CD1)==0)?1:0;
+  state_array->state[1].ready=(levels & GPIO_H3600_PCMCIA_IRQ1)?1:0;
+  state_array->state[1].bvd1=0;
+  state_array->state[1].bvd2=0;
+  state_array->state[1].wrprot=0; /* Not available on H3600. */
+  state_array->state[1].vs_3v=0;
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch (info->sock) {
+  case 0:
+    info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ0;
+    break;
+  case 1:
+    info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ1;
+    break;
+  default:
+    return -1;
+  }
+  return 0;
+}
+
+static int h3600_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  unsigned long flags;
+
+  if(configure->sock>1) return -1;
+
+  save_flags_cli(flags);
+
+  switch (configure->vcc) {
+  case 0:
+    clr_h3600_egpio(EGPIO_H3600_OPT_ON);
+    break;
+
+  case 33:
+  case 50:
+    set_h3600_egpio(EGPIO_H3600_OPT_ON);
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+          configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  if (configure->reset)
+    set_h3600_egpio(EGPIO_H3600_CARD_RESET);
+  else
+    clr_h3600_egpio(EGPIO_H3600_CARD_RESET);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level h3600_pcmcia_ops = { 
+  h3600_pcmcia_init,
+  h3600_pcmcia_shutdown,
+  h3600_pcmcia_socket_state,
+  h3600_pcmcia_get_irq_info,
+  h3600_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
new file mode 100644 (file)
index 0000000..071f550
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * drivers/pcmcia/sa1100_jornada720.c
+ *
+ * Jornada720 PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+#define SOCKET0_POWER   GPIO_GPIO0
+#define SOCKET0_3V      GPIO_GPIO2
+#define SOCKET1_POWER   (GPIO_GPIO1 | GPIO_GPIO3)
+#define SOCKET1_3V   GPIO_GPIO3
+
+static int jornada720_pcmcia_init(struct pcmcia_init *init)
+{
+  int return_val=0;
+
+  GRER |= 0x00000002;
+  /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR = 0;
+  PA_DWR = 0;
+  PA_SDR = 0;
+  PA_SSR = 0;
+
+  PB_DDR = 0;
+  PB_DWR = 0x01;
+  PB_SDR = 0;
+  PB_SSR = 0;
+
+  PC_DDR = 0x88;
+  PC_DWR = 0x20;
+  PC_SDR = 0;
+  PC_SSR = 0;
+
+  INTPOL1 |=
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+                         "Jornada720 PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+                         "Jornada720 CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "Jornada720 PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "Jornada720 CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int jornada720_pcmcia_shutdown(void)
+{
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &=
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int jornada720_pcmcia_socket_state(struct pcmcia_state_array
+                                       *state_array)
+{
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+        (state_array->size)*sizeof(struct pcmcia_state));
+  status=PCSR;
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+  return return_val;
+}
+
+static int jornada720_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+  return 0;
+}
+
+static int jornada720_pcmcia_configure_socket(const struct pcmcia_configure
+                                           *configure)
+{
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
+              configure->sock, configure->vcc, configure->vpp);
+  switch(configure->sock){
+  case 0:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio&=~(SOCKET0_POWER | SOCKET0_3V);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio |= SOCKET0_POWER | SOCKET0_3V;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio = (gpio & ~SOCKET0_3V) | SOCKET0_POWER;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+    switch(configure->vpp){
+    case 0:
+      break;
+    case 50:
+       printk(KERN_ERR "%s(): 5.0 Vpp %u\n", __FUNCTION__,
+              configure->vpp);
+      break;
+    case 120:
+       printk(KERN_ERR "%s(): 12 Vpp %u\n", __FUNCTION__,
+              configure->vpp);
+      break;
+    default:
+       printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+              configure->vpp);
+       return -1;
+    }
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      gpio &= ~(SOCKET1_POWER);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio |= SOCKET1_POWER;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio = (gpio & ~(SOCKET1_POWER)) | SOCKET1_POWER;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+            configure->vpp);
+      return -1;
+    }
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+    break;
+  default:
+    return -1;
+  }
+  PCCR = pccr;
+  PA_DWR = gpio;
+  return 0;
+}
+
+struct pcmcia_low_level jornada720_pcmcia_ops = {
+  jornada720_pcmcia_init,
+  jornada720_pcmcia_shutdown,
+  jornada720_pcmcia_socket_state,
+  jornada720_pcmcia_get_irq_info,
+  jornada720_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
new file mode 100644 (file)
index 0000000..ff5a36c
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * drivers/pcmcia/sa1100_neponset.c
+ *
+ * Neponset PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int neponset_pcmcia_init(struct pcmcia_init *init){
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  
+  /* MAX1600 to standby mode: */
+  PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
+
+  INTPOL1 |= 
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+                         "Neponset PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+                         "Neponset CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "Neponset PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "Neponset CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int neponset_pcmcia_shutdown(void){
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= 
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int neponset_pcmcia_socket_state(struct pcmcia_state_array
+                                       *state_array){
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int neponset_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int neponset_pcmcia_configure_socket(const struct pcmcia_configure
+                                           *configure){
+  unsigned long pccr=PCCR, ncr=NCR_0, gpio=PA_DWR;
+
+  /* Neponset uses the Maxim MAX1600, with the following connections:
+   *
+   *   MAX1600      Neponset
+   *
+   *    A0VCC        SA-1111 GPIO A<1>
+   *    A1VCC        SA-1111 GPIO A<0>
+   *    A0VPP        CPLD NCR A0VPP
+   *    A1VPP        CPLD NCR A1VPP
+   *    B0VCC        SA-1111 GPIO A<2>
+   *    B1VCC        SA-1111 GPIO A<3>
+   *    B0VPP        ground (slot B is CF)
+   *    B1VPP        ground (slot B is CF)
+   *
+   *     VX          VCC (5V)
+   *     VY          VCC3_3 (3.3V)
+   *     12INA       12V
+   *     12INB       ground (slot B is CF)
+   *
+   * The MAX1600 CODE pin is tied to ground, placing the device in 
+   * "Standard Intel code" mode. Refer to the Maxim data sheet for
+   * the corresponding truth table.
+   */
+
+  switch(configure->sock){
+  case 0:
+    
+    switch(configure->vcc){
+    case 0:
+      pccr=(pccr & ~PCCR_S0_FLT);
+      gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    switch(configure->vpp){
+    case 0:
+      ncr&=~(NCR_A0VPP | NCR_A1VPP);
+      break;
+
+    case 120:
+      ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A1VPP;
+      break;
+
+    default:
+      if(configure->vpp == configure->vcc)
+       ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A0VPP;
+      else {
+       printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+              configure->vpp);
+       return -1;
+      }
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr=(pccr & ~PCCR_S1_FLT);
+      gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+            configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  NCR_0 = ncr;
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level neponset_pcmcia_ops = { 
+  neponset_pcmcia_init,
+  neponset_pcmcia_shutdown,
+  neponset_pcmcia_socket_state,
+  neponset_pcmcia_get_irq_info,
+  neponset_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_pangolin.c b/drivers/pcmcia/sa1100_pangolin.c
new file mode 100644 (file)
index 0000000..9e68e50
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * drivers/pcmcia/sa1100_pangolin.c
+ *
+ * PCMCIA implementation routines for Pangolin
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int pangolin_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* set GPIO_PCMCIA_CD & GPIO_PCMCIA_IRQ as inputs */
+  GPDR &= ~(GPIO_PCMCIA_CD|GPIO_PCMCIA_IRQ);
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  /* set GPIO pins GPIO_PCMCIA_BUS_ON & GPIO_PCMCIA_RESET as output */
+  GPDR |= (GPIO_PCMCIA_BUS_ON|GPIO_PCMCIA_RESET);
+  /* Enable PCMCIA bus: */
+  GPCR = GPIO_PCMCIA_BUS_ON;
+#else
+  /* set GPIO pin GPIO_PCMCIA_RESET as output */
+  GPDR |= GPIO_PCMCIA_RESET;
+#endif
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_PCMCIA_CD, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_PCMCIA_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_PCMCIA_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int pangolin_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_PCMCIA_CD, NULL );
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+    /* Disable PCMCIA bus: */
+    GPSR = GPIO_PCMCIA_BUS_ON;
+#endif
+  return 0;
+}
+
+static int pangolin_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  state_array->state[1].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+  state_array->state[1].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+  state_array->state[1].bvd1=1; /* Not available on Pangolin. */
+  state_array->state[1].bvd2=1; /* Not available on Pangolin. */
+  state_array->state[1].wrprot=0; /* Not available on Pangolin. */
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Pangolin. */
+  state_array->state[1].vs_Xv=0;
+#else
+  state_array->state[0].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+  state_array->state[0].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+  state_array->state[0].bvd1=1; /* Not available on Pangolin. */
+  state_array->state[0].bvd2=1; /* Not available on Pangolin. */
+  state_array->state[0].wrprot=0; /* Not available on Pangolin. */
+  state_array->state[0].vs_3v=0;  /* voltage level is determined by jumper setting */
+  state_array->state[0].vs_Xv=0;
+#endif
+  return 1;
+}
+
+static int pangolin_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  if(info->sock==1)
+       info->irq=IRQ_PCMCIA_IRQ;
+#else
+  if(info->sock==0)
+        info->irq=IRQ_PCMCIA_IRQ;
+#endif
+  return 0;
+}
+
+static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  if(configure->sock==0) return 0;
+#endif
+  save_flags_cli(flags);
+
+  /* Murphy: BUS_ON different from POWER ? */
+
+  switch(configure->vcc){
+  case 0:
+    break;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+          __FUNCTION__);
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+    break;
+#else
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, determinded by jumper setting...\n", __FUNCTION__);
+    break;
+  case 33:
+    printk(KERN_WARNING "%s(): CS asked for 3.3V, determined by jumper setting...\n", __FUNCTION__);
+    break;
+#endif
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+          configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+#ifdef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  /* reset & unreset request */
+  if(configure->sock==0) {
+       if(configure->reset) {
+               GPSR |= GPIO_PCMCIA_RESET;
+       } else {
+               GPCR |= GPIO_PCMCIA_RESET;
+       }
+  }
+#endif
+  /* Silently ignore Vpp, output enable, speaker enable. */
+  restore_flags(flags);
+  return 0;
+}
+
+struct pcmcia_low_level pangolin_pcmcia_ops = { 
+  pangolin_pcmcia_init,
+  pangolin_pcmcia_shutdown,
+  pangolin_pcmcia_socket_state,
+  pangolin_pcmcia_get_irq_info,
+  pangolin_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_pfs168.c b/drivers/pcmcia/sa1100_pfs168.c
new file mode 100644 (file)
index 0000000..ce9128c
--- /dev/null
@@ -0,0 +1,237 @@
+#warning       "REVISIT_PFS168: Need to verify and test GPIO power encodings."
+/*
+ * drivers/pcmcia/sa1100_pfs168.c
+ *
+ * PFS168 PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int pfs168_pcmcia_init(struct pcmcia_init *init){
+  int return_val=0;
+
+  /* TPS2211 to standby mode: */
+  PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA (socket 0) power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  INTPOL1 |=
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+                         "PFS168 PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+                         "PFS168 CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "PFS168 PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "PFS168 CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int pfs168_pcmcia_shutdown(void){
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &=
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int pfs168_pcmcia_socket_state(struct pcmcia_state_array
+                                       *state_array){
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int pfs168_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int pfs168_pcmcia_configure_socket(const struct pcmcia_configure
+                                           *configure){
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+  /* PFS168 uses the Texas Instruments TPS2211 for PCMCIA (socket 0) voltage control only,
+   * with the following connections:
+   *
+   *   TPS2211      PFS168
+   *
+   *    -VCCD0      SA-1111 GPIO A<0>
+   *    -VCCD0      SA-1111 GPIO A<1>
+   *     VPPD0      SA-1111 GPIO A<2>
+   *     VPPD0      SA-1111 GPIO A<2>
+   *
+   */
+
+  switch(configure->sock){
+  case 0:
+
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    switch(configure->vpp){
+    case 0:
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 120:
+      printk(KERN_ERR "%s(): PFS-168 does not support Vpp %uV\n", __FUNCTION__,
+            configure->vpp/10);
+      return -1;
+      break;
+
+    default:
+      if(configure->vpp == configure->vcc)
+        gpio = (gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+      else {
+       printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+              configure->vpp);
+       return -1;
+      }
+    }
+
+    pccr = (configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    PA_DWR = gpio;
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      break;
+
+    case 50:
+      printk(KERN_ERR "%s(): PFS-168 CompactFlash socket does not support Vcc %uV\n", __FUNCTION__,
+            configure->vcc/10);
+      return -1;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CompactFlash socket does not support Vpp %uV\n", __FUNCTION__,
+            configure->vpp/10);
+      return -1;
+    }
+
+    pccr = (configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+
+  return 0;
+}
+
+struct pcmcia_low_level pfs168_pcmcia_ops = {
+  pfs168_pcmcia_init,
+  pfs168_pcmcia_shutdown,
+  pfs168_pcmcia_socket_state,
+  pfs168_pcmcia_get_irq_info,
+  pfs168_pcmcia_configure_socket
+};
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
new file mode 100644 (file)
index 0000000..84c7e2d
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * drivers/pcmcia/sa1100_pangolin.c
+ *
+ * PCMCIA implementation routines for simpad
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int simpad_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* set GPIO_CF_CD & GPIO_CF_IRQ as inputs */
+  GPDR &= ~(GPIO_CF_CD|GPIO_CF_IRQ);
+  //init_simpad_cs3();
+  printk("\nCS3:%x\n",cs3_shadow);
+  PCMCIA_setbit(PCMCIA_RESET);
+  PCMCIA_clearbit(PCMCIA_BUFF_DIS);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_CF_CD, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int simpad_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_CF_CD, NULL );
+
+  /* Disable CF bus: */
+
+  PCMCIA_setbit(PCMCIA_BUFF_DIS);
+  PCMCIA_clearbit(PCMCIA_RESET);
+  return 0;
+}
+
+static int simpad_pcmcia_socket_state(struct pcmcia_state_array
+                                      *state_array)
+{
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+  state_array->state[1].bvd1=1; /* Not available on Simpad. */
+
+  state_array->state[1].bvd2=1; /* Not available on Simpad. */
+
+  state_array->state[1].wrprot=0; /* Not available on Simpad. */
+
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Simpad. */
+
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==1)
+    info->irq=IRQ_GPIO_CF_IRQ;
+
+  return 0;
+}
+
+static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
+                                          *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==0) return 0;
+
+  save_flags_cli(flags);
+
+  /* Murphy: BUS_ON different from POWER ? */
+
+  switch(configure->vcc){
+  case 0:
+    PCMCIA_setbit(PCMCIA_BUFF_DIS);
+    break;
+
+  case 33:
+  case 50:
+    PCMCIA_setbit(PCMCIA_BUFF_DIS);
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+          configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level simpad_pcmcia_ops = {
+  simpad_pcmcia_init,
+  simpad_pcmcia_shutdown,
+  simpad_pcmcia_socket_state,
+  simpad_pcmcia_get_irq_info,
+  simpad_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_stork.c b/drivers/pcmcia/sa1100_stork.c
new file mode 100644 (file)
index 0000000..a5cc427
--- /dev/null
@@ -0,0 +1,202 @@
+/* 
+ * drivers/pcmcia/sa1100_stork.c
+ *
+    Copyright 2001 (C) Ken Gordon
+
+    This is derived from pre-existing drivers/pcmcia/sa1100_?????.c
+
+    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.
+
+    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.
+
+ * 
+ * PCMCIA implementation routines for stork
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int debug = 0;
+
+static struct pcmcia_init sa1100_stork_pcmcia_init;
+
+static int stork_pcmcia_init(struct pcmcia_init *init)
+{
+        int irq, res;
+        printk("in stork_pcmcia_init\n");
+
+        sa1100_stork_pcmcia_init = *init;
+
+        /* Enable CF bus: */
+        storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+
+        /* All those are inputs */
+       GPDR &= ~(GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT | GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY);
+
+       /* Set transition detect */
+       set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES );
+        set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );
+
+       /* Register interrupts */
+       irq = IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT;
+       res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
+       if( res < 0 ) goto irq_err;
+       irq = IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT;
+       res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
+       if( res < 0 ) goto irq_err;
+
+        return 2;
+
+ irq_err:
+        printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
+        return -1;
+}
+
+static int stork_pcmcia_shutdown(void)
+{
+        printk(__FUNCTION__ "\n");
+        /* disable IRQs */
+        free_irq( IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, NULL );
+        free_irq( IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, NULL );
+  
+        /* Disable CF bus: */
+        storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+       storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
+       storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
+        return 0;
+}
+
+static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+        unsigned long levels;
+
+        if(state_array->size<2) return -1;
+
+        memset(state_array->state, 0, 
+               (state_array->size)*sizeof(struct pcmcia_state));
+
+        levels=GPLR;
+
+       if (debug > 1)
+               printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
+       state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
+       state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
+       state_array->state[0].bvd1= 1;
+       state_array->state[0].bvd2= 1;
+       state_array->state[0].wrprot=0;
+       state_array->state[0].vs_3v=1;
+       state_array->state[0].vs_Xv=0;
+
+       state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
+       state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
+       state_array->state[1].bvd1=1;
+       state_array->state[1].bvd2=1;
+       state_array->state[1].wrprot=0;
+       state_array->state[1].vs_3v=1;
+       state_array->state[1].vs_Xv=0;
+
+        return 1;
+}
+
+static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+        switch (info->sock) {
+        case 0:
+                info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
+                break;
+        case 1:
+                info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
+                break;
+        default:
+                return -1;
+        }
+        return 0;
+}
+
+static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+        int card = configure->sock;
+       unsigned long flags;
+
+        int DETECT, RDY, POWER, RESET;
+
+        if (card > 1) return -1;
+
+       printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n", 
+                       card, configure->vcc, configure->vpp, configure->reset);
+
+       save_flags_cli(flags);
+
+        if (card == 0) {
+           DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
+           RDY = GPIO_STORK_PCMCIA_A_RDY;
+           POWER = STORK_PCMCIA_A_POWER_ON;
+           RESET = STORK_PCMCIA_A_RESET;
+        } else {
+           DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
+           RDY = GPIO_STORK_PCMCIA_B_RDY;
+           POWER = STORK_PCMCIA_B_POWER_ON;
+           RESET = STORK_PCMCIA_B_RESET;
+        }
+    
+/*
+        if (storkTestGPIO(DETECT)) {
+           printk("no card detected - but resetting anyway\r\n");
+        }
+*/
+       switch (configure->vcc) {
+       case 0:
+               storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+                storkClearLatchA(POWER);
+               break;
+
+       case 50:
+       case 33:
+                storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+                storkSetLatchA(POWER);
+               break;
+
+       default:
+               printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+                      configure->vcc);
+               restore_flags(flags);
+               return -1;
+       }
+
+       if (configure->reset)
+                storkSetLatchB(RESET);
+       else
+                storkClearLatchB(RESET);
+
+       restore_flags(flags);
+
+        /* silently ignore vpp and speaker enables. */
+
+        printk(__FUNCTION__ ": finished\n");
+
+        return 0;
+}
+
+struct pcmcia_low_level stork_pcmcia_ops = { 
+        stork_pcmcia_init,
+        stork_pcmcia_shutdown,
+        stork_pcmcia_socket_state,
+        stork_pcmcia_get_irq_info,
+        stork_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_xp860.c b/drivers/pcmcia/sa1100_xp860.c
new file mode 100644 (file)
index 0000000..cd92680
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * drivers/pcmcia/sa1100_xp860.c
+ *
+ * XP860 PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+#define NCR_A0VPP      (1<<16)
+#define NCR_A1VPP      (1<<17)
+
+static int xp860_pcmcia_init(struct pcmcia_init *init){
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  
+  /* MAX1600 to standby mode: */
+  PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  GPDR |= (NCR_A0VPP | NCR_A1VPP);
+  GPCR &= ~(NCR_A0VPP | NCR_A1VPP);
+
+  INTPOL1 |= 
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+                         "XP860 PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+                         "XP860 CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "XP860 PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+                         "XP860 CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int xp860_pcmcia_shutdown(void){
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= 
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int xp860_pcmcia_socket_state(struct pcmcia_state_array
+                                       *state_array){
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+        (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int xp860_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int xp860_pcmcia_configure_socket(const struct pcmcia_configure
+                                           *configure){
+  unsigned long pccr=PCCR, ncr=GPLR, gpio=PA_DWR;
+
+
+  /* Neponset uses the Maxim MAX1600, with the following connections:
+   *
+   *   MAX1600      Neponset
+   *
+   *    A0VCC        SA-1111 GPIO A<1>
+   *    A1VCC        SA-1111 GPIO A<0>
+   *    A0VPP        CPLD NCR A0VPP
+   *    A1VPP        CPLD NCR A1VPP
+   *    B0VCC        SA-1111 GPIO A<2>
+   *    B1VCC        SA-1111 GPIO A<3>
+   *    B0VPP        ground (slot B is CF)
+   *    B1VPP        ground (slot B is CF)
+   *
+   *     VX          VCC (5V)
+   *     VY          VCC3_3 (3.3V)
+   *     12INA       12V
+   *     12INB       ground (slot B is CF)
+   *
+   * The MAX1600 CODE pin is tied to ground, placing the device in 
+   * "Standard Intel code" mode. Refer to the Maxim data sheet for
+   * the corresponding truth table.
+   */
+
+  switch(configure->sock){
+  case 0:
+    
+    switch(configure->vcc){
+    case 0:
+      gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S0_PSE);
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S0_PSE);
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    switch(configure->vpp){
+    case 0:
+      ncr&=~(NCR_A0VPP | NCR_A1VPP);
+      break;
+
+    case 120:
+      ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A1VPP;
+      break;
+
+    default:
+      if(configure->vpp == configure->vcc)
+       ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A0VPP;
+      else {
+       printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+              configure->vpp);
+       return -1;
+      }
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+    pccr=(configure->output)?(pccr | PCCR_S0_FLT):(pccr & ~PCCR_S0_FLT);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S1_PSE);
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S1_PSE);
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+            configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+            configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+    pccr=(configure->output)?(pccr | PCCR_S1_FLT):(pccr & ~PCCR_S1_FLT);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  ncr &= NCR_A0VPP|NCR_A1VPP;
+  GPSR = ncr;
+  GPCR = (~ncr)&(NCR_A0VPP|NCR_A1VPP);
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level xp860_pcmcia_ops = { 
+  xp860_pcmcia_init,
+  xp860_pcmcia_shutdown,
+  xp860_pcmcia_socket_state,
+  xp860_pcmcia_get_irq_info,
+  xp860_pcmcia_configure_socket
+};
+
diff --git a/drivers/pcmcia/sa1100_yopy.c b/drivers/pcmcia/sa1100_yopy.c
new file mode 100644 (file)
index 0000000..25d502d
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * drivers/pcmcia/sa1100_yopy.c
+ *
+ * PCMCIA implementation routines for Yopy
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static inline void pcmcia_power(int on) {
+       /* high for power up */
+       yopy_gpio_set(GPIO_CF_POWER, on);
+}
+
+static inline void pcmcia_reset(int reset)
+{
+       /* high for reset */
+       yopy_gpio_set(GPIO_CF_RESET, reset);
+}
+
+static int yopy_pcmcia_init(struct pcmcia_init *init)
+{
+       int irq, res;
+
+       pcmcia_power(0);
+       pcmcia_reset(1);
+
+       /* All those are inputs */
+       GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);
+       GAFR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);
+
+       /* Set transition detect */
+       set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
+                          GPIO_BOTH_EDGES );
+       set_GPIO_IRQ_edge( GPIO_CF_IREQ, GPIO_FALLING_EDGE );
+
+       /* Register interrupts */
+       irq = IRQ_CF_CD;
+       res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_CD", NULL);
+       if (res < 0) goto irq_err;
+       irq = IRQ_CF_BVD2;
+       res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL);
+       if (res < 0) goto irq_err;
+       irq = IRQ_CF_BVD1;
+       res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL);
+       if (res < 0) goto irq_err;
+
+       return 1;
+irq_err:
+       printk(KERN_ERR "%s: Request for IRQ %d failed\n", __FUNCTION__, irq);
+       return -1;
+}
+
+static int yopy_pcmcia_shutdown(void)
+{
+       /* disable IRQs */
+       free_irq( IRQ_CF_CD, NULL );
+       free_irq( IRQ_CF_BVD2, NULL );
+       free_irq( IRQ_CF_BVD1, NULL );
+
+       /* Disable CF */
+       pcmcia_reset(1);
+       pcmcia_power(0);
+
+       return 0;
+}
+
+static int yopy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+       unsigned long levels;
+
+       if (state_array->size != 1)
+               return -1;
+
+       memset(state_array->state, 0,
+              state_array->size * sizeof(struct pcmcia_state));
+
+       levels = GPLR;
+
+       state_array->state[0].detect = (levels & GPIO_CF_CD)    ? 0 : 1;
+       state_array->state[0].ready  = (levels & GPIO_CF_READY) ? 1 : 0;
+       state_array->state[0].bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
+       state_array->state[0].bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
+       state_array->state[0].wrprot = 0; /* Not available on Yopy. */
+       state_array->state[0].vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
+       state_array->state[0].vs_Xv  = 0;
+
+       return 1;
+}
+
+static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+       if (info->sock != 0)
+               return -1;
+
+       info->irq = IRQ_CF_IREQ;
+
+       return 0;
+}
+
+static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+       if (configure->sock != 0)
+               return -1;
+
+       switch (configure->vcc) {
+       case 0: /* power off */;
+               pcmcia_power(0);
+               break;
+       case 50:
+               printk(KERN_WARNING __FUNCTION__"(): CS asked for 5V, applying 3.3V..\n");
+       case 33:
+               pcmcia_power(1);
+               break;
+       default:
+               printk(KERN_ERR __FUNCTION__"(): unrecognized Vcc %u\n",
+                      configure->vcc);
+               return -1;
+       }
+
+       pcmcia_reset(configure->reset);
+
+       /* Silently ignore Vpp, output enable, speaker enable. */
+
+       return 0;
+}
+
+struct pcmcia_low_level yopy_pcmcia_ops = {
+       yopy_pcmcia_init,
+       yopy_pcmcia_shutdown,
+       yopy_pcmcia_socket_state,
+       yopy_pcmcia_get_irq_info,
+       yopy_pcmcia_configure_socket
+};
index 4ba4f51155691a61381819c4edc3aee87fc65e13..14956faee5db5a38db337ed1b6906cd025d67258 100644 (file)
@@ -87,6 +87,7 @@ MODULE_PARM(isapnp_reserve_io, "1-16i");
 MODULE_PARM_DESC(isapnp_reserve_io, "ISA Plug & Play - reserve I/O region(s) - port,size");
 MODULE_PARM(isapnp_reserve_mem, "1-16i");
 MODULE_PARM_DESC(isapnp_reserve_mem, "ISA Plug & Play - reserve memory region(s) - address,size");
+MODULE_LICENSE("GPL");
 
 #define _PIDXR         0x279
 #define _PNPWRP                0xa79
@@ -1673,8 +1674,8 @@ static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx)
        }
        isapnp_for_each_dev(dev) {
                if (dev->active) {
-                       if (dev->irq_resource[0].start == irq ||
-                           dev->irq_resource[1].start == irq)
+                       if ((dev->irq_resource[0].flags && dev->irq_resource[0].start == irq) ||
+                           (dev->irq_resource[1].flags && dev->irq_resource[1].start == irq))
                                return 1;
                }
        }
@@ -1763,7 +1764,8 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
        }
        isapnp_for_each_dev(dev) {
                if (dev->active) {
-                       if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma)
+                       if ((dev->dma_resource[0].flags && dev->dma_resource[0].start == dma) ||
+                           (dev->dma_resource[1].flags && dev->dma_resource[1].start == dma))
                                return 1;
                }
        }
@@ -1784,6 +1786,10 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
 
 static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
 {
+       /* DMA priority: this table is good for i386 */
+       static unsigned short xtab[16] = {
+               1, 3, 5, 6, 7, 0, 2, 4
+       };
        int err, i;
        unsigned long *value1, *value2;
        struct isapnp_dma *dma;
@@ -1799,15 +1805,16 @@ static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
        value1 = &cfg->result.dma_resource[idx].start;
        value2 = &cfg->result.dma_resource[idx].end;
        if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
-               for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);
+               for (i = 0; i < 8 && !(dma->map & (1<<xtab[i])); i++);
                if (i >= 8)
                        return -ENOENT;
                cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
-               if (!isapnp_check_dma(cfg, *value1 = *value2 = i, idx))
+               if (!isapnp_check_dma(cfg, *value1 = *value2 = xtab[i], idx))
                        return 0;
        }
        do {
-               for (i = *value1 + 1; i < 8 && !(dma->map & (1<<i)); i++);
+               for (i = 0; i < 8 && xtab[i] != *value1; i++);
+               for (i++; i < 8 && !(dma->map & (1<<xtab[i])); i++);
                if (i >= 8) {
                        if (dma->res && dma->res->alt) {
                                if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)
@@ -1816,7 +1823,7 @@ static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
                        }
                        return -ENOENT;
                } else {
-                       *value1 = *value2 = i;
+                       *value1 = *value2 = xtab[i];
                }
        } while (isapnp_check_dma(cfg, *value1, idx));
        return 0;
index 241bb3bea9598b17a22be0fbfaee2ffc5c47a99a..1e7d342ecc2a47a14899f5b609e2f31943df021f 100644 (file)
@@ -1092,9 +1092,11 @@ dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* devi
                BUG ();
                }
         if (device->lowmem_cqr==NULL) {
-                DASD_MESSAGE (KERN_WARNING, device, 
-                              "Low memory! Using emergency request %p",
-                              device->lowmem_ccws);
+                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
+                                         "(%04x) Low memory! Using emergency request %p.",
+                                         device->devinfo.devno,
+                                         device->lowmem_ccws);
+
                 device->lowmem_cqr=device->lowmem_ccws;
                 rv = device->lowmem_ccws;
                memset (rv, 0, PAGE_SIZE);
@@ -1105,10 +1107,11 @@ dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* devi
                rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
                rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
         } else {
-                DASD_MESSAGE (KERN_WARNING, device,
-                              "Refusing emergency mem for request "
-                              "NULL, already in use at %p.",
-                              device->lowmem_ccws);
+                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
+                                         "(%04x) Refusing emergency mem for request "
+                                         "NULL, already in use at %p.",
+                                         device->devinfo.devno,
+                                         device->lowmem_ccws);
        }
        return rv;
 }
@@ -1219,6 +1222,7 @@ dasd_chanq_enq (dasd_chanq_t * q, ccw_req_t * cqr)
                         CQR_STATUS_QUEUED);
 
        
+#ifdef DASD_PROFILE
         /* save profile information for non erp cqr */
         if (cqr->refers == NULL) {
                 unsigned int  counter = 0;
@@ -1235,6 +1239,7 @@ dasd_chanq_enq (dasd_chanq_t * q, ccw_req_t * cqr)
                 dasd_global_profile.dasd_io_nr_req[counter]++;
                 device->profile.dasd_io_nr_req[counter]++;
         }
+#endif 
 }
 
 /*
@@ -1671,9 +1676,12 @@ dasd_process_queues (dasd_device_t * device)
                    chanq_max_size > 0 || (req->nr_sectors >= chanq_min_size)) {
                        ccw_req_t *cqr = NULL;
                         if (is_read_only(device->kdev) && req->cmd == WRITE) {
-                            DASD_MESSAGE (KERN_WARNING, device,
-                                          "rejecting write request %p\n",
-                                          req);
+
+                                DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
+                                                         "(%04x) Rejecting write request %p\n",
+                                                         device->devinfo.devno,
+                                                         req);
+
                                 dasd_end_request (req, 0);
                                 dasd_dequeue_request (queue,req);
                         } else {
@@ -1683,9 +1691,12 @@ dasd_process_queues (dasd_device_t * device)
                                 part[MINOR (req->rq_dev)].start_sect;
                             cqr = device->discipline->build_cp_from_req (device, req);
                             if (cqr == NULL) {
-                                   DASD_MESSAGE (KERN_WARNING, device,
-                                                  "CCW creation failed on request %p\n",
-                                                  req);
+
+                                    DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
+                                                             "(%04x) CCW creation failed "
+                                                             "on request %p\n",
+                                                             device->devinfo.devno,
+                                                             req);
                                     /* revert relocation of request */
                                     req->sector -=
                                         device->major_info->gendisk.
@@ -2032,7 +2043,7 @@ dasd_default_erp_action (ccw_req_t * cqr)
        }
 
        erp->cpaddr->cmd_code = CCW_CMD_TIC;
-       erp->cpaddr->cda = (__u32) (void *) cqr->cpaddr;
+       erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
        erp->function = dasd_default_erp_action;
        erp->refers = cqr;
        erp->device = cqr->device;
@@ -2232,13 +2243,7 @@ dasd_revalidate (dasd_device_t * device)
        }
        for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) {
                 int major = device->major_info->gendisk.major;
-               int minor = start + i;
-               kdev_t devi = MKDEV (major, minor);
-               struct super_block *sb = get_super (devi);
-               //sync_dev (devi);
-               if (sb)
-                       invalidate_inodes (sb);
-               invalidate_buffers (devi);
+               invalidate_device(MKDEV (major, start+i), 1);
        }
         dasd_destroy_partitions(device);
         dasd_setup_partitions(device);
@@ -2285,20 +2290,20 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data)
 #endif
        switch (no) {
         case DASDAPIVER: {
-                       int ver = DASD_API_VERSION;
-                       rc = copy_to_user ((int *) data, &ver, sizeof (int));
-                       if (rc)
-                               rc = -EFAULT;
-                       break;
+                       int ver = DASD_API_VERSION;
+                       rc = put_user(ver, (int *) data);
+                       break;
         }
        case BLKGETSIZE:{       /* Return device size */
                        long blocks = major_info->gendisk.sizes 
                                       [MINOR (inp->i_rdev)] << 1;
-                       rc =
-                           copy_to_user ((long *) data, &blocks,
-                                         sizeof (long));
-                       if (rc)
-                               rc = -EFAULT;
+                       rc = put_user(blocks, (long *) data);
+                       break;
+               }
+       case BLKGETSIZE64:{
+                       u64 blocks = major_info->gendisk.sizes 
+                                      [MINOR (inp->i_rdev)];
+                       rc = put_user(blocks << 10, (u64 *) data);
                        break;
                }
        case BLKRRPART:{
@@ -3253,10 +3258,6 @@ dasd_state_accept_to_init (dasd_device_t *device)
         int rc = 0;
         unsigned long flags;
 
-        printk (KERN_ERR PRINTK_HEADER
-                "called dasd_state_accept_to_init for device %02x\n",
-                device->devinfo.devno);
-
         if ( device->discipline->init_analysis ) {
                 device->init_cqr=device->discipline->init_analysis (device);
                 if ( device->init_cqr != NULL ) {
@@ -3297,8 +3298,10 @@ dasd_state_init_to_ready (dasd_device_t *device )
                                 rc = -EMEDIUMTYPE;
                         }
         if ( device->init_cqr ) {
+                /* This pointer is no longer needed, BUT dont't free the       */ 
+                /* memory, because this is done in bh for finished request!!!! */
                 atomic_dec(&dasd_init_pending);
-                device->init_cqr = NULL; /* This one is no longer needed */
+                device->init_cqr = NULL; 
         }
         device->level = DASD_STATE_READY;
         return rc;
@@ -3378,7 +3381,6 @@ static void
 dasd_deactivate_queue (dasd_device_t *device)
 {
         int i;
-        int major = MAJOR(device->kdev);
         int minor = MINOR(device->kdev);
 
         for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
@@ -3764,7 +3766,14 @@ dasd_devices_write (struct file *file, const char *user_buf,
                vfree (buffer);
                return -EFAULT;
        }
-       buffer[user_len] = 0;
+
+        /* replace LF with '\0' */
+        if (buffer[user_len -1] == '\n') {
+                buffer[user_len -1] = '\0';
+        } else {
+                buffer[user_len] = '\0';
+        }
+
        printk (KERN_INFO PRINTK_HEADER "/proc/dasd/devices: '%s'\n", buffer);
        if (strncmp (buffer, "set ", 4) && strncmp (buffer, "add ", 4)) {
                printk (KERN_WARNING PRINTK_HEADER
@@ -3798,7 +3807,7 @@ dasd_devices_write (struct file *file, const char *user_buf,
             range.to   == -EINVAL   ) {
                 
                 printk (KERN_WARNING PRINTK_HEADER
-                        "/proc/dasd/devices: parse error in '%s'", 
+                        "/proc/dasd/devices: range parse error in '%s'\n", 
                         buffer);
         } else {
                 off = (long) temp - (long) buffer;
@@ -3814,7 +3823,8 @@ dasd_devices_write (struct file *file, const char *user_buf,
                                 dasd_disable_ranges (&range, NULL, 0, 1);
                         } else {
                                 printk (KERN_WARNING PRINTK_HEADER
-                                        "/proc/dasd/devices: parse error in '%s'", buffer);
+                                        "/proc/dasd/devices: parse error in '%s'\n",
+                                        buffer);
                         }
                 }
         }
index 4ba50f2f68e934886253ac8ab8b6c1df6ccea5b1..912cd2db5bac81050af67a9496981f4bcfe77999 100644 (file)
@@ -761,7 +761,7 @@ dasd_3990_erp_action_5 (ccw_req_t *erp)
  * DASD_3990_HANDLE_ENV_DATA
  *
  * DESCRIPTION
- *   Handles 24 byte 'Enviromental data present'.
+ *   Handles 24 byte 'Environmental data present'.
  *   Does a analysis of the sense data (message Format)
  *   and prints the error messages.
  *
index 09ba9adf7791c7cbd4973f10062744c4b6a40fa7..7fc15b395eb8bf631b4cece6c691234b2652df94 100644 (file)
@@ -5,6 +5,7 @@
 O_TARGET := s390-char.o
 
 list-multi     := tub3270.o tape390.o
+export-objs    := hwc_rw.o
 
 tub3270-objs := tuball.o tubfs.o tubtty.o \
                      tubttyaid.o tubttybld.o tubttyscl.o \
index 80eeb58e7366a848b374e88f75fae0b8ba221537..621196dacc2119c2cd28abc5bdbcb4528cf08b4b 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/semaphore.h>
 #include <asm/ebcdic.h>
index cf6754a99cde6dc21c6c6f606d1a461e16954e3b..b62700a7f7954d6421076c14f643bee247031ced 100644 (file)
@@ -1670,7 +1670,7 @@ tape34xx_rfo_init_done (tape_info_t * ti)
        tapestate_set (ti, TS_DONE);
        ti->rc = 0;
        ti->wanna_wakeup=1;
-       wake_up_interruptible (&ti->wq);
+       wake_up (&ti->wq);
 }
 
 void
@@ -2274,6 +2274,8 @@ void tape34xx_error_recovery_has_failed (tape_info_t* ti,int error_id) {
        ti->wanna_wakeup=1;
        switch (tapestate_get(ti)) {
        case TS_REW_RELEASE_INIT:
+       case TS_RFO_INIT:
+       case TS_RBA_INIT:
            tapestate_set(ti,TS_FAILED);
            wake_up (&ti->wq);
            break;
index 61ddecbeffaf3bfb735f9ab2c748d1dfe4dd68cb..0a82699ae76d3f84340fbbbb55b938efde2b6d29 100644 (file)
@@ -204,13 +204,9 @@ tape_read (struct file *filp, char *data, size_t count, loff_t * ppos)
            return rc;
        }
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
-       wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+       wait_event (ti->wq,ti->wanna_wakeup);
        ti->cqr = NULL;
        ti->discipline->free_read_block (cqr, ti);
-       if (signal_pending (current)) {
-               tapestate_set (ti, TS_IDLE);
-               return -ERESTARTSYS;
-       }
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        if (tapestate_get (ti) == TS_FAILED) {
                tapestate_set (ti, TS_IDLE);
index 5e9804c83cc077ccd31f12bfd77fd94a5a12ff22..04de5c4a96b0b476250f771c60e02bd456030e37 100644 (file)
@@ -93,8 +93,8 @@ static struct console tub3270_con = {
        NULL                    /* next */
 };
 
-bcb_t tub3270_con_bcb;                 /* Buffer that receives con writes */
-spinlock_t tub3270_con_bcblock;                /* Lock for the buffer */
+static bcb_t tub3270_con_bcb;          /* Buffer that receives con writes */
+static spinlock_t tub3270_con_bcblock; /* Lock for the buffer */
 int tub3270_con_irq = -1;              /* set nonneg by _activate() */
 tub_t *tub3270_con_tubp;               /* set nonzero by _activate() */
 struct tty_driver tty3270_con_driver;  /* for /dev/console at 4, 64 */
index b5ff8ae603f2759ec195c7f3c73766e85d4153e0..0c25126efe507932b53a2d22f43451852ada252f 100644 (file)
@@ -992,8 +992,8 @@ tty3270_show_tube(int minor, char *buf, int count)
 
        if (tty)
                len += sprintf(buf+len,
-                               "    write_wait=%.8x read_wait=%.8x\n",
-                               (int)&tty->write_wait, (int)&tty->read_wait);
+                               "    write_wait=%p read_wait=%p\n",
+                               &tty->write_wait, &tty->read_wait);
 
        if (tty && ((mp = tty->termios)))
                len += sprintf(buf+len,"    iflag=%.8x oflag=%.8x "
index d1a1cb3c7161671dd06bce06249fa768077c969f..5c5b4b5f27080c582bc82cbac2da547837e33611 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.49 2001/08/31 14:50:05 felfert Exp $
+ * $Id: ctcmain.c,v 1.51 2001/09/24 10:38:02 mschwide Exp $
  *
  * CTC / ESCON network driver
  *
@@ -35,7 +35,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.49 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.51 $
  *
  */
 \f
@@ -43,7 +43,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -96,6 +96,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
 MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
+MODULE_LICENSE("GPL");
 #ifndef CTC_CHANDEV
 MODULE_PARM(ctc, "s");
 MODULE_PARM_DESC(ctc,
@@ -296,6 +297,8 @@ typedef struct channel_t {
        net_device          *netdev;
 
        ctc_profile         prof;
+
+       unsigned char       *trans_skb_data;
 } channel;
 
 #define CHANNEL_FLAGS_READ            0
@@ -382,7 +385,7 @@ static __inline__ int ctc_test_and_set_busy(net_device *dev)
  */
 static void print_banner(void) {
        static int printed = 0;
-       char vbuf[] = "$Revision: 1.49 $";
+       char vbuf[] = "$Revision: 1.51 $";
        char *version = vbuf;
 
        if (printed)
@@ -951,6 +954,7 @@ static __inline__ int ctc_checkalloc_buffer(channel *ch, int warn) {
                        return -ENOMEM;
                }
                ch->ccw[1].count = 0;
+               ch->trans_skb_data = ch->trans_skb->data;
                ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED;
        }
        return 0;
@@ -1016,7 +1020,7 @@ static void ch_action_txdone(fsm_instance *fi, int event, void *arg)
                        spin_unlock(&ch->collect_lock);
                        return;
                }
-               ch->trans_skb->tail = ch->trans_skb->data;
+               ch->trans_skb->tail = ch->trans_skb->data = ch->trans_skb_data;
                ch->trans_skb->len = 0;
                if (ch->prof.maxmulti < (ch->collect_len + 2))
                        ch->prof.maxmulti = ch->collect_len + 2;
@@ -1089,7 +1093,6 @@ static void ch_action_rx(fsm_instance *fi, int event, void *arg)
        int            len = ch->max_bufsize - ch->devstat->rescnt;
        struct sk_buff *skb = ch->trans_skb;
        __u16          block_len = *((__u16*)skb->data);
-       char           *saved_data = skb->data;
        int            check_len;
        int            rc;
 
@@ -1138,7 +1141,7 @@ static void ch_action_rx(fsm_instance *fi, int event, void *arg)
                ctc_unpack_skb(ch, skb);
        }
  again:
-       skb->data = skb->tail = saved_data;
+       skb->data = skb->tail = ch->trans_skb_data;
        skb->len = 0;
        if (ctc_checkalloc_buffer(ch, 1))
                return;
@@ -1548,9 +1551,9 @@ static void ch_action_restart(fsm_instance *fi, int event, void *arg)
        channel *ch = (channel *)arg;
        net_device *dev = ch->netdev;
 
+       fsm_deltimer(&ch->timer);
        printk(KERN_DEBUG "%s: %s channel restart\n", dev->name,
               (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
-
        fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
        oldstate = fsm_getstate(fi);
        fsm_newstate(fi, CH_STATE_STARTWAIT);
@@ -1716,8 +1719,7 @@ static void ch_action_txretry(fsm_instance *fi, int event, void *arg)
 #ifdef DEBUG
        printk(KERN_DEBUG "ccw[4].cda = %08x\n", ch->ccw[4].cda);
 #endif
-                       rc = do_IO(ch->irq, &ch->ccw[3],
-                                  (intparm_t)ch, 0xff, 0);
+                       rc = do_IO(ch->irq, &ch->ccw[3], (intparm_t)ch, 0xff, 0);
                        if (event == CH_EVENT_TIMER)
                                s390irq_spin_unlock_irqrestore(ch->irq,
                                                               saveflags);
@@ -2539,7 +2541,8 @@ static int transmit_skb(channel *ch, struct sk_buff *skb) {
                if (rc != 0) {
                        fsm_deltimer(&ch->timer);
                        ccw_check_return_code(ch, rc);
-                       skb_dequeue_tail(&ch->io_queue);
+                       if (ccw_idx == 3)
+                               skb_dequeue_tail(&ch->io_queue);
                        /**
                         * Remove our header. It gets added
                         * again on retransmit.
index 9346f10fa4f6f86612b01291efa83fc3f30ea180..82c97d49af194d0966b60e2283e3e4fb6fb58fa6 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/version.h>
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/tqueue.h>
 #include <linux/interrupt.h>
 
 #undef DEBUG
 
-#ifndef min
-#define min(a,b) (((a)<(b))?(a):(b))
-#endif
-
 /* FLAGS:
  * All flags are defined in the field IPFLAGS1 of each function
  * and can be found in CP Programming Services.
@@ -1163,7 +1159,7 @@ iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls,
 
        parm = (iparml_db *)grab_param();
 
-       parm->ipbfadr1 = (__u32) buffer;
+       parm->ipbfadr1 = (__u32) (addr_t) buffer;
        parm->ipbfln1f = (__u32) ((ulong) buflen);
        parm->ipmsgid = msgid;
        parm->ippathid = pathid;
@@ -1186,7 +1182,7 @@ iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls,
                        if (residual_buffer)
                                *residual_buffer = parm->ipbfadr1;
                } else {
-                       moved = min (buflen, 8);
+                       moved = min_t (unsigned long, buflen, 8);
 
                        memcpy ((char *) buffer,
                                (char *) &parm->ipbfadr1, moved);
@@ -1283,7 +1279,8 @@ iucv_receive_array (__u16 pathid,
 
                        while ((moved < 8) && (moved < buflen)) {
                                dyn_len =
-                                   min ((buffer + i)->length, need_to_move);
+                                   min_t (unsigned int,
+                                        (buffer + i)->length, need_to_move);
 
                                memcpy ((char *)((ulong)((buffer + i)->address)),
                                        ((char *) &parm->ipbfadr1) + moved,
index f93e6813cfe70465f393048121fd51377881fc49..3e0ca1e11ef4198db68278905548cfd143525d70 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.11 2001/07/16 17:00:02 felfert Exp $
+ * $Id: netiucv.c,v 1.12 2001/09/24 10:38:02 mschwide Exp $
  *
  * IUCV network driver
  *
@@ -28,7 +28,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.11 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.12 $
  *
  */
 \f
@@ -36,7 +36,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -2002,7 +2002,7 @@ netiucv_free_netdevice(net_device *dev)
 static void
 netiucv_banner(void)
 {
-       char vbuf[] = "$Revision: 1.11 $";
+       char vbuf[] = "$Revision: 1.12 $";
        char *version = vbuf;
 
        if ((version = strchr(version, ':'))) {
@@ -2115,7 +2115,8 @@ netiucv_init(void)
        return 0;
 }
 
-module_init(netiucv_init);
 #ifdef MODULE
+module_init(netiucv_init);
 module_exit(netiucv_exit);
+MODULE_LICENSE("GPL");
 #endif
index 31c07a00f01536198c6646f463139050fc7e6dbb..27def25fa0caf802c2b07be795eff638f8144b00 100644 (file)
@@ -1716,6 +1716,7 @@ static void __exit amd7930_exit(void)
 
 module_init(amd7930_init);
 module_exit(amd7930_exit);
+MODULE_LICENSE("GPL");
 
 /*************************************************************/
 /*                 Audio format conversion                   */
index 8af67283634bda9f571f7044767ca171beb16e2e..2be051503e114bc6cf639b98a2da0dcbe8cfa14e 100644 (file)
@@ -1073,4 +1073,3 @@ static void __exit bpp_cleanup(void)
 
 module_init(bpp_init);
 module_exit(bpp_cleanup);
-MODULE_LICENSE("GPL");
index 98079cc72994f46af889ce69b08b04b28cdf7100..375a42d2b83d3e40268c4e8fb171abdf83078088 100644 (file)
  * */
 
 /* CHANGELOG
+ *
+ * Version 2.6
+ *
+ * Following test of the 64 bit parisc kernel by Richard Hirst,
+ * several problems have now been corrected.  Also adds support for
+ * consistent memory allocation.
  *
  * Version 2.5
  * 
@@ -90,7 +96,7 @@
  * Initial modularisation from the D700.  See NCR_D700.c for the rest of
  * the changelog.
  * */
-#define NCR_700_VERSION "2.5"
+#define NCR_700_VERSION "2.6"
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -217,18 +223,39 @@ struct Scsi_Host * __init
 NCR_700_detect(Scsi_Host_Template *tpnt,
               struct NCR_700_Host_Parameters *hostdata)
 {
-       dma_addr_t pScript, pSlots;
+       dma_addr_t pScript, pMemory, pSlots;
+       __u8 *memory;
        __u32 *script;
        struct Scsi_Host *host;
        static int banner = 0;
        int j;
 
-       /* This separation of pScript and script is not strictly
-        * necessay, but may be useful in architectures which can
-        * allocate consistent memory on which virt_to_bus will not
-        * work */
-       script = kmalloc(sizeof(SCRIPT), GFP_KERNEL);
-       pScript = virt_to_bus(script);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+       memory = pci_alloc_consistent(hostdata->pci_dev, TOTAL_MEM_SIZE,
+                                     &pMemory);
+       hostdata->consistent = 1;
+       if(memory == NULL ) {
+               printk(KERN_WARNING "53c700: consistent memory allocation failed\n");
+#endif
+               memory = kmalloc(TOTAL_MEM_SIZE, GFP_KERNEL);
+               if(memory == NULL) {
+                       printk(KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n");
+                       return NULL;
+               }
+               pMemory = pci_map_single(hostdata->pci_dev, memory,
+                                        TOTAL_MEM_SIZE, PCI_DMA_BIDIRECTIONAL);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+               hostdata->consistent = 0;
+       }
+#endif
+       script = (__u32 *)memory;
+       pScript = pMemory;
+       hostdata->msgin = memory + MSGIN_OFFSET;
+       hostdata->msgout = memory + MSGOUT_OFFSET;
+       hostdata->status = memory + STATUS_OFFSET;
+       hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
+               
+       pSlots = pMemory + SLOTS_OFFSET;
 
        /* Fill in the missing routines from the host template */
        tpnt->queuecommand = NCR_700_queuecommand;
@@ -251,29 +278,6 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
 
        if((host = scsi_register(tpnt, 4)) == NULL)
                return NULL;
-       if(script == NULL) {
-               printk(KERN_ERR "53c700: Failed to allocate script, detatching\n");
-               scsi_unregister(host);
-               return NULL;
-       }
-
-       /* This separation of slots and pSlots may facilitate later
-        * migration to consistent memory on architectures which
-        * support it */
-       hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot)
-                                 * NCR_700_COMMAND_SLOTS_PER_HOST,
-                                 GFP_KERNEL);
-       pSlots = virt_to_bus(hostdata->slots);
-
-       hostdata->msgin = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
-       hostdata->msgout = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
-       hostdata->status = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
-       if(hostdata->slots == NULL || hostdata->msgin == NULL
-          || hostdata->msgout == NULL || hostdata->status==NULL) {
-               printk(KERN_ERR "53c700: Failed to allocate command slots or message buffers, detatching\n");
-               scsi_unregister(host);
-               return NULL;
-       }
        memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
               * NCR_700_COMMAND_SLOTS_PER_HOST);
        for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
@@ -295,19 +299,17 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
        for(j = 0; j < PATCHES; j++) {
                script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
        }
-       /* now patch up fixed addresses. 
-        * NOTE: virt_to_bus may be wrong if consistent memory is used
-        * for these in the future */
+       /* now patch up fixed addresses. */
        script_patch_32(script, MessageLocation,
-                       virt_to_bus(&hostdata->msgout[0]));
+                       pScript + MSGOUT_OFFSET);
        script_patch_32(script, StatusAddress,
-                       virt_to_bus(&hostdata->status[0]));
+                       pScript + STATUS_OFFSET);
        script_patch_32(script, ReceiveMsgAddress,
-                       virt_to_bus(&hostdata->msgin[0]));
+                       pScript + MSGIN_OFFSET);
 
        hostdata->script = script;
        hostdata->pScript = pScript;
-       dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
+       NCR_700_dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
        hostdata->state = NCR_700_HOST_FREE;
        spin_lock_init(&hostdata->lock);
        hostdata->cmd = NULL;
@@ -344,13 +346,18 @@ NCR_700_release(struct Scsi_Host *host)
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)host->hostdata[0];
 
-       /* NOTE: these may be NULL if we weren't fully initialised before
-        * the scsi_unregister was called */
-       kfree(hostdata->script);
-       kfree(hostdata->slots);
-       kfree(hostdata->msgin);
-       kfree(hostdata->msgout);
-       kfree(hostdata->status);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+       if(hostdata->consistent) {
+               pci_free_consistent(hostdata->pci_dev, TOTAL_MEM_SIZE,
+                                   hostdata->script, hostdata->pScript);
+       } else {
+#endif
+               pci_unmap_single(hostdata->pci_dev, hostdata->pScript,
+                                TOTAL_MEM_SIZE, PCI_DMA_BIDIRECTIONAL);
+               kfree(hostdata->script);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+       }
+#endif
        return 1;
 }
 
@@ -620,7 +627,25 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
        }
        return (offset & 0x0f) | (XFERP & 0x07)<<4;
 }
-       
+
+STATIC inline void
+NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
+             struct NCR_700_command_slot *slot)
+{
+       if(SCp->sc_data_direction != SCSI_DATA_NONE &&
+          SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
+               int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
+               if(SCp->use_sg) {
+                       pci_unmap_sg(hostdata->pci_dev, SCp->buffer,
+                                    SCp->use_sg, pci_direction);
+               } else {
+                       pci_unmap_single(hostdata->pci_dev,
+                                        slot->dma_handle,
+                                        SCp->request_bufflen,
+                                        pci_direction);
+               }
+       }
+}
 
 STATIC inline void
 NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
@@ -632,31 +657,22 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
        if(SCp != NULL) {
                struct NCR_700_command_slot *slot = 
                        (struct NCR_700_command_slot *)SCp->host_scribble;
-
+               
+               NCR_700_unmap(hostdata, SCp, slot);
+               pci_unmap_single(hostdata->pci_dev, slot->pCmd,
+                                sizeof(SCp->cmnd), PCI_DMA_TODEVICE);
                if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
 #ifdef NCR_700_DEBUG
                        printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
                               SCp, SCp->cmnd[7], result);
                        print_sense("53c700", SCp);
+
 #endif
+                       SCp->use_sg = SCp->cmnd[8];
                        if(result == 0)
                                result = SCp->cmnd[7];
                }
 
-               if(SCp->sc_data_direction != SCSI_DATA_NONE &&
-                  SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
-                       int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
-                       if(SCp->use_sg) {
-                               pci_unmap_sg(hostdata->pci_dev, SCp->buffer,
-                                            SCp->use_sg, pci_direction);
-                       } else {
-                               pci_unmap_single(hostdata->pci_dev,
-                                                slot->dma_handle,
-                                                SCp->request_bufflen,
-                                                pci_direction);
-                       }
-               }
-
                free_slot(slot, hostdata);
 
                SCp->host_scribble = NULL;
@@ -850,7 +866,7 @@ process_extended_message(struct Scsi_Host *host,
                        printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
                               host->host_no);
                        hostdata->msgout[0] = A_REJECT_MSG;
-                       dma_cache_wback((unsigned long)hostdata->msgout, 1);
+                       NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
                        script_patch_16(hostdata->script, MessageCount, 1);
                        /* SendMsgOut returns, so set up the return
                         * address */
@@ -862,7 +878,7 @@ process_extended_message(struct Scsi_Host *host,
                printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
                       host->host_no, pun, lun);
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_wback((unsigned long)hostdata->msgout, 1);
+               NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
                script_patch_16(hostdata->script, MessageCount, 1);
                resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
 
@@ -876,7 +892,7 @@ process_extended_message(struct Scsi_Host *host,
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_wback((unsigned long)hostdata->msgout, 1);
+               NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
                script_patch_16(hostdata->script, MessageCount, 1);
                /* SendMsgOut returns, so set up the return
                 * address */
@@ -954,7 +970,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_wback((unsigned long)hostdata->msgout, 1);
+               NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
                script_patch_16(hostdata->script, MessageCount, 1);
                /* SendMsgOut returns, so set up the return
                 * address */
@@ -964,7 +980,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
        }
        NCR_700_writel(temp, host, TEMP_REG);
        /* set us up to receive another message */
-       dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+       NCR_700_dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
        return resume_offset;
 }
 
@@ -1002,10 +1018,15 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                                printk("  cmd %p has status %d, requesting sense\n",
                                       SCp, hostdata->status[0]);
 #endif
-                               /* we can destroy the command here because the
-                                * contingent allegiance condition will cause a 
-                                * retry which will re-copy the command from the
-                                * saved data_cmnd */
+                               /* we can destroy the command here
+                                * because the contingent allegiance
+                                * condition will cause a retry which
+                                * will re-copy the command from the
+                                * saved data_cmnd.  We also unmap any
+                                * data associated with the command
+                                * here */
+                               NCR_700_unmap(hostdata, SCp, slot);
+
                                SCp->cmnd[0] = REQUEST_SENSE;
                                SCp->cmnd[1] = (SCp->lun & 0x7) << 5;
                                SCp->cmnd[2] = 0;
@@ -1013,21 +1034,29 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                                SCp->cmnd[4] = sizeof(SCp->sense_buffer);
                                SCp->cmnd[5] = 0;
                                SCp->cmd_len = 6;
-                               /* Here's a quiet hack: the REQUEST_SENSE command is
-                                * six bytes, so store a flag indicating that this
-                                * was an internal sense request and the original
-                                * status at the end of the command */
+                               /* Here's a quiet hack: the
+                                * REQUEST_SENSE command is six bytes,
+                                * so store a flag indicating that
+                                * this was an internal sense request
+                                * and the original status at the end
+                                * of the command */
                                SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
                                SCp->cmnd[7] = hostdata->status[0];
+                               SCp->cmnd[8] = SCp->use_sg;
+                               SCp->use_sg = 0;
                                SCp->sc_data_direction = SCSI_DATA_READ;
-                               dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
+                               pci_dma_sync_single(hostdata->pci_dev,
+                                                   slot->pCmd,
+                                                   SCp->cmd_len,
+                                                   PCI_DMA_TODEVICE);
+                               slot->dma_handle = pci_map_single(hostdata->pci_dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), PCI_DMA_FROMDEVICE);
                                slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
-                               slot->SG[0].pAddr = bS_to_host(virt_to_bus(SCp->sense_buffer));
+                               slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
                                slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
                                slot->SG[1].pAddr = 0;
                                slot->resume_offset = hostdata->pScript;
-                               dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
-                               dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
+                               NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
+                               NCR_700_dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
                                
                                /* queue the command for reissue */
                                slot->state = NCR_700_SLOT_QUEUED;
@@ -1136,7 +1165,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
 
                        /* re-patch for this command */
                        script_patch_32_abs(hostdata->script, CommandAddress, 
-                                           virt_to_bus(slot->cmnd->cmnd));
+                                           slot->pCmd);
                        script_patch_16(hostdata->script,
                                        CommandCount, slot->cmnd->cmd_len);
                        script_patch_32_abs(hostdata->script, SGScriptStartAddress,
@@ -1149,13 +1178,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                         * should therefore always clear ACK */
                        NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
                                       host, SXFER_REG);
-                       dma_cache_inv((unsigned long)hostdata->msgin,
+                       NCR_700_dma_cache_inv((unsigned long)hostdata->msgin,
                                      MSG_ARRAY_SIZE);
-                       dma_cache_wback((unsigned long)hostdata->msgout,
+                       NCR_700_dma_cache_wback((unsigned long)hostdata->msgout,
                                        MSG_ARRAY_SIZE);
                        /* I'm just being paranoid here, the command should
                         * already have been flushed from the cache */
-                       dma_cache_wback((unsigned long)slot->cmnd->cmnd,
+                       NCR_700_dma_cache_wback((unsigned long)slot->cmnd->cmnd,
                                        slot->cmnd->cmd_len);
 
 
@@ -1219,7 +1248,8 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                hostdata->reselection_id = reselection_id;
                /* just in case we have a stale simple tag message, clear it */
                hostdata->msgin[1] = 0;
-               dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+               NCR_700_dma_cache_wback_inv((unsigned long)hostdata->msgin,
+                                           MSG_ARRAY_SIZE);
                if(hostdata->tag_negotiated & (1<<reselection_id)) {
                        resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
                } else {
@@ -1334,7 +1364,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp)
        hostdata->cmd = NULL;
        /* clear any stale simple tag message */
        hostdata->msgin[1] = 0;
-       dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+       NCR_700_dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
 
        if(id == 0xff) {
                /* Selected as target, Ignore */
@@ -1404,7 +1434,7 @@ NCR_700_start_command(Scsi_Cmnd *SCp)
         * set up so we cannot take a selection interrupt */
 
        hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
-                                           SCp->lun);
+                                              SCp->lun);
        /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
         * if the negotiated transfer parameters still hold, so
         * always renegotiate them */
@@ -1437,7 +1467,7 @@ NCR_700_start_command(Scsi_Cmnd *SCp)
                        Device_ID, 1<<SCp->target);
 
        script_patch_32_abs(hostdata->script, CommandAddress, 
-                       virt_to_bus(SCp->cmnd));
+                           slot->pCmd);
        script_patch_16(hostdata->script, CommandCount, SCp->cmd_len);
        /* finally plumb the beginning of the SG list into the script
         * */
@@ -1448,10 +1478,10 @@ NCR_700_start_command(Scsi_Cmnd *SCp)
        if(slot->resume_offset == 0)
                slot->resume_offset = hostdata->pScript;
        /* now perform all the writebacks and invalidates */
-       dma_cache_wback((unsigned long)hostdata->msgout, count);
-       dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
-       dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
-       dma_cache_inv((unsigned long)hostdata->status, 1);
+       NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, count);
+       NCR_700_dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+       NCR_700_dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
+       NCR_700_dma_cache_inv((unsigned long)hostdata->status, 1);
 
        /* set the synchronous period/offset */
        NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
@@ -1519,7 +1549,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
 
                DEBUG(("scsi%d: istat %02x sstat0 %02x dstat %02x dsp %04x[%08x] dsps 0x%x\n",
                       host->host_no, istat, sstat0, dstat,
-                      (dsp - (__u32)virt_to_bus(hostdata->script))/4,
+                      (dsp - (__u32)(hostdata->pScript))/4,
                       dsp, dsps));
 
                if(SCp != NULL) {
@@ -1632,7 +1662,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                                        slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
                                        slot->SG[i].pAddr = 0;
                                }
-                               dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+                               NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
                                /* and pretend we disconnected after
                                 * the command phase */
                                resume_offset = hostdata->pScript + Ent_MsgInDuringData;
@@ -1847,7 +1877,13 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
 #endif
                
                if(old != NULL && old->tag == SCp->device->current_tag) {
-                       printk(KERN_WARNING "scsi%d (%d:%d) Tag clock back to current, queueing\n", SCp->host->host_no, SCp->target, SCp->lun);
+                       /* On some badly starving drives, this can be
+                        * a frequent occurance, so print the message
+                        * only once */
+                       if(NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_TAG_STARVATION_WARNED)) {
+                               printk(KERN_WARNING "scsi%d (%d:%d) Target is suffering from tag starvation.\n", SCp->host->host_no, SCp->target, SCp->lun);
+                               NCR_700_set_flag(SCp->device, NCR_700_DEV_TAG_STARVATION_WARNED);
+                       }
                        return 1;
                }
                slot->tag = SCp->device->current_tag++;
@@ -1900,6 +1936,18 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
                hostdata->ITL_Hash_back[hash] = slot;
        slot->ITL_back = NULL;
 
+       /* sanity check: some of the commands generated by the mid-layer
+        * have an eccentric idea of their sc_data_direction */
+       if(!SCp->use_sg && !SCp->request_bufflen 
+          && SCp->sc_data_direction != SCSI_DATA_NONE) {
+#ifdef NCR_700_DEBUG
+               printk("53c700: Command");
+               print_command(SCp->cmnd);
+               printk("Has wrong data direction %d\n", SCp->sc_data_direction);
+#endif
+               SCp->sc_data_direction = SCSI_DATA_NONE;
+       }
+
        switch (SCp->cmnd[0]) {
        case REQUEST_SENSE:
                /* clear the internal sense magic */
@@ -1965,12 +2013,14 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
                }
                slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
                slot->SG[i].pAddr = 0;
-               dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+               NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
                DEBUG((" SETTING %08lx to %x\n",
-                      virt_to_bus(&slot->SG[i].ins), 
+                      (&slot->pSG[i].ins), 
                       slot->SG[i].ins));
        }
        slot->resume_offset = 0;
+       slot->pCmd = pci_map_single(hostdata->pci_dev, SCp->cmnd,
+                                   sizeof(SCp->cmnd), PCI_DMA_TODEVICE);
        NCR_700_start_command(SCp);
        return 0;
 }
index 17b51b0d10975b888a971d72691136c66d2a6e84..66721ea238ae6188e8dd4b668fd1a6e702dbc342 100644 (file)
 #error "Config.in must define either CONFIG_53C700_IO_MAPPED or CONFIG_53C700_MEM_MAPPED to use this scsi core."
 #endif
 
+/* macros for consistent memory allocation */
+
+#ifdef CONFIG_53C700_USE_CONSISTENT
+#define NCR_700_dma_cache_wback(mem, size) \
+       if(!hostdata->consistent) \
+               dma_cache_wback(mem, size)
+#define NCR_700_dma_cache_inv(mem, size) \
+       if(!hostdata->consistent) \
+               dma_cache_inv(mem, size)
+#define NCR_700_dma_cache_wback_inv(mem, size) \
+       if(!hostdata->consistent) \
+               dma_cache_wback_inv(mem, size)
+#else
+#define NCR_700_dma_cache_wback(mem, size) dma_cache_wback(mem,size)
+#define NCR_700_dma_cache_inv(mem, size) dma_cache_inv(mem,size)
+#define NCR_700_dma_cache_wback_inv(mem, size) dma_cache_wback_inv(mem,size)
+#endif
+
 
 struct NCR_700_Host_Parameters;
 
@@ -86,6 +104,7 @@ struct NCR_700_SG_List {
 #define NCR_700_DEV_NEGOTIATED_SYNC    (1<<16)
 #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION     (1<<17)
 #define NCR_700_DEV_BEGIN_TAG_QUEUEING (1<<18)
+#define NCR_700_DEV_TAG_STARVATION_WARNED (1<<19)
 
 static inline void
 NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer)
@@ -174,6 +193,8 @@ struct NCR_700_command_slot {
        __u16   tag;
        __u32   resume_offset;
        Scsi_Cmnd       *cmnd;
+       /* The pci_mapped address of the actual command in cmnd */
+       dma_addr_t      pCmd;
        __u32           temp;
        /* if this command is a pci_single mapping, holds the dma address
         * for later unmapping in the done routine */
@@ -191,19 +212,22 @@ struct NCR_700_Host_Parameters {
        int     clock;                  /* board clock speed in MHz */
        __u32   base;                   /* the base for the port (copied to host) */
        struct pci_dev  *pci_dev;
-       __u   dmode_extra;    /* adjustable bus settings */
-       __u   differential:1; /* if we are differential */
+       __u32   dmode_extra;    /* adjustable bus settings */
+       __u32   differential:1; /* if we are differential */
 #ifdef CONFIG_53C700_LE_ON_BE
        /* This option is for HP only.  Set it if your chip is wired for
         * little endian on this platform (which is big endian) */
-       __u   force_le_on_be:1;
+       __u32   force_le_on_be:1;
 #endif
-       __u   chip710:1;      /* set if really a 710 not 700 */
-       __u   burst_disable:1;        /* set to 1 to disable 710 bursting */
+       __u32   chip710:1;      /* set if really a 710 not 700 */
+       __u32   burst_disable:1;        /* set to 1 to disable 710 bursting */
 
        /* NOTHING BELOW HERE NEEDS ALTERING */
-       __u   fast:1;         /* if we can alter the SCSI bus clock
+       __u32   fast:1;         /* if we can alter the SCSI bus clock
                                    speed (so can negiotiate sync) */
+#ifdef CONFIG_53C700_USE_CONSISTENT
+       __u32   consistent:1;
+#endif
 
        int     sync_clock;     /* The speed of the SYNC core */
 
@@ -216,15 +240,23 @@ struct NCR_700_Host_Parameters {
        spinlock_t lock;
        enum NCR_700_Host_State state; /* protected by state lock */
        Scsi_Cmnd *cmd;
-
+       /* Note: pScript contains the single consistent block of
+        * memory.  All the msgin, msgout and status are allocated in
+        * this memory too (at separate cache lines).  TOTAL_MEM_SIZE
+        * represents the total size of this area */
+#define        MSG_ARRAY_SIZE  8
+#define        MSGOUT_OFFSET   (L1_CACHE_ALIGN(sizeof(SCRIPT)))
        __u8    *msgout;
-#define        MSG_ARRAY_SIZE  16
-       __u8    tag_negotiated;
-       __u8    *status;
+#define MSGIN_OFFSET   (MSGOUT_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
        __u8    *msgin;
+#define STATUS_OFFSET  (MSGIN_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
+       __u8    *status;
+#define SLOTS_OFFSET   (STATUS_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
        struct NCR_700_command_slot     *slots;
+#define        TOTAL_MEM_SIZE  (SLOTS_OFFSET + L1_CACHE_ALIGN(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST))
        int     saved_slot_position;
        int     command_slot_count; /* protected by state lock */
+       __u8    tag_negotiated;
        __u8    rev;
        __u8    reselection_id;
        /* flags for the host */
index 527995202d2eb8b058234f7fc6a0e41f0ea4088a..bfdc7177bd91a29fa643a2cf39ead50b76b67cc3 100644 (file)
@@ -122,10 +122,11 @@ if [ "$CONFIG_MCA" = "y" ]; then
    fi
 fi
 if [ "$CONFIG_PARISC" = "y" ]; then
-   dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI700 $CONFIG_SCSI
+   dep_tristate 'HP LASI SCSI support for 53c700/710' CONFIG_SCSI_LASI700 $CONFIG_SCSI
    if [ "$CONFIG_SCSI_LASI700" != "n" ]; then
       define_bool CONFIG_53C700_MEM_MAPPED y
       define_bool CONFIG_53C700_LE_ON_BE y
+      define_bool CONFIG_53C700_USE_CONSISTENT y
    fi
 fi
 dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI $CONFIG_PCI
index 20f895946cd7019b93e124db3a55d59649666386..0da681d497a26a0948350425f57e0e6857a25133 100644 (file)
-This driver supports the 53c700 and 53c700-66 chips only.  It is full
-featured and does sync (-66 only), disconnects and tag command
-queueing.
+General Description
+===================
+
+This driver supports the 53c700 and 53c700-66 chips.  It also supports
+the 53c710 but only in 53c700 emulation mode.  It is full featured and
+does sync (-66 and 710 only), disconnects and tag command queueing.
 
 Since the 53c700 must be interfaced to a bus, you need to wrapper the
 card detector around this driver.  For an example, see the
-NCR_D700.[ch] files.
+NCR_D700.[ch] or lasi700.[ch] files.
 
 The comments in the 53c700.[ch] files tell you which parts you need to
 fill in to get the driver working.
 
-The driver is currently I/O mapped only, but it should be easy enough
-to memory map (just make the port reads #defines with MEM_MAPPED for
-memory mapping or nothing for I/O mapping, specify an extra rule for
-53c700-mem.o with the -DMEM_MAPPED flag and make your driver use it,
-that way the make rules will generate the correct version).
+
+Compile Time Flags
+==================
+
+The driver may be either io mapped or memory mapped.  This is
+selectable by configuration flags:
+
+CONFIG_53C700_MEM_MAPPED
+
+define if the driver is memory mapped.
+
+CONFIG_53C700_IO_MAPPED
+
+define if the driver is to be io mapped.
+
+One or other of the above flags *must* be defined.
+
+Other flags are:
+
+CONFIG_53C700_LE_ON_BE
+
+define if the chipset must be supported in little endian mode on a big
+endian architecture (used for the 700 on parisc).
+
+CONFIG_53C700_USE_CONSISTENT
+
+allocate consistent memory (should only be used if your architecture
+has a mixture of consistent and inconsistent memory).  Fully
+consistent or fully inconsistent architectures should not define this.
+
+
+Using the Chip Core Driver
+==========================
+
+In order to plumb the 53c700 chip core driver into a working SCSI
+driver, you need to know three things about the way the chip is wired
+into your system (or expansion card).
+
+1. The clock speed of the SCSI core
+2. The interrupt line used
+3. The memory (or io space) location of the 53c700 registers.
+
+Optionally, you may also need to know other things, like how to read
+the SCSI Id from the card bios or whether the chip is wired for
+differential operation.
+
+Usually you can find items 2. and 3. from general spec. documents or
+even by examining the configuration of a working driver under another
+operating system.
+
+The clock speed is usually buried deep in the technical literature.
+It is required because it is used to set up both the synchronous and
+asynchronous dividers for the chip.  As a general rule of thumb,
+manufacturers set the clock speed at the lowest possible setting
+consistent with the best operation of the chip (although some choose
+to drive it off the CPU or bus clock rather than going to the expense
+of an extra clock chip).  The best operation clock speeds are:
+
+53c700 - 25MHz
+53c700-66 - 50MHz
+53c710 - 40Mhz
+
+Writing Your Glue Driver
+========================
+
+This will be a standard SCSI driver (I don't know of a good document
+describing this, just copy from some other driver) with at least a
+detect and release entry.
+
+In the detect routine, you need to allocate a struct
+NCR_700_Host_Parameters sized memory area and clear it (so that the
+default values for everything are 0).  Then you must fill in the
+parameters that matter to you (see below), plumb the NCR_700_intr
+routine into the interrupt line and call NCR_700_detect with the host
+template and the new parameters as arguments.  You should also call
+the relevant request_*_region function and place the register base
+address into the `base' pointer of the host parameters.
+
+In the release routine, you must free the NCR_700_Host_Parameters that
+you allocated, call the corresponding release_*_region and free the
+interrupt.
+
+Handling Interrupts
+-------------------
+
+In general, you should just plumb the card's interrupt line in with 
+
+request_irq(irq, NCR_700_intr, <irq flags>, <driver name>, host);
+
+where host is the return from the relevant NCR_700_detect() routine.
+
+You may also write your own interrupt handling routine which calls
+NCR_700_intr() directly.  However, you should only really do this if
+you have a card with more than one chip on it and you can read a
+register to tell which set of chips wants the interrupt.
+
+Settable NCR_700_Host_Parameters
+--------------------------------
+
+The following are a list of the user settable parameters:
+
+clock: (MANDATORY)
+
+Set to the clock speed of the chip in MHz.
+
+base: (MANDATORY)
+
+set to the base of the io or mem region for the register set. On 64
+bit architectures this is only 32 bits wide, so the registers must be
+mapped into the low 32 bits of memory.
+
+pci_dev: (OPTIONAL)
+
+set to the PCI board device.  Leave NULL for a non-pci board.  This is
+used for the pci_alloc_consistent() and pci_map_*() functions.
+
+dmode_extra: (OPTIONAL, 53c710 only)
+
+extra flags for the DMODE register.  These are used to control bus
+output pins on the 710.  The settings should be a combination of
+DMODE_FC1 and DMODE_FC2.  What these pins actually do is entirely up
+to the board designer.  Usually it is safe to ignore this setting.
+
+differential: (OPTIONAL)
+
+set to 1 if the chip drives a differential bus.
+
+force_le_on_be: (OPTIONAL, only if CONFIG_53C700_LE_ON_BE is set)
+
+set to 1 if the chip is operating in little endian mode on a big
+endian architecture.
+
+chip710: (OPTIONAL)
+
+set to 1 if the chip is a 53c710.
+
+burst_disable: (OPTIONAL, 53c710 only)
+
+disable 8 byte bursting for DMA transfers.
 
index 6e95c9efb840d924de188d9de7310f6366dcf379..f3315fc0471748ea209f94589089c8de3f2a0830 100644 (file)
@@ -390,13 +390,11 @@ static int aha152x1[]  = {0, 11, 7, 1, 1, 1, DELAY_DEFAULT, 0, DEBUG_DEFAULT};
 #endif /* !defined(AHA152X_DEBUG) */
 
 #ifdef __ISAPNP__
-
 static struct isapnp_device_id id_table[] __devinitdata = {
        { ISAPNP_DEVICE_SINGLE('A','D','P',0x1505, 'A','D','P',0x1505), },
        { ISAPNP_DEVICE_SINGLE_END, }
 };
 MODULE_DEVICE_TABLE(isapnp, id_table);
-
 #endif /* ISAPNP */
 #endif /* MODULE */
 
@@ -981,28 +979,6 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
                        }
                printk("ok\n");
        }
-#ifdef __ISAPNP__
-       while (setup_count <= 2 &&
-              (dev = isapnp_find_dev (NULL, ISAPNP_VENDOR('A','D','P'),
-                                      ISAPNP_FUNCTION(0x1505), dev))) {
-               if (dev->prepare(dev) < 0)
-                       continue;
-               if (dev->active)
-                       continue;
-               if (!(dev->resource[0].flags & IORESOURCE_IO))
-                       continue;
-               dev->resource[0].flags |= IORESOURCE_AUTO;
-               if (dev->activate(dev) < 0)
-                       continue;
-               setup[setup_count].io_port = dev->resource[0].start;
-               setup[setup_count].irq = dev->irq_resource[0].start;
-               pnpdev[num_pnpdevs++] = dev;
-               printk (KERN_INFO
-                       "aha152x: found ISAPnP AVA-1505A at address 0x%03X, IRQ %d\n",
-                       setup[setup_count].io_port, setup[setup_count].irq);
-               setup_count++;
-       }
-#endif
 
 #if defined(SETUP0)
        if (setup_count < 2) {
@@ -1133,6 +1109,41 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
        }
 #endif
 
+#ifdef __ISAPNP__
+       while ( setup_count<2 && (dev=isapnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
+               if (dev->prepare(dev) < 0)
+                       continue;
+               if (dev->active)
+                       continue;
+               if (!(dev->resource[0].flags & IORESOURCE_IO))
+                       continue;
+               dev->resource[0].flags |= IORESOURCE_AUTO;
+               if (dev->activate(dev) < 0)
+                       continue;
+               if ( setup_count==1 && dev->resource[0].start==setup[0].io_port) {
+                       dev->deactivate(dev);
+                       continue;
+               }
+               setup[setup_count].io_port     = dev->resource[0].start;
+               setup[setup_count].irq         = dev->irq_resource[0].start;
+               setup[setup_count].scsiid      = 7;
+               setup[setup_count].reconnect   = 1;
+               setup[setup_count].parity      = 1;
+               setup[setup_count].synchronous = 1;
+               setup[setup_count].delay       = DELAY_DEFAULT;
+               setup[setup_count].ext_trans   = 0;
+#if defined(AHA152X_DEBUG)
+               setup[setup_count].debug       = DEBUG_DEFAULT;
+#endif
+               pnpdev[num_pnpdevs++] = dev;
+               printk (KERN_INFO
+                       "aha152x: found ISAPnP AVA-1505A at io=0x%03x, irq=%d\n",
+                       setup[setup_count].io_port, setup[setup_count].irq);
+               setup_count++;
+       }
+#endif
+
+
 #if defined(AUTOCONF)
        if (setup_count < 2) {
 #if !defined(SKIP_BIOSTEST)
index ce4992aad337169ad79d8da3aaaec12da0a0b8a7..0882f2faf17112c20f940041bfa8f08853d1c926 100644 (file)
  */
  
 #include <linux/module.h>
-
-#if defined(PCMCIA)
-#  undef MODULE
-#endif
-
 #include <stdarg.h>
 #include <asm/io.h>
 #include <asm/irq.h>
index 3c8a9d1129b2d4bb70b7f366a0b4585e4024ff67..63846c348209754d414c1724c322764a019df691 100644 (file)
@@ -1838,7 +1838,7 @@ static void adpt_sparc_info(sysInfo_S* si)
 #endif
 
 #if defined __alpha__ 
-static void adpt_sparc_info(sysInfo_S* si)
+static void adpt_alpha_info(sysInfo_S* si)
 {
        // This is all the info we need for now
        // We will add more info as our new
@@ -3324,4 +3324,4 @@ static static void adpt_delay(int millisec)
 static Scsi_Host_Template driver_template = DPT_I2O;
 #include "scsi_module.c"
 EXPORT_NO_SYMBOLS;
-MODULE_LICENSE("BSD without advertising clause");
+MODULE_LICENSE("GPL");
index 845b53a3400c6c179786f8fb6203754be953c8b7..19235dedbe09b27c33625ad4be7158c7523d0020 100644 (file)
@@ -61,6 +61,7 @@
  **************************************************************************/
 
 #include <linux/config.h>
+#include <linux/types.h>
 
 #define ULONG   unsigned long
 #define PVOID   void *
 #define UBYTE   unsigned char
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32     unsigned int
-#else
-#define U32     unsigned long
-#endif
+#define U32     u32
 
 #ifndef NULL
 #define NULL     0             /* zero          */
index 8b4633bc23a835adc333253257f8baf66654067f..fbedf6229c0383a2ffacc864ea691bcdc3c680cb 100644 (file)
@@ -54,6 +54,7 @@
  **************************************************************************/
 
 #include <linux/config.h>
+#include <linux/types.h>
 
 #define ULONG   unsigned long
 #define USHORT  unsigned short
 #define UBYTE   unsigned char
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32     unsigned int
-#else
-#define U32     unsigned long
-#endif
+#define U32     u32
 
 #ifndef NULL
 #define NULL     0             /* zero          */
index 6b907ed6de1fb1b1fc5b2beb5a0f6ac41e41f21f..910ea9aaff66da5602c70e931209dd118ea32c2b 100644 (file)
@@ -74,6 +74,7 @@
 #ifndef        LINUX_VERSION_CODE
 #include <linux/version.h>
 #endif
+#include <linux/types.h>
 
 #include "sd.h"
 
@@ -121,17 +122,13 @@ extern int i91u_biosparam(Scsi_Disk *, kdev_t, int *);    /*for linux v2.0 */
 #define ULONG   unsigned long
 #define USHORT  unsigned short
 #define UCHAR   unsigned char
-#define BYTE    unsigned char
+#define BYTE    u8
 #define WORD    unsigned short
 #define DWORD   unsigned long
-#define UBYTE   unsigned char
+#define UBYTE   u8
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32   unsigned int
-#else
-#define U32   unsigned long
-#endif
+#define U32   u32
 
 #ifndef NULL
 #define NULL     0             /* zero          */
index 800ebd42740aae3eae826bfa55be8eacea44c976..b965af0373b6f3672a72f4802b9e1cd2ffb76b72 100644 (file)
@@ -68,6 +68,8 @@
 #include <linux/version.h>
 #endif
 
+#include <linux/types.h>
+
 #include "sd.h"
 
 extern int inia100_detect(Scsi_Host_Template *);
@@ -122,11 +124,7 @@ extern int inia100_biosparam(Scsi_Disk *, kdev_t, int *);  /*for linux v2.0 */
 #define UBYTE   unsigned char
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32     unsigned int
-#else
-#define U32     unsigned long
-#endif
+#define U32     u32
 
 #ifndef NULL
 #define NULL     0             /* zero          */
index 0ef2a6befa854a59fb17b23581dafd892710df2b..dcfaabfcc13080bea76ca65164324e066aed4b1d 100644 (file)
@@ -23,7 +23,7 @@
 
 ***********************************************************************/
 
-/* $Id: nsp_cs.c,v 1.35 2001/07/05 16:58:24 elca Exp $ */
+/* $Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $ */
 
 #ifdef NSP_KERNEL_2_2
 #include <pcmcia/config.h>
 
 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
-MODULE_LICENSE("GPL");
-
 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
+MODULE_LICENSE("GPL");
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 MODULE_PARM_DESC(pc_debug, "set debug level");
-static char *version = "$Id: nsp_cs.c,v 1.35 2001/07/05 16:58:24 elca Exp $";
+static char *version = "$Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $";
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 #else
 #define DEBUG(n, args...) /* */
@@ -93,18 +92,6 @@ typedef struct scsi_info_t {
        struct bus_operations *bus;
 } scsi_info_t;
 
-static void nsp_cs_release(u_long arg);
-static int nsp_cs_event(event_t event, int priority,
-                    event_callback_args_t *args);
-static dev_link_t *nsp_cs_attach(void);
-static void nsp_cs_detach(dev_link_t *);
-static int nsp_detect(Scsi_Host_Template * );
-static int nsp_release(struct Scsi_Host *shpnt);
-static const char * nsp_info(struct Scsi_Host *shpnt);
-static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-static int nsp_abort(Scsi_Cmnd *);
-static int nsp_reset(Scsi_Cmnd *, unsigned int);
-
 
 /*----------------------------------------------------------------*/
 
@@ -191,7 +178,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
                data->CurrentSC = NULL;
                SCpnt->result   = DID_BAD_TARGET << 16;
                done(SCpnt);
-               return FALSE;
+               return -1;
        }
 
        show_command(SCpnt);
@@ -229,12 +216,12 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
                data->CurrentSC = NULL;
                SCpnt->result   = DID_NO_CONNECT << 16;
                done(SCpnt);
-               return FALSE;
+               return -1;
        }
 
 
        //DEBUG(0, __FUNCTION__ "() out\n");
-       return TRUE;
+       return 0;
 }
 
 /*
@@ -1185,7 +1172,7 @@ timer_out:
        return;
 }
 
-#ifdef DBG_SHOWCOMMAND
+#ifdef PCMCIA_DEBUG
 #include "nsp_debug.c"
 #endif /* DBG_SHOWCOMMAND */
 
@@ -1205,13 +1192,13 @@ static int nsp_detect(Scsi_Host_Template *sht)
        host->unique_id   = data->BaseAddress;
        host->n_io_port   = data->NumAddress;
        host->irq         = data->IrqNumber;
-       host->dma_channel = -1;
+       host->dma_channel = 0xff;             /* not use dms */
 
        sprintf(nspinfo,
 /* Buffer size is 100 bytes */
 /*  0         1         2         3         4         5         6         7         8         9         0*/
 /*  01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/
-   "NinjaSCSI-3/32Bi Driver version 2.7, I/O 0x%04lx-0x%04lx IRQ %2d",
+   "NinjaSCSI-3/32Bi Driver $Revision: 1.42 $, I/O 0x%04lx-0x%04lx IRQ %2d",
                host->io_port, host->io_port + host->n_io_port,
                host->irq);
        sht->name         = nspinfo;
@@ -1221,6 +1208,7 @@ static int nsp_detect(Scsi_Host_Template *sht)
        return 1; /* detect done. */
 }
 
+/* nsp_cs requires own release handler because its uses dev_id (=data) */
 static int nsp_release(struct Scsi_Host *shpnt)
 {
        nsp_hw_data *data = &nsp_data;
@@ -1228,7 +1216,7 @@ static int nsp_release(struct Scsi_Host *shpnt)
         if (shpnt->irq) {
                 free_irq(shpnt->irq, data);
        }
-        if (shpnt->io_port) {
+        if (shpnt->io_port && shpnt->n_io_port) {
                release_region(shpnt->io_port, shpnt->n_io_port);
        }
        return 0;
@@ -1249,7 +1237,9 @@ static int nsp_reset(Scsi_Cmnd *SCpnt, unsigned int why)
 {
        DEBUG(0, __FUNCTION__ " SCpnt=0x%p why=%d\n", SCpnt, why);
 
-       return nsp_eh_bus_reset(SCpnt);
+       nsp_eh_bus_reset(SCpnt);
+
+       return SCSI_RESET_SUCCESS;
 }
 
 static int nsp_abort(Scsi_Cmnd *SCpnt)
@@ -1258,7 +1248,7 @@ static int nsp_abort(Scsi_Cmnd *SCpnt)
 
        nsp_eh_bus_reset(SCpnt);
 
-       return SUCCESS;
+       return SCSI_ABORT_SUCCESS;
 }
 
 /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
@@ -1271,6 +1261,7 @@ static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
        DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
 
        nsp_eh_bus_reset(SCpnt);
+
        return SUCCESS;
 }
 
@@ -1309,9 +1300,8 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
        DEBUG(0, __FUNCTION__ "\n");
 
        nsphw_init(data);
-       nsp_eh_bus_reset(SCpnt);
 
-       return SUCCESS;
+       return nsp_eh_bus_reset(SCpnt);
 }
 
 
index 610ccfdecac80baece8eae5cce46c43340c24ac9..3b6303e21c252eb45e783727227bd03410b0aeba 100644 (file)
@@ -6,22 +6,17 @@
     Ver 0.1 : Initial version.
 
     This software may be used and distributed according to the terms of
-    the GNU Public License.
+    the GNU General Public License.
 
 =========================================================*/
 
-/* $Id: nsp_cs.h,v 1.21 2001/07/04 14:45:31 elca Exp $ */
+/* $Id: nsp_cs.h,v 1.27 2001/09/10 10:31:13 elca Exp $ */
 
 #ifndef  __nsp_cs__
 #define  __nsp_cs__
 
 /* for debugging */
-/*
-#define DBG
-#define DBG_PRINT
-#define DBG_SHOWCOMMAND
-#define PCMCIA_DEBUG 9
-*/
+/*#define PCMCIA_DEBUG 9*/
 
 /*
 #define static
@@ -258,25 +253,36 @@ typedef struct _nsp_data {
 } nsp_hw_data;
 
 
+static void nsp_cs_release(u_long arg);
+static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args);
+static dev_link_t *nsp_cs_attach(void);
+static void nsp_cs_detach(dev_link_t *);
+
 static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
 static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
 
+static int nsp_detect(Scsi_Host_Template * );
+static int nsp_release(struct Scsi_Host *shpnt);
+static const char * nsp_info(struct Scsi_Host *shpnt);
+static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
+
+static int nsp_abort(Scsi_Cmnd *);
+static int nsp_reset(Scsi_Cmnd *, unsigned int);
+
 static int nsp_eh_abort(Scsi_Cmnd * SCpnt);
 static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);
 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt);
 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt);
 
-static int nsp_fifo_count(Scsi_Cmnd *SCpnt);
+static int  nsp_fifo_count(Scsi_Cmnd *SCpnt);
 static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
-static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
+static int  nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
 
 #ifdef PCMCIA_DEBUG
-# ifdef DBG_SHOWCOMMAND
 static void show_command(Scsi_Cmnd *ptr);
 static void show_phase(Scsi_Cmnd *SCpnt);
 static void show_busphase(unsigned char stat);
 static void show_message(nsp_hw_data *data);
-# endif /* DBG_SHOWCOMMAND */
 #else
 # define show_command(ptr)   /* */
 # define show_phase(SCpnt)   /* */
index 8d45bb3fca3c83a3cf2b4c9b0193c60cf9c1cfd7..0dbf3cddf380109913d78dcdcd5d039882e92e33 100644 (file)
@@ -6,7 +6,7 @@
     the GNU General Public License.
 =========================================================================*/
 
-/* $Id: nsp_debug.c,v 1.6 2001/07/04 14:43:53 elca Exp $ */
+/* $Id: nsp_debug.c,v 1.8 2001/09/07 04:32:28 elca Exp $ */
 
 /*
  * Show the command data of a command
@@ -85,7 +85,7 @@ static void print_opcodek(unsigned char opcode)
        }
 }
 
-void print_commandk (unsigned char *command)
+static void print_commandk (unsigned char *command)
 {
        int i,s;
        printk(KERN_DEBUG);
index a26358dd56b2f54b0d319c654adf5a020d902399..898565746df35c52b25ed25b281d91a7b227b472 100644 (file)
@@ -3,11 +3,11 @@
       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
  
   This software may be used and distributed according to the terms of
-  the GNU Public License.
+  the GNU General Public License.
 
   */
 
-/* $Id: nsp_io.h,v 1.8 2001/01/30 05:16:02 elca Exp $ */
+/* $Id: nsp_io.h,v 1.9 2001/09/07 04:32:42 elca Exp $ */
 
 #ifndef __NSP_IO_H__
 #define __NSP_IO_H__
index 8c765953d6cf4ef451c9fb0014869cc3d9ba65fc..a2cdba1b5ee40977bf40007b210176c848110193 100644 (file)
@@ -6,7 +6,7 @@
    the GNU General Public License.
  */
 
-/* $Id: nsp_message.c,v 1.6 2001/07/05 10:56:37 elca Exp $ */
+/* $Id: nsp_message.c,v 1.7 2001/09/07 04:33:01 elca Exp $ */
 
 static void nsp_message_in(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
 {
index 737ed73ba0a17a9009b1a733d7bbcba10fd71457..ad3e31af55b314359731325b0174b8cf1c3c34b2 100644 (file)
@@ -421,6 +421,10 @@ void scan_scsis(struct Scsi_Host *shpnt,
                                         max_scsi_luns : shpnt->max_lun);
                                        sparse_lun = 0;
                                        for (lun = 0, lun0_sl = SCSI_2; lun < max_dev_lun; ++lun) {
+                                               /* don't probe further for luns > 7 for targets <= SCSI_2 */
+                                               if ((lun0_sl < SCSI_3) && (lun > 7))
+                                                       break;
+
                                                if (!scan_scsis_single(channel, order_dev, lun, lun0_sl,
                                                                       &max_dev_lun, &sparse_lun, &SDpnt, shpnt,
                                                                       scsi_result)
index 6cd3b1a5d551c744439fae929162de6db640ab1c..ed05e32b6008ce0b8865cb35af61ae833e88e415 100644 (file)
@@ -786,7 +786,7 @@ static int sd_init_onedisk(int i)
                        SRpnt->sr_cmd_len = 0;
                        SRpnt->sr_sense_buffer[0] = 0;
                        SRpnt->sr_sense_buffer[2] = 0;
-                       SRpnt->sr_data_direction = SCSI_DATA_READ;
+                       SRpnt->sr_data_direction = SCSI_DATA_NONE;
 
                        scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
                                0/*512*/, SD_TIMEOUT, MAX_RETRIES);
index 4f1ab28616d4729dc235751b0ef3e94147c95704..97b247fa30f31991b8aacb5a10ca7b258e36a949 100644 (file)
@@ -343,6 +343,8 @@ void __init gfx_init (const char **name)
 }
 
 #ifdef MODULE
+MODULE_LICENSE("GPL");
+
 int init_module(void) {
        static int initiated = 0;
 
index d0c9262c81e56d5150578f255718073679b23467..07133ec491d271c0f0b821ee7bc3298bb9e9e07a 100644 (file)
@@ -74,6 +74,7 @@
  *    18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it
  *                was calling prog_dmabuf with s->lock held, call missing
  *                unlock_kernel in cm_midi_release
+ *    08/10/2001 - use set_current_state in some more places
  *
  *     Carlos Eduardo Gorges <carlos@techlinux.com.br>
  *     Fri May 25 2001 
@@ -1483,7 +1484,7 @@ static int drain_dac(struct cm_state *s, int nonblock)
 
        if (s->dma_dac.mapped || !s->dma_dac.ready)
                return 0;
-        current->state = TASK_INTERRUPTIBLE;
+        set_current_state(TASK_INTERRUPTIBLE);
         add_wait_queue(&s->dma_dac.wait, &wait);
         for (;;) {
                 spin_lock_irqsave(&s->lock, flags);
@@ -1495,7 +1496,7 @@ static int drain_dac(struct cm_state *s, int nonblock)
                         break;
                 if (nonblock) {
                         remove_wait_queue(&s->dma_dac.wait, &wait);
-                        current->state = TASK_RUNNING;
+                        set_current_state(TASK_RUNNING);
                         return -EBUSY;
                 }
                tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
@@ -1504,7 +1505,7 @@ static int drain_dac(struct cm_state *s, int nonblock)
                        printk(KERN_DEBUG "cmpci: dma timed out??\n");
         }
         remove_wait_queue(&s->dma_dac.wait, &wait);
-        current->state = TASK_RUNNING;
+        set_current_state(TASK_RUNNING);
         if (signal_pending(current))
                 return -ERESTARTSYS;
         return 0;
index bf07c16eab38503ab284003265697494fe2c515e..e467733979ba717c4964f29491b7c8b364839337 100644 (file)
@@ -58,7 +58,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/sound.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/soundcard.h>
 #include <linux/pci.h>
 #include <linux/init.h>
index 2de6518d55bfe5e0ae9360441b57bff28ccc8d12..1ed8cc63892d463deaa860de805d60c8065cf309 100644 (file)
 #define SND_DEV_DSP16       5 
    
 #ifdef M_DEBUG
-static int debug=0;
+static int debug;
 #define DPMOD   1   /* per module load */
 #define DPSTR   2   /* per 'stream' */
 #define DPSYS   3   /* per syscall */
@@ -365,7 +365,7 @@ ld2(unsigned int x)
     return r;
 }
 
-static struct m3_card *devs = NULL;
+static struct m3_card *devs;
 
 /*
  * I'm not very good at laying out functions in a file :)
@@ -1289,7 +1289,7 @@ static int drain_dac(struct m3_state *s, int nonblock)
 
     if (s->dma_dac.mapped || !s->dma_dac.ready)
         return 0;
-    current->state = TASK_INTERRUPTIBLE;
+    set_current_state(TASK_INTERRUPTIBLE);
     add_wait_queue(&s->dma_dac.wait, &wait);
     for (;;) {
         spin_lock_irqsave(&s->lock, flags);
@@ -1301,7 +1301,7 @@ static int drain_dac(struct m3_state *s, int nonblock)
             break;
         if (nonblock) {
             remove_wait_queue(&s->dma_dac.wait, &wait);
-            current->state = TASK_RUNNING;
+            set_current_state(TASK_RUNNING);
             return -EBUSY;
         }
         tmo = (count * HZ) / s->ratedac;
@@ -1312,7 +1312,7 @@ static int drain_dac(struct m3_state *s, int nonblock)
             DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);
     }
     remove_wait_queue(&s->dma_dac.wait, &wait);
-    current->state = TASK_RUNNING;
+    set_current_state(TASK_RUNNING);
     if (signal_pending(current))
             return -ERESTARTSYS;
     return 0;
@@ -2251,7 +2251,7 @@ static void m3_codec_reset(struct m3_card *card, int busywait)
         if(busywait)  {
             mdelay(delay1);
         } else {
-            current->state = TASK_UNINTERRUPTIBLE;
+            set_current_state(TASK_UNINTERRUPTIBLE);
             schedule_timeout((delay1 * HZ) / 1000);
         }
 
@@ -2264,7 +2264,7 @@ static void m3_codec_reset(struct m3_card *card, int busywait)
         if(busywait) {
             mdelay(delay2);
         } else {
-            current->state = TASK_UNINTERRUPTIBLE;
+            set_current_state(TASK_UNINTERRUPTIBLE);
             schedule_timeout((delay2 * HZ) / 1000);
         }
         if(! try_read_vendor(card))
@@ -2958,8 +2958,8 @@ void check_suspend(struct m3_card *card)
 
     card->in_suspend++;
     add_wait_queue(&card->suspend_queue, &wait);
-    current->state = TASK_UNINTERRUPTIBLE;
+    set_current_state(TASK_UNINTERRUPTIBLE);
     schedule();
     remove_wait_queue(&card->suspend_queue, &wait);
-    current->state = TASK_RUNNING;
+    set_current_state(TASK_RUNNING);
 }
index 8a81f5f6aa5f8d4d3a43abc4f6d4a3bcc2ec8d6b..20bb12bf570607fdecec62943e090cb6eb1b90fb 100644 (file)
@@ -67,7 +67,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/sound.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/soundcard.h>
 #include <linux/pci.h>
 #include <linux/init.h>
index 7791f2cad1ea75fe18aa94a5e4833ceb246e554e..153d270fa35987f789b72958e479ad0581769012 100644 (file)
@@ -862,9 +862,9 @@ static int __init opl3sa2_isapnp_probe(struct address_info* hw_cfg,
 
        /* Our own config: */
        hw_cfg->io_base = dev->resource[4].start;
-       hw_cfg->irq     = 0;
-       hw_cfg->dma     = -1;
-       hw_cfg->dma2    = -1;
+       hw_cfg->irq     = dev->irq_resource[0].start;
+       hw_cfg->dma     = dev->dma_resource[0].start;
+       hw_cfg->dma2    = dev->dma_resource[1].start;
        
        /* The MSS config: */
        mss_cfg->io_base      = dev->resource[1].start;
@@ -944,9 +944,9 @@ static int __init init_opl3sa2(void)
                         *  give pretty output from conf_printf. :)
                         */
                        cfg[card].io_base = io;
-                       cfg[card].irq     = 0;
-                       cfg[card].dma     = -1;
-                       cfg[card].dma2    = -1;
+                       cfg[card].irq     = irq;
+                       cfg[card].dma     = dma;
+                       cfg[card].dma2    = dma2;
        
                        /* The MSS config: */
                        cfg_mss[card].io_base      = mss_io;
index 43945c4a68148e29cd41577b7739a9112a1f28b9..7234d4f500e2a1bf8c42445302fb49b3615550a4 100644 (file)
@@ -53,6 +53,9 @@
  *
  * 28-10-2000 Added pnplegacy support
  *     Daniel Church <dchurch@mbhs.edu>
+ *
+ * 01-10-2001 Added a new flavor of Creative SB AWE64 PnP (CTL00E9).
+ *      Jerome Cornet <jcornet@free.fr>
  */
 
 #include <linux/config.h>
@@ -434,6 +437,11 @@ static struct {
                ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
                0,0,0,0,
                0,1,1,-1},
+       {"Sound Blaster AWE 64",
+               ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9), 
+               ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
+               0,0,0,0,
+               0,1,1,-1},
        {"ESS 1688",
                ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968), 
                ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968),
@@ -623,6 +631,9 @@ static struct isapnp_device_id id_table[] __devinitdata = {
        {       ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4), 
                ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
 
+       {       ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
+               ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
+
        {       ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968), 
                ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968), 0 },
 
index 13971cc5022a6ea29c5d0b5b55f6320b9b3c4d0b..7a5b503c31852983ab8a877a14fe7ec2bcfcc5ac 100644 (file)
  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.14.9d
+ *     October 8 2001 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *     use set_current_state, properly release resources on failure in
+ *     trident_probe, get rid of check_region
  *  v0.14.9c
  *     August 10 2001 Peter Wächtler <pwaechtler@loewe-komp.de>
  *     added support for Tvia (formerly Integraphics/IGST) CyberPro5050
 
 #include <linux/pm.h>
 
-#define DRIVER_VERSION "0.14.9c"
+#define DRIVER_VERSION "0.14.9d"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC     0x5072696E /* "Prin" */
@@ -1358,7 +1362,7 @@ static int drain_dac(struct trident_state *state, int nonblock)
        for (;;) {
                /* It seems that we have to set the current state to TASK_INTERRUPTIBLE
                   every time to make the process really go to sleep */
-               current->state = TASK_INTERRUPTIBLE;
+               set_current_state(TASK_INTERRUPTIBLE);
 
                spin_lock_irqsave(&state->card->lock, flags);
                count = dmabuf->count;
@@ -1372,7 +1376,7 @@ static int drain_dac(struct trident_state *state, int nonblock)
 
                if (nonblock) {
                        remove_wait_queue(&dmabuf->wait, &wait);
-                       current->state = TASK_RUNNING;
+                       set_current_state(TASK_RUNNING);
                        return -EBUSY;
                }
 
@@ -1395,7 +1399,7 @@ static int drain_dac(struct trident_state *state, int nonblock)
                }
        }
        remove_wait_queue(&dmabuf->wait, &wait);
-       current->state = TASK_RUNNING;
+       set_current_state(TASK_RUNNING);
        if (signal_pending(current))
                return -ERESTARTSYS;
 
@@ -3695,7 +3699,7 @@ static void ali_free_other_states_resources(struct trident_state *state)
 }
 
 #ifdef CONFIG_PROC_FS
-struct proc_dir_entry *res = NULL;
+struct proc_dir_entry *res;
 static int ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
 {
        struct trident_card *card = (struct trident_card *)data;
@@ -3936,14 +3940,15 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
        int i = 0;
        u16 temp;
        struct pci_dev *pci_dev_m1533 = NULL;
+       int rc = -ENODEV;
 
        if (pci_enable_device(pci_dev))
-               return -ENODEV;
+               goto out;
 
        if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
                printk(KERN_ERR "trident: architecture does not support"
                       " 30bit PCI busmaster DMA\n");
-               return -ENODEV;
+               goto out;
        }
        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
 
@@ -3952,15 +3957,16 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
        else
                iobase = pci_resource_start(pci_dev, 0);
 
-       if (check_region(iobase, 256)) {
+       if (!request_region(iobase, 256, card_names[pci_id->driver_data])) {
                printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
                       iobase);
-               return -ENODEV;
+               goto out;
        }
 
+       rc = -ENOMEM;
        if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) {
                printk(KERN_ERR "trident: out of memory\n");
-               return -ENOMEM;
+               goto out_release_region;
        }
        memset(card, 0, sizeof(*card));
 
@@ -4014,8 +4020,9 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
                /* Add H/W Volume Control By Matt Wu Jul. 06, 2001 */
                card->hwvolctl = 0;
                pci_dev_m1533 = pci_find_device(PCI_VENDOR_ID_AL,PCI_DEVICE_ID_AL_M1533, pci_dev_m1533);
+               rc = -ENODEV;
                if (pci_dev_m1533 == NULL)
-                       return -ENODEV;
+                       goto out_proc_fs;
                pci_read_config_byte(pci_dev_m1533, 0x63, &bits);
                if (bits & (1<<5))
                        card->hwvolctl = 1;
@@ -4044,22 +4051,17 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
                card->address_interrupt = trident_address_interrupt;
        }
 
-       /* claim our iospace and irq */
-       request_region(card->iobase, 256, card_names[pci_id->driver_data]);
+       /* claim our irq */
+       rc = -ENODEV;
        if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ,
                        card_names[pci_id->driver_data], card)) {
                printk(KERN_ERR "trident: unable to allocate irq %d\n", card->irq);
-               release_region(card->iobase, 256);
-               kfree(card);
-               return -ENODEV;
+               goto out_proc_fs;
        }
        /* register /dev/dsp */
        if ((card->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0) {
                printk(KERN_ERR "trident: couldn't register DSP device!\n");
-               release_region(iobase, 256);
-               free_irq(card->irq, card);
-               kfree(card);
-               return -ENODEV;
+               goto out_free_irq;
        }
        card->mixer_regs_ready = 0;
        /* initialize AC97 codec and register /dev/mixer */
@@ -4071,11 +4073,7 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
                                kfree (card->ac97_codec[i]);
                        }
                }
-               unregister_sound_dsp(card->dev_audio);
-               release_region(iobase, 256);
-               free_irq(card->irq, card);
-               kfree(card);
-               return -ENODEV;
+               goto out_unregister_sound_dsp;
        }
        card->mixer_regs_ready = 1;
        outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
@@ -4112,13 +4110,28 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
 #endif
                /* edited by HMSEO for GT sound*/
        }
-
+       rc = 0;
        pci_set_drvdata(pci_dev, card);
 
        /* Enable Address Engine Interrupts */
        trident_enable_loop_interrupts(card);
-
-       return 0;
+out:   return rc;
+out_unregister_sound_dsp:
+       unregister_sound_dsp(card->dev_audio);
+out_free_irq:
+       free_irq(card->irq, card);
+out_proc_fs:
+#ifdef CONFIG_PROC_FS
+       if (res) {
+               remove_proc_entry("ALi5451", NULL);
+               res = NULL;
+       }
+#endif
+       kfree(card);
+       devs = NULL;
+out_release_region:
+       release_region(iobase, 256);
+       goto out;
 }
 
 static void __exit trident_remove(struct pci_dev *pci_dev)
index 738873a7983e1e6daf14de40eb20c0951684eb9f..3c6d1e1af5a855919b94abd3c4092543286bdea4 100644 (file)
@@ -542,3 +542,8 @@ static void __exit cleanup_vidc(void)
 
 module_init(init_vidc);
 module_exit(cleanup_vidc);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("VIDC20 audio driver");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 8938abfa8d556a5c4bffafc1ab3fcc8eee9568a2..36965ed83710ef03a02c3b25335515e6ac73686c 100644 (file)
@@ -25,6 +25,7 @@
 
 #define TC_DEBUG
 
+MODULE_LICENSE("GPL");
 slot_info tc_bus[MAX_SLOT];
 static int max_tcslot;
 static tcinfo *info;
index b94676cf945c24877d4d1d790a76aa28650789fa..d928e72bd0680d69471df4c513f5f2e822e0773b 100644 (file)
@@ -2565,7 +2565,7 @@ static void release_uhci(struct uhci *uhci)
 static int alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io_size)
 {
        struct uhci *uhci;
-       int retval = -EBUSY;
+       int retval;
        char buf[8], *bufp = buf;
        int i, port;
        struct usb_bus *bus;
@@ -2574,27 +2574,27 @@ static int alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io
        struct proc_dir_entry *ent;
 #endif
 
-       if (!request_region(io_addr, io_size, "usb-uhci")) {
-               err("couldn't allocate I/O range %x - %x", io_addr,
-                       io_addr + io_size - 1);
-               goto err_request_region;
+       retval = -ENODEV;
+       if (pci_enable_device(dev) < 0) {
+               err("couldn't enable PCI device");
+               goto err_enable_device;
        }
 
        if (!dev->irq) {
                err("found UHCI device with no IRQ assigned. check BIOS settings!");
-               retval = -EINVAL;
                goto err_invalid_irq;
        }
 
        if (!pci_dma_supported(dev, 0xFFFFFFFF)) {
                err("PCI subsystem doesn't support 32 bit addressing?");
-               retval = -ENODEV;
                goto err_pci_dma_supported;
        }
 
-       if (pci_enable_device(dev) < 0) {
-               err("couldn't enable PCI device");
-               goto err_enable_device;
+       retval = -EBUSY;
+       if (!request_region(io_addr, io_size, "usb-uhci")) {
+               err("couldn't allocate I/O range %x - %x", io_addr,
+                       io_addr + io_size - 1);
+               goto err_request_region;
        }
 
        pci_set_master(dev);
@@ -2897,15 +2897,15 @@ err_create_proc_entry:
 err_alloc_uhci:
 
 err_pci_set_dma_mask:
+       release_region(io_addr, io_size);
 
-err_enable_device:
+err_request_region:
 
 err_pci_dma_supported:
-       release_region(io_addr, io_size);
 
 err_invalid_irq:
 
-err_request_region:
+err_enable_device:
 
        return retval;
 }
index f5eb439b6c32b20d299e93e2e2d38d5533a2e622..9020a278f3017a2849d01a4761c028e4979c8bb9 100644 (file)
@@ -1772,4 +1772,7 @@ acornfb_init(void)
        return 0;
 }
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("VIDC 1/1a/20 framebuffer driver");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 33b7078d7b52b4e5736f26e28599eccaaa599291..cc442e37b140eb7f8530a05ccb79ebc6c8d8c073 100644 (file)
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 1998-2000 Russell King
  *
+ *  MIPS and 50xx clock support
+ *  Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.com>
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
 /*#define CFB16_IS_CFB15*/
 
-static char                    *CyberRegs;
-
 #include "cyber2000fb.h"
 
 struct cfb_info {
        struct fb_info          fb;
        struct display_switch   *dispsw;
        struct pci_dev          *dev;
+       unsigned char           *region;
+       unsigned char           *regs;
        signed int              currcon;
        int                     func_use_count;
        u_long                  ref_ps;
@@ -80,19 +83,67 @@ struct cfb_info {
        u_char                  mclk_div;
 };
 
+static char default_font_storage[40];
+static char *default_font = "Acorn8x8";
+MODULE_PARM(default_font, "s");
+MODULE_PARM_DESC(default_font, "Default font name");
+
+/*
+ * Our access methods.
+ */
+#define cyber2000fb_writel(val,reg,cfb)        writel(val, (cfb)->regs + (reg))
+#define cyber2000fb_writew(val,reg,cfb)        writew(val, (cfb)->regs + (reg))
+#define cyber2000fb_writeb(val,reg,cfb)        writeb(val, (cfb)->regs + (reg))
+
+#define cyber2000fb_readb(reg,cfb)     readb((cfb)->regs + (reg))
+
+static inline void
+cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+       cyber2000fb_writew((reg & 255) | val << 8, 0x3d4, cfb);
+}
+
+static inline void
+cyber2000_grphw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+       cyber2000fb_writew((reg & 255) | val << 8, 0x3ce, cfb);
+}
+
+static inline unsigned int
+cyber2000_grphr(unsigned int reg, struct cfb_info *cfb)
+{
+       cyber2000fb_writeb(reg, 0x3ce, cfb);
+       return cyber2000fb_readb(0x3cf, cfb);
+}
+
+static inline void
+cyber2000_attrw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+       cyber2000fb_readb(0x3da, cfb);
+       cyber2000fb_writeb(reg, 0x3c0, cfb);
+       cyber2000fb_readb(0x3c1, cfb);
+       cyber2000fb_writeb(val, 0x3c0, cfb);
+}
+
+static inline void
+cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+       cyber2000fb_writew((reg & 255) | val << 8, 0x3c4, cfb);
+}
+
 /* -------------------- Hardware specific routines ------------------------- */
 
 /*
  * Hardware Cyber2000 Acceleration
  */
-static void cyber2000_accel_wait(void)
+static void cyber2000_accel_wait(struct cfb_info *cfb)
 {
        int count = 100000;
 
-       while (cyber2000_inb(CO_REG_CONTROL) & 0x80) {
+       while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & 0x80) {
                if (!count--) {
                        debug_printf("accel_wait timed out\n");
-                       cyber2000_outb(0, CO_REG_CONTROL);
+                       cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
                        return;
                }
                udelay(1);
@@ -110,6 +161,7 @@ static void
 cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
                      int height, int width)
 {
+       struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
        struct fb_var_screeninfo *var = &p->fb_info->var;
        u_long src, dst;
        u_int fh, fw;
@@ -142,29 +194,30 @@ cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
        src    = sx + sy * var->xres_virtual;
        dst    = dx + dy * var->xres_virtual;
 
-       cyber2000_accel_wait();
-       cyber2000_outb(0x00,  CO_REG_CONTROL);
-       cyber2000_outb(0x03,  CO_REG_FORE_MIX);
-       cyber2000_outw(width, CO_REG_WIDTH);
+       cyber2000_accel_wait(cfb);
+       cyber2000fb_writeb(0x00,  CO_REG_CONTROL, cfb);
+       cyber2000fb_writeb(0x03,  CO_REG_FORE_MIX, cfb);
+       cyber2000fb_writew(width, CO_REG_WIDTH, cfb);
 
        if (var->bits_per_pixel != 24) {
-               cyber2000_outl(dst, CO_REG_DEST_PTR);
-               cyber2000_outl(src, CO_REG_SRC_PTR);
+               cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
+               cyber2000fb_writel(src, CO_REG_SRC_PTR, cfb);
        } else {
-               cyber2000_outl(dst * 3, CO_REG_DEST_PTR);
-               cyber2000_outb(dst,     CO_REG_X_PHASE);
-               cyber2000_outl(src * 3, CO_REG_SRC_PTR);
+               cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
+               cyber2000fb_writeb(dst,     CO_REG_X_PHASE, cfb);
+               cyber2000fb_writel(src * 3, CO_REG_SRC_PTR, cfb);
        }
 
-       cyber2000_outw(height, CO_REG_HEIGHT);
-       cyber2000_outw(cmd,    CO_REG_CMD_L);
-       cyber2000_outw(0x2800, CO_REG_CMD_H);
+       cyber2000fb_writew(height, CO_REG_HEIGHT, cfb);
+       cyber2000fb_writew(cmd,    CO_REG_CMD_L, cfb);
+       cyber2000fb_writew(0x2800, CO_REG_CMD_H, cfb);
 }
 
 static void
 cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
                      int height, int width)
 {
+       struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
        struct fb_var_screeninfo *var = &p->fb_info->var;
        u_long dst;
        u_int fw, fh;
@@ -177,30 +230,30 @@ cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
        width  = width * fw - 1;
        height = height * fh - 1;
 
-       cyber2000_accel_wait();
-       cyber2000_outb(0x00,   CO_REG_CONTROL);
-       cyber2000_outb(0x03,   CO_REG_FORE_MIX);
-       cyber2000_outw(width,  CO_REG_WIDTH);
-       cyber2000_outw(height, CO_REG_HEIGHT);
+       cyber2000_accel_wait(cfb);
+       cyber2000fb_writeb(0x00,   CO_REG_CONTROL,  cfb);
+       cyber2000fb_writeb(0x03,   CO_REG_FORE_MIX, cfb);
+       cyber2000fb_writew(width,  CO_REG_WIDTH,    cfb);
+       cyber2000fb_writew(height, CO_REG_HEIGHT,   cfb);
 
        switch (var->bits_per_pixel) {
        case 15:
        case 16:
                bgx = ((u16 *)p->dispsw_data)[bgx];
        case 8:
-               cyber2000_outl(dst, CO_REG_DEST_PTR);
+               cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
                break;
 
        case 24:
-               cyber2000_outl(dst * 3, CO_REG_DEST_PTR);
-               cyber2000_outb(dst, CO_REG_X_PHASE);
+               cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
+               cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
                bgx = ((u32 *)p->dispsw_data)[bgx];
                break;
        }
 
-       cyber2000_outl(bgx, CO_REG_FOREGROUND);
-       cyber2000_outw(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L);
-       cyber2000_outw(0x0800, CO_REG_CMD_H);
+       cyber2000fb_writel(bgx, CO_REG_FOREGROUND, cfb);
+       cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
+       cyber2000fb_writew(0x0800, CO_REG_CMD_H, cfb);
 }
 
 static void
@@ -209,7 +262,7 @@ cyber2000_accel_putc(struct vc_data *conp, struct display *p, int c,
 {
        struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 
-       cyber2000_accel_wait();
+       cyber2000_accel_wait(cfb);
        cfb->dispsw->putc(conp, p, c, yy, xx);
 }
 
@@ -219,7 +272,7 @@ cyber2000_accel_putcs(struct vc_data *conp, struct display *p,
 {
        struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 
-       cyber2000_accel_wait();
+       cyber2000_accel_wait(cfb);
        cfb->dispsw->putcs(conp, p, s, count, yy, xx);
 }
 
@@ -227,7 +280,7 @@ static void cyber2000_accel_revc(struct display *p, int xx, int yy)
 {
        struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 
-       cyber2000_accel_wait();
+       cyber2000_accel_wait(cfb);
        cfb->dispsw->revc(p, xx, yy);
 }
 
@@ -274,10 +327,10 @@ cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
        switch (cfb->fb.var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
        case 8:
-               cyber2000_outb(regno, 0x3c8);
-               cyber2000_outb(red,   0x3c9);
-               cyber2000_outb(green, 0x3c9);
-               cyber2000_outb(blue,  0x3c9);
+               cyber2000fb_writeb(regno, 0x3c8, cfb);
+               cyber2000fb_writeb(red,   0x3c9, cfb);
+               cyber2000fb_writeb(green, 0x3c9, cfb);
+               cyber2000fb_writeb(blue,  0x3c9, cfb);
                break;
 #endif
 
@@ -286,18 +339,18 @@ cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 #ifndef CFB16_IS_CFB15
                if (regno < 64) {
                        /* write green */
-                       cyber2000_outb(regno << 2, 0x3c8);
-                       cyber2000_outb(cfb->palette[regno >> 1].red, 0x3c9);
-                       cyber2000_outb(green, 0x3c9);
-                       cyber2000_outb(cfb->palette[regno >> 1].blue, 0x3c9);
+                       cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
+                       cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb);
+                       cyber2000fb_writeb(green, 0x3c9, cfb);
+                       cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb);
                }
 
                if (regno < 32) {
                        /* write red,blue */
-                       cyber2000_outb(regno << 3, 0x3c8);
-                       cyber2000_outb(red, 0x3c9);
-                       cyber2000_outb(cfb->palette[regno << 1].green, 0x3c9);
-                       cyber2000_outb(blue, 0x3c9);
+                       cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
+                       cyber2000fb_writeb(red, 0x3c9, cfb);
+                       cyber2000fb_writeb(cfb->palette[regno << 1].green, 0x3c9, cfb);
+                       cyber2000fb_writeb(blue, 0x3c9, cfb);
                }
 
                if (regno < 16)
@@ -308,10 +361,10 @@ cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
        case 15:
                if (regno < 32) {
-                       cyber2000_outb(regno << 3, 0x3c8);
-                       cyber2000_outb(red, 0x3c9);
-                       cyber2000_outb(green, 0x3c9);
-                       cyber2000_outb(blue, 0x3c9);
+                       cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
+                       cyber2000fb_writeb(red, 0x3c9, cfb);
+                       cyber2000fb_writeb(green, 0x3c9, cfb);
+                       cyber2000fb_writeb(blue, 0x3c9, cfb);
                }
                if (regno < 16)
                        ((u16 *)cfb->fb.pseudo_palette)[regno] =
@@ -322,10 +375,10 @@ cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
 #ifdef FBCON_HAS_CFB24
        case 24:
-               cyber2000_outb(regno, 0x3c8);
-               cyber2000_outb(red,   0x3c9);
-               cyber2000_outb(green, 0x3c9);
-               cyber2000_outb(blue,  0x3c9);
+               cyber2000fb_writeb(regno, 0x3c8, cfb);
+               cyber2000fb_writeb(red,   0x3c9, cfb);
+               cyber2000fb_writeb(green, 0x3c9, cfb);
+               cyber2000fb_writeb(blue,  0x3c9, cfb);
 
                if (regno < 16)
                        ((u32 *)cfb->fb.pseudo_palette)[regno] =
@@ -375,92 +428,92 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
         * Blank palette
         */
        for (i = 0; i < NR_PALETTE; i++) {
-               cyber2000_outb(i, 0x3c8);
-               cyber2000_outb(0, 0x3c9);
-               cyber2000_outb(0, 0x3c9);
-               cyber2000_outb(0, 0x3c9);
+               cyber2000fb_writeb(i, 0x3c8, cfb);
+               cyber2000fb_writeb(0, 0x3c9, cfb);
+               cyber2000fb_writeb(0, 0x3c9, cfb);
+               cyber2000fb_writeb(0, 0x3c9, cfb);
        }
 
-       cyber2000_outb(0xef, 0x3c2);
-       cyber2000_crtcw(0x11, 0x0b);
-       cyber2000_attrw(0x11, 0x00);
+       cyber2000fb_writeb(0xef, 0x3c2, cfb);
+       cyber2000_crtcw(0x11, 0x0b, cfb);
+       cyber2000_attrw(0x11, 0x00, cfb);
 
-       cyber2000_seqw(0x00, 0x01);
-       cyber2000_seqw(0x01, 0x01);
-       cyber2000_seqw(0x02, 0x0f);
-       cyber2000_seqw(0x03, 0x00);
-       cyber2000_seqw(0x04, 0x0e);
-       cyber2000_seqw(0x00, 0x03);
+       cyber2000_seqw(0x00, 0x01, cfb);
+       cyber2000_seqw(0x01, 0x01, cfb);
+       cyber2000_seqw(0x02, 0x0f, cfb);
+       cyber2000_seqw(0x03, 0x00, cfb);
+       cyber2000_seqw(0x04, 0x0e, cfb);
+       cyber2000_seqw(0x00, 0x03, cfb);
 
        for (i = 0; i < sizeof(crtc_idx); i++)
-               cyber2000_crtcw(crtc_idx[i], hw->crtc[i]);
+               cyber2000_crtcw(crtc_idx[i], hw->crtc[i], cfb);
 
        for (i = 0x0a; i < 0x10; i++)
-               cyber2000_crtcw(i, 0);
-
-       cyber2000_grphw(0x11, hw->crtc_ofl);
-       cyber2000_grphw(0x00, 0x00);
-       cyber2000_grphw(0x01, 0x00);
-       cyber2000_grphw(0x02, 0x00);
-       cyber2000_grphw(0x03, 0x00);
-       cyber2000_grphw(0x04, 0x00);
-       cyber2000_grphw(0x05, 0x60);
-       cyber2000_grphw(0x06, 0x05);
-       cyber2000_grphw(0x07, 0x0f);
-       cyber2000_grphw(0x08, 0xff);
+               cyber2000_crtcw(i, 0, cfb);
+
+       cyber2000_grphw(0x11, hw->crtc_ofl, cfb);
+       cyber2000_grphw(0x00, 0x00, cfb);
+       cyber2000_grphw(0x01, 0x00, cfb);
+       cyber2000_grphw(0x02, 0x00, cfb);
+       cyber2000_grphw(0x03, 0x00, cfb);
+       cyber2000_grphw(0x04, 0x00, cfb);
+       cyber2000_grphw(0x05, 0x60, cfb);
+       cyber2000_grphw(0x06, 0x05, cfb);
+       cyber2000_grphw(0x07, 0x0f, cfb);
+       cyber2000_grphw(0x08, 0xff, cfb);
 
        /* Attribute controller registers */
        for (i = 0; i < 16; i++)
-               cyber2000_attrw(i, i);
+               cyber2000_attrw(i, i, cfb);
 
-       cyber2000_attrw(0x10, 0x01);
-       cyber2000_attrw(0x11, 0x00);
-       cyber2000_attrw(0x12, 0x0f);
-       cyber2000_attrw(0x13, 0x00);
-       cyber2000_attrw(0x14, 0x00);
+       cyber2000_attrw(0x10, 0x01, cfb);
+       cyber2000_attrw(0x11, 0x00, cfb);
+       cyber2000_attrw(0x12, 0x0f, cfb);
+       cyber2000_attrw(0x13, 0x00, cfb);
+       cyber2000_attrw(0x14, 0x00, cfb);
 
        /* woody: set the interlaced bit... */
        /* FIXME: what about doublescan? */
-       cyber2000_outb(0x11, 0x3ce);
-       i = cyber2000_inb(0x3cf);
+       cyber2000fb_writeb(0x11, 0x3ce, cfb);
+       i = cyber2000fb_readb(0x3cf, cfb);
        if (hw->vmode == FB_VMODE_INTERLACED)
                i |= 0x20;
        else
                i &= ~0x20;
-       cyber2000_outb(i, 0x3cf);
+       cyber2000fb_writeb(i, 0x3cf, cfb);
 
        /* PLL registers */
-       cyber2000_grphw(DCLK_MULT, hw->clock_mult);
-       cyber2000_grphw(DCLK_DIV,  hw->clock_div);
-       cyber2000_grphw(MCLK_MULT, cfb->mclk_mult);
-       cyber2000_grphw(MCLK_DIV,  cfb->mclk_div);
-       cyber2000_grphw(0x90, 0x01);
-       cyber2000_grphw(0xb9, 0x80);
-       cyber2000_grphw(0xb9, 0x00);
-
-       cyber2000_outb(0x56, 0x3ce);
-       i = cyber2000_inb(0x3cf);
-       cyber2000_outb(i | 4, 0x3cf);
-       cyber2000_outb(hw->palette_ctrl, 0x3c6);
-       cyber2000_outb(i,    0x3cf);
-
-       cyber2000_outb(0x20, 0x3c0);
-       cyber2000_outb(0xff, 0x3c6);
-
-       cyber2000_grphw(0x14, hw->fetch);
+       cyber2000_grphw(DCLK_MULT, hw->clock_mult, cfb);
+       cyber2000_grphw(DCLK_DIV,  hw->clock_div, cfb);
+       cyber2000_grphw(MCLK_MULT, cfb->mclk_mult, cfb);
+       cyber2000_grphw(MCLK_DIV,  cfb->mclk_div, cfb);
+       cyber2000_grphw(0x90, 0x01, cfb);
+       cyber2000_grphw(0xb9, 0x80, cfb);
+       cyber2000_grphw(0xb9, 0x00, cfb);
+
+       cyber2000fb_writeb(0x56, 0x3ce, cfb);
+       i = cyber2000fb_readb(0x3cf, cfb);
+       cyber2000fb_writeb(i | 4, 0x3cf, cfb);
+       cyber2000fb_writeb(hw->palette_ctrl, 0x3c6, cfb);
+       cyber2000fb_writeb(i,    0x3cf, cfb);
+
+       cyber2000fb_writeb(0x20, 0x3c0, cfb);
+       cyber2000fb_writeb(0xff, 0x3c6, cfb);
+
+       cyber2000_grphw(0x14, hw->fetch, cfb);
        cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
-                             ((hw->pitch >> 4) & 0x30));
-       cyber2000_grphw(0x77, hw->visualid);
+                             ((hw->pitch >> 4) & 0x30), cfb);
+       cyber2000_grphw(0x77, hw->visualid, cfb);
 
        /* make sure we stay in linear mode */
-       cyber2000_grphw(0x33, 0x0d);
+       cyber2000_grphw(0x33, 0x0d, cfb);
 
        /*
         * Set up accelerator registers
         */
-       cyber2000_outw(hw->width, CO_REG_SRC_WIDTH);
-       cyber2000_outw(hw->width, CO_REG_DEST_WIDTH);
-       cyber2000_outb(hw->pixformat, CO_REG_PIX_FORMAT);
+       cyber2000fb_writew(hw->width,     CO_REG_SRC_WIDTH,  cfb);
+       cyber2000fb_writew(hw->width,     CO_REG_DEST_WIDTH, cfb);
+       cyber2000fb_writeb(hw->pixformat, CO_REG_PIX_FORMAT, cfb);
 }
 
 static inline int
@@ -475,9 +528,9 @@ cyber2000fb_update_start(struct cfb_info *cfb, struct fb_var_screeninfo *var)
        if (base >= 1 << 20)
                return -EINVAL;
 
-       cyber2000_grphw(0x10, base >> 16 | 0x10);
-       cyber2000_crtcw(0x0c, base >> 8);
-       cyber2000_crtcw(0x0d, base);
+       cyber2000_grphw(0x10, base >> 16 | 0x10, cfb);
+       cyber2000_crtcw(0x0c, base >> 8, cfb);
+       cyber2000_crtcw(0x0d, base, cfb);
 
        return 0;
 }
@@ -623,6 +676,7 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
        const u_long ref_ps = cfb->ref_ps;
        u_int div2, t_div1, best_div1, best_mult;
        int best_diff;
+       int vco;
 
        /*
         * Step 1:
@@ -697,6 +751,11 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
        hw->clock_mult = best_mult - 1;
        hw->clock_div  = div2 << 6 | (best_div1 - 1);
 
+       vco = ref_ps * best_div1 / best_mult;
+       if ((ref_ps == 40690) && (vco < 5556))
+               /* Set VFSEL when VCO > 180MHz (5.556 ps). */
+               hw->clock_div |= DCLK_DIV_VFSEL;
+
        return 0;
 }
 
@@ -1057,30 +1116,30 @@ static void cyber2000fb_blank(int blank, struct fb_info *info)
      
        switch (blank) {
        case 4: /* powerdown - both sync lines down */
-               cyber2000_grphw(0x16, 0x05);
+               cyber2000_grphw(0x16, 0x05, cfb);
                break;  
        case 3: /* hsync off */
-               cyber2000_grphw(0x16, 0x01);
+               cyber2000_grphw(0x16, 0x01, cfb);
                break;  
        case 2: /* vsync off */
-               cyber2000_grphw(0x16, 0x04);
+               cyber2000_grphw(0x16, 0x04, cfb);
                break;  
        case 1: /* soft blank */
-               cyber2000_grphw(0x16, 0x00);
+               cyber2000_grphw(0x16, 0x00, cfb);
                for (i = 0; i < NR_PALETTE; i++) {
-                       cyber2000_outb(i, 0x3c8);
-                       cyber2000_outb(0, 0x3c9);
-                       cyber2000_outb(0, 0x3c9);
-                       cyber2000_outb(0, 0x3c9);
+                       cyber2000fb_writeb(i, 0x3c8, cfb);
+                       cyber2000fb_writeb(0, 0x3c9, cfb);
+                       cyber2000fb_writeb(0, 0x3c9, cfb);
+                       cyber2000fb_writeb(0, 0x3c9, cfb);
                }
                break;
        default: /* unblank */
-               cyber2000_grphw(0x16, 0x00);
+               cyber2000_grphw(0x16, 0x00, cfb);
                for (i = 0; i < NR_PALETTE; i++) {
-                       cyber2000_outb(i, 0x3c8);
-                       cyber2000_outb(cfb->palette[i].red, 0x3c9);
-                       cyber2000_outb(cfb->palette[i].green, 0x3c9);
-                       cyber2000_outb(cfb->palette[i].blue, 0x3c9);
+                       cyber2000fb_writeb(i, 0x3c8, cfb);
+                       cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb);
+                       cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb);
+                       cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb);
                }
                break;
        }
@@ -1136,8 +1195,8 @@ static void cyber2000fb_enable_extregs(struct cfb_info *cfb)
        if (cfb->func_use_count == 1) {
                int old;
 
-               old = cyber2000_grphr(FUNC_CTL);
-               cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL);
+               old = cyber2000_grphr(FUNC_CTL, cfb);
+               cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL, cfb);
        }
 }
 
@@ -1149,8 +1208,8 @@ static void cyber2000fb_disable_extregs(struct cfb_info *cfb)
        if (cfb->func_use_count == 1) {
                int old;
 
-               old = cyber2000_grphr(FUNC_CTL);
-               cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL);
+               old = cyber2000_grphr(FUNC_CTL, cfb);
+               cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL, cfb);
        }
 
        cfb->func_use_count -= 1;
@@ -1170,7 +1229,7 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
 {
        if (int_cfb_info != NULL) {
                info->dev             = int_cfb_info->dev;
-               info->regs            = CyberRegs;
+               info->regs            = int_cfb_info->regs;
                info->fb              = int_cfb_info->fb.screen_base;
                info->fb_size         = int_cfb_info->fb.fix.smem_len;
                info->enable_extregs  = cyber2000fb_enable_extregs;
@@ -1281,14 +1340,14 @@ static inline void cyberpro_init_hw(struct cfb_info *cfb, int at_boot)
                 * initialising this card for the first time.
                 * FIXME: what about hotplug?
                 */
-               cfb->mclk_mult = cyber2000_grphr(MCLK_MULT);
-               cfb->mclk_div  = cyber2000_grphr(MCLK_DIV);
+               cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
+               cfb->mclk_div  = cyber2000_grphr(MCLK_DIV, cfb);
        }
 #endif
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
        /*
-        * x86 is simple, we just do regular outb's instead of
-        * cyber2000_outb.
+        * x86 and MIPS are simple, we just do regular
+        * outb's instead of cyber2000fb_writeb.
         */
        outb(0x18, 0x46e8);
        outb(0x01, 0x102);
@@ -1302,16 +1361,16 @@ static inline void cyberpro_init_hw(struct cfb_info *cfb, int at_boot)
                 * initialising this card for the first time.
                 * FIXME: what about hotplug?
                 */
-               cfb->mclk_mult = cyber2000_grphr(MCLK_MULT);
-               cfb->mclk_div  = cyber2000_grphr(MCLK_DIV);
+               cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
+               cfb->mclk_div  = cyber2000_grphr(MCLK_DIV, cfb);
        }
 #endif
 #ifdef __arm__
-       cyber2000_outb(0x18, 0x46e8);
-       cyber2000_outb(0x01, 0x102);
-       cyber2000_outb(0x08, 0x46e8);
-       cyber2000_outb(0x33, 0x3ce);
-       cyber2000_outb(0x01, 0x3cf);
+       cyber2000fb_writeb(0x18, 0x46e8, cfb);
+       cyber2000fb_writeb(0x01, 0x102, cfb);
+       cyber2000fb_writeb(0x08, 0x46e8, cfb);
+       cyber2000fb_writeb(0x33, 0x3ce, cfb);
+       cyber2000fb_writeb(0x01, 0x3cf, cfb);
 
        /*
         * MCLK on the NetWinder and the Shark is fixed at 75MHz
@@ -1324,7 +1383,7 @@ static inline void cyberpro_init_hw(struct cfb_info *cfb, int at_boot)
         * Initialise the CyberPro
         */
        for (i = 0; i < sizeof(igs_regs); i += 2)
-               cyber2000_grphw(igs_regs[i], igs_regs[i+1]);
+               cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb);
 
        if (at_boot) {
                /*
@@ -1332,14 +1391,14 @@ static inline void cyberpro_init_hw(struct cfb_info *cfb, int at_boot)
                 * This should have been already initialised by the BIOS,
                 * but if it's garbage, claim default 1MB VRAM (woody)
                 */
-               cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1);
-               cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2);
+               cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1, cfb);
+               cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2, cfb);
        } else {
                /*
                 * Reprogram the MEM_CTL1 and MEM_CTL2 registers
                 */
-               cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1);
-               cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2);
+               cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1, cfb);
+               cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2, cfb);
        }
 
        /*
@@ -1347,8 +1406,8 @@ static inline void cyberpro_init_hw(struct cfb_info *cfb, int at_boot)
         * (CyberPro 5000's may be programmed to use
         * an additional set of PLLs.
         */
-       cyber2000_outb(0xba, 0x3ce);
-       cyber2000_outb(cyber2000_inb(0x3cf) & 0x80, 0x3cf);
+       cyber2000fb_writeb(0xba, 0x3ce, cfb);
+       cyber2000fb_writeb(cyber2000fb_readb(0x3cf, cfb) & 0x80, 0x3cf, cfb);
 }
 
 static struct cfb_info * __devinit
@@ -1366,15 +1425,20 @@ cyberpro_alloc_fb_info(struct pci_dev *dev, const struct pci_device_id *id, char
 
        cfb->currcon            = -1;
        cfb->dev                = dev;
-       cfb->ref_ps             = 69842;
+
+       if (id->driver_data == FB_ACCEL_IGS_CYBER5000)
+               cfb->ref_ps     = 40690; // 24.576 MHz
+       else
+               cfb->ref_ps     = 69842; // 14.31818 MHz (69841?)
+
        cfb->divisors[0]        = 1;
        cfb->divisors[1]        = 2;
        cfb->divisors[2]        = 4;
 
-       if (id->driver_data == FB_ACCEL_IGS_CYBER2010)
-               cfb->divisors[3] = 6;
-       else
+       if (id->driver_data == FB_ACCEL_IGS_CYBER2000)
                cfb->divisors[3] = 8;
+       else
+               cfb->divisors[3] = 6;
 
        strcpy(cfb->fb.fix.id, name);
 
@@ -1392,7 +1456,7 @@ cyberpro_alloc_fb_info(struct pci_dev *dev, const struct pci_device_id *id, char
        cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
 
        strcpy(cfb->fb.modename, cfb->fb.fix.id);
-       strcpy(cfb->fb.fontname, "Acorn8x8");
+       strcpy(cfb->fb.fontname, default_font);
 
        cfb->fb.fbops           = &cyber2000fb_ops;
        cfb->fb.changevar       = NULL;
@@ -1422,69 +1486,32 @@ cyberpro_free_fb_info(struct cfb_info *cfb)
 }
 
 /*
- * Map in the registers
- */
-static int __devinit
-cyberpro_map_mmio(struct cfb_info *cfb, struct pci_dev *dev)
-{
-       u_long mmio_base;
-
-       mmio_base = pci_resource_start(dev, 0) + MMIO_OFFSET;
-
-       cfb->fb.fix.mmio_start = mmio_base;
-       cfb->fb.fix.mmio_len   = MMIO_SIZE;
-
-       CyberRegs = ioremap(mmio_base, MMIO_SIZE);
-       if (!CyberRegs) {
-               printk("%s: unable to map memory mapped IO\n",
-                      cfb->fb.fix.id);
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-/*
- * Unmap registers
+ * Parse Cyber2000fb options.  Usage:
+ *  video=cyber2000:font:fontname
  */
-static void __devinit cyberpro_unmap_mmio(struct cfb_info *cfb)
+int
+cyber2000fb_setup(char *options)
 {
-       if (cfb && CyberRegs) {
-               iounmap(CyberRegs);
-               CyberRegs = NULL;
-       }
-}
+       char *opt;
 
-/*
- * Map in screen memory
- */
-static int __devinit
-cyberpro_map_smem(struct cfb_info *cfb, struct pci_dev *dev, u_long smem_len)
-{
-       u_long smem_base;
+       if (!options || !*options)
+               return 0;
 
-       smem_base = pci_resource_start(dev, 0);
+       while ((opt = strsep(&options, ",")) != NULL) {
+               if (!*opt)
+                       continue;
 
-       cfb->fb.fix.smem_start  = smem_base;
-       cfb->fb.fix.smem_len    = smem_len;
+               if (strncmp(opt, "font:", 5) == 0) {
+                       strncpy(default_font_storage, opt + 5, sizeof(default_font_storage));
+                       default_font = default_font_storage;
+                       continue;
+               }
 
-       cfb->fb.screen_base = ioremap(smem_base, smem_len);
-       if (!cfb->fb.screen_base) {
-               printk("%s: unable to map screen memory\n",
-                      cfb->fb.fix.id);
-               return -ENOMEM;
+               printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);
        }
-
        return 0;
 }
 
-static void __devinit cyberpro_unmap_smem(struct cfb_info *cfb)
-{
-       if (cfb && cfb->fb.screen_base) {
-               iounmap(cfb->fb.screen_base);
-               cfb->fb.screen_base = NULL;
-       }
-}
-
 static int __devinit
 cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
@@ -1507,11 +1534,14 @@ cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
        err = -ENOMEM;
        cfb = cyberpro_alloc_fb_info(dev, id, name);
        if (!cfb)
-               goto failed;
+               goto failed_release;
 
-       err = cyberpro_map_mmio(cfb, dev);
-       if (err)
-               goto failed;
+       cfb->region = ioremap(pci_resource_start(dev, 0),
+                             pci_resource_len(dev, 0));
+       if (!cfb->region)
+               goto failed_ioremap;
+
+       cfb->regs = cfb->region + MMIO_OFFSET;
 
        cyberpro_init_hw(cfb, 1);
 
@@ -1521,9 +1551,15 @@ cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
        default:                smem_size = 0x00100000; break;
        }
 
-       err = cyberpro_map_smem(cfb, dev, smem_size);
-       if (err)
-               goto failed;
+       /*
+        * Hmm, we _need_ a portable way of finding the address for
+        * the remap stuff, both for mmio and for smem.
+        */
+       cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
+       cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
+       cfb->fb.fix.mmio_len   = MMIO_SIZE;
+       cfb->fb.fix.smem_len   = smem_size;
+       cfb->fb.screen_base    = cfb->region;
 
        if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
                          &cyber2000fb_default_mode, 8)) {
@@ -1570,11 +1606,10 @@ cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
        return 0;
 
 failed:
-       cyberpro_unmap_smem(cfb);
-       cyberpro_unmap_mmio(cfb);
+       iounmap(cfb->region);
+failed_ioremap:
        cyberpro_free_fb_info(cfb);
-
-release:
+failed_release:
        pci_release_regions(dev);
 
        return err;
@@ -1594,8 +1629,7 @@ static void __devexit cyberpro_remove(struct pci_dev *dev)
                        printk(KERN_WARNING "%s: danger Will Robinson, "
                                "danger danger!  Oopsen imminent!\n",
                                cfb->fb.fix.id);
-               cyberpro_unmap_smem(cfb);
-               cyberpro_unmap_mmio(cfb);
+               iounmap(cfb->region);
                cyberpro_free_fb_info(cfb);
 
                /*
@@ -1673,7 +1707,10 @@ static void __exit cyberpro_exit(void)
 }
 
 #ifdef MODULE
-MODULE_LICENSE("GPL");
 module_init(cyber2000fb_init);
 #endif
 module_exit(cyberpro_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
+MODULE_LICENSE("GPL");
index 933b9e7870cb50c1f405900a50da4d868daeb2b3..9c728436050a99a8bfbb6d2be11c24cbaa1a8de6 100644 (file)
  */
 #include <linux/config.h>
 
-#define cyber2000_outb(dat,reg)        writeb(dat, CyberRegs + reg)
-#define cyber2000_outw(dat,reg)        writew(dat, CyberRegs + reg)
-#define cyber2000_outl(dat,reg)        writel(dat, CyberRegs + reg)
-
-#define cyber2000_inb(reg)     readb(CyberRegs + reg)
-#define cyber2000_inw(reg)     readw(CyberRegs + reg)
-#define cyber2000_inl(reg)     readl(CyberRegs + reg)
-
 /*
  * Internal CyberPro sizes and offsets.
  */
@@ -30,6 +22,7 @@
 #if defined(DEBUG) && defined(CONFIG_DEBUG_LL)
 static void debug_printf(char *fmt, ...)
 {
+       extern void printascii(const char *);
        char buffer[128];
        va_list ap;
 
@@ -43,38 +36,6 @@ static void debug_printf(char *fmt, ...)
 #define debug_printf(x...) do { } while (0)
 #endif
 
-static inline void cyber2000_crtcw(int reg, int val)
-{
-       cyber2000_outb(reg, 0x3d4);
-       cyber2000_outb(val, 0x3d5);
-}
-
-static inline void cyber2000_grphw(int reg, int val)
-{
-       cyber2000_outb(reg, 0x3ce);
-       cyber2000_outb(val, 0x3cf);
-}
-
-static inline unsigned int cyber2000_grphr(int reg)
-{
-       cyber2000_outb(reg, 0x3ce);
-       return cyber2000_inb(0x3cf);
-}
-
-static inline void cyber2000_attrw(int reg, int val)
-{
-       cyber2000_inb(0x3da);
-       cyber2000_outb(reg, 0x3c0);
-       cyber2000_inb(0x3c1);
-       cyber2000_outb(val, 0x3c0);
-}
-
-static inline void cyber2000_seqw(int reg, int val)
-{
-       cyber2000_outb(reg, 0x3c4);
-       cyber2000_outb(val, 0x3c5);
-}
-
 #define PIXFORMAT_8BPP         0
 #define PIXFORMAT_16BPP                1
 #define PIXFORMAT_24BPP                2
@@ -166,6 +127,7 @@ static inline void cyber2000_seqw(int reg, int val)
 
 #define DCLK_MULT              0xb0
 #define DCLK_DIV               0xb1
+#define DCLK_DIV_VFSEL                 0x20
 #define MCLK_MULT              0xb2
 #define MCLK_DIV               0xb3
 
index 624f232e615e4e10dba78385badc5d4e7203ee29..eccf21e16ec73f453b317a28fc42fb616e706739 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -137,7 +137,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
                            (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
                                error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
                        if (!error)
-                               inode_setattr(inode, attr);
+                               error = inode_setattr(inode, attr);
                }
        }
        unlock_kernel();
index 2df9d2a006866df8a358e7ab4f726769823cbab0..5994b96ba36eafc4b1a06ee624f40921dd784a6a 100644 (file)
 
 #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
 
-static inline unsigned int blksize_bits(unsigned int size)
-{
-       unsigned int bits = 8;
-       do {
-               bits++;
-               size >>= 1;
-       } while (size > 256);
-       return bits;
-}
-
-static inline unsigned int block_size(kdev_t dev)
-{
-       int retval = BLOCK_SIZE;
-       int major = MAJOR(dev);
-
-       if (blksize_size[major]) {
-               int minor = MINOR(dev);
-               if (blksize_size[major][minor])
-                       retval = blksize_size[major][minor];
-       }
-       return retval;
-}
-
 static unsigned long max_block(kdev_t dev)
 {
        unsigned int retval = ~0U;
index 225aecd483b2c56008edc029086354caca0dd680..db9658b8fce487b8dc186222fbac1e3ef1f8364f 100644 (file)
@@ -52,7 +52,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/bitops.h>
index aa8560f079b43d54b6398f5364a8235ece8538ef..60e07beee0837e979c5c07db504acb030e9d7bb0 100644 (file)
@@ -9,7 +9,7 @@
 
 O_TARGET := ext2.o
 
-obj-y    := acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
                ioctl.o namei.o super.o symlink.o
 obj-m    := $(O_TARGET)
 
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
deleted file mode 100644 (file)
index 8920f55..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * linux/fs/ext2/acl.c
- *
- * Copyright (C) 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- */
-
-#include <linux/fs.h>
-#include <linux/sched.h>
-
-
-/*
- * This file will contain the Access Control Lists management for the
- * second extended file system.
- */
index bf943d470fc30bbdff3ae1fc3411062f75323a8b..8d978bdf66bee00d4a140575998d8e2034414249 100644 (file)
 #include <linux/ext2_fs.h>
 #include <linux/sched.h>
 
-static loff_t ext2_file_lseek(struct file *, loff_t, int);
-static int ext2_open_file (struct inode *, struct file *);
-
-#define EXT2_MAX_SIZE(bits)                                                    \
-       (((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) +                             \
-          (1LL << (bits - 2)) * (1LL << (bits - 2)) +                          \
-          (1LL << (bits - 2)) * (1LL << (bits - 2)) * (1LL << (bits - 2))) *   \
-         (1LL << bits)) - 1)
-
-static long long ext2_max_sizes[] = {
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
-};
-
-/*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
-static loff_t ext2_file_lseek(
-       struct file *file,
-       loff_t offset,
-       int origin)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-
-       switch (origin) {
-               case 2:
-                       offset += inode->i_size;
-                       break;
-               case 1:
-                       offset += file->f_pos;
-       }
-       if (offset<0)
-               return -EINVAL;
-       if (((unsigned long long) offset >> 32) != 0) {
-               if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
-                       return -EINVAL;
-       } 
-       if (offset != file->f_pos) {
-               file->f_pos = offset;
-               file->f_reada = 0;
-               file->f_version = ++event;
-       }
-       return offset;
-}
-
 /*
  * Called when an inode is released. Note that this is different
  * from ext2_open_file: open gets called at every open, but release
@@ -79,31 +34,17 @@ static int ext2_release_file (struct inode * inode, struct file * filp)
        return 0;
 }
 
-/*
- * Called when an inode is about to be open.
- * We use this to disallow opening RW large files on 32bit systems if
- * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
- * on this flag in sys_open.
- */
-static int ext2_open_file (struct inode * inode, struct file * filp)
-{
-       if (!(filp->f_flags & O_LARGEFILE) &&
-           inode->i_size > 0x7FFFFFFFLL)
-               return -EFBIG;
-       return 0;
-}
-
 /*
  * We have mostly NULL's here: the current defaults are ok for
  * the ext2 filesystem.
  */
 struct file_operations ext2_file_operations = {
-       llseek:         ext2_file_lseek,
+       llseek:         generic_file_llseek,
        read:           generic_file_read,
        write:          generic_file_write,
        ioctl:          ext2_ioctl,
        mmap:           generic_file_mmap,
-       open:           ext2_open_file,
+       open:           generic_file_open,
        release:        ext2_release_file,
        fsync:          ext2_sync_file,
 };
index 271cbd15b73324002bfe1886a98061261b1d2fd0..8e138cc9a2adf44ea3d1dba21b00bd84a46bbb67 100644 (file)
 #include <linux/sched.h>
 #include <linux/highuid.h>
 #include <linux/quotaops.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Remy Card and others");
+MODULE_DESCRIPTION("Second Extended Filesystem");
+MODULE_LICENSE("GPL");
+
 
 static int ext2_update_inode(struct inode * inode, int do_sync);
 
@@ -592,7 +598,7 @@ struct address_space_operations ext2_aops = {
        sync_page: block_sync_page,
        prepare_write: ext2_prepare_write,
        commit_write: generic_commit_write,
-       bmap: ext2_bmap,
+       bmap: ext2_bmap
 };
 
 /*
index 9a06acb8d50d7628938559640a6bf881f55bdbf1..99b265f0acf4ff0e2dd7efc28d06db8d516ac689 100644 (file)
@@ -49,6 +49,7 @@
 
 MODULE_AUTHOR("Christoph Hellwig");
 MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
+MODULE_LICENSE("Dual BSD/GPL");
 
 
 static void            vxfs_put_super(struct super_block *);
index 883e4cc5869869a8e87f90992bee01521103f024..d7d00ed2ce98388ce1965e1458fce260b586768f 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -676,6 +677,18 @@ nlm_stat_to_errno(u32 status)
        case NLM_LCK_BLOCKED:
                printk(KERN_NOTICE "lockd: unexpected status NLM_BLOCKED\n");
                return -ENOLCK;
+#ifdef CONFIG_LOCKD_V4
+       case NLM_DEADLCK:
+               return -EDEADLK;
+       case NLM_ROFS:
+               return -EROFS;
+       case NLM_STALE_FH:
+               return -ESTALE;
+       case NLM_FBIG:
+               return -EOVERFLOW;
+       case NLM_FAILED:
+               return -ENOLCK;
+#endif
        }
        printk(KERN_NOTICE "lockd: unexpected server status %d\n", status);
        return -ENOLCK;
index 078f568b78ba8412a832bbce2baf80ffcb4d4ab1..2b8113d747da845516cdc405176490f57da2377a 100644 (file)
 #include <linux/lockd/nlm.h>
 #include <linux/lockd/lockd.h>
 
-
 #define NLMDBG_FACILITY                NLMDBG_SVCLOCK
 
+#ifdef CONFIG_LOCKD_V4
+#define nlm_deadlock   nlm4_deadlock
+#else
+#define nlm_deadlock   nlm_lck_denied
+#endif
+
 static void    nlmsvc_insert_block(struct nlm_block *block, unsigned long);
 static int     nlmsvc_remove_block(struct nlm_block *block);
 static void    nlmsvc_grant_callback(struct rpc_task *task);
@@ -330,12 +335,7 @@ again:
                case 0:
                        return nlm_granted;
                case EDEADLK:
-#ifdef CONFIG_LOCKD_V4
-                       return nlm4_deadlock; /* will be downgraded to lck_deined if this
-                                              * is a NLMv1,3 request */
-#else
-                       /* no applicable NLM status */
-#endif
+                       return nlm_deadlock;
                case EAGAIN:
                        return nlm_lck_denied;
                default:                        /* includes ENOLCK */
@@ -348,6 +348,11 @@ again:
                return nlm_lck_denied;
        }
 
+       if (posix_locks_deadlock(&lock->fl, conflock)) {
+               up(&file->f_sema);
+               return nlm_deadlock;
+       }
+
        /* If we don't have a block, create and initialize it. Then
         * retry because we may have slept in kmalloc. */
        if (block == NULL) {
index 6af031e95125e91fd7bb8a306ec6c5966a8cdad0..a5283be9b1702a3373a3f2c948e82434a9a1f2ba 100644 (file)
@@ -29,17 +29,20 @@ static void nlmsvc_callback_exit(struct rpc_task *);
 static u32
 cast_to_nlm(u32 status, u32 vers)
 {
-
+       /* Note: status is assumed to be in network byte order !!! */
        if (vers != 4){
-               switch(ntohl(status)){
-               case NLM_LCK_GRANTED:
-               case NLM_LCK_DENIED:
-               case NLM_LCK_DENIED_NOLOCKS:
-               case NLM_LCK_BLOCKED:
-               case NLM_LCK_DENIED_GRACE_PERIOD:
+               switch (status) {
+               case nlm_granted:
+               case nlm_lck_denied:
+               case nlm_lck_denied_nolocks:
+               case nlm_lck_blocked:
+               case nlm_lck_denied_grace_period:
+                       break;
+               case nlm4_deadlock:
+                       status = nlm_lck_denied;
                        break;
                default:
-                       status = NLM_LCK_DENIED_NOLOCKS;
+                       status = nlm_lck_denied_nolocks;
                }
        }
 
index 6cc49cdd1973fb767133dfb7205ce7016ff1ba4d..e85e1f8463c970d00e4d67b197c83f98d55d135b 100644 (file)
@@ -548,7 +548,7 @@ static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl)
                return (1);
 
        default:
-               printk("locks_conflict(): impossible lock type - %d\n",
+               printk(KERN_ERR "locks_conflict(): impossible lock type - %d\n",
                       caller_fl->fl_type);
                break;
        }
@@ -660,7 +660,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
  * from a broken NFS client. But broken NFS clients have a lot more to
  * worry about than proper deadlock detection anyway... --okir
  */
-static int posix_locks_deadlock(struct file_lock *caller_fl,
+int posix_locks_deadlock(struct file_lock *caller_fl,
                                struct file_lock *block_fl)
 {
        struct list_head *tmp;
@@ -715,6 +715,9 @@ int locks_mandatory_area(int read_write, struct inode *inode,
        struct file_lock *new_fl = locks_alloc_lock(0);
        int error;
 
+       if (new_fl == NULL)
+               return -ENOMEM;
+
        new_fl->fl_owner = current->files;
        new_fl->fl_pid = current->pid;
        new_fl->fl_file = filp;
@@ -1428,6 +1431,9 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
        struct inode *inode;
        int error;
 
+       if (file_lock == NULL)
+               return -ENOLCK;
+
        /*
         * This might block, so we do it before checking the inode.
         */
@@ -1581,6 +1587,9 @@ int fcntl_setlk64(unsigned int fd, unsigned int cmd, struct flock64 *l)
        struct inode *inode;
        int error;
 
+       if (file_lock == NULL)
+               return -ENOLCK;
+
        /*
         * This might block, so we do it before checking the inode.
         */
index a58b0be4c63a3d0a2b115f28f57caf7f6335e62c..1d27255ccf0df44b52011f4312b4c7f884f63bab 100644 (file)
@@ -59,7 +59,7 @@ static kmem_cache_t *nfs_rdata_cachep;
 static __inline__ struct nfs_read_data *nfs_readdata_alloc(void)
 {
        struct nfs_read_data   *p;
-       p = kmem_cache_alloc(nfs_rdata_cachep, SLAB_NFS);
+       p = kmem_cache_alloc(nfs_rdata_cachep, SLAB_NOFS);
        if (p) {
                memset(p, 0, sizeof(*p));
                INIT_LIST_HEAD(&p->pages);
index 8fe2b47874a8d00506ff2e1baf35341bd77f57a0..fa1e4efaf54ac6548b6f1a7b7252de2c54f53ff5 100644 (file)
@@ -109,7 +109,7 @@ static kmem_cache_t *nfs_wdata_cachep;
 static __inline__ struct nfs_page *nfs_page_alloc(void)
 {
        struct nfs_page *p;
-       p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL);
+       p = kmem_cache_alloc(nfs_page_cachep, SLAB_NOFS);
        if (p) {
                memset(p, 0, sizeof(*p));
                INIT_LIST_HEAD(&p->wb_hash);
@@ -127,7 +127,7 @@ static __inline__ void nfs_page_free(struct nfs_page *p)
 static __inline__ struct nfs_write_data *nfs_writedata_alloc(void)
 {
        struct nfs_write_data   *p;
-       p = kmem_cache_alloc(nfs_wdata_cachep, SLAB_NFS);
+       p = kmem_cache_alloc(nfs_wdata_cachep, SLAB_NOFS);
        if (p) {
                memset(p, 0, sizeof(*p));
                INIT_LIST_HEAD(&p->pages);
index debae923e8f26a21be451584adea8ad6c5936587..8d25e5095f130ccdfda708e88bce25828ee151db 100644 (file)
@@ -70,7 +70,6 @@ decode_filename(u32 *p, char **namp, int *lenp)
                        if (*name == '\0' || *name == '/')
                                return NULL;
                }
-               *name = '\0';
        }
 
        return p;
index ee0ce88fed8484ab3d664d53fa92701c97b4d1e9..e933009d4f63d8726d36165260ac15d9e06f970a 100644 (file)
@@ -247,6 +247,7 @@ static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor
                printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf));
        bdev = bdget(kdev_t_to_nr(dev));
        bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9;
+       bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
        for (i = 0; check_part[i]; i++) {
                int res;
                res = check_part[i](hd, bdev, first_sector, first_part_minor);
index 8777f50178a9404a38206ea0aaa470ed432006b1..68a58ff9de97b8a2c1dde5425bb2000357647467 100644 (file)
@@ -103,21 +103,20 @@ msdos_magic_present(unsigned char *p)
  */
 
 static void extended_partition(struct gendisk *hd, struct block_device *bdev,
-                               int minor, int *current_minor)
+                       int minor, unsigned long first_size, int *current_minor)
 {
        struct partition *p;
        Sector sect;
        unsigned char *data;
-       unsigned long first_sector, first_size, this_sector, this_size;
+       unsigned long first_sector, this_sector, this_size;
        int mask = (1 << hd->minor_shift) - 1;
        int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512;
        int loopct = 0;         /* number of links followed
                                   without finding a data partition */
        int i;
 
-       first_sector = hd->part[minor].start_sect;
-       first_size = hd->part[minor].nr_sects;
-       this_sector = first_sector;
+       this_sector = first_sector = hd->part[minor].start_sect;
+       this_size = first_size;
 
        while (1) {
                if (++loopct > 100)
@@ -133,8 +132,6 @@ static void extended_partition(struct gendisk *hd, struct block_device *bdev,
 
                p = (struct partition *) (data + 0x1be);
 
-               this_size = hd->part[minor].nr_sects;
-
                /*
                 * Usually, the first entry is the real data partition,
                 * the 2nd entry is the next extended partition, or empty,
@@ -196,6 +193,7 @@ static void extended_partition(struct gendisk *hd, struct block_device *bdev,
                        goto done;       /* nothing left to do */
 
                this_sector = first_sector + START_SECT(p) * sector_size;
+               this_size = NR_SECTS(p) * sector_size;
                minor = *current_minor;
                put_dev_sector(sect);
        }
@@ -586,12 +584,13 @@ int msdos_partition(struct gendisk *hd, struct block_device *bdev,
                }
 #endif
                if (is_extended_partition(p)) {
+                       unsigned long size = hd->part[minor].nr_sects;
                        printk(" <");
                        /* prevent someone doing mkfs or mkswap on an
                           extended partition, but leave room for LILO */
-                       if (hd->part[minor].nr_sects > 2)
+                       if (size > 2)
                                hd->part[minor].nr_sects = 2;
-                       extended_partition(hd, bdev, minor, &current_minor);
+                       extended_partition(hd, bdev, minor, size, &current_minor);
                        printk(" >");
                }
        }
index 8ec5fdc95d81699613b7a6fbb51f42b1be14aa36..d8738e51bb0f0def3850b59e1330024c674573d5 100644 (file)
@@ -151,12 +151,13 @@ static inline char * task_state(struct task_struct *p, char *buffer)
        read_lock(&tasklist_lock);
        buffer += sprintf(buffer,
                "State:\t%s\n"
+               "Tgid:\t%d\n"
                "Pid:\t%d\n"
                "PPid:\t%d\n"
                "TracerPid:\t%d\n"
                "Uid:\t%d\t%d\t%d\t%d\n"
                "Gid:\t%d\t%d\t%d\t%d\n",
-               get_task_state(p),
+               get_task_state(p), p->tgid,
                p->pid, p->pid ? p->p_opptr->pid : 0, 0,
                p->uid, p->euid, p->suid, p->fsuid,
                p->gid, p->egid, p->sgid, p->fsgid);
index f041736e515fca41f6e35b2597af2fca0cc38459..e1601dba7ca8923f3d770c7291e82f41118658c7 100644 (file)
@@ -140,6 +140,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
 {
        struct sysinfo i;
        int len;
+       int pg_size ;
 
 /*
  * display in kilobytes.
@@ -148,12 +149,14 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
 #define B(x) ((unsigned long long)(x) << PAGE_SHIFT)
        si_meminfo(&i);
        si_swapinfo(&i);
+       pg_size = atomic_read(&page_cache_size) - i.bufferram ;
+
        len = sprintf(page, "        total:    used:    free:  shared: buffers:  cached:\n"
                "Mem:  %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n"
                "Swap: %8Lu %8Lu %8Lu\n",
                B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
                B(i.sharedram), B(i.bufferram),
-               B(atomic_read(&page_cache_size)), B(i.totalswap),
+               B(pg_size), B(i.totalswap),
                B(i.totalswap-i.freeswap), B(i.freeswap));
        /*
         * Tagged format, for easy grepping and expansion.
@@ -179,7 +182,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                K(i.freeram),
                K(i.sharedram),
                K(i.bufferram),
-               K(atomic_read(&page_cache_size) - swapper_space.nrpages),
+               K(pg_size - swapper_space.nrpages),
                K(swapper_space.nrpages),
                K(nr_active_pages),
                K(nr_inactive_pages),
index 0d82b45ea34fc8609fbda2546d5c2c7f4fe5a23d..982a7f808620b277545a0d6f076dae64b111a78c 100644 (file)
 #define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
 #define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
 #define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))
+#define UintBPL Uint(BITS_PER_LONG)
+#define Uint(x) xUint(x)
+#define xUint(x) Uint ## x
 
 extern inline int find_next_one_bit (void * addr, int size, int offset)
 {
-       unsigned long * p = ((unsigned long *) addr) + (offset / BITS_PER_LONG);
-       unsigned long result = offset & ~(BITS_PER_LONG-1);
-       unsigned long tmp;
+       UintBPL * p = ((UintBPL *) addr) + (offset / BITS_PER_LONG);
+       UintBPL result = offset & ~(BITS_PER_LONG-1);
+       UintBPL tmp;
 
        if (offset >= size)
                return size;
@@ -126,7 +129,7 @@ static int __load_block_bitmap(struct super_block * sb,
        }
 }
 
-static inline int load_block_bitmap(struct super_block *sb,
+static inline int load_block_bitmap(struct super_block * sb,
        struct udf_bitmap *bitmap, unsigned int block_group)
 {
        int slot;
@@ -142,7 +145,8 @@ static inline int load_block_bitmap(struct super_block *sb,
        return slot;
 }
 
-static void udf_bitmap_free_blocks(struct inode * inode,
+static void udf_bitmap_free_blocks(struct super_block * sb,
+       struct inode * inode,
        struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
 {
        struct buffer_head * bh = NULL;
@@ -152,14 +156,6 @@ static void udf_bitmap_free_blocks(struct inode * inode,
        unsigned long i;
        int bitmap_nr;
        unsigned long overflow;
-       struct super_block * sb;
-
-       sb = inode->i_sb;
-       if (!sb)
-       {
-               udf_debug("nonexistent device");
-               return;
-       }
 
        lock_super(sb);
        if (bloc.logicalBlockNum < 0 ||
@@ -200,7 +196,8 @@ do_more:
                }
                else
                {
-                       DQUOT_FREE_BLOCK(inode, 1);
+                       if (inode)
+                               DQUOT_FREE_BLOCK(inode, 1);
                        if (UDF_SB_LVIDBH(sb))
                        {
                                UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -223,7 +220,8 @@ error_return:
        return;
 }
 
-static int udf_bitmap_prealloc_blocks(struct inode * inode,
+static int udf_bitmap_prealloc_blocks(struct super_block * sb,
+       struct inode * inode,
        struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
        Uint32 block_count)
 {
@@ -231,14 +229,7 @@ static int udf_bitmap_prealloc_blocks(struct inode * inode,
        int bit, block, block_group, group_start;
        int nr_groups, bitmap_nr;
        struct buffer_head *bh;
-       struct super_block *sb;
 
-       sb = inode->i_sb;
-       if (!sb)
-       {
-               udf_debug("nonexistent device\n");
-               return 0;
-       }
        lock_super(sb);
 
        if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
@@ -293,23 +284,17 @@ out:
        return alloc_count;
 }
 
-static int udf_bitmap_new_block(struct inode * inode,
+static int udf_bitmap_new_block(struct super_block * sb,
+       struct inode * inode,
        struct udf_bitmap *bitmap, Uint16 partition, Uint32 goal, int *err)
 {
        int newbit, bit=0, block, block_group, group_start;
        int end_goal, nr_groups, bitmap_nr, i;
        struct buffer_head *bh = NULL;
-       struct super_block *sb;
        char *ptr;
        int newblock = 0;
 
        *err = -ENOSPC;
-       sb = inode->i_sb;
-       if (!sb)
-       {
-               udf_debug("nonexistent device\n");
-               return newblock;
-       }
        lock_super(sb);
 
 repeat:
@@ -404,7 +389,7 @@ got_block:
        /*
         * Check quota for allocation of this block.
         */
-       if (DQUOT_ALLOC_BLOCK(inode, 1))
+       if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
        {
                unlock_super(sb);
                *err = -EDQUOT;
@@ -439,30 +424,17 @@ error_return:
        return 0;
 }
 
-static void udf_table_free_blocks(struct inode * inode,
+static void udf_table_free_blocks(struct super_block * sb,
+       struct inode * inode,
        struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
 {
-       struct super_block * sb;
        Uint32 start, end;
        Uint32 nextoffset, oextoffset, elen;
        lb_addr nbloc, obloc, eloc;
        struct buffer_head *obh, *nbh;
-       char etype;
+       Sint8 etype;
        int i;
 
-       udf_debug("ino=%ld, bloc=%d, offset=%d, count=%d\n",
-               inode->i_ino, bloc.logicalBlockNum, offset, count);
-
-       sb = inode->i_sb;
-       if (!sb)
-       {
-               udf_debug("nonexistent device");
-               return;
-       }
-
-       if (table == NULL)
-               return;
-
        lock_super(sb);
        if (bloc.logicalBlockNum < 0 ||
                (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
@@ -475,7 +447,8 @@ static void udf_table_free_blocks(struct inode * inode,
 
        /* We do this up front - There are some error conditions that could occure,
           but.. oh well */
-       DQUOT_FREE_BLOCK(inode, count);
+       if (inode)
+               DQUOT_FREE_BLOCK(inode, count);
        if (UDF_SB_LVIDBH(sb))
        {
                UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -690,33 +663,20 @@ error_return:
        return;
 }
 
-static int udf_table_prealloc_blocks(struct inode * inode,
+static int udf_table_prealloc_blocks(struct super_block * sb,
+       struct inode * inode,
        struct inode *table, Uint16 partition, Uint32 first_block,
        Uint32 block_count)
 {
-       struct super_block *sb;
        int alloc_count = 0;
        Uint32 extoffset, elen, adsize;
        lb_addr bloc, eloc;
        struct buffer_head *bh;
-       char etype = -1;
-
-       udf_debug("ino=%ld, partition=%d, first_block=%d, block_count=%d\n",
-               inode->i_ino, partition, first_block, block_count);
-
-       sb = inode->i_sb;
-       if (!sb)
-       {
-               udf_debug("nonexistent device\n");
-               return 0;
-       }
+       Sint8 etype = -1;
 
        if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
                return 0;
 
-       if (table == NULL)
-               return 0;
-
        if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
                adsize = sizeof(short_ad);
        else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
@@ -745,7 +705,9 @@ static int udf_table_prealloc_blocks(struct inode * inode,
                extoffset -= adsize;
 
                alloc_count = (elen >> sb->s_blocksize_bits);
-               if (alloc_count > block_count)
+               if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
+                       alloc_count = 0;
+               else if (alloc_count > block_count)
                {
                        alloc_count = block_count;
                        eloc.logicalBlockNum += alloc_count;
@@ -765,37 +727,24 @@ static int udf_table_prealloc_blocks(struct inode * inode,
                UDF_SB_LVID(sb)->freeSpaceTable[partition] =
                        cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+               sb->s_dirt = 1;
        }
-       sb->s_dirt = 1;
        unlock_super(sb);
-       udf_debug("alloc_count=%d\n", alloc_count);
        return alloc_count;
 }
 
-static int udf_table_new_block(const struct inode * inode,
+static int udf_table_new_block(struct super_block * sb,
+       struct inode * inode,
        struct inode *table, Uint16 partition, Uint32 goal, int *err)
 {
-       struct super_block *sb;
        Uint32 spread = 0xFFFFFFFF, nspread;
        Uint32 newblock = 0, adsize;
        Uint32 extoffset, goal_extoffset, elen, goal_elen = 0;
        lb_addr bloc, goal_bloc, eloc, goal_eloc;
        struct buffer_head *bh, *goal_bh;
-       char etype;
-
-       udf_debug("ino=%ld, partition=%d, goal=%d\n",
-               inode->i_ino, partition, goal);
+       Sint8 etype;
 
        *err = -ENOSPC;
-       sb = inode->i_sb;
-       if (!sb)
-       {
-               udf_debug("nonexistent device\n");
-               return newblock;
-       }
-
-       if (table == NULL)
-               return newblock;
 
        if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
                adsize = sizeof(short_ad);
@@ -868,6 +817,14 @@ static int udf_table_new_block(const struct inode * inode,
        goal_eloc.logicalBlockNum ++;
        goal_elen -= sb->s_blocksize;
 
+       if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
+       {
+               udf_release_data(goal_bh);
+               unlock_super(sb);
+               *err = -EDQUOT;
+               return 0;
+       }
+
        if (goal_elen)
                udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
        else
@@ -887,93 +844,98 @@ static int udf_table_new_block(const struct inode * inode,
        return newblock;
 }
 
-inline void udf_free_blocks(struct inode * inode, lb_addr bloc,
-       Uint32 offset, Uint32 count)
+inline void udf_free_blocks(struct super_block * sb,
+       struct inode * inode,
+       lb_addr bloc, Uint32 offset, Uint32 count)
 {
-       if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_BITMAP)
+       Uint16 partition = bloc.partitionReferenceNum;
+
+       if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
        {
-               return udf_bitmap_free_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_bitmap,
+               return udf_bitmap_free_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
                        bloc, offset, count);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_TABLE)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
        {
-               return udf_table_free_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_table,
+               return udf_table_free_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
                        bloc, offset, count);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_BITMAP)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
        {
-               return udf_bitmap_free_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_bitmap,
+               return udf_bitmap_free_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
                        bloc, offset, count);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_TABLE)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
        {
-               return udf_table_free_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_table,
+               return udf_table_free_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
                        bloc, offset, count);
        }
        else
                return;
 }
 
-inline int udf_prealloc_blocks(struct inode * inode, Uint16 partition,
-       Uint32 first_block, Uint32 block_count)
+inline int udf_prealloc_blocks(struct super_block * sb,
+       struct inode * inode,
+       Uint16 partition, Uint32 first_block, Uint32 block_count)
 {
-       if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+       if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
        {
-               return udf_bitmap_prealloc_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+               return udf_bitmap_prealloc_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
                        partition, first_block, block_count);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
        {
-               return udf_table_prealloc_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+               return udf_table_prealloc_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
                        partition, first_block, block_count);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
        {
-               return udf_bitmap_prealloc_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+               return udf_bitmap_prealloc_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
                        partition, first_block, block_count);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
        {
-               return udf_table_prealloc_blocks(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+               return udf_table_prealloc_blocks(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
                        partition, first_block, block_count);
        }
        else
                return 0;
 }
 
-inline int udf_new_block(struct inode * inode, Uint16 partition,
-       Uint32 goal, int *err)
+inline int udf_new_block(struct super_block * sb,
+       struct inode * inode,
+       Uint16 partition, Uint32 goal, int *err)
 {
-       if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+       if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
        {
-               return udf_bitmap_new_block(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+               return udf_bitmap_new_block(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
                        partition, goal, err);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
        {
-               return udf_table_new_block(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+               return udf_table_new_block(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
                        partition, goal, err);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
        {
-               return udf_bitmap_new_block(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+               return udf_bitmap_new_block(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
                        partition, goal, err);
        }
-       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+       else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
        {
-               return udf_table_new_block(inode,
-                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+               return udf_table_new_block(sb, inode,
+                       UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
                        partition, goal, err);
        }
        else
index d3f42ca9306dffd23994d8d54e29c025211c6105..7a13d861ccfdd7c77c0f73b0b366cb86eb9fe738 100644 (file)
@@ -186,7 +186,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
                                udf_release_data(fibh.ebh);
                        udf_release_data(fibh.sbh);
                        udf_release_data(bh);
-                       return -ENOENT;
+                       return 0;
                }
 
                liu = le16_to_cpu(cfi.lengthOfImpUse);
index 1f8f28f9a74ace1464c5e631772c943e2fa5d176..33ff393177dc8309408373d7cc3276d01cd3eab2 100644 (file)
@@ -206,7 +206,7 @@ static ssize_t udf_file_write(struct file * file, const char * buf,
 int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        unsigned long arg)
 {
-       int result = -1;
+       int result = -EINVAL;
        struct buffer_head *bh = NULL;
        long_ad eaicb;
        Uint8 *ea = NULL;
@@ -228,16 +228,16 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        switch (cmd)
        {
                case UDF_GETVOLIDENT:
-                       if ( (result == verify_area(VERIFY_WRITE, (char *)arg, 32)) == 0)
-                               result = copy_to_user((char *)arg, UDF_SB_VOLIDENT(inode->i_sb), 32);
-                       return result;
+                       return copy_to_user((char *)arg,
+                               UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0;
                case UDF_RELOCATE_BLOCKS:
                {
                        long old, new;
 
                        if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-                       get_user(old, (long *)arg);
-                       if ((result = udf_relocate_blocks(inode->i_sb, old, &new)) == 0)
+                       if (get_user(old, (long *)arg)) return -EFAULT;
+                       if ((result = udf_relocate_blocks(inode->i_sb,
+                                       old, &new)) == 0)
                                result = put_user(new, (long *)arg);
 
                        return result;
@@ -277,16 +277,12 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        switch (cmd) 
        {
                case UDF_GETEASIZE:
-                       if ( (result = verify_area(VERIFY_WRITE, (char *)arg, 4)) == 0) 
-                               result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
+                       result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
                        break;
 
                case UDF_GETEABLOCK:
-                       if ( (result = verify_area(VERIFY_WRITE, (char *)arg, UDF_I_LENEATTR(inode))) == 0) 
-                               result = copy_to_user((char *)arg, ea, UDF_I_LENEATTR(inode));
-                       break;
-
-               default:
+                       result = copy_to_user((char *)arg, ea,
+                               UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
                        break;
        }
 
index 87553905b8f6b0fdf066c592ddaae4dfde7c41bf..7d44903b1c1acfd50d12905b2e7bcf42e8f157a3 100644 (file)
@@ -64,10 +64,9 @@ void udf_free_inode(struct inode * inode)
                
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
        }
-
        unlock_super(sb);
 
-       udf_free_blocks(inode, UDF_I_LOCATION(inode), 0, 1);
+       udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
 }
 
 struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
@@ -87,7 +86,7 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
        }
        *err = -ENOSPC;
 
-       block = udf_new_block(dir, UDF_I_LOCATION(dir).partitionReferenceNum,
+       block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
                start, err);
        if (*err)
        {
index ff919240c2128cab1ebf7e77bc58c41fd1802141..897e469aa08922e30443815b9b67605817531dd7 100644 (file)
@@ -236,7 +236,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
        }
 
        /* alloc block, and copy data to it */
-       *block = udf_new_block(inode,
+       *block = udf_new_block(inode->i_sb, inode,
                UDF_I_LOCATION(inode).partitionReferenceNum,
                UDF_I_LOCATION(inode).logicalBlockNum, err);
 
@@ -302,7 +302,6 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
        udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
        /* UniqueID stuff */
 
-       inode->i_blocks = inode->i_sb->s_blocksize / 512;
        mark_buffer_dirty(sbh);
        udf_release_data(sbh);
        mark_inode_dirty(inode);
@@ -402,14 +401,14 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
        Uint32 elen = 0;
        lb_addr eloc, pbloc, cbloc, nbloc;
        int c = 1;
-       int lbcount = 0, b_off = 0, offset = 0;
-       Uint32 newblocknum, newblock;
-       char etype;
+       Uint64 lbcount = 0, b_off = 0;
+       Uint32 newblocknum, newblock, offset = 0;
+       Sint8 etype;
        int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
        char lastblock = 0;
 
        pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
-       b_off = block << inode->i_sb->s_blocksize_bits;
+       b_off = (Uint64)block << inode->i_sb->s_blocksize_bits;
        pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
 
        /* find the extent which contains the block we are looking for.
@@ -546,7 +545,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
                                goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
                }
 
-               if (!(newblocknum = udf_new_block(inode,
+               if (!(newblocknum = udf_new_block(inode->i_sb, inode,
                        UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
                {
                        udf_release_data(pbh);
@@ -588,7 +587,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
        UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
        inode->i_ctime = CURRENT_TIME;
        UDF_I_UCTIME(inode) = CURRENT_UTIME;
-       inode->i_blocks += inode->i_sb->s_blocksize / 512;
+
        if (IS_SYNC(inode))
                udf_sync_inode(inode);
        else
@@ -692,7 +691,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
                int next = laarr[start].extLocation.logicalBlockNum +
                        (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
                        inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
-               int numalloc = udf_prealloc_blocks(inode,
+               int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
                        laarr[start].extLocation.partitionReferenceNum,
                        next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
                                UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
@@ -825,9 +824,6 @@ struct buffer_head * udf_bread(struct inode * inode, int block,
        int create, int * err)
 {
        struct buffer_head * bh = NULL;
-       int prev_blocks;
-
-       prev_blocks = inode->i_blocks;
 
        bh = udf_getblk(inode, block, create, err);
        if (!bh)
@@ -1602,7 +1598,7 @@ udf_iget(struct super_block *sb, lb_addr ino)
        return inode;
 }
 
-int udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
        lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc)
 {
        int adsize;
@@ -1637,7 +1633,7 @@ int udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
                int err, loffset;
                lb_addr obloc = *bloc;
 
-               if (!(bloc->logicalBlockNum = udf_new_block(inode,
+               if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, inode,
                        obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
                {
                        return -1;
@@ -1739,7 +1735,7 @@ int udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
        return ret;
 }
 
-int udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
+Sint8 udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
     lb_addr eloc, Uint32 elen, struct buffer_head *bh, int inc)
 {
        int adsize;
@@ -1808,12 +1804,12 @@ int udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
        return (elen >> 30);
 }
 
-int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
        lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
 {
        Uint16 tagIdent;
        int pos, alen;
-       Uint8 etype;
+       Sint8 etype;
 
        if (!(*bh))
        {
@@ -1932,11 +1928,11 @@ int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
        return -1;
 }
 
-int udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
        lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
 {
        int pos, alen;
-       Uint8 etype;
+       Sint8 etype;
 
        if (!(*bh))
        {
@@ -2013,12 +2009,12 @@ int udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
        return -1;
 }
 
-int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
+Sint8 udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
        lb_addr neloc, Uint32 nelen, struct buffer_head *bh)
 {
        lb_addr oeloc;
        Uint32 oelen;
-       int type;
+       Sint8 etype;
 
        if (!bh)
        {
@@ -2034,25 +2030,25 @@ int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
        else
                atomic_inc(&bh->b_count);
 
-       while ((type = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
+       while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
        {
                udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
 
                neloc = oeloc;
-               nelen = (type << 30) | oelen;
+               nelen = (etype << 30) | oelen;
        }
        udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
        udf_release_data(bh);
        return (nelen >> 30);
 }
 
-int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
+Sint8 udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
        lb_addr eloc, Uint32 elen, struct buffer_head *nbh)
 {
        struct buffer_head *obh;
        lb_addr obloc;
        int oextoffset, adsize;
-       char type;
+       Sint8 etype;
        struct AllocExtDesc *aed;
 
        if (!(nbh))
@@ -2084,9 +2080,9 @@ int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
        if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
                return -1;
 
-       while ((type = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+       while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
        {
-               udf_write_aext(inode, obloc, &oextoffset, eloc, (type << 30) | elen, obh, 1);
+               udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
                if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
                {
                        obloc = nbloc;
@@ -2101,7 +2097,7 @@ int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
 
        if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
        {
-               udf_free_blocks(inode, nbloc, 0, 1);
+               udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
                udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
                udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
                if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
@@ -2147,11 +2143,11 @@ int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
        return (elen >> 30);
 }
 
-int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
+Sint8 inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
        lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh)
 {
-       Uint64 lbcount = 0, bcount = block << inode->i_sb->s_blocksize_bits;
-       char etype;
+       Uint64 lbcount = 0, bcount = (Uint64)block << inode->i_sb->s_blocksize_bits;
+       Sint8 etype;
 
        if (block < 0)
        {
index b5823d5d9849c256e184ffb795b005ea7f70d423..7b6f0a6745781b446416455a41274fa7b80e0c93 100644 (file)
@@ -835,7 +835,7 @@ static int empty_dir(struct inode *dir)
 static int udf_rmdir(struct inode * dir, struct dentry * dentry)
 {
        int retval;
-       struct inode * inode;
+       struct inode * inode = dentry->d_inode;
        struct udf_fileident_bh fibh;
        struct FileIdentDesc *fi, cfi;
 
@@ -844,9 +844,6 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry)
        if (!fi)
                goto out;
 
-       inode = dentry->d_inode;
-       DQUOT_INIT(inode);
-
        retval = -EIO;
        if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) != inode->i_ino)
                goto end_rmdir;
@@ -881,7 +878,7 @@ out:
 static int udf_unlink(struct inode * dir, struct dentry * dentry)
 {
        int retval;
-       struct inode * inode;
+       struct inode * inode = dentry->d_inode;
        struct udf_fileident_bh fibh;
        struct FileIdentDesc *fi;
        struct FileIdentDesc cfi;
@@ -891,9 +888,6 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry)
        if (!fi)
                goto out;
 
-       inode = dentry->d_inode;
-       DQUOT_INIT(inode);
-
        retval = -EIO;
 
        if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) !=
@@ -954,7 +948,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
                lb_addr bloc, eloc;
                Uint32 elen, extoffset;
 
-               block = udf_new_block(inode,
+               block = udf_new_block(inode->i_sb, inode,
                        UDF_I_LOCATION(inode).partitionReferenceNum,
                        UDF_I_LOCATION(inode).logicalBlockNum, &err);
                if (!block)
@@ -968,7 +962,6 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
                udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
                udf_release_data(bh);
 
-               inode->i_blocks = inode->i_sb->s_blocksize / 512;
                block = udf_get_pblock(inode->i_sb, block,
                        UDF_I_LOCATION(inode).partitionReferenceNum, 0);
                bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize);
@@ -1150,13 +1143,13 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
 static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
        struct inode * new_dir, struct dentry * new_dentry)
 {
-       struct inode * old_inode, * new_inode;
+       struct inode * old_inode = old_dentry->d_inode;
+       struct inode * new_inode = new_dentry->d_inode;
        struct udf_fileident_bh ofibh, nfibh;
        struct FileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
        struct buffer_head *dir_bh = NULL;
        int retval = -ENOENT;
 
-       old_inode = old_dentry->d_inode;
        if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi)))
        {
                if (ofibh.sbh != ofibh.ebh)
@@ -1169,7 +1162,6 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
                goto end_rename;
        }
 
-       new_inode = new_dentry->d_inode;
        nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
        if (nfi)
        {
@@ -1180,10 +1172,6 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
                        udf_release_data(nfibh.sbh);
                        nfi = NULL;
                }
-               else
-               {
-                       DQUOT_INIT(new_inode);
-               }
        }
        if (S_ISDIR(old_inode->i_mode))
        {
index d04b47516b155aba9f2e84946d9df8e04e05cb2f..034064dfdf202c8bfd783dae006773569e68fb19 100644 (file)
@@ -85,7 +85,7 @@ static int udf_vrs(struct super_block *sb, int silent);
 static int udf_load_partition(struct super_block *, lb_addr *);
 static int udf_load_logicalvol(struct super_block *, struct buffer_head *, lb_addr *);
 static void udf_load_logicalvolint(struct super_block *, extent_ad);
-static int udf_find_anchor(struct super_block *, int, int);
+static void udf_find_anchor(struct super_block *);
 static int udf_find_fileset(struct super_block *, lb_addr *, lb_addr *);
 static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
 static void udf_load_fileset(struct super_block *, struct buffer_head *, lb_addr *);
@@ -164,7 +164,7 @@ module_exit(exit_udf_fs)
  *     noadinicb       Don't embed data in the inode
  *     shortad         Use short ad's
  *     longad          Use long ad's (default)
- *     strict          Set strict conformance
+ *     nostrict        Unset strict conformance
  *     iocharset=      Set the NLS character set
  *
  *     The remaining are for debugging and disaster recovery:
@@ -208,8 +208,8 @@ udf_parse_options(char *options, struct udf_options *uopt)
        uopt->blocksize = 2048;
        uopt->partition = 0xFFFF;
        uopt->session = 0xFFFFFFFF;
-       uopt->lastblock = 0xFFFFFFFF;
-       uopt->anchor = 0xFFFFFFFF;
+       uopt->lastblock = 0;
+       uopt->anchor = 0;
        uopt->volume = 0xFFFFFFFF;
        uopt->rootdir = 0xFFFFFFFF;
        uopt->fileset = 0xFFFFFFFF;
@@ -244,8 +244,8 @@ udf_parse_options(char *options, struct udf_options *uopt)
                        uopt->gid = simple_strtoul(val, NULL, 0);
                else if (!strcmp(opt, "umask") && val)
                        uopt->umask = simple_strtoul(val, NULL, 0);
-               else if (!strcmp(opt, "strict") && !val)
-                       uopt->flags |= (1 << UDF_FLAG_STRICT);
+               else if (!strcmp(opt, "nostrict") && !val)
+                       uopt->flags &= ~(1 << UDF_FLAG_STRICT);
                else if (!strcmp(opt, "uid") && val)
                        uopt->uid = simple_strtoul(val, NULL, 0);
                else if (!strcmp(opt, "session") && val)
@@ -496,72 +496,36 @@ udf_vrs(struct super_block *sb, int silent)
  *     July 1, 1997 - Andrew E. Mileski
  *     Written, tested, and released.
  */
-static int
-udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
+static void
+udf_find_anchor(struct super_block *sb)
 {
-       int varlastblock = udf_variable_to_fixed(lastblock);
-       int last[] =  { lastblock, lastblock - 2,
-                       lastblock - 150, lastblock - 152,
-                       varlastblock, varlastblock - 2,
-                       varlastblock - 150, varlastblock - 152 };
+       int lastblock = UDF_SB_LASTBLOCK(sb);
        struct buffer_head *bh = NULL;
        Uint16 ident;
        Uint32 location;
        int i;
 
-       UDF_SB_ANCHOR(sb)[0] = 0;
-       UDF_SB_ANCHOR(sb)[1] = 0;
-       UDF_SB_ANCHOR(sb)[2] = 0;
-       UDF_SB_ANCHOR(sb)[3] = 256 + UDF_SB_SESSION(sb);
+       if (lastblock)
+       {
+               int varlastblock = udf_variable_to_fixed(lastblock);
+               int last[] =  { lastblock, lastblock - 2,
+                               lastblock - 150, lastblock - 152,
+                               varlastblock, varlastblock - 2,
+                               varlastblock - 150, varlastblock - 152 };
 
-       lastblock = 0;
+               lastblock = 0;
 
-       /* Search for an anchor volume descriptor pointer */
+               /* Search for an anchor volume descriptor pointer */
 
-       /*  according to spec, anchor is in either:
-        *     block 256
-        *     lastblock-256
-        *     lastblock
-        *  however, if the disc isn't closed, it could be 512 */
+               /*  according to spec, anchor is in either:
+                *     block 256
+                *     lastblock-256
+                *     lastblock
+                *  however, if the disc isn't closed, it could be 512 */
 
-       for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
-       {
-               if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
-               {
-                       ident = location = 0;
-               }
-               else
+               for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
                {
-                       ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
-                       location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
-                       udf_release_data(bh);
-               }
-
-               if (ident == TID_ANCHOR_VOL_DESC_PTR)
-               {
-                       if (location == last[i] - UDF_SB_SESSION(sb))
-                       {
-                               lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
-                               UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
-                       }
-                       else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
-                       {
-                               UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
-                               lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
-                               UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
-                       }
-                       else
-                               udf_debug("Anchor found at block %d, location mismatch %d.\n",
-                                       last[i], location);
-               }
-               else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
-               {
-                       lastblock = last[i];
-                       UDF_SB_ANCHOR(sb)[2] = 512 + UDF_SB_SESSION(sb);
-               }
-               else
-               {
-                       if (!(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
+                       if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
                        {
                                ident = location = 0;
                        }
@@ -571,17 +535,32 @@ udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
                                location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
                                udf_release_data(bh);
                        }
-
-                       if (ident == TID_ANCHOR_VOL_DESC_PTR &&
-                               location == last[i] - 256 - UDF_SB_SESSION(sb))
+       
+                       if (ident == TID_ANCHOR_VOL_DESC_PTR)
+                       {
+                               if (location == last[i] - UDF_SB_SESSION(sb))
+                               {
+                                       lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
+                                       UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+                               }
+                               else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
+                               {
+                                       UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+                                       lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
+                                       UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+                               }
+                               else
+                                       udf_debug("Anchor found at block %d, location mismatch %d.\n",
+                                               last[i], location);
+                       }
+                       else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
                        {
                                lastblock = last[i];
-                               UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+                               UDF_SB_ANCHOR(sb)[3] = 512 + UDF_SB_SESSION(sb);
                        }
                        else
                        {
-                               if (!(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
-                                       sb->s_blocksize)))
+                               if (last[i] < 256 || !(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
                                {
                                        ident = location = 0;
                                }
@@ -591,13 +570,34 @@ udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
                                        location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
                                        udf_release_data(bh);
                                }
-
+       
                                if (ident == TID_ANCHOR_VOL_DESC_PTR &&
-                                       location == udf_variable_to_fixed(last[i]) - 256)
+                                       location == last[i] - 256 - UDF_SB_SESSION(sb))
                                {
-                                       UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
-                                       lastblock = udf_variable_to_fixed(last[i]);
-                                       UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+                                       lastblock = last[i];
+                                       UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+                               }
+                               else
+                               {
+                                       if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
+                                               sb->s_blocksize)))
+                                       {
+                                               ident = location = 0;
+                                       }
+                                       else
+                                       {
+                                               ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+                                               location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+                                               udf_release_data(bh);
+                                       }
+       
+                                       if (ident == TID_ANCHOR_VOL_DESC_PTR &&
+                                               location == udf_variable_to_fixed(last[i]) - 256)
+                                       {
+                                               UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+                                               lastblock = udf_variable_to_fixed(last[i]);
+                                               UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+                                       }
                                }
                        }
                }
@@ -636,15 +636,9 @@ udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
                                }
                        }
                }
-               else if (useranchor != 0xFFFFFFFF)
-               {
-                       UDF_SB_ANCHOR(sb)[i] = useranchor;
-                       useranchor = 0xFFFFFFFF;
-                       i --;
-               }
        }
 
-       return lastblock;
+       UDF_SB_LASTBLOCK(sb) = lastblock;
 }
 
 static int 
@@ -985,8 +979,10 @@ udf_load_logicalvolint(struct super_block *sb, extent_ad loc)
        struct buffer_head *bh = NULL;
        Uint16 ident;
 
-       while ((bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation, &ident)) &&
-               ident == TID_LOGICAL_VOL_INTEGRITY_DESC && loc.extLength > 0)
+       while (loc.extLength > 0 &&
+               (bh = udf_read_tagged(sb, loc.extLocation,
+                       loc.extLocation, &ident)) &&
+               ident == TID_LOGICAL_VOL_INTEGRITY_DESC)
        {
                UDF_SB_LVIDBH(sb) = bh;
                
@@ -1152,6 +1148,8 @@ udf_check_valid(struct super_block *sb, int novrs, int silent)
        else if ((block = udf_vrs(sb, silent)) == -1)
        {
                udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
+               if (!UDF_SB_LASTBLOCK(sb))
+                       UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
                return 0;
        }
        else 
@@ -1218,6 +1216,12 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
                        {
                                lb_addr ino;
 
+                               if (!UDF_SB_LASTBLOCK(sb))
+                               {
+                                       UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
+                                       udf_find_anchor(sb);
+                               }
+
                                if (!UDF_SB_LASTBLOCK(sb))
                                {
                                        udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
@@ -1355,7 +1359,7 @@ udf_read_super(struct super_block *sb, void *options, int silent)
        struct udf_options uopt;
        lb_addr rootdir, fileset;
 
-       uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB);
+       uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
        uopt.uid = -1;
        uopt.gid = -1;
        uopt.umask = 0;
@@ -1409,14 +1413,10 @@ udf_read_super(struct super_block *sb, void *options, int silent)
 
        udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
 
-       if ( uopt.lastblock == 0xFFFFFFFF )
-               UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
-       else
-               UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
-
-       UDF_SB_LASTBLOCK(sb) = udf_find_anchor(sb, uopt.anchor, UDF_SB_LASTBLOCK(sb));
-
-       udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+       UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
+       UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
+       UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
+       UDF_SB_ANCHOR(sb)[3] = UDF_SB_SESSION(sb) + 256;
 
        if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
        {
@@ -1424,6 +1424,8 @@ udf_read_super(struct super_block *sb, void *options, int silent)
                goto error_out;
        }
 
+       udf_find_anchor(sb);
+
        /* Fill in the rest of the superblock */
        sb->s_op = &udf_sb_ops;
        sb->dq_op = NULL;
@@ -1436,6 +1438,8 @@ udf_read_super(struct super_block *sb, void *options, int silent)
                goto error_out;
        }
 
+       udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+
        if ( UDF_SB_LVIDBH(sb) )
        {
                Uint16 minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
@@ -1744,7 +1748,7 @@ udf_count_free_table(struct super_block *sb, struct inode * table)
        unsigned int accum = 0;
        Uint32 extoffset, elen;
        lb_addr bloc, eloc;
-       char etype;
+       Sint8 etype;
        struct buffer_head *bh = NULL;
 
        bloc = UDF_I_LOCATION(table);
@@ -1763,6 +1767,20 @@ udf_count_free(struct super_block *sb)
 {
        unsigned int accum = 0;
 
+       if (UDF_SB_LVIDBH(sb))
+       {
+               if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
+               {
+                       accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
+
+                       if (accum == 0xFFFFFFFF)
+                               accum = 0;
+               }
+       }
+
+       if (accum)
+               return accum;
+
        if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
        {
                accum += udf_count_free_bitmap(sb,
@@ -1786,18 +1804,6 @@ udf_count_free(struct super_block *sb)
                accum += udf_count_free_table(sb,
                        UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
        }
-       if (accum)
-               return accum;
 
-       if (UDF_SB_LVIDBH(sb))
-       {
-               if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
-               {
-                       accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
-
-                       if (accum == 0xFFFFFFFF)
-                               accum = 0;
-               }
-       }
        return accum;
 }
index 2f0c09534fc10549e2c5fab6196c43e5f4a53955..72878e5334e9aeb8d0e4c7621d1a520ec89dbb19 100644 (file)
 #include "udf_sb.h"
 
 static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
-       lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
+       lb_addr eloc, Sint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
 {
        lb_addr neloc = { 0, 0 };
-       int blocks = inode->i_sb->s_blocksize / 512;
        int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
        int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
 
@@ -52,12 +51,10 @@ static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
                if (last_block - first_block > 0)
                {
                        if (etype == EXTENT_RECORDED_ALLOCATED)
-                       {
-                               inode->i_blocks -= (blocks * (last_block - first_block));
                                mark_inode_dirty(inode);
-                       }
+
                        if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
-                               udf_free_blocks(inode, eloc, first_block, last_block - first_block);
+                               udf_free_blocks(inode->i_sb, inode, eloc, first_block, last_block - first_block);
                }
        }
 }
@@ -66,7 +63,7 @@ void udf_truncate_extents(struct inode * inode)
 {
        lb_addr bloc, eloc, neloc = { 0, 0 };
        Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
-       int etype;
+       Sint8 etype;
        int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
        struct buffer_head *bh = NULL;
        int adsize;
@@ -108,7 +105,7 @@ void udf_truncate_extents(struct inode * inode)
                                                memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
                                        else
                                                memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
-                                       udf_free_blocks(inode, bloc, 0, lelen);
+                                       udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
                                }
                                else
                                {
@@ -153,7 +150,7 @@ void udf_truncate_extents(struct inode * inode)
                                memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
                        else
                                memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
-                       udf_free_blocks(inode, bloc, 0, lelen);
+                       udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
                }
                else
                {
index d13911aa76c442db09a7665e11cc78ba4a899f3b..ac4539946a29f40edd87fc4664cdcbe17675a8c0 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
-
 #include <linux/fs.h>
 
 #if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE)
@@ -129,13 +128,13 @@ extern void udf_put_inode(struct inode *);
 extern void udf_delete_inode(struct inode *);
 extern void udf_write_inode(struct inode *, int);
 extern long udf_block_map(struct inode *, long);
-extern int inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
-extern int udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
-extern int udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
-extern int udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern int udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern int udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
-extern int udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
+extern Sint8 inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
+extern Sint8 udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
+extern Sint8 udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
+extern Sint8 udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
+extern Sint8 udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
+extern Sint8 udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
+extern Sint8 udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
 extern void udf_discard_prealloc(struct inode *);
 
 /* misc.c */
@@ -171,9 +170,9 @@ extern struct inode * udf_new_inode (struct inode *, int, int *);
 extern void udf_truncate_extents(struct inode *);
 
 /* balloc.c */
-extern void udf_free_blocks(struct inode *, lb_addr, Uint32, Uint32);
-extern int udf_prealloc_blocks(struct inode *, Uint16, Uint32, Uint32);
-extern int udf_new_block(struct inode *, Uint16, Uint32, int *);
+extern void udf_free_blocks(struct super_block *, struct inode *, lb_addr, Uint32, Uint32);
+extern int udf_prealloc_blocks(struct super_block *, struct inode *, Uint16, Uint32, Uint32);
+extern int udf_new_block(struct super_block *, struct inode *, Uint16, Uint32, int *);
 
 /* fsync.c */
 extern int udf_fsync_file(struct file *, struct dentry *, int);
index 91463a42b66df9c2b19a26974dadc263df39064d..3e5fe64c439492dc274871595370e7e51f4fa55e 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ARM_A_OUT_H__
 #define __ARM_A_OUT_H__
 
+#include <linux/personality.h>
 #include <asm/types.h>
 
 struct exec
index 7e9d4c1e9e1e8a79e2d827018294d81b656bac55..be4f60fb48f255d16633e05ba8a48475ad46954f 100644 (file)
  *    SKID     ID Register
  */
 
-#define _SKCR          _SA1111( 0x0000 )
-#define _SMCR          _SA1111( 0x0004 )
-#define _SKID          _SA1111( 0x0008 )
+#define _SBI_SKCR      _SA1111( 0x0000 )
+#define _SBI_SMCR      _SA1111( 0x0004 )
+#define _SBI_SKID      _SA1111( 0x0008 )
 
 #if LANGUAGE == C
 
-#define SKCR           (*((volatile Word *) SA1111_p2v (_SKCR)))
-#define SMCR           (*((volatile Word *) SA1111_p2v (_SMCR)))
-#define SKID           (*((volatile Word *) SA1111_p2v (_SKID)))
+#define SBI_SKCR       (*((volatile Word *) SA1111_p2v (_SBI_SKCR)))
+#define SBI_SMCR       (*((volatile Word *) SA1111_p2v (_SBI_SMCR)))
+#define SBI_SKID       (*((volatile Word *) SA1111_p2v (_SBI_SKID)))
 
 #endif  /* LANGUAGE == C */
 
 #define SKCR_OPPC      (1<<9)
 #define SKCR_PLLTSTEN  (1<<10)
 #define SKCR_USBIOTSTEN        (1<<11)
+/*
+ * Don't believe the specs!  Take them, throw them outside.  Leave them
+ * there for a week.  Spit on them.  Walk on them.  Stamp on them.
+ * Pour gasoline over them and finally burn them.  Now think about coding.
+ *  - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
+ *  - The Feb 2001 errata (278260-010) says that the previous errata
+ *    (278260-009) is wrong, and its bit actually 12, fixed in spec
+ *    278242-003.
+ *  - The SA1111 manual (278242) says bit 12, but 0 to enable.
+ *  - Reality is bit 13, 1 to enable.
+ *      -- rmk
+ */
 #define SKCR_OE_EN     (1<<13)
 
 #define SMCR_DTIM      (1<<0)
 #define SKPCR_DCLKEN   (1<<7)
 #define SKPCR_PWMCLKEN (1<<8)
 
+/*
+ * USB Host controller
+ */
+#define _USB_OHCI_OP_BASE      _SA1111( 0x400 )
+#define _USB_STATUS            _SA1111( 0x518 )
+#define _USB_RESET             _SA1111( 0x51c )
+#define _USB_INTERRUPTEST      _SA1111( 0x520 )
+
+#define _USB_EXTENT            (_USB_INTERRUPTEST - _USB_OHCI_OP_BASE + 4)
+
+#if LANGUAGE == C
+
+#define USB_OHCI_OP_BASE       (*((volatile Word *) SA1111_p2v (_USB_OHCI_OP_BASE)))
+#define USB_STATUS             (*((volatile Word *) SA1111_p2v (_USB_STATUS)))
+#define USB_RESET              (*((volatile Word *) SA1111_p2v (_USB_RESET)))
+#define USB_INTERRUPTEST       (*((volatile Word *) SA1111_p2v (_USB_INTERRUPTEST)))
+
+#endif  /* LANGUAGE == C */
+
+#define USB_RESET_FORCEIFRESET (1 << 0)
+#define USB_RESET_FORCEHCRESET (1 << 1)
+#define USB_RESET_CLKGENRESET  (1 << 2)
+#define USB_RESET_SIMSCALEDOWN (1 << 3)
+#define USB_RESET_USBINTTEST   (1 << 4)
+#define USB_RESET_SLEEPSTBYEN  (1 << 5)
+#define USB_RESET_PWRSENSELOW  (1 << 6)
+#define USB_RESET_PWRCTRLLOW   (1 << 7)
+
 /*
  * Serial Audio Controller
  *
diff --git a/include/asm-arm/arch-sa1100/adsbitsy.h b/include/asm-arm/arch-sa1100/adsbitsy.h
new file mode 100644 (file)
index 0000000..cb82224
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/adsbitsy.h
+ *
+ * Created 7/3/01 by Woojung <whuh@applieddata.net>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS Bitsy Board
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define        SA1111_BASE             (0x18000000)
index 2992dad54f63f10b054333eadd40d45ae2a35cea..ae282d1ffd9a748c7054549c15ea81bb9397b98d 100644 (file)
@@ -38,7 +38,7 @@
 #define BCR_DB1111 \
        (BCR_SPK_OFF  | BCR_QMUTE     | BCR_LED_GREEN  | BCR_LED_RED   | \
         BCR_RS232EN  | BCR_LCD_12RGB | BCR_CF_BUS_OFF | BCR_STEREO_LB | \
-        BCR_IRDA_MD1 | BCR_CF_RST)
+        BCR_IRDA_MD0 | BCR_CF_RST)
 
 #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) */
@@ -183,6 +183,10 @@ extern unsigned long BCR_value;
 #define NCR_A1VPP              (1<<6)
 
 #ifndef __ASSEMBLY__
+#ifdef CONFIG_ASSABET_NEPONSET
 #define machine_has_neponset()  ((SCR_value & SCR_SA1111) == 0)
+#else
+#define machine_has_neponset() (0)
+#endif
 #endif
 
diff --git a/include/asm-arm/arch-sa1100/bitsy.h b/include/asm-arm/arch-sa1100/bitsy.h
deleted file mode 100644 (file)
index acd71eb..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-*
-* Definitions for H3600 Handheld Computer
-*
-* Copyright 2000 Compaq Computer Corporation.
-*
-* Use consistent with the GNU GPL is permitted,
-* provided that this copyright notice is
-* preserved in its entirety in all copies and derived works.
-*
-* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-* FITNESS FOR ANY PARTICULAR PURPOSE.
-*
-* Author: Jamey Hicks.
-*
-*/
-
-#ifndef _INCLUDE_BITSY_H_
-#define _INCLUDE_BITSY_H_
-
-#define GPIO_BITSY_NPOWER_BUTTON       GPIO_GPIO (0)
-#define GPIO_BITSY_ACTION_BUTTON       GPIO_GPIO (18)
-
-#define GPIO_BITSY_PCMCIA_CD0          GPIO_GPIO (17)
-#define GPIO_BITSY_PCMCIA_CD1          GPIO_GPIO (10)
-#define GPIO_BITSY_PCMCIA_IRQ0         GPIO_GPIO (21)
-#define GPIO_BITSY_PCMCIA_IRQ1         GPIO_GPIO (11)
-
-/* audio sample rate clock generator */
-#define GPIO_BITSY_CLK_SET0            GPIO_GPIO (12)
-#define GPIO_BITSY_CLK_SET1            GPIO_GPIO (13)
-
-/* UDA1341 L3 Interface */
-#define GPIO_BITSY_L3_DATA             GPIO_GPIO (14)
-#define GPIO_BITSY_L3_CLOCK            GPIO_GPIO (16)
-#define GPIO_BITSY_L3_MODE             GPIO_GPIO (15)
-
-#define GPIO_BITSY_OPT_LOCK            GPIO_GPIO (22)
-#define GPIO_BITSY_OPT_IRQ             GPIO_GPIO (24)
-#define GPIO_BITSY_OPT_DET             GPIO_GPIO (27)
-
-#define GPIO_BITSY_COM_DCD             GPIO_GPIO (23)
-#define GPIO_BITSY_COM_CTS             GPIO_GPIO (25)
-#define GPIO_BITSY_COM_RTS             GPIO_GPIO (26)
-
-#define IRQ_GPIO_BITSY_NPOWER_BUTTON    IRQ_GPIO0
-#define IRQ_GPIO_BITSY_ACTION_BUTTON    IRQ_GPIO18
-#define IRQ_GPIO_BITSY_PCMCIA_CD0      IRQ_GPIO17
-#define IRQ_GPIO_BITSY_PCMCIA_CD1      IRQ_GPIO10
-#define IRQ_GPIO_BITSY_PCMCIA_IRQ0     IRQ_GPIO21
-#define IRQ_GPIO_BITSY_PCMCIA_IRQ1     IRQ_GPIO11
-#define IRQ_GPIO_BITSY_OPT_IRQ         IRQ_GPIO24
-#define IRQ_GPIO_BITSY_OPT_DET         IRQ_GPIO27
-#define IRQ_GPIO_BITSY_COM_DCD          IRQ_GPIO23
-#define IRQ_GPIO_BITSY_COM_CTS          IRQ_GPIO25
-
-#define EGPIO_BITSY_VPP_ON             (1 << 0)
-#define EGPIO_BITSY_CARD_RESET         (1 << 1)  /* reset the attached pcmcia/compactflash card.  active high. */
-#define EGPIO_BITSY_OPT_RESET          (1 << 2)  /* reset the attached option pack.  active high. */
-#define EGPIO_BITSY_CODEC_NRESET       (1 << 3)  /* reset the onboard UDA1341.  active low. */
-#define EGPIO_BITSY_OPT_NVRAM_ON       (1 << 4)  /* apply power to optionpack nvram, active high. */
-#define EGPIO_BITSY_OPT_ON             (1 << 5)  /* full power to option pack.  active high. */
-#define EGPIO_BITSY_LCD_ON             (1 << 6)  /* enable 3.3V to LCD.  active high. */
-#define EGPIO_BITSY_RS232_ON           (1 << 7)  /* UART3 transceiver force on.  Active high. */
-#define EGPIO_BITSY_LCD_PCI            (1 << 8)  /* LCD control IC enable.  active high. */
-#define EGPIO_BITSY_IR_ON              (1 << 9)  /* apply power to IR module.  active high. */
-#define EGPIO_BITSY_AUD_AMP_ON         (1 << 10) /* apply power to audio power amp.  active high. */
-#define EGPIO_BITSY_AUD_PWR_ON         (1 << 11) /* apply poewr to reset of audio circuit.  active high. */
-#define EGPIO_BITSY_QMUTE              (1 << 12) /* mute control for onboard UDA1341.  active high. */
-#define EGPIO_BITSY_IR_FSEL            (1 << 13) /* IR speed select: 1->fast, 0->slow */
-#define EGPIO_BITSY_LCD_5V_ON          (1 << 14) /* enable 5V to LCD. active high. */
-#define EGPIO_BITSY_LVDD_ON            (1 << 15) /* enable 9V and -6.5V to LCD. */
-
-#ifndef __ASSEMBLY__
-#define BITSY_EGPIO    (*(volatile int *)0xf0000000)
-extern void clr_bitsy_egpio(unsigned long x);
-extern void set_bitsy_egpio(unsigned long x);
-#endif
-
-#endif
index d44589428861d32b59602583d793188abc573640..471c41021d730c64eb54f6fb1d67b04d918227fa 100644 (file)
@@ -109,8 +109,13 @@ extern int sa1111_check_dma_bug( dma_addr_t addr );
 static inline void
 __arch_adjust_zones(int node, unsigned long *size, unsigned long *holes)
 {
-       size[1] = size[0] - 256;
-       size[0] = 256;
+       unsigned int sz = 256;
+
+       if (node != 0)
+               sz = 0;
+
+       size[1] = size[0] - sz;
+       size[0] = sz;
 }
 
 #define arch_adjust_zones(node,size,holes) __arch_adjust_zones(node,size,holes)
diff --git a/include/asm-arm/arch-sa1100/graphicsmaster.h b/include/asm-arm/arch-sa1100/graphicsmaster.h
new file mode 100644 (file)
index 0000000..289bc25
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/graphicsmaster.h
+ *
+ * Created 2000/12/18 by Woojung Huh <whuh@applieddata.net>
+ *
+ * This file comes from graphicsclient.h of Nicolas Pitre <nico@cam.org>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS GraphicsMaster
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define ADS_CPLD_BASE          (0x10000000)
+#define ADS_p2v( x )           ((x) - ADS_CPLD_BASE + 0xf0000000)
+#define ADS_v2p( x )           ((x) - 0xf0000000 + ADS_CPLD_BASE)
+
+
+#define _ADS_SW_SWITCHES       0x10060000      /* Software Switches */
+
+/* Extra IRQ Controller */
+#define _ADS_INT_ST1           0x10080000      /* IRQ Status #1 */
+#define _ADS_INT_ST2           0x10080004      /* IRQ Status #2 */
+#define _ADS_INT_EN1           0x10080008      /* IRQ Enable #1 */
+#define _ADS_INT_EN2           0x1008000c      /* IRQ Enable #2 */
+#define _ADS_DCR                       0x10080018      /* Discrete Control Reg */
+
+/* Discrete Controller (AVR:Atmel AT90LS8535) */
+#define _ADS_AVR_REG           0x10080018
+
+/* On-Board Ethernet */
+#define _ADS_ETHERNET          0x100e0000      /* Ethernet */
+
+/* On-Board Quad UART 16C554 */
+#define        ADS_QUAD_UART1          0x10100000
+#define        ADS_QUAD_UART2          0x10120000
+#define        ADS_QUAD_UART3          0x10140000
+#define        ADS_QUAD_UART4          0x10160000
+
+/* LEDs */
+#define ADS_LED0       GPIO_GPIO20             /* on-board Green */
+#define ADS_LED1       GPIO_GPIO25             /* on-board Yellow */
+#define ADS_LED2       GPIO_GPIO26             /* on-board Red */
+
+/* DCR */
+#define DCR_AVR_RESET          0x01
+#define DCR_SA1111_RESET       0x02
+#define        DCR_BACKLITE_ON         0x04
+
+/* Virtual register addresses */
+
+#ifndef __ASSEMBLY__
+#define ADS_INT_ST1    (*((volatile u_char *) ADS_p2v(_ADS_INT_ST1)))
+#define ADS_INT_ST2    (*((volatile u_char *) ADS_p2v(_ADS_INT_ST2)))
+#define ADS_INT_EN1    (*((volatile u_char *) ADS_p2v(_ADS_INT_EN1)))
+#define ADS_INT_EN2    (*((volatile u_char *) ADS_p2v(_ADS_INT_EN2)))
+#define ADS_ETHERNET   ((int) ADS_p2v(_ADS_ETHERNET))
+#define ADS_AVR_REG    (*((volatile u_char *) ADS_p2v(_ADS_AVR_REG)))
+#define ADS_DCR                (*((volatile u_char *) ADS_p2v(_ADS_DCR)))
+#endif
+
+#define        SA1111_BASE     (0x18000000)
+
+#include "SA-1111.h"
diff --git a/include/asm-arm/arch-sa1100/h3600.h b/include/asm-arm/arch-sa1100/h3600.h
new file mode 100644 (file)
index 0000000..1ae5b77
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+*
+* Definitions for H3600 Handheld Computer
+*
+* Copyright 2000 Compaq Computer Corporation.
+*
+* Use consistent with the GNU GPL is permitted,
+* provided that this copyright notice is
+* preserved in its entirety in all copies and derived works.
+*
+* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+* FITNESS FOR ANY PARTICULAR PURPOSE.
+*
+* Author: Jamey Hicks.
+*
+*/
+
+#ifndef _INCLUDE_H3600_H_
+#define _INCLUDE_H3600_H_
+
+#define GPIO_H3600_NPOWER_BUTTON       GPIO_GPIO (0)
+#define GPIO_H3600_ACTION_BUTTON       GPIO_GPIO (18)
+
+#define GPIO_H3600_PCMCIA_CD0          GPIO_GPIO (17)
+#define GPIO_H3600_PCMCIA_CD1          GPIO_GPIO (10)
+#define GPIO_H3600_PCMCIA_IRQ0         GPIO_GPIO (21)
+#define GPIO_H3600_PCMCIA_IRQ1         GPIO_GPIO (11)
+
+/* audio sample rate clock generator */
+#define GPIO_H3600_CLK_SET0            GPIO_GPIO (12)
+#define GPIO_H3600_CLK_SET1            GPIO_GPIO (13)
+
+/* UDA1341 L3 Interface */
+#define GPIO_H3600_L3_DATA             GPIO_GPIO (14)
+#define GPIO_H3600_L3_CLOCK            GPIO_GPIO (16)
+#define GPIO_H3600_L3_MODE             GPIO_GPIO (15)
+
+#define GPIO_H3600_OPT_LOCK            GPIO_GPIO (22)
+#define GPIO_H3600_OPT_IRQ             GPIO_GPIO (24)
+#define GPIO_H3600_OPT_DET             GPIO_GPIO (27)
+
+#define GPIO_H3600_COM_DCD             GPIO_GPIO (23)
+#define GPIO_H3600_COM_CTS             GPIO_GPIO (25)
+#define GPIO_H3600_COM_RTS             GPIO_GPIO (26)
+
+#define IRQ_GPIO_H3600_NPOWER_BUTTON    IRQ_GPIO0
+#define IRQ_GPIO_H3600_ACTION_BUTTON    IRQ_GPIO18
+#define IRQ_GPIO_H3600_PCMCIA_CD0      IRQ_GPIO17
+#define IRQ_GPIO_H3600_PCMCIA_CD1      IRQ_GPIO10
+#define IRQ_GPIO_H3600_PCMCIA_IRQ0     IRQ_GPIO21
+#define IRQ_GPIO_H3600_PCMCIA_IRQ1     IRQ_GPIO11
+#define IRQ_GPIO_H3600_OPT_IRQ         IRQ_GPIO24
+#define IRQ_GPIO_H3600_OPT_DET         IRQ_GPIO27
+#define IRQ_GPIO_H3600_COM_DCD          IRQ_GPIO23
+#define IRQ_GPIO_H3600_COM_CTS          IRQ_GPIO25
+
+#define EGPIO_H3600_VPP_ON             (1 << 0)
+#define EGPIO_H3600_CARD_RESET         (1 << 1)  /* reset the attached pcmcia/compactflash card.  active high. */
+#define EGPIO_H3600_OPT_RESET          (1 << 2)  /* reset the attached option pack.  active high. */
+#define EGPIO_H3600_CODEC_NRESET       (1 << 3)  /* reset the onboard UDA1341.  active low. */
+#define EGPIO_H3600_OPT_NVRAM_ON       (1 << 4)  /* apply power to optionpack nvram, active high. */
+#define EGPIO_H3600_OPT_ON             (1 << 5)  /* full power to option pack.  active high. */
+#define EGPIO_H3600_LCD_ON             (1 << 6)  /* enable 3.3V to LCD.  active high. */
+#define EGPIO_H3600_RS232_ON           (1 << 7)  /* UART3 transceiver force on.  Active high. */
+#define EGPIO_H3600_LCD_PCI            (1 << 8)  /* LCD control IC enable.  active high. */
+#define EGPIO_H3600_IR_ON              (1 << 9)  /* apply power to IR module.  active high. */
+#define EGPIO_H3600_AUD_AMP_ON         (1 << 10) /* apply power to audio power amp.  active high. */
+#define EGPIO_H3600_AUD_PWR_ON         (1 << 11) /* apply poewr to reset of audio circuit.  active high. */
+#define EGPIO_H3600_QMUTE              (1 << 12) /* mute control for onboard UDA1341.  active high. */
+#define EGPIO_H3600_IR_FSEL            (1 << 13) /* IR speed select: 1->fast, 0->slow */
+#define EGPIO_H3600_LCD_5V_ON          (1 << 14) /* enable 5V to LCD. active high. */
+#define EGPIO_H3600_LVDD_ON            (1 << 15) /* enable 9V and -6.5V to LCD. */
+
+#ifndef __ASSEMBLY__
+#define H3600_EGPIO    (*(volatile int *)0xf0000000)
+extern void clr_h3600_egpio(unsigned long x);
+extern void set_h3600_egpio(unsigned long x);
+#endif
+
+#endif
index 801008b3e4bd17baad8115a649f7f4a8bc316a27..2ed692616b16249669e99f07d6cdcb3362b972a3 100644 (file)
@@ -122,8 +122,8 @@ extern unsigned short get_cclk_frequency(void);
 #include "empeg.h"
 #endif
 
-#ifdef CONFIG_SA1100_BITSY
-#include "bitsy.h"
+#ifdef CONFIG_SA1100_H3600
+#include "h3600.h"
 #endif
 
 #ifdef CONFIG_SA1100_ITSY
@@ -154,6 +154,14 @@ extern unsigned short get_cclk_frequency(void);
 #include "simpad.h"
 #endif
 
+#if defined(CONFIG_SA1100_GRAPHICSMASTER)
+#include "graphicsmaster.h"
+#endif
+
+#if defined(CONFIG_SA1100_ADSBITSY)
+#include "adsbitsy.h"
+#endif
+
 #ifdef CONFIG_SA1101
 
 /*
index f83cddd3c189ce7cc57d55d6c11d0a49d9baecce..806efb138176693444636fe63e67eb761c76584c 100644 (file)
@@ -72,7 +72,7 @@
 #define        NR_IRQS         (IRQ_GPIO27 + 1)
 
 
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_GRAPHICSMASTER)
 #define ADS_EXT_IRQ(x) (IRQ_GPIO27 + 1 + (x))
 #undef NR_IRQS
 #define NR_IRQS                (ADS_EXT_IRQ(15) + 1)
 
 #if defined(CONFIG_SA1111)
 
+#if defined(CONFIG_SA1100_GRAPHICSMASTER)
+#define        SA1111_IRQ(x)   (ADS_EXT_IRQ(15) + 1 + 1 + (x))
+#else
 #define SA1111_IRQ(x)  (IRQ_GPIO27 + 1 + (x))
+#endif
 
 #define GPAIN0         SA1111_IRQ(0)
 #define GPAIN1         SA1111_IRQ(1)
index 83e9c02ee786ee8b840697f418f2dbb6a8dd9d95..90ff3e8119157d06d025a44a34f6523ffb55e424 100644 (file)
@@ -8,11 +8,37 @@
 #define _SA1100_KEYBOARD_H
 
 #include <linux/config.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
 
+extern struct kbd_ops_struct *kbd_ops;
 
-// #ifdef CONFIG_SA1100_BRUTUS
-/* need fixing... */
-#if 0
+#define kbd_disable_irq()      do { } while(0);
+#define kbd_enable_irq()       do { } while(0);
+
+
+/*
+ * SA1111 keyboard driver
+ */
+extern void sa1111_kbd_init_hw(void);
+
+/*
+ * GraphicsClient keyboard driver
+ */
+extern void gc_kbd_init_hw(void);
+
+static inline void kbd_init_hw(void)
+{
+       if (machine_is_assabet() && machine_has_neponset())
+               sa1111_kbd_init_hw();
+
+       if (machine_is_graphicsclient())
+               gc_kbd_init_hw();
+}
+
+
+
+#if 0   /* Brutus needs fixing */
 
 extern int Brutus_kbd_translate(unsigned char scancode, unsigned char *keycode,
                           char raw_mode);
@@ -34,7 +60,9 @@ extern unsigned char Brutus_kbd_sysrq_xlate[128];
 
 #define SYSRQ_KEY 0x54
 
-#elif CONFIG_SA1100_GRAPHICSCLIENT
+#elif 0 // CONFIG_SA1100_GRAPHICSCLIENT
+extern int gc_kbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int gc_kbd_getkeycode(unsigned int scancode);
 extern int gc_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);
 extern void gc_kbd_leds(unsigned char leds);
 extern void gc_kbd_init_hw(void);
@@ -42,137 +70,17 @@ extern void gc_kbd_enable_irq(void);
 extern void gc_kbd_disable_irq(void);
 extern unsigned char gc_kbd_sysrq_xlate[128];
 
-#define kbd_setkeycode(x...)    (-ENOSYS)
-#define kbd_getkeycode(x...)    (-ENOSYS)
+#define kbd_setkeycode(x...)    gc_kbd_setkeycode      //(-ENOSYS)
+#define kbd_getkeycode(x...)    gc_kbd_getkeycode      //(-ENOSYS)
 #define kbd_translate           gc_kbd_translate
 #define kbd_unexpected_up(x...) (1)
 #define kbd_leds                gc_kbd_leds
 #define kbd_init_hw             gc_kbd_init_hw
 #define kbd_enable_irq          gc_kbd_enable_irq
 #define kbd_disable_irq         gc_kbd_disable_irq
-#define kbd_sysrq_xlate         gc_kbd_sysrq_xlate
-
-#elif CONFIG_SA1100_BITSY
-
-#define kbd_setkeycode(x...)    (-ENOSYS)
-#define kbd_getkeycode(x...)    (-ENOSYS)
-#define kbd_translate(sc_,kc_,rm_)     ((*(kc_)=(sc_)),1)
-#define kbd_unexpected_up(x...) (1)
-#define kbd_leds(x...)         do { } while (0)
-#define kbd_init_hw(x...)      do { } while (0)
-#define kbd_enable_irq(x...)   do { } while (0)
-#define kbd_disable_irq(x...)  do { } while (0)
-
-#elif 0 //defined(CONFIG_SA1111)   /*@@@@@*/
-
-#define KEYBOARD_IRQ           TPRXINT
-#define DISABLE_KBD_DURING_INTERRUPTS  0
+#define kbd_sysrq_xlate         (1)
 
-/* redefine some macros */
-#ifdef KBD_DATA_REG
-#undef KBD_DATA_REG
 #endif
-#ifdef KBD_STATUS_REG
-#undef KBD_STATUS_REG
-#endif
-#ifdef KBD_CNTL_REG
-#undef KBD_CNTL_REG
-#endif
-#define KBD_DATA_REG           KBDDATA
-#define KBD_STATUS_REG         KBDSTAT
-#define KBD_CNTL_REG           KBDCR
-
-extern int sa1111_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int sa1111_getkeycode(unsigned int scancode);
-extern int sa1111_translate(unsigned char scancode, unsigned char *keycode,
-                               char raw_mode);
-extern char sa1111_unexpected_up(unsigned char keycode);
-extern void sa1111_leds(unsigned char leds);
-extern void sa1111_init_hw(void);
-extern unsigned char sa1111_sysrq_xlate[128];
-
-#define kbd_setkeycode         sa1111_setkeycode
-#define kbd_getkeycode         sa1111_getkeycode
-#define kbd_translate          sa1111_translate
-#define kbd_unexpected_up      sa1111_unexpected_up
-#define kbd_leds               sa1111_leds
-#define kbd_init_hw            sa1111_init_hw
-#define kbd_sysrq_xlate                sa1111_sysrq_xlate
-#define kbd_disable_irq(x...)  do{;}while(0)
-#define kbd_enable_irq(x...)   do{;}while(0)
-
-#define SYSRQ_KEY 0x54
-
-/* resource allocation */
-#define kbd_request_region()
-#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
-                                       "keyboard", NULL)
-
-/* How to access the keyboard macros on this platform.  */
-#define kbd_read_input()       (*KBDDATA & 0x00ff)
-#define kbd_read_status()      (*KBDSTAT & 0x01ff)
-#define kbd_write_output(val)  (*KBDDATA = (val))
-#define kbd_write_command(val) (*KBDCR = (val))
-
-/* Some stoneage hardware needs delays after some operations.  */
-#define kbd_pause() do {;} while(0)
-
-/* bit definitions for some registers */
-#define KBD_CR_ENA     (1<<3)
-
-#define KBD_STAT_RXB   (1<<4)
-#define KBD_STAT_RXF   (1<<5)
-#define KBD_STAT_TXB   (1<<6)
-#define KBD_STAT_TXE   (1<<7)
-#define KBD_STAT_STP   (1<<8)
-
-/*
- * Machine specific bits for the PS/2 driver
- */
-
-#define AUX_IRQ                MSRXINT
-
-#define aux_request_irq(hand, dev_id)  \
-               request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
-#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
-
-/* How to access the mouse macros on this platform.  */
-#define mse_read_input()       (*MSEDATA & 0x00ff)
-#define mse_read_status()      (*MSESTAT & 0x01ff)
-#define mse_write_output(val)  (*MSEDATA = (val))
-#define mse_write_command(val) (*MSECR = (val))
-
-/* bit definitions for some registers */
-#define MSE_CR_ENA     (1<<3)
-
-#define MSE_STAT_RXB   (1<<4)
-#define MSE_STAT_RXF   (1<<5)
-#define MSE_STAT_TXB   (1<<6)
-#define MSE_STAT_TXE   (1<<7)
-#define MSE_STAT_STP   (1<<8)
-
-
-#else
-
-/* dummy i.e. no real keyboard */
-#define kbd_setkeycode(x...)   (-ENOSYS)
-#define kbd_getkeycode(x...)   (-ENOSYS)
-#define kbd_translate(x...)    (0)
-#define kbd_unexpected_up(x...)        (1)
-#define kbd_leds(x...)         do {;} while (0)
-#define kbd_init_hw(x...)      do {;} while (0)
-#define kbd_enable_irq(x...)   do {;} while (0)
-#define kbd_disable_irq(x...)  do {;} while (0)
-
-#endif
-
-
-/* needed if MAGIC_SYSRQ is enabled for serial console */
-#ifndef SYSRQ_KEY
-#define SYSRQ_KEY              ((unsigned char)(-1))
-#define kbd_sysrq_xlate         ((unsigned char *)NULL)
-#endif
-
 
 #endif  /* _SA1100_KEYBOARD_H */
 
index 4f7d0b7bfaf45eed0c88902ae7d3f8c3faa8617e..b261dd4437aebbb356b8ca4568118ccd0ad8b587 100644 (file)
@@ -11,6 +11,7 @@
 #error "include <asm/hardware.h> instead"
 #endif
 
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
 
 /* GPIOs for which the generic definition doesn't say much */
 #define GPIO_CF_BUS_ON         GPIO_GPIO (3)
 
 #define IRQ_GPIO_CF_IRQ                IRQ_GPIO21
 #define IRQ_GPIO_CF_CD         IRQ_GPIO22
+
+#else
+/*
+ *  These definitions are for PCMCIA/IDE card
+ *
+ *  PSKTSEL = 0 ---> PCMCIA
+ *  PCMCIA_RESET = GPIO_7        ( output )( 0: normal   1: reset )
+ *  PCMCIA_IRQ = GPIO_24         ( input )
+ *  PCMCIA_CD = GPIO_25          ( input )
+ *
+ *  PSKTSEL = 1 ---> IDE port
+ *  IDE_IRQ = GPIO_23            ( input )
+ *
+ *  !!WARNING!!
+ *  When the PCMCIA/IDE card is inserted, the CF slot
+ *  should not have any card inserted!!
+ *
+ */
+
+#define GPIO_PCMCIA_RESET       GPIO_GPIO (7)
+#define GPIO_PCMCIA_IRQ         GPIO_GPIO (24)
+#define GPIO_PCMCIA_CD          GPIO_GPIO (25)
+#define GPIO_IDE_IRQ            GPIO_GPIO (8)
+
+#define IRQ_PCMCIA_IRQ          IRQ_GPIO24
+#define IRQ_PCMCIA_CD           IRQ_GPIO25
+#define IRQ_IDE_IRQ             IRQ_GPIO8
+
+#endif
+
+/*
+ * On board LAN chip
+ */
+#define PANGOLIN_LAN_ADDR      0x32000000
+#define PANGOLIN_LAN_RESET     GPIO_GPIO (8)
+#define PANGOLIN_LAN_IRQ       GPIO_GPIO (26)
+#define PANGOLIN_IRQ_LAN_IRQ   IRQ_GPIO26
+
index fc1daa24eb5099adbcd55f62615086a46574d546..c505e14156b5472740c7bc8b92ee2bbcdc75be25 100644 (file)
@@ -3,23 +3,16 @@
  *
  * (C) 1999 Nicolas Pitre <nico@cam.org>
  *
- * Reorganised to use machine_is_*() macros.
+ * Reorganised to be machine independent.
  */
 
 #include "hardware.h"
 
-#include <asm/mach-types.h>
-
-/* Assabet's Status Control "Register" */
-unsigned long SCR_value;
-
-/* sa1100_setup() will perform any special initialization for UART, etc. */
-extern void sa1100_setup( int arch_id );
-#define arch_decomp_setup()    sa1100_setup(arch_id)
-
 /*
  * The following code assumes the serial port has already been
- * initialized by the bootloader or such...
+ * initialized by the bootloader.  We search for the first enabled
+ * port in the most probable order.  If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
  */
 
 #define UART(x)                (*(volatile unsigned long *)(serial_port + (x)))
@@ -28,22 +21,15 @@ static void puts( const char *s )
 {
        unsigned long serial_port;
 
-       if (machine_is_assabet()) {
-               if( machine_has_neponset() )
-                       serial_port = _Ser3UTCR0;
-               else
-                       serial_port = _Ser1UTCR0;
-       } else if (machine_is_brutus()||machine_is_nanoengine() ||
-                  machine_is_pangolin() || machine_is_freebird() ||
-                  machine_is_pfs168() || machine_is_flexanet())
-               serial_port = _Ser1UTCR0;
-       else if (machine_is_empeg() || machine_is_bitsy() ||
-                machine_is_victor() || machine_is_lart() ||
-                machine_is_sherman() || machine_is_yopy() ||
-                machine_is_huw_webpanel() || machine_is_itsy() )
+       do {
                serial_port = _Ser3UTCR0;
-       else
+               if (UART(UTCR3) & UTCR3_TXE) break;
+               serial_port = _Ser1UTCR0;
+               if (UART(UTCR3) & UTCR3_TXE) break;
+               serial_port = _Ser2UTCR0;
+               if (UART(UTCR3) & UTCR3_TXE) break;
                return;
+       } while (0);
 
        for (; *s; s++) {
                /* wait for space in the UART's transmiter */
@@ -63,4 +49,5 @@ static void puts( const char *s )
 /*
  * Nothing to do for these
  */
+#define arch_decomp_setup()
 #define arch_decomp_wdog()
index ba1e5492811a2122e26d02a5c8d121e62605844d..1e488f0945969217ddcaf68657421e941fc41657 100644 (file)
 #error SMP not supported
 #endif
 
-#ifdef CONFIG_ARCH_CO285
 typedef struct { volatile int counter; } atomic_t;
-#else
-typedef struct { int counter; } atomic_t;
-#endif
 
 #define ATOMIC_INIT(i) { (i) }
 
index 7f07bc8e55cd0d7369b9d30d387c0ffcd0f3b790..5348bb4699b0f8cdb97f8ba672f6f2e3a25eb80e 100644 (file)
@@ -9,6 +9,7 @@
  */
 #ifndef __ASSEMBLY__
 
+#include <asm/memory.h>
 #include <asm/page.h>
 
 /* forward-declare task_struct */
@@ -156,4 +157,13 @@ extern const struct processor sa110_processor_functions;
 
 #define cpu_switch_mm(pgd,tsk)                 cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
 
+#define cpu_get_pgd()  \
+       ({                                              \
+               unsigned long pg;                       \
+               __asm__("mrc p15, 0, %0, c2, c0, 0"     \
+                        : "=r" (pg));                  \
+               pg &= ~0x3fff;                          \
+               (pgd_t *)phys_to_virt(pg);              \
+       })
+
 #endif
index 476115883f4667477d64001c2d6f65868d007e71..0c561b7037d90cc502dd290cc60ce5b0a1865122 100644 (file)
@@ -51,6 +51,7 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/memory.h>
 #include <asm/page.h>
 
 /* forward declare task_struct */
@@ -86,4 +87,13 @@ extern volatile void cpu_reset(unsigned long addr);
 
 #define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
 
+#define cpu_get_pgd()  \
+       ({                                              \
+               unsigned long pg;                       \
+               __asm__("mrc p15, 0, %0, c2, c0, 0"     \
+                        : "=r" (pg));                  \
+               pg &= ~0x3fff;                          \
+               (pgd_t *)phys_to_virt(pg);              \
+       })
+
 #endif
index c3111a0a2e83f3ce00e61c5a744f8f31911d4296..572e729095f8ce688091958e0baff900055a9e60 100644 (file)
@@ -2,6 +2,7 @@
 #define __ASM_HARDIRQ_H
 
 #include <linux/config.h>
+#include <linux/cache.h>
 #include <linux/threads.h>
 
 /* softirq.h is sensitive to the offsets of these fields */
index 274dcf0773c530907e3e7113a68144b75e9757e8..4d497bdb9a9796b6efb6a7fa50bca889374fcff0 100644 (file)
 
 /*  PCI_CFG bits
  */
+#define V3_PCI_CFG_M_I2O_EN            (1 << 15)
+#define V3_PCI_CFG_M_IO_REG_DIS                (1 << 14)
+#define V3_PCI_CFG_M_IO_DIS            (1 << 13)
+#define V3_PCI_CFG_M_EN3V              (1 << 12)
 #define V3_PCI_CFG_M_RETRY_EN           (1 << 10)
 #define V3_PCI_CFG_M_AD_LOW1            (1 << 9)
 #define V3_PCI_CFG_M_AD_LOW0            (1 << 8)
index 8d7520f0fdeacaf5e9afbe76c367abcbab69497c..91e50dc218f0836430c7ce085ecc8844845e8528 100644 (file)
@@ -72,18 +72,22 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
 #include <asm/arch/io.h>
 
 /*
- * IO definitions.  We define {out,in,outs,ins}[bwl] if __io is
- * defined by the machine.  Otherwise, these definitions are left
- * for the machine specific header files to pick up.
+ * IO definitions.  We define {out,in,outs,ins}[bwl] if __io is defined
+ * by the machine.  Otherwise, these definitions are left for the machine
+ * specific header files to pick up.
+ *
+ * Note that we prevent GCC re-ordering or caching values in expressions
+ * by introducing sequence points into the in*() definitions.  Note that
+ * __raw_* do not guarantee this behaviour.
  */
 #ifdef __io
 #define outb(v,p)                      __raw_writeb(v,__io(p))
 #define outw(v,p)                      __raw_writew(v,__io(p))
 #define outl(v,p)                      __raw_writel(v,__io(p))
 
-#define inb(p)                         __raw_readb(__io(p))
-#define inw(p)                         __raw_readw(__io(p))
-#define inl(p)                         __raw_readl(__io(p))
+#define inb(p)         ({ unsigned int __v = __raw_readb(__io(p)); __v; })
+#define inw(p)         ({ unsigned int __v = __raw_readw(__io(p)); __v; })
+#define inl(p)         ({ unsigned int __v = __raw_readl(__io(p)); __v; })
 
 #define outsb(p,d,l)                   __raw_writesb(__io(p),d,l)
 #define outsw(p,d,l)                   __raw_writesw(__io(p),d,l)
@@ -168,9 +172,10 @@ extern void __readwrite_bug(const char *fn);
  */
 #ifdef __mem_pci
 
-#define readb(addr)                    __raw_readb(__mem_pci(addr))
-#define readw(addr)                    __raw_readw(__mem_pci(addr))
-#define readl(addr)                    __raw_readl(__mem_pci(addr))
+#define readb(addr) ({ unsigned int __v = __raw_readb(__mem_pci(addr)); __v; })
+#define readw(addr) ({ unsigned int __v = __raw_readw(__mem_pci(addr)); __v; })
+#define readl(addr) ({ unsigned int __v = __raw_readl(__mem_pci(addr)); __v; })
+
 #define writeb(val,addr)               __raw_writeb(val,__mem_pci(addr))
 #define writew(val,addr)               __raw_writew(val,__mem_pci(addr))
 #define writel(val,addr)               __raw_writel(val,__mem_pci(addr))
index 5f47b7ee7105ed721d388bd371061e05ce6e31a1..9e15e251e5dec4b30808391f2a7da9df6bfa0760 100644 (file)
@@ -27,7 +27,8 @@ struct machine_desc {
        unsigned int            nr;             /* architecture number  */
        unsigned int            phys_ram;       /* start of physical ram */
        unsigned int            phys_io;        /* start of physical io */
-       unsigned int            virt_io;        /* start of virtual io  */
+       unsigned int            io_pg_offst;    /* byte offset for io 
+                                                * page tabe entry      */
 
        const char              *name;          /* architecture name    */
        unsigned int            param_offset;   /* parameter page       */
@@ -59,9 +60,9 @@ const struct machine_desc __mach_desc_##_type \
 #define MAINTAINER(n)
 
 #define BOOT_MEM(_pram,_pio,_vio)              \
-       phys_ram:       _pram,                  \
-       phys_io:        _pio,                   \
-       virt_io:        _vio,
+       phys_ram:       _pram,                  \
+       phys_io:        _pio,                   \
+       io_pg_offst:    ((_vio)>>18)&0xfffc,
 
 #define BOOT_PARAMS(_params)                   \
        param_offset:   _params,
index e8d174722b2f926718cb3f98fdd73fb352025354..67af57ce2ec64052cf6e08815883910624baa85e 100644 (file)
@@ -16,6 +16,9 @@
 #ifndef HZ
 #define HZ 100
 #endif
+#if defined(__KERNEL__) && (HZ == 100)
+#define hz_to_std(a) (a)
+#endif
 
 #ifndef NGROUPS
 #define NGROUPS         32
index 2875af4685752ca3d6e85bdc33633f829fab8710..8689bba5212806f13ece734a5d2915890bc58c70 100644 (file)
@@ -44,7 +44,6 @@ pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
        consistent_free(vaddr, size, dma_handle);
 }
 
-#if !defined(CONFIG_SA1111)
 /* Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
  *
@@ -54,6 +53,17 @@ pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
 static inline dma_addr_t
 pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
+#ifdef CONFIG_SA1111
+       extern dma_addr_t sa1111_map_single(struct pci_dev *, void *, size_t, int);
+
+       /*
+        * for SA1111 these functions are "magic" and relocate buffers.  We
+        * only need to do these if hwdev is non-null; otherwise we expect
+        * the buffer to already be suitable for DMA.
+        */
+       if (hwdev != NULL)
+               return sa1111_map_single(hwdev, ptr, size, direction);
+#endif
        consistent_sync(ptr, size, direction);
        return virt_to_bus(ptr);
 }
@@ -68,16 +78,14 @@ pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 static inline void
 pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
 {
+#ifdef CONFIG_SA1111
+       extern void sa1111_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
+
+       if (hwdev != NULL)
+               sa1111_unmap_single(hwdev, dma_addr, size, direction);
+#endif
        /* nothing to do */
 }
-#else
-/* for SA1111 these functions are "magic" and relocate buffers */
-extern dma_addr_t pci_map_single(struct pci_dev *hwdev,
-                                void *ptr, size_t size, int direction);
-extern void pci_unmap_single(struct pci_dev *hwdev,
-                            dma_addr_t dma_addr,
-                            size_t size, int direction);
-#endif
 
 /* Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
index 12d7ae55a7b61dc50aa1f40fa886e4e82858d041..418f738bd958152b55a6889c71038b554e81f84f 100644 (file)
@@ -175,6 +175,8 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
 #include <asm-generic/pgtable.h>
 
+extern void pgtable_cache_init(void);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASMARM_PGTABLE_H */
index cd4a06d7c49f7a111ab982d2f7d517bcca852448..aa0148d9054f77fa54ec9192caac571f98c606f0 100644 (file)
@@ -68,6 +68,13 @@ struct thread_struct {
        EXTRA_THREAD_STRUCT
 };
 
+#define INIT_MMAP {                                    \
+       vm_mm:          &init_mm,                       \
+       vm_page_prot:   PAGE_SHARED,                    \
+       vm_flags:       VM_READ | VM_WRITE | VM_EXEC,   \
+       vm_avl_height:  1,                              \
+}
+
 #define INIT_THREAD  {                                 \
        refcount:       ATOMIC_INIT(1),                 \
        EXTRA_THREAD_STRUCT_INIT                        \
index 2e27fe9ca212d23dd1d56d5a1275c38edb130467..e0650ed3f8ab50a79a7484a8f9db1241a837b1e6 100644 (file)
@@ -126,7 +126,7 @@ struct tag_videotext {
 
 struct tag_ramdisk {
        u32 flags;      /* bit 0 = load, bit 1 = prompt */
-       u32 size;       /* decompressed ramdisk size */
+       u32 size;       /* decompressed ramdisk size in _kilo_ bytes */
        u32 start;      /* starting block of floppy-based RAM disk image */
 };
 
@@ -135,7 +135,7 @@ struct tag_ramdisk {
 
 struct tag_initrd {
        u32 start;      /* physical start address */
-       u32 size;       /* size of compressed ramdisk image */
+       u32 size;       /* size of compressed ramdisk image in bytes */
 };
 
 /* board serial number. "64 bits should be enough for everybody" */
index afca084cb8561b8d1c332c0910073b4858595580..1bc7f174eee280abbd653e0a114b9c68363aa26b 100644 (file)
@@ -75,13 +75,16 @@ typedef unsigned long sigset_t;
 /*
  * SA_FLAGS values:
  *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
- * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
+ * SA_NOCLDSTOP                flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT                flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO          deliver the signal with SIGINFO structs
+ * SA_THIRTYTWO                delivers the signal in 32-bit mode, even if the task 
+ *                     is running in 26-bit.
+ * SA_ONSTACK          allows alternate signal stacks (see sigaltstack(2)).
+ * SA_RESTART          flag to get restarting signals (which were the default long ago)
+ * SA_INTERRUPT                is a no-op, but left due to historical reasons. Use the
+ * SA_NODEFER          prevents the current signal from being masked in the handler.
+ * SA_RESETHAND                clears the handler when the signal is delivered.
  *
  * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
  * Unix names RESETHAND and NODEFER respectively.
@@ -89,6 +92,8 @@ typedef unsigned long sigset_t;
 #define SA_NOCLDSTOP   0x00000001
 #define SA_NOCLDWAIT   0x00000002 /* not supported yet */
 #define SA_SIGINFO     0x00000004
+#define SA_THIRTYTWO   0x02000000
+#define SA_RESTORER    0x04000000
 #define SA_ONSTACK     0x08000000
 #define SA_RESTART     0x10000000
 #define SA_NODEFER     0x40000000
@@ -98,9 +103,6 @@ typedef unsigned long sigset_t;
 #define SA_ONESHOT     SA_RESETHAND
 #define SA_INTERRUPT   0x20000000 /* dummy -- ignored */
 
-#define SA_RESTORER    0x04000000
-#define SA_THIRTYTWO   0x02000000 /* deliver signal in 32-bit mode even if
-                                     task is running 26 bits. */
 
 /* 
  * sigaltstack controls
index 1fac1a34f62adf285733001203df1e270f629000..98a9dfba2760b259487b0a83676e65c7a967c527 100644 (file)
@@ -63,11 +63,81 @@ static inline int verify_area(int type, const void * addr, unsigned long size)
  * error occurs, and leave it unchanged on success.  Note that these
  * versions are void (ie, don't return a value as such).
  */
-#define get_user(x,p)          __get_user_check((x),(p),sizeof(*(p)))
+
+extern int __get_user_1(void *);
+extern int __get_user_2(void *);
+extern int __get_user_4(void *);
+extern int __get_user_8(void *);
+extern int __get_user_bad(void);
+
+#define __get_user_x(__r1,__p,__e,__s,__i...)                          \
+          __asm__ __volatile__ ("bl    __get_user_" #__s               \
+               : "=&r" (__e), "=r" (__r1)                              \
+               : "0" (__p)                                             \
+               : __i)
+
+#define get_user(x,p)                                                  \
+       ({                                                              \
+               const register typeof(*(p)) *__p asm("r0") = (p);       \
+               register typeof(*(p)) __r1 asm("r1");                   \
+               register int __e asm("r0");                             \
+               switch (sizeof(*(p))) {                                 \
+               case 1:                                                 \
+                       __get_user_x(__r1, __p, __e, 1, "lr");          \
+                       break;                                          \
+               case 2:                                                 \
+                       __get_user_x(__r1, __p, __e, 2, "r2", "lr");    \
+                       break;                                          \
+               case 4:                                                 \
+                       __get_user_x(__r1, __p, __e, 4, "lr");          \
+                       break;                                          \
+               case 8:                                                 \
+                       __get_user_x(__r1, __p, __e, 8, "lr");          \
+                       break;                                          \
+               default: __e = __get_user_bad(); break;                 \
+               }                                                       \
+               x = __r1;                                               \
+               __e;                                                    \
+       })
+
 #define __get_user(x,p)                __get_user_nocheck((x),(p),sizeof(*(p)))
 #define __get_user_error(x,p,e)        __get_user_nocheck_error((x),(p),sizeof(*(p)),(e))
 
-#define put_user(x,p)          __put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p)))
+extern int __put_user_1(void *, unsigned int);
+extern int __put_user_2(void *, unsigned int);
+extern int __put_user_4(void *, unsigned int);
+extern int __put_user_8(void *, unsigned long long);
+extern int __put_user_bad(void);
+
+#define __put_user_x(__r1,__p,__e,__s,__i...)                          \
+          __asm__ __volatile__ ("bl    __put_user_" #__s               \
+               : "=&r" (__e)                                           \
+               : "0" (__p), "r" (__r1)                                 \
+               : __i)
+
+#define put_user(x,p)                                                  \
+       ({                                                              \
+               const register typeof(*(p)) *__p asm("r0") = (p);       \
+               const register typeof(*(p)) __r1 asm("r1") = (x);       \
+               register int __e asm("r0");                             \
+               switch (sizeof(*(p))) {                                 \
+               case 1:                                                 \
+                       __put_user_x(__r1, __p, __e, 1, "r2", "lr");    \
+                       break;                                          \
+               case 2:                                                 \
+                       __put_user_x(__r1, __p, __e, 2, "r2", "lr");    \
+                       break;                                          \
+               case 4:                                                 \
+                       __put_user_x(__r1, __p, __e, 4, "r2", "lr");    \
+                       break;                                          \
+               case 8:                                                 \
+                       __put_user_x(__r1, __p, __e, 8, "ip", "lr");    \
+                       break;                                          \
+               default: __e = __put_user_bad(); break;                 \
+               }                                                       \
+               __e;                                                    \
+       })
+
 #define __put_user(x,p)                __put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
 #define __put_user_error(x,p,e)        __put_user_nocheck_error((x),(p),sizeof(*(p)),(e))
 
@@ -142,6 +212,7 @@ static inline long strnlen_user(const char *s, long n)
 /*
  * These are the work horses of the get/put_user functions
  */
+#if 0
 #define __get_user_check(x,ptr,size)                                   \
 ({                                                                     \
        long __gu_err = -EFAULT, __gu_val = 0;                          \
@@ -153,6 +224,7 @@ static inline long strnlen_user(const char *s, long n)
        (x) = (__typeof__(*(ptr)))__gu_val;                             \
        __gu_err;                                                       \
 })
+#endif
 
 #define __get_user_nocheck(x,ptr,size)                                 \
 ({                                                                     \
@@ -195,8 +267,6 @@ static inline long strnlen_user(const char *s, long n)
        (void) 0;                                                       \
 })
 
-extern long __get_user_bad(void);
-
 #define __get_user_size(x,ptr,size,retval)                             \
 do {                                                                   \
        switch (size) {                                                 \
@@ -207,8 +277,6 @@ do {                                                                        \
        }                                                               \
 } while (0)
 
-extern long __put_user_bad(void);
-
 #define __put_user_size(x,ptr,size,retval)                             \
 do {                                                                   \
        switch (size) {                                                 \
index 932aa29c5f49822889f5c81c65348ea0eda5da33..481f324e36ddb527cc9730ccf03ec20708e8466c 100644 (file)
@@ -281,10 +281,19 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
  * I expect future Intel CPU's to have a weaker ordering,
  * but I'd also expect them to finally get their act together
  * and add some real memory barriers if so.
+ *
+ * Some non intel clones support out of order store. wmb() ceases to be a
+ * nop for these.
  */
 #define mb()   __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
 #define rmb()  mb()
+
+#ifdef CONFIG_X86_OOSTORE
+#define wmb()  __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#else
 #define wmb()  __asm__ __volatile__ ("": : :"memory")
+#endif
 
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
index 26dc6d6ebba9d3eea42a2847c06e40790f40bca2..a9d658f732c5ff12d4a18c167d8b9af8e3ece153 100644 (file)
@@ -139,6 +139,10 @@ chandev_msck_status prevstatus,chandev_msck_status newstatus);
  * not operational the previous status is sent in the prevstatus variable.
  * This can be used in cases when the default handling isn't quite adequete
  * e.g. if a ssch is needed to reinitialize long running channel programs.
+ *
+ * This returns the number of devices found or -ENOMEM if the code didn't
+ * have enough memory to allocate the chandev control block
+ * or -EPERM if a duplicate entry is found.
  */
 int chandev_register_and_probe(chandev_probefunc probefunc,
                               chandev_shutdownfunc shutdownfunc,
index fbc9f101febf432613e2df7cd27f40cc24e8bb6b..a9f548b67b9509ad4ca51ecc8633d4c2f7b9ebf0 100644 (file)
@@ -19,7 +19,7 @@ static inline struct task_struct * get_current(void)
 {
         struct task_struct *current;
         __asm__("lhi   %0,-8192\n\t"
-                "nr    %0,15"
+                "al    %0,0xc40"
                 : "=&r" (current) : : "cc" );
         return current;
  }
index f9ee1d530e482734c1692f5144d5478ce9938729..5627e8133bda24f8d7094be27c8f5922bb3a20ff 100644 (file)
@@ -36,6 +36,7 @@ typedef struct dasd_profile_info_t {
         unsigned int dasd_io_time2[32];         /* histogram of time from start to irq */
         unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */
         unsigned int dasd_io_time3[32];         /* histogram of time from irq to end */
+        unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
 } dasd_profile_info_t;
 
 /* 
index 9be9863c8160b9e54667ede15568016b9657b164..4c228a8dc4fdc256cd5316f8d1fa90971f8ffe8e 100644 (file)
@@ -44,6 +44,7 @@ struct __debug_entry{
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
 #define DEBUG_OFF_LEVEL            -1 /* level where debug is switched off */
+#define DEBUG_FLUSH_ALL            -1 /* parameter to flush all areas */
 #define DEBUG_MAX_VIEWS            10 /* max number of views in proc fs */
 #define DEBUG_MAX_PROCF_LEN        16 /* max length for a proc file name */
 #define DEBUG_DEFAULT_LEVEL        3  /* initial debug level */
index fa68800f4d47596a1963a77629999572e97f6e71..e97c80b76bba527682ab76be8c8c5d354ab33bca 100644 (file)
 #define __S390_GDB_STUB__
 #include <linux/config.h>
 #if CONFIG_REMOTE_DEBUG
-#include <asm/s390-gdbregs.h>
 #include <asm/ptrace.h>
 extern int    gdb_stub_initialised;
-extern void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval);
+extern void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval);
+struct net_device;
+struct net_device *gdb_dev;
+void gdb_do_timers(void);
+extern int putDebugChar(char c);    /* write a single character      */
+extern char getDebugChar(void);     /* read and return a single char */
 #endif
 #endif
index 4eec0a973b492c1d9fb629803337c54d5f5ea973..7a1507a97dbf7f528efd52a0d5f54d8ea1b48424 100644 (file)
@@ -41,7 +41,7 @@
 
 #define __LC_SAVE_AREA                  0xC00
 #define __LC_KERNEL_STACK               0xC40
-#define __LC_KERNEL_LEVEL               0xC44
+#define __LC_ASYNC_STACK                0xC44
 #define __LC_CPUID                      0xC60
 #define __LC_CPUADDR                    0xC68
 #define __LC_IPLDEV                     0xC7C
 #include <asm/atomic.h>
 #include <asm/sigp.h>
 
+void restart_int_handler(void);
+void ext_int_handler(void);
+void system_call(void);
+void pgm_check_handler(void);
+void mcck_int_handler(void);
+void io_int_handler(void);
 
 struct _lowcore
 {
@@ -107,7 +113,7 @@ struct _lowcore
        __u16        cpu_addr;                 /* 0x084 */
        __u16        ext_int_code;             /* 0x086 */
         __u16        svc_ilc;                  /* 0x088 */
-        __u16        scv_code;                 /* 0x08a */
+        __u16        svc_code;                 /* 0x08a */
         __u16        pgm_ilc;                  /* 0x08c */
         __u16        pgm_code;                 /* 0x08e */
        __u32        trans_exc_code;           /* 0x090 */
@@ -147,7 +153,7 @@ struct _lowcore
         /* System info area */
        __u32        save_area[16];            /* 0xc00 */
        __u32        kernel_stack;             /* 0xc40 */
-       __u32        kernel_level;             /* 0xc44 */
+       __u32        async_stack;              /* 0xc44 */
        /* entry.S sensitive area start */
        __u8         pad10[0xc60-0xc48];       /* 0xc5c */
        struct       cpuinfo_S390 cpu_data;    /* 0xc60 */
@@ -157,9 +163,7 @@ struct _lowcore
         /* SMP info area: defined by DJB */
         __u64        jiffy_timer_cc;           /* 0xc80 */
        atomic_t     ext_call_fast;            /* 0xc88 */
-       atomic_t     ext_call_queue;           /* 0xc8c */
-        atomic_t     ext_call_count;           /* 0xc90 */
-        __u8         pad11[0xe00-0xc94];       /* 0xc94 */
+        __u8         pad11[0xe00-0xc8c];       /* 0xc8c */
 
         /* 0xe00 is used as indicator for dump tools */
         /* whether the kernel died with panic() or not */
index 417a03c2882346418b4561914f94b9bd579cfd21..1f3a006759c741170db8ceae18cb3344d4c39d8e 100644 (file)
@@ -84,6 +84,8 @@ extern __inline__ void free_pgd_slow(pgd_t *pgd)
 #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
 #define pmd_free(x)                     do { } while (0)
+#define pmd_free_slow(x)               do { } while (0)
+#define pmd_free_fast(x)                do { } while (0)
 #define pgd_populate(mm, pmd, pte)      BUG()
 
 extern inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
index bf316297a0cad689da701d2bdd58c79f502e8c3e..eac4173c45319bb7cb0133154d1ae2d41e0bf0ba 100644 (file)
@@ -57,13 +57,6 @@ extern char empty_zero_page[PAGE_SIZE];
 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 #endif /* !__ASSEMBLY__ */
 
-/*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
 /*
  * PMD_SHIFT determines the size of the area a second-level page
  * table can map
@@ -162,6 +155,7 @@ extern char empty_zero_page[PAGE_SIZE];
 
 /* Bits in the page table entry */
 #define _PAGE_PRESENT   0x001          /* Software                         */
+#define _PAGE_MKCLEAR   0x002          /* Software                         */
 #define _PAGE_RO        0x200          /* HW read-only                     */
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
 
@@ -225,6 +219,25 @@ extern char empty_zero_page[PAGE_SIZE];
 #define __S110  PAGE_SHARED
 #define __S111  PAGE_SHARED
 
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+       if ((pte_val(pteval) & (_PAGE_MKCLEAR|_PAGE_INVALID))
+           == _PAGE_MKCLEAR) 
+       {
+               pte_val(pteval) &= ~_PAGE_MKCLEAR;
+               
+               asm volatile ("sske %0,%1" 
+                               : : "d" (0), "a" (pte_val(pteval)));
+       }
+
+       *pteptr = pteval;
+}
+
 /*
  * Permanent address of a page.
  */
@@ -323,23 +336,22 @@ extern inline pte_t pte_mkwrite(pte_t pte)
 
 extern inline pte_t pte_mkclean(pte_t pte)
 {
-       /* We can't clear the changed bit atomically. The iske/and/sske
-         * sequence has a race condition with the page referenced bit.
-         * At the moment pte_mkclean is always followed by a pte_mkold.
-         * So its safe to ignore the problem for now. Hope this will
-         * never change ... */
-       asm volatile ("sske %0,%1" 
-                     : : "d" (0), "a" (pte_val(pte)));
+       /* The only user of pte_mkclean is the fork() code.
+          We must *not* clear the *physical* page dirty bit
+          just because fork() wants to clear the dirty bit in
+          *one* of the page's mappings.  So we just do nothing. */
        return pte;
 }
 
 extern inline pte_t pte_mkdirty(pte_t pte)
 {
-       /* We can't set the changed bit atomically either. For now we
+       /* We can't set the changed bit atomically. For now we
          * set (!) the page referenced bit. */
        asm volatile ("sske %0,%1" 
                      : : "d" (_PAGE_CHANGED|_PAGE_REFERENCED),
                          "a" (pte_val(pte)));
+
+       pte_val(pte) &= ~_PAGE_MKCLEAR;
        return pte;
 }
 
@@ -411,7 +423,23 @@ extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
        pte_val(__pte) = physpage + pgprot_val(pgprot);
        return __pte;
 }
-#define mk_pte(page,pgprot) mk_pte_phys(__pa(((page)-mem_map)<<PAGE_SHIFT),pgprot)
+
+#define mk_pte(pg, pgprot)                                                \
+({                                                                        \
+       struct page *__page = (pg);                                       \
+       unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
+       pte_t __pte = mk_pte_phys(__physpage, (pgprot));                  \
+                                                                         \
+       if (__page != ZERO_PAGE(__physpage)) {                            \
+               int __users = page_count(__page);                         \
+               __users -= !!__page->buffers + !!__page->mapping;         \
+                                                                         \
+               if (__users == 1)                                         \
+                       pte_val(__pte) |= _PAGE_MKCLEAR;                  \
+        }                                                                 \
+                                                                         \
+       __pte;                                                            \
+})
 
 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
@@ -473,5 +501,10 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
 #define PageSkip(page)          (0)
 #define kern_addr_valid(addr)   (1)
 
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
 #endif /* _S390_PAGE_H */
 
index 68c37d338f6c7ae389866e4d5e6bccee1876356b..ac6129aa5a0af8fbe0e65bee29a3fea14e4eed5e 100644 (file)
@@ -191,6 +191,7 @@ struct gdb_pt_regs
        __u32 trap;
        __u32 crs[16];
        s390_fp_regs fp_regs;
+       __u32 old_ilc;
 };
 #endif
 
index d284922bc70b3da1649cf7ce6ef25c39d2f246c4..9a6022b50126f43cefc11a05aa3b1f84b01b92b2 100644 (file)
@@ -62,35 +62,10 @@ typedef enum
         ec_restart,
         ec_halt,
         ec_power_off,
-        ec_ptlb,
+       ec_call_function,
        ec_bit_last
 } ec_bit_sig;
 
-/* Signals which come with a parameter area, synchronous */
-typedef enum
-{
-        ec_callback_async,
-        ec_callback_sync
-} ec_cmd_sig;
-
-/* state information for synchronous signals */
-typedef enum
-{
-       ec_pending,
-       ec_executing,
-       ec_done
-} ec_state;
-
-/* header for the queuing of signals with a parameter area */
-typedef struct ec_ext_call
-{
-       ec_cmd_sig cmd;
-       atomic_t status;
-       struct ec_ext_call *next;
-        void (*func)(void *info);
-        void *info;
-} ec_ext_call;
-
 /*
  * Signal processor
  */
index 447681e367dd8fa72b2b1ba681456f0590a135b3..e3e74ae4a188eaae2b1a5869ad38f60a06973f18 100644 (file)
@@ -26,6 +26,8 @@ typedef struct
        __u16      cpu;
 } sigp_info;
 
+extern unsigned long cpu_online_map;
+
 #define NO_PROC_ID             0xFF            /* No processor magic marker */
 
 /*
@@ -64,12 +66,5 @@ extern __inline__ __u16 hard_smp_processor_id(void)
 
 void smp_local_timer_interrupt(struct pt_regs * regs);
 
-sigp_ccode smp_ext_call(int cpu, void (*cb)(void *info), void *info, int wait);
-void smp_ext_call_others(void (*cb)(void *info), void *info, int wait);
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig);
-void smp_ext_bitcall_others(ec_bit_sig sig);
-
-int smp_signal_others(sigp_order_code order_code,__u32 parameter,
-                      int spin,sigp_info *info);
 #endif
 #endif
index 6374feb28e07b83d67a3c42b963f3412bbc8ca76..b82aac30db215529eea3339b06d6368a4ad7a5e6 100644 (file)
 #include <asm/lowcore.h>
 
 #define __cpu_bh_enable(cpu) \
-               do { barrier(); local_bh_count(cpu)--; } while (0)
+                do { barrier(); local_bh_count(cpu)--; } while (0)
 #define cpu_bh_disable(cpu) \
-               do { local_bh_count(cpu)++; barrier(); } while (0)
+                do { local_bh_count(cpu)++; barrier(); } while (0)
 
 #define local_bh_disable()      cpu_bh_disable(smp_processor_id())
 #define __local_bh_enable()     __cpu_bh_enable(smp_processor_id())
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
+extern void do_call_softirq(void);
+
 #define local_bh_enable()                                              \
 do {                                                                   \
-       unsigned int *ptr = &local_bh_count(smp_processor_id());        \
-       barrier();                                                      \
-       if (!--*ptr)                                                    \
+        unsigned int *ptr = &local_bh_count(smp_processor_id());        \
+        barrier();                                                      \
+        if (!--*ptr)                                                   \
                if (softirq_pending(smp_processor_id()))                \
-                       do_softirq();                                   \
+                       /* Use the async. stack for softirq */          \
+                       do_call_softirq();                              \
 } while (0)
 
 #endif /* __ASM_SOFTIRQ_H */
index adf251e795a7920ead57c3a342338b7b5043c1f1..48bd752be6baf13badf5cd6725d46170575a7e6c 100644 (file)
@@ -32,20 +32,19 @@ extern inline void spin_lock(spinlock_t *lp)
         __asm__ __volatile("    bras  1,1f\n"
                            "0:  diag  0,0,68\n"
                            "1:  slr   0,0\n"
-                           "    cs    0,1,%1\n"
+                           "    cs    0,1,0(%0)\n"
                            "    jl    0b\n"
-                           : "=m" (lp->lock)
-                           : "0" (lp->lock) : "0", "1", "cc" );
+                           : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
 }
 
 extern inline int spin_trylock(spinlock_t *lp)
 {
        unsigned long result;
-       __asm__ __volatile("    slr   %1,%1\n"
+       __asm__ __volatile("    slr   %0,%0\n"
                           "    basr  1,0\n"
-                          "0:  cs    %1,1,%0"
-                          : "=m" (lp->lock), "=&d" (result)
-                          : "0" (lp->lock) : "1", "cc" );
+                          "0:  cs    %0,1,0(%1)"
+                          : "=&d" (result)
+                          : "a" (&lp->lock) : "1", "cc", "memory" );
        return !result;
 }
 
@@ -53,7 +52,7 @@ extern inline void spin_unlock(spinlock_t *lp)
 {
        __asm__ __volatile("    xc 0(4,%0),0(%0)\n"
                            "    bcr 15,0"
-                          : /* no output */ : "a" (lp) : "memory", "cc" );
+                          : : "a" (&lp->lock) : "memory", "cc" );
 }
                
 /*
@@ -76,24 +75,24 @@ typedef struct {
 #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
 #define read_lock(rw)   \
-        asm volatile("   l     2,%0\n"   \
+        asm volatile("   l     2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: diag  0,0,68\n" \
-                     "1: la    2,0(2)\n"  /* clear high (=write) bit */ \
-                     "   la    3,1(2)\n"  /* one more reader */ \
-                     "   cs    2,3,%0\n"  /* try to write new value */ \
+                     "1: la    2,0(2)\n"     /* clear high (=write) bit */ \
+                     "   la    3,1(2)\n"     /* one more reader */ \
+                     "   cs    2,3,0(%0)\n"  /* try to write new value */ \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define read_unlock(rw) \
-        asm volatile("   l     2,%0\n"   \
+        asm volatile("   l     2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: diag  0,0,68\n" \
                      "1: lr    3,2\n"    \
                      "   ahi   3,-1\n"    /* one less reader */ \
-                     "   cs    2,3,%0\n" \
+                     "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_lock(rw) \
         asm volatile("   lhi   3,1\n"    \
@@ -101,9 +100,9 @@ typedef struct {
                      "   j     1f\n"     \
                      "0: diag  0,0,68\n" \
                      "1: slr   2,2\n"     /* old lock value must be 0 */ \
-                     "   cs    2,3,%0\n" \
+                     "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_unlock(rw) \
         asm volatile("   slr   3,3\n"     /* new lock value = 0 */ \
@@ -111,8 +110,8 @@ typedef struct {
                      "0: diag  0,0,68\n" \
                      "1: lhi   2,1\n"    \
                      "   sll   2,31\n"    /* old lock value must be 0x80000000 */ \
-                     "   cs    2,3,%0\n" \
+                     "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #endif /* __ASM_SPINLOCK_H */
index d8bf6be498f29f0571fb3ae317e9eb30ed7df9a9..ae5390d7f1d065accbf727f526dfa8a8df357aa3 100644 (file)
@@ -78,6 +78,35 @@ extern unsigned long search_exception_table(unsigned long);
  * use the right size if we just have the right pointer type.
  */
 
+extern inline int __put_user_asm_8(__u64 x, void *ptr)
+{
+        int err;
+
+        __asm__ __volatile__ (  "   sr    %1,%1\n"
+                               "   la    2,%2\n"
+                               "   la    4,%0\n"
+                                "   sacf  512\n"
+                                "0: mvc   0(8,4),0(2)\n"
+                                "   sacf  0\n"
+                               "1:\n"
+                               ".section .fixup,\"ax\"\n"
+                               "2: sacf  0\n"
+                               "   lhi   %1,%h3\n"
+                               "   bras  4,3f\n"
+                               "   .long 1b\n"
+                               "3: l     4,0(4)\n"
+                               "   br    4\n"
+                               ".previous\n"
+                               ".section __ex_table,\"a\"\n"
+                               "   .align 4\n"
+                               "   .long  0b,2b\n"
+                               ".previous"
+                                : "=m" (*((__u32*) ptr)), "=&d" (err)
+                                : "m" (x), "K" (-EFAULT)
+                                : "cc", "2", "4" );
+        return err;
+}
+
 extern inline int __put_user_asm_4(__u32 x, void *ptr)
 {
         int err;
@@ -179,6 +208,9 @@ extern inline int __put_user_asm_1(__u8 x, void *ptr)
                 case 4:                                         \
                         __pu_err = __put_user_asm_4((__u32) x,(ptr));\
                         break;                                  \
+               case 8:                                         \
+                       __pu_err = __put_user_asm_8((__u64) x,(ptr));\
+                       break;                                  \
                 default:                                        \
                 __pu_err = __put_user_bad();                    \
                 break;                                          \
@@ -200,6 +232,31 @@ extern inline int __put_user_asm_1(__u8 x, void *ptr)
 
 extern int __put_user_bad(void);
 
+#define __get_user_asm_8(x, ptr, err)                                      \
+({                                                                         \
+        __asm__ __volatile__ (  "   sr    %1,%1\n"                         \
+                               "   la    2,%0\n"                          \
+                                "   la    4,%2\n"                          \
+                                "   sacf  512\n"                           \
+                                "0: mvc   0(8,2),0(4)\n"                   \
+                                "   sacf  0\n"                             \
+                                "1:\n"                                     \
+                                ".section .fixup,\"ax\"\n"                 \
+                                "2: sacf  0\n"                             \
+                                "   lhi   %1,%h3\n"                        \
+                                "   bras  4,3f\n"                          \
+                                "   .long 1b\n"                            \
+                                "3: l     4,0(4)\n"                        \
+                                "   br    4\n"                             \
+                                ".previous\n"                              \
+                                ".section __ex_table,\"a\"\n"              \
+                                "   .align 4\n"                            \
+                                "   .long 0b,2b\n"                         \
+                                ".previous"                                \
+                                : "=m" (x) , "=&d" (err)                   \
+                                : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) \
+                                : "cc", "2", "4" );                        \
+})
 
 #define __get_user_asm_4(x, ptr, err)                                      \
 ({                                                                         \
@@ -290,6 +347,9 @@ extern int __put_user_bad(void);
                 case 4:                                         \
                         __get_user_asm_4(x,ptr,__gu_err);       \
                         break;                                  \
+                case 8:                                         \
+                        __get_user_asm_8(x,ptr,__gu_err);       \
+                        break;                                  \
                 default:                                        \
                         (x) = 0;                                \
                         __gu_err = __get_user_bad();            \
@@ -372,7 +432,7 @@ __copy_from_user_asm(void* to, const void* from,  long n)
                                 "0: mvcle 2,4,0\n"
                                 "   jo    0b\n"
                                 "   sacf  0\n"
-                                "   lr    %0,3\n"
+                                "   lr    %0,5\n"
                                ".section __ex_table,\"a\"\n"
                                "   .align 4\n"
                                "   .long  0b,__copy_from_user_fixup\n"
index d4e39ae77de98c8830d4c10ad800605de76e6b1c..d69bec0b03f58e830cc1eecbe3476173be22d39d 100644 (file)
@@ -13,10 +13,8 @@ struct ucontext {
        unsigned long     uc_flags;
        struct ucontext  *uc_link;
        stack_t           uc_stack;
+       _sigregs          uc_mcontext;
        sigset_t          uc_sigmask;   /* mask last for extensibility */
-       struct sigcontext *sc; /* Added for pthread support */
 };
 
-
-
 #endif /* !_ASM_S390_UCONTEXT_H */
index b223e049063eb7e9451282ea87849349ae1c2415..2c5a01426b1f1ceb72af528a61e0f99ffc7747a5 100644 (file)
 #define __NR_capset             185
 #define __NR_sigaltstack        186
 #define __NR_sendfile           187
+#define __NR_getpmsg           188
+#define __NR_putpmsg           189
 #define __NR_vfork             190
 #define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
 #define __NR_mmap2             192
index 4a7927896ed566cb77e3a02ab0a6543b7498d12f..f3310604374edc1322ca2283531199e9e83deb92 100644 (file)
 
 #define VTOC_ERROR "VTOC error:"
 
-enum failure {unable_to_open,
-             unable_to_seek,
-             unable_to_write,
-             unable_to_read};
-
-unsigned char ASCtoEBC[256] =
-{
-  /*00  NL    SH    SX    EX    ET    NQ    AK    BL */
-  0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
-  /*08  BS    HT    LF    VT    FF    CR    SO    SI */
-  0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-  /*10  DL    D1    D2    D3    D4    NK    SN    EB */
-  0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
-  /*18  CN    EM    SB    EC    FS    GS    RS    US */
-  0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
-  /*20  SP     !     "     #     $     %     &     ' */
-  0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
-  /*28   (     )     *     +     ,     -    .      / */
-  0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
-  /*30   0     1     2     3     4     5     6     7 */
-  0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
-  /*38   8     9     :     ;     <     =     >     ? */
-  0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
-  /*40   @     A     B     C     D     E     F     G */
-  0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
-  /*48   H     I     J     K     L     M     N     O */
-  0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
-  /*50   P     Q     R     S     T     U     V     W */
-  0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
-  /*58   X     Y     Z     [     \     ]     ^     _ */
-  0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
-  /*60   `     a     b     c     d     e     f     g */
-  0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-  /*68   h     i     j     k     l     m     n     o */
-  0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
-  /*70   p     q     r     s     t     u     v     w */
-  0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
-  /*78   x     y     z     {     |     }     ~    DL */
-  0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-
-unsigned char EBCtoASC[256] =
-{
- /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
-          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
-          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
-                                  -ENP  ->LF             */
-          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
-                                                    -IUS */
-          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
-                                  -INP                   */
-          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                       -SW                               */ 
-          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
-          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
-          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40    SP   RSP           Ã¤              ----       */
-          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48                       .     <     (     +     | */
-          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50     &                                      ---- */
-          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58           ÃŸ     !     $     *     )     ;       */
-          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60     -     /  ----     Ã„  ----  ----  ----       */
-          0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68              ----     ,     %     _     >     ? */ 
-          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
-          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78     *     `     :     #     @     '     =     " */
-          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80     *     a     b     c     d     e     f     g */
-          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88     h     i              ----  ----  ----       */
-          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90     Â°     j     k     l     m     n     o     p */
-          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98     q     r                    ----        ---- */
-          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0           ~     s     t     u     v     w     x */
-          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8     y     z              ----  ----  ----  ---- */
-          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0     ^                    ----     Â§  ----       */
-          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
-          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0     {     A     B     C     D     E     F     G */
-          0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8     H     I  ----           Ã¶              ---- */
-          0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0     }     J     K     L     M     N     O     P */
-          0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8     Q     R  ----           Ã¼                   */
-          0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0     \           S     T     U     V     W     X */
-          0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8     Y     Z        ----     Ã–  ----  ----  ---- */
-          0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0     0     1     2     3     4     5     6     7 */
-          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8     8     9  ----  ----     Ãœ  ----  ----  ---- */
-          0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
 
 typedef struct ttr 
 {
index 26dc6d6ebba9d3eea42a2847c06e40790f40bca2..a9d658f732c5ff12d4a18c167d8b9af8e3ece153 100644 (file)
@@ -139,6 +139,10 @@ chandev_msck_status prevstatus,chandev_msck_status newstatus);
  * not operational the previous status is sent in the prevstatus variable.
  * This can be used in cases when the default handling isn't quite adequete
  * e.g. if a ssch is needed to reinitialize long running channel programs.
+ *
+ * This returns the number of devices found or -ENOMEM if the code didn't
+ * have enough memory to allocate the chandev control block
+ * or -EPERM if a duplicate entry is found.
  */
 int chandev_register_and_probe(chandev_probefunc probefunc,
                               chandev_shutdownfunc shutdownfunc,
index e7307c4f0f31db1318b9afb3f4b5252ea25468a8..ad6a6fe50ae29052b8ad41336ee1687e33cef3a5 100644 (file)
@@ -19,7 +19,7 @@ static inline struct task_struct * get_current(void)
 {
         struct task_struct *current;
         __asm__("lghi  %0,-16384\n\t"
-                "ngr   %0,15"
+                "alg   %0,0xd40"
                 : "=&r" (current) : : "cc" );
         return current;
  }
index f9ee1d530e482734c1692f5144d5478ce9938729..5627e8133bda24f8d7094be27c8f5922bb3a20ff 100644 (file)
@@ -36,6 +36,7 @@ typedef struct dasd_profile_info_t {
         unsigned int dasd_io_time2[32];         /* histogram of time from start to irq */
         unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */
         unsigned int dasd_io_time3[32];         /* histogram of time from irq to end */
+        unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
 } dasd_profile_info_t;
 
 /* 
index 9be9863c8160b9e54667ede15568016b9657b164..4c228a8dc4fdc256cd5316f8d1fa90971f8ffe8e 100644 (file)
@@ -44,6 +44,7 @@ struct __debug_entry{
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
 #define DEBUG_OFF_LEVEL            -1 /* level where debug is switched off */
+#define DEBUG_FLUSH_ALL            -1 /* parameter to flush all areas */
 #define DEBUG_MAX_VIEWS            10 /* max number of views in proc fs */
 #define DEBUG_MAX_PROCF_LEN        16 /* max length for a proc file name */
 #define DEBUG_DEFAULT_LEVEL        3  /* initial debug level */
index 1594560ae6abc9300a5621e7a6491c8916331eb8..443b28e68b83e65ceb88920640515aadaaa4ced8 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  *  include/asm-s390/lowcore.h
  *
@@ -39,7 +40,7 @@
 
 #define __LC_SAVE_AREA                  0xC00
 #define __LC_KERNEL_STACK               0xD40
-#define __LC_KERNEL_LEVEL               0xD48
+#define __LC_ASYNC_STACK                0xD48
 #define __LC_CPUID                      0xD90
 #define __LC_CPUADDR                    0xD98
 #define __LC_IPLDEV                     0xDB8
 #include <asm/atomic.h>
 #include <asm/sigp.h>
 
+void restart_int_handler(void);
+void ext_int_handler(void);
+void system_call(void);
+void pgm_check_handler(void);
+void mcck_int_handler(void);
+void io_int_handler(void);
 
 struct _lowcore
 {
@@ -96,7 +103,7 @@ struct _lowcore
        __u16        cpu_addr;                 /* 0x084 */
        __u16        ext_int_code;             /* 0x086 */
         __u16        svc_ilc;                  /* 0x088 */
-        __u16        scv_code;                 /* 0x08a */
+        __u16        svc_code;                 /* 0x08a */
         __u16        pgm_ilc;                  /* 0x08c */
         __u16        pgm_code;                 /* 0x08e */
        __u32        data_exc_code;            /* 0x090 */
@@ -142,7 +149,7 @@ struct _lowcore
        __u64        save_area[16];            /* 0xc00 */
         __u8         pad9[0xd40-0xc80];        /* 0xc80 */
        __u64        kernel_stack;             /* 0xd40 */
-       __u64        kernel_level;             /* 0xd48 */
+       __u64        async_stack;              /* 0xd48 */
        /* entry.S sensitive area start */
        __u8         pad10[0xd80-0xd50];       /* 0xd64 */
        struct       cpuinfo_S390 cpu_data;    /* 0xd80 */
@@ -153,10 +160,7 @@ struct _lowcore
         /* SMP info area: defined by DJB */
         __u64        jiffy_timer_cc;           /* 0xdc0 */
        __u64        ext_call_fast;            /* 0xdc8 */
-       __u64        ext_call_queue;           /* 0xdd0 */
-        __u64        ext_call_count;           /* 0xdd8 */
-
-        __u8         pad12[0xe00-0xde0];       /* 0xde0 */
+        __u8         pad12[0xe00-0xdd0];       /* 0xdd0 */
 
         /* 0xe00 is used as indicator for dump tools */
         /* whether the kernel died with panic() or not */
diff --git a/include/asm-s390x/mathemu.h b/include/asm-s390x/mathemu.h
deleted file mode 100644 (file)
index c78d97b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  arch/s390/kernel/mathemu.h
- *    IEEE floating point emulation.
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
- */
-
-#ifndef __MATHEMU__
-#define __MATHEMU__
-
-extern int math_emu_b3(__u8 *, struct pt_regs *);
-extern int math_emu_ed(__u8 *, struct pt_regs *);
-extern void math_emu_ldr(__u8 *);
-extern void math_emu_ler(__u8 *);
-extern void math_emu_std(__u8 *, struct pt_regs *);
-extern void math_emu_ld(__u8 *, struct pt_regs *);
-extern void math_emu_ste(__u8 *, struct pt_regs *);
-extern void math_emu_le(__u8 *, struct pt_regs *);
-extern int math_emu_lfpc(__u8 *, struct pt_regs *);
-extern int math_emu_stfpc(__u8 *, struct pt_regs *);
-extern int math_emu_srnm(__u8 *, struct pt_regs *);
-
-
-extern __u64 __adddf3(__u64,__u64);
-extern __u64 __subdf3(__u64,__u64);
-extern __u64 __muldf3(__u64,__u64);
-extern __u64 __divdf3(__u64,__u64);
-extern long  __cmpdf2(__u64,__u64);
-extern __u64 __negdf2(__u64);
-extern __u64 __absdf2(__u64);
-extern __u32 __addsf3(__u32,__u32);
-extern __u32 __subsf3(__u32,__u32);
-extern __u32 __mulsf3(__u32,__u32);
-extern __u32 __divsf3(__u32,__u32);
-extern __u32 __negsf2(__u32);
-extern __u32 __abssf2(__u32);
-extern long  __cmpsf2(__u32,__u32);
-extern __u32 __truncdfsf2(__u64);
-extern __u32 __fixsfsi(__u32);
-extern __u32 __fixdfsi(__u64);
-extern __u64  __floatsidf(__u32);
-extern __u32  __floatsisf(__u32);
-extern __u64  __extendsfdf2(__u32);
-
-#endif                                 /* __MATHEMU__                      */
-
index afad87da7b1fdec0da7349f0cd0dd2b1e17e9609..6f8b67118cb4abcba4f871e48a52b74ac4ac1956 100644 (file)
@@ -110,11 +110,6 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
-/*
- *
- *
- */
-
 #define __PAGE_OFFSET           0x0UL
 #define PAGE_OFFSET             0x0UL
 #define __pa(x)                 (unsigned long)(x)
index fc5aec78c2a2b4a4bb2cd46e637758685ad1099c..f2e0cc0a4dccd52dcab3b478b8fa289c1c8baa39 100644 (file)
@@ -11,6 +11,9 @@
 
 #ifndef HZ
 #define HZ 100
+#ifdef __KERNEL__
+#define hz_to_std(a) (a)
+#endif
 #endif
 
 #define EXEC_PAGESIZE  4096
index 21937e571f5b6b89e8c81fa591699098e51836b7..1bc4b2f36e3d6ad376408d5a0ca10e3cf55d0b2d 100644 (file)
@@ -53,13 +53,6 @@ extern char empty_zero_page[PAGE_SIZE];
 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 #endif /* !__ASSEMBLY__ */
 
-/*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
 /*
  * PMD_SHIFT determines the size of the area a second-level page
  * table can map
@@ -164,6 +157,7 @@ extern char empty_zero_page[PAGE_SIZE];
 
 /* Bits in the page table entry */
 #define _PAGE_PRESENT   0x001          /* Software                         */
+#define _PAGE_MKCLEAR   0x002          /* Software                         */
 #define _PAGE_RO        0x200          /* HW read-only                     */
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
 
@@ -180,7 +174,8 @@ extern char empty_zero_page[PAGE_SIZE];
  */
 #define _REGION_THIRD       0x4
 #define _REGION_THIRD_LEN   0x3 
-#define _REGION_TABLE       (_REGION_THIRD|_REGION_THIRD_LEN|0x40)
+#define _REGION_TABLE       (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
+#define _KERN_REGION_TABLE  (_REGION_THIRD|_REGION_THIRD_LEN)
 
 /* Bits in the storage key */
 #define _PAGE_CHANGED    0x02          /* HW changed bit                   */
@@ -219,6 +214,25 @@ extern char empty_zero_page[PAGE_SIZE];
 #define __S110  PAGE_SHARED
 #define __S111  PAGE_SHARED
 
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+       if ((pte_val(pteval) & (_PAGE_MKCLEAR|_PAGE_INVALID))
+           == _PAGE_MKCLEAR) 
+       {
+               pte_val(pteval) &= ~_PAGE_MKCLEAR;
+               
+               asm volatile ("sske %0,%1" 
+                               : : "d" (0), "a" (pte_val(pteval)));
+       }
+
+       *pteptr = pteval;
+}
+
 /*
  * Permanent address of a page.
  */
@@ -341,13 +355,10 @@ extern inline pte_t pte_mkwrite(pte_t pte)
 
 extern inline pte_t pte_mkclean(pte_t pte)
 {
-       /* We can't clear the changed bit atomically. The iske/and/sske
-         * sequence has a race condition with the page referenced bit.
-         * At the moment pte_mkclean is always followed by a pte_mkold.
-         * So its safe to ignore the problem for now. Hope this will
-         * never change ... */
-       asm volatile ("sske %0,%1" 
-                     : : "d" (0), "a" (pte_val(pte)));
+       /* The only user of pte_mkclean is the fork() code.
+          We must *not* clear the *physical* page dirty bit
+          just because fork() wants to clear the dirty bit in
+          *one* of the page's mappings.  So we just do nothing. */
        return pte;
 }
 
@@ -358,6 +369,8 @@ extern inline pte_t pte_mkdirty(pte_t pte)
        asm volatile ("sske %0,%1" 
                      : : "d" (_PAGE_CHANGED|_PAGE_REFERENCED),
                          "a" (pte_val(pte)));
+
+       pte_val(pte) &= ~_PAGE_MKCLEAR;
        return pte;
 }
 
@@ -429,7 +442,23 @@ extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
        pte_val(__pte) = physpage + pgprot_val(pgprot);
        return __pte;
 }
-#define mk_pte(page,pgprot) mk_pte_phys(__pa(((page)-mem_map)<<PAGE_SHIFT),pgprot)
+
+#define mk_pte(pg, pgprot)                                                \
+({                                                                        \
+       struct page *__page = (pg);                                       \
+       unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
+       pte_t __pte = mk_pte_phys(__physpage, (pgprot));                  \
+                                                                         \
+       if (__page != ZERO_PAGE(__physpage)) {                            \
+               int __users = page_count(__page);                         \
+               __users -= !!__page->buffers + !!__page->mapping;         \
+                                                                         \
+               if (__users == 1)                                         \
+                       pte_val(__pte) |= _PAGE_MKCLEAR;                  \
+        }                                                                 \
+                                                                         \
+       __pte;                                                            \
+})
 
 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
@@ -492,5 +521,10 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
 #define PageSkip(page)          (0)
 #define kern_addr_valid(addr)   (1)
 
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
 #endif /* _S390_PAGE_H */
 
index d6a12e84d28edddc876eb819dfed9133c7bf3942..a53b5fee864daaeee0ade6d2c0733e477440b383 100644 (file)
@@ -62,33 +62,10 @@ typedef enum
         ec_restart,
         ec_halt,
         ec_power_off,
+       ec_call_function,
        ec_bit_last
 } ec_bit_sig;
 
-/* Signals which come with a parameter area */
-typedef enum
-{
-        ec_callback_sync,
-        ec_callback_async
-} ec_cmd_sig;
-
-/* state information for signals */
-typedef enum
-{
-       ec_pending,
-       ec_executing,
-       ec_done
-} ec_state;
-
-/* header for the queuing of callbacks */
-typedef struct ec_ext_call
-{
-       ec_cmd_sig cmd;
-       atomic_t status;
-       struct ec_ext_call *next;
-       void (*func)(void *info);
-       void *info;
-} ec_ext_call;
 
 /*
  * Signal processor
index 447681e367dd8fa72b2b1ba681456f0590a135b3..e3e74ae4a188eaae2b1a5869ad38f60a06973f18 100644 (file)
@@ -26,6 +26,8 @@ typedef struct
        __u16      cpu;
 } sigp_info;
 
+extern unsigned long cpu_online_map;
+
 #define NO_PROC_ID             0xFF            /* No processor magic marker */
 
 /*
@@ -64,12 +66,5 @@ extern __inline__ __u16 hard_smp_processor_id(void)
 
 void smp_local_timer_interrupt(struct pt_regs * regs);
 
-sigp_ccode smp_ext_call(int cpu, void (*cb)(void *info), void *info, int wait);
-void smp_ext_call_others(void (*cb)(void *info), void *info, int wait);
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig);
-void smp_ext_bitcall_others(ec_bit_sig sig);
-
-int smp_signal_others(sigp_order_code order_code,__u32 parameter,
-                      int spin,sigp_info *info);
 #endif
 #endif
index 6374feb28e07b83d67a3c42b963f3412bbc8ca76..b82aac30db215529eea3339b06d6368a4ad7a5e6 100644 (file)
 #include <asm/lowcore.h>
 
 #define __cpu_bh_enable(cpu) \
-               do { barrier(); local_bh_count(cpu)--; } while (0)
+                do { barrier(); local_bh_count(cpu)--; } while (0)
 #define cpu_bh_disable(cpu) \
-               do { local_bh_count(cpu)++; barrier(); } while (0)
+                do { local_bh_count(cpu)++; barrier(); } while (0)
 
 #define local_bh_disable()      cpu_bh_disable(smp_processor_id())
 #define __local_bh_enable()     __cpu_bh_enable(smp_processor_id())
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
+extern void do_call_softirq(void);
+
 #define local_bh_enable()                                              \
 do {                                                                   \
-       unsigned int *ptr = &local_bh_count(smp_processor_id());        \
-       barrier();                                                      \
-       if (!--*ptr)                                                    \
+        unsigned int *ptr = &local_bh_count(smp_processor_id());        \
+        barrier();                                                      \
+        if (!--*ptr)                                                   \
                if (softirq_pending(smp_processor_id()))                \
-                       do_softirq();                                   \
+                       /* Use the async. stack for softirq */          \
+                       do_call_softirq();                              \
 } while (0)
 
 #endif /* __ASM_SOFTIRQ_H */
index da46da82ec7bc75f50bee38cc358bf78e6ae945b..b0dc918b395c4cd3404eecf712c24e2aafc6cf54 100644 (file)
@@ -32,20 +32,19 @@ extern inline void spin_lock(spinlock_t *lp)
         __asm__ __volatile("    bras  1,1f\n"
                            "0:  # diag  0,0,68\n"
                            "1:  slr   0,0\n"
-                           "    cs    0,1,%1\n"
+                           "    cs    0,1,0(%0)\n"
                            "    jl    0b\n"
-                           : "=m" (lp->lock)
-                           : "0" (lp->lock) : "0", "1", "cc" );
+                           : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
 }
 
 extern inline int spin_trylock(spinlock_t *lp)
 {
        unsigned int result;
-       __asm__ __volatile("    slr   %1,%1\n"
+       __asm__ __volatile("    slr   %0,%0\n"
                           "    basr  1,0\n"
-                          "0:  cs    %1,1,%0"
-                          : "=m" (lp->lock), "=&d" (result)
-                          : "0" (lp->lock) : "1", "cc" );
+                          "0:  cs    %0,1,0(%1)"
+                          : "=&d" (result)
+                          : "a" (&lp->lock) : "1", "cc", "memory" );
        return !result;
 }
 
@@ -53,7 +52,7 @@ extern inline void spin_unlock(spinlock_t *lp)
 {
        __asm__ __volatile("    xc 0(4,%0),0(%0)\n"
                            "    bcr 15,0"
-                          : /* no output */ : "a" (lp) : "memory", "cc" );
+                          : : "a" (&lp->lock) : "memory", "cc" );
 }
                
 /*
@@ -76,46 +75,42 @@ typedef struct {
 #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
 #define read_lock(rw)   \
-        asm volatile("   la    1,%0\n"   \
-                     "   lg    2,0(1)\n"   \
+        asm volatile("   lg    2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: # diag  0,0,68\n" \
                      "1: nihh  2,0x7fff\n" /* clear high (=write) bit */ \
                      "   la    3,1(2)\n"   /* one more reader */  \
-                     "   csg   2,3,0(1)\n" /* try to write new value */ \
+                     "   csg   2,3,0(%0)\n" /* try to write new value */ \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define read_unlock(rw) \
-        asm volatile("   la    1,%0\n"   \
-                     "   lg    2,0(1)\n"   \
+        asm volatile("   lg    2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: # diag  0,0,68\n" \
                      "1: lgr   3,2\n"    \
                      "   bctgr 3,0\n"    /* one less reader */ \
-                     "   csg   2,3,0(1)\n" \
+                     "   csg   2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_lock(rw) \
-        asm volatile("   la    1,%0\n"     \
-                     "   llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
+        asm volatile("   llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
                      "   j     1f\n"       \
                      "0: # diag  0,0,68\n"   \
                      "1: slgr  2,2\n"      /* old lock value must be 0 */ \
-                     "   csg   2,3,0(1)\n" \
+                     "   csg   2,3,0(%0)\n" \
                      "   jl    0b"         \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_unlock(rw) \
-        asm volatile("   la    1,%0\n"     \
-                     "   slgr  3,3\n"      /* new lock value = 0 */ \
+        asm volatile("   slgr  3,3\n"      /* new lock value = 0 */ \
                      "   j     1f\n"       \
                      "0: # diag  0,0,68\n"   \
                      "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\
-                     "   csg   2,3,0(1)\n"   \
+                     "   csg   2,3,0(%0)\n"   \
                      "   jl    0b"         \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #endif /* __ASM_SPINLOCK_H */
 
index d4e39ae77de98c8830d4c10ad800605de76e6b1c..d69bec0b03f58e830cc1eecbe3476173be22d39d 100644 (file)
@@ -13,10 +13,8 @@ struct ucontext {
        unsigned long     uc_flags;
        struct ucontext  *uc_link;
        stack_t           uc_stack;
+       _sigregs          uc_mcontext;
        sigset_t          uc_sigmask;   /* mask last for extensibility */
-       struct sigcontext *sc; /* Added for pthread support */
 };
 
-
-
 #endif /* !_ASM_S390_UCONTEXT_H */
index 34b72ab5b1a32b12751d38b88e4897b0b8046bef..eeec47819b0b34e95158b6381eecd083c1debe82 100644 (file)
 #define __NR_capset             185
 #define __NR_sigaltstack        186
 #define __NR_sendfile           187
+#define __NR_getpmsg           188
+#define __NR_putpmsg           189
 #define __NR_vfork             190
 #define __NR_getrlimit         191     /* SuS compliant getrlimit */
 #define __NR_lchown            198
@@ -199,7 +201,7 @@ type name(void) {                                            \
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name)                          \
                 : _svc_clobber );                            \
@@ -212,7 +214,7 @@ type name(type1 arg1) {                                      \
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1)                               \
@@ -227,7 +229,7 @@ type name(type1 arg1, type2 arg2) {                          \
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
@@ -244,7 +246,7 @@ type name(type1 arg1, type2 arg2, type3 arg3) {              \
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
@@ -264,7 +266,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {  \
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
@@ -287,7 +289,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
index cf40d7e6b7a1e674376773a7f1e9d15887cb76ef..24ec4670a0332ae83dbee89366864d4ec79af78f 100644 (file)
@@ -1,10 +1,12 @@
-/*
- * $Id: b1lli.h,v 1.8.8.2 2001/05/17 20:41:52 kai Exp $
+/* $Id: b1lli.h,v 1.8.8.3 2001/09/23 22:25:05 kai Exp $
  *
  * ISDN lowlevel-module for AVM B1-card.
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #ifndef _B1LLI_H_
index b73e4ddbeaa001f79b782547cffd7029124cfc5d..12a867c6061e70fa2edccb9165db1afadc002066 100644 (file)
@@ -1,11 +1,13 @@
-/*
- * $Id: b1pcmcia.h,v 1.1.8.1 2001/05/17 20:41:52 kai Exp $
+/* $Id: b1pcmcia.h,v 1.1.8.2 2001/09/23 22:25:05 kai Exp $
  *
  * Exported functions of module b1pcmcia to be called by
  * avm_cs card services module.
  *
  * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #ifndef _B1PCMCIA_H_
index 86ea92ae5a94436edcbb908ef552f83b93e7a4d1..7168cbdf37f652f8b81db42cd666d96c5929f1c2 100644 (file)
@@ -203,4 +203,27 @@ static inline int get_hardsect_size(kdev_t dev)
 #define blk_finished_io(nsects)        do { } while (0)
 #define blk_started_io(nsects) do { } while (0)
 
+static inline unsigned int blksize_bits(unsigned int size)
+{
+       unsigned int bits = 8;
+       do {
+               bits++;
+               size >>= 1;
+       } while (size > 256);
+       return bits;
+}
+
+static inline unsigned int block_size(kdev_t dev)
+{
+       int retval = BLOCK_SIZE;
+       int major = MAJOR(dev);
+
+       if (blksize_size[major]) {
+               int minor = MINOR(dev);
+               if (blksize_size[major][minor])
+                       retval = blksize_size[major][minor];
+       }
+       return retval;
+}
+
 #endif
index 4dc4750ac2eb26cb3479a6be3cd7a3c33e09ef20..bbf34f3aa21f80b8ed36c02c4281edea9151feb5 100644 (file)
@@ -68,7 +68,7 @@ struct vc_data {
        unsigned char   vc_utf          : 1;    /* Unicode UTF-8 encoding */
        unsigned char   vc_utf_count;
                 int    vc_utf_char;
-       unsigned int    vc_tab_stop[5];         /* Tab stops. 160 columns. */
+       unsigned int    vc_tab_stop[8];         /* Tab stops. 256 columns. */
        unsigned char   vc_palette[16*3];       /* Colour palette for VGA+ */
        unsigned short * vc_translate;
        unsigned char   vc_G0_charset;
index 79d82d2ac6d8dcd649d8e950b1002f74bf85e8af..03112a82fadb257e52d92b90ee6e602032b6c761 100644 (file)
@@ -558,14 +558,15 @@ extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
                                                    unsigned int block_group,
                                                    struct buffer_head ** bh);
 
-/* bitmap.c */
-extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
-
 /* dir.c */
-
-/* file.c */
-extern int ext2_read (struct inode *, struct file *, char *, int);
-extern int ext2_write (struct inode *, struct file *, char *, int);
+extern int ext2_add_link (struct dentry *, struct inode *);
+extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
+extern int ext2_make_empty(struct inode *, struct inode *);
+extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
+extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
+extern int ext2_empty_dir (struct inode *);
+extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
+extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
 
 /* fsync.c */
 extern int ext2_sync_file (struct file *, struct dentry *, int);
@@ -576,26 +577,21 @@ extern struct inode * ext2_new_inode (const struct inode *, int);
 extern void ext2_free_inode (struct inode *);
 extern unsigned long ext2_count_free_inodes (struct super_block *);
 extern void ext2_check_inodes_bitmap (struct super_block *);
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
 
 /* inode.c */
-
-extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
-extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
-
 extern void ext2_read_inode (struct inode *);
 extern void ext2_write_inode (struct inode *, int);
 extern void ext2_put_inode (struct inode *);
 extern void ext2_delete_inode (struct inode *);
 extern int ext2_sync_inode (struct inode *);
 extern void ext2_discard_prealloc (struct inode *);
+extern void ext2_truncate (struct inode *);
 
 /* ioctl.c */
 extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
                       unsigned long);
 
-/* namei.c */
-extern struct inode_operations ext2_dir_inode_operations;
-
 /* super.c */
 extern void ext2_error (struct super_block *, const char *, const char *, ...)
        __attribute__ ((format (printf, 3, 4)));
@@ -611,33 +607,26 @@ extern int ext2_remount (struct super_block *, int *, char *);
 extern struct super_block * ext2_read_super (struct super_block *,void *,int);
 extern int ext2_statfs (struct super_block *, struct statfs *);
 
-/* truncate.c */
-extern void ext2_truncate (struct inode *);
-
 /*
  * Inodes and files operations
  */
 
 /* dir.c */
 extern struct file_operations ext2_dir_operations;
-extern int ext2_add_link (struct dentry *, struct inode *);
-extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
-extern int ext2_make_empty(struct inode *, struct inode *);
-extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
-extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
-extern int ext2_empty_dir (struct inode *);
-extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
-extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
 
 /* file.c */
 extern struct inode_operations ext2_file_inode_operations;
 extern struct file_operations ext2_file_operations;
 
+/* inode.c */
+extern struct address_space_operations ext2_aops;
+
+/* namei.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
 /* symlink.c */
 extern struct inode_operations ext2_fast_symlink_inode_operations;
 
-extern struct address_space_operations ext2_aops;
-
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_EXT2_FS_H */
index d1327ef61f97026667743547281c04a856cb1061..73c5e08eac09fc0e4460fc38378a8f487f07b9b5 100644 (file)
@@ -604,6 +604,7 @@ extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
 extern int posix_lock_file(struct file *, struct file_lock *, unsigned int);
 extern void posix_block_lock(struct file_lock *, struct file_lock *);
 extern void posix_unblock_lock(struct file_lock *);
+extern int posix_locks_deadlock(struct file_lock *, struct file_lock *);
 extern int __get_lease(struct inode *inode, unsigned int flags);
 extern time_t lease_get_mtime(struct inode *);
 extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
index 9c2d23ecb6024bf1cfcaa4927f4b40d9eb3a10b8..7134c8b8a18e52ca38c02bd465fe126da2d1eaa0 100644 (file)
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/* $Id: i2c-dev.h,v 1.8 2000/08/12 16:37:15 mds Exp $ */
+/* $Id: i2c-dev.h,v 1.9 2001/08/15 03:04:58 mds Exp $ */
 
 #ifndef I2C_DEV_H
 #define I2C_DEV_H
index f2d8155b28e9c90f6f24b07f61e6dc9c0e99762d..7c921317589273ddbadaa6f7c788147cbd1141be 100644 (file)
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elektor.h,v 1.4 2000/01/18 23:54:07 frodo Exp $ */
+/* $Id: i2c-elektor.h,v 1.5 2001/06/05 01:46:33 mds Exp $ */
 
 #ifndef I2C_PCF_ELEKTOR_H
 #define I2C_PCF_ELEKTOR_H 1
 
 /*
- * This struct contains the hw-dependent functions of PCF8584 adapters to 
- * manipulate the registers, and to init any hw-specific features. 
- */
+ * This struct contains the hw-dependent functions of PCF8584 adapters to
+ * manipulate the registers, and to init any hw-specific features.
+ * vdovikin: removed: this module in real supports only one device,
+ * due to missing arguments in some functions, called from the algo-pcf module.
+ * Sometimes it's need to be rewriten -
+ * but for now just remove this for simpler reading */
 
+/*
 struct i2c_pcf_isa {
        int pi_base;
        int pi_irq;
        int pi_clock;
        int pi_own;
 };
-
+*/
 
 #endif /* PCF_ELEKTOR_H */
index b0f62dd14386257971d330dca173dbf5c662323d..74f4f23c1b0943ce97f7da16af3181cd138c2544 100644 (file)
@@ -20,7 +20,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
 /* ------------------------------------------------------------------------- */
 
-/* $Id: i2c-id.h,v 1.25 2000/10/12 07:27:29 simon Exp $ */
+/* $Id: i2c-id.h,v 1.35 2001/08/12 17:22:20 mds Exp $ */
 
 #ifndef I2C_ID_H
 #define I2C_ID_H
@@ -65,7 +65,7 @@
 #define I2C_DRIVERID_BT829     19      /* pc to tv encoder             */
 #define I2C_DRIVERID_TDA9850   20      /* audio mixer                  */
 #define I2C_DRIVERID_TDA9855   21      /* audio mixer                  */
-#define I2C_DRIVERID_SAA7110   22      /*                              */
+#define I2C_DRIVERID_SAA7110   22      /* video decoder                */
 #define I2C_DRIVERID_MGATVO    23      /* Matrox TVOut                 */
 #define I2C_DRIVERID_SAA5249   24      /* SAA5249 and compatibles      */
 #define I2C_DRIVERID_PCF8583   25      /* real time clock              */
 #define I2C_DRIVERID_VES1820   37     /* VLSI DVB-C decoder            */
 #define I2C_DRIVERID_SAA7113   38     /* video decoder                 */
 #define I2C_DRIVERID_TDA8444   39     /* octuple 6-bit DAC             */
-
+#define I2C_DRIVERID_BT819     40     /* video decoder                 */
+#define I2C_DRIVERID_BT856     41     /* video encoder                 */
+#define I2C_DRIVERID_VPX32XX   42     /* video decoder+vbi/vtxt        */
+#define I2C_DRIVERID_DRP3510   43     /* ADR decoder (Astra Radio)     */
+#define I2C_DRIVERID_SP5055    44     /* Satellite tuner               */
+#define I2C_DRIVERID_STV0030   45     /* Multipurpose switch           */
 
 #define I2C_DRIVERID_EXP0      0xF0    /* experimental use id's        */
 #define I2C_DRIVERID_EXP1      0xF1
 #define I2C_DRIVERID_I2CDEV    900
 #define I2C_DRIVERID_I2CPROC   901
 
+/* IDs --   Use DRIVERIDs 1000-1999 for sensors. 
+   These were originally in sensors.h in the lm_sensors package */
+#define I2C_DRIVERID_LM78 1002
+#define I2C_DRIVERID_LM75 1003
+#define I2C_DRIVERID_GL518 1004
+#define I2C_DRIVERID_EEPROM 1005
+#define I2C_DRIVERID_W83781D 1006
+#define I2C_DRIVERID_LM80 1007
+#define I2C_DRIVERID_ADM1021 1008
+#define I2C_DRIVERID_ADM9240 1009
+#define I2C_DRIVERID_LTC1710 1010
+#define I2C_DRIVERID_SIS5595 1011
+#define I2C_DRIVERID_ICSPLL 1012
+#define I2C_DRIVERID_BT869 1013
+#define I2C_DRIVERID_MAXILIFE 1014
+#define I2C_DRIVERID_MATORB 1015
+#define I2C_DRIVERID_GL520 1016
+#define I2C_DRIVERID_THMC50 1017
+#define I2C_DRIVERID_DDCMON 1018
+#define I2C_DRIVERID_VIA686A 1019
+#define I2C_DRIVERID_ADM1025 1020
+#define I2C_DRIVERID_LM87 1021
+#define I2C_DRIVERID_PCF8574 1022
+#define I2C_DRIVERID_MTP008 1023
+#define I2C_DRIVERID_DS1621 1024
+#define I2C_DRIVERID_ADM1024 1025
+#define I2C_DRIVERID_IT87 1026
+#define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */
+
 /*
  * ---- Adapter types ----------------------------------------------------
  *
 #define I2C_ALGO_ISA   0x050000        /* lm_sensors ISA pseudo-adapter */
 #define I2C_ALGO_SAA7146 0x060000      /* SAA 7146 video decoder bus   */
 #define I2C_ALGO_ACB   0x070000        /* ACCESS.bus algorithm         */
-#define I2C_ALGO_IIC    0x080000       /* ITE IIC bus */
 
 #define I2C_ALGO_EC     0x100000        /* ACPI embedded controller     */
 
 #define I2C_HW_B_G400  0x09    /* Matrox G400                          */
 #define I2C_HW_B_I810  0x0a    /* Intel I810                           */
 #define I2C_HW_B_VOO   0x0b    /* 3dfx Voodoo 3 / Banshee              */
+#define I2C_HW_B_PPORT  0x0c   /* Primitive parallel port adapter      */
 #define I2C_HW_B_RIVA  0x10    /* Riva based graphics cards            */
 #define I2C_HW_B_IOC   0x11    /* IOC bit-wiggling                     */
+#define I2C_HW_B_TSUNA  0x12   /* DEC Tsunami chipset                  */
 
 /* --- PCF 8584 based algorithms                                       */
 #define I2C_HW_P_LP    0x00    /* Parallel port interface              */
 /* --- MPC8xx PowerPC adapters                                         */
 #define I2C_HW_MPC8XX_EPON 0x00        /* Eponymous MPC8xx I2C adapter         */
 
-/* --- ITE based algorithms                                            */
-#define I2C_HW_I_IIC   0x00    /* controller on the ITE */
-
 /* --- SMBus only adapters                                             */
 #define I2C_HW_SMBUS_PIIX4     0x00
 #define I2C_HW_SMBUS_ALI15X3   0x01
diff --git a/include/linux/i2c-proc.h b/include/linux/i2c-proc.h
new file mode 100644 (file)
index 0000000..364cfe7
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+    sensors.h - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef SENSORS_SENSORS_H
+#define SENSORS_SENSORS_H
+
+#ifdef __KERNEL__
+
+/* Next two must be included before sysctl.h can be included, in 2.0 kernels */
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+
+/* The type of callback functions used in sensors_{proc,sysctl}_real */
+typedef void (*i2c_real_callback) (struct i2c_client * client,
+                                      int operation, int ctl_name,
+                                      int *nrels_mag, long *results);
+
+/* Values for the operation field in the above function type */
+#define SENSORS_PROC_REAL_INFO 1
+#define SENSORS_PROC_REAL_READ 2
+#define SENSORS_PROC_REAL_WRITE 3
+
+/* These funcion reads or writes a 'real' value (encoded by the combination
+   of an integer and a magnitude, the last is the power of ten the value
+   should be divided with) to a /proc/sys directory. To use these functions,
+   you must (before registering the ctl_table) set the extra2 field to the
+   client, and the extra1 field to a function of the form:
+      void func(struct i2c_client *client, int operation, int ctl_name,
+                int *nrels_mag, long *results)
+   This last function can be called for three values of operation. If
+   operation equals SENSORS_PROC_REAL_INFO, the magnitude should be returned
+   in nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
+   be read into results. nrels_mag should return the number of elements
+   read; the maximum number is put in it on entry. Finally, if operation
+   equals SENSORS_PROC_REAL_WRITE, the values in results should be
+   written to the chip. nrels_mag contains on entry the number of elements
+   found.
+   In all cases, client points to the client we wish to interact with,
+   and ctl_name is the SYSCTL id of the file we are accessing. */
+extern int i2c_sysctl_real(ctl_table * table, int *name, int nlen,
+                              void *oldval, size_t * oldlenp,
+                              void *newval, size_t newlen,
+                              void **context);
+extern int i2c_proc_real(ctl_table * ctl, int write, struct file *filp,
+                            void *buffer, size_t * lenp);
+
+
+
+/* These rather complex functions must be called when you want to add or
+   delete an entry in /proc/sys/dev/sensors/chips (not yet implemented). It
+   also creates a new directory within /proc/sys/dev/sensors/.
+   ctl_template should be a template of the newly created directory. It is
+   copied in memory. The extra2 field of each file is set to point to client.
+   If any driver wants subdirectories within the newly created directory,
+   these functions must be updated! */
+extern int i2c_register_entry(struct i2c_client *client,
+                                 const char *prefix,
+                                 ctl_table * ctl_template,
+                                 struct module *controlling_mod);
+
+extern void i2c_deregister_entry(int id);
+
+
+/* A structure containing detect information.
+   Force variables overrule all other variables; they force a detection on
+   that place. If a specific chip is given, the module blindly assumes this
+   chip type is present; if a general force (kind == 0) is given, the module
+   will still try to figure out what type of chip is present. This is useful
+   if for some reasons the detect for SMBus or ISA address space filled
+   fails.
+   probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second is the address. 
+   kind: The kind of chip. 0 equals any chip.
+*/
+struct i2c_force_data {
+       unsigned short *force;
+       unsigned short kind;
+};
+
+/* A structure containing the detect information.
+   normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
+     A list of I2C addresses which should normally be examined.
+   normal_i2c_range: filled in by the module writer. Terminated by 
+     SENSORS_I2C_END
+     A list of pairs of I2C addresses, each pair being an inclusive range of
+     addresses which should normally be examined.
+   normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
+     A list of ISA addresses which should normally be examined.
+   normal_isa_range: filled in by the module writer. Terminated by 
+     SENSORS_ISA_END
+     A list of triples. The first two elements are ISA addresses, being an
+     range of addresses which should normally be examined. The third is the
+     modulo parameter: only addresses which are 0 module this value relative
+     to the first address of the range are actually considered.
+   probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second is the address. These
+     addresses are also probed, as if they were in the 'normal' list.
+   probe_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
+     values.
+     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
+     These form an inclusive range of addresses that are also probed, as
+     if they were in the 'normal' list.
+   ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second is the I2C address. These
+     addresses are never probed. This parameter overrules 'normal' and 
+     'probe', but not the 'force' lists.
+   ignore_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
+      values.
+     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
+     These form an inclusive range of I2C addresses that are never probed.
+     This parameter overrules 'normal' and 'probe', but not the 'force' lists.
+   force_data: insmod parameters. A list, ending with an element of which
+     the force field is NULL.
+*/
+struct i2c_address_data {
+       unsigned short *normal_i2c;
+       unsigned short *normal_i2c_range;
+       unsigned int *normal_isa;
+       unsigned int *normal_isa_range;
+       unsigned short *probe;
+       unsigned short *probe_range;
+       unsigned short *ignore;
+       unsigned short *ignore_range;
+       struct i2c_force_data *forces;
+};
+
+/* Internal numbers to terminate lists */
+#define SENSORS_I2C_END 0xfffe
+#define SENSORS_ISA_END 0xfffefffe
+
+/* The numbers to use to set an ISA or I2C bus address */
+#define SENSORS_ISA_BUS 9191
+#define SENSORS_ANY_I2C_BUS 0xffff
+
+/* The length of the option lists */
+#define SENSORS_MAX_OPTS 48
+
+/* Default fill of many variables */
+#define SENSORS_DEFAULTS {SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END}
+
+/* This is ugly. We need to evaluate SENSORS_MAX_OPTS before it is 
+   stringified */
+#define SENSORS_MODPARM_AUX1(x) "1-" #x "h"
+#define SENSORS_MODPARM_AUX(x) SENSORS_MODPARM_AUX1(x)
+#define SENSORS_MODPARM SENSORS_MODPARM_AUX(SENSORS_MAX_OPTS)
+
+/* SENSORS_MODULE_PARM creates a module parameter, and puts it in the
+   module header */
+#define SENSORS_MODULE_PARM(var,desc) \
+  static unsigned short var[SENSORS_MAX_OPTS] = SENSORS_DEFAULTS; \
+  MODULE_PARM(var,SENSORS_MODPARM); \
+  MODULE_PARM_DESC(var,desc)
+
+/* SENSORS_MODULE_PARM creates a 'force_*' module parameter, and puts it in
+   the module header */
+#define SENSORS_MODULE_PARM_FORCE(name) \
+  SENSORS_MODULE_PARM(force_ ## name, \
+                      "List of adapter,address pairs which are unquestionably" \
+                      " assumed to contain a `" # name "' chip")
+
+
+/* This defines several insmod variables, and the addr_data structure */
+#define SENSORS_INSMOD \
+  SENSORS_MODULE_PARM(probe, \
+                      "List of adapter,address pairs to scan additionally"); \
+  SENSORS_MODULE_PARM(probe_range, \
+                      "List of adapter,start-addr,end-addr triples to scan " \
+                      "additionally"); \
+  SENSORS_MODULE_PARM(ignore, \
+                      "List of adapter,address pairs not to scan"); \
+  SENSORS_MODULE_PARM(ignore_range, \
+                      "List of adapter,start-addr,end-addr triples not to " \
+                      "scan"); \
+  static struct i2c_address_data addr_data = \
+                                       {normal_i2c, normal_i2c_range, \
+                                        normal_isa, normal_isa_range, \
+                                        probe, probe_range, \
+                                        ignore, ignore_range, \
+                                        forces}
+
+/* The following functions create an enum with the chip names as elements. 
+   The first element of the enum is any_chip. These are the only macros
+   a module will want to use. */
+
+#define SENSORS_INSMOD_0 \
+  enum chips { any_chip }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  static struct i2c_force_data forces[] = {{force,any_chip},{NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_1(chip1) \
+  enum chips { any_chip, chip1 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  static struct i2c_force_data forces[] = {{force,any_chip},\
+                                                 {force_ ## chip1,chip1}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_2(chip1,chip2) \
+  enum chips { any_chip, chip1, chip2 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_3(chip1,chip2,chip3) \
+  enum chips { any_chip, chip1, chip2, chip3 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_4(chip1,chip2,chip3,chip4) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_5(chip1,chip2,chip3,chip4,chip5) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  SENSORS_MODULE_PARM_FORCE(chip5); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {force_ ## chip5,chip5}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_6(chip1,chip2,chip3,chip4,chip5,chip6) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  SENSORS_MODULE_PARM_FORCE(chip5); \
+  SENSORS_MODULE_PARM_FORCE(chip6); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {force_ ## chip5,chip5}, \
+                                                 {force_ ## chip6,chip6}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_7(chip1,chip2,chip3,chip4,chip5,chip6,chip7) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, chip7 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  SENSORS_MODULE_PARM_FORCE(chip5); \
+  SENSORS_MODULE_PARM_FORCE(chip6); \
+  SENSORS_MODULE_PARM_FORCE(chip7); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {force_ ## chip5,chip5}, \
+                                                 {force_ ## chip6,chip6}, \
+                                                 {force_ ## chip7,chip7}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+typedef int i2c_found_addr_proc(struct i2c_adapter *adapter,
+                                   int addr, unsigned short flags,
+                                   int kind);
+
+/* Detect function. It iterates over all possible addresses itself. For
+   SMBus addresses, it will only call found_proc if some client is connected
+   to the SMBus (unless a 'force' matched); for ISA detections, this is not
+   done. */
+extern int i2c_detect(struct i2c_adapter *adapter,
+                         struct i2c_address_data *address_data,
+                         i2c_found_addr_proc * found_proc);
+
+
+/* This macro is used to scale user-input to sensible values in almost all
+   chip drivers. */
+extern inline int SENSORS_LIMIT(long value, long low, long high)
+{
+       if (value < low)
+               return low;
+       else if (value > high)
+               return high;
+       else
+               return value;
+}
+
+#endif                         /* def __KERNEL__ */
+
+
+/* The maximum length of the prefix */
+#define SENSORS_PREFIX_MAX 20
+
+/* Sysctl IDs */
+#ifdef DEV_HWMON
+#define DEV_SENSORS DEV_HWMON
+#else                          /* ndef DEV_HWMOM */
+#define DEV_SENSORS 2          /* The id of the lm_sensors directory within the
+                                  dev table */
+#endif                         /* def DEV_HWMON */
+
+#define SENSORS_CHIPS 1
+struct i2c_chips_data {
+       int sysctl_id;
+       char name[SENSORS_PREFIX_MAX + 13];
+};
+
+#endif                         /* def SENSORS_SENSORS_H */
+
index 546c573a45d3dc2d4ddc157924ec0a4a8468393a..256a7da0d84521da07adfc7e7363978a1cc02508 100644 (file)
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c.h,v 1.42 2000/09/06 20:14:06 frodo Exp $ */
+/* $Id: i2c.h,v 1.46 2001/08/31 00:04:07 phil Exp $ */
 
 #ifndef I2C_H
 #define I2C_H
 
+#define I2C_DATE "20010830"
+#define I2C_VERSION "2.6.1"
+
 #include <linux/i2c-id.h>      /* id values of adapters et. al.        */
 #include <linux/types.h>
 
@@ -202,7 +205,7 @@ struct i2c_algorithm {
        char name[32];                          /* textual description  */
        unsigned int id;
 
-       /* If a adapter algorithm can't to I2C-level access, set master_xfer
+       /* If an adapter algorithm can't to I2C-level access, set master_xfer
           to NULL. If an adapter algorithm can do SMBus access, set 
           smbus_xfer. If set to NULL, the SMBus protocol is simulated
           using common I2C messages */
@@ -344,7 +347,7 @@ extern int i2c_release_client(struct i2c_client *);
    you can cheat by simply not registering. Not recommended, of course! */
 extern int i2c_check_addr (struct i2c_adapter *adapter, int addr);
 
-/* Detect function. It itterates over all possible addresses itself.
+/* Detect function. It iterates over all possible addresses itself.
  * It will only call found_proc if some client is connected at the
  * specific address (unless a 'force' matched);
  */
@@ -360,7 +363,7 @@ extern int i2c_probe(struct i2c_adapter *adapter,
 extern int i2c_control(struct i2c_client *,unsigned int, unsigned long);
 
 /* This call returns a unique low identifier for each registered adapter,
- * or -1 if the adapter was not regisitered. 
+ * or -1 if the adapter was not registered. 
  */
 extern int i2c_adapter_id(struct i2c_adapter *adap);
 
@@ -454,8 +457,9 @@ union i2c_smbus_data {
  *     corresponding header files.
  */
                                /* -> bit-adapter specific ioctls       */
-#define I2C_RETRIES    0x0701  /* number times a device address should */
-                               /* be polled when not acknowledging     */
+#define I2C_RETRIES    0x0701  /* number of times a device address      */
+                               /* should be polled when not            */
+                                /* acknowledging                       */
 #define I2C_TIMEOUT    0x0702  /* set timeout - call with int          */
 
 
@@ -549,5 +553,12 @@ union i2c_smbus_data {
                                         ignore, ignore_range, \
                                         force}
 
+/* Detect whether we are on the isa bus. If this returns true, all i2c
+   access will fail! */
+#define i2c_is_isa_client(clientptr) \
+        ((clientptr)->adapter->algo->id == I2C_ALGO_ISA)
+#define i2c_is_isa_adapter(adapptr) \
+        ((adapptr)->algo->id == I2C_ALGO_ISA)
+
 #endif /* def __KERNEL__ */
 #endif /* I2C_H */
index 5ac8d9cef46e44722e8ad51dadc856f2066306f1..cd4eb5ac5a9b23f32ee19f93b935f6dc95dc6589 100644 (file)
 #define I2OLCTGET              _IOWR(I2O_MAGIC_NUMBER,2,struct i2o_cmd_hrtlct)
 #define I2OPARMSET             _IOWR(I2O_MAGIC_NUMBER,3,struct i2o_cmd_psetget)
 #define I2OPARMGET             _IOWR(I2O_MAGIC_NUMBER,4,struct i2o_cmd_psetget)
-#define I2OSWDL                        _IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer)
-#define I2OSWUL                        _IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer)
+#define I2OSWDL                _IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer)
+#define I2OSWUL                _IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer)
 #define I2OSWDEL               _IOWR(I2O_MAGIC_NUMBER,7,struct i2o_sw_xfer)
 #define I2OVALIDATE            _IOR(I2O_MAGIC_NUMBER,8,u32)
-#define I2OHTML                        _IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html)
+#define I2OHTML                _IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html)
 #define I2OEVTREG              _IOW(I2O_MAGIC_NUMBER,10,struct i2o_evt_id)
 #define I2OEVTGET              _IOR(I2O_MAGIC_NUMBER,11,struct i2o_evt_info)
 
@@ -68,7 +68,7 @@ struct i2o_sw_xfer
        void *buf;              /* Pointer to software buffer */
        unsigned int *swlen;    /* Length of software data */
        unsigned int *maxfrag;  /* Maximum fragment count */
-        unsigned int *curfrag; /* Current fragment count */
+       unsigned int *curfrag;  /* Current fragment count */
 };
 
 struct i2o_html
@@ -98,7 +98,7 @@ struct i2o_evt_info
 {
        struct i2o_evt_id id;
        unsigned char evt_data[I2O_EVT_DATA_SIZE];
-       unsigned int data_size;
+       unsigned int data_size;
 };
 
 struct i2o_evt_get
@@ -119,8 +119,8 @@ struct i2o_evt_get
 #define I2O_BUS_PCI    4
 #define I2O_BUS_PCMCIA 5
 #define I2O_BUS_NUBUS  6
-#define I2O_BUS_CARDBUS        7
-#define I2O_BUS_UNKNOWN        0x80
+#define I2O_BUS_CARDBUS 7
+#define I2O_BUS_UNKNOWN 0x80
 
 #ifndef __KERNEL__
 
@@ -130,127 +130,139 @@ typedef unsigned int u32;
 
 #endif /* __KERNEL__ */
 
-typedef struct _i2o_pci_bus {
-       u8 PciFunctionNumber;
-       u8 PciDeviceNumber;
-       u8 PciBusNumber;
-       u8 reserved;
-       u16 PciVendorID;
-       u16 PciDeviceID;
+typedef struct _i2o_pci_bus
+{
+       u8      PciFunctionNumber;
+       u8      PciDeviceNumber;
+       u8      PciBusNumber;
+       u8      reserved;
+       u16     PciVendorID;
+       u16     PciDeviceID;
 } i2o_pci_bus;
 
-typedef struct _i2o_local_bus {
-       u16 LbBaseIOPort;
-       u16 reserved;
-       u32 LbBaseMemoryAddress;
+typedef struct _i2o_local_bus
+{
+       u16     LbBaseIOPort;
+       u16     reserved;
+       u32     LbBaseMemoryAddress;
 } i2o_local_bus;
 
-typedef struct _i2o_isa_bus {
-       u16 IsaBaseIOPort;
-       u8 CSN;
-       u8 reserved;
-       u32 IsaBaseMemoryAddress;
+typedef struct _i2o_isa_bus
+{
+       u16     IsaBaseIOPort;
+       u8      CSN;
+       u8      reserved;
+       u32     IsaBaseMemoryAddress;
 } i2o_isa_bus;
 
-typedef struct _i2o_eisa_bus_info {
-       u16 EisaBaseIOPort;
-       u8 reserved;
-       u8 EisaSlotNumber;
-       u32 EisaBaseMemoryAddress;
+typedef struct _i2o_eisa_bus_info
+{
+       u16     EisaBaseIOPort;
+       u8      reserved;
+       u8      EisaSlotNumber;
+       u32     EisaBaseMemoryAddress;
 } i2o_eisa_bus;
 
-typedef struct _i2o_mca_bus {
-       u16 McaBaseIOPort;
-       u8 reserved;
-       u8 McaSlotNumber;
-       u32 McaBaseMemoryAddress;
+typedef struct _i2o_mca_bus
+{
+       u16     McaBaseIOPort;
+       u8      reserved;
+       u8      McaSlotNumber;
+       u32     McaBaseMemoryAddress;
 } i2o_mca_bus;
 
-typedef struct _i2o_other_bus {
+typedef struct _i2o_other_bus
+{
        u16 BaseIOPort;
        u16 reserved;
        u32 BaseMemoryAddress;
 } i2o_other_bus;
 
-typedef struct _i2o_hrt_entry {
-       u32 adapter_id;
-       u32 parent_tid:12;
-       u32 state:4;
-       u32 bus_num:8;
-       u32 bus_type:8;
-       union {
-               i2o_pci_bus pci_bus;
-               i2o_local_bus local_bus;
-               i2o_isa_bus isa_bus;
-               i2o_eisa_bus eisa_bus;
-               i2o_mca_bus mca_bus;
-               i2o_other_bus other_bus;
+typedef struct _i2o_hrt_entry
+{
+       u32     adapter_id;
+       u32     parent_tid:12;
+       u32     tate:4;
+       u32     bus_num:8;
+       u32     bus_type:8;
+       union
+       {
+               i2o_pci_bus     pci_bus;
+               i2o_local_bus   local_bus;
+               i2o_isa_bus     isa_bus;
+               i2o_eisa_bus    eisa_bus;
+               i2o_mca_bus     mca_bus;
+               i2o_other_bus   other_bus;
        } bus;
 } i2o_hrt_entry;
 
-typedef struct _i2o_hrt {
-       u16 num_entries;
-       u8 entry_len;
-       u8 hrt_version;
-       u32 change_ind;
+typedef struct _i2o_hrt
+{
+       u16     num_entries;
+       u8      entry_len;
+       u8      hrt_version;
+       u32     change_ind;
        i2o_hrt_entry hrt_entry[1];
 } i2o_hrt;
 
-typedef struct _i2o_lct_entry {
-       u32 entry_size:16;
-       u32 tid:12;
-       u32 reserved:4;
-       u32 change_ind;
-       u32 device_flags;
-       u32 class_id:12;
-       u32 version:4;
-       u32 vendor_id:16;
-       u32 sub_class;
-       u32 user_tid:12;
-       u32 parent_tid:12;
-       u32 bios_info:8;
-       u8 identity_tag[8];
-       u32 event_capabilities;
+typedef struct _i2o_lct_entry
+{
+       u32     entry_size:16;
+       u32     tid:12;
+       u32     reserved:4;
+       u32     change_ind;
+       u32     device_flags;
+       u32     class_id:12;
+       u32     version:4;
+       u32     vendor_id:16;
+       u32     sub_class;
+       u32     user_tid:12;
+       u32     parent_tid:12;
+       u32     bios_info:8;
+       u8      identity_tag[8];
+       u32     event_capabilities;
 } i2o_lct_entry;
 
-typedef struct _i2o_lct {
-       u32 table_size:16;
-       u32 boot_tid:12;
-       u32 lct_ver:4;
-       u32 iop_flags;
-       u32 change_ind;
+typedef struct _i2o_lct
+{
+       u32     table_size:16;
+       u32     boot_tid:12;
+       u32     lct_ver:4;
+       u32     iop_flags;
+       u32     change_ind;
        i2o_lct_entry lct_entry[1];
 } i2o_lct;
 
-typedef struct _i2o_status_block {
-       u16 org_id;
-       u16 reserved;
-       u16 iop_id:12;
-       u16 reserved1:4;
-       u16 host_unit_id;
-       u16 segment_number:12;
-       u16 i2o_version:4;
-       u8 iop_state;
-       u8 msg_type;
-       u16 inbound_frame_size;
-       u8 init_code;   
-       u8 reserved2;
-       u32 max_inbound_frames;
-       u32 cur_inbound_frames;
-       u32 max_outbound_frames;
-       char product_id[24];    
-       u32 expected_lct_size;
-       u32 iop_capabilities;
-       u32 desired_mem_size;
-       u32 current_mem_size;
-       u32 current_mem_base;
-       u32 desired_io_size;
-       u32 current_io_size;
-       u32 current_io_base;
-       u32 reserved3:24;
-       u32 cmd_status:8;
+typedef struct _i2o_status_block
+{
+       u16     org_id;
+       u16     reserved;
+       u16     iop_id:12;
+       u16     reserved1:4;
+       u16     host_unit_id;
+       u16     segment_number:12;
+       u16     i2o_version:4;
+       u8      iop_state;
+       u8      msg_type;
+       u16     inbound_frame_size;
+       u8      init_code;
+       u8      reserved2;
+       u32     max_inbound_frames;
+       u32     cur_inbound_frames;
+       u32     max_outbound_frames;
+       char    product_id[24];
+       u32     expected_lct_size;
+       u32     iop_capabilities;
+       u32     desired_mem_size;
+       u32     current_mem_size;
+       u32     current_mem_base;
+       u32     desired_io_size;
+       u32     current_io_size;
+       u32     current_io_base;
+       u32     reserved3:24;
+       u32     cmd_status:8;
 } i2o_status_block;
+
 /* Event indicator mask flags */
 #define I2O_EVT_IND_STATE_CHANGE               0x80000000
 #define I2O_EVT_IND_GENERAL_WARNING            0x40000000
@@ -269,7 +281,7 @@ typedef struct _i2o_status_block {
 #define I2O_EVT_IND_EXEC_ADAPTER_FAULT         0x00000004
 #define I2O_EVT_IND_EXEC_POWER_FAIL            0x00000008
 #define I2O_EVT_IND_EXEC_RESET_PENDING         0x00000010
-#define I2O_EVT_IND_EXEC_RESET_IMMINENT                0x00000020
+#define I2O_EVT_IND_EXEC_RESET_IMMINENT        0x00000020
 #define I2O_EVT_IND_EXEC_HW_FAIL               0x00000040
 #define I2O_EVT_IND_EXEC_XCT_CHANGE            0x00000080
 #define I2O_EVT_IND_EXEC_NEW_LCT_ENTRY         0x00000100
@@ -280,14 +292,14 @@ typedef struct _i2o_status_block {
 #define I2O_EVT_IND_BSA_VOLUME_LOAD            0x00000001
 #define I2O_EVT_IND_BSA_VOLUME_UNLOAD          0x00000002
 #define I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ      0x00000004
-#define I2O_EVT_IND_BSA_CAPACITY_CHANGE                0x00000008
+#define I2O_EVT_IND_BSA_CAPACITY_CHANGE        0x00000008
 #define I2O_EVT_IND_BSA_SCSI_SMART             0x00000010
 
 /* Event data for generic events */
 #define I2O_EVT_STATE_CHANGE_NORMAL            0x00
 #define I2O_EVT_STATE_CHANGE_SUSPENDED         0x01
 #define I2O_EVT_STATE_CHANGE_RESTART           0x02
-#define I2O_EVT_STATE_CHANGE_NA_RECOVER                0x03
+#define I2O_EVT_STATE_CHANGE_NA_RECOVER        0x03
 #define I2O_EVT_STATE_CHANGE_NA_NO_RECOVER     0x04
 #define I2O_EVT_STATE_CHANGE_QUIESCE_REQUEST   0x05
 #define I2O_EVT_STATE_CHANGE_FAILED            0x10
@@ -295,7 +307,7 @@ typedef struct _i2o_status_block {
 
 #define I2O_EVT_GEN_WARNING_NORMAL             0x00
 #define I2O_EVT_GEN_WARNING_ERROR_THRESHOLD    0x01
-#define I2O_EVT_GEN_WARNING_MEDIA_FAULT                0x02
+#define I2O_EVT_GEN_WARNING_MEDIA_FAULT        0x02
 
 #define I2O_EVT_CAPABILITY_OTHER               0x01
 #define I2O_EVT_CAPABILITY_CHANGED             0x02
@@ -309,89 +321,89 @@ typedef struct _i2o_status_block {
 /*  Class ID and Code Assignments
  *  (LCT.ClassID.Version field)
  */
-#define    I2O_CLASS_VERSION_10                        0x00
-#define    I2O_CLASS_VERSION_11                        0x01
+#define I2O_CLASS_VERSION_10                   0x00
+#define I2O_CLASS_VERSION_11                   0x01
 
 /*  Class code names
  *  (from v1.5 Table 6-1 Class Code Assignments.)
  */
-#define    I2O_CLASS_EXECUTIVE                         0x000
-#define    I2O_CLASS_DDM                               0x001
-#define    I2O_CLASS_RANDOM_BLOCK_STORAGE              0x010
-#define    I2O_CLASS_SEQUENTIAL_STORAGE                0x011
-#define    I2O_CLASS_LAN                               0x020
-#define    I2O_CLASS_WAN                               0x030
-#define    I2O_CLASS_FIBRE_CHANNEL_PORT                0x040
-#define    I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL          0x041
-#define    I2O_CLASS_SCSI_PERIPHERAL                   0x051
-#define    I2O_CLASS_ATE_PORT                          0x060
-#define    I2O_CLASS_ATE_PERIPHERAL                    0x061
-#define    I2O_CLASS_FLOPPY_CONTROLLER                 0x070
-#define    I2O_CLASS_FLOPPY_DEVICE                     0x071
-#define    I2O_CLASS_BUS_ADAPTER_PORT                  0x080
-#define    I2O_CLASS_PEER_TRANSPORT_AGENT              0x090
-#define    I2O_CLASS_PEER_TRANSPORT                    0x091
+
+#define I2O_CLASS_EXECUTIVE                    0x000
+#define I2O_CLASS_DDM                          0x001
+#define I2O_CLASS_RANDOM_BLOCK_STORAGE         0x010
+#define I2O_CLASS_SEQUENTIAL_STORAGE           0x011
+#define I2O_CLASS_LAN                          0x020
+#define I2O_CLASS_WAN                          0x030
+#define I2O_CLASS_FIBRE_CHANNEL_PORT           0x040
+#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL     0x041
+#define I2O_CLASS_SCSI_PERIPHERAL              0x051
+#define I2O_CLASS_ATE_PORT                     0x060
+#define I2O_CLASS_ATE_PERIPHERAL               0x061
+#define I2O_CLASS_FLOPPY_CONTROLLER            0x070
+#define I2O_CLASS_FLOPPY_DEVICE                0x071
+#define I2O_CLASS_BUS_ADAPTER_PORT             0x080
+#define I2O_CLASS_PEER_TRANSPORT_AGENT         0x090
+#define I2O_CLASS_PEER_TRANSPORT               0x091
 
 /* 
  *  Rest of 0x092 - 0x09f reserved for peer-to-peer classes
  */
-#define    I2O_CLASS_MATCH_ANYCLASS                    0xffffffff
+
+#define I2O_CLASS_MATCH_ANYCLASS               0xffffffff
 
 /* 
  *  Subclasses
  */
 
-#define    I2O_SUBCLASS_i960                           0x001
-#define    I2O_SUBCLASS_HDM                            0x020
-#define    I2O_SUBCLASS_ISM                            0x021
+#define I2O_SUBCLASS_i960                      0x001
+#define I2O_SUBCLASS_HDM                       0x020
+#define I2O_SUBCLASS_ISM                       0x021
+
 /* Operation functions */
 
-#define I2O_PARAMS_FIELD_GET   0x0001
-#define I2O_PARAMS_LIST_GET    0x0002
-#define I2O_PARAMS_MORE_GET    0x0003
-#define I2O_PARAMS_SIZE_GET    0x0004
-#define I2O_PARAMS_TABLE_GET   0x0005
-#define I2O_PARAMS_FIELD_SET   0x0006
-#define I2O_PARAMS_LIST_SET    0x0007
-#define I2O_PARAMS_ROW_ADD     0x0008
-#define I2O_PARAMS_ROW_DELETE  0x0009
-#define I2O_PARAMS_TABLE_CLEAR 0x000A
+#define I2O_PARAMS_FIELD_GET                   0x0001
+#define I2O_PARAMS_LIST_GET                    0x0002
+#define I2O_PARAMS_MORE_GET                    0x0003
+#define I2O_PARAMS_SIZE_GET                    0x0004
+#define I2O_PARAMS_TABLE_GET                   0x0005
+#define I2O_PARAMS_FIELD_SET                   0x0006
+#define I2O_PARAMS_LIST_SET                    0x0007
+#define I2O_PARAMS_ROW_ADD                     0x0008
+#define I2O_PARAMS_ROW_DELETE                  0x0009
+#define I2O_PARAMS_TABLE_CLEAR                 0x000A
 
 /*
  * I2O serial number conventions / formats 
  * (circa v1.5)
  */
 
-#define    I2O_SNFORMAT_UNKNOWN                        0
-#define    I2O_SNFORMAT_BINARY                         1
-#define    I2O_SNFORMAT_ASCII                          2
-#define    I2O_SNFORMAT_UNICODE                        3
-#define    I2O_SNFORMAT_LAN48_MAC                      4
-#define    I2O_SNFORMAT_WAN                            5
+#define I2O_SNFORMAT_UNKNOWN                   0
+#define I2O_SNFORMAT_BINARY                    1
+#define I2O_SNFORMAT_ASCII                     2
+#define I2O_SNFORMAT_UNICODE                   3
+#define I2O_SNFORMAT_LAN48_MAC                 4
+#define I2O_SNFORMAT_WAN                       5
 
 /* 
  * Plus new in v2.0 (Yellowstone pdf doc)
  */
 
-#define    I2O_SNFORMAT_LAN64_MAC                      6
-#define    I2O_SNFORMAT_DDM                            7
-#define    I2O_SNFORMAT_IEEE_REG64                     8
-#define    I2O_SNFORMAT_IEEE_REG128                    9
-#define    I2O_SNFORMAT_UNKNOWN2                       0xff
+#define I2O_SNFORMAT_LAN64_MAC                 6
+#define I2O_SNFORMAT_DDM                       7
+#define I2O_SNFORMAT_IEEE_REG64                8
+#define I2O_SNFORMAT_IEEE_REG128               9
+#define I2O_SNFORMAT_UNKNOWN2                  0xff
 
 /*
  *     I2O Get Status State values 
  */
 
-#define        ADAPTER_STATE_INITIALIZING              0x01
-#define        ADAPTER_STATE_RESET                     0x02
-#define        ADAPTER_STATE_HOLD                      0x04
-#define        ADAPTER_STATE_READY                     0x05
-#define        ADAPTER_STATE_OPERATIONAL               0x08
-#define        ADAPTER_STATE_FAILED                    0x10
-#define        ADAPTER_STATE_FAULTED                   0x11
-       
+#define ADAPTER_STATE_INITIALIZING             0x01
+#define ADAPTER_STATE_RESET                    0x02
+#define ADAPTER_STATE_HOLD                     0x04
+#define ADAPTER_STATE_READY                    0x05
+#define ADAPTER_STATE_OPERATIONAL              0x08
+#define ADAPTER_STATE_FAILED                   0x10
+#define ADAPTER_STATE_FAULTED                  0x11
+
 #endif /* _I2O_DEV_H */
index 3ece9cee16bb6ee4b1a5c48fdb71caec2c471fc0..6fdec1eca6cac0dbcfee233cba905481b3b24bf2 100644 (file)
 
 #ifndef _I2O_H
 #define _I2O_H
-#ifdef __KERNEL__      /* This file to be included by kernel only */
+
+#ifdef __KERNEL__ /* This file to be included by kernel only */
 
 #include <linux/i2o-dev.h>
 
-/* How many different OSM's are we allowing */ 
+/* How many different OSM's are we allowing */
 #define MAX_I2O_MODULES                64
 
 /* How many OSMs can register themselves for device status updates? */
 #define I2O_MAX_MANAGERS       4
 
-#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+#include <asm/semaphore.h>     /* Needed for MUTEX init macros */
 #include <linux/config.h>
 #include <linux/notifier.h>
-#include <linux/ioport.h>
 #include <asm/atomic.h>
 
 /*
- * message structures
+ *     Message structures
  */
 struct i2o_message
 {
@@ -43,7 +43,7 @@ struct i2o_message
        u16     size;
        u32     target_tid:12;
        u32     init_tid:12;
-       u32     function:8;     
+       u32     function:8;
        u32     initiator_context;
        /* List follows */
 };
@@ -54,18 +54,19 @@ struct i2o_message
  */
 struct i2o_device
 {
-       i2o_lct_entry lct_data; /* Device LCT information */
-       u32 flags;              
-       int i2oversion;         /* I2O version supported. Actually there
-                                * should be high and low version */
+       i2o_lct_entry lct_data;         /* Device LCT information */
+       u32 flags;
+       int i2oversion;                 /* I2O version supported. Actually
+                                        * there should be high and low
+                                        * version */
 
-       struct proc_dir_entryproc_entry;      /* /proc dir */
+       struct proc_dir_entry *proc_entry;      /* /proc dir */
 
        /* Primary user */
        struct i2o_handler *owner;
 
        /* Management users */
-       struct i2o_handler *managers[I2O_MAX_MANAGERS];         
+       struct i2o_handler *managers[I2O_MAX_MANAGERS];
        int num_managers;
 
        struct i2o_controller *controller;      /* Controlling IOP */
@@ -76,24 +77,23 @@ struct i2o_device
 
 /*
  *     Resource data for each PCI I2O controller
- */            
+ */
 struct i2o_pci
 {
-       struct pci_dev *pdev;   /* PCI device */
-       int irq;
-       int queue_buggy:1;      /* Don't send a lot of messages */
-       int short_req:1;        /* Use small block sizes        */
-       int dpt:1;              /* Don't quiesce                */
+       int             irq;
+       int             queue_buggy:1;  /* Don't send a lot of messages */
+       int             short_req:1;    /* Use small block sizes        */
+       int             dpt:1;          /* Don't quiesce                */
 #ifdef CONFIG_MTRR
-       int mtrr_reg0;
-       int mtrr_reg1;
+       int             mtrr_reg0;
+       int             mtrr_reg1;
 #endif
 };
 
 /*
  * Transport types supported by I2O stack
  */
-#define I2O_TYPE_PCI           0x01            /* PCI I2O controller */        
+#define I2O_TYPE_PCI           0x01            /* PCI I2O controller */
 
 
 /*
@@ -101,6 +101,8 @@ struct i2o_pci
  */
 struct i2o_controller
 {
+       struct pci_dev *pdev;           /* PCI device */
+
        char name[16];
        int unit;
        int type;
@@ -126,35 +128,35 @@ struct i2o_controller
 
        u32 mem_offset;                         /* MFA offset */
        u32 mem_phys;                           /* MFA physical */
-       
+
        int battery:1;                          /* Has a battery backup */
        int io_alloc:1;                         /* An I/O resource was allocated */
        int mem_alloc:1;                        /* A memory resource was allocated */
-       
+
        struct resource io_resource;            /* I/O resource allocated to the IOP */
        struct resource mem_resource;           /* Mem resource allocated to the IOP */
 
-       struct proc_dir_entryproc_entry;      /* /proc dir */
+       struct proc_dir_entry *proc_entry;      /* /proc dir */
 
-       union
-       {                                       /* Bus information */
+       union {                                 /* Bus information */
                struct i2o_pci pci;
        } bus;
 
        /* Bus specific destructor */
-       void (*destructor)(struct i2o_controller *);            
+       void (*destructor)(struct i2o_controller *);
 
        /* Bus specific attach/detach */
-       int (*bind)(struct i2o_controller *, struct i2o_device *);      
+       int (*bind)(struct i2o_controller *, struct i2o_device *);
 
        /* Bus specific initiator */
        int (*unbind)(struct i2o_controller *, struct i2o_device *);
 
        /* Bus specific enable/disable */
-       void (*bus_enable)(struct i2o_controller *c);
-       void (*bus_disable)(struct i2o_controller *c);
+       void (*bus_enable)(struct i2o_controller *);
+       void (*bus_disable)(struct i2o_controller *);
 
-       void *page_frame;               /* Message buffers */
+       void *page_frame;                       /* Message buffers */
+       dma_addr_t page_frame_map;              /* Cache map */
 };
 
 /*
@@ -169,7 +171,8 @@ struct i2o_controller
 struct i2o_handler
 {
        /* Message reply handler */
-       void (*reply)(struct i2o_handler *, struct i2o_controller *, struct i2o_message *);
+       void (*reply)(struct i2o_handler *, struct i2o_controller *,
+                     struct i2o_message *);
 
        /* New device notification handler */
        void (*new_dev_notify)(struct i2o_controller *, struct i2o_device *);
@@ -181,7 +184,7 @@ struct i2o_handler
        void (*reboot_notify)(void);
 
        char *name;             /* OSM name */
-       int context;    /* Low 8 bits of the transaction info */
+       int context;            /* Low 8 bits of the transaction info */
        u32 class;              /* I2O classes that this driver handles */
        /* User data follows */
 };
@@ -201,12 +204,12 @@ struct i2o_core_func_table
 {
        int     (*install)(struct i2o_controller *);
        int     (*activate)(struct i2o_controller *);
-       struct  i2o_controller* (*find)(int);
+       struct i2o_controller *(*find)(int);
        void    (*unlock)(struct i2o_controller *);
-       void    (*run_queue)(struct i2o_controller *c);
+       void    (*run_queue)(struct i2o_controller * c);
        int     (*delete)(struct i2o_controller *);
 };
-#endif // MODULE
+#endif /* MODULE */
 
 /*
  * I2O System table entry
@@ -222,9 +225,9 @@ struct i2o_sys_tbl_entry
        u32     iop_id:12;
        u32     reserved2:20;
        u16     seg_num:12;
-       u16     i2o_version:4;
-       u8      iop_state;
-       u8      msg_type;
+       u16     i2o_version:4;
+       u8      iop_state;
+       u8      msg_type;
        u16     frame_size;
        u16     reserved3;
        u32     last_changed;
@@ -235,14 +238,14 @@ struct i2o_sys_tbl_entry
 
 struct i2o_sys_tbl
 {
-       u8      num_entries;
-       u8      version;
-       u16     reserved1;
+       u8      num_entries;
+       u8      version;
+       u16     reserved1;
        u32     change_ind;
        u32     reserved2;
        u32     reserved3;
        struct i2o_sys_tbl_entry iops[0];
-};     
+};
 
 /*
  *     Messenger inlines
@@ -265,9 +268,9 @@ static inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
 
 static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 Val)
 {
-       *c->reply_port= Val;
+       *c->reply_port = Val;
 }
+
 
 static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
 {
@@ -283,13 +286,13 @@ static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 Val)
 static inline void i2o_post_message(struct i2o_controller *c, u32 m)
 {
        /* The second line isnt spurious - thats forcing PCI posting */
-       I2O_POST_WRITE32(c,m);
+       I2O_POST_WRITE32(c, m);
        (void) I2O_IRQ_READ32(c);
 }
 
 static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
 {
-       I2O_REPLY_WRITE32(c,m);
+       I2O_REPLY_WRITE32(c, m);
 }
 
 extern struct i2o_controller *i2o_find_controller(int);
@@ -304,23 +307,27 @@ extern int i2o_remove_handler(struct i2o_handler *);
 extern int i2o_claim_device(struct i2o_device *, struct i2o_handler *);
 extern int i2o_release_device(struct i2o_device *, struct i2o_handler *);
 extern int i2o_device_notify_on(struct i2o_device *, struct i2o_handler *);
-extern int i2o_device_notify_off(struct i2o_device *, struct i2o_handler *);
+extern int i2o_device_notify_off(struct i2o_device *,
+                                struct i2o_handler *);
 
 extern int i2o_post_this(struct i2o_controller *, u32 *, int);
 extern int i2o_post_wait(struct i2o_controller *, u32 *, int, int);
-extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int, void *, void *);
-
-extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *, int);
-extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *, int);
-extern int i2o_query_table(int, struct i2o_controller *, int, int, int, void *,
-                          int, void *, int);
-extern int i2o_clear_table(struct i2o_controller *, int, int); 
-extern int i2o_row_add_table(struct i2o_controller *, int, int, int, void *,
-                            int);
-extern int i2o_issue_params(int, struct i2o_controller *, int, void *,
-                           int, void *, int); 
-
-extern int i2o_event_register(struct i2o_controller *, u32, u32, u32, u32); 
+extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int,
+                            void *, void *);
+
+extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *,
+                           int);
+extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *,
+                         int);
+extern int i2o_query_table(int, struct i2o_controller *, int, int, int,
+                          void *, int, void *, int);
+extern int i2o_clear_table(struct i2o_controller *, int, int);
+extern int i2o_row_add_table(struct i2o_controller *, int, int, int,
+                            void *, int);
+extern int i2o_issue_params(int, struct i2o_controller *, int, void *, int,
+                           void *, int);
+
+extern int i2o_event_register(struct i2o_controller *, u32, u32, u32, u32);
 extern int i2o_event_ack(struct i2o_controller *, u32 *);
 
 extern void i2o_report_status(const char *, const char *, u32 *);
@@ -339,7 +346,7 @@ extern int i2o_delete_controller(struct i2o_controller *);
 
 /*
  * Executive Class
- */ 
+ */
 #define        I2O_CMD_ADAPTER_ASSIGN          0xB3
 #define        I2O_CMD_ADAPTER_READ            0xB2
 #define        I2O_CMD_ADAPTER_RELEASE         0xB5
@@ -524,7 +531,7 @@ extern int i2o_delete_controller(struct i2o_controller *);
 #define        I2O_CLAIM_MANAGEMENT                                    0x02000000
 #define        I2O_CLAIM_AUTHORIZED                                    0x03000000
 #define        I2O_CLAIM_SECONDARY                                     0x04000000
+
 /* Message header defines for VersionOffset */
 #define I2OVER15       0x0001
 #define I2OVER20       0x0002
index bc3d02f4d24933ebd6b8a2c675a8e9443b5d42a5..f39bcabdf7c016422681e778ac78774c654bcc34 100644 (file)
 #define PCI_DEVICE_ID_INTEL_82801BA_9  0x244b
 #define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c
 #define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e
+#define PCI_DEVICE_ID_INTEL_82801CA_0  0x2480
+#define PCI_DEVICE_ID_INTEL_82801CA_2  0x2482
+#define PCI_DEVICE_ID_INTEL_82801CA_3  0x2483
+#define PCI_DEVICE_ID_INTEL_82801CA_4  0x2484
+#define PCI_DEVICE_ID_INTEL_82801CA_5  0x2485
+#define PCI_DEVICE_ID_INTEL_82801CA_6  0x2486
+#define PCI_DEVICE_ID_INTEL_82801CA_7  0x2487
+#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
+#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
+#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
 #define PCI_DEVICE_ID_INTEL_82810_MC1  0x7120
 #define PCI_DEVICE_ID_INTEL_82810_IG1  0x7121
 #define PCI_DEVICE_ID_INTEL_82810_MC3  0x7122
index 29a0c691883c3bf27ff3c8528c752b915786ffa6..48aab6f712a33b8c69df12f17b4e6dcc6aac3ea3 100644 (file)
 #define SONYPI_EVENT_FNKEY_S                   29
 #define SONYPI_EVENT_FNKEY_B                   30
 #define SONYPI_EVENT_BLUETOOTH_PRESSED         31
-#define SONYPI_EVENT_PKEY_P1                    32
-#define SONYPI_EVENT_PKEY_P2                    33
-#define SONYPI_EVENT_PKEY_P3                    34
+#define SONYPI_EVENT_PKEY_P1                   32
+#define SONYPI_EVENT_PKEY_P2                   33
+#define SONYPI_EVENT_PKEY_P3                   34
+#define SONYPI_EVENT_BACK_PRESSED              35
+#define SONYPI_EVENT_LID_CLOSED                        36
+#define SONYPI_EVENT_LID_OPENED                        37
 
 
 /* brightness etc. ioctls */
index 059329c7759e33007b415cad102083ccddca2e95..440ba7df43eca3de13d1a3d09dcce9668410cc36 100644 (file)
 #define write_unlock_irqrestore(lock, flags)   do { write_unlock(lock); local_irq_restore(flags); } while (0)
 #define write_unlock_irq(lock)                 do { write_unlock(lock); local_irq_enable();       } while (0)
 #define write_unlock_bh(lock)                  do { write_unlock(lock); local_bh_enable();        } while (0)
+#define spin_trylock_bh(lock)                  ({ int __r; local_bh_disable();\
+                                               __r = spin_trylock(lock);      \
+                                               if (!__r) local_bh_enable();   \
+                                               __r; })
 
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
index 736d617f0a687c01f7876cf54909125de873f31f..c2a0b4b2394887fc5a120dd0f6f2b38a838bcbe6 100644 (file)
@@ -37,8 +37,8 @@
 #define UDF_PREALLOCATE
 #define UDF_DEFAULT_PREALLOC_BLOCKS    8
 
-#define UDFFS_DATE                     "2001/06/13"
-#define UDFFS_VERSION                  "0.9.4.1"
+#define UDFFS_DATE                     "2001/10/10"
+#define UDFFS_VERSION                  "0.9.5"
 
 #if !defined(UDFFS_RW)
 
index c07d6678708dbd2b92efe1dd82f893aab56435eb..fdb078d9dbc61a5fe361b030f5f96f08c33f7492 100644 (file)
 #if !defined(_LINUX_UDF_FS_SB_H)
 #define _LINUX_UDF_FS_SB_H
 
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
 #pragma pack(1)
 
 #define UDF_MAX_BLOCK_LOADED   8
@@ -89,7 +85,7 @@ struct udf_sb_info
        __u16                   s_partition;
 
        /* Sector headers */
-       __u32                   s_session;
+       __s32                   s_session;
        __u32                   s_anchor[4];
        __u32                   s_lastblock;
 
index 007639810d75b1a0233c35641169f67812c3fcf2..9ae491f509d5ef71b6629f417b12ea308b1fc4ee 100644 (file)
@@ -185,7 +185,7 @@ struct video_capture
 {
        __u32   x,y;                    /* Offsets into image */
        __u32   width, height;          /* Area to capture */
-       __u16   decimation;             /* Decimation divder */
+       __u16   decimation;             /* Decimation divider */
        __u16   flags;                  /* Flags for capture */
 #define VIDEO_CAPTURE_ODD              0       /* Temporal */
 #define VIDEO_CAPTURE_EVEN             1
@@ -378,14 +378,4 @@ struct video_code
 #define VID_HARDWARE_MEYE      32      /* Sony Vaio MotionEye cameras */
 #define VID_HARDWARE_CPIA2     33
 
-/*
- *     Initialiser list
- */
-struct video_init
-{
-       char *name;
-       int (*init)(struct video_init *);
-};
-
 #endif
index f6382c4ba696e7f404c26a2580b539d418eb6101..3a0f7476dbb360a00e2b64e9474226e34e87fb46 100644 (file)
 #include <sys/types.h>
 #endif
 
-typedef u_short        socket_t;
+#ifdef __arm__
+typedef u_int   ioaddr_t;
+#else
 typedef u_short        ioaddr_t;
+#endif
+
+typedef u_short        socket_t;
 typedef u_int  event_t;
 typedef u_char cisdata_t;
 typedef u_short        page_t;
index 02f3b8e872533e2871b8878385a75bad8aab6cbf..17c534cfc50c4b144eb0d130dc41549edcadd8f4 100644 (file)
@@ -30,6 +30,8 @@
 #ifndef _LINUX_SS_H
 #define _LINUX_SS_H
 
+#include <pcmcia/cs_types.h>
+
 /* Definitions for card status flags for GetStatus */
 #define SS_WRPROT      0x0001
 #define SS_CARDLOCK    0x0002
@@ -52,6 +54,7 @@ typedef struct socket_cap_t {
     u_int      features;
     u_int      irq_mask;
     u_int      map_size;
+    ioaddr_t   io_offset;
     u_char     pci_irq;
     struct pci_dev *cb_dev;
     struct bus_operations *bus;
@@ -101,7 +104,7 @@ typedef struct pccard_io_map {
     u_char     map;
     u_char     flags;
     u_short    speed;
-    u_short    start, stop;
+    ioaddr_t   start, stop;
 } pccard_io_map;
 
 typedef struct pccard_mem_map {
index 9ae4b60109011016fe773e6a36809e2b9002d77c..4fbd1924c833f6e6cbf0808ec2ad443c2b7b87a7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/unistd.h>
 #include <linux/signal.h>
+#include <linux/completion.h>
 
 static DECLARE_TASK_QUEUE(tq_context);
 static DECLARE_WAIT_QUEUE_HEAD(context_task_wq);
@@ -63,7 +64,7 @@ int schedule_task(struct tq_struct *task)
        return ret;
 }
 
-static int context_thread(void *dummy)
+static int context_thread(void *startup)
 {
        struct task_struct *curtask = current;
        DECLARE_WAITQUEUE(wait, curtask);
@@ -79,6 +80,8 @@ static int context_thread(void *dummy)
        recalc_sigpending(curtask);
        spin_unlock_irq(&curtask->sigmask_lock);
 
+       complete((struct completion *)startup);
+
        /* Install a handler so SIGCLD is delivered */
        sa.sa.sa_handler = SIG_IGN;
        sa.sa.sa_flags = 0;
@@ -150,7 +153,10 @@ void flush_scheduled_tasks(void)
        
 int start_context_thread(void)
 {
-       kernel_thread(context_thread, NULL, CLONE_FS | CLONE_FILES);
+       static struct completion startup __initdata = COMPLETION_INITIALIZER(startup);
+
+       kernel_thread(context_thread, &startup, CLONE_FS | CLONE_FILES);
+       wait_for_completion(&startup);
        return 0;
 }
 
index 7a920ffc969457ef716ad9100b189d81b3ad5b52..80882368e8eaaf769e8f6cc1905679367f29759a 100644 (file)
@@ -223,6 +223,7 @@ EXPORT_SYMBOL(posix_lock_file);
 EXPORT_SYMBOL(posix_test_lock);
 EXPORT_SYMBOL(posix_block_lock);
 EXPORT_SYMBOL(posix_unblock_lock);
+EXPORT_SYMBOL(posix_locks_deadlock);
 EXPORT_SYMBOL(locks_mandatory_area);
 EXPORT_SYMBOL(dput);
 EXPORT_SYMBOL(have_submounts);
index 3f8e0a763698ad4c601955cbc54e96a9202aee84..5a0152e46a8b11874f81a77dcea7a624cdf74769 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
+#include <linux/kernel.h>
 
 #include <asm/div64.h>
 
@@ -519,36 +520,44 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
        int num = 0;
        int qualifier;
        int base;
-       unsigned int field_width;
+       int field_width = -1;
        int is_sign = 0;
 
-       for (; *fmt; fmt++) {
+       while(*fmt && *str) {
                /* skip any white space in format */
+               /* white space in format matchs any amount of
+                * white space, including none, in the input.
+                */
                if (isspace(*fmt)) {
-                       continue;
+                       while (isspace(*fmt))
+                               ++fmt;
+                       while (isspace(*str))
+                               ++str;
                }
 
                /* anything that is not a conversion must match exactly */
-               if (*fmt != '%') {
+               if (*fmt != '%' && *fmt) {
                        if (*fmt++ != *str++)
-                               return num;
+                               break;
                        continue;
                }
+
+               if (!*fmt)
+                       break;
                ++fmt;
                
                /* skip this conversion.
                 * advance both strings to next white space
                 */
                if (*fmt == '*') {
-                       while (!isspace(*fmt))
+                       while (!isspace(*fmt) && *fmt)
                                fmt++;
-                       while(!isspace(*str))
+                       while (!isspace(*str) && *str)
                                str++;
                        continue;
                }
 
                /* get field width */
-               field_width = 0xffffffffUL;
                if (isdigit(*fmt))
                        field_width = skip_atoi(&fmt);
 
@@ -561,25 +570,32 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
                base = 10;
                is_sign = 0;
 
-               switch(*fmt) {
+               if (!*fmt || !*str)
+                       break;
+
+               switch(*fmt++) {
                case 'c':
                {
                        char *s = (char *) va_arg(args,char*);
+                       if (field_width == -1)
+                               field_width = 1;
                        do {
                                *s++ = *str++;
-                       } while(field_width-- > 0);
+                       } while(field_width-- > 0 && *str);
                        num++;
                }
                continue;
                case 's':
                {
                        char *s = (char *) va_arg(args, char *);
+                       if(field_width == -1)
+                               field_width = INT_MAX;
                        /* first, skip leading white space in buffer */
                        while (isspace(*str))
                                str++;
 
                        /* now copy until next white space */
-                       while (!isspace(*str) && field_width--) {
+                       while (*str && !isspace(*str) && field_width--) {
                                *s++ = *str++;
                        }
                        *s = '\0';
@@ -621,6 +637,9 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
                while (isspace(*str))
                        str++;
 
+               if (!*str || !isdigit(*str))
+                       break;
+
                switch(qualifier) {
                case 'h':
                        if (is_sign) {
index a997ef33650c2494b1f0d55059f411f554302041..170691dee9e50ff44b48d569d76e703107871a9f 100644 (file)
@@ -667,8 +667,7 @@ int add_to_page_cache_unique(struct page * page,
 static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
 static int page_cache_read(struct file * file, unsigned long offset)
 {
-       struct inode *inode = file->f_dentry->d_inode;
-       struct address_space *mapping = inode->i_mapping;
+       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
        struct page **hash = page_hash(mapping, offset);
        struct page *page; 
 
@@ -1589,8 +1588,8 @@ struct page * filemap_nopage(struct vm_area_struct * area,
 {
        int error;
        struct file *file = area->vm_file;
-       struct inode *inode = file->f_dentry->d_inode;
-       struct address_space *mapping = inode->i_mapping;
+       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+       struct inode *inode = mapping->host;
        struct page *page, **hash, *old_page;
        unsigned long size, pgoff;
 
@@ -1851,15 +1850,14 @@ static struct vm_operations_struct generic_file_vm_ops = {
 
 int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
 {
-       struct inode *inode = file->f_dentry->d_inode;
+       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+       struct inode *inode = mapping->host;
 
        if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) {
-               if (!inode->i_mapping->a_ops->writepage)
+               if (!mapping->a_ops->writepage)
                        return -EINVAL;
        }
-       if (!inode->i_sb || !S_ISREG(inode->i_mode))
-               return -EACCES;
-       if (!inode->i_mapping->a_ops->readpage)
+       if (!mapping->a_ops->readpage)
                return -ENOEXEC;
        UPDATE_ATIME(inode);
        vma->vm_ops = &generic_file_vm_ops;
index 18210bb45a9f68c46a50b4a3438e45926428cb7c..a5c004adf7df2df6796671b95d563048522327c6 100644 (file)
@@ -95,7 +95,7 @@
  */
 
 /* This is used by platforms which might be able to set the ipconfig
- * variabled using firmware environment vars.  If this is set, it will
+ * variables using firmware environment vars.  If this is set, it will
  * ignore such firmware variables.
  */
 int ic_set_manually __initdata = 0;            /* IPconfig parameters set manually */
index 3aabeff42924c8c622cf7aa43c32748ad64e76d1..2610e85d8e4c221f539aafc58a94c1fae716b685 100644 (file)
@@ -30,7 +30,7 @@ static int                    rpc_task_id;
 /*
  * We give RPC the same get_free_pages priority as NFS
  */
-#define GFP_RPC                        GFP_NFS
+#define GFP_RPC                        GFP_NOFS
 
 static void                    __rpc_default_timer(struct rpc_task *task);
 static void                    rpciod_killall(void);
@@ -744,7 +744,7 @@ __rpc_schedule(void)
  * for readahead):
  *
  *   sync user requests:       GFP_KERNEL
- *   async requests:           GFP_RPC         (== GFP_NFS)
+ *   async requests:           GFP_RPC         (== GFP_NOFS)
  *   swap requests:            GFP_ATOMIC      (or new GFP_SWAPPER)
  */
 void *
@@ -1068,8 +1068,6 @@ rpciod(void *ptr)
 
        strcpy(current->comm, "rpciod");
 
-       current->flags |= PF_MEMALLOC;
-
        dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
        while (rpciod_users) {
                if (signalled()) {
index 9016889325f213a8809dce77dbf95d4eacd0e1f3..99168eb0c12639cfedf53ab7b18d618195540a12 100644 (file)
@@ -202,3 +202,4 @@ cleanup_module(void)
        rpc_proc_exit();
 }
 #endif
+MODULE_LICENSE("GPL");