]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.18pre5 2.2.18pre5
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:22:15 +0000 (15:22 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:22:15 +0000 (15:22 -0500)
o Added older VIA ide chipsets to the not to be (Alan Cox)
autotuned list
o Fix crash on boot problem with __setup stuff (Alan Cox)
o Small acenic fix (Matt Domsch)
o Fix hfc_pci isdn driver (Jens David)
o Fix smbfs configuration problem (Urban Widmark)
o Emu10K wrapper/build fixes (Rui Sousa)
o Small cleanups (Arjan van de Ven)
o Fix sparc32 build bug (Horst von Brand)
o Fix quota oops (Martin Diehl)
o Add i810 random number driver (Jeff Garzik)
o Clear suid bits on ext2 truncate as per SuS (Andi Kleen)
o Fix illegal use of section attributes (Arjan van de Ven)
o Documentation for nmi watchdog (Marcelo Tosatti)
o Fix uninitialised variable warnings (Arjan van de Ven)
o Save DR6 condition into the TSS (Ryan Wallach)
o Add additional __init's to the kernel (Andrzej M. Krzysztofowicz)
o Backport 2.4 wdt_pci driver (JP Nollman, Alan Cox)
o AGP i810 fixes (Chip Salzenberg)
o UDMA support for ALI1543 & 1543C IDE devices (ALI)
o 2.4 MSR/CPUID driver backport (Dave Jones,
H Peter Anvin)
o Fix incorrect use of kernel v user ptr in NCPfs (Petr Vandrovec)
o Updated scsi tape driver (Kai Makisara)

60 files changed:
Documentation/Configure.help
Documentation/nmi_watchdog.txt [new file with mode: 0644]
Makefile
arch/i386/config.in
arch/i386/kernel/Makefile
arch/i386/kernel/apm.c
arch/i386/kernel/cpuid.c [new file with mode: 0644]
arch/i386/kernel/msr.c [new file with mode: 0644]
arch/i386/kernel/smp.c
arch/i386/kernel/traps.c
arch/i386/math-emu/poly_tan.c
arch/i386/mm/init.c
drivers/block/Config.in
drivers/block/Makefile
drivers/block/alim15x3.c [new file with mode: 0644]
drivers/block/ide-dma.c
drivers/block/ide-pci.c
drivers/char/Config.in
drivers/char/Makefile
drivers/char/agp/agpgart_be.c
drivers/char/i810_rng.c [new file with mode: 0644]
drivers/char/misc.c
drivers/char/saa7111.c
drivers/char/saa7185.c
drivers/char/wd501p.h
drivers/char/wdt_pci.c [new file with mode: 0644]
drivers/isdn/hisax/hfc_pci.c
drivers/net/3c505.c
drivers/net/3c509.c
drivers/net/3c515.c
drivers/net/3c527.c
drivers/net/acenic.c
drivers/net/ne2.c
drivers/net/tulip.c
drivers/net/via-rhine.c
drivers/scsi/README.st
drivers/scsi/st.c
drivers/sound/emu10k1/audio.c
drivers/sound/emu10k1/emu_wrapper.h
drivers/sound/emu10k1/main.c
drivers/sound/emu10k1/mixer.c
drivers/sound/sonicvibes.c
drivers/sound/sound_core.c
drivers/video/fbcon-mac.c
fs/Config.in
fs/adfs/file.c
fs/dquot.c
fs/ext2/file.c
fs/ext2/truncate.c
fs/ncpfs/file.c
fs/nls/Config.in
fs/ntfs/support.c
fs/smbfs/inode.c
include/linux/apm_bios.h
include/linux/ext2_fs.h
include/linux/init.h
include/linux/major.h
include/linux/smp.h
init/main.c
net/irda/compressors/Config.in

index 73667e44a5042a8ac045efd3454a01512fe20fb1..e4e30275ca3004cf35c0fc60052ed19204eef9b3 100644 (file)
@@ -624,6 +624,11 @@ CONFIG_BLK_DEV_PS2
   say M here and read Documentation/modules.txt. The module will be
   called ps2esdi.o.
 
+ALI M15X3 chipset support (EXPERIMENTAL)
+CONFIG_BLK_DEV_ALI15X3
+  This driver ensures (U)DMA support for ALI 1543 and 1543C,
+  1535, 1535D onboard chipsets.
+
 Tekram TRM290 chipset support (EXPERIMENTAL)
 CONFIG_BLK_DEV_TRM290
   This driver adds support for bus master DMA transfers
@@ -7948,6 +7953,13 @@ CONFIG_SMB_FS
   want), say M here and read Documentation/modules.txt. The module
   will be called smbfs.o. Most people say N, however.
 
+use nls by default
+CONFIG_SMB_NLS_DEFAULT
+  Enabling this will make smbfs use nls translations by default. You
+  need to specify the local charset (CONFIG_NLS_DEFAULT) in the nls
+  settings and you need to give the default nls for the SMB server as
+  CONFIG_SMB_NLS_REMOTE.
+
 nls support setting
 CONFIG_SMB_NLS_REMOTE
   This setting allows you to specify a default value for which
diff --git a/Documentation/nmi_watchdog.txt b/Documentation/nmi_watchdog.txt
new file mode 100644 (file)
index 0000000..58303e9
--- /dev/null
@@ -0,0 +1,34 @@
+
+Is your SMP system locking up unpredictably? No keyboard activity, just
+a frustrating complete hard lockup? Do you want to help us debugging
+such lockups? If all yes then this document is definitely for you.
+
+on Intel SMP hardware there is a feature that enables us to generate
+'watchdog NMI interrupts'. (NMI: Non Maskable Interrupt - these get
+executed even if the system is otherwise locked up hard) This can be
+used to debug hard kernel lockups. By executing periodic NMI interrupts,
+the kernel can monitor wether any CPU has locked up, and print out
+debugging messages if so.  You can enable/disable the NMI watchdog at boot
+time with the 'nmi_watchdog=1' boot parameter. Eg. the relevant
+lilo.conf entry:
+
+        append="nmi_watchdog=1"
+
+A 'lockup' is the following scenario: if any CPU in the system does not
+execute the period local timer interrupt for more than 5 seconds, then
+the NMI handler generates an oops and kills the process. This
+'controlled crash' (and the resulting kernel messages) can be used to
+debug the lockup. Thus whenever the lockup happens, wait 5 seconds and
+the oops will show up automatically. If the kernel produces no messages
+then the system has crashed so hard (eg. hardware-wise) that either it
+cannot even accept NMI interrupts, or the crash has made the kernel
+unable to print messages.
+
+You can find NMI watchdog patch against Linux 2.2.x at 
+http://people.redhat.com/mingo/NMI-watchdog-patches/
+
+
+[ feel free to send bug reports, suggestions and patches to
+  Ingo Molnar <mingo@redhat.com> or the Linux SMP mailing
+  list at <linux-smp@vger.rutgers.edu> ]
+
index 9e4ffaef794eaad2ad90baa4a19106a0f95f46bb..7cfa63258605d6853b0119801f70351987a30440 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 18
-EXTRAVERSION = pre4
+EXTRAVERSION = pre5
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
index 9bcdbad0d185de51905be6b64e4ae6ded13eb1a2..1b01142ef8282c12256d61fd0f103276c4924427 100644 (file)
@@ -34,6 +34,8 @@ if [ "$CONFIG_M686" = "y" ]; then
 fi
 
 tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE
+tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR
+tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID
 
 choice 'Maximum Physical Memory' \
        "1GB            CONFIG_1GB \
@@ -111,7 +113,6 @@ if [ "$CONFIG_APM" != "n" ]; then
   bool '   Enable PM at boot time' CONFIG_APM_DO_ENABLE
   bool '   Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
   bool '   Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
-  bool '   Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
   bool '   RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
   bool '   Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
   bool '   Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
index 5ad96667ba93a975bbcd7da8a6cbbde6bafdda0e..daae39d2ed13a5b6b6f5c0df018f6d6dcf3fece7 100644 (file)
@@ -43,6 +43,22 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_X86_MSR),y)
+OX_OBJS += msr.o
+else
+  ifeq ($(CONFIG_X86_MSR),m)
+  MX_OBJS += msr.o
+  endif
+endif
+
+ifeq ($(CONFIG_X86_CPUID),y)
+OX_OBJS += cpuid.o
+else
+  ifeq ($(CONFIG_X86_CPUID),m)
+  MX_OBJS += cpuid.o
+  endif
+endif
+
 ifdef CONFIG_APM
 OX_OBJS += apm.o
 endif
index 9565f40d211814cf6c372705e21a1666eedde353..a1eef7a50a259fe8269ab40e71acb43d5c875372 100644 (file)
 #include <asm/desc.h>
 #include <asm/softirq.h>
 
-/* 2.2-2.3 Compatability defines */
-#define __setup(x, y)
-#define module_init(x)
-
 EXPORT_SYMBOL(apm_register_callback);
 EXPORT_SYMBOL(apm_unregister_callback);
 
@@ -1430,7 +1426,7 @@ static int __init apm(void *unused)
        return 0;
 }
 
-void __init apm_setup(char *str, int *dummy)
+static int __init apm_setup(char *str)
 {
        int     invert;
 
@@ -1450,6 +1446,7 @@ void __init apm_setup(char *str, int *dummy)
                if (str != NULL)
                        str += strspn(str, ", \t");
        }
+       return 1;
 }
 
 __setup("apm=", apm_setup);
@@ -1468,13 +1465,12 @@ static struct miscdevice apm_device = {
        &apm_bios_fops
 };
 
-#define APM_INIT_ERROR_RETURN  return
 
-void __init apm_init(void)
+static int __init apm_init(void)
 {
        if (apm_bios_info.version == 0) {
                printk(KERN_INFO "apm: BIOS not found.\n");
-               APM_INIT_ERROR_RETURN;
+               return -ENODEV;
        }
        printk(KERN_INFO
                "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
@@ -1484,7 +1480,7 @@ void __init apm_init(void)
                driver_version);
        if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0) {
                printk(KERN_INFO "apm: no 32 bit BIOS support\n");
-               APM_INIT_ERROR_RETURN;
+               return -ENODEV;
        }
 
        /*
@@ -1513,11 +1509,11 @@ void __init apm_init(void)
 
        if (apm_disabled) {
                printk(KERN_NOTICE "apm: disabled on user request.\n");
-               APM_INIT_ERROR_RETURN;
+               return -ENODEV;
        }
        if ((smp_num_cpus > 1) && !power_off_enabled) {
                printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
-               APM_INIT_ERROR_RETURN;
+               return -ENODEV;
        }
 
        /*
@@ -1565,7 +1561,7 @@ void __init apm_init(void)
        if (smp_num_cpus > 1) {
                printk(KERN_NOTICE
                   "apm: disabled - APM is not SMP safe (power off active).\n");
-               APM_INIT_ERROR_RETURN;
+               return 0;
        }
 
        init_timer(&apm_timer);
@@ -1578,6 +1574,7 @@ void __init apm_init(void)
 #ifdef CONFIG_APM_CPU_IDLE
        acpi_idle = apm_cpu_idle;
 #endif
+       return 0;
 }
 
 module_init(apm_init)
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
new file mode 100644 (file)
index 0000000..a10b340
--- /dev/null
@@ -0,0 +1,171 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2000 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+
+/*
+ * cpuid.c
+ *
+ * x86 CPUID access device
+ *
+ * This device is accessed by lseek() to the appropriate CPUID level
+ * and then read in chunks of 16 bytes.  A larger size means multiple
+ * reads of consecutive levels.
+ *
+ * This driver uses /dev/cpu/%d/cpuid where %d is the minor number, and on
+ * an SMP box will direct the access to CPU %d.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/smp.h>
+#include <linux/major.h>
+
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SMP
+
+struct cpuid_command {
+  int cpu;
+  u32 reg;
+  u32 *data;
+};
+
+static void cpuid_smp_cpuid(void *cmd_block)
+{
+  struct cpuid_command *cmd = (struct cpuid_command *) cmd_block;
+  
+  if ( cmd->cpu == smp_processor_id() )
+    cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2], &cmd->data[3]);
+}
+
+extern inline void do_cpuid(int cpu, u32 reg, u32 *data)
+{
+  struct cpuid_command cmd;
+  
+  if ( cpu == smp_processor_id() ) {
+    cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
+  } else {
+    cmd.cpu  = cpu;
+    cmd.reg  = reg;
+    cmd.data = data;
+    
+    smp_call_function(cpuid_smp_cpuid, &cmd, 1, 1);
+  }
+}
+#else /* ! CONFIG_SMP */
+
+extern inline void do_cpuid(int cpu, u32 reg, u32 *data)
+{
+  cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
+}
+
+#endif /* ! CONFIG_SMP */
+
+static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
+{
+  switch (orig) {
+  case 0:
+    file->f_pos = offset;
+    return file->f_pos;
+  case 1:
+    file->f_pos += offset;
+    return file->f_pos;
+  default:
+    return -EINVAL;    /* SEEK_END not supported */
+  }
+}
+
+static ssize_t cpuid_read(struct file * file, char * buf,
+                       size_t count, loff_t *ppos)
+{
+  u32 *tmp = (u32 *)buf;
+  u32 data[4];
+  size_t rv;
+  u32 reg = *ppos;
+  int cpu = MINOR(file->f_dentry->d_inode->i_rdev);
+  
+  if ( count % 16 )
+    return -EINVAL; /* Invalid chunk size */
+  
+  for ( rv = 0 ; count ; count -= 16 ) {
+    do_cpuid(cpu, reg, data);
+    if ( copy_to_user(tmp,&data,16) )
+      return -EFAULT;
+    tmp += 4;
+    *ppos = reg++;
+  }
+  
+  return ((char *)tmp) - buf;
+}
+
+static int cpuid_open(struct inode *inode, struct file *file)
+{
+  int cpu = MINOR(file->f_dentry->d_inode->i_rdev);
+  struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+
+  if ( !(cpu_online_map & (1UL << cpu)) )
+    return -ENXIO;             /* No such CPU */
+  if ( c->cpuid_level < 0 )
+    return -EIO;               /* CPUID not supported */
+  
+  return 0;
+}
+
+/*
+ * File operations we support
+ */
+static struct file_operations cpuid_fops = {
+  llseek:      cpuid_seek,
+  read:                cpuid_read,
+  open:                cpuid_open,
+};
+
+int __init cpuid_init(void)
+{
+  if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
+    printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
+          CPUID_MAJOR);
+    return -EBUSY;
+  }
+
+  return 0;
+}
+
+#ifdef MODULE
+static void cpuid_exit(void)
+{
+}
+
+int init_module (void)
+{
+       return cpuid_init();
+}
+void cleanup_module (void)
+{
+       cpuid_exit();
+}
+#endif
+       
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
+MODULE_DESCRIPTION("x86 generic CPUID driver");
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
new file mode 100644 (file)
index 0000000..0eeab16
--- /dev/null
@@ -0,0 +1,278 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2000 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * msr.c
+ *
+ * x86 MSR access device
+ *
+ * This device is accessed by lseek() to the appropriate register number
+ * and then read/write in chunks of 8 bytes.  A larger size means multiple
+ * reads or writes of the same register.
+ *
+ * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
+ * an SMP box will direct the access to CPU %d.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/smp.h>
+#include <linux/major.h>
+
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+/* Note: "err" is handled in a funny way below.  Otherwise one version
+   of gcc or another breaks. */
+
+extern inline int wrmsr_eio(u32 reg, u32 eax, u32 edx)
+{
+  int err;
+
+  asm volatile(
+              "1:      wrmsr\n"
+              "2:\n"
+              ".section .fixup,\"ax\"\n"
+              "3:      movl %4,%0\n"
+              "        jmp 2b\n"
+              ".previous\n"
+              ".section __ex_table,\"a\"\n"
+              "        .align 4\n"
+              "        .long 1b,3b\n"
+              ".previous"
+              : "=&bDS" (err)
+              : "a" (eax), "d" (edx), "c" (reg), "i" (-EIO), "0" (0));
+
+  return err;
+}
+
+extern inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx)
+{
+  int err;
+
+  asm volatile(
+              "1:      rdmsr\n"
+              "2:\n"
+              ".section .fixup,\"ax\"\n"
+              "3:      movl %4,%0\n"
+              "        jmp 2b\n"
+              ".previous\n"
+              ".section __ex_table,\"a\"\n"
+              "        .align 4\n"
+              "        .long 1b,3b\n"
+              ".previous"
+              : "=&bDS" (err), "=a" (*eax), "=d" (*edx)
+              : "c" (reg), "i" (-EIO), "0" (0));
+
+  return err;
+}
+
+#ifdef CONFIG_SMP
+
+struct msr_command {
+  int cpu;
+  int err;
+  u32 reg;
+  u32 data[2];
+};
+
+static void msr_smp_wrmsr(void *cmd_block)
+{
+  struct msr_command *cmd = (struct msr_command *) cmd_block;
+  
+  if ( cmd->cpu == smp_processor_id() )
+    cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]);
+}
+
+static void msr_smp_rdmsr(void *cmd_block)
+{
+  struct msr_command *cmd = (struct msr_command *) cmd_block;
+  
+  if ( cmd->cpu == smp_processor_id() )
+    cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]);
+}
+
+extern inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
+{
+  struct msr_command cmd;
+
+  if ( cpu == smp_processor_id() ) {
+    return wrmsr_eio(reg, eax, edx);
+  } else {
+    cmd.cpu = cpu;
+    cmd.reg = reg;
+    cmd.data[0] = eax;
+    cmd.data[1] = edx;
+    
+    smp_call_function(msr_smp_wrmsr, &cmd, 1, 1);
+    return cmd.err;
+  }
+}
+
+extern inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
+{
+  struct msr_command cmd;
+
+  if ( cpu == smp_processor_id() ) {
+    return rdmsr_eio(reg, eax, edx);
+  } else {
+    cmd.cpu = cpu;
+    cmd.reg = reg;
+
+    smp_call_function(msr_smp_rdmsr, &cmd, 1, 1);
+    
+    *eax = cmd.data[0];
+    *edx = cmd.data[1];
+
+    return cmd.err;
+  }
+}
+
+#else /* ! CONFIG_SMP */
+
+extern inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
+{
+  return wrmsr_eio(reg, eax, edx);
+}
+
+extern inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
+{
+  return rdmsr_eio(reg, eax, edx);
+}
+
+#endif /* ! CONFIG_SMP */
+
+static loff_t msr_seek(struct file *file, loff_t offset, int orig)
+{
+  switch (orig) {
+  case 0:
+    file->f_pos = offset;
+    return file->f_pos;
+  case 1:
+    file->f_pos += offset;
+    return file->f_pos;
+  default:
+    return -EINVAL;    /* SEEK_END not supported */
+  }
+}
+
+static ssize_t msr_read(struct file * file, char * buf,
+                       size_t count, loff_t *ppos)
+{
+  u32 *tmp = (u32 *)buf;
+  u32 data[2];
+  size_t rv;
+  u32 reg = *ppos;
+  int cpu = MINOR(file->f_dentry->d_inode->i_rdev);
+  int err;
+
+  if ( count % 8 )
+    return -EINVAL; /* Invalid chunk size */
+  
+  for ( rv = 0 ; count ; count -= 8 ) {
+    err = do_rdmsr(cpu, reg, &data[0], &data[1]);
+    if ( err )
+      return err;
+    if ( copy_to_user(tmp,&data,8) )
+      return -EFAULT;
+    tmp += 2;
+  }
+
+  return ((char *)tmp) - buf;
+}
+
+static ssize_t msr_write(struct file * file, const char * buf,
+                        size_t count, loff_t *ppos)
+{
+  const u32 *tmp = (const u32 *)buf;
+  u32 data[2];
+  size_t rv;
+  u32 reg = *ppos;
+  int cpu = MINOR(file->f_dentry->d_inode->i_rdev);
+  int err;
+
+  if ( count % 8 )
+    return -EINVAL; /* Invalid chunk size */
+  
+  for ( rv = 0 ; count ; count -= 8 ) {
+    if ( copy_from_user(&data,tmp,8) )
+      return -EFAULT;
+    err = do_wrmsr(cpu, reg, data[0], data[1]);
+    if ( err )
+      return err;
+    tmp += 2;
+  }
+
+  return ((char *)tmp) - buf;
+}
+
+static int msr_open(struct inode *inode, struct file *file)
+{
+  int cpu = MINOR(file->f_dentry->d_inode->i_rdev);
+  struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+  
+  if ( !(cpu_online_map & (1UL << cpu)) )
+    return -ENXIO;             /* No such CPU */
+  if ( !(c->x86_capability & X86_FEATURE_MSR) )
+    return -EIO;               /* MSR not supported */
+  
+  return 0;
+}
+
+/*
+ * File operations we support
+ */
+static struct file_operations msr_fops = {
+  llseek:      msr_seek,
+  read:                msr_read,
+  write:       msr_write,
+  open:                msr_open,
+};
+
+int __init msr_init(void)
+{
+  if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
+    printk(KERN_ERR "msr: unable to get major %d for msr\n",
+          MSR_MAJOR);
+    return -EBUSY;
+  }
+  
+  return 0;
+}
+
+#ifdef MODULE
+static void msr_exit(void)
+{
+}
+
+int init_module(void)
+{
+       return msr_init();
+}
+void cleanup_module(void)
+{
+       msr_exit();
+}
+#endif
+
+MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
+MODULE_DESCRIPTION("x86 generic MSR driver");
+EXPORT_NO_SYMBOLS;
index cf86f700dbccd39eef8f435346d8d15aeb6c930d..48a02c3ff8bd05959485a789841a84062a143a2b 100644 (file)
@@ -658,7 +658,7 @@ static unsigned long __init setup_trampoline(void)
        return virt_to_phys(trampoline_base);
 }
 
