## Automatically generated incremental diff
## From:   linux-2.2.17-pre5
## To:     linux-2.2.17-pre6
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.2.17-pre5/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.2.17-pre5/Documentation/Configure.help	Mon Dec  3 22:06:30 2001
+++ linux/Documentation/Configure.help	Mon Dec  3 22:06:36 2001
@@ -7588,13 +7588,17 @@
   The module will be called ntfs.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
-NTFS read-write support (experimental)
+NTFS read-write support (DANGEROUS)
 CONFIG_NTFS_RW
-  If you say Y here, you will (hopefully) be able to write to NTFS
-  file systems as well as read from them. The read-write support
-  in NTFS is far from being complete and is not well tested. If you
+  If you say Y here, you will (maybe) be able to write to NTFS file
+  systems as well as read from them. The read-write support in
+  NTFS is far from being complete and is not well tested. If you
   enable this, back up your NTFS volume first since it may get
-  damaged.
+  damaged. Also, make sure to run chkdsk from within Microsoft
+  Windows NT after having performed any writes to a NTFS partition
+  from Linux to detect any problems as early as possible.
+  Please note that write support is limited to Windows NT4 and
+  earlier versions.
 
   If unsure, say N.
 
diff -urN linux-2.2.17-pre5/Documentation/filesystems/ntfs.txt linux/Documentation/filesystems/ntfs.txt
--- linux-2.2.17-pre5/Documentation/filesystems/ntfs.txt	Tue Apr 28 14:22:04 1998
+++ linux/Documentation/filesystems/ntfs.txt	Mon Dec  3 22:06:36 2001
@@ -4,10 +4,16 @@
 To mount an NTFS volume, use the filesystem type 'ntfs'. The driver
 currently works only in read-only mode, with no fault-tolerance
 supported.  If you enable the experimental write support, make sure
-you can recover from a complete loss of data. For ftdisk support,
-limited success was reported with volume sets on top of the md driver,
-although mirror and stripe sets should work as well - if the md
-driver can be talked into using the same layout as Windows NT.
+you can recover from a complete loss of data and also always run
+chkdsk from within Microsoft Windows NT after performing a write to
+a NTFS partition from Linux to detect any problems as early as 
+possible. For ftdisk support, limited success was reported with 
+volume sets on top of the md driver, although mirror and stripe 
+sets should work as well - if the md driver can be talked into 
+using the same layout as Windows NT.
+
+Please note that the experimental write support is limited to
+Windows NT4 and earlier versions.
 
 The ntfs driver supports the following mount options:
 iocharset=name      Character set to use when returning file names.
diff -urN linux-2.2.17-pre5/MAINTAINERS linux/MAINTAINERS
--- linux-2.2.17-pre5/MAINTAINERS	Mon Dec  3 22:06:30 2001
+++ linux/MAINTAINERS	Mon Dec  3 22:06:36 2001
@@ -660,6 +660,12 @@
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
+NTFS FILESYSTEM
+P:	Anton Altaparmakov
+M:	aia21@cus.cam.ac.uk
+L:	linux-kernel@vger.rutgers.edu
+S:	Odd Fixes
+
 OLYMPIC NETWORK DRIVER
 P:	Peter De Shrijver
 M:	p2@ace.ulyssis.sutdent.kuleuven.ac.be	
diff -urN linux-2.2.17-pre5/Makefile linux/Makefile
--- linux-2.2.17-pre5/Makefile	Mon Dec  3 22:06:30 2001
+++ linux/Makefile	Mon Dec  3 22:06:36 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 17
-EXTRAVERSION = pre5
+EXTRAVERSION = pre6
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -urN linux-2.2.17-pre5/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- linux-2.2.17-pre5/arch/i386/kernel/setup.c	Mon Dec  3 22:06:30 2001
+++ linux/arch/i386/kernel/setup.c	Mon Dec  3 22:06:36 2001
@@ -464,6 +464,7 @@
 			    (boot_cpu_data.x86_mask >= 8)))
 				c->x86_capability |= X86_FEATURE_MTRR;
 		}
+
 		/* Fall through */
 
 	case X86_VENDOR_TRANSMETA:
@@ -474,7 +475,16 @@
 				ecx>>24, edx>>24);
 			c->x86_cache_size=(ecx>>24)+(edx>>24);
 		}
