Date: Mon, 1 Jun 1998 15:59:31 +0200 (MET DST)
From: Geert Uytterhoeven <geert@thomas.kotnet.org>
To: Linux/m68k <linux-m68k@lists.linux-m68k.org>
Subject: L68K: More patches for 2.1.101
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: Geert Uytterhoeven <geert@thomas.kotnet.org>


More patches, relative to Linux/m68k 2.1.101-current

Frame buffer devices:

  - vesafb for VESA compliant graphics boards on PC (Gerd Knorr
    <kraxel@cs.tu-berlin.de>)
  - mdafb for dual-headed MDA on PC (Andrew Apted
    <ajapted@netspace.net.au>)
  - monochrome attributes with vgafb (Andrew Apted)
  - README.fb
  - smem_start and mmio_start are now `physical' (whatever that may mean
    on m68k :-) adresses
  - atyfb: better distinction among different Mach64 classes
  - fix logo drawing on little endian machines (Petr Vandrovec
    <VANDROVE@vc.cvut.cz>)
  - optimized fast_memmove for ia32 (Petr Vandrovec <VANDROVE@vc.cvut.cz>)

Abstract console driver:

  - compatcon: the thingy that should allow the SPARC/MIPS guys to use the
    abstract console driver without completely reworking their current
    console drivers.

Block devices: (will be sent to Mark Lord)

  - Missing pieces of Mac IDE support (Michael Schmitz)
  - Integrate m68k block device support in drivers/block/Config.in
    (requested by Mark Lord)
  - Put low-level IDE drivers in separate files in drivers/block
    (requested by Mark Lord)
  - add m68k specific entries for hwif_chipset_t (not used yet)
  - Configure.help update

diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/arch/m68k/config.in m68k/arch/m68k/config.in
--- m68k-current/arch/m68k/config.in	Thu May 14 21:34:07 1998
+++ m68k/arch/m68k/config.in	Mon Jun  1 12:13:13 1998
@@ -92,72 +92,7 @@
 bool '/proc/hardware support' CONFIG_PROC_HARDWARE
 endmenu
 
-#
-# Block device driver configuration
-#
-mainmenu_option next_comment
-comment 'Floppy, IDE, and other block devices'
-
-if [ "$CONFIG_AMIGA" = "y" ]; then
-  tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY
-fi
-if [ "$CONFIG_ATARI" = "y" ]; then
-  tristate 'Atari floppy support' CONFIG_ATARI_FLOPPY
-fi
-if [ "$CONFIG_MAC" = "y" ]; then
-  tristate 'Macintosh IWM floppy support' CONFIG_MAC_FLOPPY_IWM
-fi
-#Normal floppy disk support' CONFIG_BLK_DEV_FD
-
-tristate 'Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE
-if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
-  dep_tristate '   Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE
-  dep_tristate '   Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE
-  dep_tristate '   Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE
-  dep_tristate '   Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
-  dep_tristate '   SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE
-  if [ "$CONFIG_AMIGA" = "y" ]; then
-    bool '   Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      bool '   Buddha/Catweasel IDE interface support' CONFIG_BLK_DEV_BUDDHA
-      bool '   Amiga IDE Doubler support' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE
-    fi
-  fi
-  if [ "$CONFIG_ATARI" = "y" ]; then
-    bool '   Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE
-  fi
-  if [ "$CONFIG_MAC" = "y" ]; then
-    bool '   Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE
-  fi
-fi
-if [ "$CONFIG_AMIGA" = "y" ]; then
-  tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
-fi
-if [ "$CONFIG_ATARI" = "y" ]; then
-  tristate 'Atari ACSI support' CONFIG_ATARI_ACSI
-  if [ "$CONFIG_ATARI_ACSI" != "n" ]; then
-    comment 'Some devices (e.g. CD jukebox) support multiple LUNs'
-    bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN
-    dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
-  fi
-fi
-
-comment 'Additional Block Devices'
-
-tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
-bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
-if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
-  tristate '   Linear (append) mode' CONFIG_MD_LINEAR
-  tristate '   RAID-0 (striping) mode' CONFIG_MD_STRIPED
-fi
-if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then
-  bool '      Boot support (linear, striped)' CONFIG_MD_BOOT
-fi
-tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
-if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
-  bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
-fi
-endmenu
+source drivers/block/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
   source net/Config.in
@@ -205,6 +140,9 @@
     bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI
 #    bool 'Cyberstorm Mk III SCSI support' CONFIG_CYBERSTORMIII_SCSI
 #    bool 'GVP Turbo 040/060 SCSI support' CONFIG_GVP_TURBO_SCSI
+  fi
+  if [ "$CONFIG_MAC" = "y" ]; then
+    bool '   Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE
   fi
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/char/fbmem.c m68k/drivers/char/fbmem.c
--- m68k-current/drivers/char/fbmem.c	Thu May 14 21:34:33 1998
+++ m68k/drivers/char/fbmem.c	Mon Jun  1 11:23:01 1998
@@ -92,9 +92,6 @@
 #ifdef CONFIG_FB_MAC
 	{ "macfb", macfb_init, macfb_setup },
 #endif
-#ifdef CONFIG_FB_HP300
-	{ "hpfb", hpfb_init, hpfb_setup },
-#endif
 #ifdef CONFIG_FB_CYBER
 	{ "cyber", cyberfb_init, cyberfb_setup },
 #endif
@@ -125,6 +122,15 @@
 #ifdef CONFIG_FB_VGA
 	{ "vga", vgafb_init, vgafb_setup },
 #endif 
+#ifdef CONFIG_FB_VESA
+	{ "vesa", vesafb_init, vesafb_setup },
+#endif 
+#ifdef CONFIG_FB_MDA
+	{ "mda", mdafb_init, mdafb_setup },
+#endif 
+#ifdef CONFIG_FB_HP300
+	{ "hpfb", hpfb_init, hpfb_setup },
+#endif 
 #ifdef CONFIG_GSP_RESOLVER
 	/* Not a real frame buffer device... */
 	{ "resolver", NULL, resolver_video_setup },
@@ -189,11 +195,11 @@
 	char *base_addr;
 	ssize_t copy_size;
 
-	if (! fb)
+	if (! fb || ! info->disp)
 		return -ENODEV;
 
 	fb->fb_get_fix(&fix,PROC_CONSOLE(), info);
-	base_addr=(char *) fix.smem_start;
+	base_addr=info->disp->screen_base;
 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
 	copy_to_user(buf, base_addr+p, copy_size);
 	*ppos += copy_size;
@@ -212,10 +218,11 @@
 	char *base_addr;
 	ssize_t copy_size;
 
-	if (! fb)
+	if (! fb || ! info->disp)
 		return -ENODEV;
+
 	fb->fb_get_fix(&fix, PROC_CONSOLE(), info);
-	base_addr=(char *) fix.smem_start;
+	base_addr=info->disp->screen_base;
 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
 	copy_from_user(base_addr+p, buf, copy_size); 
 	file->f_pos += copy_size;
@@ -375,11 +382,6 @@
 	}
 	if ((vma->vm_end - vma->vm_start + vma->vm_offset) > len)
 		return -EINVAL;
-#ifdef __powerpc__
-	start = iopa(start);
-#else
-	start = __pa(start);
-#endif
 	vma->vm_offset += start;
 	if (vma->vm_offset & ~PAGE_MASK)
 		return -ENXIO;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/Config.in m68k/drivers/video/Config.in
--- m68k-current/drivers/video/Config.in	Thu May 14 21:34:48 1998
+++ m68k/drivers/video/Config.in	Mon Jun  1 11:23:00 1998
@@ -55,6 +55,13 @@
   if [ "$ARCH" = "i386" -o "$ARCH" = "alpha" -o "$ARCH" = "ppc" ]; then
     bool 'VGA chipset support (text only)' CONFIG_FB_VGA
   fi
+  if [ "$ARCH" = "i386" ]; then
+    bool 'VESA VGA graphics console' CONFIG_FB_VESA
+    define_bool CONFIG_VIDEO_SELECT y
+  fi
+  if [ "$ARCH" = "i386" ]; then
+    tristate 'MDA dual-headed support' CONFIG_FB_MDA
+  fi
   tristate 'Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL
 
   bool 'Advanced low level driver options' CONFIG_FBCON_ADVANCED
@@ -102,12 +109,14 @@
 	 "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_OF" = "m" -o \
 	 "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_MAC" = "m" -o  \
 	 "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_TGA" = "m" -o \
+	 "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VESA" = "m" -o \
 	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_CFB8 y
     fi
     if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
 	 "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_ATY" = "m" -o \
 	 "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_MAC" = "m" -o \
+	 "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VESA" = "m" -o \
 	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_CFB16 y
     fi
@@ -116,6 +125,7 @@
     fi
     if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
 	 "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_ATY" = "m" -o \
+	 "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VESA" = "m" -o \
 	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_CFB32 y
     fi
@@ -125,7 +135,8 @@
       define_bool CONFIG_FBCON_CFB4 y
       define_bool CONFIG_FBCON_CFB8 y
     fi
-    if [ "$CONFIG_FB_VGA" = "y" -o "$CONFIG_FB_VGA" = "m" ]; then
+    if [ "$CONFIG_FB_VGA" = "y" -o "$CONFIG_FB_VGA" = "m" -o \
+	 "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_MDA" = "m" ]; then
       define_bool CONFIG_FBCON_VGA y
     fi
   fi
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/Makefile m68k/drivers/video/Makefile
--- m68k-current/drivers/video/Makefile	Thu May 14 21:34:48 1998
+++ m68k/drivers/video/Makefile	Mon Jun  1 11:23:00 1998
@@ -96,6 +96,18 @@
 L_OBJS += vgafb.o
 endif
 
+ifeq ($(CONFIG_FB_VESA),y)
+L_OBJS += vesafb.o
+endif
+
+ifeq ($(CONFIG_FB_MDA),y)
+L_OBJS += mdafb.o
+else
+  ifeq ($(CONFIG_FB_MDA),m)
+  M_OBJS += mdafb.o
+  endif
+endif
+
 ifeq ($(CONFIG_FB_VIRGE),y)
 L_OBJS += virgefb.o
 else
@@ -180,8 +192,16 @@
 
 ifdef CONFIG_ABSTRACT_CONSOLE
 ifdef CONFIG_VGA_CONSOLE
+ifndef CONFIG_FB_VGA
 L_OBJS := $(L_OBJS) vgacon.o
 endif
+endif
+endif
+
+# Console Wrapper
+
+ifdef CONFIG_ABSCON_COMPAT
+L_OBJS := $(L_OBJS) compatcon.o
 endif
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/README.fb m68k/drivers/video/README.fb
--- m68k-current/drivers/video/README.fb	Thu Jan  1 01:00:00 1970
+++ m68k/drivers/video/README.fb	Mon Jun  1 11:23:00 1998
@@ -0,0 +1,87 @@
+
+This is a first start for some documentation about frame buffer device
+internals. It should probably move to the Documentation directory some day.
+You may want to read Documentation/m68k/framebuffer.txt also.
+
+Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>, 30 Mar 1998
+
+--------------------------------------------------------------------------------
+
+	    ***  STRUCTURES USED BY THE FRAME BUFFER DEVICE API  ***
+
+The following structures play a role in the game of frame buffer devices. They
+are defined in <linux/fb.h>.
+
+1. Outside the kernel (user space)
+
+  - struct fb_fix_screeninfo
+
+    Device independent unchangeable information about a frame buffer device and
+    a specific video mode. This can be obtained using the FBIOGET_FSCREENINFO
+    ioctl.
+
+  - struct fb_var_screeninfo
+
+    Device independent changeable information about a frame buffer device and a
+    specific video mode. This can be obtained using the FBIOGET_VSCREENINFO
+    ioctl, and updated with the FBIOPUT_VSCREENINFO ioctl. If you want to pan
+    the screen only, you can use the FBIOPAN_DISPLAY ioctl.
+
+  - struct fb_cmap
+
+    Device independent colormap information. You can get and set the colormap
+    using the FBIOGETCMAP and FBIOPUTCMAP ioctls.
+
+
+2. Inside the kernel
+
+  - struct fb_info
+
+    Generic information, API and low level information about a specific frame
+    buffer device instance (slot number, board address, ...).
+
+  - struct `par'
+
+    Device dependent information that uniquely defines the video mode for this
+    particular piece of hardware.
+
+  - struct display
+
+    Interface between the frame buffer device and the console driver.
+
+
+--------------------------------------------------------------------------------
+
+	    ***  VISUALS USED BY THE FRAME BUFFER DEVICE API  ***
+
+
+Monochrome (FB_VISUAL_MONO01 and FB_VISUAL_MONO10)
+-------------------------------------------------
+Each pixel is either black or white.
+
+
+Pseudo color (FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR)
+---------------------------------------------------------------------
+The whole pixel value is fed through a programmable lookup table that has one
+color (including red, green, and blue intensities) for each possible pixel
+value, and that color is displayed.
+
+
+True color (FB_VISUAL_TRUECOLOR)
+--------------------------------
+The pixel value is broken up into red, green, and blue fields, each of which 
+are looked up in separate red, green, and blue lookup tables.
+
+
+Direct color (FB_VISUAL_DIRECTCOLOR)
+------------------------------------
+The pixel value is broken up into red, green, and blue fields. This is what
+most people mean when then say `true color'.
+
+
+Grayscale displays
+------------------
+Grayscale and static grayscale are special variants of pseudo color and static
+pseudo color, where the red, green and blue components are always equal to
+each other.
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/S3triofb.c m68k/drivers/video/S3triofb.c
--- m68k-current/drivers/video/S3triofb.c	Thu May 14 21:34:48 1998
+++ m68k/drivers/video/S3triofb.c	Mon Jun  1 11:23:00 1998
@@ -41,7 +41,7 @@
 #include <asm/pci-bridge.h>
 #include <linux/pci.h>
 #ifdef CONFIG_FB_COMPAT_XPMAC
-#include <linux/vc_ioctl.h>
+#include <asm/vc_ioctl.h>
 #endif
 
 #include "fbcon.h"
@@ -66,7 +66,7 @@
 static struct fb_info fb_info;
 static struct { u_char red, green, blue, pad; } palette[256];
 static char s3trio_name[16] = "S3Trio ";
-
+static char *s3trio_base;
 
 static struct fb_fix_screeninfo fb_fix;
 static struct fb_var_screeninfo fb_var = { 0, };
@@ -453,39 +453,42 @@
 
     s3trio_init(dp);
     address = 0xc6000000;
-    fb_fix.smem_start = ioremap(address,64*1024*1024);
+    s3trio_base = ioremap(address,64*1024*1024);
+    fb_fix.smem_start = (char *)address;
     fb_fix.type = FB_TYPE_PACKED_PIXELS;
     fb_fix.type_aux = 0;
     fb_fix.accel = FB_ACCEL_S3_TRIO64;
+    fb_fix.mmio_start = (char *)address+0x1000000;
+    fb_fix.mmio_len = 0x1000000;
 
     fb_fix.xpanstep = 1;
     fb_fix.ypanstep = 1;
 
     s3trio_resetaccel();
 
-    mem_out8(0x30, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0x2d, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0x2e, fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0x30, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0x2d, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0x2e, s3trio_base+0x1008000 + 0x03D4);
 
-    mem_out8(0x50, fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0x50, s3trio_base+0x1008000 + 0x03D4);
 
     /* disable HW cursor */
 
-    mem_out8(0x39, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0xa0, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x39, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0xa0, s3trio_base+0x1008000 + 0x03D5);
 
-    mem_out8(0x45, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
 
-    mem_out8(0x4e, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x4e, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
 
-    mem_out8(0x4f, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x4f, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
 
     /* init HW cursor */
 
-    CursorBase = (u_long *)(fb_fix.smem_start + 2*1024*1024 - 0x400);
+    CursorBase = (u_long *)(s3trio_base + 2*1024*1024 - 0x400);
 	for (i = 0; i < 8; i++) {
 		*(CursorBase  +(i*4)) = 0xffffff00;
 		*(CursorBase+1+(i*4)) = 0xffff0000;
@@ -500,27 +503,27 @@
 	}
 
 
-    mem_out8(0x4c, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(((2*1024 - 1)&0xf00)>>8, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x4c, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(((2*1024 - 1)&0xf00)>>8, s3trio_base+0x1008000 + 0x03D5);
 
-    mem_out8(0x4d, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8((2*1024 - 1) & 0xff, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x4d, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8((2*1024 - 1) & 0xff, s3trio_base+0x1008000 + 0x03D5);
 
-    mem_out8(0x45, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_in8(fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
+    mem_in8(s3trio_base+0x1008000 + 0x03D4);
 
-    mem_out8(0x4a, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0x80, fb_fix.smem_start+0x1008000 + 0x03D5);
-    mem_out8(0x80, fb_fix.smem_start+0x1008000 + 0x03D5);
-    mem_out8(0x80, fb_fix.smem_start+0x1008000 + 0x03D5);
-
-    mem_out8(0x4b, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0x00, fb_fix.smem_start+0x1008000 + 0x03D5);
-    mem_out8(0x00, fb_fix.smem_start+0x1008000 + 0x03D5);
-    mem_out8(0x00, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x4a, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
+    mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
+    mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
+
+    mem_out8(0x4b, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
+    mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
+    mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
 
-    mem_out8(0x45, fb_fix.smem_start+0x1008000 + 0x03D4);
-    mem_out8(0, fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
+    mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
 
     /* setup default color table */
 
@@ -533,7 +536,7 @@
 
     s3trio_setcolreg(255, 56, 100, 160, 0, NULL /* not used */);
     s3trio_setcolreg(254, 0, 0, 0, 0, NULL /* not used */);
-    memset((char *)fb_fix.smem_start, 0, 640*480);
+    memset((char *)s3trio_base, 0, 640*480);
 
 #if 0
     Trio_RectFill(0, 0, 90, 90, 7, 1);
@@ -563,7 +566,7 @@
     disp.cmap.start = 0;
     disp.cmap.len = 0;
     disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
-    disp.screen_base = fb_fix.smem_start;
+    disp.screen_base = s3trio_base;
     disp.visual = fb_fix.visual;
     disp.type = fb_fix.type;
     disp.type_aux = fb_fix.type_aux;
@@ -657,10 +660,9 @@
 {
     unsigned char x;
 
-    mem_out8(0x1, fb_fix.smem_start+0x1008000 + 0x03c4);
-    x = mem_in8(fb_fix.smem_start+0x1008000 + 0x03c5);
-    mem_out8((x & (~0x20)) | (blank << 5),
-	     fb_fix.smem_start+0x1008000 + 0x03c5);
+    mem_out8(0x1, s3trio_base+0x1008000 + 0x03c4);
+    x = mem_in8(s3trio_base+0x1008000 + 0x03c5);
+    mem_out8((x & (~0x20)) | (blank << 5), s3trio_base+0x1008000 + 0x03c5);
 }
 
     /*
@@ -707,10 +709,10 @@
     palette[regno].green = green;
     palette[regno].blue = blue;
 
-    mem_out8(regno,fb_fix.smem_start+0x1008000 + 0x3c8);
-    mem_out8((red & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
-    mem_out8((green & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
-    mem_out8((blue & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
+    mem_out8(regno,s3trio_base+0x1008000 + 0x3c8);
+    mem_out8((red & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
+    mem_out8((green & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
+    mem_out8((blue & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
 
     return 0;
 }
@@ -785,7 +787,7 @@
 
         do
         {
-		status = mem_in16(fb_fix.smem_start + 0x1000000 + 0x9AE8);
+		status = mem_in16(s3trio_base + 0x1000000 + 0x9AE8);
 	}  while (!(status & fifo));
 
 }
@@ -796,7 +798,7 @@
 
         do
         {
-		status = mem_in16(fb_fix.smem_start + 0x1000000 + 0x9AE8);
+		status = mem_in16(s3trio_base + 0x1000000 + 0x9AE8);
 	}  while (status & 0x200);
 
 }
@@ -864,18 +866,18 @@
 
 static void Trio_MoveCursor(u_short x, u_short y) {
 
-	mem_out8(0x39, fb_fix.smem_start + 0x1008000 + 0x3d4);
-	mem_out8(0xa0, fb_fix.smem_start + 0x1008000 + 0x3d5);
+	mem_out8(0x39, s3trio_base + 0x1008000 + 0x3d4);
+	mem_out8(0xa0, s3trio_base + 0x1008000 + 0x3d5);
 
-	mem_out8(0x46, fb_fix.smem_start + 0x1008000 + 0x3d4);
-	mem_out8((x & 0x0700) >> 8, fb_fix.smem_start + 0x1008000 + 0x3d5);
-	mem_out8(0x47, fb_fix.smem_start + 0x1008000 + 0x3d4);
-	mem_out8(x & 0x00ff, fb_fix.smem_start + 0x1008000 + 0x3d5);
-
-	mem_out8(0x48, fb_fix.smem_start + 0x1008000 + 0x3d4);
-	mem_out8((y & 0x0700) >> 8, fb_fix.smem_start + 0x1008000 + 0x3d5);
-	mem_out8(0x49, fb_fix.smem_start + 0x1008000 + 0x3d4);
-	mem_out8(y & 0x00ff, fb_fix.smem_start + 0x1008000 + 0x3d5);
+	mem_out8(0x46, s3trio_base + 0x1008000 + 0x3d4);
+	mem_out8((x & 0x0700) >> 8, s3trio_base + 0x1008000 + 0x3d5);
+	mem_out8(0x47, s3trio_base + 0x1008000 + 0x3d4);
+	mem_out8(x & 0x00ff, s3trio_base + 0x1008000 + 0x3d5);
+
+	mem_out8(0x48, s3trio_base + 0x1008000 + 0x3d4);
+	mem_out8((y & 0x0700) >> 8, s3trio_base + 0x1008000 + 0x3d5);
+	mem_out8(0x49, s3trio_base + 0x1008000 + 0x3d4);
+	mem_out8(y & 0x00ff, s3trio_base + 0x1008000 + 0x3d5);
 
 }
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/atafb.c m68k/drivers/video/atafb.c
--- m68k-current/drivers/video/atafb.c	Mon May  4 20:25:25 1998
+++ m68k/drivers/video/atafb.c	Mon Jun  1 11:23:00 1998
@@ -2467,7 +2467,7 @@
 	atafb_get_var(&var, con, info);
 	if (con == -1)
 		con=0;
-	display->screen_base = (u_char *)fix.smem_start;
+	display->screen_base = fix.smem_start;
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/aty.h m68k/drivers/video/aty.h
--- m68k-current/drivers/video/aty.h	Mon Jun  1 11:33:51 1998
+++ m68k/drivers/video/aty.h	Mon Jun  1 11:23:00 1998
@@ -691,18 +691,31 @@
 
 /* ATI PCI constants */
 #define PCI_ATI_VENDOR_ID	0x1002
-#define PCI_MACH64_GX		0x4758
-#define PCI_MACH64_CX		0x4358
-#define PCI_MACH64_CT		0x4354
-#define PCI_MACH64_ET		0x4554
+
+/* mach64GX family */
+#define PCI_MACH64_GX		0x4758	/* mach64GX (ATI888GX00) */
+#define PCI_MACH64_CX		0x4358	/* mach64CX (ATI888CX00) */
+
+/* mach64CT family */
+#define PCI_MACH64_CT		0x4354	/* mach64CT (ATI264CT) */
+#define PCI_MACH64_ET		0x4554	/* mach64ET (ATI264ET) */
+
+/* mach64CT family / mach64VT class */
+#define PCI_MACH64_VT		0x5654	/* mach64VT (ATI264VT) */
+#define PCI_MACH64_VTB		0x5655	/* mach64VTB (ATI264VTB) */
+#define PCI_MACH64_VT4		0x5656	/* mach64VT4 (ATI264VT4) */
+
+/* mach64CT family / mach64GT (3D RAGE) class */
 #define PCI_MACH64_GB		0x4742	/* RAGE PRO, BGA, AGP 1x and 2x */
 #define PCI_MACH64_GD		0x4744	/* RAGE PRO, BGA, AGP 1x only */
 #define PCI_MACH64_GI		0x4749	/* RAGE PRO, BGA, PCI33 only */
 #define PCI_MACH64_GP		0x4750	/* RAGE PRO, PQFP, PCI33, full 3D */
 #define PCI_MACH64_GQ		0x4751	/* RAGE PRO, PQFP, PCI33, limited 3D */
 #define PCI_MACH64_GT		0x4754	/* 3D RAGE II/II+ */
-#define PCI_MACH64_LG		0x4c47	/* 3D RAGE LT */
-#define PCI_MACH64_VT		0x5654	/* 264VT */
+#define PCI_MACH64_GTB		0x4755	/* 3D II+ */
+#define PCI_MACH64_GTC		0x4756	/* 3D RAGE IIC */
+#define PCI_MACH64_LT		0x4c47	/* 3D RAGE LT */
+
 
 /* CONFIG_CHIP_ID register constants */
 #define CFG_CHIP_TYPE		0x0000FFFF
@@ -712,19 +725,33 @@
 #define CFG_CHIP_FND_ID		0x38000000
 #define CFG_CHIP_MINOR		0xC0000000
 
+
 /* Chip IDs read from CONFIG_CHIP_ID */
-#define MACH64_GX_ID		0xD7
-#define MACH64_CX_ID		0x57
-#define MACH64_CT_ID		0x4354
-#define MACH64_ET_ID		0x4554
-#define MACH64_GB_ID		0x4742	/* RAGE PRO, BGA, AGP 1x and 2x */
-#define MACH64_GD_ID		0x4744	/* RAGE PRO, BGA, AGP 1x only */
-#define MACH64_GI_ID		0x4749	/* RAGE PRO, BGA, PCI33 only */
-#define MACH64_GP_ID		0x4750	/* RAGE PRO, PQFP, PCI33, full 3D */
-#define MACH64_GQ_ID		0x4751	/* RAGE PRO, PQFP, PCI33, limited 3D */
-#define MACH64_GT_ID		0x4754	/* 3D RAGE II/II+ */
-#define MACH64_LG_ID		0x4c47	/* 3D RAGE LT */
-#define MACH64_VT_ID		0x5654	/* 264VT */
+
+/* mach64GX family */
+#define MACH64_GX_ID		0xD7	/* mach64GX (ATI888GX00) */
+#define MACH64_CX_ID		0x57	/* mach64CX (ATI888CX00) */
+
+/* mach64CT family */
+#define MACH64_CT_ID		PCI_MACH64_CT
+#define MACH64_ET_ID		PCI_MACH64_ET
+
+/* mach64CT family / mach64VT class */
+#define MACH64_VT_ID		PCI_MACH64_VT
+#define MACH64_VTB_ID		PCI_MACH64_VTB
+#define MACH64_VT4_ID		PCI_MACH64_VT4
+
+/* mach64CT family / mach64GT (3D RAGE) class */
+#define MACH64_GB_ID		PCI_MACH64_GB
+#define MACH64_GD_ID		PCI_MACH64_GD
+#define MACH64_GI_ID		PCI_MACH64_GI
+#define MACH64_GP_ID		PCI_MACH64_GP
+#define MACH64_GQ_ID		PCI_MACH64_GQ
+#define MACH64_GT_ID		PCI_MACH64_GT
+#define MACH64_GTB_ID		PCI_MACH64_GTB
+#define MACH64_GTC_ID		PCI_MACH64_GTC
+#define MACH64_LT_ID		PCI_MACH64_LT
+
 
 /* Mach64 major ASIC revisions */
 #define MACH64_ASIC_NEC_VT_A3		0x08
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/atyfb.c m68k/drivers/video/atyfb.c
--- m68k-current/drivers/video/atyfb.c	Mon Jun  1 11:33:51 1998
+++ m68k/drivers/video/atyfb.c	Mon Jun  1 11:23:00 1998
@@ -241,9 +241,13 @@
 
 struct fb_info_aty {
     struct fb_info fb_info;
+    unsigned long ati_regbase_phys;
     unsigned long ati_regbase;
+    unsigned long frame_buffer_phys;
     unsigned long frame_buffer;
-    u32 chip_type;
+    u8 chip_class;
+    u8 pixclock_lim_8;	/* ps, <= 8 bpp */
+    u8 pixclock_lim_hi;	/* ps, > 8 bpp */
     u32 total_vram;
     struct aty_cmap_regs *aty_cmap_regs;
     struct { u8 red, green, blue, pad; } palette[256];
@@ -317,6 +321,46 @@
 	&aty_vt_reg_init_20
 };
 
+
+#define CLASS_GX	1
+#define CLASS_CT	2
+#define CLASS_VT	3
+#define CLASS_GT	4
+
+struct aty_features {
+    u16 pci_id;
+    u16 chip_type;
+    const char *name;
+    u8 chip_class;
+    u8 pixclock_lim_8;	/* MHz, <= 8 bpp (not sure about these limits!) */
+    u8 pixclock_lim_hi;	/* MHz, > 8 bpp (not sure about these limits!) */
+} aty_features[] __initdata = {
+    /* mach64GX family */
+    { 0x4758, 0x00d7, "mach64GX (ATI888GX00)", CLASS_GX, 135, 80 },
+    { 0x4358, 0x0057, "mach64CX (ATI888CX00)", CLASS_GX, 135, 80 },
+
+    /* mach64CT family */
+    { 0x4354, 0x4354, "mach64CT (ATI264CT)", CLASS_CT, 135, 80 },
+    { 0x4554, 0x4554, "mach64ET (ATI264ET)", CLASS_CT, 135, 80 },
+
+    /* mach64CT family / mach64VT class */
+    { 0x5654, 0x5654, "mach64VT (ATI264VT)", CLASS_VT, 160, 135 },
+    { 0x5655, 0x5655, "mach64VTB (ATI264VTB)", CLASS_VT, 160, 135 },
+    { 0x5656, 0x5656, "mach64VT4 (ATI264VT4)", CLASS_VT, 160, 135 },
+
+    /* mach64CT family / mach64GT (3D RAGE) class */
+    { 0x4742, 0x4742, "3D RAGE PRO (BGA, AGP)", CLASS_GT, 240, 240 },
+    { 0x4744, 0x4744, "3D RAGE PRO (BGA, AGP, 1x only)", CLASS_GT, 240, 240 },
+    { 0x4749, 0x4749, "3D RAGE PRO (BGA, PCI)", CLASS_GT, 240, 240 },
+    { 0x4750, 0x4750, "3D RAGE PRO (PQFP, PCI)", CLASS_GT, 240, 240 },
+    { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)", CLASS_GT, 240, 240 },
+    { 0x4754, 0x4754, "3D RAGE (GT)", CLASS_GT, 200, 200 },
+    { 0x4755, 0x4755, "3D RAGE II+ (GTB)", CLASS_GT, 200, 200 },
+    { 0x4756, 0x4756, "3D RAGE IIC", CLASS_GT, 200, 200 },
+    { 0x4c47, 0x4c47, "3D RAGE LT", CLASS_GT, 200, 200 },
+};
+
+
     /*
      *  Interface used by the world
      */
@@ -647,16 +691,20 @@
 {
     int v = vmode - 1;
 
-    switch (info->chip_type) {
-	case MACH64_GT_ID:
-	    return aty_gt_reg_init[v];
+    switch (info->chip_class) {
+	case CLASS_GX:
+	    return aty_gx_reg_init[v];
 	    break;
-	case MACH64_VT_ID:
+	case CLASS_CT:
+	case CLASS_VT:
 	    return aty_vt_reg_init[v];
 	    break;
-	default: /* default to MACH64_GX_ID */
-	    return aty_gx_reg_init[v];
+	case CLASS_GT:
+	    return aty_gt_reg_init[v];
 	    break;
+	default:
+	    /* should NOT happen */
+	    return NULL;
     }
 }
 
@@ -737,7 +785,7 @@
 
 static void atyfb_set_par(struct atyfb_par *par, struct fb_info_aty *info)
 {
-    int i, hres;
+    int i, j, hres;
     struct aty_regvals *init = get_aty_struct(par->hw.gx.vmode, info);
     int vram_type = aty_ld_le32(CONFIG_STAT0, info) & 7;
 
@@ -747,18 +795,31 @@
     info->current_par = *par;
     hres = vmode_attrs[par->hw.gx.vmode-1].hres;
 
-    if (info->chip_type != MACH64_GT_ID) {
+    if (info->chip_class != CLASS_GT) {
 	i = aty_ld_le32(CRTC_GEN_CNTL, info);
 	aty_st_le32(CRTC_GEN_CNTL, i | CRTC_EXT_DISP_EN, info);
     }
 
-    if (info->chip_type == MACH64_GX_ID) {
+    if (info->chip_class == CLASS_GX) {
 	i = aty_ld_le32(GEN_TEST_CNTL, info);
 	aty_st_le32(GEN_TEST_CNTL, i | GEN_OVR_OUTPUT_EN, info);
     }
 
-    switch (info->chip_type) {
-	case MACH64_VT_ID:
+    switch (info->chip_class) {
+	case CLASS_GX:
+	    RGB514_Program(par->hw.gx.cmode, info);
+	    wait_for_idle(info);
+	    aty_st_514(0x06, 0x02, info);
+	    aty_st_514(0x10, 0x01, info);
+	    aty_st_514(0x70, 0x01, info);
+	    aty_st_514(0x8f, 0x1f, info);
+	    aty_st_514(0x03, 0x00, info);
+	    aty_st_514(0x05, 0x00, info);
+	    aty_st_514(0x20, init->clock_val[0], info);
+	    aty_st_514(0x21, init->clock_val[1], info);
+	    break;
+	case CLASS_CT:
+	case CLASS_VT:
 	    aty_st_pll(VPLL_CNTL, 0xb5, info);
 	    aty_st_pll(PLL_REF_DIV, 0x2d, info);
 	    aty_st_pll(PLL_GEN_CNTL, 0x14, info);
@@ -773,7 +834,7 @@
 	    aty_st_pll(PLL_TEST_CTRL, 0x0, info);
 	    aty_st_pll(PLL_TEST_COUNT, 0x0, info);
 	    break;
-	case MACH64_GT_ID:
+	case CLASS_GT:
 	    if (vram_type == 5) {
 		aty_st_pll(MPLL_CNTL, 0xcd, info);
 		aty_st_pll(VPLL_CNTL,
@@ -810,18 +871,6 @@
 		aty_st_pll(VFC_CNTL, 0x1b, info);
 	    }
 	    break;
-	default:
-	    RGB514_Program(par->hw.gx.cmode, info);
-	    wait_for_idle(info);
-	    aty_st_514(0x06, 0x02, info);
-	    aty_st_514(0x10, 0x01, info);
-	    aty_st_514(0x70, 0x01, info);
-	    aty_st_514(0x8f, 0x1f, info);
-	    aty_st_514(0x03, 0x00, info);
-	    aty_st_514(0x05, 0x00, info);
-	    aty_st_514(0x20, init->clock_val[0], info);
-	    aty_st_514(0x21, init->clock_val[1], info);
-	    break;
     }
 
     aty_ld_8(DAC_REGS, info);	/* clear counter */
@@ -840,90 +889,92 @@
 
     set_off_pitch(par, info);
 
-    if (info->chip_type == MACH64_GT_ID) {
-	aty_st_le32(BUS_CNTL, 0x7b23a040, info);
-
-	/* need to set DSP values !! assume sdram */
-	i = init->crtc_gen_cntl[0] - (0x100000 * par->hw.gx.cmode);
-	if ( vram_type == 5 )
-	    i = init->crtc_gen_cntl[1] - (0x100000 * par->hw.gx.cmode);
-	aty_st_le32(DSP_CONFIG, i, info);
-
-	i = aty_ld_le32(MEM_CNTL, info) & MEM_SIZE_ALIAS;
-	if ( vram_type == 5 ) {
-	    i |= ((1 * par->hw.gx.cmode) << 26) | 0x4215b0;
-	    aty_st_le32(DSP_ON_OFF,
-			sgram_dsp[par->hw.gx.vmode-1][par->hw.gx.cmode], info);
-
-	    /* aty_st_le32(CLOCK_CNTL, 8192, info); */
-	} else {
-	    i |= ((1 * par->hw.gx.cmode) << 26) | 0x300090;
-	    aty_st_le32(DSP_ON_OFF, init->mem_cntl[par->hw.gx.cmode], info);
-	}
+    switch (info->chip_class) {
+	case CLASS_GX:
+	    /* The magic constant below translates into:
+	     * 5  = No RDY delay, 1 wait st for mem write, increment during
+	     *      burst transfer
+	     * 9  = DAC access delayed, 1 wait state for DAC
+	     * 0  = Disables interupts for FIFO errors
+	     * e  = Allows FIFO to generate 14 wait states before generating
+	     *      error
+	     * 1  = DAC snooping disabled, ROM disabled
+	     * 0  = ROM page at 0 (disabled so doesn't matter)
+	     * f  = 15 ROM wait states (disabled so doesn't matter)
+	     * f  = 15 BUS wait states (I'm not sure this applies to PCI bus
+	     *      types)
+	     * at some point it would be good to experiment with bench marks to
+	     * if we can gain some speed by fooling with the wait states etc.
+	     */
+	    aty_st_le32(BUS_CNTL, 0x890e20f1 /* 0x590e10ff */, info);
+	    j = 0x47012100;
+	    j = 0x47052100;
+	    break;
+
+	case CLASS_CT:
+	case CLASS_VT:
+	    aty_st_le32(BUS_CNTL, 0x680000f9, info);
+	    switch (info->total_vram) {
+		case 0x00100000:
+		    aty_st_le32(MEM_CNTL, vt_mem_cntl[0][par->hw.gx.cmode],
+				info);
+		    break;
+		case 0x00200000:
+		    aty_st_le32(MEM_CNTL, vt_mem_cntl[1][par->hw.gx.cmode],
+				info);
+		    break;
+		case 0x00400000:
+		    aty_st_le32(MEM_CNTL, vt_mem_cntl[2][par->hw.gx.cmode],
+				info);
+		    break;
+		default:
+		    i = aty_ld_le32(MEM_CNTL, info) & 0x000F;
+		    aty_st_le32(MEM_CNTL,
+				(init->mem_cntl[par->hw.gx.cmode] &
+				 0xFFFFFFF0) | i,
+				info);
+	    }
+	    j = 0x87010184;
+	    break;
 
-	aty_st_le32(MEM_CNTL, i, info);
-	aty_st_le32(EXT_MEM_CNTL, 0x5000001, info);
+	case CLASS_GT:
+	    aty_st_le32(BUS_CNTL, 0x7b23a040, info);
 
-	/* if (info->total_vram > 0x400000)	
-	    i |= 0x538; this not been verified on > 4Megs!! */
-    } else if (info->chip_type == MACH64_VT_ID) {
-	aty_st_le32(BUS_CNTL, 0x680000f9, info);
-	switch (info->total_vram) {
-	    case 0x00100000:
-		aty_st_le32(MEM_CNTL, vt_mem_cntl[0][par->hw.gx.cmode],
-			    info);
-		break;
-	    case 0x00200000:
-		aty_st_le32(MEM_CNTL, vt_mem_cntl[1][par->hw.gx.cmode],
+	    /* need to set DSP values !! assume sdram */
+	    i = init->crtc_gen_cntl[0] - (0x100000 * par->hw.gx.cmode);
+	    if ( vram_type == 5 )
+		i = init->crtc_gen_cntl[1] - (0x100000 * par->hw.gx.cmode);
+	    aty_st_le32(DSP_CONFIG, i, info);
+
+	    i = aty_ld_le32(MEM_CNTL, info) & MEM_SIZE_ALIAS;
+	    if ( vram_type == 5 ) {
+		i |= ((1 * par->hw.gx.cmode) << 26) | 0x4215b0;
+		aty_st_le32(DSP_ON_OFF,
+			    sgram_dsp[par->hw.gx.vmode-1][par->hw.gx.cmode],
 			    info);
-		break;
-	    case 0x00400000:
-		aty_st_le32(MEM_CNTL, vt_mem_cntl[2][par->hw.gx.cmode],
-			    info);
-		break;
-	    default:
-		i = aty_ld_le32(MEM_CNTL, info) & 0x000F;
-		aty_st_le32(MEM_CNTL,
-			    (init->mem_cntl[par->hw.gx.cmode] &
-			     0xFFFFFFF0) | i,
+
+		/* aty_st_le32(CLOCK_CNTL, 8192, info); */
+	    } else {
+		i |= ((1 * par->hw.gx.cmode) << 26) | 0x300090;
+		aty_st_le32(DSP_ON_OFF, init->mem_cntl[par->hw.gx.cmode],
 			    info);
-	}
-    } else /* not GT/VT => GX */ {
-	/* The magic constant below translates into:
-	 * 5  = No RDY delay, 1 wait st for mem write, increment during burst
-	 *	transfer
-	 * 9  = DAC access delayed, 1 wait state for DAC
-	 * 0  = Disables interupts for FIFO errors
-	 * e  = Allows FIFO to generate 14 wait states before generating error
-	 * 1  = DAC snooping disabled, ROM disabled
-	 * 0  = ROM page at 0 (disabled so doesn't matter)
-	 * f  = 15 ROM wait states (disabled so doesn't matter)
-	 * f  = 15 BUS wait states (I'm not sure this applies to PCI bus types)
-	 * at some point it would be good to experiment with bench marks to see
-	 * if we can gain some speed by fooling with the wait states etc.
-	 */
-	aty_st_le32(BUS_CNTL, 0x890e20f1 /* 0x590e10ff */, info);
-    }
+	    }
+	    aty_st_le32(MEM_CNTL, i, info);
+	    aty_st_le32(EXT_MEM_CNTL, 0x5000001, info);
 
-/* These magic constants are harder to figure out
-* on the vt chipset bit 2 set makes the screen brighter
-* and bit 15 makes the screen black! But nothing else
-* seems to matter for the vt DAC_CNTL
-*/
-    switch (info->chip_type) {
-	case MACH64_GT_ID:
-	    i = 0x86010102;
-	    break;
-	case MACH64_VT_ID:
-	    i = 0x87010184;
-	    break;
-	default:
-	    i = 0x47012100;
-	    i = 0x47052100;
+	    /* if (info->total_vram > 0x400000)	
+		i |= 0x538; this not been verified on > 4Megs!! */
+
+	    j = 0x86010102;
 	    break;
     }
 
-    aty_st_le32(DAC_CNTL, i, info);
+    /* These magic constants (variable j) are harder to figure out
+    * on the vt chipset bit 2 set makes the screen brighter
+    * and bit 15 makes the screen black! But nothing else
+    * seems to matter for the vt DAC_CNTL
+    */
+    aty_st_le32(DAC_CNTL, j, info);
     aty_st_8(DAC_MASK, 0xff, info);
 
     switch (par->hw.gx.cmode) {
@@ -937,7 +988,7 @@
 	    i = CRTC_PIX_WIDTH_8BPP; break;
     }
 
-    if (info->chip_type != MACH64_GT_ID) {
+    if (info->chip_class != CLASS_GT) {
 	aty_st_le32(CRTC_INT_CNTL, 0x00000002, info);
 	aty_st_le32(GEN_TEST_CNTL, GUI_ENGINE_ENABLE | BLOCK_WRITE_ENABLE,
 		    info);	/* gui_en block_en */
@@ -958,12 +1009,12 @@
 	display_info.pitch = par->vxres<<par->hw.gx.cmode;
 	display_info.mode = par->hw.gx.vmode;
 	strcpy(display_info.name, atyfb_name);
-	display_info.fb_address = info->frame_buffer;
-	if (info->chip_type == MACH64_VT_ID)
+	display_info.fb_address = info->frame_buffer_phys;
+	if (info->chip_class == CLASS_VT)
 	    display_info.fb_address += init->offset[par->hw.gx.cmode];
-	display_info.cmap_adr_address = iopa(info->aty_cmap_regs->windex);
-	display_info.cmap_data_address = iopa(info->aty_cmap_regs->lut);
-	display_info.disp_reg_address = iopa(info->ati_regbase);
+	display_info.cmap_adr_address = info->ati_regbase_phys+0xc0;
+	display_info.cmap_data_address = info->ati_regbase_phys+0xc1;
+	display_info.disp_reg_address = info->ati_regbase_phys;
     }
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 }
@@ -1004,8 +1055,8 @@
      *  FIXME: This will cause problems on non-GT chips, because the frame
      *  buffer must be aligned to a page
      */
-    fix->smem_start = (char *)info->frame_buffer;
-    if (info->chip_type == MACH64_VT_ID)
+    fix->smem_start = (char *)info->frame_buffer_phys;
+    if (info->chip_class == CLASS_VT)
 	fix->smem_start += init->offset[par->hw.gx.cmode];
     fix->smem_len = (u32)info->total_vram;
 
@@ -1019,11 +1070,35 @@
 	fix->smem_len = 0x800000-PAGE_SIZE;
 #endif
     /*
-     *  Reg Block 0 (CT-compatible block) is at ati_regbase
-     *  Reg Block 1 (multimedia extensions) is at ati_regbase-0x400
+     *  Reg Block 0 (CT-compatible block) is at ati_regbase_phys
+     *  Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400
      */
-    fix->mmio_start = (char *)(info->ati_regbase-0x400);
-    fix->mmio_len = 0x800;
+    switch (info->chip_class) {
+	case CLASS_GX:
+	    fix->mmio_start = (char *)info->ati_regbase_phys;
+	    fix->mmio_len = 0x400;
+	    fix->accel = FB_ACCEL_ATI_MACH64GX;
+	    break;
+	case CLASS_CT:
+	    fix->mmio_start = (char *)info->ati_regbase_phys;
+	    fix->mmio_len = 0x400;
+	    fix->accel = FB_ACCEL_ATI_MACH64CT;
+	    break;
+	case CLASS_VT:
+	    fix->mmio_start = (char *)(info->ati_regbase_phys-0x400);
+	    fix->mmio_len = 0x800;
+	    fix->accel = FB_ACCEL_ATI_MACH64VT;
+	    break;
+	case CLASS_GT:
+	    fix->mmio_start = (char *)(info->ati_regbase_phys-0x400);
+	    fix->mmio_len = 0x800;
+	    fix->accel = FB_ACCEL_ATI_MACH64GT;
+	    break;
+	default:
+	    fix->mmio_start = NULL;
+	    fix->mmio_len = 0;
+	    fix->accel = 0;
+    }
     fix->type = FB_TYPE_PACKED_PIXELS;
     fix->type_aux = 0;
     fix->line_length = par->vxres<<par->hw.gx.cmode;
@@ -1032,7 +1107,6 @@
     fix->ywrapstep = 0;
     fix->xpanstep = 8;
     fix->ypanstep = 1;
-    fix->accel = FB_ACCEL_ATI_MACH64;
 
     return 0;
 }
@@ -1108,9 +1182,9 @@
     /* Check if we know about the wanted video mode */
     init = get_aty_struct(par->hw.gx.vmode, info);
     if (init == NULL || init->crtc_h_sync_strt_wid[par->hw.gx.cmode] == 0 ||
-	(info->chip_type != MACH64_GT_ID &&
+	(info->chip_class != CLASS_GT &&
 	 init->crtc_gen_cntl[par->hw.gx.cmode] == 0) ||
-	(info->chip_type == MACH64_GT_ID &&
+	(info->chip_class == CLASS_GT &&
 	 (aty_ld_le32(CONFIG_STAT0, info) & 7) == 5 &&
 	 init->crtc_gen_cntl[1] == 0))
 	return -EINVAL;
@@ -1218,10 +1292,39 @@
 		(v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT);
 
     xtalin = 69841;	/* 14.31818 MHz */
-    switch (info->chip_type) {
-	case MACH64_GT_ID:
-	case MACH64_VT_ID:
-	    if (info->chip_type == MACH64_GT_ID) {
+    switch (info->chip_class) {
+	case CLASS_GX:
+	    {
+		/* haven't read the IBM RGB514 PDF yet, so just guesses */
+		static u32 gx_vclk[VMODE_MAX] = {
+		        0,	/* vmode  1 */	
+		        0,	/* vmode  2 */	
+		        0,	/* vmode  3 */	
+		        0,	/* vmode  4 */	
+		    39722,	/* vmode  5 (25.175 MHz) */
+		    33333,	/* vmode  6 (30 MHz) */
+		        0,	/* vmode  7 */	
+		        0,	/* vmode  8 */	
+		    27778,	/* vmode  9 (36 MHz) */
+		    25000,	/* vmode 10 (40 MHz) */
+		    20000,	/* vmode 11 (50 MHz) */
+		    20000,	/* vmode 12 (50 MHz) */
+		    17544,	/* vmode 13 (57 MHz) */
+		    15385,	/* vmode 14 (65 MHz) */
+		    13333,	/* vmode 15 (75 MHz) */
+		        0,	/* vmode 16 */	
+		    12821,	/* vmode 17 (78 MHz) */
+		    10000,	/* vmode 18 (100 MHz) */
+		     7937,	/* vmode 19 (126 MHz) */
+		     7407	/* vmode 20 (135 MHz) */
+		};
+		vclk = gx_vclk[vmode-1];
+	    }
+	    break;
+	case CLASS_CT:
+	case CLASS_GT:
+	case CLASS_VT:
+	    if (info->chip_class == CLASS_GT) {
 		pll_ref_div = 0x21;
 		vclk_post_div = init->offset[0];
 		vclk_fb_div = init->offset[1];
@@ -1251,34 +1354,6 @@
 	    }
 	    vclk /= 2*vclk_fb_div;
 	    break;
-	default: /* MACH64_GX_ID */
-	    {
-		/* haven't read the IBM RGB514 PDF yet, so just guesses */
-		static u32 gx_vclk[VMODE_MAX] = {
-		        0,	/* vmode  1 */	
-		        0,	/* vmode  2 */	
-		        0,	/* vmode  3 */	
-		        0,	/* vmode  4 */	
-		    39722,	/* vmode  5 (25.175 MHz) */
-		    33333,	/* vmode  6 (30 MHz) */
-		        0,	/* vmode  7 */	
-		        0,	/* vmode  8 */	
-		    27778,	/* vmode  9 (36 MHz) */
-		    25000,	/* vmode 10 (40 MHz) */
-		    20000,	/* vmode 11 (50 MHz) */
-		    20000,	/* vmode 12 (50 MHz) */
-		    17544,	/* vmode 13 (57 MHz) */
-		    15385,	/* vmode 14 (65 MHz) */
-		    13333,	/* vmode 15 (75 MHz) */
-		        0,	/* vmode 16 */	
-		    12821,	/* vmode 17 (78 MHz) */
-		    10000,	/* vmode 18 (100 MHz) */
-		     7937,	/* vmode 19 (126 MHz) */
-		     7407	/* vmode 20 (135 MHz) */
-		};
-		vclk = gx_vclk[vmode-1];
-	    }
-	    break;
     }
     var->pixclock = vclk;
 
@@ -1371,7 +1446,7 @@
 	    struct fb_fix_screeninfo fix;
 
 	    encode_fix(&fix, &par, info2);
-	    display->screen_base = fix.smem_start;
+	    display->screen_base = (char *)info2->frame_buffer;
 	    display->visual = fix.visual;
 	    display->type = fix.type;
 	    display->type_aux = fix.type_aux;
@@ -1496,120 +1571,44 @@
 
 __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
 {
+    u32 chip_id;
     u32 i;
     int j, k, err, sense;
     struct fb_var_screeninfo var;
     struct aty_regvals *init;
-    u8 asic, fnd;
+    const char *chipname = NULL;
+    u8 rev;
 
     info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
-    info->chip_type = (aty_ld_le32(CONFIG_CHIP_ID, info) & CFG_CHIP_TYPE);
-    asic = (aty_ld_le32(CONFIG_CHIP_ID, info) & CFG_CHIP_MAJOR)>>24;
-    fnd = (aty_ld_le32(CONFIG_CHIP_ID, info) & CFG_CHIP_FND_ID)>>27;
-    printk("atyfb: ");
-    switch (fnd) {
+    chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
+    for (j = 0; j < (sizeof(aty_features)/sizeof(*aty_features)); j++)
+	if (aty_features[j].chip_type == (chip_id & CFG_CHIP_TYPE)) {
+	    chipname = aty_features[j].name;
+	    info->chip_class = aty_features[j].chip_class;
+	    info->pixclock_lim_8 = 1000000/aty_features[j].pixclock_lim_8;
+	    info->pixclock_lim_hi = 1000000/aty_features[j].pixclock_lim_hi;
+	}
+    if (!chipname) {
+	printk("atyfb: Unknown Mach64 0x%04x\n", chip_id & CFG_CHIP_TYPE);
+	return 0;
+    } else
+	printk("atyfb: %s [", chipname);
+    rev = (chip_id & CFG_CHIP_REV)>>24;
+    switch ((rev>>3) & 7) {
 	case MACH64_FND_SGS:
-	    printk("SGS ");
+	    printk("SGS");
 	    break;
 	case MACH64_FND_NEC:
-	    printk("NEC ");
+	    printk("NEC");
 	    break;
 	case MACH64_FND_UMC:
-	    printk("UMC ");
-	    break;
-    }
-    switch (info->chip_type) {
-	case MACH64_GX_ID:
-	    printk("Mach64 GX");
-	    break;
-	case MACH64_CX_ID:
-	    printk("Mach64 CX");
-	    break;
-	case MACH64_CT_ID:
-	    printk("Mach64 CT");
-	    break;
-	case MACH64_ET_ID:
-	    printk("Mach64 ET");
-	    break;
-	case MACH64_GB_ID:
-	    printk("3D RAGE PRO AGP 1x/2x");
-	    goto RAGE_PRO;
-	case MACH64_GD_ID:
-	    printk("3D RAGE PRO AGP 1x");
-	    goto RAGE_PRO;
-	case MACH64_GI_ID:
-	case MACH64_GP_ID:
-	    printk("3D RAGE PRO PCI");
-	    goto RAGE_PRO;
-	case MACH64_GQ_ID:
-	    printk("RAGE PRO PCI");
-RAGE_PRO:   switch (asic) {
-		case MACH64_ASIC_UMC_R3B_D_P_A1:
-		    i = 1;
-		    goto UMC_R3B;
-		case MACH64_ASIC_UMC_R3B_D_P_A2:
-		    i = 2;
-		    goto UMC_R3B;
-		case MACH64_ASIC_UMC_R3B_D_P_A3:
-		    i = 3;
-		    goto UMC_R3B;
-		case MACH64_ASIC_UMC_R3B_D_P_A4:
-		    i = 4;
-UMC_R3B:	    printk(" UMC R3B/D/P-A%d", i);
-		    break;
-	    }
-	    break;
-	case MACH64_GT_ID:
-	    printk("3D RAGE II/II+");
-	    switch (asic) {
-		case MACH64_ASIC_SGS_GT_B1S1:
-		    printk(" SGS GT-B1S1");
-		    break;
-		case MACH64_ASIC_SGS_GT_B1S2:
-		    printk(" SGS GT-B1S2");
-		    break;
-		case MACH64_ASIC_UMC_GT_B2U1:
-		    printk(" UMC GT-B2U1");
-		    break;
-		case MACH64_ASIC_UMC_GT_B2U2:
-		    printk(" UMC GT-B2U2");
-		    break;
-		case MACH64_ASIC_UMC_GT_B2U3:
-		    printk(" UMC GT-B2U3");
-		    break;
-	    }
-	    break;
-	case MACH64_LG_ID:
-	    printk("3D RAGE LT");
-	    break;
-	case MACH64_VT_ID:
-	    printk("Mach64 VT");
-	    switch (asic) {
-		case MACH64_ASIC_NEC_VT_A3:
-		    printk(" NEC VT-A3");
-		    break;
-		case MACH64_ASIC_NEC_VT_A4:
-		    printk(" NEC VT-A4");
-		    break;
-		case MACH64_ASIC_SGS_VT_A4:
-		    printk(" SGS VT-A4");
-		    break;
-		case MACH64_ASIC_SGS_VT_B1S1:
-		    printk(" SGS VT-B1S1");
-		    break;
-		case MACH64_ASIC_UMC_VT_B2U3:
-		    printk(" UMC VT-B2U3");
-		    break;
-	    }
-	    break;
-	default:
-	    printk("Unknown Mach64");
+	    printk("UMC");
 	    break;
     }
-    printk("\n");
+    printk(" %c%d]\n", 'A'+(rev & 7), rev>>6);
 
     i = aty_ld_le32(MEM_CNTL, info);
-    if (info->chip_type != MACH64_GT_ID)
+    if (info->chip_class != CLASS_GT)
 	switch (i & MEM_SIZE_ALIAS) {
 	    case MEM_SIZE_512K:
 		info->total_vram = 0x80000;
@@ -1655,16 +1654,14 @@
 	    default:
 		info->total_vram = 0x80000;
 	}
-#ifdef CONFIG_ATARI /* this is definately not the wrong way to set this */
-    if((info->total_vram == 0x400000) || (info->total_vram == 0x800000))
-    {
-      /* protect GUI-regs if complete Aperture is VRAM */
-      info->total_vram -= 0x00001000;
+#ifdef CONFIG_ATARI	/* this is definately not the wrong way to set this */
+    if ((info->total_vram == 0x400000) || (info->total_vram == 0x800000)) {
+	/* protect GUI-regs if complete Aperture is VRAM */
+	info->total_vram -= 0x00001000;
     }
-    /*endif*/
 #endif
 
-#if 1
+#if 0
     printk("aty_init: regbase = %lx, frame_buffer = %lx, total_vram = %x\n",
 	   info->ati_regbase, info->frame_buffer, info->total_vram);
 #endif
@@ -1720,7 +1717,7 @@
 		     (default_vmode > VMODE_640_480_60));
     }
 
-    if (info->chip_type == MACH64_GT_ID &&
+    if (info->chip_class == CLASS_GT &&
 	(aty_ld_le32(CONFIG_STAT0, info) & 7) == 5
 	&& init->crtc_gen_cntl[1] == 0) {
 	    default_vmode = VMODE_640_480_67;
@@ -1728,18 +1725,19 @@
 	    init_par(&info->default_par, default_vmode, default_cmode);
     }
 
-    switch (info->chip_type) {
-	case MACH64_GX_ID:
+    switch (info->chip_class) {
+	case CLASS_GX:
 	    strcat(atyfb_name, "GX");
 	    break;
-	case MACH64_VT_ID:
+	case CLASS_CT:
+	    strcat(atyfb_name, "CT");
+	    break;
+	case CLASS_VT:
 	    strcat(atyfb_name, "VT");
 	    break;
-	case MACH64_GT_ID:
+	case CLASS_GT:
 	    strcat(atyfb_name, "GT");
 	    break;
-	default:
-	    break;
     }
     strcpy(info->fb_info.modename, atyfb_name);
     info->fb_info.node = -1;
@@ -1800,9 +1798,11 @@
 	info->frame_buffer = kernel_map(phys_vmembase[m64_num],
 					phys_size[m64_num],
 					KERNELMAP_NOCACHE_SER, &mem_start);
+	info->frame_buffer_phys = info->frame_buffer;
 	info->ati_regbase = kernel_map(phys_guiregbase[m64_num], 0x10000,
 				       KERNELMAP_NOCACHE_SER, &mem_start)
 			    +0xFC00ul;
+	info->ati_regbase_phys = info->ati_regbase;
 
 	if (!aty_init(info, "ISA bus")) {
 	    /* This is insufficient! kernel_map has added two large chunks!! */
@@ -1831,6 +1831,11 @@
 	info->ati_regbase = (unsigned long)ioremap(0x7ff000+
 						   dp->addrs[0].address,
 						   0x1000)+0xc00;
+	info->ati_regbase_phys = 0x7ff000+dp->addrs[0].address;
+	info->ati_regbase = (unsigned long)ioremap(info->ati_regbase_phys,
+						   0x1000);
+	info->ati_regbase_phys += 0xc00;
+	info->ati_regbase += 0xc00;
 
 	/* enable memory-space accesses using config-space command register */
 	if (pci_device_loc(dp, &bus, &devfn) == 0) {
@@ -1847,8 +1852,8 @@
 	/* Use the big-endian aperture */
 	addr += 0x800000;
 #endif
-	info->frame_buffer = (unsigned long)__ioremap(addr, 0x800000,
-						      _PAGE_WRITETHRU);
+	info->frame_buffer_phys = addr;
+	info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
 
 	if (!aty_init(info, dp->full_name)) {
 	    kfree(info);
@@ -2054,12 +2059,12 @@
     info2->palette[regno].green = green;
     info2->palette[regno].blue = blue;
     i = aty_ld_8(DAC_CNTL, info2) & 0xfc;
-    if (info2->chip_type == MACH64_GT_ID)
+    if (info2->chip_class == CLASS_GT)
 	i |= 0x2;	/*DAC_CNTL|0x2 turns off the extra brightness for gt*/
     aty_st_8(DAC_CNTL, i, info2);
     aty_st_8(DAC_REGS + DAC_MASK, 0xff, info2);
     eieio();
-    scale = ((info2->chip_type != MACH64_GX_ID) &&
+    scale = ((info2->chip_class != CLASS_GX) &&
 	     (info2->current_par.hw.gx.cmode == CMODE_16)) ? 3 : 0;
     info2->aty_cmap_regs->windex = regno << scale;
     eieio();
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/compatcon.c m68k/drivers/video/compatcon.c
--- m68k-current/drivers/video/compatcon.c	Thu Jan  1 01:00:00 1970
+++ m68k/drivers/video/compatcon.c	Mon Jun  1 11:23:00 1998
@@ -0,0 +1,354 @@
+/*
+ *  linux/drivers/video/compatcon.c -- Console wrapper
+ *
+ *	Created 26 Apr 1998 by Geert Uytterhoeven
+ *
+ *  This will be removed once there are frame buffer devices for all supported
+ *  graphics hardware
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/console_struct.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/linux_logo.h>
+
+#include <linux/console_compat.h>
+
+
+    /*
+     *  Interface used by the world
+     */
+
+static const char *compatcon_startup(void);
+static void compatcon_init(struct vc_data *conp);
+static void compatcon_deinit(struct vc_data *conp);
+static void compatcon_clear(struct vc_data *conp, int sy, int sx, int height,
+			    int width);
+static void compatcon_putc(struct vc_data *conp, int c, int ypos, int xpos);
+static void compatcon_putcs(struct vc_data *conp, const char *s, int count,
+			    int ypos, int xpos);
+static void compatcon_cursor(struct vc_data *conp, int mode);
+static void compatcon_scroll(struct vc_data *conp, int t, int b, int dir,
+			     int count);
+static void compatcon_bmove(struct vc_data *conp, int sy, int sx, int dy,
+			    int dx, int height, int width);
+static int compatcon_switch(struct vc_data *conp);
+static int compatcon_blank(int blank);
+static int compatcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
+static int compatcon_set_font(struct vc_data *conp, int w, int h, char *data);
+static int compatcon_set_palette(struct vc_data *conp, unsigned char *table);
+static int compatcon_scrolldelta(struct vc_data *conp, int lines);
+
+
+    /*
+     *  Internal routines
+     */
+
+#if 0
+static int compatcon_show_logo(void);
+#endif
+
+unsigned long video_num_columns;
+unsigned long video_num_lines;
+unsigned long video_size_row;
+unsigned char video_type;
+unsigned long video_mem_base;
+unsigned long video_mem_term;
+unsigned long video_screen_size;
+int can_do_color;
+
+extern void set_cursor(int currcons);
+extern void hide_cursor(void);
+extern int set_get_cmap(unsigned char *arg, int set);
+extern void set_palette(void);
+extern int set_get_font(unsigned char *arg, int set, int ch512);
+extern void set_vesa_blanking(unsigned long arg);
+extern void vesa_blank(void);
+extern void vesa_powerdown(void);
+extern int con_adjust_height(unsigned long fontheight);
+extern void con_type_init(const char **);
+extern void con_type_init_finish(void);
+
+#define BLANK	0x0020
+
+
+__initfunc(static const char *compatcon_startup(void))
+{
+    const char *display_desc = "????";
+
+    video_num_lines = ORIG_VIDEO_LINES;
+    video_num_columns = ORIG_VIDEO_COLS;
+    video_size_row = 2*video_num_columns;
+    video_screen_size = video_num_lines*video_size_row;
+
+    con_type_init(&display_desc);
+#if 0
+    if (!console_show_logo)
+	console_show_logo = compatcon_show_logo;
+#endif
+    return display_desc;
+}
+
+
+static void compatcon_init(struct vc_data *conp)
+{
+    static int first = 1;
+
+    conp->vc_cols = video_num_columns;
+    conp->vc_rows = video_num_lines;
+    conp->vc_can_do_color = can_do_color;
+    if (first) {
+	con_type_init_finish();
+	first = 0;
+    }
+}
+
+static void compatcon_deinit(struct vc_data *conp)
+{
+}
+
+
+static void compatcon_clear(struct vc_data *conp, int sy, int sx, int height,
+			    int width)
+{
+    int rows;
+    unsigned long dest;
+
+    if (console_blanked)
+	return;
+
+    dest = video_mem_base+sy*video_size_row+sx*2;
+    if (sx == 0 && width == video_num_columns)      
+	memsetw((void *)dest, conp->vc_video_erase_char, height*video_size_row);
+    else
+	for (rows = height; rows-- ; dest += video_size_row)
+	    memsetw((void *)dest, conp->vc_video_erase_char, width*2);
+}
+
+
+static void compatcon_putc(struct vc_data *conp, int c, int ypos, int xpos)
+{
+    u16 *p;
+
+    if (console_blanked)
+	return;
+
+    p = (u16 *)(video_mem_base+ypos*video_size_row+xpos*2);
+    scr_writew(conp->vc_attr << 8 | c, p);
+}
+
+
+static void compatcon_putcs(struct vc_data *conp, const char *s, int count,
+			    int ypos, int xpos)
+{
+    u16 *p;
+    u16 sattr;
+
+    if (console_blanked)
+	return;
+
+    p = (u16 *)(video_mem_base+ypos*video_size_row+xpos*2);
+    sattr = conp->vc_attr << 8;
+    while (count--)
+	scr_writew(sattr | ((int) (*s++) & 0xff), p++);
+}
+
+
+static void compatcon_cursor(struct vc_data *conp, int mode)
+{
+    switch (mode) {
+	case CM_ERASE:
+	    hide_cursor();
+	    break;
+
+	case CM_MOVE:
+	case CM_DRAW:
+	    set_cursor(conp->vc_num);
+	    break;
+    }
+}
+
+
+static void compatcon_scroll(struct vc_data *conp, int t, int b, int dir,
+			     int count)
+{
+    if (console_blanked)
+	return;
+
+    compatcon_cursor(conp, CM_ERASE);
+
+    switch (dir) {
+	case SM_UP:
+	    if (count > conp->vc_rows)	/* Maximum realistic size */
+		count = conp->vc_rows;
+	    compatcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
+	    compatcon_clear(conp, b-count, 0, count, conp->vc_cols);
+	    break;
+
+	case SM_DOWN:
+	    if (count > conp->vc_rows)	/* Maximum realistic size */
+		count = conp->vc_rows;
+	    /*
+	     *  Fixed bmove() should end Arno's frustration with copying?
+	     *  Confucius says:
+	     *	Man who copies in wrong direction, end up with trashed
+	     *	data
+	     */
+	    compatcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
+	    compatcon_clear(conp, t, 0, count, conp->vc_cols);
+	    break;
+
+	case SM_LEFT:
+	    compatcon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);
+	    compatcon_clear(conp, 0, b-count, conp->vc_rows, count);
+	    break;
+
+	case SM_RIGHT:
+	    compatcon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);
+	    compatcon_clear(conp, 0, t, conp->vc_rows, count);
+	    break;
+    }
+}
+
+
+static inline void memmovew(u16 *to, u16 *from, unsigned int count)
+{
+    if ((unsigned long)to < (unsigned long)from)
+	memcpyw(to, from, count);
+    else {
+	count /= 2;
+	to += count;
+	from += count;
+	while (count) {
+	    count--;
+	    scr_writew(scr_readw(--from), --to);
+	}
+    }
+}
+
+static void compatcon_bmove(struct vc_data *conp, int sy, int sx, int dy,
+			    int dx, int height, int width)
+{
+    unsigned long src, dst;
+    int rows;
+
+    if (console_blanked)
+	return;
+
+    if (sx == 0 && dx == 0 && width == video_num_columns) {
+	src = video_mem_base+sy*video_size_row;
+	dst = video_mem_base+dy*video_size_row;
+	memmovew((u16 *)dst, (u16 *)src, height*video_size_row);
+    } else if (dy < sy || (dy == sy && dx < sx)) {
+	src = video_mem_base+sy*video_size_row+sx*2;
+	dst = video_mem_base+dy*video_size_row+dx*2;
+	for (rows = height; rows-- ;) {
+	    memmovew((u16 *)dst, (u16 *)src, width*2);
+	    src += video_size_row;
+	    dst += video_size_row;
+	}
+    } else {
+	src = video_mem_base+(sy+height-1)*video_size_row+sx*2;
+	dst = video_mem_base+(dy+height-1)*video_size_row+dx*2;
+	for (rows = height; rows-- ;) {
+	    memmovew((u16 *)dst, (u16 *)src, width*2);
+	    src -= video_size_row;
+	    dst -= video_size_row;
+	}
+    }
+}
+
+
+static int compatcon_switch(struct vc_data *conp)
+{
+    return 0;
+}
+
+
+static int compatcon_blank(int blank)
+{
+    if (blank) {
+	set_vesa_blanking(blank-1);
+	if (blank-1 == 0)
+	    vesa_blank();
+	else
+	    vesa_powerdown();
+	return 0;
+    } else {
+	/* Tell console.c that it has to restore the screen itself */
+	return 1;
+    }
+    return 0;
+}
+
+
+static int compatcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+{
+    /* this is not supported: data already points to a kernel space copy */
+    return -ENOSYS;
+}
+
+
+static int compatcon_set_font(struct vc_data *conp, int w, int h, char *data)
+{
+    /* this is not supported: data already points to a kernel space copy */
+    return -ENOSYS;
+}
+
+static int compatcon_set_palette(struct vc_data *conp, unsigned char *table)
+{
+    if (console_blanked || vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+	return -EINVAL;
+    set_palette();
+    return 0;
+}
+
+static int compatcon_scrolldelta(struct vc_data *conp, int lines)
+{
+    /* TODO */
+    return -ENOSYS;
+}
+
+#if 0
+__initfunc(static int compatcon_show_logo( void ))
+{
+    int height = 0;
+    char *p;
+
+    printk(linux_serial_image);
+    for (p = linux_serial_image; *p; p++)
+	if (*p == '\n')
+	    height++;
+    return height;
+}
+#endif
+
+
+    /*
+     *  The console `switch' structure for the console wrapper
+     */
+
+struct consw compat_con = {
+    compatcon_startup, compatcon_init, compatcon_deinit, compatcon_clear,
+    compatcon_putc, compatcon_putcs, compatcon_cursor, compatcon_scroll,
+    compatcon_bmove, compatcon_switch, compatcon_blank, compatcon_get_font,
+    compatcon_set_font, compatcon_set_palette, compatcon_scrolldelta
+};
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/cyberfb.c m68k/drivers/video/cyberfb.c
--- m68k-current/drivers/video/cyberfb.c	Thu May 14 21:34:48 1998
+++ m68k/drivers/video/cyberfb.c	Mon Jun  1 11:23:00 1998
@@ -20,6 +20,7 @@
  * for more details.
  */
 
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -374,9 +375,9 @@
 {
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 	strcpy(fix->id, cyberfb_name);
-	fix->smem_start = (caddr_t)CyberMem;
+	fix->smem_start = (char *)CyberMem;
 	fix->smem_len = CyberSize;
-	fix->mmio_start = (unsigned char *)CyberRegs;
+	fix->mmio_start = (char *)CyberRegs;
 	fix->mmio_len = 0x10000;
 
 	fix->type = FB_TYPE_PACKED_PIXELS;
@@ -843,7 +844,7 @@
 	cyberfb_get_fix(&fix, con, info);
 	if (con == -1)
 		con = 0;
-	display->screen_base = (u_char *)fix.smem_start;
+	display->screen_base = fix.smem_start;
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/dnfb.c m68k/drivers/video/dnfb.c
--- m68k-current/drivers/video/dnfb.c	Mon May  4 20:25:27 1998
+++ m68k/drivers/video/dnfb.c	Mon Jun  1 11:23:00 1998
@@ -295,7 +295,7 @@
   if(con==-1) 
     con=0;
 
-   disp[con].screen_base = (u_char *)fix.smem_start;
+   disp[con].screen_base = fix.smem_start;
    disp[con].visual = fix.visual;
    disp[con].type = fix.type;
    disp[con].type_aux = fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/fbcon-vga.c m68k/drivers/video/fbcon-vga.c
--- m68k-current/drivers/video/fbcon-vga.c	Thu May 14 21:34:48 1998
+++ m68k/drivers/video/fbcon-vga.c	Mon Jun  1 11:23:00 1998
@@ -3,6 +3,7 @@
  *				       VGA characters/attributes
  *
  *	Created 28 Mar 1998 by Geert Uytterhoeven
+ *	Monochrome attributes added May 1998 by Andrew Apted
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License.  See the file COPYING in the main directory of this archive for
@@ -75,6 +76,24 @@
      *  VGA characters/attributes
      */
 
+static inline u16 fbcon_vga_attr(struct display *p,
+				 struct vc_data *conp)
+{
+	if (conp->vc_can_do_color) {
+		return conp->vc_attr << 8;
+	}
+
+        /* Underline and reverse-video are mutually exclusive on MDA.
+         * Since reverse-video is used for cursors and selected areas, 
+	 * it takes precedence.
+         */
+
+	return (attr_reverse(p, conp) ? 0x7000 :
+		(attr_underline(p, conp) ? 0x0100 : 0x0700)) |
+	       (attr_bold(p, conp) ? 0x0800 : 0) |
+	       (attr_blink(p, conp) ? 0x8000 : 0);
+}
+
 void fbcon_vga_setup(struct display *p)
 {
     p->next_line = p->line_length;
@@ -127,14 +146,14 @@
 		    int x)
 {
     u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
-    vga_writew(conp->vc_attr << 8 | c, dst);
+    vga_writew(fbcon_vga_attr(p, conp) | (c & 0xff), dst);
 }
 
 void fbcon_vga_putcs(struct vc_data *conp, struct display *p, const char *s,
 		     int count, int y, int x)
 {
     u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
-    u16 sattr = conp->vc_attr << 8;
+    u16 sattr = fbcon_vga_attr(p, conp);
     while (count--)
 	vga_writew(sattr | ((int) (*s++) & 0xff), dst++);
 }
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/fbcon.c m68k/drivers/video/fbcon.c
--- m68k-current/drivers/video/fbcon.c	Mon Jun  1 11:34:01 1998
+++ m68k/drivers/video/fbcon.c	Mon Jun  1 11:23:00 1998
@@ -1202,7 +1202,11 @@
 		    val = (*src << redshift) |
 			  (*src << greenshift) |
 			  (*src << blueshift);
+#ifdef __LITTLE_ENDIAN
+		    for( i = 0; i < bdepth; ++i )
+#else
 		    for( i = bdepth-1; i >= 0; --i )
+#endif
 			*dst++ = val >> (i*8);
 		}
 	    }