-extern unsigned long i386_endbase __initdata;
+extern unsigned long i386_endbase;
 /*
  *     We are called very early to get the low memory for the
  *     SMP bootup trampoline page.
index 8332102a929df0a2f934489213e05cbfd99a4ae5..c15ade35b23a23b739c714fa24c1b83aff5e7e61 100644 (file)
@@ -399,6 +399,7 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
        /* Ok, finally something we can handle */
        tsk->tss.trap_no = 1;
        tsk->tss.error_code = error_code;
+       tsk->tss.debugreg[DR_STATUS] = condition;
        force_sig(SIGTRAP, tsk);
        return;
 
index 13a32b9fcfbb575dc2491f42338779ac257a9d53..251f004557735522ff884456091cceb0ec4e2fb2 100644 (file)
@@ -89,7 +89,7 @@ void  poly_tan(FPU_REG *st0_ptr)
        {
          FPU_settag0(TAG_Valid);
          significand(st0_ptr) = 0x8a51e04daabda360LL;
-         setexponent16(st0_ptr, 0x41 + EXTENDED_Ebias | SIGN_Negative);
+         setexponent16(st0_ptr, (0x41 + EXTENDED_Ebias) | SIGN_Negative);
          return;
        }
 
index d0c7586b07e83cdf76e99ef82b95304b3f0e84dc..757e59cef8fbca925797171901fc11d111d53931 100644 (file)
@@ -384,7 +384,7 @@ __initfunc(void test_wp_bit(void))
                printk(".\n");
 }
 