-		if (n >= 0x80000006){
+		if(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+			boot_cpu_data.x86 == 6 && 
+			boot_cpu_data.x86_model== 3 &&
+			boot_cpu_data.x86_mask == 0)
+		{
+			/* AMD errata T13 (order #21922) */
+			printk("CPU: L2 Cache: 64K\n");
+			c->x86_cache_size = 64;
+		}
+		else if (n >= 0x80000006){
 			cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
 			printk("CPU: L2 Cache: %dK\n", ecx>>16);
 			c->x86_cache_size = ecx>>16;
@@ -1118,10 +1128,15 @@
 		    case X86_VENDOR_AMD:
 			if (c->x86 == 5 && c->x86_model == 6)
 				x86_cap_flags[10] = "sep";
-			x86_cap_flags[16] = "fcmov";
+			if (c->x86 < 6)
+				x86_cap_flags[16] = "fcmov";
+			x86_cap_flags[16] = "pat";
+			x86_cap_flags[22] = "mmxext";
+			x86_cap_flags[24] = "fxsr";
+			x86_cap_flags[30] = "3dnowext";
 			x86_cap_flags[31] = "3dnow";
 			break;
-
+																																										
 		    case X86_VENDOR_INTEL:
 			x86_cap_flags[6] = "pae";
 			x86_cap_flags[9] = "apic";
diff -urN linux-2.2.17-pre5/arch/ppc/kernel/feature.c linux/arch/ppc/kernel/feature.c
--- linux-2.2.17-pre5/arch/ppc/kernel/feature.c	Mon Dec  3 22:06:30 2001
+++ linux/arch/ppc/kernel/feature.c	Mon Dec  3 22:06:36 2001
@@ -18,7 +18,7 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/spinlock.h>
+#include <asm/spinlock.h>
 #include <asm/errno.h>
 #include <asm/ohare.h>
 #include <asm/heathrow.h>
diff -urN linux-2.2.17-pre5/drivers/scsi/aic7xxx/aic7xxx.seq linux/drivers/scsi/aic7xxx/aic7xxx.seq
--- linux-2.2.17-pre5/drivers/scsi/aic7xxx/aic7xxx.seq	Mon Dec  3 22:06:30 2001
+++ linux/drivers/scsi/aic7xxx/aic7xxx.seq	Mon Dec  3 22:06:36 2001
@@ -574,7 +574,7 @@
 		test	SCSIOFFSET, 0x7f	jnz ultra2_shutdown;
 ultra2_await_nreq:
 		test	SCSISIGI, REQI	jz ultra2_shutdown;
-		test	SSTAT1, PHASEMIS	jz ultra2_await_nreq;
+		test	SSTAT1, (PHASEMIS|REQINIT)	jz ultra2_await_nreq;
 ultra2_shutdown:
 		and     DFCNTRL, ~(HDMAEN|SCSIEN);
 		test	DFCNTRL, (HDMAEN|SCSIEN) jnz .;
@@ -617,7 +617,7 @@
 		test	SSTAT1,PHASEMIS	jz p_command_dma_loop;	/* ie. underrun */
 p_command_ultra2_dma_done:
 		test	SCSISIGI, REQI	jz p_command_ultra2_shutdown;
-		test	SSTAT1, PHASEMIS	jz p_command_ultra2_dma_done;
+		test	SSTAT1, (PHASEMIS|REQINIT)	jz p_command_ultra2_dma_done;
 p_command_ultra2_shutdown:
 		and     DFCNTRL, ~(HDMAEN|SCSIEN);
 		test	DFCNTRL, (HDMAEN|SCSIEN) jnz .;
@@ -1069,7 +1069,7 @@
 	test	SCSIRATE, 0x0f	jnz dma_shutdown;
 dma_await_nreq:
 	test	SCSISIGI, REQI	jz dma_shutdown;
-	test	SSTAT1, PHASEMIS	jz dma_await_nreq;
+	test	SSTAT1, (PHASEMIS|REQINIT)	jz dma_await_nreq;
 dma_shutdown:
 	and	DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);
 dma_halt:
diff -urN linux-2.2.17-pre5/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- linux-2.2.17-pre5/drivers/scsi/aic7xxx.c	Mon Dec  3 22:06:30 2001
+++ linux/drivers/scsi/aic7xxx.c	Mon Dec  3 22:06:36 2001
@@ -270,7 +270,7 @@
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.1.30"
+#define AIC7XXX_C_VERSION  "5.1.31"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
diff -urN linux-2.2.17-pre5/drivers/scsi/aic7xxx_seq.c linux/drivers/scsi/aic7xxx_seq.c
--- linux-2.2.17-pre5/drivers/scsi/aic7xxx_seq.c	Mon Dec  3 22:06:30 2001
+++ linux/drivers/scsi/aic7xxx_seq.c	Mon Dec  3 22:06:36 2001
@@ -209,7 +209,7 @@
 	0x10, 0x94, 0x98, 0x69,
 	0x7f, 0x05, 0xa0, 0x69,
 	0x02, 0x03, 0xa0, 0x79,
-	0x10, 0x0c, 0x9c, 0x79,
+	0x11, 0x0c, 0x9c, 0x79,
 	0xd7, 0x93, 0x26, 0x09,
 	0x28, 0x93, 0xa2, 0x69,
 	0x03, 0x08, 0x52, 0x31,
@@ -231,7 +231,7 @@
 	0x04, 0x0b, 0xc8, 0x69,
 	0x10, 0x0c, 0xc4, 0x79,
 	0x02, 0x03, 0xcc, 0x79,
-	0x10, 0x0c, 0xc8, 0x79,
+	0x11, 0x0c, 0xc8, 0x79,
 	0xd7, 0x93, 0x26, 0x09,
 	0x28, 0x93, 0xce, 0x69,
 	0x12, 0x01, 0x02, 0x00,
@@ -388,7 +388,7 @@
 	0x80, 0x3d, 0x02, 0x73,
 	0x0f, 0x04, 0x06, 0x6b,
 	0x02, 0x03, 0x06, 0x7b,
-	0x10, 0x0c, 0x02, 0x7b,
+	0x11, 0x0c, 0x02, 0x7b,
 	0xc7, 0x93, 0x26, 0x09,
 	0xff, 0x99, 0xd4, 0x08,
 	0x38, 0x93, 0x08, 0x6b,
diff -urN linux-2.2.17-pre5/drivers/video/Config.in linux/drivers/video/Config.in
--- linux-2.2.17-pre5/drivers/video/Config.in	Tue Jan  4 10:12:22 2000
+++ linux/drivers/video/Config.in	Mon Dec  3 22:06:36 2001
@@ -49,6 +49,8 @@
   fi
   if [ "$CONFIG_ATARI" = "y" ]; then
     bool 'Atari native chipset support' CONFIG_FB_ATARI
+  fi
+  if [ "$CONFIG_ATARI" = "y" -o "$CONFIG_PCI" != "n" ]; then
     bool 'ATI Mach64 display support' CONFIG_FB_ATY
   fi
   if [ "$CONFIG_PPC" = "y" ]; then
@@ -60,6 +62,7 @@
       bool 'IMS Twin Turbo display support' CONFIG_FB_IMSTT
       bool 'Chips 65550 display support' CONFIG_FB_CT65550
       bool 'S3 Trio display support' CONFIG_FB_S3TRIO
+      bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
     fi
   fi
   if [ "$CONFIG_MAC" = "y" ]; then
@@ -89,7 +92,7 @@
         bool '  G100/G200 support' CONFIG_FB_MATROX_G100
         bool '  Multihead support' CONFIG_FB_MATROX_MULTIHEAD
       fi
-      bool 'ATI Mach64 display support' CONFIG_FB_ATY
+      bool 'ATI Rage128 display support' CONFIG_FB_ATY128
     fi
   fi
   if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
diff -urN linux-2.2.17-pre5/drivers/video/Makefile linux/drivers/video/Makefile
--- linux-2.2.17-pre5/drivers/video/Makefile	Wed Aug 25 17:29:49 1999
+++ linux/drivers/video/Makefile	Mon Dec  3 22:06:36 2001
@@ -104,6 +104,10 @@
 L_OBJS += atyfb.o
 endif
 
+ifeq ($(CONFIG_FB_ATY128),y)
+  L_OBJS += aty128fb.o
+endif
+
 ifeq ($(CONFIG_FB_IGA),y)
 L_OBJS += igafb.o
 endif
diff -urN linux-2.2.17-pre5/drivers/video/aty.h linux/drivers/video/aty.h
--- linux-2.2.17-pre5/drivers/video/aty.h	Tue Oct 26 17:53:41 1999
+++ linux/drivers/video/aty.h	Mon Dec  3 22:06:36 2001
@@ -67,6 +67,8 @@
 #define CUR_HORZ_VERT_POSN	0x006C	/* Dword offset 0_1B */
 #define CUR_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
 
+#define CONFIG_PANEL_LG		0x0074	/* Dword offset 0_1D */
+
 #define GP_IO			0x0078	/* Dword offset 0_1E */
 
 #define HW_DEBUG		0x007C	/* Dword offset 0_1F */
@@ -82,6 +84,9 @@
 
 #define BUS_CNTL		0x00A0	/* Dword offset 0_28 */
 
+#define LCD_INDEX		0x00A4	/* Dword offset 0_29 */
+#define LCD_DATA		0x00A8	/* Dword offset 0_2A */
+
 #define EXT_MEM_CNTL		0x00AC	/* Dword offset 0_2B */
 #define MEM_CNTL		0x00B0	/* Dword offset 0_2C */
 
@@ -100,8 +105,9 @@
 #define GEN_TEST_CNTL		0x00D0	/* Dword offset 0_34 */
 
 #define CUSTOM_MACRO_CNTL	0x00D4	/* Dword offset 0_35 */
+#define LCD_GEN_CNTL_LG		0x00D4	/* Dword offset 0_35 */
 
-#define POWER_MANAGEMENT	0x00D8	/* Dword offset 0_36 (LG) */
+#define POWER_MANAGEMENT_LG	0x00D8	/* Dword offset 0_36 (LG) */
 
 #define CONFIG_CNTL		0x00DC	/* Dword offset 0_37 (CT, ET, VT) */
 #define CONFIG_CHIP_ID		0x00E0	/* Dword offset 0_38 */
@@ -725,7 +731,7 @@
 /* mach64CT family / mach64GT (3D RAGE) class */
 #define LB_CHIP_ID	0x4c42	/* RAGE LT PRO, AGP */
 #define LD_CHIP_ID	0x4c44	/* RAGE LT PRO */
-#define LG_CHIP_ID	0x4c47	/* RAGE LT PRO */
+#define LG_CHIP_ID	0x4c47	/* RAGE LT */
 #define LI_CHIP_ID	0x4c49	/* RAGE LT PRO */
 #define LP_CHIP_ID	0x4c50	/* RAGE LT PRO */
 #define LT_CHIP_ID	0x4c54	/* RAGE LT */
@@ -739,6 +745,7 @@
 #define GI_CHIP_ID	0x4749	/* RAGE PRO, BGA, PCI33 only */
 #define GP_CHIP_ID	0x4750	/* RAGE PRO, PQFP, PCI33, full 3D */
 #define GQ_CHIP_ID	0x4751	/* RAGE PRO, PQFP, PCI33, limited 3D */
+#define LN_CHIP_ID	0x4c4d	/* RAGE Mobility AGP */
 
 
 /* Mach64 major ASIC revisions */
@@ -951,15 +958,43 @@
 #define MACH64_NUM_CLOCKS	16
 #define MACH64_NUM_FREQS	50
 
-/* Power Management register constants (LTG and LT Pro) */
+/* Power Management register constants (LT & LT Pro) */
 #define PWR_MGT_ON		0x00000001
 #define PWR_MGT_MODE_MASK	0x00000006
 #define AUTO_PWR_UP		0x00000008
+#define USE_F32KHZ		0x00000400
+#define TRISTATE_MEM_EN		0x00000800
 #define SELF_REFRESH		0x00000080
 #define PWR_BLON		0x02000000
 #define STANDBY_NOW		0x10000000
 #define SUSPEND_NOW		0x20000000
 #define PWR_MGT_STATUS_MASK	0xC0000000
 #define PWR_MGT_STATUS_SUSPEND	0x80000000
+
+/* PM Mode constants  */
+#define PWR_MGT_MODE_PIN	0x00000000
+#define PWR_MGT_MODE_REG	0x00000002
+#define PWR_MGT_MODE_TIMER	0x00000004
+#define PWR_MGT_MODE_PCI	0x00000006
+
+/* LCD registers (LT Pro) */
+
+/* LCD Index register */
+#define LCD_INDEX_MASK		0x0000003F
+#define LCD_DISPLAY_DIS		0x00000100
+#define LCD_SRC_SEL		0x00000200
+#define CRTC2_DISPLAY_DIS	0x00000400
+
+/* LCD register indices */
+#define LCD_CONFIG_PANEL	0x00
+#define LCD_GEN_CTRL		0x01
+#define LCD_DSTN_CONTROL	0x02
+#define LCD_HFB_PITCH_ADDR	0x03
+#define LCD_HORZ_STRETCHING	0x04
+#define LCD_VERT_STRETCHING	0x05
+#define LCD_EXT_VERT_STRETCH	0x06
+#define LCD_LT_GIO		0x07
+#define LCD_POWER_MANAGEMENT	0x08
+#define LCD_ZVGPIO		0x09
 
 #endif /* REGMACH64_H */
diff -urN linux-2.2.17-pre5/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- linux-2.2.17-pre5/drivers/video/atyfb.c	Wed Jun  7 14:26:43 2000
+++ linux/drivers/video/atyfb.c	Mon Dec  3 22:06:36 2001
@@ -87,7 +87,7 @@
 /*
  * Debug flags.
  */
-#undef DEBUG
+#define DEBUG
 
 #define GUI_RESERVE	0x00001000
 
@@ -419,7 +419,7 @@
 static int default_mclk __initdata = 0;
 
 #if defined(CONFIG_PPC)
-static int default_vmode __initdata = VMODE_NVRAM;
+static int default_vmode __initdata = VMODE_CHOOSE;
 static int default_cmode __initdata = CMODE_NVRAM;
 #endif
 
@@ -452,7 +452,7 @@
     /* mach64CT family / mach64GT (3D RAGE) class */
     { 0x4c42, 0x4c42, "3D RAGE LT PRO (AGP)" },
     { 0x4c44, 0x4c44, "3D RAGE LT PRO" },
-    { 0x4c47, 0x4c47, "3D RAGE LT PRO" },
+    { 0x4c47, 0x4c47, "3D RAGE LT-G" },
     { 0x4c49, 0x4c49, "3D RAGE LT PRO" },
     { 0x4c50, 0x4c50, "3D RAGE LT PRO" },
     { 0x4c54, 0x4c54, "3D RAGE LT" },
@@ -466,6 +466,7 @@
     { 0x4749, 0x4749, "3D RAGE PRO (BGA, PCI)" },
     { 0x4750, 0x4750, "3D RAGE PRO (PQFP, PCI)" },
     { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)" },
+    { 0x4c4e, 0x4c4e, "3D RAGE Mobility (AGP)" }, /* Doesn't quite work yet */
 };
 
 static const char *aty_gx_ram[8] __initdata = {
@@ -485,7 +486,7 @@
 
 #if defined(__powerpc__)
     temp = info->ati_regbase;
-    asm("lwbrx %0,%1,%2" : "=r"(val) : "b" (regindex), "r" (temp));
+     __asm__ __volatile__("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b" (regindex), "r" (temp));
 #elif defined(__sparc_v9__)
     temp = info->ati_regbase + regindex;
     asm("lduwa [%1] %2, %0" : "=r" (val) : "r" (temp), "i" (ASI_PL));
@@ -503,7 +504,7 @@
 
 #if defined(__powerpc__)
     temp = info->ati_regbase;
-    asm("stwbrx %0,%1,%2" : : "r" (val), "b" (regindex), "r" (temp) :
+     __asm__ __volatile__("stwbrx %0,%1,%2;eieio" : : "r" (val), "b" (regindex), "r" (temp) :
 	"memory");
 #elif defined(__sparc_v9__)
     temp = info->ati_regbase + regindex;
@@ -517,15 +518,43 @@
 static inline u8 aty_ld_8(volatile unsigned int regindex,
 			  const struct fb_info_aty *info)
 {
-    return *(volatile u8 *)(info->ati_regbase+regindex);
+    u8 val = *(volatile u8 *)(info->ati_regbase+regindex);
+#if defined(__powerpc__)
+    eieio();
+#endif
+    return val;
 }
 
 static inline void aty_st_8(volatile unsigned int regindex, u8 val,
 			    const struct fb_info_aty *info)
 {
     *(volatile u8 *)(info->ati_regbase+regindex) = val;
+#if defined(__powerpc__)
+    eieio();
+#endif
+}
+
+static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info)
+{
+    unsigned long temp;
+    
+    /* write addr byte */
+    temp = aty_ld_le32(LCD_INDEX, info);
+    aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
+    /* write the register value */
+    aty_st_le32(LCD_DATA, val, info);
 }
 
+static u32 aty_ld_lcd(int index, const struct fb_info_aty *info)
+{
+    unsigned long temp;
+    
+    /* write addr byte */
+    temp = aty_ld_le32(LCD_INDEX, info);
+    aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
+    /* read the register value */
+    return aty_ld_le32(LCD_DATA, info);
+}
 
     /*
      *  Generic Mach64 routines
@@ -683,9 +712,7 @@
     aty_st_8(DAC_W_INDEX, offset & 0xff, info);
     /* left addr byte */
     aty_st_8(DAC_DATA, (offset >> 8) & 0xff, info);
-    eieio();
     aty_st_8(DAC_MASK, val, info);
-    eieio();
     aty_st_8(DAC_CNTL, 0, info);
 }
 