@@ -1256,10 +1260,14 @@
 	for( y1 = 0; y1 < LOGO_H; y1++ ) {
 	    dst = fb + y1*line;
 	    for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
-		val = ((linux_logo_red[*src]   & redmask)   << redshift) |
-		      ((linux_logo_green[*src] & greenmask) << greenshift) |
-		      ((linux_logo_blue[*src]  & bluemask)  << blueshift);
+		val = ((linux_logo_red[*src-32]   & redmask)   << redshift) |
+		      ((linux_logo_green[*src-32] & greenmask) << greenshift) |
+		      ((linux_logo_blue[*src-32]  & bluemask)  << blueshift);
+#ifdef __LITTLE_ENDIAN
+		for( i = 0; i < bdepth; ++i )
+#else
 		for( i = bdepth-1; i >= 0; --i )
+#endif
 		    *dst++ = val >> (i*8);
 	    }
 	}
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/fbcon.h m68k/drivers/video/fbcon.h
--- m68k-current/drivers/video/fbcon.h	Thu May 14 21:34:48 1998
+++ m68k/drivers/video/fbcon.h	Mon Jun  1 11:23:00 1998
@@ -46,12 +46,14 @@
 	(((conp)->vc_video_erase_char >> ((p)->inverse ? 8 : 12)) & 0x0f)
 
 /* Monochrome */