-extern unsigned long i386_endbase __initdata;
+extern unsigned long i386_endbase;
 
 __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
 {
index b5951af72379f7bf3f60a2c67e1d9f1f60fecb75..4faeb42e4abd519decda423bd8c951d778ee52ea 100644 (file)
@@ -40,6 +40,7 @@ else
         if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
           bool '     OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621
           if [ "$CONFIG_BLK_DEV_IDEDMA" = "y" ]; then
+                       bool '     ALI 15X3 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_ALI15X3
             bool '     Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
             bool '     NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415
             bool '     VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586
index cd1ff13f44e00b3d97557c8fb527ef2c4b6be1db..f50fa17affdb2e627c46f36b304a3b2c7dd952e7 100644 (file)
@@ -142,6 +142,10 @@ ifeq ($(CONFIG_BLK_DEV_PDC4030),y)
 IDE_OBJS += pdc4030.o
 endif
 
+ifeq ($(CONFIG_BLK_DEV_ALI15X3),y)
+IDE_OBJS += alim15x3.o
+endif
+
 ifeq ($(CONFIG_BLK_DEV_TRM290),y)
 IDE_OBJS += trm290.o
 endif
diff --git a/drivers/block/alim15x3.c b/drivers/block/alim15x3.c
new file mode 100644 (file)
index 0000000..61c036a
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ *
+ *  Copyright (C) 1998-99 Michel Aubry, Maintainer
+ *  Copyright (C) 1998-99 Andrzej Krzysztofowicz, Maintainer
+ *  Copyright (C) 1998-99 Andre Hedrick, Integrater and Maintainer
+ *
+ *  (U)DMA capable version of ali 1543(C), 1535(D)
+ *
+ */
+
+/*  ======================================================
+ *  linux/drivers/block/alim15x3.c
+ *  version: 1.0 beta3 (Sep. 6, 1999)
+ *     e-mail your problems to cjtsai@ali.com.tw
+ *
+ *  Note: if you want to combine the code to kernel 2.3.x
+ *  you should ---
+ *             change:         //#define ALI_KERNEL_2_3_X
+ *             to:                     #define ALI_KERNEL_2_3_X
+ *  and replace the "alim15x3.c" exists in kernel 2.3.x
+ *  with this file. I am not very sure that this file can 
+ *  support all 2.3.x. Because I only test it in kernel
+ *  version 2.3.16. So, before you replace the file, backup
+ *     the old one.
+ * ======================================================= */
+
+/* ===================== important =======================
+ *  for 2.2.x, you should use "//#define ALI_KERNEL_2_3_X"
+ *  for 2.3.x, you should use "#define ALI_KERNEL_2_3_X"
+ * ======================================================= */
+//#define ALI_KERNEL_2_3_X
+
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#if defined(ALI_KERNEL_2_3_X)
+#include <linux/ide.h>
+#else
+#include "ide.h"
+#endif
+
+#include "ide_modes.h"
+
+static int m5229_revision = -1;
+static int chip_is_1543c_e = 0;
+static int cable_80_pin[2] = { 0, 0 };
+
+/* This is fun.  -DaveM */
+#define IDE_SETXFER                    0x03
+#define IDE_SETFEATURE         0xef
+
+#define IDE_DMA2_ENABLE                0x22    // dma
+#define IDE_DMA1_ENABLE                0x21
+#define IDE_DMA0_ENABLE                0x20
+
+#define IDE_UDMA4_ENABLE       0x44    // ultra 66
+#define IDE_UDMA3_ENABLE       0x43
+
+#define IDE_UDMA2_ENABLE       0x42    // ultra 33
+#define IDE_UDMA1_ENABLE       0x41
+#define IDE_UDMA0_ENABLE       0x40
+
+
+
+#if defined(ALI_KERNEL_2_3_X)
+// =====================   Support 2.3.x   =====================
+
+
+#define DISPLAY_ALI_TIMINGS
+
+#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int dummy);
+extern int (*ali_display_info)(char *, char **, off_t, int, int);  /* ide-proc.c */
+struct pci_dev *bmide_dev;
+
+char *fifo[4] = {
+       "FIFO Off",
+       "FIFO On ",
+       "DMA mode",
+       "PIO mode" };
+
+char *udmaT[8] = {
+       "1.5T",
+       "  2T",
+       "2.5T",
+       "  3T",
+       "3.5T",
+       "  4T",
+       "  6T",
+       "  8T"
+};
+
+char *channel_status[8] = {
+       "OK            ",
+       "busy          ",
+       "DRQ           ",
+       "DRQ busy      ",
+       "error         ",
+       "error busy    ",
+       "error DRQ     ",
+       "error DRQ busy"
+};
+#endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name)
+{
+       byte confreg0 = 0, confreg1 =0, progif = 0;
+       int errors = 0;
+
+       if (pci_read_config_byte(dev, 0x50, &confreg1))
+               goto veryspecialsettingserror;
+       if (!(confreg1 & 0x02))
+               if (pci_write_config_byte(dev, 0x50, confreg1 | 0x02))
+                       goto veryspecialsettingserror;
+
+       if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif))
+               goto veryspecialsettingserror;
+       if (!(progif & 0x40)) {
+               /*
+                * The way to enable them is to set progif
+                * writable at 0x4Dh register, and set bit 6
+                * of progif to 1:
+                */
+               if (pci_read_config_byte(dev, 0x4d, &confreg0))
+                       goto veryspecialsettingserror;
+               if (confreg0 & 0x80)
+                       if (pci_write_config_byte(dev, 0x4d, confreg0 & ~0x80))
+                               goto veryspecialsettingserror;
+               if (pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x40))
+                       goto veryspecialsettingserror;
+               if (confreg0 & 0x80)
+                       if (pci_write_config_byte(dev, 0x4d, confreg0))
+                               errors++;
+       }
+
+       if ((pci_read_config_byte(dev, PCI_CLASS_PROG, &progif)) || (!(progif & 0x40)))
+               goto veryspecialsettingserror;
+
+       printk("%s: enabled read of IDE channels state (en/dis-abled) %s.\n",
+               name, errors ? "with Error(s)" : "Succeeded" );
+       return 0;
+
+veryspecialsettingserror:
+       printk("%s: impossible to enable read of IDE channels state (en/dis-abled)!\n", name);
+       return 0;
+}
+
+static void ali15x3_tune_drive (ide_drive_t *drive, byte pio)
+{
+       ide_pio_data_t d;
+       ide_hwif_t *hwif = HWIF(drive);
+       struct pci_dev *dev = hwif->pci_dev;
+       int s_time, a_time, c_time;
+       byte s_clc, a_clc, r_clc;
+       unsigned long flags;
+       int bus_speed = ide_system_bus_speed();
+       int port = hwif->index ? 0x5c : 0x58;
+
+       pio = ide_get_best_pio_mode(drive, pio, 5, &d);
+       s_time = ide_pio_timings[pio].setup_time;
+       a_time = ide_pio_timings[pio].active_time;
+       if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
+               s_clc = 0;
+       if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
+               a_clc = 0;
+       c_time = ide_pio_timings[pio].cycle_time;
+
+#if 0
+       if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16)
+               r_clc = 0;
+#endif
+
+       if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
+               r_clc = 1;
+       } else {
+               if (r_clc >= 16)
+               r_clc = 0;
+       }
+       save_flags(flags);
+       cli();
+       pci_write_config_byte(dev, port, s_clc);
+       pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
+       restore_flags(flags);
+
+       /*
+        * setup   active  rec
+        * { 70,   165,    365 },   PIO Mode 0
+        * { 50,   125,    208 },   PIO Mode 1
+        * { 30,   100,    110 },   PIO Mode 2
+        * { 30,   80,     70  },   PIO Mode 3 with IORDY
+        * { 25,   70,     25  },   PIO Mode 4 with IORDY  ns
+        * { 20,   50,     30  }    PIO Mode 5 with IORDY (nonstandard)
+        */
+}
+
+#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
+static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int dummy)
+{
+       byte reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1;
+       unsigned int bibma;
+       byte c0, c1;
+       byte rev, tmp;
+       char *p = buffer;
+       char *q;
+
+       /* fetch rev. */
+       pci_read_config_byte(bmide_dev, 0x08, &rev);
+       if (rev >= 0xc1)        /* M1543C or newer */
+               udmaT[7] = " ???";
+       else
+               fifo[3]  = "   ???  ";
+
+       /* first fetch bibma: */
+       pci_read_config_dword(bmide_dev, 0x20, &bibma);
+       bibma = (bibma & 0xfff0) ;
+       /*
+        * at that point bibma+0x2 et bibma+0xa are byte
+        * registers to investigate:
+        */
+       c0 = inb((unsigned short)bibma + 0x02);
+       c1 = inb((unsigned short)bibma + 0x0a);
+
+       p += sprintf(p,
+               "\n                                Ali M15x3 Chipset.\n");
+       p += sprintf(p,
+               "                                ------------------\n");
+       pci_read_config_byte(bmide_dev, 0x78, &reg53h);
+       p += sprintf(p, "PCI Clock: %d.\n", reg53h);
+
+       pci_read_config_byte(bmide_dev, 0x53, &reg53h);
+       p += sprintf(p,
+               "CD_ROM FIFO:%s, CD_ROM DMA:%s\n",
+               (reg53h & 0x02) ? "Yes" : "No ",
+               (reg53h & 0x01) ? "Yes" : "No " );
+       pci_read_config_byte(bmide_dev, 0x74, &reg53h);
+       p += sprintf(p,
+               "FIFO Status: contains %d Words, runs%s%s\n\n",
+               (reg53h & 0x3f),
+               (reg53h & 0x40) ? " OVERWR" : "",
+               (reg53h & 0x80) ? " OVERRD." : "." );
+
+       p += sprintf(p,
+               "-------------------primary channel-------------------secondary channel---------\n\n");
+
+       pci_read_config_byte(bmide_dev, 0x09, &reg53h);
+       p += sprintf(p,
+               "channel status:       %s                               %s\n",
+               (reg53h & 0x20) ? "On " : "Off",
+               (reg53h & 0x10) ? "On " : "Off" );
+
+       p += sprintf(p,
+               "both channels togth:  %s                               %s\n",
+               (c0&0x80) ? "No " : "Yes",
+               (c1&0x80) ? "No " : "Yes" );
+
+       pci_read_config_byte(bmide_dev, 0x76, &reg53h);
+       p += sprintf(p,
+               "Channel state:        %s                    %s\n",
+               channel_status[reg53h & 0x07],
+               channel_status[(reg53h & 0x70) >> 4] );
+
+       pci_read_config_byte(bmide_dev, 0x58, &reg5xh);
+       pci_read_config_byte(bmide_dev, 0x5c, &reg5yh);
+       p += sprintf(p,
+               "Add. Setup Timing:    %dT                                %dT\n",
+               (reg5xh & 0x07) ? (reg5xh & 0x07) : 8,
+               (reg5yh & 0x07) ? (reg5yh & 0x07) : 8 );
+
+       pci_read_config_byte(bmide_dev, 0x59, &reg5xh);
+       pci_read_config_byte(bmide_dev, 0x5d, &reg5yh);
+       p += sprintf(p,
+               "Command Act. Count:   %dT                                %dT\n"
+               "Command Rec. Count:   %dT                               %dT\n\n",
+               (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
+               (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, 
+               (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
+               (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 );
+
+       p += sprintf(p,
+               "----------------drive0-----------drive1------------drive0-----------drive1------\n\n");
+       p += sprintf(p,
+               "DMA enabled:      %s              %s               %s              %s\n",
+               (c0&0x20) ? "Yes" : "No ",
+               (c0&0x40) ? "Yes" : "No ",
+               (c1&0x20) ? "Yes" : "No ",
+               (c1&0x40) ? "Yes" : "No " );
+
+       pci_read_config_byte(bmide_dev, 0x54, &reg5xh);
+       pci_read_config_byte(bmide_dev, 0x55, &reg5yh);
+       q = "FIFO threshold:   %2d Words         %2d Words          %2d Words         %2d Words\n";
+       if (rev < 0xc1) {
+               if ((rev == 0x20) && (pci_read_config_byte(bmide_dev, 0x4f, &tmp), (tmp &= 0x20))) {
+                       p += sprintf(p, q, 8, 8, 8, 8);
+               } else {
+                       p += sprintf(p, q,
+                               (reg5xh & 0x03) + 12,
+                               ((reg5xh & 0x30)>>4) + 12,
+                               (reg5yh & 0x03) + 12,
+                               ((reg5yh & 0x30)>>4) + 12 );
+               }
+       } else {
+               p += sprintf(p, q,
+                       (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4,
+                       (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4,
+                       (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4,
+                       (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4 );
+       }
+
+#if 0
+       p += sprintf(p, 
+               "FIFO threshold:   %2d Words         %2d Words          %2d Words         %2d Words\n",
+               (reg5xh & 0x03) + 12,
+               ((reg5xh & 0x30)>>4) + 12,
+               (reg5yh & 0x03) + 12,
+               ((reg5yh & 0x30)>>4) + 12 );
+#endif
+
+       p += sprintf(p,
+               "FIFO mode:        %s         %s          %s         %s\n",
+               fifo[((reg5xh & 0x0c) >> 2)],
+               fifo[((reg5xh & 0xc0) >> 6)],
+               fifo[((reg5yh & 0x0c) >> 2)],
+               fifo[((reg5yh & 0xc0) >> 6)] );
+
+       pci_read_config_byte(bmide_dev, 0x5a, &reg5xh);
+       pci_read_config_byte(bmide_dev, 0x5b, &reg5xh1);
+       pci_read_config_byte(bmide_dev, 0x5e, &reg5yh);
+       pci_read_config_byte(bmide_dev, 0x5f, &reg5yh1);
+
+       p += sprintf(p,/*
+               "------------------drive0-----------drive1------------drive0-----------drive1------\n")*/
+               "Dt RW act. Cnt    %2dT              %2dT               %2dT              %2dT\n"
+               "Dt RW rec. Cnt    %2dT              %2dT               %2dT              %2dT\n\n",
+               (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
+               (reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8,
+               (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8,
+               (reg5yh1 & 0x70) ? ((reg5yh1 & 0x70) >> 4) : 8,
+               (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
+               (reg5xh1 & 0x0f) ? (reg5xh1 & 0x0f) : 16,
+               (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16,
+               (reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 );
+
+       p += sprintf(p,
+               "-----------------------------------UDMA Timings--------------------------------\n\n");
+
+       pci_read_config_byte(bmide_dev, 0x56, &reg5xh);
+       pci_read_config_byte(bmide_dev, 0x57, &reg5yh);
+       p += sprintf(p,
+               "UDMA:             %s               %s                %s               %s\n"
+               "UDMA timings:     %s             %s              %s             %s\n\n",
+               (reg5xh & 0x08) ? "OK" : "No",
+               (reg5xh & 0x80) ? "OK" : "No",
+               (reg5yh & 0x08) ? "OK" : "No",
+               (reg5yh & 0x80) ? "OK" : "No",
+               udmaT[(reg5xh & 0x07)],
+               udmaT[(reg5xh & 0x70) >> 4],
+               udmaT[reg5yh & 0x07],
+               udmaT[(reg5yh & 0x70) >> 4] );
+
+       return p-buffer; /* => must be less than 4k! */
+}
+#endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+
+// ===================   End Support 2.3.x   ===================
+#endif // defined(ALI_KERNEL_2_3_X)
+
+
+
+static __inline__ unsigned char dma2_bits_to_command(unsigned char bits)
+{
+       if(bits & 0x04)
+               return IDE_DMA2_ENABLE;
+       if(bits & 0x02)
+               return IDE_DMA1_ENABLE;
+       return IDE_DMA0_ENABLE;
+}
+
+static __inline__ unsigned char udma2_bits_to_command(unsigned char bits)
+{
+       if(bits & 0x10)
+               return IDE_UDMA4_ENABLE;
+       if(bits & 0x08)
+               return IDE_UDMA3_ENABLE;
+       if(bits & 0x04)
+               return IDE_UDMA2_ENABLE;
+       if(bits & 0x02)
+               return IDE_UDMA1_ENABLE;
+       return IDE_UDMA0_ENABLE;
+}
+
+static __inline__ int wait_for_ready(ide_drive_t *drive)
+{
+       int timeout = 20000;
+       byte stat;
+
+       while(--timeout) {
+               stat = GET_STAT();      // printk("STAT(%2x) ", stat);
+               
+               if(!(stat & BUSY_STAT)) {
+                       if((stat & READY_STAT) || (stat & ERR_STAT))
+                               break;
+               }
+               udelay(150);
+       }
+       if((stat & ERR_STAT) || timeout <= 0)
+               return 1;
+       return 0;
+}
+
+static void ali15x3_do_setfeature(ide_drive_t *drive, byte command)
+{
+       unsigned long flags;
+       byte old_select;
+
+       save_flags(flags);
+       cli();
+               
+       old_select = IN_BYTE(IDE_SELECT_REG);   //  save old selected device
+       OUT_BYTE(drive->select.all, IDE_SELECT_REG);    // "SELECT "
+
+       OUT_BYTE(IDE_SETXFER, IDE_FEATURE_REG); // "SETXFER "   
+       OUT_BYTE(command, IDE_NSECTOR_REG);     // "CMND "
+       
+       if(wait_for_ready(drive))       // "wait "
+               goto out;
+
+       OUT_BYTE(IDE_SETFEATURE, IDE_COMMAND_REG);      // "SETFEATURE "
+       (void) wait_for_ready(drive);   // "wait "
+
+out:   
+       OUT_BYTE(old_select, IDE_SELECT_REG);   // restore to old "selected device"
+       restore_flags(flags);
+}
+
+static void ali15x3_dma2_enable(ide_drive_t *drive, unsigned long dma_base)
+{
+       byte unit = (drive->select.b.unit & 0x01);
+       byte bits = (drive->id->dma_mword | drive->id->dma_1word) & 0x07;
+       byte tmpbyte;
+       ide_hwif_t *hwif = HWIF(drive);
+       unsigned long flags;
+       int m5229_udma_setting_index = hwif->channel? 0x57 : 0x56;              
+       
+/*     if((((drive->id->dma_mword & 0x0007) << 8) !=
+          (drive->id->dma_mword & 0x0700)))*/
+               ali15x3_do_setfeature(drive, dma2_bits_to_command(bits));
+
+       // clear "ultra enable" bit
+       pci_read_config_byte(hwif->pci_dev, m5229_udma_setting_index, &tmpbyte);
+       if(unit)
+               tmpbyte &= 0x7f;
+       else
+               tmpbyte &= 0xf7;
+       save_flags(flags);
+       cli();
+       pci_write_config_byte(hwif->pci_dev, m5229_udma_setting_index, tmpbyte);
+       restore_flags(flags);
+       drive->id->dma_ultra = 0x00;
+
+       /* Enable DMA*/
+       outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+
+       printk(" ALI15X3: MultiWord DMA enabled\n");
+}
+
+static void ali15x3_udma_enable(ide_drive_t *drive, unsigned long dma_base)
+{      
+       byte unit = (drive->select.b.unit & 0x01);
+       byte bits = drive->id->dma_ultra & 0x1f;        
+       byte tmpbyte;
+       ide_hwif_t *hwif = HWIF(drive);
+       unsigned long flags;
+       unsigned char udma_mode = 0;
+       int m5229_udma_setting_index = hwif->channel? 0x57 : 0x56;
+
+       if(bits & 0x18) {       // 00011000, disk: ultra66
+               if(m5229_revision < 0xc2) {             // controller: ultra33
+                       bits = 0x04;    // 00000100, use ultra33, mode 2                        
+                       drive->id->dma_ultra &= ~0xFF00;
+                       drive->id->dma_ultra |= 0x0004;                 
+               }
+               else {  // controller: ultra66
+                       // Try to detect word93 bit13 and 80-pin cable (from host view)
+                       if( ! ( (drive->id->word93 & 0x2000) && cable_80_pin[hwif->channel] ) ) {       
+                               bits = 0x04;    // 00000100, use ultra33, mode 2
+                               drive->id->dma_ultra &= ~0xFF00;
+                               drive->id->dma_ultra |= 0x0004;
+                       }
+               }
+       }
+
+       // set feature only if we are not in that mode
+/*     if(((drive->id->dma_ultra & 0x001f) << 8) !=
+          (drive->id->dma_ultra & 0x1f00))*/
+               ali15x3_do_setfeature(drive, udma_mode = udma2_bits_to_command(bits));
+       udma_mode &= 0x0f;      // get UDMA mode
+
+       /* Enable DMA and UltraDMA */
+       outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+
+       // m5229 ultra
+       pci_read_config_byte(hwif->pci_dev, m5229_udma_setting_index, &tmpbyte);
+       
+       tmpbyte &= (0x0f << ( (1-unit) << 2) ); // clear bit0~3 or bit 4~7
+       // enable ultra dma and set timing
+       tmpbyte |= ( (0x08 | (4-udma_mode) ) << (unit << 2) );
+       // set to m5229
+       save_flags(flags);
+       cli();          
+       pci_write_config_byte(hwif->pci_dev, m5229_udma_setting_index, tmpbyte);
+       restore_flags(flags);
+
+       if(udma_mode >= 3) { // ultra 66
+               pci_read_config_byte(hwif->pci_dev, 0x4b, &tmpbyte);
+               tmpbyte |= 1;                   
+               save_flags(flags);
+               cli();
+               pci_write_config_byte(hwif->pci_dev, 0x4b, tmpbyte);            
+               restore_flags(flags);
+       }
+
+       printk(" ALI15X3: Ultra DMA enabled\n");
+}
+
+static int ali15x3_dma_onoff(ide_drive_t *drive, int enable)
+{
+       if(enable) {
+               ide_hwif_t *hwif = HWIF(drive);
+               unsigned long dma_base = hwif->dma_base;
+               struct hd_driveid *id = drive->id;
+                               
+               if((id->field_valid & 0x0004) && 
+                  (id->dma_ultra & 0x001f)) {
+                       // 1543C_E, in ultra mode, some WDC "harddisk" will cause "CRC" errors
+                       // (even if no CRC problem), so we try to use "DMA" here
+                       if( m5229_revision <= 0x20)
+                               ali15x3_dma2_enable(drive, dma_base);   /* Normal MultiWord DMA modes. */
+                       else if( (m5229_revision < 0xC2) && 
+                          ( (drive->media!=ide_disk) || (chip_is_1543c_e && strstr(id->model, "WDC ")) ) )
+                               ali15x3_dma2_enable(drive, dma_base);   /* Normal MultiWord DMA modes. */
+                       else    // >= 0xC2 or 0xC1 with no problem
+                               ali15x3_udma_enable(drive, dma_base);   /* UltraDMA modes. */
+               } else {
+                       ali15x3_dma2_enable(drive, dma_base);   /* Normal MultiWord DMA modes. */               
+               }
+       }
+
+       drive->using_dma = enable;      // on, off
+       return 0;
+}
+
+static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
+{
+       struct hd_driveid *id = drive->id;
+       ide_hwif_t *hwif = HWIF(drive);
+
+       if( (m5229_revision<=0x20) && (drive->media!=ide_disk) )
+               return hwif->dmaproc(ide_dma_off_quietly, drive);       
+
+       /* Even if the drive is not _currently_ in a DMA
+        * mode, we succeed, and we'll enable it manually
+        * below in alim15x3_dma_onoff */
+       if((id != NULL) && 
+          (id->capability & 1) &&      // dma supported
+          hwif->autodma ) {            
+               if(id->field_valid & 0x0004)    // word 88 is valid
+                       if(id->dma_ultra & 0x001F)      // 00011111 => ultra dma mode 0~4
+                               return hwif->dmaproc(ide_dma_on, drive);
+
+               if(id->field_valid & 0x0002)    // words 64~70 is valid
+                       if((id->dma_mword & 0x0007)     // word 63, multiword DMA mode 0~2
+                        || (id->dma_1word & 0x0007)) // word 62, single word DMA mode 0~2
+                               return hwif->dmaproc(ide_dma_on, drive);
+       }
+
+       return hwif->dmaproc(ide_dma_off_quietly, drive);
+}
+
+static int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+{
+       switch (func) {
+               case ide_dma_check:
+                       return ali15x3_config_drive_for_dma(drive);
+               case ide_dma_on:
+               case ide_dma_off:
+               case ide_dma_off_quietly:
+                       return ali15x3_dma_onoff(drive, (func == ide_dma_on));                                  
+               case ide_dma_write:
+                       if( (m5229_revision < 0xC2) && (drive->media != ide_disk) )
+                               return 1;       /* try PIO instead of DMA */
+                       break;
+               default:
+       }
+
+       return ide_dmaproc(func, drive);        // use standard DMA stuff
+}
+
+void __init ide_init_ali15x3 (ide_hwif_t *hwif)
+{      
+       unsigned long flags;
+       byte tmp_m5229_revision;
+
+       struct pci_dev *dev_m1533, *dev_m5229 = hwif->pci_dev;
+       byte ideic, inmir, tmpbyte;     
+       byte irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
+                                                                 1, 11, 0, 12, 0, 14, 0, 15 };
+
+       hwif->irq = hwif->channel ? 15 : 14;    
+
+       // look for ISA bridge m1533
+       for (dev_m1533=pci_devices; dev_m1533; dev_m1533=dev_m1533->next)
+               if(dev_m1533->vendor==PCI_VENDOR_ID_AL && 
+                  dev_m1533->device==PCI_DEVICE_ID_AL_M1533)
+                       break;  // we find it
+
+       pci_read_config_byte(dev_m1533, 0x58, &ideic);  // read IDE interface control
+       ideic = ideic & 0x03;   // bit0, bit1
+       
+       /* get IRQ for IDE Controller */
+       if ((hwif->channel && ideic == 0x03) || (!hwif->channel && !ideic)) { // get SIRQ1 routing table
+               pci_read_config_byte(dev_m1533, 0x44, &inmir);  
+               inmir = inmir & 0x0f;
+               hwif->irq = irq_routing_table[inmir];
+       }       
+       else if (hwif->channel && !(ideic & 0x01)) { // get SIRQ2 routing table
+               pci_read_config_byte(dev_m1533, 0x75, &inmir);
+               inmir = inmir & 0x0f;
+               hwif->irq = irq_routing_table[inmir];
+       }
+       
+       // read m5229 revision to a temp variable
+       pci_read_config_byte(dev_m5229, PCI_REVISION_ID, &tmp_m5229_revision);
+
+       if(m5229_revision == -1)        {       // only do it one time.
+               m5229_revision = 0;     // change the default to 0      
+               printk("\n************************************\n");
+               printk("*    ALi IDE driver (1.0 beta3)    *\n");
+               printk("*       Chip Revision is %02X        *\n", tmp_m5229_revision);
+               printk("*  Maximum capability is ");
+               if(tmp_m5229_revision >= 0xC2)
+                       printk("- UDMA 66 *\n");
+               else if(tmp_m5229_revision >= 0xC0)
+                       printk("- UDMA 33 *\n");
+               else if(tmp_m5229_revision == 0x20)
+                       printk("  -  DMA  *\n");
+               else
+                       printk("  -  PIO  *\n");
+               printk("************************************\n\n");     
+
+               // support CD-ROM DMA mode
+               pci_read_config_byte(dev_m5229, 0x53, &tmpbyte);
+               tmpbyte = (tmpbyte & (~0x02)) | 0x01;
+               save_flags(flags);
+               cli();          
+               pci_write_config_byte(dev_m5229, 0x53, tmpbyte);
+               restore_flags(flags);
+       }
+       
+       if ( (hwif->dma_base) && (tmp_m5229_revision>=0x20) ) {
+               
+#if defined(ALI_KERNEL_2_3_X)
+               if(tmp_m5229_revision>=0xC2)
+                       hwif->udma_four = 1;
+               else
+                       hwif->udma_four = 0;
+#endif
+               
+               if(m5229_revision == 0) {       // only do it one time
+                       m5229_revision = tmp_m5229_revision;    // keep it
+
+                       if(m5229_revision >= 0xC2) {    // 1543C-B?, 1535, 1535D, 1553
+                               // Note 1: not all "motherboard" support this detection
+                               // Note 2: if no udma 66 device, the detection may "error".
+                               //                 but in this case, we will not set the device to 
+                               //                 ultra 66, the detection result is not important
+                               save_flags(flags);
+                               cli();
+                               // enable "Cable Detection", m5229, 0x4b, bit3
+                               pci_read_config_byte(dev_m5229, 0x4b, &tmpbyte);
+                               pci_write_config_byte(dev_m5229, 0x4b, tmpbyte | 0x08);
+
+                               // set south-bridge's enable bit, m1533, 0x79
+                               pci_read_config_byte(dev_m1533, 0x79, &tmpbyte);
+                               if(m5229_revision==0xC2)                // 1543C-B0 (m1533, 0x79, bit 2)
+                                       pci_write_config_byte(dev_m1533, 0x79, tmpbyte | 0x04);
+                               else if (m5229_revision==0xC3)  // 1553/1535 (m1533, 0x79, bit 1)
+                                       pci_write_config_byte(dev_m1533, 0x79, tmpbyte | 0x02);
+                               restore_flags(flags);
+                                                               
+                               // Ultra66 cable detection (from Host View)
+                               // m5229, 0x4a, bit0: primary, bit1: secondary 80 pin
+                               pci_read_config_byte(dev_m5229, 0x4a, &tmpbyte);
+                               if(! (tmpbyte & 0x01))  // 0x4a, bit0 is 0 => 
+                                       cable_80_pin[0] = 1;    // primary channel has 80-pin (from host view)
+                               if(! (tmpbyte & 0x02))  // 0x4a, bit1 is 0 =>                           
+                                       cable_80_pin[1] = 1;    // secondary channel has 80-pin (from host view)                                        
+                       } else {
+                               // revision 0x20 (1543-E, 1543-F)
+                               // revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E)
+                               // clear CD-ROM DMA write bit, m5229, 0x4b, bit 7
+                               pci_read_config_byte(dev_m5229, 0x4b, &tmpbyte);
+                               save_flags(flags);
+                               cli();
+                               pci_write_config_byte(dev_m5229, 0x4b, tmpbyte & 0x7F); // clear bit 7
+                               restore_flags(flags);
+
+                               // check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
+                               pci_read_config_byte(dev_m1533, 0x5e, &tmpbyte);
+                               chip_is_1543c_e = ( (tmpbyte & 0x1e) == 0x12 ) ? 1: 0;
+                       }                       
+               }
+               
+               // M1543 or newer for DMAing
+               hwif->dmaproc = &ali15x3_dmaproc;
+               hwif->autodma = 1;
+       } else {
+               // if both channel use PIO, then chip revision is not important.
+               // we should't assign m5229_revision here (assign it will affect
+               // the chip detection procedure above --- if(! m5229_revision)
+               hwif->autodma = 0;                      
+               hwif->drives[0].autotune = 1;
+               hwif->drives[1].autotune = 1;
+       }
+       
+#if defined(ALI_KERNEL_2_3_X) 
+       hwif->tuneproc = &ali15x3_tune_drive;
+#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
+       bmide_dev = hwif->pci_dev;
+       ali_display_info = &ali_get_info;
+#endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */  
+#endif  /* defined(ALI_KERNEL_2_3_X) */        
+       
+       return;
+}
\ No newline at end of file
index a55bdecfa0136eb944e579359cc29e4400b86d9e..11bb76a4bf1696de61f9cd5238665053a6bb552d 100644 (file)
@@ -433,6 +433,12 @@ __initfunc(unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, c
                        request_region(dma_base+16, extra, name);
                dma_base += hwif->channel ? 8 : 0;
                hwif->dma_extra = extra;
+               
+               /* ====== ALI M5229 ================================*/
+               if( hwif->pci_dev->device == PCI_DEVICE_ID_AL_M5229)
+                       outb(inb(dma_base+2) & 0x60, dma_base+2);           
+               /* =================================================*/
+               
                if (inb(dma_base+2) & 0x80) {
                        printk("%s: simplex device:  DMA disabled\n", name);
                        dma_base = 0;
index 3f3a64bf657d0e1ae747363b91d12320193883b8..d9104b2dd0ed6c7fa88890fac6b66e55cbae3c5a 100644 (file)
@@ -30,6 +30,7 @@
 #define DEVID_PIIX3    ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82371SB_1})
 #define DEVID_PIIX4    ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82371AB})
 #define DEVID_VP_IDE   ((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C586_1})
+#define DEVID_VP_OLDIDE        ((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C586_0})
 #define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246})
 #define DEVID_RZ1000   ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_RZ1000})
 #define DEVID_RZ1001   ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_RZ1001})
@@ -39,6 +40,7 @@
 #define DEVID_OPTI621  ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI,    PCI_DEVICE_ID_OPTI_82C621})
 #define DEVID_OPTI621V ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI,    PCI_DEVICE_ID_OPTI_82C558})
 #define DEVID_OPTI621X ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI,    0xd568})  /* from datasheets */
+#define DEVID_ALI15X3   ((ide_pci_devid_t){PCI_VENDOR_ID_AL,      PCI_DEVICE_ID_AL_M5229})
 #define DEVID_TRM290   ((ide_pci_devid_t){PCI_VENDOR_ID_TEKRAM,  PCI_DEVICE_ID_TEKRAM_DC290})
 #define DEVID_NS87410  ((ide_pci_devid_t){PCI_VENDOR_ID_NS,      PCI_DEVICE_ID_NS_87410})
 #define DEVID_NS87415  ((ide_pci_devid_t){PCI_VENDOR_ID_NS,      PCI_DEVICE_ID_NS_87415})
 
 #define IDE_IGNORE     ((void *)-1)
 
+#ifdef CONFIG_BLK_DEV_ALI15X3
+extern void ide_init_ali15x3(ide_hwif_t *);
+#define INIT_ALI15X3  &ide_init_ali15x3
+#else
+#define INIT_ALI15X3  NULL
+#endif
+
 #ifdef CONFIG_BLK_DEV_TRM290
 extern void ide_init_trm290(ide_hwif_t *);
 #define INIT_TRM290    &ide_init_trm290
@@ -145,6 +154,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
        {DEVID_HT6565,  "HT6565",       NULL,           {{0x00,0x00,0x00}, {0x00,0x00,0x00}},   ON_BOARD,       0 },
        {DEVID_OPTI621, "OPTI621",      INIT_OPTI621,   {{0x45,0x80,0x00}, {0x40,0x08,0x00}},   ON_BOARD,       0 },
        {DEVID_OPTI621X,"OPTI621X",     INIT_OPTI621,   {{0x45,0x80,0x00}, {0x40,0x08,0x00}},   ON_BOARD,       0 },
+       {DEVID_ALI15X3, "ALI15X3",  INIT_ALI15X3,   {{0x00,0x00,0x00}, {0x00,0x00,0x00}},   ON_BOARD,   0 },
        {DEVID_TRM290,  "TRM290",       INIT_TRM290,    {{0x00,0x00,0x00}, {0x00,0x00,0x00}},   ON_BOARD,       0 },
        {DEVID_NS87415, "NS87415",      INIT_NS87415,   {{0x00,0x00,0x00}, {0x00,0x00,0x00}},   ON_BOARD,       0 },
        {DEVID_AEC6210, "AEC6210",      NULL,           {{0x00,0x00,0x00}, {0x00,0x00,0x00}},   OFF_BOARD,      0 },
@@ -454,6 +464,19 @@ __initfunc(void ide_scan_pcibus (void))
                        autodma_default = 0;
                        break;
                }
+               /*
+                *      Don't try and tune a VIA 82C586 or 586A
+                */
+               if (IDE_PCI_DEVID_RQ(devid, DEVID_VP_IDE))
+               {
+                       autodma_default = 0;
+                       break;
+               }
+               if (IDE_PCI_DEVID_RQ(devid, DEVID_VP_OLDIDE))
+               {
+                       autodma_default = 0;
+                       break;
+               }
        }
 #endif
 
index ec9012fadbea74c1649858fb7df530659dccc3f8..a142c4c45a5bddec96f6520d5dd0f174cc75eef3 100644 (file)
@@ -106,6 +106,7 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
          bool '       Fan Tachometer' CONFIG_WDT_501_FAN
      fi
   fi
+  tristate '   WDT PCI Watchdog timer' CONFIG_WDTPCI
   tristate '   Software Watchdog' CONFIG_SOFT_WATCHDOG
   tristate '   Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
   tristate '   Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
@@ -120,6 +121,9 @@ bool 'Enhanced Real Time Clock Support' CONFIG_RTC
 if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then
   bool 'Tadpole ANA H8 Support'  CONFIG_H8
 fi
+if [ "$CONFIG_PCI" = "y" ]; then
+  tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG
+fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    tristate '/dev/agpgart (AGP Support) (EXPERIMENTAL)' CONFIG_AGP n
index 8f8dd82862c9bbc211ddd4a7e45a2c2f62562ab7..74ed3ede2e46259d113197f48cb21b2c2855a5f4 100644 (file)
@@ -350,6 +350,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_WDTPCI),y)
+O_OBJS += wdt_pci.o
+else
+  ifeq ($(CONFIG_WDTPCI),m)
+    M_OBJS += wdt_pci.o
+  endif
+endif
+
 ifeq ($(CONFIG_RTC),y)
 O_OBJS += rtc.o
 endif
@@ -376,6 +384,14 @@ else
   MOD_SUB_DIRS += agp
   endif
 endif
+
+ifeq ($(CONFIG_INTEL_RNG),y)
+L_OBJS += i810_rng.o
+else
+  ifeq ($(CONFIG_INTEL_RNG),m)
+  M_OBJS += i810_rng.o
+  endif
+endif
     
 ifeq ($(CONFIG_VIDEO_DEV),y)
 OX_OBJS += videodev.o
index d672cf70dc5bb71fc0900d63f1a620ff2997d39f..2adc7a9d250686c6d4821b99527580f9073c118b 100644 (file)
@@ -23,7 +23,6 @@
  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
-#define EXPORT_SYMTAB 1
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
@@ -790,6 +789,8 @@ void agp_enable(u32 mode)
 
 /* End - Generic Agp routines */
 
+#ifdef CONFIG_AGP_I810
+
 static aper_size_info_fixed intel_i810_sizes[] =
 {
        {64, 16384, 4},
@@ -950,11 +951,13 @@ static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
 {
        int i;
 
+       CACHE_FLUSH();
        for (i = pg_start; i < (mem->page_count + pg_start); i++) {
                OUTREG32(intel_i810_private.registers,
                         I810_PTE_BASE + (i * 4),
                         agp_bridge.scratch_page);
        }
+       CACHE_FLUSH();
 
        agp_bridge.tlb_flush(mem);
        return 0;
@@ -1062,6 +1065,7 @@ static int __init intel_i810_setup(struct pci_dev *i810_dev)
        return 0;
 }
 
+#endif /* CONFIG_AGP_I810 */
 
 #ifdef CONFIG_AGP_INTEL
 
@@ -2197,7 +2201,7 @@ static int __init agp_find_supported_device(void)
        agp_bridge.dev = dev;
 
        /* Need to test for I810 here */
-
+#ifdef CONFIG_AGP_I810
        if (dev->vendor == PCI_VENDOR_ID_INTEL) {
                struct pci_dev *i810_dev;
 
@@ -2271,7 +2275,7 @@ static int __init agp_find_supported_device(void)
                        break;
                }
        }
-
+#endif /* CONFIG_AGP_I810 */
 
        /* find capndx */
        pci_read_config_dword(dev, 0x04, &scratch);
diff --git a/drivers/char/i810_rng.c b/drivers/char/i810_rng.c
new file mode 100644 (file)
index 0000000..5116fcd
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+
+       Hardware driver for Intel i810 Random Number Generator (RNG)
+       Copyright 2000 Jeff Garzik <jgarzik@mandrakesoft.com>
+
+       Driver Web site:  http://gtf.org/garzik/drivers/i810_rng/
+
+
+
+       Based on:
+       Intel 82802AB/82802AC Firmware Hub (FWH) Datasheet
+               May 1999 Order Number: 290658-002 R
+
+       Intel 82802 Firmware Hub: Random Number Generator
+       Programmer's Reference Manual
+               December 1999 Order Number: 298029-001 R
+
+       Intel 82802 Firmware HUB Random Number Generator Driver
+       Copyright (c) 2000 Matt Sottek <msottek@quiknet.com>
+
+       Special thanks to Matt Sottek.  I did the "guts", he
+       did the "brains" and all the testing.  (Anybody wanna send
+       me an i810 or i820?)
+
+       ----------------------------------------------------------
+
+       This software may be used and distributed according to the terms
+        of the GNU Public License, incorporated herein by reference.
+
+       ----------------------------------------------------------
+
+       From the firmware hub datasheet:
+
+       The Firmware Hub integrates a Random Number Generator (RNG)
+       using thermal noise generated from inherently random quantum
+       mechanical properties of silicon. When not generating new random
+       bits the RNG circuitry will enter a low power state. Intel will
+       provide a binary software driver to give third party software
+       access to our RNG for use as a security feature. At this time,
+       the RNG is only to be used with a system in an OS-present state.
+
+       ----------------------------------------------------------
+
+       Theory of operation:
+
+       Character driver.  Using the standard open()
+       and read() system calls, you can read random data from
+       the i810 RNG device.  This data is NOT CHECKED by any
+       fitness tests, and could potentially be bogus (if the
+       hardware is faulty or has been tampered with).
+
+       /dev/intel_rng is char device major 10, minor 183.
+
+
+       ----------------------------------------------------------
+
+       Driver notes:
+
+       * In order to unload the i810_rng module, you must first
+       make sure all users of the character device have closed
+
+       * FIXME:  Currently only one open() of the character device is allowed.
+       If another user tries to open() the device, they will get an
+       -EBUSY error.  Instead, this really should either support
+       multiple simultaneous users of the character device (not hard),
+       or simply block open() until the current user of the chrdev
+       calls close().
+
+       * FIXME: support poll()
+
+       * FIXME: should we be crazy and support mmap()?
+
+       ----------------------------------------------------------
+
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/spinlock.h>
+#include <linux/random.h>
+#include <linux/sysctl.h>
+#include <linux/miscdevice.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+
+/*
+ * core module and version information
+ */
+#define RNG_VERSION "0.6.2-2.2.x"
+#define RNG_MODULE_NAME "i810_rng"
+#define RNG_DRIVER_NAME   RNG_MODULE_NAME " hardware driver " RNG_VERSION
+#define PFX RNG_MODULE_NAME ": "
+
+
+/*
+ * debugging macros
+ */
+#undef RNG_DEBUG /* define to 1 to enable copious debugging info */
+
+#ifdef RNG_DEBUG
+/* note: prints function name for you */
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define RNG_NDEBUG 0        /* define to 1 to disable lightweight runtime checks */
+#if RNG_NDEBUG
+#define assert(expr)
+#else
+#define assert(expr) \
+        if(!(expr)) {                                   \
+        printk( "Assertion failed! %s,%s,%s,line=%d\n", \
+        #expr,__FILE__,__FUNCTION__,__LINE__);          \
+        }
+#endif
+
+
+/*
+ * misc helper macros
+ */
+#define arraysize(x)            (sizeof(x)/sizeof(*(x)))
+
+
+/*
+ * RNG registers (offsets from rng_mem)
+ */
+#define RNG_HW_STATUS                  0
+#define                RNG_PRESENT             0x40
+#define                RNG_ENABLED             0x01
+#define RNG_STATUS                     1
+#define                RNG_DATA_PRESENT        0x01
+#define RNG_DATA                       2
+
+#define RNG_ADDR                       0xFFBC015F
+#define RNG_ADDR_LEN                   3
+
+#define RNG_MISCDEV_MINOR              183 /* official */
+
+
+/*
+ * various RNG status variables.  they are globals
+ * as we only support a single RNG device
+ */
+static int rng_allocated;              /* is someone using the RNG region? */
+static int rng_hw_enabled;             /* is the RNG h/w enabled? */
+static int rng_use_count;              /* number of times RNG has been enabled */
+static void *rng_mem;                  /* token to our ioremap'd RNG register area */
+static spinlock_t rng_lock = SPIN_LOCK_UNLOCKED; /* hardware lock */
+static int rng_open;                   /* boolean, 0 (false) if chrdev is closed, 1 (true) if open */
+
+/*
+ * inlined helper functions for accessing RNG registers
+ */
+static inline u8 rng_hwstatus (void)
+{
+       assert (rng_mem != NULL);
+       return readb (rng_mem + RNG_HW_STATUS);
+}
+
+
+static inline void rng_hwstatus_set (u8 hw_status)
+{
+       assert (rng_mem != NULL);
+       writeb (hw_status, rng_mem + RNG_HW_STATUS);
+}
+
+
+static inline int rng_data_present (void)
+{
+       assert (rng_mem != NULL);
+       assert (rng_hw_enabled == 1);
+
+       return (readb (rng_mem + RNG_STATUS) & RNG_DATA_PRESENT) ? 1 : 0;
+}
+
+
+static inline int rng_data_read (void)
+{
+       assert (rng_mem != NULL);
+       assert (rng_hw_enabled == 1);
+
+       return readb (rng_mem + RNG_DATA);
+}
+
+
+/*
+ * rng_enable - enable or disable the RNG hardware
+ */
+static int rng_enable (int enable)
+{
+       int rc = 0;
+       u8 hw_status;
+
+       DPRINTK ("ENTER\n");
+
+       spin_lock (&rng_lock);
+
+       hw_status = rng_hwstatus ();
+
+       if (enable) {
+               rng_hw_enabled = 1;
+               rng_use_count++;
+               MOD_INC_USE_COUNT;
+       } else {
+               rng_use_count--;
+               if (rng_use_count == 0)
+                       rng_hw_enabled = 0;
+               MOD_DEC_USE_COUNT;
+       }
+
+       if (rng_hw_enabled && ((hw_status & RNG_ENABLED) == 0)) {
+               rng_hwstatus_set (hw_status | RNG_ENABLED);
+               printk (KERN_INFO PFX "RNG h/w enabled\n");
+       }
+
+       else if (!rng_hw_enabled && (hw_status & RNG_ENABLED)) {
+               rng_hwstatus_set (hw_status & ~RNG_ENABLED);
+               printk (KERN_INFO PFX "RNG h/w disabled\n");
+       }
+
+       spin_unlock (&rng_lock);
+
+       if ((!!enable) != (!!(rng_hwstatus () & RNG_ENABLED))) {
+               printk (KERN_ERR PFX "Unable to %sable the RNG\n",
+                       enable ? "en" : "dis");
+               rc = -EIO;
+       }
+
+       DPRINTK ("EXIT, returning %d\n", rc);
+       return rc;
+}
+
+
+static int rng_dev_open (struct inode *inode, struct file *filp)
+{
+       int rc = -EINVAL;
+
+       MOD_INC_USE_COUNT;
+
+       if ((filp->f_mode & FMODE_READ) == 0)
+               goto err_out;
+       if (filp->f_mode & FMODE_WRITE)
+               goto err_out;
+
+       spin_lock (&rng_lock);
+
+       /* only allow one open of this device, exit with -EBUSY if already open */
+       /* FIXME: we should sleep on a semaphore here, unless O_NONBLOCK */
+       if (rng_open) {
+               spin_unlock (&rng_lock);
+               rc = -EBUSY;
+               goto err_out;
+       }
+
+       rng_open = 1;
+
+       spin_unlock (&rng_lock);
+
+       if (rng_enable(1) != 0) {
+               spin_lock (&rng_lock);
+               rng_open = 0;
+               spin_unlock (&rng_lock);
+               rc = -EIO;
+               goto err_out;
+       }
+
+       return 0;
+
+err_out:
+       MOD_DEC_USE_COUNT;
+       return rc;
+}
+
+
+static int rng_dev_release (struct inode *inode, struct file *filp)
+{
+
+       if (rng_enable(0) != 0)
+               return -EIO;
+
+       spin_lock (&rng_lock);
+       rng_open = 0;
+       spin_unlock (&rng_lock);
+
+       MOD_DEC_USE_COUNT;
+       return 0;
+}
+
+
+static ssize_t rng_dev_read (struct file *filp, char * buf, size_t size,
+                            loff_t *offp)
+{
+       int have_data, copied = 0;
+       u8 data=0;
+       u8 *page;
+
+       if (size < 1)
+               return 0;
+
+       page = (unsigned char *) get_free_page (GFP_KERNEL);
+       if (!page)
+               return -ENOMEM;
+
+read_loop:
+       /* using the fact that read() can return >0 but
+        * less than the requested amount, we simply
+        * read up to PAGE_SIZE or buffer size, whichever
+        * is smaller, and return that data.
+        */
+       if ((copied == size) || (copied == PAGE_SIZE)) {
+               size_t tmpsize = (copied == size) ? size : PAGE_SIZE;
+               int rc = copy_to_user (buf, page, tmpsize);
+               free_page ((long)page);
+               if (rc) return rc;
+               return tmpsize;
+       }
+
+       spin_lock (&rng_lock);
+
+       have_data = 0;
+       if (rng_data_present ()) {
+               data = rng_data_read ();
+               have_data = 1;
+       }
+
+       spin_unlock (&rng_lock);
+
+       if (have_data) {
+               page[copied] = data;
+               copied++;
+       } else {
+               if (filp->f_flags & O_NONBLOCK) {
+                       free_page ((long)page);
+                       return -EAGAIN;
+               }
+       }
+
+       if (current->need_resched)
+               schedule ();
+
+       if (signal_pending (current)) {
+               free_page ((long)page);
+               return -ERESTARTSYS;
+       }
+
+       goto read_loop;
+}
+
+
+/*
+ * rng_init_one - look for and attempt to init a single RNG
+ */
+static int __init rng_init_one (struct pci_dev *dev)
+{
+       int rc;
+       u8 hw_status;
+
+       DPRINTK ("ENTER\n");
+
+       if (rng_allocated) {
+               printk (KERN_ERR PFX "this driver only supports one RNG\n");
+               DPRINTK ("EXIT, returning -EBUSY\n");
+               return -EBUSY;
+       }
+
+       rng_mem = ioremap (RNG_ADDR, RNG_ADDR_LEN);
+       if (rng_mem == NULL) {
+               printk (KERN_ERR PFX "cannot ioremap RNG Memory\n");
+               DPRINTK ("EXIT, returning -EBUSY\n");
+               rc = -EBUSY;
+               goto err_out;
+       }
+
+       /* Check for Intel 82802 */
+       hw_status = rng_hwstatus ();
+       if ((hw_status & RNG_PRESENT) == 0) {
+               printk (KERN_ERR PFX "RNG not detected\n");
+               DPRINTK ("EXIT, returning -ENODEV\n");
+               rc = -ENODEV;
+               goto err_out;
+       }
+
+       rng_allocated = 1;
+
+       rc = rng_enable (0);
+       if (rc) {
+               printk (KERN_ERR PFX "cannot disable RNG, aborting\n");
+               goto err_out;
+       }
+
+       DPRINTK ("EXIT, returning 0\n");
+       return 0;
+
+err_out:
+       if (rng_mem)
+               iounmap (rng_mem);
+       return rc;
+}
+
+
+/*
+ * Data for PCI driver interface
+ */
+
+MODULE_AUTHOR("Jeff Garzik, Matt Sottek");
+MODULE_DESCRIPTION("Intel i8xx chipset Random Number Generator (RNG) driver");
+
+
+static struct file_operations rng_chrdev_ops = {
+       open:           rng_dev_open,
+       release:        rng_dev_release,
+       read:           rng_dev_read,
+};
+
+
+static struct miscdevice rng_miscdev = {
+       RNG_MISCDEV_MINOR,
+       RNG_MODULE_NAME,
+       &rng_chrdev_ops,
+};
+
+
+/*
+ * rng_init - initialize RNG module
+ */
+int __init rng_init (void)
+{
+       int rc;
+       struct pci_dev *pdev;
+       
+       pdev = pci_find_device (0x8086, 0x2418, NULL);
+       if (!pdev)
+               pdev = pci_find_device (0x8086, 0x2428, NULL);
+       if (!pdev)
+               return -ENODEV;
+
+       DPRINTK ("ENTER\n");
+
+       rc = rng_init_one(pdev);
+       if (rc) {
+               DPRINTK ("EXIT, returning -ENODEV\n");
+               return rc;
+       }
+
+       rc = misc_register (&rng_miscdev);
+       if (rc) {
+               if (rng_mem)
+                       iounmap (rng_mem);
+               DPRINTK ("EXIT, returning %d\n", rc);
+               return rc;
+       }
+
+       printk (KERN_INFO RNG_DRIVER_NAME " loaded\n");
+
+       DPRINTK ("EXIT, returning 0\n");
+       return 0;
+}
+
+#ifdef MODULE
+
+int init_module (void) { return rng_init (); }
+
+/*
+ * rng_init - shutdown RNG module
+ */
+void cleanup_module (void)
+{
+       DPRINTK ("ENTER\n");
+       
+       iounmap (rng_mem);
+
+       rng_hwstatus_set (rng_hwstatus() & ~RNG_ENABLED);
+
+       misc_deregister (&rng_miscdev);
+
+       DPRINTK ("EXIT\n");
+}
+
+#endif /* MODULE */
index 4d45be5062ef818ebdb1d396ff11d232c27f1e58..c776f6fd5aee352d99b9f0d3c73ba53892561d2f 100644 (file)
@@ -43,9 +43,6 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/init.h>
-#ifdef CONFIG_APM
-#include <linux/apm_bios.h>
-#endif
 
 #include <linux/tty.h>
 #include <linux/selection.h>
@@ -87,6 +84,7 @@ extern void hfmodem_init(void);
 extern int pc110pad_init(void);
 extern int pmu_device_init(void);
 extern int tosh_init(void);
+extern int rng_init(void);
 
 static int misc_read_proc(char *buf, char **start, off_t offset,
                          int len, int *eof, void *private)
@@ -241,9 +239,6 @@ int __init misc_init(void)
 #ifdef CONFIG_DTLK
        dtlk_init();
 #endif
-#ifdef CONFIG_APM
-       apm_init();
-#endif
 #ifdef CONFIG_H8
        h8_init();
 #endif
@@ -280,6 +275,9 @@ int __init misc_init(void)
 #ifdef CONFIG_SGI
        streamable_init ();
 #endif
+#ifdef CONFIG_INTEL_RNG
+       rng_init ();
+#endif
 #ifdef CONFIG_TOSHIBA
        tosh_init();
 #endif
index 1c14027b3d5ecb119f6f00ba814d1b39e55138cf..9a1538591fecb654cc290558623e5374cbd09b5b 100644 (file)
@@ -85,7 +85,7 @@ static int saa7111_write(struct saa7111 *dev, unsigned char subaddr, unsigned ch
 
 static int saa7111_write_block(struct saa7111 *dev, unsigned const char *data, unsigned int len)
 {
-       int ack;
+       int ack = 0;
        unsigned subaddr;
        unsigned long flags;
 
index c42b29c37ed8d9b05cd52c2908a1356a18c7413f..7f62a6046fece7ca4498e7cf7811d77d3969bcd5 100644 (file)
@@ -85,7 +85,7 @@ static int saa7185_write(struct saa7185 *dev, unsigned char subaddr, unsigned ch
 
 static int saa7185_write_block(struct saa7185 *dev, unsigned const char *data, unsigned int len)
 {
-       int ack;
+       int ack=0;
        unsigned subaddr;
        unsigned long flags;
 
index 81971da6b4f2a82659a4670e5235b7a5519b6546..47c74844338e8bc57722b3dc3f15cedd52cb7832 100644 (file)
 #define WDT_COUNT1             (io+1)
 #define WDT_COUNT2             (io+2)
 #define WDT_CR                 (io+3)
-#define WDT_SR                 (io+4)
-#define WDT_RT                 (io+5)
-#define WDT_UNUSED             (io+6)
+#define WDT_SR                 (io+4)          /* Buzzer start PCI */
+#define WDT_RT                 (io+5)          /* Buzzer stop PCI */
+#define WDT_BUZZER             (io+6)          /* PCI only */
 #define WDT_DC                 (io+7)
 
+/* The following are only on the PCI card, they're outside of I/O space on
+ * the ISA card: */
+#define WDT_CLOCK              (io+12) /* COUNT2: rd=16.67MHz, wr=2.0833MHz */
+/* inverted opto isolated reset output: */
+#define WDT_OPTONOTRST         (io+13) /* wr=enable, rd=disable */
+/* opto isolated reset output: */
+#define WDT_OPTORST            (io+14) /* wr=enable, rd=disable */
+/* programmable outputs: */
+#define WDT_PROGOUT            (io+15) /* wr=enable, rd=disable */
+
 #define WDC_SR_WCCR            1       /* Active low */
 #define WDC_SR_TGOOD           2
 #define WDC_SR_ISOI0           4
@@ -39,6 +49,8 @@
 #define WDC_SR_PSUUNDR         64      /* Active low */
 #define WDC_SR_IRQ             128     /* Active low */
 
+#ifndef WDT_IS_PCI
+
 /*
  *     Feature Map 1 is the active high inputs not supported on your card.
  *     Feature Map 2 is the active low inputs not supported on your card.
 #define WDT_OPTION_MASK                (WDIOF_OVERHEAT)
 #endif
 
+#else
+
+#define FEATUREMAP1            (WDC_SR_TGOOD|WDC_SR_FANGOOD)
+#define FEATUREMAP2            (WDC_SR_PSUOVER|WDC_SR_PSUUNDR)
+#define WDT_OPTION_MASK                (WDIOF_OVERHEAT)
+#endif
+
 #ifndef FEATUREMAP1
 #error "Config option not set"
 #endif
diff --git a/drivers/char/wdt_pci.c b/drivers/char/wdt_pci.c
new file mode 100644 (file)
index 0000000..b02bbbe
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ *     Industrial Computer Source WDT500/501 driver for Linux 2.1.x
+ *
+ *     (c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *                             http://www.redhat.com
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ *     
+ *     Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
+ *     warranty for any of this software. This material is provided 
+ *     "AS-IS" and at no charge.       
+ *
+ *     (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ *     Release 0.08.
+ *
+ *     Fixes
+ *             Dave Gregorich  :       Modularisation and minor bugs
+ *             Alan Cox        :       Added the watchdog ioctl() stuff
+ *             Alan Cox        :       Fixed the reboot problem (as noted by
+ *                                     Matt Crocker).
+ *             Alan Cox        :       Added wdt= boot option
+ *             Alan Cox        :       Cleaned up copy/user stuff
+ *             Tim Hockin      :       Added insmod parameters, comment cleanup
+ *                                     Parameterized timeout
+ *             JP Nollmann     :       Added support for PCI wdt501p
+ *             Alan Cox        :       Split ISA and PCI cards into two drivers
+ *             Jeff Garzik     :       PCI cleanups
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#define WDT_IS_PCI
+#include "wd501p.h"
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/kcomp.h>
+#include <linux/pci.h>
+
+#define PFX "wdt_pci: "
+
+/*
+ * Until Access I/O gets their application for a PCI vendor ID approved,
+ * I don't think that it's appropriate to move these constants into the
+ * regular pci_ids.h file. -- JPN 2000/01/18
+ */
+
+#ifndef PCI_VENDOR_ID_ACCESSIO
+#define PCI_VENDOR_ID_ACCESSIO 0x494f
+#endif
+#ifndef PCI_DEVICE_ID_WDG_CSM
+#define PCI_DEVICE_ID_WDG_CSM 0x22c0
+#endif
+
+static int wdt_is_open=0;
+
+/*
+ *     You must set these - there is no sane way to probe for this board.
+ *     You can use wdt=x,y to set these now.
+ */
+static int io=0x240;
+static int irq=11;
+
+#define WD_TIMO (100*60)               /* 1 minute */
+
+#ifndef MODULE
+
+/**
+ *     wdtpci_setup:
+ *     @str: command line string
+ *
+ *     Setup options. The board isn't really probe-able so we have to
+ *     get the user to tell us the configuration. Sane people build it 
+ *     modular but the others come here.
+ */
+static int __init wdtpci_setup(char *str)
+{
+       int ints[4];
+
+       str = get_options (str, ARRAY_SIZE(ints), ints);
+
+       if (ints[0] > 0)
+       {
+               io = ints[1];
+               if(ints[0] > 1)
+                       irq = ints[2];
+       }
+
+       return 1;
+}
+
+__setup("wdt=", wdtpci_setup);
+
+#endif /* !MODULE */
+/*
+ *     Programming support
+ */
+static void wdtpci_ctr_mode(int ctr, int mode)
+{
+       ctr<<=6;
+       ctr|=0x30;
+       ctr|=(mode<<1);
+       outb_p(ctr, WDT_CR);
+}
+
+static void wdtpci_ctr_load(int ctr, int val)
+{
+       outb_p(val&0xFF, WDT_COUNT0+ctr);
+       outb_p(val>>8, WDT_COUNT0+ctr);
+}
+
+/*
+ *     Kernel methods.
+ */
+/**
+ *     wdtpci_status:
+ *     
+ *     Extract the status information from a WDT watchdog device. There are
+ *     several board variants so we have to know which bits are valid. Some
+ *     bits default to one and some to zero in order to be maximally painful.
+ *
+ *     we then map the bits onto the status ioctl flags.
+ */
+static int wdtpci_status(void)
+{
+       /*
+        *      Status register to bit flags
+        */
+        
+       int flag=0;
+       unsigned char status=inb_p(WDT_SR);
+       status|=FEATUREMAP1;
+       status&=~FEATUREMAP2;   
+       
+       if(!(status&WDC_SR_TGOOD))
+               flag|=WDIOF_OVERHEAT;
+       if(!(status&WDC_SR_PSUOVER))
+               flag|=WDIOF_POWEROVER;
+       if(!(status&WDC_SR_PSUUNDR))
+               flag|=WDIOF_POWERUNDER;
+       if(!(status&WDC_SR_FANGOOD))
+               flag|=WDIOF_FANFAULT;
+       if(status&WDC_SR_ISOI0)
+               flag|=WDIOF_EXTERN1;
+       if(status&WDC_SR_ISII1)
+               flag|=WDIOF_EXTERN2;
+       return flag;
+}
+
+/**
+ *     wdtpci_interrupt:
+ *     @irq:           Interrupt number
+ *     @dev_id:        Unused as we don't allow multiple devices.
+ *     @regs:          Unused.
+ *
+ *     Handle an interrupt from the board. These are raised when the status
+ *     map changes in what the board considers an interesting way. That means
+ *     a failure condition occuring.
+ */
+static void wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       /*
+        *      Read the status register see what is up and
+        *      then printk it. 
+        */
+        
+       unsigned char status=inb_p(WDT_SR);
+       
+       status|=FEATUREMAP1;
+       status&=~FEATUREMAP2;   
+       
+       printk(KERN_CRIT "WDT status %d\n", status);
+       
+       if(!(status&WDC_SR_TGOOD))
+               printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT));
+       if(!(status&WDC_SR_PSUOVER))
+               printk(KERN_CRIT "PSU over voltage.\n");
+       if(!(status&WDC_SR_PSUUNDR))
+               printk(KERN_CRIT "PSU under voltage.\n");
+       if(!(status&WDC_SR_FANGOOD))
+               printk(KERN_CRIT "Possible fan fault.\n");
+       if(!(status&WDC_SR_WCCR))
+#ifdef SOFTWARE_REBOOT
+#ifdef ONLY_TESTING
+               printk(KERN_CRIT "Would Reboot.\n");
+#else          
+               printk(KERN_CRIT "Initiating system reboot.\n");
+               machine_restart(NULL);
+#endif         
+#else
+               printk(KERN_CRIT "Reset in 5ms.\n");
+#endif         
+}
+
+
+static long long wdtpci_llseek(struct file *file, long long offset, int origin)
+{
+       return -ESPIPE;
+}
+
+/**
+ *     wdtpci_ping:
+ *
+ *     Reload counter one with the watchdog timeout. We don't bother reloading
+ *     the cascade counter. 
+ */
+static void wdtpci_ping(void)
+{
+       /* Write a watchdog value */
+       inb_p(WDT_DC);
+       wdtpci_ctr_mode(1,2);
+       wdtpci_ctr_load(1,WD_TIMO);             /* Timeout */
+       outb_p(0, WDT_DC);
+}
+
+/**
+ *     wdtpci_write:
+ *     @file: file handle to the watchdog
+ *     @buf: buffer to write (unused as data does not matter here 
+ *     @count: count of bytes
+ *     @ppos: pointer to the position to write. No seeks allowed
+ *
+ *     A write to a watchdog device is defined as a keepalive signal. Any
+ *     write of data will do, as we we don't define content meaning.
+ */
+static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+       /*  Can't seek (pwrite) on this device  */
+       if (ppos != &file->f_pos)
+               return -ESPIPE;
+
+       if(count)
+       {
+               wdtpci_ping();
+               return 1;
+       }
+       return 0;
+}
+
+/**
+ *     wdtpci_read:
+ *     @file: file handle to the watchdog board
+ *     @buf: buffer to write 1 byte into
+ *     @count: length of buffer
+ *     @ptr: offset (no seek allowed)
+ *
+ *     Read reports the temperature in degrees Fahrenheit. The API is in
+ *     farenheit. It was designed by an imperial measurement luddite.
+ */
+static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *ptr)
+{
+       unsigned short c=inb_p(WDT_RT);
+       unsigned char cp;
+       
+       /*  Can't seek (pread) on this device  */
+       if (ptr != &file->f_pos)
+               return -ESPIPE;
+
+       switch(MINOR(file->f_dentry->d_inode->i_rdev))
+       {
+               case TEMP_MINOR:
+                       c*=11;
+                       c/=15;
+                       cp=c+7;
+                       if(copy_to_user(buf,&cp,1))
+                               return -EFAULT;
+                       return 1;
+               default:
+                       return -EINVAL;
+       }
+}
+
+/**
+ *     wdtpci_ioctl:
+ *     @inode: inode of the device
+ *     @file: file handle to the device
+ *     @cmd: watchdog command
+ *     @arg: argument pointer
+ *
+ *     The watchdog API defines a common set of functions for all watchdogs
+ *     according to their available features. We only actually usefully support
+ *     querying capabilities and current status. 
+ */
+static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+       unsigned long arg)
+{
+       static struct watchdog_info ident=
+       {
+               WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER
+                       |WDIOF_EXTERN1|WDIOF_EXTERN2|WDIOF_FANFAULT,
+               1,
+               "WDT500/501PCI"
+       };
+       
+       ident.options&=WDT_OPTION_MASK; /* Mask down to the card we have */
+       switch(cmd)
+       {
+               default:
+                       return -ENOIOCTLCMD;
+               case WDIOC_GETSUPPORT:
+                       return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+
+               case WDIOC_GETSTATUS:
+                       return put_user(wdtpci_status(),(int *)arg);
+               case WDIOC_GETBOOTSTATUS:
+                       return put_user(0, (int *)arg);
+               case WDIOC_KEEPALIVE:
+                       wdtpci_ping();
+                       return 0;
+       }
+}
+
+/**
+ *     wdtpci_open:
+ *     @inode: inode of device
+ *     @file: file handle to device
+ *
+ *     One of our two misc devices has been opened. The watchdog device is
+ *     single open and on opening we load the counters. Counter zero is a 
+ *     100Hz cascade, into counter 1 which downcounts to reboot. When the
+ *     counter triggers counter 2 downcounts the length of the reset pulse
+ *     which set set to be as long as possible. 
+ */
+static int wdtpci_open(struct inode *inode, struct file *file)
+{
+       switch(MINOR(inode->i_rdev))
+       {
+               case WATCHDOG_MINOR:
+                       if(wdt_is_open)
+                               return -EBUSY;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT        
+                       MOD_INC_USE_COUNT;
+#endif
+                       /*
+                        *      Activate 
+                        */
+        
+                       wdt_is_open=1;
+
+                       inb_p(WDT_DC);          /* Disable */
+
+                       /*
+                        * "pet" the watchdog, as Access says.
+                        * This resets the clock outputs.
+                        */
+                               
+                       wdtpci_ctr_mode(2,0);
+                       outb_p(0, WDT_DC);
+
+                       inb_p(WDT_DC);
+
+                       outb_p(0, WDT_CLOCK);   /* 2.0833MHz clock */
+                       inb_p(WDT_BUZZER);      /* disable */
+                       inb_p(WDT_OPTONOTRST);  /* disable */
+                       inb_p(WDT_OPTORST);     /* disable */
+                       inb_p(WDT_PROGOUT);     /* disable */
+                       wdtpci_ctr_mode(0,3);
+                       wdtpci_ctr_mode(1,2);
+                       wdtpci_ctr_mode(2,1);
+                       wdtpci_ctr_load(0,20833);       /* count at 100Hz */
+                       wdtpci_ctr_load(1,WD_TIMO);/* Timeout 60 seconds */
+                       /* DO NOT LOAD CTR2 on PCI card! -- JPN */
+                       outb_p(0, WDT_DC);      /* Enable */
+                       return 0;
+               case TEMP_MINOR:
+                       return 0;
+               default:
+                       return -ENODEV;
+       }
+}
+
+/**
+ *     wdtpci_close:
+ *     @inode: inode to board
+ *     @file: file handle to board
+ *
+ *     The watchdog has a configurable API. There is a religious dispute 
+ *     between people who want their watchdog to be able to shut down and 
+ *     those who want to be sure if the watchdog manager dies the machine
+ *     reboots. In the former case we disable the counters, in the latter
+ *     case you have to open it again very soon.
+ */
+static int wdtpci_release(struct inode *inode, struct file *file)
+{
+       if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
+       {
+               lock_kernel();
+#ifndef CONFIG_WATCHDOG_NOWAYOUT       
+               inb_p(WDT_DC);          /* Disable counters */
+               wdtpci_ctr_load(2,0);   /* 0 length reset pulses now */
+#endif         
+               wdt_is_open=0;
+               unlock_kernel();
+       }
+       return 0;
+}
+
+/**
+ *     notify_sys:
+ *     @this: our notifier block
+ *     @code: the event being reported
+ *     @unused: unused
+ *
+ *     Our notifier is called on system shutdowns. We want to turn the card
+ *     off at reboot otherwise the machine will reboot again during memory
+ *     test or worse yet during the following fsck. This would suck, in fact
+ *     trust me - if it happens it does suck.
+ */
+
+static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
+       void *unused)
+{
+       if(code==SYS_DOWN || code==SYS_HALT)
+       {
+               /* Turn the card off */
+               inb_p(WDT_DC);
+               wdtpci_ctr_load(2,0);
+       }
+       return NOTIFY_DONE;
+}
+/*
+ *     Kernel Interfaces
+ */
+static struct file_operations wdtpci_fops = {
+       llseek:         wdtpci_llseek,
+       read:           wdtpci_read,
+       write:          wdtpci_write,
+       ioctl:          wdtpci_ioctl,
+       open:           wdtpci_open,
+       release:        wdtpci_release,
+};
+
+static struct miscdevice wdtpci_miscdev=
+{
+       WATCHDOG_MINOR,
+       "watchdog",
+       &wdtpci_fops
+};
+
+#ifdef CONFIG_WDT_501
+static struct miscdevice temp_miscdev=
+{
+       TEMP_MINOR,
+       "temperature",
+       &wdtpci_fops
+};
+#endif
+
+/*
+ *     The WDT card needs to learn about soft shutdowns in order to
+ *     turn the timebomb registers off. 
+ */
+static struct notifier_block wdtpci_notifier=
+{
+       wdtpci_notify_sys,
+       NULL,
+       0
+};
+
+
+static int __init wdtpci_init_one (struct pci_dev *dev)
+{
+       static int dev_count = 0;
+
+       dev_count++;
+       if (dev_count > 1) {
+               printk (KERN_ERR PFX
+                       "this driver only supports 1 device\n");
+               return -ENODEV;
+       }
+
+       irq = dev->irq;
+       io = dev->base_address[2]&PCI_BASE_ADDRESS_IO_MASK;
+       
+       printk ("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X "
+               "(Interrupt %d)\n", io, irq);
+
+       request_region (io, 16, "wdt-pci");
+       if (request_irq (irq, wdtpci_interrupt, SA_INTERRUPT | SA_SHIRQ,
+                        "wdt-pci", &wdtpci_miscdev)) {
+               printk (KERN_ERR PFX "IRQ %d is not free.\n", irq);
+               goto err_out_free_res;
+       }
+
+       misc_register (&wdtpci_miscdev);
+
+#ifdef CONFIG_WDT_501
+       misc_register (&temp_miscdev);
+#endif
+
+       register_reboot_notifier (&wdtpci_notifier);
+
+       return 0;
+
+err_out_free_res:
+       release_region (io, 16);
+}
+
+
+static void __exit wdtpci_remove_one (struct pci_dev *pdev)
+{
+       /* here we assume only one device will ever have
+        * been picked up and registered by probe function */
+       unregister_reboot_notifier(&wdtpci_notifier);
+#ifdef CONFIG_WDT_501_PCI
+       misc_deregister(&temp_miscdev);
+#endif 
+       misc_deregister(&wdtpci_miscdev);
+       free_irq(irq, &wdtpci_miscdev);
+       release_region(io, 16);
+}
+
+/**
+ *     wdtpci_cleanup:
+ *
+ *     Unload the watchdog. You cannot do this with any file handles open.
+ *     If your watchdog is set to continue ticking on close and you unload
+ *     it, well it keeps ticking. We won't get the interrupt but the board
+ *     will not touch PC memory so all is fine. You just have to load a new
+ *     module in 60 seconds or reboot.
+ */
+
+static struct pci_dev *wdt_dev;
+static void __exit wdtpci_cleanup(void)
+{
+       if(wdt_dev)
+               wdtpci_remove_one(wdt_dev);
+       wdt_dev = NULL;
+}
+
+
+/**
+ *     wdtpci_init:
+ *
+ *     Set up the WDT watchdog board. All we have to do is grab the
+ *     resources we require and bitch if anyone beat us to them.
+ *     The open() function will actually kick the board off.
+ */
+static int __init wdtpci_init(void)
+{
+       wdt_dev=pci_find_device(PCI_VENDOR_ID_ACCESSIO, PCI_DEVICE_ID_WDG_CSM, NULL);
+       if (wdt_dev ==NULL)
+               return -ENODEV;
+       if(wdtpci_init_one(wdt_dev)<0)
+       {
+               wdt_dev=NULL;
+               return -ENODEV;
+       }
+       return 0;
+}
+
+
+module_init(wdtpci_init);
+module_exit(wdtpci_cleanup);
index 3008ecfd8d9a4b385a4b13663be5f1010fb9cea0..33fdc308d3e7f35f37bcaecacbc15fb9560126ef 100644 (file)
@@ -1761,6 +1761,7 @@ __initfunc(int
                        printk(KERN_WARNING "HFC-PCI: No PCI card found\n");
                        return (0);
                }
+#ifdef notdef
                if (((int) cs->hw.hfcpci.pci_io & (PAGE_SIZE - 1))) {
                        printk(KERN_WARNING "HFC-PCI shared mem address will be corrected\n");
                        pcibios_write_config_word(cs->hw.hfcpci.pci_bus,
@@ -1794,6 +1795,7 @@ __initfunc(int
                        }
                        dev_hfcpci->base_address[1] = (int) cs->hw.hfcpci.pci_io;
                }
+#endif
                if (!cs->hw.hfcpci.pci_io) {
                        printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
                        return (0);
index 34edf220005ab4c69f4aca775ccbfc0155039b2d..e3a8ae2ffc87277705d66923cdbbea9352ba58c8 100644 (file)
@@ -129,15 +129,15 @@ static const char *invalid_pcb_msg =
 #define INVALID_PCB_MSG(len) \
        printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
 
-static const char *search_msg = "%s: Looking for 3c505 adapter at address %#x...";
+static char *search_msg __initdata = "%s: Looking for 3c505 adapter at address %#x...";
 
-static const char *stilllooking_msg = "still looking...";
+static char *stilllooking_msg __initdata = "still looking...";
 
-static const char *found_msg = "found.\n";
+static char *found_msg __initdata = "found.\n";
 
-static const char *notfound_msg = "not found (reason = %d)\n";
+static char *notfound_msg __initdata = "not found (reason = %d)\n";
 
-static const char *couldnot_msg = "%s: 3c505 not found\n";
+static char *couldnot_msg __initdata = "%s: 3c505 not found\n";
 
 /*********************************************************
  *
@@ -179,7 +179,7 @@ static const int elp_debug = 0;
  * Last element MUST BE 0!
  *****************************************************************/
 
-static const int addr_list[] __initdata = {0x300, 0x280, 0x310, 0};
+static int addr_list[] __initdata = {0x300, 0x280, 0x310, 0};
 
 /* Dma Memory related stuff */
 
index 9ccb9e9f5e892f4fd2a3ae149475399c090a8e5c..ae0325212e3e26b0cc07fe62fe23e2b74fe87318 100644 (file)
@@ -64,6 +64,7 @@ static int max_interrupt_work = 10;
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>       /* for udelay() */
+#include <linux/init.h>
 
 #include <asm/spinlock.h>
 #include <asm/bitops.h>
@@ -156,7 +157,7 @@ struct el3_mca_adapters_struct {
        int id;
 };
 
-struct el3_mca_adapters_struct el3_mca_adapters[] = {
+static struct el3_mca_adapters_struct el3_mca_adapters[] __initdata = {
        { "3Com 3c529 EtherLink III (10base2)", 0x627c },
        { "3Com 3c529 EtherLink III (10baseT)", 0x627d },
        { "3Com 3c529 EtherLink III (test mode)", 0x62db },
@@ -166,7 +167,7 @@ struct el3_mca_adapters_struct el3_mca_adapters[] = {
 };
 #endif
 
-int el3_probe(struct device *dev)
+int __init el3_probe(struct device *dev)
 {
        short lrs_state = 0xff, i;
        int ioaddr, irq, if_port;
@@ -396,7 +397,7 @@ int el3_probe(struct device *dev)
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
  */
-static ushort read_eeprom(int ioaddr, int index)
+static ushort __init read_eeprom(int ioaddr, int index)
 {
        outw(EEPROM_READ + index, ioaddr + 10);
        /* Pause for at least 162 us. for the read to take place. */
@@ -405,7 +406,7 @@ static ushort read_eeprom(int ioaddr, int index)
 }
 
 /* Read a word from the EEPROM when in the ISA ID probe state. */
-static ushort id_read_eeprom(int index)
+static ushort __init id_read_eeprom(int index)
 {
        int bit, word = 0;
 
index 85452646d95fbb350aa4f24365f7ac84dba43c5d..5b7306d0169b758e07af1962cee0c41edafd2b38 100644 (file)
@@ -62,6 +62,7 @@ static int max_interrupt_work = 20;
 
 #define NEW_MULTICAST
 #include <linux/delay.h>
+#include <linux/init.h>
 
 /* Kernel version compatibility functions. */
 #define RUN_AT(x) (jiffies + (x))
@@ -399,7 +400,7 @@ init_module(void)
 }
 
 #else
-int tc515_probe(struct device *dev)
+int __init tc515_probe(struct device *dev)
 {
        int cards_found = 0;
 
@@ -412,7 +413,7 @@ int tc515_probe(struct device *dev)
 }
 #endif  /* not MODULE */
 
-static int vortex_scan(struct device *dev)
+static int __init vortex_scan(struct device *dev)
 {
        int cards_found = 0;
        static int ioaddr = 0x100;
@@ -452,7 +453,7 @@ static int vortex_scan(struct device *dev)
        return cards_found;
 }
 
-static struct device *vortex_found_device(struct device *dev, int ioaddr,
+static struct device * __init vortex_found_device(struct device *dev, int ioaddr,
                                                                                  int irq, int product_index,
                                                                                  int options)
 {
@@ -517,7 +518,7 @@ static struct device *vortex_found_device(struct device *dev, int ioaddr,
        return dev;
 }
 
-static int vortex_probe1(struct device *dev)
+static int __init vortex_probe1(struct device *dev)
 {
        int ioaddr = dev->base_addr;
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
index cbf2aade6d7658ae7631bc2a80fd0b97c63a265d..6feeccf89d4bfbacdd31c65cb170b55e77420f8a 100644 (file)
@@ -124,7 +124,7 @@ struct mca_adapters_t {
        char            *name;
 };
 
-const struct mca_adapters_t mc32_adapters[] = {
+static struct mca_adapters_t mc32_adapters[] __initdata = {
        { 0x0041, "3COM EtherLink MC/32" },
        { 0x8EF5, "IBM High Performance Lan Adapter" },
        { 0x0000, NULL }
index 6ceafdd1ddf3acf59a2a2e5364841b817c3d1491..a3f784f10aeaa60226fb1c049db49455189c8d5f 100644 (file)
@@ -720,7 +720,7 @@ int __init ace_module_init(void)
        return status;
 }
 
-
+#ifdef MODULE
 #if (LINUX_VERSION_CODE < 0x02032a)
 int init_module(void)
 {
@@ -736,7 +736,7 @@ void cleanup_module(void)
 module_init(ace_module_init);
 module_exit(ace_module_cleanup);
 #endif
-
+#endif
 
 static void ace_free_descriptors(struct net_device *dev)
 {
index 3fabee261bab55069efc751ad6cc36d27baf6c81..485b5125057f13153d162f28f10dddbee745926a 100644 (file)
@@ -110,16 +110,16 @@ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.o
 #define NESM_STOP_PG   0x80    /* Last page +1 of RX ring */
 
 /* From the .ADF file: */
-static unsigned int addresses[7]=
+static unsigned int addresses[7] __initdata =
                {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0};
-static int irqs[4] = {3, 4, 5, 9};
+static int irqs[4] __initdata = {3, 4, 5, 9};
 
 struct ne2_adapters_t {
        unsigned int    id;
        char            *name;
 };
 
-const struct ne2_adapters_t ne2_adapters[] = {
+static struct ne2_adapters_t ne2_adapters[] __initdata = {
        { 0x6354, "Arco Ethernet Adapter AE/2" },
        { 0x70DE, "Compex ENET-16 MC/P" },
        { 0x7154, "Novell Ethernet Adapter NE/2" },
index 4140350cd855e966210352894636d5084888958d..21014e150d76fdc23229eeb96825abb68c9b9600 100644 (file)
@@ -126,6 +126,7 @@ static int csr0 = 0x00A00000 | 0x4800;
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -320,7 +321,7 @@ struct pci_id_info {
                                                         long ioaddr, int irq, int chip_idx, int fnd_cnt);
 };
 #ifndef CARDBUS
-static struct pci_id_info pci_tbl[] = {
+static struct pci_id_info pci_tbl[] __initdata = {
   { "Digital DC21040 Tulip",
        0x1011, 0x0002, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 },
   { "Digital DC21041 Tulip",
@@ -571,7 +572,7 @@ static void set_rx_mode(struct device *dev);
 static struct device *root_tulip_dev = NULL;
 
 #ifndef CARDBUS
-int tulip_probe(struct device *dev)
+int __init tulip_probe(struct device *dev)
 {
        int cards_found = 0;
        int pci_index = 0;
index f7f42ba344bf19237b20af130ec4b608fa385293..6c0e485774b39b7330bad394113234f154c74bd5 100644 (file)
@@ -77,6 +77,7 @@ static const int multicast_filter_limit = 32;
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -261,7 +262,7 @@ static struct device *via_probe1(int pci_bus, int pci_devfn,
                                                                 struct device *dev, long ioaddr, int irq,
                                                                 int chp_idx, int fnd_cnt);
 
-static struct pci_id_info pci_tbl[] = {
+static struct pci_id_info pci_tbl[] __initdata = {
        { "VIA VT86C100A Rhine-II", 0x1106, 0x6100, 0xffff,
          PCI_USES_MEM|PCI_USES_IO|PCI_USES_MEM|PCI_USES_MASTER, 128, via_probe1},
        { "VIA VT3043 Rhine", 0x1106, 0x3043, 0xffff,
@@ -275,7 +276,7 @@ enum chip_capability_flags {CanHaveMII=1, };
 struct chip_info {
        int io_size;
        int flags;
-} static cap_tbl[] = {
+} static cap_tbl[] __initdata = {
        {128, CanHaveMII, },
        {128, CanHaveMII, },
 };
@@ -398,7 +399,7 @@ static struct device *root_net_dev = NULL;
    well when dynamically adding drivers.  So instead we detect just the
    cards we know about in slot order. */
 
-static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[])
+static int __init pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[])
 {
        int cards_found = 0;
        int pci_index = 0;
@@ -506,7 +507,7 @@ static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[])
 }
 
 #ifndef MODULE
-int via_rhine_probe(struct device *dev)
+int __init via_rhine_probe(struct device *dev)
 {
        static int did_version = 0;
        if (!did_version++)
@@ -515,7 +516,7 @@ int via_rhine_probe(struct device *dev)
 }
 #endif
 
-static struct device *via_probe1(int pci_bus, int pci_devfn,
+static struct device * __init via_probe1(int pci_bus, int pci_devfn,
                                                                 struct device *dev, long ioaddr, int irq,
                                                                 int chip_id, int card_idx)
 {
index 8537cf9bbf0e0fb22b638adeea1d1600ab46bda4..6584afb3cd3f2b02aea056ab209728a44a9215e7 100644 (file)
@@ -2,7 +2,7 @@ This file contains brief information about the SCSI tape driver.
 The driver is currently maintained by Kai M{kisara (email
 Kai.Makisara@metla.fi)
 
-Last modified: Sun Apr 18 13:24:43 1999 by makisara@home
+Last modified: Tue Aug 15 15:54:46 2000 by makisara@kai.makisara.local
 
 
 BASICS
@@ -67,7 +67,7 @@ non-rewind devices (minor is 128 + device number) are implemented.
 In variable block mode, the byte count in write() determines the size
 of the physical block on tape. When reading, the drive reads the next
 tape block and returns to the user the data if the read() byte count
-is at least the block size. Otherwise the data is truncated.
+is at least the block size. Otherwise an error is returned.
 
 In fixed block mode, the data transfer between the drive and the
 driver is in multiples of the block size. The write() byte count must
index 0fd98ebb77d426ab6de539507a0496601c336439..e02dcbd28517fdda154d58ebf9ad6e441c0d103d 100644 (file)
@@ -11,7 +11,7 @@
   Copyright 1992 - 2000 Kai Makisara
                 email Kai.Makisara@metla.fi
 
-  Last modified: Sat Jun 17 17:29:35 2000 by makisara@kai.makisara.local
+  Last modified: Tue Sep  5 23:17:08 2000 by makisara@kai.makisara.local
   Some small formal changes - aeb, 950809
 */
 
@@ -1459,8 +1459,11 @@ read_tape(struct inode *inode, long count, Scsi_Cmnd **aSCpnt)
 
                if (SCpnt->sense_buffer[2] & 0x20) { /* ILI */
                    if (STp->block_size == 0) {
-                       if (transfer <= 0)
-                           transfer = 0;
+                       if (transfer < 0) {
+                           if (STps->drv_block >= 0)
+                               STps->drv_block += 1;
+                           return (-ENOMEM);
+                       }
                        (STp->buffer)->buffer_bytes = bytes - transfer;
                    }
                    else {
@@ -2932,6 +2935,8 @@ st_ioctl(struct inode * inode,struct file * file,
           i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
               mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
               mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
+              mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
+              mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
               mtc.mt_op == MTCOMPRESSION;
        }
        i = flush_buffer(inode, file, i);
@@ -3099,6 +3104,51 @@ st_ioctl(struct inode * inode,struct file * file,
 }
 
 \f
+/* The following two functions are nearly identical to scsi_init_malloc and
+   scsi_init_free. The only difference is that the GFP_DMA flag is not set
+   by default. */
+static void * st_malloc(unsigned int size, int gfp_mask)
+{
+    void * retval;
+
+    /*
+     * For buffers used by the DMA pool, we assume page aligned 
+     * structures.
+     */
+    if ((size % PAGE_SIZE) == 0) {
+       int order, a_size;
+       for (order = 0, a_size = PAGE_SIZE;
+             a_size < size; order++, a_size <<= 1)
+            ;
+       retval = (void *) __get_free_pages(gfp_mask, order);
+    } else
+       retval = kmalloc(size, gfp_mask);
+
+    if (retval)
+       memset(retval, 0, size);
+    return retval;
+}
+
+
+static void st_free(char * ptr, unsigned int size)
+{
+    /*
+     * We need this special code here because the DMA pool assumes
+     * page aligned data.  Besides, it is wasteful to allocate
+     * page sized chunks with kmalloc.
+     */
+    if ((size % PAGE_SIZE) == 0) {
+       int order, a_size;
+
+       for (order = 0, a_size = PAGE_SIZE;
+            a_size < size; order++, a_size <<= 1)
+           ;
+       free_pages((unsigned long)ptr, order);
+    } else
+       kfree(ptr);
+}
+
+
 /* Try to allocate a new tape buffer */
        static ST_buffer *
 new_tape_buffer( int from_initialization, int need_dma )
@@ -3115,7 +3165,7 @@ new_tape_buffer( int from_initialization, int need_dma )
     priority = GFP_KERNEL;
 
   i = sizeof(ST_buffer) + (st_max_sg_segs - 1) * sizeof(struct scatterlist);
-  tb = (ST_buffer *)scsi_init_malloc(i, priority);
+  tb = (ST_buffer *)st_malloc(i, priority);
   if (tb) {
     tb->this_size = i;
     if (need_dma)
@@ -3128,7 +3178,7 @@ new_tape_buffer( int from_initialization, int need_dma )
        b_size /= 2;
     for ( ; b_size >= PAGE_SIZE; b_size /= 2) {
        tb->sg[0].address =
-           (unsigned char *)scsi_init_malloc(b_size, priority);
+           (unsigned char *)st_malloc(b_size, priority);
        if (tb->sg[0].address != NULL) {
            tb->sg[0].alt_address = NULL;
            tb->sg[0].length = b_size;
@@ -3136,7 +3186,7 @@ new_tape_buffer( int from_initialization, int need_dma )
        }
     }
     if (tb->sg[segs].address == NULL) {
-       scsi_init_free((char *)tb, tb->this_size);
+       st_free((char *)tb, tb->this_size);
        tb = NULL;
     }
     else {  /* Got something, continue */
@@ -3148,7 +3198,7 @@ new_tape_buffer( int from_initialization, int need_dma )
        for (segs=1, got=tb->sg[0].length;
             got < st_buffer_size && segs < ST_FIRST_SG; ) {
            tb->sg[segs].address =
-               (unsigned char *)scsi_init_malloc(b_size, priority);
+               (unsigned char *)st_malloc(b_size, priority);
            if (tb->sg[segs].address == NULL) {
                if (st_buffer_size - got <=
                    (ST_FIRST_SG - segs) * b_size / 2) {
@@ -3156,8 +3206,8 @@ new_tape_buffer( int from_initialization, int need_dma )
                    continue;
                }
                for (i=0; i < segs - 1; i++)
-                   scsi_init_free(tb->sg[i].address, tb->sg[i].length);
-               scsi_init_free((char *)tb, tb->this_size);
+                   st_free(tb->sg[i].address, tb->sg[i].length);
+               st_free((char *)tb, tb->this_size);
                tb = NULL;
                break;
            }
@@ -3220,7 +3270,7 @@ enlarge_buffer(ST_buffer *STbuffer, int new_size, int need_dma)
   for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size;
        segs < max_segs && got < new_size; ) {
       STbuffer->sg[segs].address =
-         (unsigned char *)scsi_init_malloc(b_size, priority);
+         (unsigned char *)st_malloc(b_size, priority);
       if (STbuffer->sg[segs].address == NULL) {
          if (new_size - got <= (max_segs - segs) * b_size / 2) {
              b_size /= 2;  /* Large enough for the rest of the buffers */
@@ -3256,7 +3306,7 @@ normalize_buffer(ST_buffer *STbuffer)
   int i;
 
   for (i=STbuffer->orig_sg_segs; i < STbuffer->sg_segs; i++) {
-      scsi_init_free(STbuffer->sg[i].address, STbuffer->sg[i].length);
+      st_free(STbuffer->sg[i].address, STbuffer->sg[i].length);
       STbuffer->buffer_size -= STbuffer->sg[i].length;
   }
 #if DEBUG
@@ -3489,7 +3539,7 @@ static int st_init()
   if (st_template.dev_max > 128 / ST_NBR_MODES)
     printk(KERN_INFO "st: Only %d tapes accessible.\n", 128 / ST_NBR_MODES);
   scsi_tapes =
-    (Scsi_Tape *) scsi_init_malloc(st_template.dev_max * sizeof(Scsi_Tape),
+    (Scsi_Tape *) st_malloc(st_template.dev_max * sizeof(Scsi_Tape),
                                   GFP_ATOMIC);
   if (scsi_tapes == NULL) {
     printk(KERN_ERR "Unable to allocate descriptors for SCSI tapes.\n");
@@ -3506,7 +3556,7 @@ static int st_init()
   for (i=0; i < st_template.dev_max; ++i) {
     STp = &(scsi_tapes[i]);
     STp->capacity = 0xfffff;
-    STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget),
+    STp->mt_status = (struct mtget *) st_malloc(sizeof(struct mtget),
                                                       GFP_ATOMIC);
     /* Initialize status */
     memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
@@ -3514,12 +3564,12 @@ static int st_init()
 
   /* Allocate the buffers */
   st_buffers =
-    (ST_buffer **) scsi_init_malloc(st_template.dev_max * sizeof(ST_buffer *),
+    (ST_buffer **) st_malloc(st_template.dev_max * sizeof(ST_buffer *),
                                    GFP_ATOMIC);
   if (st_buffers == NULL) {
     printk(KERN_ERR "Unable to allocate tape buffer pointers.\n");
     unregister_chrdev(SCSI_TAPE_MAJOR, "st");
-    scsi_init_free((char *) scsi_tapes,
+    st_free((char *) scsi_tapes,
                   st_template.dev_max * sizeof(Scsi_Tape));
     return 1;
   }
@@ -3532,6 +3582,8 @@ static int st_init()
     target_nbr = ST_EXTRA_DEVS;
   if (target_nbr > st_max_buffers)
     target_nbr = st_max_buffers;
+  if (target_nbr > st_template.dev_noticed)
+    target_nbr = st_template.dev_noticed;
 
   for (i=st_nbr_buffers=0; i < target_nbr; i++) {
     if (!new_tape_buffer(TRUE, TRUE)) {
@@ -3539,9 +3591,9 @@ static int st_init()
 #if 0
        printk(KERN_ERR "Can't continue without at least one tape buffer.\n");
        unregister_chrdev(SCSI_TAPE_MAJOR, "st");
-       scsi_init_free((char *) st_buffers,
+       st_free((char *) st_buffers,
                       st_template.dev_max * sizeof(ST_buffer *));
-       scsi_init_free((char *) scsi_tapes,
+       st_free((char *) scsi_tapes,
                       st_template.dev_max * sizeof(Scsi_Tape));
        return 1;
 #else
@@ -3608,19 +3660,19 @@ void cleanup_module( void)
   unregister_chrdev(SCSI_TAPE_MAJOR, "st");
   st_registered--;
   if(scsi_tapes != NULL) {
-    scsi_init_free((char *) scsi_tapes,
+    st_free((char *) scsi_tapes,
                   st_template.dev_max * sizeof(Scsi_Tape));
 
     if (st_buffers != NULL) {
       for (i=0; i < st_nbr_buffers; i++)
        if (st_buffers[i] != NULL) {
          for (j=0; j < st_buffers[i]->sg_segs; j++)
-             scsi_init_free((char *) st_buffers[i]->sg[j].address,
+             st_free((char *) st_buffers[i]->sg[j].address,
                             st_buffers[i]->sg[j].length);
-         scsi_init_free((char *) st_buffers[i], st_buffers[i]->this_size);
+         st_free((char *) st_buffers[i], st_buffers[i]->this_size);
        }
 
-      scsi_init_free((char *) st_buffers,
+      st_free((char *) st_buffers,
                     st_template.dev_max * sizeof(ST_buffer *));
     }
   }
index 29bd0af5be5e64532bdba96c03cb69945b8aa623..6f3485b6526526cb613c7e14018c7150a18cd17a 100644 (file)
@@ -373,7 +373,9 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SPEED:
                DPF(2, "SNDCTL_DSP_SPEED:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
+
                DPD(2, "val is %d\n", val);
 
                if (val > 0) {
@@ -427,7 +429,9 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_STEREO:
                DPF(2, "SNDCTL_DSP_STEREO:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
+
                DPD(2, " val is %d\n", val);
 
                if (file->f_mode & FMODE_READ) {
@@ -472,7 +476,9 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_CHANNELS:
                DPF(2, "SNDCTL_DSP_CHANNELS:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
+
                DPD(2, " val is %d\n", val);
 
                if (val > 0) {
@@ -534,7 +540,9 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
                DPF(2, "SNDCTL_DSP_SETFMT:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
+
                DPD(2, " val is %d\n", val);
 
                if (val != AFMT_QUERY) {
@@ -636,7 +644,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SETTRIGGER:
                DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
 
                if (file->f_mode & FMODE_WRITE) {
                        spin_lock_irqsave(&woinst->lock, flags);
@@ -862,7 +871,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SETFRAGMENT:
                DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
 
                DPD(2, "val is 0x%x\n", val);
 
index 23c74f8649cb708048d6db77926cd95d6ee9e183..3da387aaa2cd11a99a21cf775c4dac796a88ebd6 100644 (file)
 #define __devexit
 #define __devexitdata
 
-/* Not sure what version aliases were introduced in, but certainly in 2.91.66.  */
-#ifdef MODULE
-  #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
-    #define module_init(x)      int init_module(void) __attribute__((alias(#x)));
-    #define module_exit(x)      void cleanup_module(void) __attribute__((alias(#x)));
-  #else
-    #define module_init(x)      int init_module(void) { return x(); }
-    #define module_exit(x)      void cleanup_module(void) { x(); }
-  #endif
-#else
-  #define module_init(x)
-  #define module_exit(x)
-#endif
-
 #define MODULE_DEVICE_TABLE(foo,bar)
 
 #define pci_dma_supported(dev, mask) 1
@@ -110,7 +96,7 @@ pci_alloc_consistent(struct pci_dev *hwdev,
 
         if (hwdev == NULL)
                 gfp |= GFP_DMA;
-        ret = (void *)__get_free_pages(gfp, compat_get_order(size));
+        ret = (void *)__get_free_pages(gfp, get_order(size));
 
         if (ret != NULL) {
                 memset(ret, 0, size);
@@ -123,7 +109,7 @@ extern __inline__ void
 pci_free_consistent(struct pci_dev *hwdev, size_t size,
                     void *vaddr, dma_addr_t dma_handle)
 {
-        free_pages((unsigned long)vaddr, compat_get_order(size));
+        free_pages((unsigned long)vaddr, get_order(size));
 }
 
 static inline int pci_module_init(struct pci_driver *drv)
index d4b15d8a5e7d267d784b0b6b07921fb809d7b632..9385e53c0f6c65296e3bf908f2b18f064674c35b 100644 (file)
@@ -121,14 +121,14 @@ static void __devinit audio_init(struct emu10k1_card *card)
 
        /* stereo voice */
        card->waveout.send_a[1] = 0x00;
-        card->waveout.send_b[1] = 0xff;
-        card->waveout.send_c[1] = 0x00;
+        card->waveout.send_b[1] = 0x00;
+        card->waveout.send_c[1] = 0xff;
         card->waveout.send_d[1] = 0x00;
         card->waveout.send_routing[1] = 0xd01c;
 
        card->waveout.send_a[2] = 0x00;
-        card->waveout.send_b[2] = 0x00;
-        card->waveout.send_c[2] = 0xff;
+        card->waveout.send_b[2] = 0xff;
+        card->waveout.send_c[2] = 0x00;
         card->waveout.send_d[2] = 0x00;
         card->waveout.send_routing[2] = 0xd01c;
 
index 6d1a97bd4eb71d0378f43c3a9025f92a288baa07..5f9726f27595d08b34c68f7ce20d88a1f57ed800 100644 (file)
@@ -1038,7 +1038,9 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
                if (card->isaps)
                        return -EINVAL;
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
+
                i = hweight32(val);
                if (i == 0)
                        return 0;       /* val = mixer_recmask(s); */
@@ -1062,7 +1064,9 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
 
                if (i >= SOUND_MIXER_NRDEVICES)
                        return -EINVAL;
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
+
                if (emu10k1_mixer_wrch(card, i, val))
                        return -EINVAL;
 
index 0f2386b1c56519a1ef40af6b733cc9d6fc24ce29..7ff22383144ada44014916796f9bc98004c4d3ab 100644 (file)
@@ -524,7 +524,7 @@ static void frobindir(struct sv_state *s, unsigned char idx, unsigned char mask,
 static unsigned setpll(struct sv_state *s, unsigned char reg, unsigned rate)
 {
        unsigned long flags;
-       unsigned char r, m, n;
+       unsigned char r=0, m=0, n=0;
        unsigned xm, xn, xr, xd, metric = ~0U;
        /* the warnings about m and n used uninitialized are bogus and may safely be ignored */
 
index 9a18559dc688a6935bc206834111bab1ea14d080..270efc5ac2447fcdaccb098b3475e205fa68fd31 100644 (file)
@@ -88,6 +88,8 @@ extern int cs_probe(void);
 #ifdef CONFIG_SOUND_EMU10K1
 extern int init_emu10k1(void);
 #endif
+extern int cs4281_probe(void);
+
 
 /*
  *     Low level list operator. Scan the ordered list, find a hole and
index 2c6486c41d38092cf6280c26d980d87d54b0763c..752a85a7282a224e05d941e323b1d90fdb7f4598 100644 (file)
@@ -455,7 +455,7 @@ static int get_pixel_mac(struct display *p, int pixel_x, int pixel_y)
   u8 *dest, bit;
   u16 *dest16;
   u32 *dest32;
-  u8 pixel;
+  u8 pixel = 0x5a;
 
   switch (p->var.bits_per_pixel) {
   case 1:
index ed91c5532c75b0193a6e530cfd8e6dcc76e22e32..b15ec9e3b4792225e8d64a30b9a972b952cbd827 100644 (file)
@@ -92,7 +92,10 @@ if [ "$CONFIG_INET" = "y" ]; then
   fi
   tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS
   if [ "$CONFIG_SMB_FS" != "n" ]; then
-     string 'Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE ""
+     bool '   Use a default NLS' CONFIG_SMB_NLS_DEFAULT
+     if [ "$CONFIG_SMB_NLS_DEFAULT" = "y" ]; then
+        string '  Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE "cp437"
+     fi
   fi   
 fi
 if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then
index a886c68cee483c833fc6798fc1433f7c520dcd24..a1ed40dcf1bf37a10289b17f4ef1e9a0f0f57ef7 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
index 065383a43861f56a64800a35380b7795a25ccb27..dc1178a191ae06407e7c82d33cfa1d5ebeb9b4ac 100644 (file)
@@ -1337,12 +1337,15 @@ int dquot_transfer(struct dentry *dentry, struct iattr *iattr, uid_t initiator)
        else
                blocks = (inode->i_blocks / 2);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+       {
+               if (transfer_to[cnt] == NODQUOT)
+                       continue;
                if (check_idq(transfer_to[cnt], cnt, 1, initiator, tty) == NO_QUOTA ||
                    check_bdq(transfer_to[cnt], cnt, blocks, initiator, tty, 0) == NO_QUOTA) {
                        cnt = MAXQUOTAS;
                        goto put_all;
                }
-
+}
        if ((error = notify_change(dentry, iattr)))
                goto put_all; 
        /*
index f13984544d18324a0297244d640dc48775388e24..7c111f53d41eb32c5fe3b60fa902ee93364b58ac 100644 (file)
@@ -136,7 +136,7 @@ static long long ext2_file_lseek(
        return offset;
 }
 
-static inline void remove_suid(struct inode *inode)
+inline void ext2_remove_suid(struct inode *inode)
 {
        unsigned int mode;
 
@@ -190,7 +190,7 @@ static ssize_t ext2_file_write (struct file * filp, const char * buf,
                              inode->i_mode);
                return -EINVAL;
        }
-       remove_suid(inode);
+       ext2_remove_suid(inode);
 
        if (filp->f_flags & O_APPEND)
                pos = inode->i_size;
index afd15e84b51b85a4e4a424d8feb3847f2d2a0e9a..fad55020804b0a67d7dd20072bbf1ad0fbdaa879 100644 (file)
@@ -388,6 +388,8 @@ void ext2_truncate (struct inode * inode)
                return;
        if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
                return;
+       
+       ext2_remove_suid(inode); 
        ext2_discard_prealloc(inode);
        while (1) {
                retry = trunc_direct(inode);
index 0ec1c3896fe54381b2ad41d9987f0b168e8c3d92..54342a7c4176627a07dd15c3d51e26a5894afc71 100644 (file)
@@ -252,7 +252,7 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                }
                if (ncp_write_kernel(NCP_SERVER(inode), 
                    NCP_FINFO(inode)->file_handle,
-                   pos, to_write, buf, &written_this_time) != 0) {
+                   pos, to_write, bouncebuffer, &written_this_time) != 0) {
                        errno = -EIO;
                        break;
                }
index aeeeb216662fc82221ce8163770639ed795354ec..c10a2a1f33b8d4f2e87f4a5712dbe44c0b7a6865 100644 (file)
@@ -5,7 +5,7 @@
 # msdos and Joliet want NLS
 if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \
        -o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" \
-       -o "$CONFIG_SMB_FS" != n ]; then
+       -o "$CONFIG_SMB_FS" != "n" ]; then
   define_bool CONFIG_NLS y
 else
   define_bool CONFIG_NLS n
index 86f2a159957b2aa6a41fedf2adb4873efa10c9bd..5ef0a818da0e651490b3fcb10c3931dac6ca687b 100644 (file)
@@ -298,7 +298,7 @@ int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out,
        if(!result)return ENOMEM;
        *out_len=in_len;
        for(i=o=0;i<in_len;i++, o++){
-               unsigned short cl,ch;
+               unsigned short cl=0,ch=0;
                if(in[i]!=':' || (vol->nct & nct_uni_xlate)==0){
                        int len;
                        unsigned char clc=cl, chc=ch;
index 2ac79f78d6dc8159b2f058bb5db33550accf8a04..e4cf5171988bfc631fac929edd43daf751a96eaa 100644 (file)
 
 #include "smb_debug.h"
 
+/* Always pick a default string */
+#ifdef CONFIG_SMB_NLS_REMOTE
+#define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE
+#else
+#define SMB_NLS_REMOTE ""
+#endif
+
 static void smb_read_inode(struct inode *);
 static void smb_put_inode(struct inode *);
 static void smb_delete_inode(struct inode *);
@@ -383,7 +390,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
        memcpy(mnt, raw_data, sizeof(struct smb_mount_data));
        strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
                SMB_NLS_MAXNAMELEN);
-       strncpy(mnt->codepage.remote_name, CONFIG_SMB_NLS_REMOTE,
+       strncpy(mnt->codepage.remote_name, SMB_NLS_REMOTE,
                SMB_NLS_MAXNAMELEN);
 
        /* FIXME: ** temp ** pass config flags in file mode */
index 86e8edeca46cc0b5c69cd710c9b8d1b54dfd6e15..69ea9cf48686046f0c73a841104ca6c6528cc8e5 100644 (file)
@@ -95,9 +95,6 @@ struct apm_bios_info {
  */
 extern struct apm_bios_info    apm_bios_info;
 
-extern void            apm_init(void);
-extern void            apm_setup(char *, int *);
-
 extern int             apm_register_callback(int (*callback)(apm_event_t));
 extern void            apm_unregister_callback(int (*callback)(apm_event_t));
 
index 840e7cadc4ddcf7a30af9d21204a77e14e8b815a..e3d538fec5eba64c0b96abf3e9c8d46dded99ad9 100644 (file)
@@ -546,6 +546,7 @@ extern int ext2_check_dir_entry (const char *, struct inode *,
 /* file.c */
 extern int ext2_read (struct inode *, struct file *, char *, int);
 extern int ext2_write (struct inode *, struct file *, char *, int);
+extern void ext2_remove_suid (struct inode *); 
 
 /* fsync.c */
 extern int ext2_sync_file (struct file *, struct dentry *);
index 0d255a27e9ef5f7ebd5c34ac56f1c45a902c6ab0..431d1d600172eeb136f728833785829670c305a2 100644 (file)
@@ -17,7 +17,7 @@
  *    extern int z; z = x * y;
  * }
  *
- * Depricated: you can surround the whole function declaration 
+ * Deprecated: you can surround the whole function declaration 
  * just before function body into __initfunc() macro, like:
  *
  * __initfunc (static void initme(int x, int y))
@@ -66,6 +66,8 @@
 #endif
 
 
+#ifndef __ASSEMBLY__
+
 /*
  * Used for kernel command line parameter setup
  */
@@ -127,5 +129,5 @@ typedef void (*__cleanup_module_func_t)(void);
 #define module_exit(x) __exitcall(x);
 #endif
 
-
+#endif /* __ASSEMBLY __ */
 #endif
index 3a7c3cc8baa1626592616522e25977f3d734bb8d..4336220f2169e96223e9f2358dcab40150c76204 100644 (file)
 #define UNIX98_PTY_MAJOR_COUNT 8
 #define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
 
+#define MSR_MAJOR 202
+#define CPUID_MAJOR 203
+
 /*
  * Tests for SCSI devices.
  */
index e1936d63d55e3ebd15e2bb46b37155a34987fb81..7e436260fabfb8851597a5c04e5a91df9da16731 100644 (file)
@@ -81,6 +81,7 @@ extern volatile int smp_msg_id;
 #define kernel_lock()
 #define cpu_logical_map(cpu)                   0
 #define smp_call_function(func,info,retry,wait)        ({0;})
+#define cpu_online_map 1
 
 #endif
 #endif
index f228004f49d58e4a21532f6f282259944ab17c59..d6795a378ee49690c7dbb78d6841d532d1020930 100644 (file)
 #  include <asm/mtrr.h>
 #endif
 
-#ifdef CONFIG_APM
-#include <linux/apm_bios.h>
-#endif
-
 #ifdef CONFIG_DASD
 #include <asm/dasd.h>
 #endif
@@ -1096,9 +1092,6 @@ static struct kernel_param raw_params[] __initdata = {
 #ifdef CONFIG_PARIDE_PG
         { "pg.", pg_setup },
 #endif
-#ifdef CONFIG_APM
-       { "apm=", apm_setup },
-#endif
 #ifdef CONFIG_N2
        { "n2=", n2_setup },
 #endif
@@ -1180,15 +1173,14 @@ static int __init checksetup(char *line)
 
        /* Now handle new-style __setup parameters */
        p = &__setup_start;
-       do {
+       while (p < &__setup_end) {
                int n = strlen(p->str);
                if (!strncmp(line,p->str,n)) {
                        if (p->setup_func(line+n))
                                return 1;
                }
                p++;
-       } while (p < &__setup_end);
-
+       }
        return 0;
 }
 
@@ -1493,10 +1485,12 @@ static void __init do_initcalls(void)
        initcall_t *call;
 
        call = &__initcall_start;
-       do {
+       
+       while (call < &__initcall_end)
+       {
                (*call)();
                call++;
-       } while (call < &__initcall_end);
+       } 
 }
 
 
index 1a4306dea02a8cd37b3fed6119d4f4776294c099..3ad825a2df0143d45bde4ec42858a9922d1324fa 100644 (file)
@@ -4,7 +4,7 @@ bool '  IrLAP compression' CONFIG_IRDA_COMPRESSION
 if [ "$CONFIG_IRDA_COMPRESSION" != "n" ]; then
    comment '    IrDA compressors'
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      dep_tristate '    Deflate compression (EXPERIMENTAL)' CONFIG_IRDA_DEFLATE $CONFIG_IRDA
+      dep_tristate '    Deflate compression (EXPERIMENTAL)' CONFIG_IRDA_DEFLATE $CONFIG_IRDA m
    fi
 #   tristate '    BZIP2 compression' CONFIG_IRDA_BZIP2
 #   tristate '    BSD compression' CONFIG_IRDA_BSD