@@ -693,10 +720,8 @@
 {
     /* write addr byte */
     aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
-    eieio();
     /* write the register value */
     aty_st_8(CLOCK_CNTL + 2, val, info);
-    eieio();
     aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
 }
 
@@ -706,10 +731,8 @@
 
     /* write addr byte */
     aty_st_8(CLOCK_CNTL + 1, (offset << 2), info);
-    eieio();
     /* read the register value */
     res = aty_ld_8(CLOCK_CNTL + 2, info);
-    eieio();
     return res;
 }
 
@@ -1772,6 +1795,9 @@
 	} else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID)) {
 	    aty_st_le32(DAC_CNTL, 0x87010184, info);
 	    aty_st_le32(BUS_CNTL, 0x680000f9, info);
+	} else if (Gx == LN_CHIP_ID) {
+	    aty_st_le32(DAC_CNTL, 0x80010102, info);
+	    aty_st_le32(BUS_CNTL, 0x7b33a040, info);
 	} else {
 	    /* GT */
 	    aty_st_le32(DAC_CNTL, 0x86010102, info);
@@ -1788,7 +1814,7 @@
 	init_engine(par, info);
 
 #ifdef CONFIG_FB_COMPAT_XPMAC
-    if (console_fb_info == &info->fb_info) {
+    if (!console_fb_info || console_fb_info == &info->fb_info) {
 	struct fb_var_screeninfo var;
 	int vmode, cmode;
 	display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
@@ -2406,7 +2432,6 @@
 			tmp |= 0x2;
 		aty_st_8(DAC_CNTL, tmp, info);
 		aty_st_8(DAC_MASK, 0xff, info);
-		eieio();
 		scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
 			(info->current_par.crtc.bpp == 16)) ? 3 : 0;
 		info->aty_cmap_regs->rindex = i << scale;
@@ -2549,11 +2574,19 @@
 	    } else if (Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
 		       Gx == GI_CHIP_ID || Gx == GP_CHIP_ID ||
 		       Gx == GQ_CHIP_ID || Gx == LB_CHIP_ID ||
-		       Gx == LD_CHIP_ID || Gx == LG_CHIP_ID ||
+		       Gx == LD_CHIP_ID ||
 		       Gx == LI_CHIP_ID || Gx == LP_CHIP_ID) {
 		/* RAGE PRO or LT PRO */
 		pll = 230;
 		mclk = 100;
+	    } else if (Gx == LG_CHIP_ID) {
+		/* Rage LT */
+		pll = 230;
+		mclk = 63;
+	    } else if (Gx == LN_CHIP_ID) {
+	    	/* Rage mobility */
+	    	pll = 230;
+	    	mclk = 100;
 	    } else {
 		/* other RAGE */
 		pll = 135;
@@ -2706,24 +2739,43 @@
 	}
 
 #if defined(CONFIG_PPC)
+    if (Gx == LI_CHIP_ID && machine_is_compatible("PowerBook1,1")) {
+	/* these bits let the 101 powerbook wake up from sleep -- paulus */
+	aty_st_lcd(LCD_POWER_MANAGEMENT, aty_ld_lcd(LCD_POWER_MANAGEMENT, info)
+		| (USE_F32KHZ | TRISTATE_MEM_EN), info);
+    }
+
     if (default_vmode == VMODE_NVRAM) {
+#if 0 /* This is not really supported */
 	default_vmode = nvram_read_byte(NV_VMODE);
 	if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+#endif
 	    default_vmode = VMODE_CHOOSE;
     }
+    /*
+     * The default video mode is 1024x768 @ 75Hz, as that
+     * works on iMacs as well as the G3 powerbooks. - paulus
+     */
     if (default_vmode == VMODE_CHOOSE) {
 	if (Gx == LG_CHIP_ID)
 	    /* G3 PowerBook with 1024x768 LCD */
 	    default_vmode = VMODE_1024_768_60;
-	else {
-	    sense = read_aty_sense(info);
-	    default_vmode = mac_map_monitor_sense(sense);
-	}
+	else if (Gx == LN_CHIP_ID)
+	    /* iBook with 800x600 LCD */
+	    default_vmode = VMODE_800_600_60;
+	else
+	    default_vmode = VMODE_1024_768_75;
+	/* 'twould be nice to get this going - paulus */
+	sense = read_aty_sense(info);
+	printk(KERN_INFO "atyfb: monitor sense=%x, maps to mode %d\n",
+	       sense, mac_map_monitor_sense(sense));
     }
     if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-	default_vmode = VMODE_640_480_60;
+	default_vmode = VMODE_1024_768_75;
+#if 0
     if (default_cmode == CMODE_NVRAM)
 	default_cmode = nvram_read_byte(NV_CMODE);
+#endif
     if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
 	default_cmode = CMODE_8;
     if (mac_vmode_to_var(default_vmode, default_cmode, &var))
@@ -3476,11 +3528,10 @@
     if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
 	Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
 	Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
-	Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID)
+	Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || Gx == LI_CHIP_ID)
 	i |= 0x2;	/*DAC_CNTL|0x2 turns off the extra brightness for gt*/
     aty_st_8(DAC_CNTL, i, info);
     aty_st_8(DAC_MASK, 0xff, info);