-#define attr_bold(p,conp)     \
-	(((conp)->vc_attr & 3) == 2)
-#define attr_reverse(p,conp)  \
+#define attr_bold(p,conp) \
+	((conp)->vc_attr & 2)
+#define attr_reverse(p,conp) \
 	(((conp)->vc_attr & 8) ^ ((p)->inverse ? 8 : 0))
 #define attr_underline(p,conp) \
-	(((conp)->vc_attr) & 4)
+	((conp)->vc_attr & 4)
+#define attr_blink(p,conp) \
+	((conp)->vc_attr & 0x80)
 
 
 /* ================================================================= */
@@ -318,6 +320,54 @@
     return(memset(s, 255, count));
 }
 
+#ifdef __i386__
+static __inline__ void fast_memmove(void *d, const void *s, size_t count)
+{
+    if (d < s) {
+__asm__ __volatile__ (
+	"cld\n\t"
+	"shrl $1,%%ecx\n\t"
+	"jnc 1f\n\t"
+	"movsb\n"
+	"1:\tshrl $1,%%ecx\n\t"
+	"jnc 2f\n\t"
+	"movsw\n"
+	"2:\trep\n\t"
+	"movsl"
+	: /* no output */
+	:"c"(count),"D"((long)d),"S"((long)s)
+	:"cx","di","si","memory");
+    } else {
+__asm__ __volatile__ (
+	"std\n\t"
+	"shrl $1,%%ecx\n\t"
+	"jnc 1f\n\t"
+	"movb 3(%%esi),%%al\n\t"
+	"movb %%al,3(%%edi)\n\t"
+	"decl %%esi\n\t"
+	"decl %%edi\n"
+	"1:\tshrl $1,%%ecx\n\t"
+	"jnc 2f\n\t"
+	"movw 2(%%esi),%%ax\n\t"
+	"movw %%ax,2(%%edi)\n\t"
+	"decl %%esi\n\t"
+	"decl %%edi\n\t"
+	"decl %%esi\n\t"
+	"decl %%edi\n"
+	"2:\trep\n\t"
+	"movsl"
+	: /* no output */
+	:"c"(count),"D"(count-4+(long)d),"S"(count-4+(long)s)
+	:"ax","cx","di","si","memory");
+    }
+}
+
+static __inline__ void *mymemmove(char *dst, const char *src, size_t size)
+{
+    fast_memmove(dst, src, size);
+    return dst;
+}
+#else
 static __inline__ void *mymemmove(void *d, const void *s, size_t count)
 {
     return(memmove(d, s, count));
@@ -327,6 +377,7 @@
 {
     memmove(dst, src, size);
 }
+#endif	/* !i386 */
 
 #endif /* !m68k */
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/hpfb.c m68k/drivers/video/hpfb.c
--- m68k-current/drivers/video/hpfb.c	Thu May 14 21:34:48 1998
+++ m68k/drivers/video/hpfb.c	Mon Jun  1 11:23:00 1998
@@ -235,7 +235,7 @@
 
 	hpfb_get_fix(&fix, con, 0);
 
-	display->screen_base = (u_char *)(fix.smem_start);
+	display->screen_base = fix.smem_start;
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/macfb.c m68k/drivers/video/macfb.c
--- m68k-current/drivers/video/macfb.c	Thu May 14 21:34:49 1998
+++ m68k/drivers/video/macfb.c	Mon Jun  1 11:23:00 1998
@@ -205,7 +205,7 @@
 
 	macfb_get_fix(&fix, con, 0);
 
-	display->screen_base = (u_char *)(fix.smem_start+fix.smem_offset);
+	display->screen_base = fix.smem_start+fix.smem_offset;
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/mdafb.c m68k/drivers/video/mdafb.c
--- m68k-current/drivers/video/mdafb.c	Thu Jan  1 01:00:00 1970
+++ m68k/drivers/video/mdafb.c	Mon Jun  1 11:23:00 1998
@@ -0,0 +1,483 @@
+/*
+ *  linux/drivers/video/mdafb.c -- MDA frame buffer device
+ *
+ *	Adapted from vgafb, May 1998 by Andrew Apted
+ *
+ *  This file is based on vgacon.c and vgafb.c.  Read about their
+ *  contributors there.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+
+/* KNOWN PROBLEMS/TO DO ==================================================== *
+ *
+ *	-  detecting amount of memory is not yet implemented
+ *
+ * ========================================================================= */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "fbcon.h"
+#include "fbcon-vga.h"
+
+
+#ifdef __powerpc__
+#define VGA_OFFSET _ISA_MEM_BASE;
+#else
+#define VGA_OFFSET 0x0
+#endif
+
+
+static int mda_font_height = 16;   /* !!! */
+
+
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+
+static struct fb_fix_screeninfo fb_fix = { { 0, } };
+static struct fb_var_screeninfo fb_var = { 0, };
+
+
+/* Description of the hardware situation */
+static unsigned char mda_video_type;
+static unsigned long mda_video_mem_base;	/* Base of video memory */
+static unsigned long mda_video_mem_len;		/* End of video memory */
+static u16 mda_video_port_reg;			/* Video register select port */
+static u16 mda_video_port_val;			/* Video register value port */
+static unsigned long mda_video_num_columns;	/* Number of text columns */
+static unsigned long mda_video_num_lines;	/* Number of text lines */
+
+
+    /*
+     *  MDA screen access
+     */ 
+
+static inline void mda_writew(u16 val, u16 *addr)
+{
+#ifdef __powerpc__
+	st_le16(addr, val);
+#else
+	writew(val, (unsigned long)addr);
+#endif /* !__powerpc__ */
+}
+
+static inline u16 mda_readw(u16 *addr)
+{
+#ifdef __powerpc__
+	return ld_le16(addr);
+#else
+	return readw((unsigned long)addr);
+#endif /* !__powerpc__ */	
+}
+
+
+static inline void write_mda(unsigned char reg, unsigned int val)
+{
+	unsigned long flags;
+
+	save_flags(flags); cli();
+
+	outb(reg, mda_video_port_reg);
+	outb(val >> 8, mda_video_port_val);
+	outb(reg+1, mda_video_port_reg);
+	outb(val & 0xff, mda_video_port_val);
+
+	restore_flags(flags);
+}
+
+static inline void mda_set_origin(unsigned short offset)
+{
+	write_mda(12, offset);
+}
+
+    /*
+     *  Move hardware mda cursor
+     */
+    
+static int mda_write_cursor (int location) 
+{
+	write_mda(14, location >> 1);
+	return 0;
+}
+
+
+void fbcon_mdafb_cursor(struct display *p, int mode, int x, int y)
+{
+	switch (mode) {
+		case CM_ERASE:
+			mda_write_cursor(mda_video_mem_len - 1);
+			break;
+
+		case CM_MOVE:
+		case CM_DRAW:
+			mda_write_cursor(y*p->next_line + (x << 1));
+			break;
+	}
+}
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+void mdafb_setup(char *options, int *ints);
+static int mdafbcon_switch(int con, struct fb_info *info);
+static int mdafbcon_updatevar(int con, struct fb_info *info);
+static void mdafbcon_blank(int blank, struct fb_info *info);
+
+
+    /*
+     *  Open/Release the frame buffer device
+     */
+
+static int mdafb_open(struct fb_info *info)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int mdafb_release(struct fb_info *info)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int mdafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
+{
+	memcpy(fix, &fb_fix, sizeof(fb_fix));
+	return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int mdafb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+	memcpy(var, &fb_var, sizeof(fb_var));
+	return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int mdafb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+    struct display *display;
+
+    if (con >= 0)
+	display = &fb_display[con];
+    else
+	display = &disp;	/* used during initialization */
+
+    if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
+	var->xres_virtual > fb_var.xres_virtual ||
+	var->yres_virtual > fb_var.yres_virtual ||
+	var->bits_per_pixel > fb_var.bits_per_pixel ||
+	var->nonstd || !(var->accel_flags & FB_ACCELF_TEXT) ||
+	(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+	return -EINVAL;
+
+    memcpy(var, &fb_var, sizeof(fb_var));
+
+    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+	display->var = *var;
+	mda_set_origin(var->yoffset/mda_font_height*fb_fix.line_length/2);
+    }
+
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int mdafb_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info *info)
+{
+	if (var->xoffset || var->yoffset+var->yres > var->yres_virtual)
+		return -EINVAL;
+
+	mda_set_origin(var->yoffset/mda_font_height*fb_fix.line_length/2);
+	return 0;
+}
+
+
+    /*
+     *  Get the Colormap
+     */
+
+static int mdafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+	/* MDA is simply black and white */
+
+	return 0;
+}
+
+
+    /*
+     *  Set the Colormap
+     */
+
+static int mdafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+	/* MDA is simply black and white */
+
+	return 0;
+}
+
+
+static int mdafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		       u_long arg, int con, struct fb_info *info)
+{
+	return -EINVAL;
+}
+
+    /*
+     *  Interface used by the world
+     */
+
+static struct fb_ops mdafb_ops = {
+	mdafb_open, mdafb_release, mdafb_get_fix, mdafb_get_var,
+	mdafb_set_var, mdafb_get_cmap, mdafb_set_cmap, mdafb_pan_display, 
+	mdafb_ioctl
+};
+
+    /*
+     *  MDA text console with hardware cursor
+     */
+
+static struct display_switch fbcon_mdafb = {
+    fbcon_vga_setup, fbcon_vga_bmove, fbcon_vga_clear, fbcon_vga_putc,
+    fbcon_vga_putcs, fbcon_vga_revc, fbcon_mdafb_cursor
+};
+
+
+    /*
+     *  Initialisation
+     */
+
+__initfunc(void mdafb_init(void))
+{
+    int err;
+    u16 saved;
+    u16 *p;
+
+    mda_video_num_lines = 25;
+    mda_video_num_columns = 80;
+    mda_video_type = VIDEO_TYPE_MDA;
+    mda_video_mem_base = 0xb0000 + VGA_OFFSET;
+    mda_video_mem_len  = 0x01000;
+    mda_video_port_reg = 0x3b4;
+    mda_video_port_val = 0x3b5;
+
+    strcpy(fb_fix.id, "MDA-Dual-Head");
+    request_region(0x3b0, 12, "mda-2");
+    request_region(0x3bf, 1, "mda-2");
+
+    /*
+     *	Find out if there is a graphics card present.
+     *	Are there smarter methods around?
+     */
+    p = (u16 *)mda_video_mem_base;
+    saved = mda_readw(p);
+    mda_writew(0xAA55, p);
+    if (mda_readw(p) != 0xAA55) {
+	mda_writew(saved, p);
+	return;
+    }
+    mda_writew(0x55AA, p);
+    if (mda_readw(p) != 0x55AA) {
+	mda_writew(saved, p);
+	return;
+    }
+    mda_writew(saved, p);
+
+    fb_fix.smem_start = (char *) mda_video_mem_base;
+    fb_fix.smem_len = mda_video_mem_len;
+    fb_fix.type = FB_TYPE_VGA_TEXT;
+    fb_fix.type_aux = 0;
+    fb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
+    fb_fix.ypanstep = mda_font_height;
+    fb_fix.xpanstep = 0;
+    fb_fix.ywrapstep = 0;
+    fb_fix.line_length = 2 * mda_video_num_columns;
+    fb_fix.mmio_start = NULL;
+    fb_fix.mmio_len = 0;
+    fb_fix.accel = FB_ACCEL_NONE;
+
+    fb_var.xres = mda_video_num_columns*8;
+    fb_var.yres = mda_video_num_lines * mda_font_height;
+    fb_var.xres_virtual = fb_var.xres;
+    /* the cursor is put at the end of the video memory, hence the -2 */
+    fb_var.yres_virtual = ((fb_fix.smem_len-2)/fb_fix.line_length)*
+			  mda_font_height;
+
+    fb_var.xoffset = fb_var.yoffset = 0;
+    fb_var.bits_per_pixel = 1;
+    fb_var.grayscale = 1;
+    fb_var.red.offset = 0;
+    fb_var.red.length = 0;
+    fb_var.red.msb_right = 0;
+    fb_var.green.offset = 0;
+    fb_var.green.length = 0;
+    fb_var.green.msb_right = 0;
+    fb_var.blue.offset = 0;
+    fb_var.blue.length = 0;
+    fb_var.blue.msb_right = 0;
+    fb_var.transp.offset = 0;
+    fb_var.transp.length = 0;
+    fb_var.transp.msb_right = 0;
+    fb_var.nonstd = 0;
+    fb_var.activate = 0;
+    fb_var.height = fb_var.width = -1;
+    fb_var.accel_flags = FB_ACCELF_TEXT;
+    fb_var.pixclock = 39722;		/* 25.175 MHz */
+    fb_var.left_margin = 40;
+    fb_var.right_margin = 24;
+    fb_var.upper_margin = 39;
+    fb_var.lower_margin = 9;
+    fb_var.hsync_len = 96;
+    fb_var.vsync_len = 2;
+    fb_var.sync = 0;
+    fb_var.vmode = FB_VMODE_NONINTERLACED;
+
+    disp.var = fb_var;
+    disp.cmap.start = 0;
+    disp.cmap.len = 0;
+    disp.cmap.red = NULL;
+    disp.cmap.green = NULL;
+    disp.cmap.blue = NULL;
+    disp.cmap.transp = NULL;
+
+#ifdef __i386__
+    disp.screen_base = ioremap((unsigned long) fb_fix.smem_start, 
+    				fb_fix.smem_len);
+#else
+    disp.screen_base = bus_to_virt((unsigned long) fb_fix.smem_start);
+#endif
+    disp.visual = fb_fix.visual;
+    disp.type = fb_fix.type;
+    disp.type_aux = fb_fix.type_aux;
+    disp.ypanstep = fb_fix.ypanstep;
+    disp.ywrapstep = fb_fix.ywrapstep;
+    disp.line_length = fb_fix.line_length;
+    disp.can_soft_blank = 1;
+    disp.inverse = 0;
+    disp.dispsw = &fbcon_mdafb;
+
+    strcpy(fb_info.modename, fb_fix.id);
+    fb_info.node = -1;
+    fb_info.fbops = &mdafb_ops;
+    fb_info.disp = &disp;
+    fb_info.fontname[0] = '\0';
+    fb_info.changevar = NULL;
+    fb_info.switch_con = &mdafbcon_switch;
+    fb_info.updatevar = &mdafbcon_updatevar;
+    fb_info.blank = &mdafbcon_blank;
+
+    err = register_framebuffer(&fb_info);
+
+    if (err < 0)
+	return;
+
+    mdafb_set_var(&fb_var, -1, &fb_info);
+
+    printk("fb%d: MDA frame buffer device, using %dK of video memory\n",
+	   GET_FB_IDX(fb_info.node), fb_fix.smem_len>>10);
+}
+
+__initfunc(void mdafb_setup(char *options, int *ints))
+{
+	/* nothing yet */
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int mdafbcon_updatevar(int con, struct fb_info *info)
+{
+	if (con == currcon) {
+		struct fb_var_screeninfo *var = &fb_display[currcon].var;
+
+		/* hardware scrolling */
+
+		mda_set_origin(var->yoffset / mda_font_height *
+			fb_fix.line_length / 2);
+	}
+
+	return 0;
+}
+
+static int mdafbcon_switch(int con, struct fb_info *info)
+{
+	currcon = con;
+	mdafbcon_updatevar(con, info);
+	return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void mdafbcon_blank(int blank, struct fb_info *info)
+{
+	if (blank) {
+		outb_p(0x00, 0x3b8);  /* disable video */
+	} else {
+		outb_p(0x08, 0x3b8);  /* enable video */
+	}
+}
+
+
+#ifdef MODULE
+int init_module(void)
+{
+	mdafb_init();
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	unregister_framebuffer(&fb_info);
+}
+#endif /* MODULE */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/offb.c m68k/drivers/video/offb.c
--- m68k-current/drivers/video/offb.c	Thu May 14 21:34:49 1998
+++ m68k/drivers/video/offb.c	Mon Jun  1 11:23:00 1998
@@ -27,7 +27,7 @@
 #include <linux/selection.h>
 #include <linux/init.h>
 #ifdef CONFIG_FB_COMPAT_XPMAC
-#include <linux/vc_ioctl.h>
+#include <asm/vc_ioctl.h>
 #endif
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -280,7 +280,7 @@
 static const char *aty_names[] = {
     "ATY,mach64", "ATY,XCLAIM", "ATY,264VT", "ATY,mach64ii", "ATY,264GT-B", 
     "ATY,mach64_3D_pcc", "ATY,XCLAIM3D", "ATY,XCLAIMVR", "ATY,RAGEII_M",
-    "ATY,XCLAIMVRPro", "ATY,mach64_3DU"
+    "ATY,XCLAIMVRPro", "ATY,mach64_3DU", "ATY,XCLAIM3DPro"
 };
 #endif /* CONFIG_FB_ATY */
 #ifdef CONFIG_FB_S3TRIO
@@ -363,7 +363,7 @@
 	    }
 	    address = (u_long)dp->addrs[i].address;
 	}
