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.
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.
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
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/)
(boot_cpu_data.x86_mask >= 8)))
c->x86_capability |= X86_FEATURE_MTRR;
}
+
/* Fall through */
case X86_VENDOR_TRANSMETA:
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;
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";
#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>
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))
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 .;
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 .;
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:
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,
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,
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,
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
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
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
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
#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 */
#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 */
#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 */
/* 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 */
#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 */
#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 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 */
/*
* Debug flags.
*/
-#undef DEBUG
+#define DEBUG
#define GUI_RESERVE 0x00001000
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
/* 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" },
{ 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 = {
#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));
#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;
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
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);
}
{
/* 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);
}
/* 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;
}
} 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);
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;
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;
} 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;
}
#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))
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;
#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.
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;
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) {
/* 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 */
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) {
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;
-
- par->cmode = nvram_read_byte(NV_CMODE);
- if(par->cmode < CMODE_8 || par->cmode > CMODE_32)
- par->cmode = CMODE_8;
+ 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;
+
/*
* Reduce the pixel size if we don't have enough VRAM.
*/
* 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)
}
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) {
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);
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);
#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
#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 },
#endif
continue;
if (var->pixclock > mode->pixclock)
continue;
+#if 0
if ((var->vmode & FB_VMODE_MASK) != mode->vmode)
continue;
+#endif
*vmode = mode->number;
return 0;
}
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;
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];
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
#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 */
goto foundit;
}
+ /*
+ * 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.
boot_infos->dispDeviceRect[2],
boot_infos->dispDeviceRect[3],
boot_infos->dispDeviceDepth,
- boot_infos->dispDeviceRowBytes, addr);
+ boot_infos->dispDeviceRowBytes, addr, 0);
}
}
__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);
&& 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))
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;
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;
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;
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
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) {
/* 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>
#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;
* 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;
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.
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
* 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
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;
* 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"
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;
* Structure definitions
*
* Copyright (C) 1997 Régis Duchesne
+ * Copyright (C) 2000 Anton Altaparmakov
*/
/* Necessary forward definition */
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;
* 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"
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;
}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;
}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);
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;
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;
}
return -1;
if(b[i]<a[i])
return 1;
+ if (a[i] == 0)
+ return 0;
}
return 0;
}
return -1;
if(b[i]<NTFS_GETU16(a+i))
return 1;
+ if (b[i] == 0)
+ return 0;
}
return 0;
}
((elevator_t) { \
128, /* read_latency */ \
8192, /* write_latency */ \
- 4, /* max_bomb_segments */ \
+ 32, /* max_bomb_segments */ \
0 /* queue_ID */ \
})
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;
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;
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;
/* 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;
}
--menu '$menu_instructions' \
$ROWS $COLS $((ROWS-10)) \
'$default' " >MCmenu
- >MCradiolists
+ echo "#!/bin/sh" >MCradiolists
}
#
++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)
}
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