-    eieio();
     scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
 	     (info->current_par.crtc.bpp == 16)) ? 3 : 0;
     info->aty_cmap_regs->windex = regno << scale;
@@ -3930,6 +3981,124 @@
 #endif
 
 #ifdef CONFIG_PMAC_PBOOK
+
+/* Power management routines. Those are used for PowerBook sleep.
+ *
+ * It appears that Rage LT and Rage LT Pro have different power
+ * management registers. There's is some confusion about which
+ * chipID is a Rage LT or LT pro :(
+ */
+static int
+aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
+{
+ 	unsigned int pm;
+	int timeout;
+	
+	pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+	pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
+	aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+	pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+	
+	timeout = 200000;
+	if (sleep) {
+		/* Sleep */
+		pm &= ~PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm &= ~(PWR_BLON | AUTO_PWR_UP);
+		pm |= SUSPEND_NOW;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		do {
+			pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+			udelay(10);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
+	} else {
+		/* Wakeup */
+		pm &= ~PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm |=  (PWR_BLON | AUTO_PWR_UP);
+		pm &= ~SUSPEND_NOW;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		do {
+			pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+			udelay(10);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != 0);
+	}
+	mdelay(500);
+
+	return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
+}
+
+static int
+aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
+{
+ 	unsigned int pm;
+	int timeout;
+	
+	pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+	pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
+	aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+	pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+
+	timeout = 200;
+	if (sleep) {
+		/* Sleep */
+		pm &= ~PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm &= ~(PWR_BLON | AUTO_PWR_UP);
+		pm |= SUSPEND_NOW;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		do {
+			pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+			udelay(1000);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
+	} else {
+		/* Wakeup */
+		pm &= ~PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm &= ~SUSPEND_NOW;
+		pm |= (PWR_BLON | AUTO_PWR_UP);
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		do {
+			pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);			
+			udelay(1000);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != 0);
+	}
+
+	return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
+}
+
 /*
  * Save the contents of the frame buffer when we go to sleep,
  * and restore it when we wake up again.
@@ -3938,7 +4107,9 @@
 aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
 	struct fb_info_aty *info;
- 	unsigned int pm;
+ 	int result;
+
+	result = PBOOK_SLEEP_OK;
 
 	for (info = first_display; info != NULL; info = info->next) {
 		struct fb_fix_screeninfo fix;
@@ -3950,6 +4121,8 @@
 		switch (when) {
 		case PBOOK_SLEEP_REQUEST:
 			info->save_framebuffer = vmalloc(nb);
+			if (info->save_framebuffer == NULL)
+				return PBOOK_SLEEP_REFUSE;
 			break;
 		case PBOOK_SLEEP_REJECT:
 			if (info->save_framebuffer) {
@@ -3966,80 +4139,38 @@
 
 			/* Backup fb content */	
 			if (info->save_framebuffer)
-				memcpy(info->save_framebuffer,
+				memcpy_fromio(info->save_framebuffer,
 				       (void *)info->frame_buffer, nb);
 
 			/* Blank display and LCD */
 			atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
 
-			/* Set chip to "suspend" mode. Note: There's a HW bug
-			   in the chip which prevents proper resync on wakeup
-			   with automatic power management, we handle suspend
-			   manually using the following (weird) sequence
-			   described by ATI.
-			   Note2:
-			   We could enable this for all Rage LT Pro chip ids */
-			if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID)
-			    || (Gx == LP_CHIP_ID)) {
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				pm &= ~PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm &= ~(PWR_BLON | AUTO_PWR_UP);
-				pm |= SUSPEND_NOW;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm |= PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				do {
-					pm = aty_ld_le32(POWER_MANAGEMENT, info);
-					/* Fix a problem with revision 4c50 of the chip */
-					if (Gx == LP_CHIP_ID)
-						break;
-				} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
-				mdelay(500);
-			}
+			/* Set chip to "suspend" mode */
+			if (Gx == LG_CHIP_ID)
+				result = aty_power_mgmt_LT(1, info);
+			else
+				result = aty_power_mgmt_LTPro(1, info);
 			break;
 		case PBOOK_WAKE:
 			/* Wakeup chip */
-			if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID) || (Gx == LP_CHIP_ID)) {
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				pm &= ~PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm |=  (PWR_BLON | AUTO_PWR_UP);
-				pm &= ~SUSPEND_NOW;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm |= PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				do {
-					pm = aty_ld_le32(POWER_MANAGEMENT, info);
-					/* Fix a problem with revision 4c50 of the chip */
-					if (Gx == LP_CHIP_ID)
-						break;
-				} while ((pm & PWR_MGT_STATUS_MASK) != 0);
-				mdelay(500);
-			}
+			if (Gx == LG_CHIP_ID)
+				result = aty_power_mgmt_LT(0, info);
+			else
+				result = aty_power_mgmt_LTPro(0, info);
 
 			/* Restore fb content */			
 			if (info->save_framebuffer) {
-				memcpy((void *)info->frame_buffer,
+				memcpy_toio((void *)info->frame_buffer,
 				       info->save_framebuffer, nb);
 				vfree(info->save_framebuffer);
 				info->save_framebuffer = 0;
 			}
-
-			/* Restore display */			
+			/* Restore display */
 			atyfb_set_par(&info->current_par, info);
 			atyfbcon_blank(0, (struct fb_info *)info);
 			break;
 		}
 	}