-	fix->smem_start = ioremap(address, fix->smem_len);
+	fix->smem_start = (char *)address;
 	fix->type = FB_TYPE_PACKED_PIXELS;
 	fix->type_aux = 0;
 
@@ -396,8 +396,11 @@
 	disp->var = *var;
 	disp->cmap.start = 0;
 	disp->cmap.len = 0;
-	disp->cmap.red = disp->cmap.green = disp->cmap.blue = disp->cmap.transp = NULL;
-	disp->screen_base = fix->smem_start;
+	disp->cmap.red = NULL;
+	disp->cmap.green = NULL;
+	disp->cmap.blue = NULL;
+	disp->cmap.transp = NULL;
+	disp->screen_base = ioremap(address, fix->smem_len);
 	disp->visual = fix->visual;
 	disp->type = fix->type;
 	disp->type_aux = fix->type_aux;
@@ -449,15 +452,15 @@
 	    display_info.pitch = fix->line_length;
 	    display_info.mode = 0;
 	    strncpy(display_info.name, dp->name, sizeof(display_info.name));
-	    display_info.fb_address = iopa((unsigned long)fix->smem_start);
+	    display_info.fb_address = address;
 	    display_info.cmap_adr_address = 0;
 	    display_info.cmap_data_address = 0;
 	    display_info.disp_reg_address = 0;
 	    /* XXX kludge for ati */
 	    if (strncmp(dp->name, "ATY,", 4) == 0) {
-		    display_info.disp_reg_address = iopa(address + 0x7ffc00);
-		    display_info.cmap_adr_address = iopa(address + 0x7ffcc0);
-		    display_info.cmap_data_address = iopa(address + 0x7ffcc1);
+		    display_info.disp_reg_address = address + 0x7ffc00;
+		    display_info.cmap_adr_address = address + 0x7ffcc0;
+		    display_info.cmap_data_address = address + 0x7ffcc1;
 	    }
 	    console_fb_info = &info->info;
 	    console_set_cmap_ptr = offb_set_cmap;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/retz3fb.c m68k/drivers/video/retz3fb.c
