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
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
--- /dev/null
+
+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> ]
+
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/)
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 \
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
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
#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);
return 0;
}
-void __init apm_setup(char *str, int *dummy)
+static int __init apm_setup(char *str)
{
int invert;
if (str != NULL)
str += strspn(str, ", \t");
}
+ return 1;
}
__setup("apm=", apm_setup);
&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",
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;
}
/*
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;
}
/*
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);
#ifdef CONFIG_APM_CPU_IDLE
acpi_idle = apm_cpu_idle;
#endif
+ return 0;
}
module_init(apm_init)
--- /dev/null
+#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");
--- /dev/null
+#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;
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.
/* 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;
{
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;
}
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))
{
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
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
--- /dev/null
+/*
+ *
+ * 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, ®53h);
+ p += sprintf(p, "PCI Clock: %d.\n", reg53h);
+
+ pci_read_config_byte(bmide_dev, 0x53, ®53h);
+ 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, ®53h);
+ 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, ®53h);
+ 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, ®53h);
+ p += sprintf(p,
+ "Channel state: %s %s\n",
+ channel_status[reg53h & 0x07],
+ channel_status[(reg53h & 0x70) >> 4] );
+
+ pci_read_config_byte(bmide_dev, 0x58, ®5xh);
+ pci_read_config_byte(bmide_dev, 0x5c, ®5yh);
+ 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, ®5xh);
+ pci_read_config_byte(bmide_dev, 0x5d, ®5yh);
+ 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, ®5xh);
+ pci_read_config_byte(bmide_dev, 0x55, ®5yh);
+ 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, ®5xh);
+ pci_read_config_byte(bmide_dev, 0x5b, ®5xh1);
+ pci_read_config_byte(bmide_dev, 0x5e, ®5yh);
+ pci_read_config_byte(bmide_dev, 0x5f, ®5yh1);
+
+ 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, ®5xh);
+ pci_read_config_byte(bmide_dev, 0x57, ®5yh);
+ 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
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;
#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})
#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
{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 },
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
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
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
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
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
* 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>
/* End - Generic Agp routines */
+#ifdef CONFIG_AGP_I810
+
static aper_size_info_fixed intel_i810_sizes[] =
{
{64, 16384, 4},
{
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;
return 0;
}
+#endif /* CONFIG_AGP_I810 */
#ifdef CONFIG_AGP_INTEL
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;
break;
}
}
-
+#endif /* CONFIG_AGP_I810 */
/* find capndx */
pci_read_config_dword(dev, 0x04, &scratch);
--- /dev/null
+/*
+
+ 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 */
#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>
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)
#ifdef CONFIG_DTLK
dtlk_init();
#endif
-#ifdef CONFIG_APM
- apm_init();
-#endif
#ifdef CONFIG_H8
h8_init();
#endif
#ifdef CONFIG_SGI
streamable_init ();
#endif
+#ifdef CONFIG_INTEL_RNG
+ rng_init ();
+#endif
#ifdef CONFIG_TOSHIBA
tosh_init();
#endif
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;
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;
#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
#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
--- /dev/null
+/*
+ * 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);
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,
}
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);
#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";
/*********************************************************
*
* 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 */
#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>
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 },
};
#endif
-int el3_probe(struct device *dev)
+int __init el3_probe(struct device *dev)
{
short lrs_state = 0xff, i;
int ioaddr, irq, if_port;
/* 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. */
}
/* 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;
#define NEW_MULTICAST
#include <linux/delay.h>
+#include <linux/init.h>
/* Kernel version compatibility functions. */
#define RUN_AT(x) (jiffies + (x))
}
#else
-int tc515_probe(struct device *dev)
+int __init tc515_probe(struct device *dev)
{
int cards_found = 0;
}
#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;
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)
{
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;
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 }
return status;
}
-
+#ifdef MODULE
#if (LINUX_VERSION_CODE < 0x02032a)
int init_module(void)
{
module_init(ace_module_init);
module_exit(ace_module_cleanup);
#endif
-
+#endif
static void ace_free_descriptors(struct net_device *dev)
{
#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" },
#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>
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",
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;
#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>
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,
struct chip_info {
int io_size;
int flags;
-} static cap_tbl[] = {
+} static cap_tbl[] __initdata = {
{128, CanHaveMII, },
{128, CanHaveMII, },
};
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;
}
#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++)
}
#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)
{
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
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
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
*/
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 {
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);
}
\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 )
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)
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;
}
}
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 */
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) {
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;
}
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 */
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
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");
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));
/* 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;
}
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)) {
#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
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 *));
}
}
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) {
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) {
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) {
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) {
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);
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);
#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
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);
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)
/* 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;
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); */
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;
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 */
#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
u8 *dest, bit;
u16 *dest16;
u32 *dest32;
- u8 pixel;
+ u8 pixel = 0x5a;
switch (p->var.bits_per_pixel) {
case 1:
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
#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>
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;
/*
return offset;
}
-static inline void remove_suid(struct inode *inode)
+inline void ext2_remove_suid(struct inode *inode)
{
unsigned int mode;
inode->i_mode);
return -EINVAL;
}
- remove_suid(inode);
+ ext2_remove_suid(inode);
if (filp->f_flags & O_APPEND)
pos = inode->i_size;
return;
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
+
+ ext2_remove_suid(inode);
ext2_discard_prealloc(inode);
while (1) {
retry = trunc_direct(inode);
}
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;
}
# 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
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;
#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 *);
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 */
*/
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));
/* 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 *);
* 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))
#endif
+#ifndef __ASSEMBLY__
+
/*
* Used for kernel command line parameter setup
*/
#define module_exit(x) __exitcall(x);
#endif
-
+#endif /* __ASSEMBLY __ */
#endif
#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.
*/
#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
# include <asm/mtrr.h>
#endif
-#ifdef CONFIG_APM
-#include <linux/apm_bios.h>
-#endif
-
#ifdef CONFIG_DASD
#include <asm/dasd.h>
#endif
#ifdef CONFIG_PARIDE_PG
{ "pg.", pg_setup },
#endif
-#ifdef CONFIG_APM
- { "apm=", apm_setup },
-#endif
#ifdef CONFIG_N2
{ "n2=", n2_setup },
#endif
/* 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;
}
initcall_t *call;
call = &__initcall_start;
- do {
+
+ while (call < &__initcall_end)
+ {
(*call)();
call++;
- } while (call < &__initcall_end);
+ }
}
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