-	return PBOOK_SLEEP_OK;
+	return result;
 }
 #endif /* CONFIG_PMAC_PBOOK */
diff -urN linux-2.2.17-pre5/drivers/video/chipsfb.c linux/drivers/video/chipsfb.c
--- linux-2.2.17-pre5/drivers/video/chipsfb.c	Tue Jan  4 10:12:22 2000
+++ linux/drivers/video/chipsfb.c	Mon Dec  3 22:06:36 2001
@@ -728,6 +728,8 @@
 		switch (when) {
 		case PBOOK_SLEEP_REQUEST:
 			p->save_framebuffer = vmalloc(nb);
+			if (p->save_framebuffer == NULL)
+				return PBOOK_SLEEP_REFUSE;
 			break;
 		case PBOOK_SLEEP_REJECT:
 			if (p->save_framebuffer) {
diff -urN linux-2.2.17-pre5/drivers/video/controlfb.c linux/drivers/video/controlfb.c
--- linux-2.2.17-pre5/drivers/video/controlfb.c	Mon Aug  9 12:04:57 1999
+++ linux/drivers/video/controlfb.c	Mon Dec  3 22:06:36 2001
@@ -531,18 +531,26 @@
 
 	p->sense = read_control_sense(p);
 	printk(KERN_INFO "Monitor sense value = 0x%x, ", p->sense);
+	
 	/* Try to pick a video mode out of NVRAM if we have one. */
-	par->vmode = nvram_read_byte(NV_VMODE);
-	if(par->vmode <= 0 || par->vmode > VMODE_MAX || !control_reg_init[par->vmode - 1])
-		par->vmode = VMODE_CHOOSE;
-	if(par->vmode == VMODE_CHOOSE)
-		par->vmode = mac_map_monitor_sense(p->sense);
-	if(!control_reg_init[par->vmode - 1])
-		par->vmode = VMODE_640_480_60;
+	if (default_vmode == VMODE_NVRAM) {
+		par->vmode = nvram_read_byte(NV_VMODE);
+		if(par->vmode <= 0 || par->vmode > VMODE_MAX || !control_reg_init[par->vmode - 1])
+			par->vmode = VMODE_CHOOSE;
+		if(par->vmode == VMODE_CHOOSE)
+			par->vmode = mac_map_monitor_sense(p->sense);
+		if(!control_reg_init[par->vmode - 1])
+			par->vmode = VMODE_640_480_60;
+	} else
+		par->vmode=default_vmode;
+
+	if (default_cmode == CMODE_NVRAM){
+		par->cmode = nvram_read_byte(NV_CMODE);
+		if(par->cmode < CMODE_8 || par->cmode > CMODE_32)
+			par->cmode = CMODE_8;}
+	else
+		par->cmode=default_cmode;
 
-	par->cmode = nvram_read_byte(NV_CMODE);
-	if(par->cmode < CMODE_8 || par->cmode > CMODE_32)
-		par->cmode = CMODE_8;
 	/*
 	 * Reduce the pixel size if we don't have enough VRAM.
 	 */
@@ -780,14 +788,10 @@
      *  bitfields, horizontal timing, vertical timing.
      */
 	/* swiped by jonh from atyfb.c */
-	if (xres <= 512 && yres <= 384)
-		par->vmode = VMODE_512_384_60;		/* 512x384, 60Hz */
-	else if (xres <= 640 && yres <= 480)
+	if (xres <= 640 && yres <= 480)
 		par->vmode = VMODE_640_480_67;		/* 640x480, 67Hz */
 	else if (xres <= 640 && yres <= 870)
 		par->vmode = VMODE_640_870_75P;		/* 640x870, 75Hz (portrait) */
-	else if (xres <= 768 && yres <= 576)
-		par->vmode = VMODE_768_576_50I;		/* 768x576, 50Hz (PAL full frame) */
 	else if (xres <= 800 && yres <= 600)
 		par->vmode = VMODE_800_600_75;		/* 800x600, 75Hz */
 	else if (xres <= 832 && yres <= 624)
@@ -1176,8 +1180,8 @@
 		}
 		if (!strncmp(this_opt, "vmode:", 6)) {
 			int vmode = simple_strtoul(this_opt+6, NULL, 0);
-		if (vmode > 0 && vmode <= VMODE_MAX)
-			default_vmode = vmode;
+			if (vmode > 0 && vmode <= VMODE_MAX)
+				default_vmode = vmode;
 		} else if (!strncmp(this_opt, "cmode:", 6)) {
 			int depth = simple_strtoul(this_opt+6, NULL, 0);
 			switch (depth) {
diff -urN linux-2.2.17-pre5/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.2.17-pre5/drivers/video/fbmem.c	Tue Jan  4 10:12:22 2000
+++ linux/drivers/video/fbmem.c	Mon Dec  3 22:06:36 2001
@@ -68,6 +68,8 @@
 extern void offb_setup(char *options, int *ints);
 extern void atyfb_init(void);
 extern void atyfb_setup(char *options, int *ints);
+extern void aty128fb_init(void);
+extern void aty128fb_setup(char *options, int *ints);
 extern void igafb_init(void);
 extern void igafb_setup(char *options, int *ints);
 extern void imsttfb_init(void);
@@ -92,6 +94,8 @@
 extern void sbusfb_setup(char *options, int *ints);
 extern void valkyriefb_init(void);
 extern void valkyriefb_setup(char *options, int *ints);
+extern void control_init(void);
+extern void control_setup(char *options, int *ints);
 extern void g364fb_init(void);
 extern void fm2fb_init(void);
 extern void fm2fb_setup(char *options, int *ints);
@@ -143,6 +147,9 @@
 #ifdef CONFIG_FB_ATY
 	{ "atyfb", atyfb_init, atyfb_setup },
 #endif
+#ifdef CONFIG_FB_ATY128
+	{ "aty128fb", aty128fb_init, aty128fb_setup },
+#endif
 #ifdef CONFIG_FB_IGA
         { "igafb", igafb_init, igafb_setup },
 #endif
@@ -178,6 +185,9 @@
 #endif 
 #ifdef CONFIG_FB_VALKYRIE
 	{ "valkyriefb", valkyriefb_init, valkyriefb_setup },
+#endif
+#ifdef CONFIG_FB_CONTROL
+	{ "controlfb", control_init, control_setup },
 #endif
 #ifdef CONFIG_FB_G364
 	{ "g364", g364fb_init, NULL },
diff -urN linux-2.2.17-pre5/drivers/video/macmodes.c linux/drivers/video/macmodes.c
--- linux-2.2.17-pre5/drivers/video/macmodes.c	Wed Sep 30 10:19:11 1998
+++ linux/drivers/video/macmodes.c	Mon Dec  3 22:06:36 2001
@@ -367,8 +367,10 @@
 	    continue;
 	if (var->pixclock > mode->pixclock)
 	    continue;
+#if 0
 	if ((var->vmode & FB_VMODE_MASK) != mode->vmode)
 	    continue;
+#endif
 	*vmode = mode->number;
 	return 0;
     }
diff -urN linux-2.2.17-pre5/drivers/video/offb.c linux/drivers/video/offb.c
--- linux-2.2.17-pre5/drivers/video/offb.c	Wed Aug 25 17:29:49 1999
+++ linux/drivers/video/offb.c	Mon Dec  3 22:06:36 2001
@@ -42,6 +42,15 @@
 
 static int currcon = 0;
 
+/* Supported palette hacks */
+enum {
+	cmap_unknown,
+	cmap_m64,	/* ATI Mach64 */
+	cmap_r128,	/* ATI Rage128 */
+	cmap_M3A,	/* ATI Rage Mobility M3 Head A */
+	cmap_M3B	/* ATI Rage Mobility M3 Head B */
+};
+
 struct fb_info_offb {
     struct fb_info info;
     struct fb_fix_screeninfo fix;
@@ -50,6 +59,7 @@
     struct { u_char red, green, blue, pad; } palette[256];
     volatile unsigned char *cmap_adr;
     volatile unsigned char *cmap_data;
+    int cmap_type;
     union {
 #ifdef FBCON_HAS_CFB16
 	u16 cfb16[16];
@@ -106,7 +116,8 @@
 static int offb_init_driver(struct device_node *);
 static void offb_init_nodriver(struct device_node *);
 static void offb_init_fb(const char *name, const char *full_name, int width,
-		      int height, int depth, int pitch, unsigned long address);
+		      int height, int depth, int pitch, unsigned long address,
+		      struct device_node *dp);
 
     /*
      *  Interface to the low level console driver
@@ -293,6 +304,9 @@
 #ifdef CONFIG_FB_ATY
 extern void atyfb_of_init(struct device_node *dp);
 #endif /* CONFIG_FB_ATY */
+#if defined(CONFIG_FB_ATY128)
+extern void aty128fb_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_ATY128 */
 #ifdef CONFIG_FB_S3TRIO
 extern void s3triofb_init_of(struct device_node *dp);
 #endif /* CONFIG_FB_S3TRIO */
@@ -362,6 +376,20 @@
 	    }
 
 	    /*
+	     * The M3 on the Pismo powerbook has no addresses
+	     * on the display nodes, they are on their parent.
+	     */
+	    if (dp->n_addrs == 0 && device_is_compatible(dp, "ATY,RageM3p")) {
+		int na;
+		unsigned int *ap = (unsigned int *)
+		    get_property(dp, "AAPL,address", &na);
+		if (ap != 0)
+		    for (na /= sizeof(unsigned int); na > 0; --na, ++ap)
+			if (*ap <= addr && addr < *ap + 0x1000000)
+			    goto foundit;
+	    }
+
+	    /*
 	     * See if the display address is in one of the address
 	     * ranges for this display.
 	     */
@@ -386,7 +414,7 @@
 			 boot_infos->dispDeviceRect[2],
 			 boot_infos->dispDeviceRect[3],
 			 boot_infos->dispDeviceDepth,
-			 boot_infos->dispDeviceRowBytes, addr);
+			 boot_infos->dispDeviceRowBytes, addr, 0);
 	}
     }
 