--- m68k-current/drivers/video/retz3fb.c	Mon May  4 20:25:33 1998
+++ m68k/drivers/video/retz3fb.c	Mon Jun  1 11:23:00 1998
@@ -840,7 +840,7 @@
 	strcpy(fix->id, retz3fb_name);
 	fix->smem_start = (char *)z3_fbmem;
 	fix->smem_len = z3_size;
-	fix->mmio_start = (unsigned char *)z3_regs;
+	fix->mmio_start = (char *)z3_regs;
 	fix->mmio_len = 0x00c00000;
 
 	fix->type = FB_TYPE_PACKED_PIXELS;
@@ -1271,7 +1271,7 @@
 	if (con == -1)
 		con = 0;
 
-	display->screen_base = (unsigned char *)fix.smem_start;
+	display->screen_base = fix.smem_start;
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/tgafb.c m68k/drivers/video/tgafb.c
--- m68k-current/drivers/video/tgafb.c	Thu May 14 21:34:49 1998
+++ m68k/drivers/video/tgafb.c	Mon Jun  1 11:23:00 1998
@@ -689,11 +689,11 @@
     fb_var.xres = fb_var.xres_virtual = 640;
     fb_var.yres = fb_var.yres_virtual = 480;
     fb_fix.line_length = 80*fb_var.bits_per_pixel;
-    fb_fix.smem_start = (char *)(tga_fb_base + LCA_DENSE_MEM);
+    fb_fix.smem_start = (char *)__pa(tga_fb_base + LCA_DENSE_MEM);
     fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
     fb_fix.type = FB_TYPE_PACKED_PIXELS;
     fb_fix.type_aux = 0;
-    fb_fix.mmio_start = (unsigned char *)tga_regs_base;
+    fb_fix.mmio_start = (char *)__pa(tga_regs_base);
     fb_fix.mmio_len = 0x1000;		/* Is this sufficient? */
     fb_fix.accel = FB_ACCEL_DEC_TGA;
 
@@ -730,7 +730,7 @@
     disp.cmap.start = 0;
     disp.cmap.len = 0;
     disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
-    disp.screen_base = fb_fix.smem_start;
+    disp.screen_base = (char *)tga_fb_base + LCA_DENSE_MEM;
     disp.visual = fb_fix.visual;
     disp.type = fb_fix.type;
     disp.type_aux = fb_fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/vesafb.c m68k/drivers/video/vesafb.c
--- m68k-current/drivers/video/vesafb.c	Thu Jan  1 01:00:00 1970
+++ m68k/drivers/video/vesafb.c	Mon Jun  1 11:23:00 1998
@@ -0,0 +1,535 @@
+/*
+ * framebuffer driver for VBE 2.0 compilant graphic boards
+ *
+ * switching to graphics mode happens at boot time (while
+ * running in real mode, see arch/i386/video.S).
+ *
+ * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ */ 
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+
+#include "fbcon.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+#include "fbcon-cfb32.h"
+
+#define dac_reg	(0x3c8)
+#define dac_val	(0x3c9)
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * card parameters
+ */
+
+/* card */
+char *video_base;
+int   video_size;
+char *video_vbase;        /* mapped */
+
+/* mode */
+int  video_bpp;
+int  video_width;
+int  video_height;
+int  video_type = FB_TYPE_PACKED_PIXELS;
+int  video_visual;
+int  video_linelength;
+int  video_cmap_len;
+
+/* --------------------------------------------------------------------- */
+
+static struct fb_var_screeninfo vesafb_defined = {
+	0,0,0,0,	/* W,H, W, H (virtual) load xres,xres_virtual*/
+	0,0,		/* virtual -> visible no offset */
+	8,		/* depth -> load bits_per_pixel */
+	0,		/* greyscale ? */
+	{0,0,0},	/* R */
+	{0,0,0},	/* G */
+	{0,0,0},	/* B */
+	{0,0,0},	/* transparency */
+	0,		/* standard pixel format */
+	FB_ACTIVATE_NOW,
+	-1,-1,
+	0,
+	0L,0L,0L,0L,0L,
+	0L,0L,0,	/* No sync info */
+	FB_VMODE_NONINTERLACED,
+	{0,0,0,0,0,0}
+};
+
+#define NUM_TOTAL_MODES		1
+#define NUM_PREDEF_MODES	1
+
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+
+static int inverse = 0;
+
+struct vesafb_par
+{
+	void *unused;
+};
+
+static int currcon = 0;
+static int current_par_valid = 0;
+struct vesafb_par current_par;
+
+/* --------------------------------------------------------------------- */
+/* speed up scrolling                                                    */
+
+#define USE_REDRAW   1
+#define USE_MEMMOVE  2
+  
+static vesafb_scroll = USE_REDRAW;
+static struct display_switch vesafb_sw;
+
+void vesafb_bmove(struct display *p, int sy, int sx, int dy, int dx,
+		  int height, int width)
+{
+	/*
+	 * this is really faster than memmove (at least with my box)
+	 *    read access to video memory is slow...
+	 */
+	update_screen(currcon);
+}
+
+/* --------------------------------------------------------------------- */
+
+	/*
+	 * Open/Release the frame buffer device
+	 */
+
+static int vesafb_open(struct fb_info *info)
+{
+	/*
+	 * Nothing, only a usage count for the moment
+	 */
+	MOD_INC_USE_COUNT;
+	return(0);
+}
+
+static int vesafb_release(struct fb_info *info)
+{
+	MOD_DEC_USE_COUNT;
+	return(0);
+}
+
+static void vesafb_encode_var(struct fb_var_screeninfo *var, 
+				struct vesafb_par *par)
+{
+	memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
+}
+
+static void vesafb_get_par(struct vesafb_par *par)
+{
+	*par=current_par;
+}
+
+static int fb_update_var(int con, struct fb_info *info)
+{
+	return 0;
+}
+
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+{
+	struct vesafb_par par;
+	
+	vesafb_get_par(&par);
+	vesafb_encode_var(var, &par);
+	return 0;
+}
+
+static void vesafb_encode_fix(struct fb_fix_screeninfo *fix, 
+				struct vesafb_par *par)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id,"VESA VGA");
+
+	fix->smem_start=(char *) video_base;
+	fix->smem_len=video_size;
+	fix->type = video_type;
+	fix->visual = video_visual;
+	fix->xpanstep=0;
+	fix->ypanstep=0;
+	fix->ywrapstep=0;
+	fix->line_length=video_linelength;
+	return;
+}
+
+static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
+{
+	struct vesafb_par par;
+	vesafb_get_par(&par);
+	vesafb_encode_fix(fix, &par);
+	return 0;
+}
+
+static int vesafb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+	struct vesafb_par par;
+	if(con==-1)
+	{
+		vesafb_get_par(&par);
+		vesafb_encode_var(var, &par);
+	}
+	else
+		*var=fb_display[con].var;
+	return 0;
+}
+
+static void vesafb_set_disp(int con)
+{
+	struct fb_fix_screeninfo fix;
+	struct display *display;
+	
+	if (con >= 0)
+		display = &fb_display[con];
+	else
+		display = &disp;	/* used during initialization */
+
+	vesafb_get_fix(&fix, con, 0);
+
+	display->screen_base = video_vbase;
+	display->visual = fix.visual;
+	display->type = fix.type;
+	display->type_aux = fix.type_aux;
+	display->ypanstep = fix.ypanstep;
+	display->ywrapstep = fix.ywrapstep;
+	display->line_length = fix.line_length;
+	display->next_line = fix.line_length;
+	display->can_soft_blank = 0;
+	display->inverse = inverse;
+
+	switch (video_bpp) {
+#ifdef CONFIG_FBCON_CFB8
+	case 8:
+		display->dispsw = &fbcon_cfb8;
+		break;
+#endif
+#ifdef CONFIG_FBCON_CFB16
+	case 15:
+	case 16:
+		display->dispsw = &fbcon_cfb16;
+		break;
+#endif
+#ifdef CONFIG_FBCON_CFB32
+	case 32:
+		display->dispsw = &fbcon_cfb32;
+		break;
+#endif
+	default:
+		display->dispsw = NULL;
+		break;
+	}
+	if (vesafb_scroll == USE_REDRAW) {
+		memcpy(&vesafb_sw,display->dispsw,sizeof(vesafb_sw));
+		vesafb_sw.bmove = vesafb_bmove;
+		display->dispsw = &vesafb_sw;
+	}
+}
+
+static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+	int err;
+	
+	if ((err=do_fb_set_var(var, 1)))
+		return err;
+	return 0;
+}
+
+static int vesa_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			  unsigned *blue, unsigned *transp,
+			  struct fb_info *fb_info)
+{
+	/*
+	 *  Read a single color register and split it into colors/transparent.
+	 *  Return != 0 for invalid regno.
+	 */
+
+	if (regno >= video_cmap_len)
+		return 1;
+
+	*red   = palette[regno].red;
+	*green = palette[regno].green;
+	*blue  = palette[regno].blue;
+	return 0;
+}
+
+static int vesa_setcolreg(unsigned regno, unsigned red, unsigned green,
+			  unsigned blue, unsigned transp,
+			  struct fb_info *fb_info)
+{
+	/*
+	 *  Set a single color register. The values supplied are
+	 *  already rounded down to the hardware's capabilities
+	 *  (according to the entries in the `var' structure). Return
+	 *  != 0 for invalid regno.
+	 */
+	
+	if (regno >= video_cmap_len)
+		return 1;
+	
+	palette[regno].red   = red;
+	palette[regno].green = green;
+	palette[regno].blue  = blue;
+	
+	switch (video_bpp) {
+#ifdef CONFIG_FBCON_CFB8
+	case 8:
+		/* Hmm, can we do it _allways_ this way ??? */
+		outb_p(regno, dac_reg);
+		outb_p(red, dac_val);
+		outb_p(green, dac_val);
+		outb_p(blue, dac_val);
+		break;
+#endif
+#ifdef CONFIG_FBCON_CFB16
+	case 15:
+	case 16:
+		fbcon_cfb16_cmap[regno] =
+			(red << vesafb_defined.red.offset) | (green << 5) | blue;
+		break;
+#endif
+#ifdef CONFIG_FBCON_CFB24
+	case 24:
+		/* FIXME: todo */
+		break;
+#endif
+#ifdef CONFIG_FBCON_CFB32
+	case 32:
+		fbcon_cfb32_cmap[regno] =
+			(red   << vesafb_defined.red.offset)   |
+			(green << vesafb_defined.green.offset) |
+			(blue  << vesafb_defined.blue.offset);
+		break;
+#endif
+    }
+    return 0;
+}
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+	if (con != currcon)
+		return;
+	if (fb_display[con].cmap.len)
+		fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+			    vesa_setcolreg, info);
+	else
+		fb_set_cmap(fb_default_cmap(video_cmap_len),
+			    &fb_display[con].var, 1, vesa_setcolreg,
+			    info);
+}
+
+static int vesafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			   struct fb_info *info)
+{
+	if (con == currcon) /* current console? */
+		return fb_get_cmap(cmap, &fb_display[con].var, kspc, vesa_getcolreg, info);
+	else if (fb_display[con].cmap.len) /* non default colormap? */
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(video_cmap_len),
+		     cmap, kspc ? 0 : 2);
+	return 0;
+}
+
+static int vesafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			   struct fb_info *info)
+{
+	int err;
+
+	if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+		err = fb_alloc_cmap(&fb_display[con].cmap,video_cmap_len,0);
+		if (err)
+			return err;
+	}
+	if (con == currcon)			/* current console? */
+		return fb_set_cmap(cmap, &fb_display[con].var, kspc, vesa_setcolreg, info);
+	else
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+	return 0;
+}
+
+static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info *info)
+{
+	/* no panning */
+	return -EINVAL;
+}
+
+static int vesafb_ioctl(struct inode *inode, struct file *file, 
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info)
+{
+	return -EINVAL;
+}
+
+static struct fb_ops vesafb_ops = {
+	vesafb_open,
+	vesafb_release,
+	vesafb_get_fix,
+	vesafb_get_var,
+	vesafb_set_var,
+	vesafb_get_cmap,
+	vesafb_set_cmap,
+	vesafb_pan_display,
+	vesafb_ioctl
+};
+
+void vesafb_setup(char *options, int *ints)
+{
+	char *this_opt;
+	
+	fb_info.fontname[0] = '\0';
+	
+	if (!options || !*options)
+		return;
+	
+	for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+		if (!*this_opt) continue;
+		
+		printk("vesafb_setup: option %s\n", this_opt);
+		
+		if (! strcmp(this_opt, "inverse"))
+			inverse=1;
+		else if (! strcmp(this_opt, "redraw"))
+			vesafb_scroll = USE_REDRAW;
+		else if (! strcmp(this_opt, "memmove"))
+			vesafb_scroll = USE_MEMMOVE;
+		else if (!strncmp(this_opt, "font:", 5))
+			strcpy(fb_info.fontname, this_opt+5);
+	}
+}
+
+static int vesafb_switch(int con, struct fb_info *info)
+{
+	/* Do we have to save the colormap? */
+	if (fb_display[currcon].cmap.len)
+		fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+			    vesa_getcolreg, info);
+	
+	currcon = con;
+	/* Install new colormap */
+	do_install_cmap(con, info);
+	fb_update_var(con, info);
+	return 0;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void vesafb_blank(int blank, struct fb_info *info)
+{
+	/* Not supported */
+}
+
+__initfunc(void vesafb_init(void))
+{
+	int i,j;
+
+	if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
+		return;
+
+	video_base          = (char*)screen_info.lfb_base;
+	video_bpp           = screen_info.lfb_depth;
+	video_width         = screen_info.lfb_width;
+	video_height        = screen_info.lfb_height;
+	video_linelength    = screen_info.lfb_linelength;
+	video_size          = video_linelength * video_height /* screen_info.lfb_size */;
+	video_visual = (video_bpp == 8) ?
+		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+        video_vbase = ioremap((unsigned long)video_base, video_size);
+
+	printk("vesafb: %dx%dx%d, linelength=%d\n",
+	       video_width, video_height, video_bpp, video_linelength);
+	printk("vesafb: framebuffer at 0x%p, mapped to 0x%p, size %d\n",
+	       video_base, video_vbase, video_size);
+	if (vesafb_scroll == USE_REDRAW)  printk("vesafb: scrolling=redraw\n");
+	if (vesafb_scroll == USE_MEMMOVE) printk("vesafb: scrolling=memmove\n");
+	 
+	vesafb_defined.xres=video_width;
+	vesafb_defined.yres=video_height;
+	vesafb_defined.xres_virtual=video_width;
+	vesafb_defined.yres_virtual=video_height;
+	vesafb_defined.bits_per_pixel=video_bpp;
+
+	if (video_bpp > 8) {
+		vesafb_defined.red.offset    = screen_info.red_pos;
+		vesafb_defined.red.length    = screen_info.red_size;
+		vesafb_defined.green.offset  = screen_info.green_pos;
+		vesafb_defined.green.length  = screen_info.green_size;
+		vesafb_defined.blue.offset   = screen_info.blue_pos;
+		vesafb_defined.blue.length   = screen_info.blue_size;
+		vesafb_defined.transp.offset = screen_info.rsvd_pos;
+		vesafb_defined.transp.length = screen_info.rsvd_size;
+		printk("vesafb: directcolor: "
+		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
+		       screen_info.rsvd_size,
+		       screen_info.red_size,
+		       screen_info.green_size,
+		       screen_info.blue_size,
+		       screen_info.rsvd_pos,
+		       screen_info.red_pos,
+		       screen_info.green_pos,
+		       screen_info.blue_pos);
+		video_cmap_len = 16;
+	} else {
+		vesafb_defined.red.length   = 6;
+		vesafb_defined.green.length = 6;
+		vesafb_defined.blue.length  = 6;
+		for(i = 0; i < 16; i++) {
+			j = color_table[i];
+			palette[i].red   = default_red[j];
+			palette[i].green = default_grn[j];
+			palette[i].blue  = default_blu[j];
+		}
+		video_cmap_len = 256;
+	}
+	request_region(0x3c0, 32, "vga+");
+	
+	strcpy(fb_info.modename, "VESA VGA");
+	fb_info.changevar = NULL;
+	fb_info.node = -1;
+	fb_info.fbops = &vesafb_ops;
+	fb_info.disp=&disp;
+	fb_info.switch_con=&vesafb_switch;
+	fb_info.updatevar=&fb_update_var;
+	fb_info.blank=&vesafb_blank;
+	do_fb_set_var(&vesafb_defined,1);
+
+	if (register_framebuffer(&fb_info)<0)
+		return;
+
+	vesafb_get_var(&disp.var, -1, &fb_info);
+	vesafb_set_disp(-1);
+
+	printk("fb%d: %s frame buffer device\n",
+	       GET_FB_IDX(fb_info.node), fb_info.modename);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/vfb.c m68k/drivers/video/vfb.c
--- m68k-current/drivers/video/vfb.c	Mon May  4 20:25:35 1998
+++ m68k/drivers/video/vfb.c	Mon Jun  1 11:23:00 1998
@@ -250,7 +250,7 @@
 	    struct fb_fix_screeninfo fix;
 
 	    vfb_encode_fix(&fix, var);
-	    display->screen_base = (u_char *)fix.smem_start;
+	    display->screen_base = (char *)videomemory;
 	    display->visual = fix.visual;
 	    display->type = fix.type;
 	    display->type_aux = fix.type_aux;
@@ -501,7 +501,7 @@
 {
     memset(fix, 0, sizeof(struct fb_fix_screeninfo));
     strcpy(fix->id, vfb_name);
-    fix->smem_start = (caddr_t)videomemory;
+    fix->smem_start = (char *)videomemory;
     fix->smem_len = videomemorysize;
     fix->type = FB_TYPE_PACKED_PIXELS;
     fix->type_aux = 0;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/vgacon.c m68k/drivers/video/vgacon.c
--- m68k-current/drivers/video/vgacon.c	Thu May 14 21:34:49 1998
+++ m68k/drivers/video/vgacon.c	Mon Jun  1 11:23:00 1998
@@ -404,7 +404,7 @@
     p = (u16 *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
     sattr = conp->vc_attr << 8;
     while (count--)
-	vga_writew(sattr | *s++, p++);
+	vga_writew(sattr | ((int) (*s++) & 0xff), p++);
 }
 
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/vgafb.c m68k/drivers/video/vgafb.c
--- m68k-current/drivers/video/vgafb.c	Thu May 14 21:34:49 1998
+++ m68k/drivers/video/vgafb.c	Mon Jun  1 11:23:00 1998
@@ -16,10 +16,6 @@
 
 /* KNOWN PROBLEMS/TO DO ===================================================== *
  *
- *	- monochrome attribute encoding (convert abscon <-> VGA style)
- *
- *	- speed up scrolling by changing the screen origin
- *
  *	- add support for loadable fonts and VESA blanking
  *
  *	- for now only VGA _text_ mode is supported
@@ -385,21 +381,19 @@
 
 static void vga_write_cursor(int location)
 {
-    write_vga(14, location);
+    write_vga(14, location >> 1);
 }
 
 static void fbcon_vgafb_cursor(struct display *p, int mode, int x, int y)
 {
     switch (mode) {
 	case CM_ERASE:
-	   /* Emmanuel: hiding doesn't work properly on MediaGX.
-	      probably a Cyrix VSA bug. investigate. */
-	   vga_write_cursor(p->vrows * (p->next_line >> 1));
+	   vga_write_cursor(vga_video_mem_term - vga_video_mem_base - 1);
 	   break;
 
 	case CM_MOVE:
 	case CM_DRAW:
-	   vga_write_cursor(y*(p->next_line >> 1)+x);
+	   vga_write_cursor(y*p->next_line + (x << 1));
 	   break;
     }
 }
@@ -415,6 +409,9 @@
     u16 saved;
     u16 *p;
 
+    if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB)
+	return;
+
     vga_video_num_lines = ORIG_VIDEO_LINES;
     vga_video_num_columns = ORIG_VIDEO_COLS;
 
@@ -429,7 +426,7 @@
 	    request_region(0x3b0, 16, "ega");
 	} else {
 	    vga_video_type = VIDEO_TYPE_MDA;
-	    vga_video_mem_term = 0xb2000 + VGA_OFFSET;
+	    vga_video_mem_term = 0xb1000 + VGA_OFFSET;
 	    strcpy(fb_fix.id, "*MDA");
 	    request_region(0x3b0, 12, "mda");
 	    request_region(0x3bf, 1, "mda");
@@ -519,13 +516,15 @@
 	|| vga_video_type == VIDEO_TYPE_EGAC
 	|| vga_video_type == VIDEO_TYPE_EGAM) {
 	    video_font_height = ORIG_VIDEO_POINTS;
-	    /* This may be suboptimal but is a safe bet - go with it */
-	    video_scan_lines =
-		    video_font_height * vga_video_num_lines;
+    } else {
+            video_font_height = 16;
     }
 
-    fb_fix.smem_start = bus_to_virt(vga_video_mem_base);
-    fb_fix.smem_len = vga_video_mem_term-vga_video_mem_base;
+    /* This may be suboptimal but is a safe bet - go with it */
+    video_scan_lines = video_font_height * vga_video_num_lines;
+
+    fb_fix.smem_start = (char *) vga_video_mem_base;
+    fb_fix.smem_len = vga_video_mem_term - vga_video_mem_base;
     fb_fix.type = FB_TYPE_VGA_TEXT;
     fb_fix.type_aux = 0;
     fb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -545,7 +544,7 @@
 			  video_font_height;
 
     fb_var.xoffset = fb_var.yoffset = 0;
-    fb_var.bits_per_pixel = 4;
+    fb_var.bits_per_pixel = vga_can_do_color ? 4 : 1;
     fb_var.grayscale = !vga_can_do_color;
     fb_var.red.offset = 0;
     fb_var.red.length = 6;
@@ -580,7 +579,13 @@
     disp.cmap.green = NULL;
     disp.cmap.blue = NULL;
     disp.cmap.transp = NULL;
-    disp.screen_base = fb_fix.smem_start;
+
+#ifdef __i386__
+    disp.screen_base = ioremap((unsigned long) fb_fix.smem_start,
+				fb_fix.smem_len);
+#else
+    disp.screen_base = bus_to_virt((unsigned long) fb_fix.smem_start);
+#endif
     disp.visual = fb_fix.visual;
     disp.type = fb_fix.type;
     disp.type_aux = fb_fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/drivers/video/virgefb.c m68k/drivers/video/virgefb.c
--- m68k-current/drivers/video/virgefb.c	Thu May 14 21:34:49 1998
+++ m68k/drivers/video/virgefb.c	Mon Jun  1 11:23:01 1998
@@ -373,9 +373,9 @@
 {
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 	strcpy(fix->id, virgefb_name);
-	fix->smem_start = (caddr_t)CyberMem;
+	fix->smem_start = (char *)CyberMem;
 	fix->smem_len = CyberSize;
-	fix->mmio_start = (unsigned char *)CyberRegs;
+	fix->mmio_start = (char *)CyberRegs;
 	fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
 
 	fix->type = FB_TYPE_PACKED_PIXELS;
@@ -838,7 +838,7 @@
 	virgefb_get_fix(&fix, con, info);
 	if (con == -1)
 		con = 0;
-	display->screen_base = (u_char *)fix.smem_start;
+	display->screen_base = fix.smem_start;
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file m68k-current/include/linux/fb.h m68k/include/linux/fb.h
--- m68k-current/include/linux/fb.h	Mon Jun  1 11:32:34 1998
+++ m68k/include/linux/fb.h	Mon Jun  1 11:23:01 1998
@@ -46,12 +46,16 @@
 #define FB_ACCEL_S3_TRIO64	3	/* Cybervision64 (S3 Trio64)    */
 #define FB_ACCEL_NCR_77C32BLT	4	/* RetinaZ3 (NCR 77C32BLT)      */
 #define FB_ACCEL_S3_VIRGE	5	/* Cybervision64/3D (S3 ViRGE)	*/
-#define FB_ACCEL_ATI_MACH64	6	/* ATI Mach 64			*/
+#define FB_ACCEL_ATI_MACH64GX	6	/* ATI Mach 64GX family		*/
 #define FB_ACCEL_DEC_TGA	7	/* DEC 21030 TGA		*/
+#define FB_ACCEL_ATI_MACH64CT	8	/* ATI Mach 64CT family		*/
+#define FB_ACCEL_ATI_MACH64VT	9	/* ATI Mach 64CT family VT class */
+#define FB_ACCEL_ATI_MACH64GT	10	/* ATI Mach 64CT family GT class */
 
 struct fb_fix_screeninfo {
 	char id[16];			/* identification string eg "TT Builtin" */
 	char *smem_start;		/* Start of frame buffer mem */
+					/* (physical address) */
 	__u32 smem_len;			/* Length of frame buffer mem */
 	__u32 type;			/* see FB_TYPE_*		*/
 	__u32 type_aux;			/* Interleave for interleaved Planes */
@@ -61,6 +65,7 @@
 	__u16 ywrapstep;		/* zero if no hardware ywrap    */
 	__u32 line_length;		/* length of a line in bytes    */
 	char *mmio_start;		/* Start of Memory Mapped I/O   */
+					/* (physical address) */
 	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
 	__u32 accel;			/* Type of acceleration available */
 	__u16 reserved[3];		/* Reserved for future compatibility */
@@ -222,6 +227,7 @@
                                     /* are updated by fbcon.c */
    struct fb_cmap cmap;             /* colormap */
    char *screen_base;               /* pointer to top of virtual screen */    
+				    /* (virtual address) */
    int visual;
    int type;                        /* see FB_TYPE_* */
    int type_aux;                    /* Interleave for interleaved Planes */
--- m68k-current/drivers/block/ide-pci.c	Thu May 14 21:34:29 1998
+++ m68k/drivers/block/ide-pci.c	Mon Jun  1 15:09:38 1998
@@ -268,8 +268,9 @@
 		printk("%s: bad irq (%d): will probe later\n", d->name, pciirq);
 		pciirq = 0;
 	} else {
-#ifdef __sparc_v9__
-		printk("%s: 100%% native mode on irq %08x\n", d->name, pciirq);
+#ifdef __sparc__
+		printk("%s: 100%% native mode on irq %s\n",
+		       d->name, __irq_itoa(pciirq));
 #else
 		printk("%s: 100%% native mode on irq %d\n", d->name, pciirq);
 #endif
--- m68k-current/drivers/block/ide-probe.c	Mon Jun  1 11:34:00 1998
+++ m68k/drivers/block/ide-probe.c	Mon Jun  1 15:13:21 1998
@@ -574,14 +574,23 @@
 	hwgroup->hwif = HWIF(hwgroup->drive);
 	restore_flags(flags);	/* all CPUs; safe now that hwif->hwgroup is set up */
 
-#if !defined(__mc68000__) && !defined(CONFIG_APUS)
+#if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)
 	printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,
-		hwif->io_ports[IDE_DATA_OFFSET], hwif->io_ports[IDE_DATA_OFFSET]+7, hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);
+		hwif->io_ports[IDE_DATA_OFFSET],
+		hwif->io_ports[IDE_DATA_OFFSET]+7,
+		hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);
+#elif defined(__sparc__)
+	printk("%s at 0x%03x-0x%03x,0x%03x on irq %s", hwif->name,
+		hwif->io_ports[IDE_DATA_OFFSET],
+		hwif->io_ports[IDE_DATA_OFFSET]+7,
+		hwif->io_ports[IDE_CONTROL_OFFSET], __irq_itoa(hwif->irq));
 #else
-	printk("%s at %p on irq 0x%08x", hwif->name, hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
+	printk("%s at %p on irq 0x%08x", hwif->name,
+		hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
 #endif /* __mc68000__ && CONFIG_APUS */
 	if (match)
-		printk(" (%sed with %s)", hwif->sharing_irq ? "shar" : "serializ", match->name);
+		printk(" (%sed with %s)",
+			hwif->sharing_irq ? "shar" : "serializ", match->name);
 	printk("\n");
 	return 0;
 }
--- m68k-current/drivers/block/ide.c	Mon Jun  1 11:32:34 1998
+++ m68k/drivers/block/ide.c	Mon Jun  1 15:09:39 1998
@@ -128,446 +128,6 @@
 #endif /* CONFIG_KMOD */
 
 
-#ifdef CONFIG_BLK_DEV_PCIDE
-
-/* ------------------------- PC I/O Port IDE Driver ------------------------ */
-
-    /*
-     *  Bases of the IDE interfaces
-     */
-
-#define PCIDE_NUM_HWIFS	4
-
-#define PCIDE_BASE1	0x1f0
-#define PCIDE_BASE2	0x170
-#define PCIDE_BASE3	0x1e8
-#define PCIDE_BASE4	0x168
-
-const ide_ioreg_t pcide_bases[PCIDE_NUM_HWIFS] = {
-    PCIDE_BASE1, PCIDE_BASE2, PCIDE_BASE3, PCIDE_BASE4
-};
-
-
-    /*
-     *  Offsets from one of the above bases
-     */
-
-#define PCIDE_REG(x)	(HD_##x-PCIDE_BASE1)
-
-const int pcide_offsets[IDE_NR_PORTS] = {
-    PCIDE_REG(DATA), PCIDE_REG(ERROR), PCIDE_REG(NSECTOR), PCIDE_REG(SECTOR),
-    PCIDE_REG(LCYL), PCIDE_REG(HCYL), PCIDE_REG(CURRENT), PCIDE_REG(STATUS),
-    PCIDE_REG(CMD)
-};
-
-
-    /*
-     *  Probe for PC IDE interfaces
-     */
-
-int pcide_probe_hwif(int index, ide_hwif_t *hwif)
-{
-    static int pcide_index[PCIDE_NUM_HWIFS] = { 0, };
-    int i;
-
-    for (i = 0; i < PCIDE_NUM_HWIFS; i++) {
-	if (!pcide_index[i]) {
-	    printk("ide%d: PC IDE interface\n", index);
-	    pcide_index[i] = index+1;
-	}
-	if (pcide_index[i] == index+1) {
-	    ide_setup_ports(hwif, pcide_bases[i], pcide_offsets, 0, NULL);
-	    hwif->irq = 0;
-	    return 1;
-	}
-    }
-    return 0;
-}
-
-#endif
-
-
-#ifdef CONFIG_BLK_DEV_GAYLE
-
-/* ------------------------- Amiga Gayle IDE Driver ------------------------ */
-
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-
-
-    /*
-     *  Bases of the IDE interfaces
-     */
-
-#define GAYLE_BASE_4000	0xdd2020	/* A4000/A4000T */
-#define GAYLE_BASE_1200	0xda0000	/* A1200/A600 */
-
-    /*
-     *  Offsets from one of the above bases
-     */
-
-#define GAYLE_DATA	0x00
-#define GAYLE_ERROR	0x06		/* see err-bits */
-#define GAYLE_NSECTOR	0x0a		/* nr of sectors to read/write */
-#define GAYLE_SECTOR	0x0e		/* starting sector */
-#define GAYLE_LCYL	0x12		/* starting cylinder */
-#define GAYLE_HCYL	0x16		/* high byte of starting cyl */
-#define GAYLE_SELECT	0x1a		/* 101dhhhh , d=drive, hhhh=head */
-#define GAYLE_STATUS	0x1e		/* see status-bits */
-#define GAYLE_CONTROL	0x101a
-
-u_int gayle_offsets[IDE_NR_PORTS] = {
-    GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL,
-    GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, GAYLE_CONTROL
-};
-
-
-    /*
-     *  These are at different offsets from the base
-     */
-
-#define GAYLE_IRQ_4000	0xdd3020	/* MSB = 1, Harddisk is source of */
-#define GAYLE_IRQ_1200	0xda9000	/* interrupt */
-
-
-    /*
-     *  Offset of the secondary port for IDE doublers
-     *  Note that GAYLE_CONTROL is NOT available then!
-     */
-
-#define GAYLE_NEXT_PORT	0x1000
-
-#ifndef CONFIG_BLK_DEV_IDEDOUBLER
-#define GAYLE_NUM_HWIFS		1
-#define GAYLE_NUM_PROBE_HWIFS	GAYLE_NUM_HWIFS
-#define GAYLE_HAS_CONTROL_REG	1
-#else /* CONFIG_BLK_DEV_IDEDOUBLER */
-#define GAYLE_NUM_HWIFS		2
-#define GAYLE_NUM_PROBE_HWIFS	(ide_doubler ? GAYLE_NUM_HWIFS : \
-					       GAYLE_NUM_HWIFS-1)
-#define GAYLE_HAS_CONTROL_REG	(!ide_doubler)
-int ide_doubler = 0;	/* support IDE doublers? */
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-
-
-    /*
-     *  Check and acknowledge the interrupt status
-     */
-
-static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
-{
-    unsigned char ch;
-
-    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
-    if (!(ch & 0x80))
-	return 0;
-    return 1;
-}
-
-static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
-{
-    unsigned char ch;
-
-    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
-    if (!(ch & 0x80))
-	return 0;
-    (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
-    outb(0x7c | (ch & 0x03), hwif->io_ports[IDE_IRQ_OFFSET]);
-    return 1;
-}
-
-
-    /*
-     *  Probe for a Gayle IDE interface (and optionally for an IDE doubler)
-     */
-
-int gayle_probe_hwif(int index, ide_hwif_t *hwif)
-{
-    static int gayle_index[GAYLE_NUM_HWIFS] = { 0, };
-    int a4000, i;
-
-    if (!MACH_IS_AMIGA)
-	return 0;
-
-    if (!(a4000 = AMIGAHW_PRESENT(A4000_IDE)) && !AMIGAHW_PRESENT(A1200_IDE))
-	return 0;
-
-    if (!GAYLE_HAS_CONTROL_REG)
-	gayle_offsets[IDE_CONTROL_OFFSET] = -1;
-
-    for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
-	if (!gayle_index[i]) {
-	    switch (i) {
-		case 0:
-		    printk("ide%d: Gayle IDE interface (A%d style)\n", index,
-			   a4000 ? 4000 : 1200);
-		    break;
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
-		case 1:
-		    printk("ide%d: IDE doubler\n", index);
-		    break;
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-	    }
-	    gayle_index[i] = index+1;
-	}
-	if (gayle_index[i] == index+1) {
-	    ide_ioreg_t base, irqport;
-	    ide_ack_intr_t *ack_intr;
-	    if (a4000) {
-		base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_4000);
-		irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000);
-		ack_intr = gayle_ack_intr_a4000;
-	    } else {
-		base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_1200);
-		irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200);
-		ack_intr = gayle_ack_intr_a1200;
-	    }
-	    base += i*GAYLE_NEXT_PORT;
-	    ide_setup_ports(hwif, base, gayle_offsets, irqport, ack_intr);
-#if 1 /* TESTING */
-	    if (i == 1) {
-		volatile u_short *addr = (u_short *)base;
-		u_short data;
-		printk("+++ Probing for IDE doubler... ");
-		*addr = 0xffff;
-		data = *addr;
-		printk("probe returned 0x%02x (PLEASE REPORT THIS!!)\n", data);
-	    }
-#endif /* TESTING */
-	    hwif->irq = IRQ_AMIGA_PORTS;
-	    return 1;
-	}
-    }
-    return 0;
-}
-
-#endif /* CONFIG_BLK_DEV_GAYLE */
-
-
-#ifdef CONFIG_BLK_DEV_FALCON_IDE
-
-/* ------------------------ Atari Falcon IDE Driver ------------------------ */
-
-#include <asm/atarihw.h>
-#include <asm/atariints.h>
-
-
-    /*
-     *  Base of the IDE interface
-     */
-
-#define ATA_HD_BASE	0xfff00000
-
-    /*
-     *  Offsets from the above base
-     */
-
-#define ATA_HD_DATA	0x00
-#define ATA_HD_ERROR	0x05		/* see err-bits */
-#define ATA_HD_NSECTOR	0x09		/* nr of sectors to read/write */
-#define ATA_HD_SECTOR	0x0d		/* starting sector */
-#define ATA_HD_LCYL	0x11		/* starting cylinder */
-#define ATA_HD_HCYL	0x15		/* high byte of starting cyl */
-#define ATA_HD_SELECT	0x19		/* 101dhhhh , d=drive, hhhh=head */
-#define ATA_HD_STATUS	0x1d		/* see status-bits */
-#define ATA_HD_CONTROL	0x39
-
-const int falconide_offsets[IDE_NR_PORTS] = {
-    ATA_HD_DATA, ATA_HD_ERROR, ATA_HD_NSECTOR, ATA_HD_SECTOR, ATA_HD_LCYL,
-    ATA_HD_HCYL, ATA_HD_SELECT, ATA_HD_STATUS, ATA_HD_CONTROL
-};
-
-
-    /*
-     *  Probe for a Falcon IDE interface
-     */
-
-int falconide_probe_hwif(int index, ide_hwif_t *hwif)
-{
-    static int falcon_index = 0;
-
-    if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
-	return 0;
-
-    if (!falcon_index) {
-	printk("ide%d: Falcon IDE interface\n", index);
-	falcon_index = index+1;
-    }
-    if (falcon_index == index+1) {
-	ide_setup_ports(hwif, (ide_ioreg_t)ATA_HD_BASE, falconide_offsets, 0,
-			NULL);
-	hwif->irq = IRQ_MFP_IDE;
-	return 1;
-    }
-    return 0;
-}
-
-#endif /* CONFIG_BLK_DEV_FALCON_IDE */
-
-
-#ifdef CONFIG_BLK_DEV_BUDDHA
-
-/* ----------------- Amiga Buddha and Catweasel IDE Driver ----------------- */
-
-/*
- *  This driver was written by Geert Uytterhoeven based on the specifications
- *  in README.buddha.
- *
- *  TODO:
- *    - test it :-)
- *    - tune the timings using the speed-register
- */
-
-#include <linux/zorro.h>
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-
-
-    /*
-     *  The Buddha has 2 IDE interfaces, the Catweasel has 3
-     */
-
-#define BUDDHA_NUM_HWIFS	2
-#define CATWEASEL_NUM_HWIFS	3
-
-
-    /*
-     *  Bases of the IDE interfaces (relative to the board address)
-     */
-
-#define BUDDHA_BASE1	0x800
-#define BUDDHA_BASE2	0xa00
-#define BUDDHA_BASE3	0xc00
-
-const u_int buddha_bases[CATWEASEL_NUM_HWIFS] = {
-    BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
-};
-
-
-    /*
-     *  Offsets from one of the above bases
-     */
-
-#define BUDDHA_DATA	0x00
-#define BUDDHA_ERROR	0x06		/* see err-bits */
-#define BUDDHA_NSECTOR	0x0a		/* nr of sectors to read/write */
-#define BUDDHA_SECTOR	0x0e		/* starting sector */
-#define BUDDHA_LCYL	0x12		/* starting cylinder */
-#define BUDDHA_HCYL	0x16		/* high byte of starting cyl */
-#define BUDDHA_SELECT	0x1a		/* 101dhhhh , d=drive, hhhh=head */
-#define BUDDHA_STATUS	0x1e		/* see status-bits */
-#define BUDDHA_CONTROL	0x11a
-
-const u_int buddha_offsets[IDE_NR_PORTS] = {
-    BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL,
-    BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL
-};
-
-
-    /*
-     *  Other registers
-     */
-
-#define BUDDHA_IRQ1	0xf00		/* MSB = 1, Harddisk is source of */
-#define BUDDHA_IRQ2	0xf40		/* interrupt */
-#define BUDDHA_IRQ3	0xf80
-
-const int buddha_irqports[CATWEASEL_NUM_HWIFS] = {
-    BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3
-};
-
-#define BUDDHA_IRQ_MR	0xfc0		/* master interrupt enable */
-
-
-    /*
-     *  Board information
-     */
-
-static u_long buddha_board = 0;
-static int buddha_num_hwifs = -1;
-
-
-    /*
-     *  Check and acknowledge the interrupt status
-     */
-
-static int buddha_ack_intr(ide_hwif_t *hwif)
-{
-    unsigned char ch;
-
-    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
-    if (!(ch & 0x80))
-	return 0;
-    return 1;
-}
-
-
-    /*
-     *  Any Buddha or Catweasel boards present?
-     */
-
-int find_buddha(void)
-{
-    u_int key;
-    const struct ConfigDev *cd;
-
-    buddha_num_hwifs = 0;
-    if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA, 0, 0)))
-	buddha_num_hwifs = BUDDHA_NUM_HWIFS;
-    else if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL, 0,
-			       0)))
-	buddha_num_hwifs = CATWEASEL_NUM_HWIFS;
-    if (key) {
-	cd = zorro_get_board(key);
-	buddha_board = (u_long)cd->cd_BoardAddr;
-	if (buddha_board) {
-	    buddha_board = ZTWO_VADDR(buddha_board);
-	    /* write to BUDDHA_IRQ_MR to enable the board IRQ */
-	    *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0;
-	    zorro_config_board(key, 0);
-	}
-    }
-    return buddha_num_hwifs;
-}
-
-
-    /*
-     *  Probe for a Buddha or Catweasel IDE interface
-     *  We support only _one_ of them, no multiple boards!
-     */
-
-int buddha_probe_hwif(int index, ide_hwif_t *hwif)
-{
-    static int buddha_index[CATWEASEL_NUM_HWIFS] = { 0, };
-    int i;
-
-    if (buddha_num_hwifs < 0 && !find_buddha())
-	return 0;
-
-    for (i = 0; i < buddha_num_hwifs; i++) {
-	if (!buddha_index[i]) {
-	    printk("ide%d: %s IDE interface\n", index,
-		   buddha_num_hwifs == BUDDHA_NUM_HWIFS ? "Buddha" :
-		   					  "Catweasel");
-	    buddha_index[i] = index+1;
-	}
-	if (buddha_index[i] == index+1) {
-	    ide_setup_ports(hwif, (ide_ioreg_t)(buddha_board+buddha_bases[i]),
-	    		    buddha_offsets,
-			    (ide_ioreg_t)(buddha_board+buddha_irqports[i]),
-			    buddha_ack_intr);
-	    hwif->irq = IRQ_AMIGA_PORTS;
-	    return 1;
-	}
-    }
-    return 0;
-}
-
-#endif /* CONFIG_BLK_DEV_BUDDHA */
-
-/* ------------------------- End of Low Level Stuff ------------------------ */
-
-
 static const byte	ide_hwif_to_major[] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR };
 
 static int	idebus_parameter; /* holds the "idebus=" parameter */