@@ -409,6 +437,15 @@
 
 __initfunc(static int offb_init_driver(struct device_node *dp))
 {
+#ifdef CONFIG_FB_ATY128
+    if (!strncmp(dp->name, "ATY,Rage128", 11) ||
+    	!strncmp(dp->name, "ATY,RageM3pA", 12)) {
+	aty128fb_of_init(dp);
+	return 1;
+    }
+    if (!strncmp(dp->name, "ATY,RageM3pB", 12))
+    	return 0;
+#endif /* CONFIG_FB_ATY128*/
 #ifdef CONFIG_FB_ATY
     if (!strncmp(dp->name, "ATY", 3)) {
 	atyfb_of_init(dp);
@@ -477,9 +514,11 @@
 	&& len == sizeof(int))
 	height = *pp;
     if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
-	&& len == sizeof(int))
+	&& len == sizeof(int)) {
 	pitch = *pp;
-    else
+	if (pitch == 1)
+	    pitch = 0x1000;
+    } else
 	pitch = width;
     if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
 	&& len == sizeof(unsigned))
@@ -500,13 +539,14 @@
 	    address += 0x1000;
     }
     offb_init_fb(dp->name, dp->full_name, width, height, depth,
-		 pitch, address);
+		 pitch, address, dp);
     
 }
 
 __initfunc(static void offb_init_fb(const char *name, const char *full_name,
 				    int width, int height, int depth,
-				    int pitch, unsigned long address))
+				    int pitch, unsigned long address,
+				    struct device_node *dp))
 {
     int i;
     struct fb_fix_screeninfo *fix;
@@ -543,13 +583,27 @@
     fix->type = FB_TYPE_PACKED_PIXELS;
     fix->type_aux = 0;
 
+    info->cmap_type = cmap_unknown;
     if (depth == 8)
     {
     	/* XXX kludge for ati */
-    	if (strncmp(name, "ATY,", 4) == 0) {
+	if (dp && !strncmp(name, "ATY,Rage128", 11)) {
+		unsigned long regbase = dp->addrs[2].address;
+		info->cmap_adr = ioremap(regbase, 0x1FFF);
+		info->cmap_type = cmap_r128;
+	} else if (dp && !strncmp(name, "ATY,RageM3pA", 12)) {
+		unsigned long regbase = dp->parent->addrs[2].address;
+		info->cmap_adr = ioremap(regbase, 0x1FFF);
+		info->cmap_type = cmap_M3A;
+	} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
+		unsigned long regbase = dp->parent->addrs[2].address;
+		info->cmap_adr = ioremap(regbase, 0x1FFF);
+		info->cmap_type = cmap_M3B;
+	} else if (!strncmp(name, "ATY,", 4)) {
 		unsigned long base = address & 0xff000000UL;
 		info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
 		info->cmap_data = info->cmap_adr + 1;
+		info->cmap_type = cmap_m64;
 	}
         fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
 				     : FB_VISUAL_STATIC_PSEUDOCOLOR;
@@ -706,7 +760,7 @@
 	display_info.cmap_data_address = 0;
 	display_info.disp_reg_address = 0;
 	/* XXX kludge for ati */
-	if (strncmp(name, "ATY,", 4) == 0) {
+	if (info->cmap_type == cmap_m64) {
 	    unsigned long base = address & 0xff000000UL;
 	    display_info.disp_reg_address = base + 0x7ffc00;
 	    display_info.cmap_adr_address = base + 0x7ffcc0;
@@ -767,12 +821,33 @@
 	return;
 
     if (blank)
-	for (i = 0; i < 256; i++) {
-	    *info2->cmap_adr = i;
-	    mach_eieio();
-	    for (j = 0; j < 3; j++) {
-		*info2->cmap_data = 0;
-		mach_eieio();
+        for (i = 0; i < 256; i++) {
+	    switch(info2->cmap_type) {
+	    case cmap_m64:
+	        *info2->cmap_adr = i;
+	  	mach_eieio();
+	  	for (j = 0; j < 3; j++) {
+		    *info2->cmap_data = 0;
+		    mach_eieio();
+	    	}
+	    	break;
+	    case cmap_M3A:
+	        /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+	    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+	    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+	    case cmap_r128:
+	    	/* Set palette index & data */
+    	        out_8(info2->cmap_adr + 0xb0, i);
+	    	out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+	    	break;
+	    case cmap_M3B:
+	        /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+	    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+	    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+	    	/* Set palette index & data */
+	    	out_8(info2->cmap_adr + 0xb0, i);
+	    	out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+	    	break;
 	    }
 	}
     else
@@ -823,14 +898,37 @@
     info2->palette[regno].green = green;
     info2->palette[regno].blue = blue;
 
-    *info2->cmap_adr = regno;/* On some chipsets, add << 3 in 15 bits */
-    mach_eieio();
-    *info2->cmap_data = red;
-    mach_eieio();
-    *info2->cmap_data = green;
-    mach_eieio();
-    *info2->cmap_data = blue;
-    mach_eieio();
+    switch(info2->cmap_type) {
+    case cmap_m64:
+        *info2->cmap_adr = regno;
+	mach_eieio();
+	*info2->cmap_data = red;
+	mach_eieio();
+	*info2->cmap_data = green;
+	mach_eieio();
+	*info2->cmap_data = blue;
+	mach_eieio();
+	break;
+    case cmap_M3A:
+	/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+		in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+    case cmap_r128:
+	/* Set palette index & data */
+	out_8(info2->cmap_adr + 0xb0, regno);
+	out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+		(red << 16 | green << 8 | blue));
+	break;
+    case cmap_M3B:
+        /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+    	/* Set palette index & data */
+    	out_8(info2->cmap_adr + 0xb0, regno);
+  	out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+    		(red << 16 | green << 8 | blue));
+    	break;
+    }
 
     if (regno < 16)
 	switch (info2->var.bits_per_pixel) {
diff -urN linux-2.2.17-pre5/fs/buffer.c linux/fs/buffer.c
--- linux-2.2.17-pre5/fs/buffer.c	Mon Dec  3 22:06:30 2001
+++ linux/fs/buffer.c	Mon Dec  3 22:06:36 2001
@@ -27,6 +27,10 @@
 /* invalidate_buffers/set_blocksize/sync_dev race conditions and
    fs corruption fixes, 1999, Andrea Arcangeli <andrea@suse.de> */
 
+/* Wait for dirty buffers to sync in sync_page_buffers.
+ * 2000, Marcelo Tosatti <marcelo@conectiva.com.br>
+ */
+
 #include <linux/malloc.h>
 #include <linux/locks.h>
 #include <linux/errno.h>
@@ -1464,20 +1468,25 @@
 #define BUFFER_BUSY_BITS	((1<<BH_Dirty) | (1<<BH_Lock) | (1<<BH_Protected))
 #define buffer_busy(bh)		((bh)->b_count || ((bh)->b_state & BUFFER_BUSY_BITS))
 
-static inline int sync_page_buffers(struct buffer_head * bh)
+static int sync_page_buffers(struct buffer_head *bh, int wait)
 {
 	struct buffer_head * tmp = bh;
 
 	do {
-		if (buffer_dirty(tmp) && !buffer_locked(tmp))
-			ll_rw_block(WRITE, 1, &tmp);
+		struct buffer_head *p = tmp;
 		tmp = tmp->b_this_page;
+		if (buffer_locked(p)) {
+			if (wait)
+				__wait_on_buffer(p);
+		} else if (buffer_dirty(p))
+			ll_rw_block(WRITE, 1, &p);
 	} while (tmp != bh);
 
 	do {
-		if (buffer_busy(tmp))
-			return 1;
+		struct buffer_head *p = tmp;
 		tmp = tmp->b_this_page;
+		if (buffer_busy(p))
+			return 1;
 	} while (tmp != bh);
 
 	return 0;
@@ -1490,7 +1499,7 @@
  * Wake up bdflush() if this fails - if we're running low on memory due
  * to dirty buffers, we need to flush them out as quickly as possible.
  */
-int try_to_free_buffers(struct page * page_map)
+int try_to_free_buffers(struct page * page_map, int wait)
 {
 	struct buffer_head * tmp, * bh = page_map->buffers;
 
@@ -1521,7 +1530,7 @@
 	return 1;
 
  busy:
-	if (!sync_page_buffers(bh))
+	if (!sync_page_buffers(bh, wait))
 		/*
 		 * We can jump after the busy check because
 		 * we rely on the kernel lock.
diff -urN linux-2.2.17-pre5/fs/ntfs/Makefile linux/fs/ntfs/Makefile
--- linux-2.2.17-pre5/fs/ntfs/Makefile	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/Makefile	Mon Dec  3 22:06:36 2001
@@ -3,7 +3,7 @@
 O_TARGET := ntfs.o
 O_OBJS   := fs.o sysctl.o support.o util.o inode.o dir.o super.o attr.o
 M_OBJS   := $(O_TARGET)
-EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"990411\"
+EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"000607\"
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.2.17-pre5/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- linux-2.2.17-pre5/fs/ntfs/fs.c	Wed Jun  7 14:26:44 2000
+++ linux/fs/ntfs/fs.c	Mon Dec  3 22:06:36 2001
@@ -5,6 +5,7 @@
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996 Richard Russon
  *  Copyright (C) 1996-1997 Régis Duchesne
+ *  Copyright (C) 2000 Anton Altaparmakov
  */
 
 #ifdef HAVE_CONFIG_H
@@ -79,7 +80,7 @@
 	io.param=buf;
 	io.size=count;
 	error=ntfs_read_attr(ino,ino->vol->at_data,NULL,*off,&io);
-	if(error)return -error;
+	if(error && !io.size)return -error;
 	
 	*off+=io.size;
 	return io.size;
diff -urN linux-2.2.17-pre5/fs/ntfs/inode.c linux/fs/ntfs/inode.c
--- linux-2.2.17-pre5/fs/ntfs/inode.c	Tue Jan  4 10:12:23 2000
+++ linux/fs/ntfs/inode.c	Mon Dec  3 22:06:36 2001
@@ -6,6 +6,7 @@
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1998 Joseph Malicki
  *  Copyright (C) 1999 Steve Dodd
+ *  Copyright (C) 2000 Anton Altaparmakov
  */
 
 #include "ntfstypes.h"
@@ -551,11 +552,11 @@
 		dest->size=chunk;
 		error=ntfs_getput_clusters(ino->vol,s_cluster,
 					   offset-s_vcn*clustersize,dest);
-		if(error)/* FIXME: maybe return failure */
+		if(error)
 		{
 			ntfs_error("Read error\n");
 			dest->size=copied;
-			return 0;
+			return error;
 		}
 		l-=chunk;
 		copied+=chunk;
diff -urN linux-2.2.17-pre5/fs/ntfs/struct.h linux/fs/ntfs/struct.h
--- linux-2.2.17-pre5/fs/ntfs/struct.h	Fri Dec 19 15:24:21 1997
+++ linux/fs/ntfs/struct.h	Mon Dec  3 22:06:36 2001
@@ -3,6 +3,7 @@
  * Structure definitions
  *
  *  Copyright (C) 1997 Régis Duchesne
+ *  Copyright (C) 2000 Anton Altaparmakov
  */
 
 /* Necessary forward definition */
@@ -42,7 +43,10 @@
 	ntfs_u32 at_standard_information;
 	ntfs_u32 at_attribute_list;
 	ntfs_u32 at_file_name;
+	ntfs_u32 at_volume_version;
 	ntfs_u32 at_security_descriptor;
+	ntfs_u32 at_volume_name;
+	ntfs_u32 at_volume_information;
 	ntfs_u32 at_data;
 	ntfs_u32 at_index_root;
 	ntfs_u32 at_index_allocation;
diff -urN linux-2.2.17-pre5/fs/ntfs/super.c linux/fs/ntfs/super.c
--- linux-2.2.17-pre5/fs/ntfs/super.c	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/super.c	Mon Dec  3 22:06:36 2001
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1999 Steve Dodd
+ *  Copyright (C) 2000 Anton Altparmakov
  */
 
 #include "ntfstypes.h"
@@ -62,7 +63,10 @@
 	vol->at_standard_information=0x10;
 	vol->at_attribute_list=0x20;
 	vol->at_file_name=0x30;
+	vol->at_volume_version=0x40;
 	vol->at_security_descriptor=0x50;
+	vol->at_volume_name=0x60;
+	vol->at_volume_information=0x70;
 	vol->at_data=0x80;
 	vol->at_index_root=0x90;
 	vol->at_index_allocation=0xA0;
@@ -141,8 +145,18 @@
 	}else if(ntfs_ua_strncmp(name,"$FILE_NAME",64)==0){
 		vol->at_file_name=type;
 		check_type=0x30;
+	}else if(ntfs_ua_strncmp(name,"$VOLUME_VERSION",64)==0){
+		vol->at_volume_version=type;
+		check_type=0x40;
 	}else if(ntfs_ua_strncmp(name,"$SECURITY_DESCRIPTOR",64)==0){
-		vol->at_file_name=type;
+		vol->at_security_descriptor=type;
+		check_type=0x50;
+	}else if(ntfs_ua_strncmp(name,"$VOLUME_NAME",64)==0){
+		vol->at_volume_name=type;
+		check_type=0x60;
+	}else if(ntfs_ua_strncmp(name,"$VOLUME_INFORMATION",64)==0){
+		vol->at_volume_information=type;
+		check_type=0x70;
 	}else if(ntfs_ua_strncmp(name,"$DATA",64)==0){
 		vol->at_data=type;
 		check_type=0x80;
@@ -158,6 +172,7 @@
 	}else if(ntfs_ua_strncmp(name,"$SYMBOLIC_LINK",64)==0 ||
 		 ntfs_ua_strncmp(name,"$REPARSE_POINT",64)==0){
 		vol->at_symlink=type;
+		check_type=0xC0;
 	}
 	if(check_type && check_type!=type){
 		ntfs_error("Unexpected type %x for %x\n",type,check_type);
@@ -196,10 +211,31 @@
 	return error;
 }
 
+/* ntfs_get_version will determine the NTFS version of the 
+   volume and will return the version in a BCD format, with
+   the MSB being the major version number and the LSB the
+   minor one. Otherwise return <0 on error. 
+   Example: version 3.1 will be returned as 0x0301.
+   This has the obvious limitation of not coping with version
+   numbers above 0x80 but that shouldn't be a problem... */
+int ntfs_get_version(ntfs_inode* volume)
+{
+	ntfs_attribute *volinfo;
+
+	volinfo = ntfs_find_attr(volume, volume->vol->at_volume_information, 0);
+	if (!volinfo) 
+		return -EINVAL;
+	if (!volinfo->resident) {
+		ntfs_error("Volume information attribute is not resident!\n");
+		return -EINVAL;
+	}
+	return ((ntfs_u8*)volinfo->d.data)[8] << 8 | ((ntfs_u8*)volinfo->d.data)[9];
+}
+
 int ntfs_load_special_files(ntfs_volume *vol)
 {
 	int error;
-	ntfs_inode upcase,attrdef;
+	ntfs_inode upcase, attrdef, volume;
 
 	vol->mft_ino=(ntfs_inode*)ntfs_calloc(3*sizeof(ntfs_inode));
 	error=ENOMEM;
@@ -232,6 +268,21 @@
 	error=ntfs_init_attrdef(&attrdef);
 	ntfs_clear_inode(&attrdef);
 	if(error)return error;
+
+	/* Check for NTFS version and if Win2k version (ie. 3.0+)
+	   do not allow write access since the driver write support
+	   is broken, especially for Win2k. */
+	ntfs_debug(DEBUG_BSD,"Going to load VOLUME\n");
+	error = ntfs_init_inode(&volume,vol,FILE_VOLUME);
+	if (error) return error;
+	if ((error = ntfs_get_version(&volume)) >= 0x0300) {
+		NTFS_SB(vol)->s_flags |= MS_RDONLY;
+		ntfs_error("Warning! NTFS volume version is Win2k+: Mounting read-only\n");
+	}
+	ntfs_clear_inode(&volume);
+	if (error < 0) return error;
+	ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8, error & 0xff);
+
 	return 0;
 }
 
diff -urN linux-2.2.17-pre5/fs/ntfs/util.c linux/fs/ntfs/util.c
--- linux-2.2.17-pre5/fs/ntfs/util.c	Sat Jan  2 10:24:46 1999
+++ linux/fs/ntfs/util.c	Mon Dec  3 22:06:36 2001
@@ -266,6 +266,8 @@
 			return -1;
 		if(b[i]<a[i])
 			return 1;
+		if (a[i] == 0)
+			return 0;
 	}
 	return 0;
 }
@@ -281,6 +283,8 @@
 			return -1;
 		if(b[i]<NTFS_GETU16(a+i))
 			return 1;
+		if (b[i] == 0)
+			return 0;
 	}
 	return 0;
 }
diff -urN linux-2.2.17-pre5/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux-2.2.17-pre5/include/linux/blkdev.h	Wed Jun  7 14:26:44 2000
+++ linux/include/linux/blkdev.h	Mon Dec  3 22:06:36 2001
@@ -50,7 +50,7 @@
 ((elevator_t) {						\
 	128,			/* read_latency */	\
 	8192,			/* write_latency */	\
-	4,			/* max_bomb_segments */	\
+	32,			/* max_bomb_segments */	\
         0                       /* queue_ID */          \
 	})
 
diff -urN linux-2.2.17-pre5/include/linux/fs.h linux/include/linux/fs.h
--- linux-2.2.17-pre5/include/linux/fs.h	Wed Jun  7 14:26:44 2000
+++ linux/include/linux/fs.h	Mon Dec  3 22:06:36 2001
@@ -754,7 +754,7 @@
 
 extern void refile_buffer(struct buffer_head * buf);
 extern void set_writetime(struct buffer_head * buf, int flag);
-extern int try_to_free_buffers(struct page *);
+extern int try_to_free_buffers(struct page *, int wait);
 
 extern int nr_buffers;
 extern long buffermem;
diff -urN linux-2.2.17-pre5/include/linux/ntfs_fs_sb.h linux/include/linux/ntfs_fs_sb.h
--- linux-2.2.17-pre5/include/linux/ntfs_fs_sb.h	Fri Dec 19 15:24:22 1997
+++ linux/include/linux/ntfs_fs_sb.h	Mon Dec  3 22:06:36 2001
@@ -15,7 +15,10 @@
 	ntfs_u32 at_standard_information;
 	ntfs_u32 at_attribute_list;
 	ntfs_u32 at_file_name;
+	ntfs_u32 at_volume_version;
 	ntfs_u32 at_security_descriptor;
+	ntfs_u32 at_volume_name;
+	ntfs_u32 at_volume_information;
 	ntfs_u32 at_data;
 	ntfs_u32 at_index_root;
 	ntfs_u32 at_index_allocation;
diff -urN linux-2.2.17-pre5/mm/filemap.c linux/mm/filemap.c
--- linux-2.2.17-pre5/mm/filemap.c	Mon Dec  3 22:06:30 2001
+++ linux/mm/filemap.c	Mon Dec  3 22:06:37 2001
@@ -141,7 +141,8 @@
 	unsigned long limit = num_physpages;
 	struct page * page;
 	int count;
-
+	int nr_dirty = 0;
+	
 	/* Make sure we scan all pages twice at priority 0. */
 	count = (limit << 1) >> priority;
 
@@ -197,13 +198,22 @@
 
 		/* Is it a buffer page? */
 		if (page->buffers) {
+			/*
+			 * Wait for async IO to complete
+			 * at each 64 buffers
+			 */ 
+
+			int wait = ((gfp_mask & __GFP_IO) 
+				&& (!(nr_dirty++ % 64)));
+
 			if (buffer_under_min())
 				continue;
 			/*
 			 * We can sleep if we need to do some write
 			 * throttling.
 			 */
-			if (!try_to_free_buffers(page))
+
+			if (!try_to_free_buffers(page, wait))
 				goto refresh_clock;
 			return 1;
 		}
diff -urN linux-2.2.17-pre5/scripts/Menuconfig linux/scripts/Menuconfig
--- linux-2.2.17-pre5/scripts/Menuconfig	Wed Jun  7 14:26:44 2000
+++ linux/scripts/Menuconfig	Mon Dec  3 22:06:37 2001
@@ -425,7 +425,7 @@
 			--menu '$menu_instructions' \
 			$ROWS $COLS $((ROWS-10)) \
 			'$default' " >MCmenu
-	>MCradiolists
+	echo "#!/bin/sh" >MCradiolists
 }
 
 #
@@ -713,11 +713,11 @@
 			++menu_no
 
 			printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu
-
-			printf( "function MCmenu%s () {\n"\
+			printf( "#!/bin/sh\n"\
+				"function MCmenu%s () {\n"\
 				"default=$1\n"\
 				"menu_name %s\n",\
-				 menu_no, $0) >"MCmenu"menu_no
+				 menu_no, $0) >>"MCmenu"menu_no
 
 			parser(ifile, "MCmenu"menu_no)
 		}
@@ -772,7 +772,8 @@
 function parse_config_files () {
 	rm -f MCmenu*
 
-	echo "function MCmenu0 () {" >MCmenu0
+	echo "#!/bin/sh" > MCmenu0
+	echo "function MCmenu0 () {" >>MCmenu0
 	echo 'default=$1' >>MCmenu0
 	echo "menu_name 'Main Menu'" >>MCmenu0
 