@@ -660,6 +220,12 @@
  */
 static int probe_hwif(int index, ide_hwif_t *hwif)
 {
+    extern int pcide_probe_hwif(int index, ide_hwif_t *hwif);
+    extern int gayle_probe_hwif(int index, ide_hwif_t *hwif);
+    extern int falconide_probe_hwif(int index, ide_hwif_t *hwif);
+    extern int macide_probe_hwif(int index, ide_hwif_t *hwif);
+    extern int buddha_probe_hwif(int index, ide_hwif_t *hwif);
+
     return 0
 #ifdef CONFIG_BLK_DEV_PCIDE
 	|| pcide_probe_hwif(index, hwif)
@@ -670,6 +236,9 @@
 #ifdef CONFIG_BLK_DEV_FALCON_IDE
 	|| falconide_probe_hwif(index, hwif)
 #endif
+#ifdef CONFIG_BLK_DEV_MAC_IDE
+	|| macide_probe_hwif(index, hwif)
+#endif
 #ifdef CONFIG_BLK_DEV_BUDDHA
 	|| buddha_probe_hwif(index, hwif)
 #endif
@@ -3222,7 +2791,7 @@
 #ifdef CONFIG_BLK_DEV_IDE
 #if defined(__mc68000__) || defined(CONFIG_APUS)
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
-		ide_get_lock(&ide_lock, NULL, NULL);	/* for atari only */
+		ide_get_lock(&ide_lock, NULL, NULL);
 		disable_irq(ide_hwifs[0].irq);
 	}
 #endif /* __mc68000__ || CONFIG_APUS */
@@ -3232,9 +2801,9 @@
 #if defined(__mc68000__) || defined(CONFIG_APUS)
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
 		enable_irq(ide_hwifs[0].irq);
-		ide_release_lock(&ide_lock);	/* for atari only */
+		ide_release_lock(&ide_lock);
 	}
-#endif /* __mc68000__ || CONFIG_APUS */
+#endif /* __mc68000__ || CONFIG_APUS*/
 #endif /* CONFIG_BLK_DEV_IDE */
 
 #ifdef CONFIG_PROC_FS
--- m68k-current/drivers/block/ide.h	Thu May 14 21:34:30 1998
+++ m68k/drivers/block/ide.h	Mon Jun  1 15:13:58 1998
@@ -311,7 +311,8 @@
 		ide_cmd640,	ide_dtc2278,	ide_ali14xx,
 		ide_qd6580,	ide_umc8672,	ide_ht6560b,
 		ide_pdc4030,	ide_rz1000,	ide_trm290,
-		ide_4drives
+		ide_cmd646,	ide_4drives,	ide_gayle,
+		ide_falcon,	ide_mac,	ide_buddha
 	} hwif_chipset_t;
 
 typedef struct ide_pci_devid_s {
--- m68k-current/drivers/block/sl82c105.c	Thu May 14 21:34:31 1998
+++ m68k/drivers/block/sl82c105.c	Mon Jun  1 15:09:40 1998
@@ -38,7 +38,10 @@
 	pci_write_config_dword(dev, 0x40, 0x10ff08a1);
 }
 
-#if 0	/* nobody ever calls these.. ?? */
+/* nobody ever calls these.. ??  -mlord
+ *
+ * Yes somebody certainly does, check asm-ppc/ide.h for the place.  -DaveM
+ */
 void chrp_ide_probe(void) {
 
 	struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL);
@@ -68,4 +71,3 @@
         if (irq != NULL)
                 *irq = chrp_ide_irq;
 }
-#endif
--- m68k-current/drivers/block/Config.in	Thu May 14 21:34:24 1998
+++ m68k/drivers/block/Config.in	Mon Jun  1 13:15:17 1998
@@ -4,12 +4,20 @@
 mainmenu_option next_comment
 comment 'Floppy, IDE, and other block devices'
 
-tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
+tristate 'Normal PC floppy disk support' CONFIG_BLK_DEV_FD
+if [ "$CONFIG_AMIGA" = "y" ]; then
+  tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY
+fi
+if [ "$CONFIG_ATARI" = "y" ]; then
+  tristate 'Atari floppy support' CONFIG_ATARI_FLOPPY
+fi
+if [ "$CONFIG_MAC" = "y" ]; then
+  tristate 'Macintosh IWM floppy support' CONFIG_MAC_FLOPPY_IWM
+fi
+
 tristate 'Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE
 comment 'Please see Documentation/ide.txt for help/info on IDE drives'
 
-define_bool CONFIG_BLK_DEV_PCIDE $CONFIG_BLK_DEV_IDE
-
 if [ "$CONFIG_BLK_DEV_IDE" = "n" ]; then
   bool 'Old harddisk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY
 else
@@ -20,6 +28,20 @@
   dep_tristate '   Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
   dep_tristate '   SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE
   if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
+    bool '   Generic PC I/O-port driver' CONFIG_BLK_DEV_PCIDE
+    if [ "$CONFIG_AMIGA" = "y" ]; then
+      bool '   Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	bool '   Buddha/Catweasel IDE interface support' CONFIG_BLK_DEV_BUDDHA
+	bool '   Amiga IDE Doubler support' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE
+      fi
+    fi
+    if [ "$CONFIG_ATARI" = "y" ]; then
+      bool '   Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE
+    fi
+    if [ "$CONFIG_MAC" = "y" ]; then
+      bool '   Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE
+    fi
     bool '   CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640
     if [ "$CONFIG_BLK_DEV_CMD640" = "y" ]; then
       bool '     CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED
@@ -58,6 +80,17 @@
 fi
 if [ "$CONFIG_MCA" = "y" ]; then
   bool 'PS/2 ESDI harddisk support' CONFIG_BLK_DEV_PS2
+fi
+if [ "$CONFIG_AMIGA" = "y" ]; then
+  tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
+fi
+if [ "$CONFIG_ATARI" = "y" ]; then
+  tristate 'Atari ACSI support' CONFIG_ATARI_ACSI
+  if [ "$CONFIG_ATARI_ACSI" != "n" ]; then
+    comment 'Some devices (e.g. CD jukebox) support multiple LUNs'
+    bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN
+    dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
+  fi
 fi
 
 comment 'Additional Block Devices'
--- m68k-current/drivers/block/Makefile	Thu May 14 21:34:24 1998
+++ m68k/drivers/block/Makefile	Mon Jun  1 13:21:13 1998
@@ -26,6 +26,8 @@
 LX_OBJS := ll_rw_blk.o genhd.o
 MX_OBJS :=
 
+IDE_OBJS :=
+
 ifeq ($(CONFIG_MSDOS_PARTITION),y)
   L_OBJS += partbl_msdos.o
 else
@@ -78,6 +80,10 @@
 L_OBJS += swim3.o
 endif
 
+ifeq ($(CONFIG_MAC_FLOPPY_IWM),y)
+L_OBJS += iwm.o
+endif
+
 ifeq ($(CONFIG_BLK_DEV_FD),y)
 L_OBJS += floppy.o
 else
@@ -146,21 +152,6 @@
 L_OBJS += hd.o
 endif
 
-ifeq ($(CONFIG_BLK_DEV_IDE),y)
-  LX_OBJS += ide.o
-  ifeq ($(CONFIG_PROC_FS),y)
-    L_OBJS += ide-proc.o
-  endif
-  L_OBJS += ide-probe.o
-else
-  ifeq ($(CONFIG_BLK_DEV_IDE),m)
-  MIX_OBJS += ide.o
-  # ide-mod includes ide-proc
-  M_OBJS += ide-mod.o
-  MX_OBJS += ide-probe.o
-  endif
-endif
-
 ifeq ($(CONFIG_BLK_DEV_RZ1000),y)
 L_OBJS += rz1000.o
 endif
@@ -182,39 +173,59 @@
 endif
 
 ifeq ($(CONFIG_BLK_DEV_DTC2278),y)
-L_OBJS += dtc2278.o
+IDE_OBJS += dtc2278.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_HT6560B),y)
-L_OBJS += ht6560b.o
+IDE_OBJS += ht6560b.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_QD6580),y)
-L_OBJS += qd6580.o
+IDE_OBJS += qd6580.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_UMC8672),y)
-L_OBJS += umc8672.o
+IDE_OBJS += umc8672.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_ALI14XX),y)
-L_OBJS += ali14xx.o
+IDE_OBJS += ali14xx.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_PDC4030),y)
-L_OBJS += pdc4030.o
+IDE_OBJS += pdc4030.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_TRM290),y)
-L_OBJS += trm290.o
+IDE_OBJS += trm290.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_OPTI621),y)
-L_OBJS += opti621.o
+IDE_OBJS += opti621.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_NS87415),y)
-L_OBJS += ns87415.o
+IDE_OBJS += ns87415.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_PCIDE),y)
+IDE_OBJS += pcide.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_GAYLE),y)
+IDE_OBJS += gayle.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_FALCON_IDE),y)
+IDE_OBJS += falconide.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_MAC_IDE),y)
+IDE_OBJS += macide.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_BUDDHA),y)
+IDE_OBJS += buddha.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_CMD646),y)
@@ -319,7 +330,22 @@
   endif
 endif
 
+ifeq ($(CONFIG_BLK_DEV_IDE),y)
+  LX_OBJS += ide.o
+  ifeq ($(CONFIG_PROC_FS),y)
+    L_OBJS += ide-proc.o
+  endif
+  L_OBJS += ide-probe.o $(IDE_OBJS)
+else
+  ifeq ($(CONFIG_BLK_DEV_IDE),m)
+  MIX_OBJS += ide.o
+  # ide-mod includes ide-proc and IDE_OBJS
+  M_OBJS += ide-mod.o
+  MX_OBJS += ide-probe.o
+  endif
+endif
+
 include $(TOPDIR)/Rules.make
 
-ide-mod.o: ide.o ide-proc.o
-	$(LD) $(LD_RFLAG) -r -o $@ ide.o ide-proc.o
+ide-mod.o: ide.o ide-proc.o $(IDE_OBJS)
+	$(LD) $(LD_RFLAG) -r -o $@ ide.o ide-proc.o $(IDE_OBJS)
--- m68k-current/include/asm-alpha/ide.h	Thu May 14 21:34:52 1998
+++ m68k/include/asm-alpha/ide.h	Mon Jun  1 14:42:44 1998
@@ -85,19 +85,10 @@
 /*
  * The following are not needed for the non-m68k ports
  */
-#define ide_ack_intr(hwif)	(1)
-
-static __inline__ void ide_fix_driveid(struct hd_driveid *id)
-{
-}
-
-static __inline__ void ide_release_lock (int *ide_lock)
-{
-}
-
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
-{
-}
+#define ide_ack_intr(hwif)		(1)
+#define ide_fix_driveid(id)		do {} while (0)      
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
 #endif /* __KERNEL__ */
 
--- m68k-current/include/asm-arm/ide.h	Thu May 14 21:34:53 1998
+++ m68k/include/asm-arm/ide.h	Mon Jun  1 14:41:05 1998
@@ -63,22 +63,10 @@
 /*
  * The following are not needed for the non-m68k ports
  */
-static __inline__ int ide_ack_intr (ide_ioreg_t status_port, ide_ioreg_t irq_port)
-{
-	return(1);
-}
-
-static __inline__ void ide_fix_driveid(struct hd_driveid *id)
-{
-}
-
-static __inline__ void ide_release_lock (int *ide_lock)
-{
-}
-
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
-{
-}
+#define ide_ack_intr(hwif)		(1)
+#define ide_fix_driveid(id)		do {} while (0)
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
 #endif /* __KERNEL__ */
 
--- m68k-current/include/asm-i386/ide.h	Thu May 14 21:34:54 1998
+++ m68k/include/asm-i386/ide.h	Mon Jun  1 14:43:21 1998
@@ -87,19 +87,10 @@
 /*
  * The following are not needed for the non-m68k ports
  */
-#define ide_ack_intr(hwif)	(1)
-
-static __inline__ void ide_fix_driveid(struct hd_driveid *id)
-{
-}
-
-static __inline__ void ide_release_lock (int *ide_lock)
-{
-}
-
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
-{
-}
+#define ide_ack_intr(hwif)		(1)
+#define ide_fix_driveid(id)		do {} while (0)      
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
 #endif /* __KERNEL__ */
 
--- m68k-current/include/asm-m68k/ide.h	Mon Jun  1 11:34:01 1998
+++ m68k/include/asm-m68k/ide.h	Mon Jun  1 12:00:05 1998
@@ -41,6 +41,10 @@
 #include <asm/atari_stdma.h>
 #endif
 
+#ifdef CONFIG_MAC
+#include <asm/macints.h>
+#endif
+
 typedef unsigned char * ide_ioreg_t;
 
 #ifndef MAX_HWIFS
@@ -73,6 +77,10 @@
 	} b;
 	} select_t;
 
+#ifdef CONFIG_MAC	/* MSch: Hack; wrapper for ide_intr */
+void mac_ide_intr(int irq, void *dev_id, struct pt_regs *regs);
+#endif
+
 static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
 			unsigned long flags, const char *device, void *dev_id)
 {
@@ -80,6 +88,14 @@
 	if (MACH_IS_AMIGA)
 		return request_irq(irq, handler, 0, device, dev_id);
 #endif /* CONFIG_AMIGA */
+#ifdef CONFIG_MAC
+	if (MACH_IS_MAC)
+#if 0	/* MSch Hack: maybe later we'll call ide_intr without a wrapper */
+	return nubus_request_irq(12, dev_id, handler);
+#else
+	return nubus_request_irq(12, dev_id, mac_ide_intr);
+#endif
+#endif /* CONFIG_MAC */
 	return 0;
 }
 
@@ -89,6 +105,10 @@
 	if (MACH_IS_AMIGA)
 		free_irq(irq, dev_id);
 #endif /* CONFIG_AMIGA */
+#ifdef CONFIG_MAC
+	if (MACH_IS_MAC)
+		nubus_free_irq(12);
+#endif /* CONFIG_MAC */
 }
 
 /*
@@ -308,11 +328,11 @@
 #define D_INT(cnt)      (T_INT   | (cnt))
 #define D_TEXT(cnt)     (T_TEXT  | (cnt))
 
-#ifdef CONFIG_AMIGA
+#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
 static u_short driveid_types[] = {
 	D_SHORT(10),	/* config - vendor2 */
 	D_TEXT(20),	/* serial_no */
-	D_SHORT(3),	/* buf_type - ecc_bytes */
+	D_SHORT(3),	/* buf_type, buf_size - ecc_bytes */
 	D_TEXT(48),	/* fw_rev - model */
 	D_CHAR(2),	/* max_multsect - vendor3 */
 	D_SHORT(1),	/* dword_io */
@@ -331,12 +351,12 @@
 
 static __inline__ void ide_fix_driveid(struct hd_driveid *id)
 {
-#ifdef CONFIG_AMIGA
+#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
    u_char *p = (u_char *)id;
    int i, j, cnt;
    u_char t;
 
-   if (!MACH_IS_AMIGA)
+   if (!MACH_IS_AMIGA && !MACH_IS_MAC)
    	return;
    for (i = 0; i < num_driveid_types; i++) {
       cnt = driveid_types[i] & T_MASK_COUNT;
@@ -421,7 +441,7 @@
  * an interrupt, and in that case it does nothing. Hope that is reasonable and
  * works. (Roman)
  */
-#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA)
+#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC)
 #define	ide__sti()					\
     do {						\
 	if (!in_interrupt()) __sti();			\
--- m68k-current/include/asm-mips/ide.h	Thu May 14 21:34:55 1998
+++ m68k/include/asm-mips/ide.h	Mon Jun  1 14:50:32 1998
@@ -16,7 +16,7 @@
 typedef unsigned short ide_ioreg_t;
 
 #ifndef MAX_HWIFS
-#define MAX_HWIFS	4
+#define MAX_HWIFS	6
 #endif
 
 #define ide__sti()	__sti()
@@ -68,7 +68,7 @@
 			unsigned long flags, const char *device, void *dev_id)
 {
 	return ide_ops->ide_request_irq(irq, handler, flags, device, dev_id);
-{
+}
 
 static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
 {
@@ -95,26 +95,10 @@
 /*
  * The following are not needed for the non-m68k ports
  */
-static __inline__ int ide_ack_intr (ide_ioreg_t status_port,
-                                    ide_ioreg_t irq_port)
-{
-	return 1;
-}
-
-static __inline__ void ide_fix_driveid(struct hd_driveid *id)
-{
-}
-
-static __inline__ void ide_release_lock (int *ide_lock)
-{
-}
-
-static __inline__ void ide_get_lock (int *ide_lock,
-                                     void (*handler)(int, void *,
-                                                    struct pt_regs *),
-                                     void *data)
-{
-}
+#define ide_ack_intr(hwif)		(1)
+#define ide_fix_driveid(id)		do {} while (0)      
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
 #endif /* __KERNEL__ */
 
--- m68k-current/include/asm-ppc/ide.h	Thu May 14 21:34:57 1998
+++ m68k/include/asm-ppc/ide.h	Mon Jun  1 15:33:07 1998
@@ -11,6 +11,31 @@
 #ifndef __ASMPPC_IDE_H
 #define __ASMPPC_IDE_H
 
+#include <linux/config.h>
+#ifdef CONFIG_APUS
+#include <linux/hdreg.h>
+#include <asm-m68k/ide.h>
+void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq);
+void ide_insw(ide_ioreg_t port, void *buf, int ns);
+void ide_outsw(ide_ioreg_t port, void *buf, int ns);
+#undef insw
+#define insw(port, buf, ns) 	do {			\
+	if ( _machine != _MACH_Pmac && _machine != _MACH_apus )	\
+		/* this must be the same as insw in io.h!! */	\
+		_insw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \
+	else						\
+		ide_insw((port), (buf), (ns));		\
+} while (0)
+#undef outsw
+#define outsw(port, buf, ns) 	do {			\
+	if ( _machine != _MACH_Pmac && _machine != _MACH_apus )	\
+		/* this must be the same as outsw in io.h!! */	\
+		_outsw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \
+	else						\
+		ide_outsw((port), (buf), (ns));		\
+} while (0)
+#else /* CONFIG_APUS */
+
 #ifdef __KERNEL__
 
 #include <linux/ioport.h>
@@ -181,16 +206,11 @@
 /*
  * The following are not needed for the non-m68k ports
  */
-#define ide_ack_intr(hwif)	(1)
-
-static __inline__ void ide_release_lock (int *ide_lock)
-{
-}
-
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
-{
-}
+#define ide_ack_intr(hwif)		(1)
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
 #endif /* __KERNEL__ */
+#endif /* CONFIG_APUS */
 
 #endif /* __ASMPPC_IDE_H */
--- m68k-current/include/asm-sparc64/ide.h	Thu May 14 21:34:58 1998
+++ m68k/include/asm-sparc64/ide.h	Mon Jun  1 14:44:45 1998
@@ -90,10 +90,7 @@
 #undef  HD_DATA
 #define HD_DATA ((ide_ioreg_t)0)
 
-static __inline__ int ide_ack_intr(ide_hwif_t *hwif)
-{
-	return 1;
-}
+#define ide_ack_intr(hwif)		(1)
 
 /* From m68k code... */
 
@@ -269,13 +266,8 @@
 	}
 }
 
-static __inline__ void ide_release_lock (int *ide_lock)
-{
-}
-
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
-{
-}
+#define ide_release_lock(lock)          do {} while (0)
+#define ide_get_lock(lock, hdlr, data)  do {} while (0)
 
 #endif /* __KERNEL__ */
 
--- m68k-current/Documentation/Configure.help	Thu May 14 21:34:04 1998
+++ m68k/Documentation/Configure.help	Mon Jun  1 15:54:08 1998
@@ -474,6 +474,12 @@
   I/O speeds to be set as well.  See the Documentation/ide.txt and
   ali14xx.c files for more info.
 
+Generic PC I/O port IDE interface support
+CONFIG_BLK_DEV_PCIDE
+  This is the IDE driver for most generic PC style IDE interfaces.
+  Say Y if you have a PC and want to use IDE devices (hard disks, CD-ROM
+  drives, etc.) that are connected to the builtin IDE interface.
+
 Amiga builtin Gayle IDE interface support
 CONFIG_BLK_DEV_GAYLE
   This is the IDE driver for the builtin IDE interface on some Amiga
--- /dev/null	Sat Jun 17 03:20:38 1995
+++ m68k/drivers/block/buddha.c	Sun Apr  5 23:23:26 1998
@@ -0,0 +1,168 @@
+/*
+ *  linux/drivers/block/buddha.c -- Amiga Buddha and Catweasel IDE Driver
+ *
+ *	Copyright (C) 1997 by Geert Uytterhoeven
+ *
+ *  This driver was written by based on the specifications in README.buddha.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ *
+ *  TODO:
+ *    - test it :-)
+ *    - tune the timings using the speed-register
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/zorro.h>
+
+#include "ide.h"
+
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+
+
+    /*
+     *  The Buddha has 2 IDE interfaces, the Catweasel has 3
+     */
+
+#define BUDDHA_NUM_HWIFS	2
+#define CATWEASEL_NUM_HWIFS	3
+
+
+    /*
+     *  Bases of the IDE interfaces (relative to the board address)
+     */
+
+#define BUDDHA_BASE1	0x800
+#define BUDDHA_BASE2	0xa00
+#define BUDDHA_BASE3	0xc00
+
+static const u_int buddha_bases[CATWEASEL_NUM_HWIFS] = {
+    BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
+};
+
+
+    /*
+     *  Offsets from one of the above bases
+     */
+
+#define BUDDHA_DATA	0x00
+#define BUDDHA_ERROR	0x06		/* see err-bits */
+#define BUDDHA_NSECTOR	0x0a		/* nr of sectors to read/write */
+#define BUDDHA_SECTOR	0x0e		/* starting sector */
+#define BUDDHA_LCYL	0x12		/* starting cylinder */
+#define BUDDHA_HCYL	0x16		/* high byte of starting cyl */
+#define BUDDHA_SELECT	0x1a		/* 101dhhhh , d=drive, hhhh=head */
+#define BUDDHA_STATUS	0x1e		/* see status-bits */
+#define BUDDHA_CONTROL	0x11a
+
+static const u_int buddha_offsets[IDE_NR_PORTS] = {
+    BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL,
+    BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL
+};
+
+
+    /*
+     *  Other registers
+     */
+
+#define BUDDHA_IRQ1	0xf00		/* MSB = 1, Harddisk is source of */
+#define BUDDHA_IRQ2	0xf40		/* interrupt */
+#define BUDDHA_IRQ3	0xf80
+
+static const int buddha_irqports[CATWEASEL_NUM_HWIFS] = {
+    BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3
+};
+
+#define BUDDHA_IRQ_MR	0xfc0		/* master interrupt enable */
+
+
+    /*
+     *  Board information
+     */
+
+static u_long buddha_board = 0;
+static int buddha_num_hwifs = -1;
+
+
+    /*
+     *  Check and acknowledge the interrupt status
+     */
+
+static int buddha_ack_intr(ide_hwif_t *hwif)
+{
+    unsigned char ch;
+
+    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    if (!(ch & 0x80))
+	return 0;
+    return 1;
+}
+
+
+    /*
+     *  Any Buddha or Catweasel boards present?
+     */
+
+static int find_buddha(void)
+{
+    u_int key;
+    const struct ConfigDev *cd;
+
+    buddha_num_hwifs = 0;
+    if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA, 0, 0)))
+	buddha_num_hwifs = BUDDHA_NUM_HWIFS;
+    else if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL, 0,
+			       0)))
+	buddha_num_hwifs = CATWEASEL_NUM_HWIFS;
+    if (key) {
+	cd = zorro_get_board(key);
+	buddha_board = (u_long)cd->cd_BoardAddr;
+	if (buddha_board) {
+	    buddha_board = ZTWO_VADDR(buddha_board);
+	    /* write to BUDDHA_IRQ_MR to enable the board IRQ */
+	    *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0;
+	    zorro_config_board(key, 0);
+	}
+    }
+    return buddha_num_hwifs;
+}
+
+
+    /*
+     *  Probe for a Buddha or Catweasel IDE interface
+     *  We support only _one_ of them, no multiple boards!
+     */
+
+int buddha_probe_hwif(int index, ide_hwif_t *hwif)
+{
+    static int buddha_index[CATWEASEL_NUM_HWIFS] = { 0, };
+    int i;
+
+    if (buddha_num_hwifs < 0 && !find_buddha())
+	return 0;
+
+    for (i = 0; i < buddha_num_hwifs; i++) {
+	if (!buddha_index[i]) {
+	    printk("ide%d: %s IDE interface\n", index,
+		   buddha_num_hwifs == BUDDHA_NUM_HWIFS ? "Buddha" :
+		   					  "Catweasel");
+	    buddha_index[i] = index+1;
+	}
+	if (buddha_index[i] == index+1) {
+	    ide_setup_ports(hwif, (ide_ioreg_t)(buddha_board+buddha_bases[i]),
+	    		    buddha_offsets,
+			    (ide_ioreg_t)(buddha_board+buddha_irqports[i]),
+			    buddha_ack_intr);
+	    hwif->irq = IRQ_AMIGA_PORTS;
+	    return 1;
+	}
+    }
+    return 0;
+}
--- /dev/null	Sat Jun 17 03:20:38 1995
+++ m68k/drivers/block/falconide.c	Sun Apr  5 23:23:26 1998
@@ -0,0 +1,72 @@
+/*
+ *  linux/drivers/block/falconide.c -- Atari Falcon IDE Driver
+ *
+ *     Created 12 Jul 1997 by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+
+#include "ide.h"
+
+#include <asm/atarihw.h>
+#include <asm/atariints.h>
+#include <asm/atari_stdma.h>
+
+
+    /*
+     *  Base of the IDE interface
+     */
+
+#define ATA_HD_BASE	0xfff00000
+
+    /*
+     *  Offsets from the above base
+     */
+
+#define ATA_HD_DATA	0x00
+#define ATA_HD_ERROR	0x05		/* see err-bits */
+#define ATA_HD_NSECTOR	0x09		/* nr of sectors to read/write */
+#define ATA_HD_SECTOR	0x0d		/* starting sector */
+#define ATA_HD_LCYL	0x11		/* starting cylinder */
+#define ATA_HD_HCYL	0x15		/* high byte of starting cyl */
+#define ATA_HD_SELECT	0x19		/* 101dhhhh , d=drive, hhhh=head */
+#define ATA_HD_STATUS	0x1d		/* see status-bits */
+#define ATA_HD_CONTROL	0x39
+
+static const int falconide_offsets[IDE_NR_PORTS] = {
+    ATA_HD_DATA, ATA_HD_ERROR, ATA_HD_NSECTOR, ATA_HD_SECTOR, ATA_HD_LCYL,
+    ATA_HD_HCYL, ATA_HD_SELECT, ATA_HD_STATUS, ATA_HD_CONTROL
+};
+
+
+    /*
+     *  Probe for a Falcon IDE interface
+     */
+
+int falconide_probe_hwif(int index, ide_hwif_t *hwif)
+{
+    static int falcon_index = 0;
+
+    if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
+	return 0;
+
+    if (!falcon_index) {
+	printk("ide%d: Falcon IDE interface\n", index);
+	falcon_index = index+1;
+    }
+    if (falcon_index == index+1) {
+	ide_setup_ports(hwif, (ide_ioreg_t)ATA_HD_BASE, falconide_offsets, 0,
+			NULL);
+	hwif->irq = IRQ_MFP_IDE;
+	return 1;
+    }
+    return 0;
+}
--- /dev/null	Sat Jun 17 03:20:38 1995
+++ m68k/drivers/block/gayle.c	Sun Apr  5 23:23:27 1998
@@ -0,0 +1,168 @@
+/*
+ *  linux/drivers/block/gayle.c -- Amiga Gayle IDE Driver
+ *
+ *     Created 9 Jul 1997 by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+
+#include "ide.h"
+
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+
+
+    /*
+     *  Bases of the IDE interfaces
+     */
+
+#define GAYLE_BASE_4000	0xdd2020	/* A4000/A4000T */
+#define GAYLE_BASE_1200	0xda0000	/* A1200/A600 */
+
+    /*
+     *  Offsets from one of the above bases
+     */
+
+#define GAYLE_DATA	0x00
+#define GAYLE_ERROR	0x06		/* see err-bits */
+#define GAYLE_NSECTOR	0x0a		/* nr of sectors to read/write */
+#define GAYLE_SECTOR	0x0e		/* starting sector */
+#define GAYLE_LCYL	0x12		/* starting cylinder */
+#define GAYLE_HCYL	0x16		/* high byte of starting cyl */
+#define GAYLE_SELECT	0x1a		/* 101dhhhh , d=drive, hhhh=head */
+#define GAYLE_STATUS	0x1e		/* see status-bits */
+#define GAYLE_CONTROL	0x101a
+
+static u_int gayle_offsets[IDE_NR_PORTS] = {
+    GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL,
+    GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, GAYLE_CONTROL
+};
+
+
+    /*
+     *  These are at different offsets from the base
+     */
+
+#define GAYLE_IRQ_4000	0xdd3020	/* MSB = 1, Harddisk is source of */
+#define GAYLE_IRQ_1200	0xda9000	/* interrupt */
+
+
+    /*
+     *  Offset of the secondary port for IDE doublers
+     *  Note that GAYLE_CONTROL is NOT available then!
+     */
+
+#define GAYLE_NEXT_PORT	0x1000
+
+#ifndef CONFIG_BLK_DEV_IDEDOUBLER
+#define GAYLE_NUM_HWIFS		1
+#define GAYLE_NUM_PROBE_HWIFS	GAYLE_NUM_HWIFS
+#define GAYLE_HAS_CONTROL_REG	1
+#else /* CONFIG_BLK_DEV_IDEDOUBLER */
+#define GAYLE_NUM_HWIFS		2
+#define GAYLE_NUM_PROBE_HWIFS	(ide_doubler ? GAYLE_NUM_HWIFS : \
+					       GAYLE_NUM_HWIFS-1)
+#define GAYLE_HAS_CONTROL_REG	(!ide_doubler)
+int ide_doubler = 0;	/* support IDE doublers? */
+#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
+
+
+    /*
+     *  Check and acknowledge the interrupt status
+     */
+
+static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
+{
+    unsigned char ch;
+
+    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    if (!(ch & 0x80))
+	return 0;
+    return 1;
+}
+
+static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
+{
+    unsigned char ch;
+
+    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    if (!(ch & 0x80))
+	return 0;
+    (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
+    outb(0x7c | (ch & 0x03), hwif->io_ports[IDE_IRQ_OFFSET]);
+    return 1;
+}
+
+
+    /*
+     *  Probe for a Gayle IDE interface (and optionally for an IDE doubler)
+     */
+
+int gayle_probe_hwif(int index, ide_hwif_t *hwif)
+{
+    static int gayle_index[GAYLE_NUM_HWIFS] = { 0, };
+    int a4000, i;
+
+    if (!MACH_IS_AMIGA)
+	return 0;
+
+    if (!(a4000 = AMIGAHW_PRESENT(A4000_IDE)) && !AMIGAHW_PRESENT(A1200_IDE))
+	return 0;
+
+    if (!GAYLE_HAS_CONTROL_REG)
+	gayle_offsets[IDE_CONTROL_OFFSET] = -1;
+
+    for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
+	if (!gayle_index[i]) {
+	    switch (i) {
+		case 0:
+		    printk("ide%d: Gayle IDE interface (A%d style)\n", index,
+			   a4000 ? 4000 : 1200);
+		    break;
+#ifdef CONFIG_BLK_DEV_IDEDOUBLER
+		case 1:
+		    printk("ide%d: IDE doubler\n", index);
+		    break;
+#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
+	    }
+	    gayle_index[i] = index+1;
+	}
+	if (gayle_index[i] == index+1) {
+	    ide_ioreg_t base, irqport;
+	    ide_ack_intr_t *ack_intr;
+	    if (a4000) {
+		base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_4000);
+		irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000);
+		ack_intr = gayle_ack_intr_a4000;
+	    } else {
+		base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_1200);
+		irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200);
+		ack_intr = gayle_ack_intr_a1200;
+	    }
+	    base += i*GAYLE_NEXT_PORT;
+	    ide_setup_ports(hwif, base, gayle_offsets, irqport, ack_intr);
+#if 1 /* TESTING */
+	    if (i == 1) {
+		volatile u_short *addr = (u_short *)base;
+		u_short data;
+		printk("+++ Probing for IDE doubler... ");
+		*addr = 0xffff;
+		data = *addr;
+		printk("probe returned 0x%02x (PLEASE REPORT THIS!!)\n", data);
+	    }
+#endif /* TESTING */
+	    hwif->irq = IRQ_AMIGA_PORTS;
+	    return 1;
+	}
+    }
+    return 0;
+}
--- /dev/null	Sat Jun 17 03:20:38 1995
+++ m68k/drivers/block/macide.c	Mon Jun  1 11:58:51 1998
@@ -0,0 +1,172 @@
+/*
+ *  linux/drivers/block/macide.c -- Macintosh IDE Driver
+ *
+ *     Copyright (C) 1998 by Michael Schmitz
+ *
+ *  This driver was written based on information obtained from the MacOS IDE
+ *  driver binary by Mikael Forselius
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/zorro.h>
+
+#include "ide.h"
+
+#include <asm/machw.h>
+#include <asm/macintosh.h>
+#include <asm/macints.h>
+
+    /*
+     *  Base of the IDE interface (see ATAManager ROM code)
+     */
+
+#define MAC_HD_BASE	0x50f1a000
+
+    /*
+     *  Offsets from the above base (scaling 4)
+     */
+
+#define MAC_HD_DATA	0x00
+#define MAC_HD_ERROR	0x04		/* see err-bits */
+#define MAC_HD_NSECTOR	0x08		/* nr of sectors to read/write */
+#define MAC_HD_SECTOR	0x0c		/* starting sector */
+#define MAC_HD_LCYL	0x10		/* starting cylinder */
+#define MAC_HD_HCYL	0x14		/* high byte of starting cyl */
+#define MAC_HD_SELECT	0x18		/* 101dhhhh , d=drive, hhhh=head */
+#define MAC_HD_STATUS	0x1c		/* see status-bits */
+#define MAC_HD_CONTROL	0x38		/* control/altstatus */
+
+static const int macide_offsets[IDE_NR_PORTS] = {
+    MAC_HD_DATA, MAC_HD_ERROR, MAC_HD_NSECTOR, MAC_HD_SECTOR, MAC_HD_LCYL,
+    MAC_HD_HCYL, MAC_HD_SELECT, MAC_HD_STATUS, MAC_HD_CONTROL
+};
+
+	/*
+	 * Other registers
+	 */
+
+	/* 
+	 * IDE interrupt status register for both (?) hwifs on Quadra
+	 * Initial setting: 0xc
+	 * Guessing again:
+	 * Bit 0+1: some interrupt flags
+	 * Bit 2+3: some interrupt enable
+	 * Bit 4:   ??
+	 * Bit 5:   IDE interrupt flag (any hwif)
+	 * Bit 6:   maybe IDE interrupt enable (any hwif) ??
+	 * Bit 7:   Any interrupt condition
+	 *
+	 * Only relevant item: bit 5, to be checked by mac_ack_intr
+	 */
+
+#define MAC_HD_ISR	0x101
+
+	/*
+	 * IDE interrupt glue - seems to be wired to Nubus, Slot C?
+	 * (ROM code disassembly again)
+	 * First try: just use Nubus interrupt for Slot C. Have Nubus code call
+	 * a wrapper to ide_intr that checks the ISR (see above).
+	 * Need to #define IDE_IRQ_NUBUS though.
+	 * Alternative method: set a mac_ide_hook function pointer to the wrapper 
+	 * here and have via_do_nubus call that hook if set. 
+	 *
+	 * Quadra needs the hook, Powerbook can use Nubus slot C. 
+	 * Checking the ISR on Quadra is done by mac_ack_intr (see Amiga code). mac_ide_intr
+	 * mac_ide_intr is obsolete except for providing the hwgroup argument.
+	 */
+
+	/* The Mac hwif data, for passing hwgroup to ide_intr */
+static ide_hwif_t *mac_hwif = NULL;
+
+	/* The function pointer used in the Nubus handler */
+void (*mac_ide_intr_hook)(int, void *, struct pt_regs *) = NULL;
+
+	/*
+	 * Only purpose: feeds the hwgroup to the main IDE handler. 
+	 * Obsolete as soon as Nubus code is fixed WRT pseudo slot C int.
+	 * (should be the case on Powerbooks)
+	 * Alas, second purpose: feed correct irq to IDE handler (I know,
+	 * that's cheating) :-(((
+	 * Fix needed for interrupt code: accept Nubus ints in the regular
+	 * request_irq code, then register Powerbook IDE as Nubus slot C, 
+	 * Quadra as slot F (F for fictious).
+	 */
+void mac_ide_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	ide_intr(mac_hwif->irq, mac_hwif->hwgroup, regs);
+}
+
+    /*
+     *  Check the interrupt status
+     *
+     *  Note: In 2.0 kernels, there have been timing problems with the 
+     *  Powerbook IDE interface (BUSY was asserted too long after the
+     *  interrupt triggered). Result: repeated errors, recalibrate etc. 
+     *  Adding a wait loop to read_intr, write_intr and set_geom_intr
+     *  fixed the problem (waits in read/write_intr were present for Amiga
+     *  already). 
+     *  Powerbooks were not tested with 2.1 due to lack of FPU emulation
+     *  (thanks Apple for using LC040). If the BUSY problem resurfaces in 
+     *  2.1, my best bet would be to add the wait loop right here, afterr
+     *  checking the interrupt register.
+     */
+
+static int mac_ack_intr(ide_hwif_t *hwif)
+{
+    unsigned char ch;
+
+    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    if (!(ch & 0x20))
+	return 0;
+    return 1;
+}
+
+    /*
+     *  Probe for a Macintosh IDE interface
+     */
+
+int macide_probe_hwif(int index, ide_hwif_t *hwif)
+{
+    static int mac_index = 0;
+
+    if (!MACH_IS_MAC || macintosh_config->ide_type == 0)
+	return 0;
+
+    if (!mac_index) {
+	if (macintosh_config->ide_type == MAC_IDE_QUADRA)
+		printk("ide%d: Macintosh Quadra IDE interface\n", index);
+	else
+		printk("ide%d: Macintosh Powerbook IDE interface\n", index);
+	mac_index = index+1;
+    }
+    if (mac_index == index+1) {
+	/* Quadra (pseudo Nubus interrupt) needs to check interrupt status */
+	if (macintosh_config->ide_type == MAC_IDE_QUADRA)
+		ide_setup_ports(hwif, (ide_ioreg_t)MAC_HD_BASE, macide_offsets, 
+				(ide_ioreg_t)(MAC_HD_BASE+MAC_HD_ISR), 
+				mac_ack_intr);
+	else
+		ide_setup_ports(hwif, (ide_ioreg_t)MAC_HD_BASE, macide_offsets, 
+				0, NULL);
+
+	hwif->irq = IRQ_MAC_NUBUS;
+
+	/* set IDE interrupt hook for Nubus dispatch (Quadra only) */
+	if (macintosh_config->ide_type == MAC_IDE_QUADRA)
+		mac_ide_intr_hook = mac_ide_intr;
+
+	/* XXX remember interface struct for reference in interrupt wrapper */
+	mac_hwif = hwif;
+
+	return 1;
+    }
+    return 0;
+}
--- /dev/null	Sat Jun 17 03:20:38 1995
+++ m68k/drivers/block/pcide.c	Sun Apr  5 23:23:30 1998
@@ -0,0 +1,73 @@
+/*
+ *  linux/drivers/block/pcide.c -- PC I/O port IDE Driver
+ *
+ *     Created 12 Jul 1997 by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+
+#include "ide.h"
+
+
+    /*
+     *  Bases of the IDE interfaces
+     */
+
+#define PCIDE_NUM_HWIFS	6
+
+#define PCIDE_BASE1	0x1f0
+#define PCIDE_BASE2	0x170
+#define PCIDE_BASE3	0x1e8
+#define PCIDE_BASE4	0x168
+#define PCIDE_BASE5	0x1e0
+#define PCIDE_BASE6	0x160
+
+static const ide_ioreg_t pcide_bases[PCIDE_NUM_HWIFS] = {
+    PCIDE_BASE1, PCIDE_BASE2, PCIDE_BASE3, PCIDE_BASE4, PCIDE_BASE5,
+    PCIDE_BASE6
+};
+
+
+    /*
+     *  Offsets from one of the above bases
+     */
+
+#define PCIDE_REG(x)	(HD_##x-PCIDE_BASE1)
+
+static const int pcide_offsets[IDE_NR_PORTS] = {
+    PCIDE_REG(DATA), PCIDE_REG(ERROR), PCIDE_REG(NSECTOR), PCIDE_REG(SECTOR),
+    PCIDE_REG(LCYL), PCIDE_REG(HCYL), PCIDE_REG(CURRENT), PCIDE_REG(STATUS),
+    PCIDE_REG(CMD)
+};
+
+
+    /*
+     *  Probe for PC IDE interfaces
+     */
+
+int pcide_probe_hwif(int index, ide_hwif_t *hwif)
+{
+    static int pcide_index[PCIDE_NUM_HWIFS] = { 0, };
+    int i;
+
+    for (i = 0; i < PCIDE_NUM_HWIFS; i++) {
+	if (!pcide_index[i]) {
+	    printk("ide%d: PC IDE interface\n", index);
+	    pcide_index[i] = index+1;
+	}
+	if (pcide_index[i] == index+1) {
+	    ide_setup_ports(hwif, pcide_bases[i], pcide_offsets, 0, NULL);
+	    hwif->irq = 0;
+	    return 1;
+	}
+    }
+    return 0;
+}

Greetings,

						Geert

--
Geert Uytterhoeven                     Geert.Uytterhoeven@thomas.kotnet.org
Linux/{m68k~Amiga,ppc~CHRP}, Wavelets  http://www.cs.kuleuven.ac.be/~geert/
KotNET@Thomas Network Administration --- Make your bed part of Cyberspace!!





