summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@penguin.transmeta.com>2003-01-14 01:08:14 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2003-01-14 01:08:14 -0800
commit200ce8b3fe4fa22d95da992de667a9097c97c529 (patch)
treea11a303e9a7da68e21cb3deb09a84c6d24140896
parent9f9618b6ae0025f394834c6ec53a37baed5cdeb7 (diff)
parent1105415188b0cf41e28c0145e827b60a975e45d7 (diff)
Merge http://fbdev.bkbits.net:8080/fbdev-2.5
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
-rw-r--r--Documentation/crypto/api-intro.txt12
-rw-r--r--arch/arm/kernel/calls.S20
-rw-r--r--arch/arm/mach-integrator/cpu.c2
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c2
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1110.c2
-rw-r--r--arch/i386/kernel/cpu/amd.c2
-rw-r--r--arch/i386/kernel/cpu/proc.c2
-rw-r--r--arch/sparc64/Kconfig33
-rw-r--r--arch/sparc64/kernel/Makefile1
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c250
-rw-r--r--crypto/Kconfig12
-rw-r--r--crypto/Makefile1
-rw-r--r--crypto/des.c4
-rw-r--r--crypto/sha512.c373
-rw-r--r--crypto/tcrypt.c116
-rw-r--r--crypto/tcrypt.h109
-rw-r--r--drivers/char/i8k.c105
-rw-r--r--drivers/char/tty_io.c7
-rw-r--r--drivers/char/watchdog/acquirewdt.c14
-rw-r--r--drivers/char/watchdog/advantechwdt.c210
-rw-r--r--drivers/char/watchdog/alim7101_wdt.c14
-rw-r--r--drivers/char/watchdog/eurotechwdt.c156
-rw-r--r--drivers/char/watchdog/i810-tco.c3
-rw-r--r--drivers/char/watchdog/ib700wdt.c73
-rw-r--r--drivers/char/watchdog/indydog.c1
-rw-r--r--drivers/char/watchdog/machzwd.c12
-rw-r--r--drivers/char/watchdog/mixcomwd.c4
-rw-r--r--drivers/char/watchdog/pcwd.c10
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c1
-rw-r--r--drivers/char/watchdog/sbc60xxwdt.c13
-rw-r--r--drivers/char/watchdog/sc1200wdt.c9
-rw-r--r--drivers/char/watchdog/sc520_wdt.c14
-rw-r--r--drivers/char/watchdog/scx200_wdt.c6
-rw-r--r--drivers/char/watchdog/shwdt.c1
-rw-r--r--drivers/char/watchdog/softdog.c57
-rw-r--r--drivers/char/watchdog/w83877f_wdt.c16
-rw-r--r--drivers/char/watchdog/wafer5823wdt.c5
-rw-r--r--drivers/char/watchdog/wdt.c44
-rw-r--r--drivers/char/watchdog/wdt285.c23
-rw-r--r--drivers/char/watchdog/wdt977.c1
-rw-r--r--drivers/char/watchdog/wdt_pci.c133
-rw-r--r--drivers/hotplug/acpiphp_glue.c45
-rw-r--r--drivers/serial/sunsab.c2
-rw-r--r--fs/ext3/ialloc.c28
-rw-r--r--fs/ext3/inode.c36
-rw-r--r--fs/ext3/namei.c16
-rw-r--r--fs/hugetlbfs/inode.c3
-rw-r--r--fs/jbd/checkpoint.c1
-rw-r--r--fs/jbd/commit.c33
-rw-r--r--fs/jbd/transaction.c38
-rw-r--r--fs/proc/inode.c7
-rw-r--r--fs/proc/proc_misc.c3
-rw-r--r--fs/xfs/linux/xfs_linux.h2
-rw-r--r--fs/xfs/linux/xfs_lrw.c7
-rw-r--r--fs/xfs/linux/xfs_vnode.h3
-rw-r--r--fs/xfs/pagebuf/page_buf.c6
-rw-r--r--fs/xfs/support/debug.c38
-rw-r--r--fs/xfs/xfs_dir.c6
-rw-r--r--fs/xfs/xfs_dir2.c8
-rw-r--r--fs/xfs/xfs_inode.h7
-rw-r--r--fs/xfs/xfs_log_recover.c10
-rw-r--r--fs/xfs/xfs_rename.c53
-rw-r--r--fs/xfs/xfs_utils.c4
-rw-r--r--fs/xfs/xfs_vfsops.c4
-rw-r--r--fs/xfs/xfs_vnodeops.c59
-rw-r--r--include/asm-arm/ide.h2
-rw-r--r--include/asm-arm/unistd.h64
-rw-r--r--include/asm-sparc64/bug.h3
-rw-r--r--include/linux/ext3_fs.h2
-rw-r--r--include/linux/ext3_jbd.h12
-rw-r--r--include/linux/jbd.h28
-rw-r--r--include/linux/miscdevice.h1
-rw-r--r--include/linux/mmzone.h3
-rw-r--r--include/linux/sched.h3
-rw-r--r--include/linux/xattr.h2
-rw-r--r--kernel/exit.c19
-rw-r--r--kernel/fork.c16
-rw-r--r--mm/page_alloc.c8
-rw-r--r--mm/readahead.c5
79 files changed, 1708 insertions, 752 deletions
diff --git a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt
index d2e805565bdc..f6abc861c271 100644
--- a/Documentation/crypto/api-intro.txt
+++ b/Documentation/crypto/api-intro.txt
@@ -80,6 +80,10 @@ should also be added:
alias digest_null crypto_null
alias compress_null crypto_null
+The SHA384 algorithm shares code within the SHA512 module, so you'll
+also need:
+ alias sha384 sha512
+
DEVELOPER NOTES
@@ -182,7 +186,7 @@ Original developers of the crypto algorithms:
Andrew Tridgell and Steve French (MD4)
Colin Plumb (MD5)
Steve Reid (SHA1)
- Jean-Luc Cooke (SHA256)
+ Jean-Luc Cooke (SHA256, SHA384, SHA512)
Kazunori Miyazawa / USAGI (HMAC)
Matthew Skala (Twofish)
Dag Arne Osvik (Serpent)
@@ -201,9 +205,11 @@ Twofish algorithm contributors:
Werner Koch
Marc Mutz
-SHA256 algorithm contributors:
+SHA256/384/512 algorithm contributors:
Andrew McDonald
-
+ Kyle McMartin
+ Herbert Valerio Riedel
+
AES algorithm contributors:
Alexander Kjeldaas
Herbert Valerio Riedel
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 7e6df7d5f2da..58e4c2d4b239 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -10,7 +10,7 @@
* This file is included twice in entry-common.S
*/
#ifndef NR_syscalls
-#define NR_syscalls 256
+#define NR_syscalls 288
#else
__syscall_start:
@@ -253,6 +253,24 @@ __syscall_start:
.long sys_lremovexattr
.long sys_fremovexattr
.long sys_tkill
+ .long sys_sendfile64
+/* 240 */ .long sys_futex
+ .long sys_sched_setaffinity
+ .long sys_sched_getaffinity
+ .long sys_io_setup
+ .long sys_io_destroy
+/* 245 */ .long sys_io_getevents
+ .long sys_io_submit
+ .long sys_io_cancel
+ .long sys_exit_group
+ .long sys_lookup_dcookie
+/* 250 */ .long sys_epoll_create
+ .long sys_epoll_ctl
+ .long sys_epoll_wait
+ .long sys_remap_file_pages
+ .long sys_ni_syscall /* sys_set_thread_area */
+/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
+ .long sys_ni_syscall /* sys_set_tid_address */
__syscall_end:
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index 2d71baa76351..9a55cfdb6cbe 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -228,4 +228,4 @@ static int __init integrator_cpu_init(void)
return 0;
}
-core_initcall(integrator_cpu_init);
+arch_initcall(integrator_cpu_init);
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index b4226692b902..9c1c4ba81c4e 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -232,4 +232,4 @@ static int __init sa1100_dram_init(void)
return ret;
}
-core_initcall(sa1100_dram_init);
+arch_initcall(sa1100_dram_init);
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 2ab03f867d86..ecfc2c113a7e 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -345,4 +345,4 @@ static int __init sa1110_clk_init(void)
return 0;
}
-core_initcall(sa1110_clk_init);
+arch_initcall(sa1110_clk_init);
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index d0272733c39b..762a1a8d8c01 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -56,7 +56,7 @@ static void __init init_amd(struct cpuinfo_x86 *c)
if (inl (CBAR) & CBAR_ENB)
outl (0 | CBAR_KEY, CBAR);
}
-
+ break;
case 5:
if( c->x86_model < 6 )
{
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index af05636fe86d..722d29cc1b3a 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -22,7 +22,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
"pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
- "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
+ "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
/* AMD-defined */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index b5403396d199..155876ea5314 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -139,6 +139,39 @@ config NR_CPUS
depends on SMP
default "64"
+config CPU_FREQ
+ bool "CPU Frequency scaling"
+ help
+ Clock scaling allows you to change the clock speed of CPUs on the
+ fly. Currently there is only a sparc64 driver for UltraSPARC-III
+ processors.
+
+ For details, take a look at linux/Documentation/cpufreq.
+
+ If in doubt, say N.
+
+config CPU_FREQ_PROC_INTF
+ bool "/proc/cpufreq interface (DEPRECATED)"
+ depends on CPU_FREQ && PROC_FS
+ help
+ This enables the /proc/cpufreq interface for controlling
+ CPUFreq. Please note that it is recommended to use the sysfs
+ interface instead (which is built automatically).
+
+ For details, take a look at linux/Documentation/cpufreq.
+
+ If in doubt, say N.
+
+config US3_FREQ
+ tristate "UltraSPARC-III CPU Frequency driver"
+ depends on CPU_FREQ
+ help
+ This adds the CPUFreq driver for UltraSPARC-III processors.
+
+ For details, take a look at linux/Documentation/cpufreq.
+
+ If in doubt, say N.
+
# Identify this as a Sparc64 build
config SPARC64
bool
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 322a6f191154..dcfab416133c 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
ifdef CONFIG_SUNOS_EMUL
obj-y += sys_sunos32.o sunos_ioctl32.o
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
new file mode 100644
index 000000000000..520860cd46da
--- /dev/null
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -0,0 +1,250 @@
+/* us3_cpufreq.c: UltraSPARC-III cpu frequency support
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ *
+ * Many thanks to Dominik Brodowski for fixing up the cpufreq
+ * infrastructure in order to make this driver easier to implement.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/cpufreq.h>
+#include <linux/threads.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+static struct cpufreq_driver *cpufreq_us3_driver;
+
+/* Index by [(CPU * 4) + INDEX] (first three indices are
+ * actual us3 divisor entries, last is for CPUFREQ_TABLE_END)
+ */
+static struct cpufreq_frequency_table *us3_freq_table;
+
+/* UltraSPARC-III has three dividers: 1, 2, and 32. These are controlled
+ * in the Safari config register.
+ */
+#define SAFARI_CFG_DIV_1 0x0000000000000000UL
+#define SAFARI_CFG_DIV_2 0x0000000040000000UL
+#define SAFARI_CFG_DIV_32 0x0000000080000000UL
+#define SAFARI_CFG_DIV_MASK 0x00000000C0000000UL
+
+static unsigned long read_safari_cfg(void)
+{
+ unsigned long ret;
+
+ __asm__ __volatile__("ldxa [%%g0] %1, %0"
+ : "=&r" (ret)
+ : "i" (ASI_SAFARI_CONFIG));
+ return ret;
+}
+
+static void write_safari_cfg(unsigned long val)
+{
+ __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (val), "i" (ASI_SAFARI_CONFIG)
+ : "memory");
+}
+
+#ifndef CONFIG_SMP
+extern unsigned long up_clock_tick;
+#endif
+
+static __inline__ unsigned long get_clock_tick(unsigned int cpu)
+{
+#ifdef CONFIG_SMP
+ return cpu_data[cpu].clock_tick;
+#else
+ return up_clock_tick;
+#endif
+}
+
+static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg)
+{
+ unsigned long clock_tick = get_clock_tick(cpu);
+ unsigned long ret;
+
+ switch (safari_cfg & SAFARI_CFG_DIV_MASK) {
+ case SAFARI_CFG_DIV_1:
+ ret = clock_tick / 1;
+ break;
+ case SAFARI_CFG_DIV_2:
+ ret = clock_tick / 2;
+ break;
+ case SAFARI_CFG_DIV_32:
+ ret = clock_tick / 32;
+ break;
+ default:
+ BUG();
+ };
+
+ return ret;
+}
+
+static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
+{
+ unsigned long new_bits, new_freq, reg, cpus_allowed;
+ struct cpufreq_freqs freqs;
+
+ if (!cpu_online(cpu))
+ return;
+
+ cpus_allowed = current->cpus_allowed;
+ set_cpus_allowed(current, (1UL << cpu));
+
+ new_freq = get_clock_tick(cpu);
+ switch (index) {
+ case 0:
+ new_bits = SAFARI_CFG_DIV_1;
+ new_freq /= 1;
+ break;
+ case 1:
+ new_bits = SAFARI_CFG_DIV_2;
+ new_freq /= 2;
+ break;
+ case 2:
+ new_bits = SAFARI_CFG_DIV_32;
+ new_freq /= 32;
+ break;
+
+ default:
+ BUG();
+ };
+
+ reg = read_safari_cfg();
+
+ freqs.old = get_current_freq(cpu, reg);
+ freqs.new = new_freq;
+ freqs.cpu = cpu;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ reg &= ~SAFARI_CFG_DIV_MASK;
+ reg |= new_bits;
+ write_safari_cfg(reg);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ set_cpus_allowed(current, cpus_allowed);
+}
+
+static int us3_setpolicy(struct cpufreq_policy *policy)
+{
+ unsigned int new_index = 0;
+
+ if (cpufreq_frequency_table_setpolicy(policy,
+ &us3_freq_table[(policy->cpu * 4) + 0],
+ &new_index))
+ return -EINVAL;
+
+ us3_set_cpu_divider_index(policy->cpu, new_index);
+
+ return 0;
+}
+
+static int us3_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy,
+ &us3_freq_table[(policy->cpu * 4) + 0]);
+}
+
+#ifndef CONFIG_SMP
+extern unsigned long up_clock_tick;
+#endif
+
+static void __init us3_init_freq_table(unsigned int cpu)
+{
+ unsigned long clock_tick = get_clock_tick(cpu);
+
+ us3_freq_table[(cpu * 4) + 0].index = 0;
+ us3_freq_table[(cpu * 4) + 0].frequency = clock_tick / 1;
+ us3_freq_table[(cpu * 4) + 1].index = 1;
+ us3_freq_table[(cpu * 4) + 1].frequency = clock_tick / 2;
+ us3_freq_table[(cpu * 4) + 2].index = 2;
+ us3_freq_table[(cpu * 4) + 2].frequency = clock_tick / 32;
+ us3_freq_table[(cpu * 4) + 3].index = 0;
+ us3_freq_table[(cpu * 4) + 3].frequency = CPUFREQ_TABLE_END;
+}
+
+static int __init us3freq_init(void)
+{
+ struct cpufreq_driver *driver;
+ unsigned long manuf, impl, ver;
+ int i, ret;
+
+ __asm__("rdpr %%ver, %0" : "=r" (ver));
+ manuf = ((ver >> 48) & 0xffff);
+ impl = ((ver >> 32) & 0xffff);
+
+ /* XXX Maybe accept cheetah+ too? */
+ if (manuf == 0x3e && impl == 0x14) {
+ driver = kmalloc(sizeof(struct cpufreq_driver) +
+ (NR_CPUS * sizeof(struct cpufreq_policy)),
+ GFP_KERNEL);
+ if (!driver)
+ return -ENOMEM;
+ us3_freq_table = kmalloc(
+ (NR_CPUS * 4 * sizeof(struct cpufreq_frequency_table)),
+ GFP_KERNEL);
+ if (!us3_freq_table) {
+ kfree(driver);
+ return -ENOMEM;
+ }
+
+ driver->policy = (struct cpufreq_policy *) (driver + 1);
+ driver->verify = us3_verify;
+ driver->setpolicy = us3_setpolicy;
+
+ for (i = 0; i < NR_CPUS; i++) {
+ driver->policy[i].cpu = i;
+ us3_init_freq_table(i);
+ ret = cpufreq_frequency_table_cpuinfo(&driver->policy[i],
+ &us3_freq_table[(i * 4) + 0]);
+ if (ret) {
+ kfree(driver);
+ kfree(us3_freq_table);
+ us3_freq_table = NULL;
+ return ret;
+ }
+ driver->policy[i].policy = CPUFREQ_POLICY_PERFORMANCE;
+ us3_set_cpu_divider_index(i, 0);
+ }
+ cpufreq_us3_driver = driver;
+ ret = cpufreq_register_driver(driver);
+ if (ret) {
+ kfree(driver);
+ cpufreq_us3_driver = NULL;
+ kfree(us3_freq_table);
+ us3_freq_table = NULL;
+ return ret;
+ }
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static void __exit us3freq_exit(void)
+{
+ int i;
+
+ if (cpufreq_us3_driver) {
+ for (i = 0; i < NR_CPUS; i++)
+ us3_set_cpu_divider_index(i, 0);
+ cpufreq_unregister_driver(cpufreq_us3_driver);
+
+ kfree(cpufreq_us3_driver);
+ cpufreq_us3_driver = NULL;
+ kfree(us3_freq_table);
+ us3_freq_table = NULL;
+ }
+}
+
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_DESCRIPTION("cpufreq driver for UltraSPARC-III");
+MODULE_LICENSE("GPL");
+
+module_init(us3freq_init);
+module_exit(us3freq_exit);
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 3fbb8e5108b6..8b81dcd7da4b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -53,6 +53,18 @@ config CRYPTO_SHA256
This version of SHA implements a 256 bit hash with 128 bits of
security against collision attacks.
+config CRYPTO_SHA512
+ tristate "SHA384 and SHA512 digest algorithms"
+ depends on CRYPTO
+ help
+ SHA512 secure hash standard (DFIPS 180-2).
+
+ This version of SHA implements a 512 bit hash with 256 bits of
+ security against collision attacks.
+
+ This code also includes SHA-384, a 384 bit hash with 192 bits
+ of security against collision attacks.
+
config CRYPTO_DES
tristate "DES and Triple DES EDE cipher algorithms"
depends on CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index c05967e3ba0d..fa66d0d7ad91 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_CRYPTO_MD4) += md4.o
obj-$(CONFIG_CRYPTO_MD5) += md5.o
obj-$(CONFIG_CRYPTO_SHA1) += sha1.o
obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
+obj-$(CONFIG_CRYPTO_SHA512) += sha512.o
obj-$(CONFIG_CRYPTO_DES) += des.o
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
diff --git a/crypto/des.c b/crypto/des.c
index 08ca675c24f7..edc648ed891b 100644
--- a/crypto/des.c
+++ b/crypto/des.c
@@ -1279,10 +1279,8 @@ static int __init init(void)
goto out;
ret = crypto_register_alg(&des3_ede_alg);
- if (ret < 0) {
+ if (ret < 0)
crypto_unregister_alg(&des_alg);
- goto out;
- }
out:
return ret;
}
diff --git a/crypto/sha512.c b/crypto/sha512.c
new file mode 100644
index 000000000000..686bb1198397
--- /dev/null
+++ b/crypto/sha512.c
@@ -0,0 +1,373 @@
+/* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
+ *
+ * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
+ *
+ * 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, or (at your option) any
+ * later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/crypto.h>
+
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#define SHA384_DIGEST_SIZE 48
+#define SHA512_DIGEST_SIZE 64
+#define SHA384_HMAC_BLOCK_SIZE 96
+#define SHA512_HMAC_BLOCK_SIZE 128
+
+struct sha512_ctx {
+ u64 state[8];
+ u32 count[4];
+ u8 buf[128];
+};
+
+static inline u64 Ch(u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ (~x & z));
+}
+
+static inline u64 Maj(u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u64 RORu64(u64 x, u64 y)
+{
+ return (x >> y) | (x << (64 - y));
+}
+
+const u64 sha512_K[80] = {
+ 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
+ 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
+ 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
+ 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+ 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
+ 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
+ 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
+ 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+ 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
+ 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+ 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
+ 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
+ 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
+ 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
+ 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
+ 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
+ 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
+ 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
+ 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
+ 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+ 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
+ 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
+ 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
+ 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
+ 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
+ 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
+ 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
+};
+
+#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
+#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
+#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
+#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
+
+/* H* initial state for SHA-512 */
+#define H0 0x6a09e667f3bcc908
+#define H1 0xbb67ae8584caa73b
+#define H2 0x3c6ef372fe94f82b
+#define H3 0xa54ff53a5f1d36f1
+#define H4 0x510e527fade682d1
+#define H5 0x9b05688c2b3e6c1f
+#define H6 0x1f83d9abfb41bd6b
+#define H7 0x5be0cd19137e2179
+
+/* H'* initial state for SHA-384 */
+#define HP0 0xcbbb9d5dc1059ed8
+#define HP1 0x629a292a367cd507
+#define HP2 0x9159015a3070dd17
+#define HP3 0x152fecd8f70e5939
+#define HP4 0x67332667ffc00b31
+#define HP5 0x8eb44a8768581511
+#define HP6 0xdb0c2e0d64f98fa7
+#define HP7 0x47b5481dbefa4fa4
+
+static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+{
+ u64 t1 = input[(8*I) ] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+1] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+2] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+3] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+4] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+5] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+6] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+7] & 0xff;
+ W[I] = t1;
+}
+
+static inline void BLEND_OP(int I, u64 *W)
+{
+ W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+}
+
+static void
+sha512_transform(u64 *state, const u8 *input)
+{
+ u64 a, b, c, d, e, f, g, h, t1, t2;
+ u64 W[80];
+
+ int i;
+
+ /* load the input */
+ for (i = 0; i < 16; i++)
+ LOAD_OP(i, W, input);
+
+ for (i = 16; i < 80; i++) {
+ BLEND_OP(i, W);
+ }
+
+ /* load the state into our registers */
+ a=state[0]; b=state[1]; c=state[2]; d=state[3];
+ e=state[4]; f=state[5]; g=state[6]; h=state[7];
+
+ /* now iterate */
+ for (i=0; i<80; i+=8) {
+ t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ];
+ t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
+ t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1];
+ t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
+ t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2];
+ t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
+ t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3];
+ t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
+ t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4];
+ t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
+ t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5];
+ t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
+ t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6];
+ t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
+ t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7];
+ t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
+ }
+
+ state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+ state[4] += e; state[5] += f; state[6] += g; state[7] += h;
+
+ /* erase our data */
+ a = b = c = d = e = f = g = h = t1 = t2 = 0;
+ memset(W, 0, 80 * sizeof(u64));
+}
+
+static void
+sha512_init(void *ctx)
+{
+ struct sha512_ctx *sctx = ctx;
+ sctx->state[0] = H0;
+ sctx->state[1] = H1;
+ sctx->state[2] = H2;
+ sctx->state[3] = H3;
+ sctx->state[4] = H4;
+ sctx->state[5] = H5;
+ sctx->state[6] = H6;
+ sctx->state[7] = H7;
+ sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+ memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void
+sha384_init(void *ctx)
+{
+ struct sha512_ctx *sctx = ctx;
+ sctx->state[0] = HP0;
+ sctx->state[1] = HP1;
+ sctx->state[2] = HP2;
+ sctx->state[3] = HP3;
+ sctx->state[4] = HP4;
+ sctx->state[5] = HP5;
+ sctx->state[6] = HP6;
+ sctx->state[7] = HP7;
+ sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+ memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void
+sha512_update(void *ctx, const u8 *data, unsigned int len)
+{
+ struct sha512_ctx *sctx = ctx;
+
+ unsigned int i, index, part_len;
+
+ /* Compute number of bytes mod 128 */
+ index = (unsigned int)((sctx->count[0] >> 3) & 0x7F);
+
+ /* Update number of bits */
+ if ((sctx->count[0] += (len << 3)) < (len << 3)) {
+ if ((sctx->count[1] += 1) < 1)
+ if ((sctx->count[2] += 1) < 1)
+ sctx->count[3]++;
+ sctx->count[1] += (len >> 29);
+ }
+
+ part_len = 128 - index;
+
+ /* Transform as many times as possible. */
+ if (len >= part_len) {
+ memcpy(&sctx->buf[index], data, part_len);
+ sha512_transform(sctx->state, sctx->buf);
+
+ for (i = part_len; i + 127 < len; i+=128)
+ sha512_transform(sctx->state, &data[i]);
+
+ index = 0;
+ } else {
+ i = 0;
+ }
+
+ /* Buffer remaining input */
+ memcpy(&sctx->buf[index], &data[i], len - i);
+}
+
+static void
+sha512_final(void *ctx, u8 *hash)
+{
+ struct sha512_ctx *sctx = ctx;
+
+ const static u8 padding[128] = { 0x80, };
+
+ u32 t;
+ u64 t2;
+ u8 bits[128];
+ unsigned int index, pad_len;
+ int i, j;
+
+ index = pad_len = t = i = j = 0;
+ t2 = 0;
+
+ /* Save number of bits */
+ t = sctx->count[0];
+ bits[15] = t; t>>=8;
+ bits[14] = t; t>>=8;
+ bits[13] = t; t>>=8;
+ bits[12] = t;
+ t = sctx->count[1];
+ bits[11] = t; t>>=8;
+ bits[10] = t; t>>=8;
+ bits[9 ] = t; t>>=8;
+ bits[8 ] = t;
+ t = sctx->count[2];
+ bits[7 ] = t; t>>=8;
+ bits[6 ] = t; t>>=8;
+ bits[5 ] = t; t>>=8;
+ bits[4 ] = t;
+ t = sctx->count[3];
+ bits[3 ] = t; t>>=8;
+ bits[2 ] = t; t>>=8;
+ bits[1 ] = t; t>>=8;
+ bits[0 ] = t;
+
+ /* Pad out to 112 mod 128. */
+ index = (sctx->count[0] >> 3) & 0x7f;
+ pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
+ sha512_update(sctx, padding, pad_len);
+
+ /* Append length (before padding) */
+ sha512_update(sctx, bits, 16);
+
+ /* Store state in digest */
+ for (i = j = 0; i < 8; i++, j += 8) {
+ t2 = sctx->state[i];
+ hash[j+7] = (char)t2 & 0xff; t2>>=8;
+ hash[j+6] = (char)t2 & 0xff; t2>>=8;
+ hash[j+5] = (char)t2 & 0xff; t2>>=8;
+ hash[j+4] = (char)t2 & 0xff; t2>>=8;
+ hash[j+3] = (char)t2 & 0xff; t2>>=8;
+ hash[j+2] = (char)t2 & 0xff; t2>>=8;
+ hash[j+1] = (char)t2 & 0xff; t2>>=8;
+ hash[j ] = (char)t2 & 0xff;
+ }
+
+ /* Zeroize sensitive information. */
+ memset(sctx, 0, sizeof(struct sha512_ctx));
+}
+
+static void sha384_final(void *ctx, u8 *hash)
+{
+ struct sha512_ctx *sctx = ctx;
+ u8 D[64];
+
+ sha512_final(sctx, D);
+
+ memcpy(hash, D, 48);
+ memset(D, 0, 64);
+}
+
+static struct crypto_alg sha512 = {
+ .cra_name = "sha512",
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = SHA512_HMAC_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct sha512_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(sha512.cra_list),
+ .cra_u = { .digest = {
+ .dia_digestsize = SHA512_DIGEST_SIZE,
+ .dia_init = sha512_init,
+ .dia_update = sha512_update,
+ .dia_final = sha512_final }
+ }
+};
+
+static struct crypto_alg sha384 = {
+ .cra_name = "sha384",
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = SHA384_HMAC_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct sha512_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(sha384.cra_list),
+ .cra_u = { .digest = {
+ .dia_digestsize = SHA384_DIGEST_SIZE,
+ .dia_init = sha384_init,
+ .dia_update = sha512_update,
+ .dia_final = sha384_final }
+ }
+};
+
+static int __init init(void)
+{
+ int ret = 0;
+
+ if ((ret = crypto_register_alg(&sha384)) < 0)
+ goto out;
+ if ((ret = crypto_register_alg(&sha512)) < 0)
+ crypto_unregister_alg(&sha384);
+out:
+ return ret;
+}
+
+static void __exit fini(void)
+{
+ crypto_unregister_alg(&sha384);
+ crypto_unregister_alg(&sha512);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 3c2ce9382bdd..bcce9065242a 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -48,7 +48,7 @@ static char *tvmem;
static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
- "twofish", "serpent",
+ "twofish", "serpent", "sha384", "sha512", "md4", "aes",
NULL
};
@@ -549,6 +549,110 @@ test_sha256(void)
crypto_free_tfm(tfm);
}
+static void
+test_sha384(void)
+{
+ char *p;
+ unsigned int i;
+ struct crypto_tfm *tfm;
+ struct sha384_testvec *sha384_tv;
+ struct scatterlist sg[2];
+ unsigned int tsize;
+ char result[SHA384_DIGEST_SIZE];
+
+ printk("\ntesting sha384\n");
+
+ tsize = sizeof (sha384_tv_template);
+ if (tsize > TVMEMSIZE) {
+ printk("template (%u) too big for tvmem (%u)\n", tsize,
+ TVMEMSIZE);
+ return;
+ }
+
+ memcpy(tvmem, sha384_tv_template, tsize);
+ sha384_tv = (void *) tvmem;
+
+ tfm = crypto_alloc_tfm("sha384", 0);
+ if (tfm == NULL) {
+ printk("failed to load transform for sha384\n");
+ return;
+ }
+
+ for (i = 0; i < SHA384_TEST_VECTORS; i++) {
+ printk("test %u:\n", i + 1);
+ memset(result, 0, sizeof (result));
+
+ p = sha384_tv[i].plaintext;
+ sg[0].page = virt_to_page(p);
+ sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].length = strlen(sha384_tv[i].plaintext);
+
+ crypto_digest_init(tfm);
+ crypto_digest_update(tfm, sg, 1);
+ crypto_digest_final(tfm, result);
+
+ hexdump(result, crypto_tfm_alg_digestsize(tfm));
+ printk("%s\n",
+ memcmp(result, sha384_tv[i].digest,
+ crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+ "pass");
+ }
+
+ crypto_free_tfm(tfm);
+}
+
+static void
+test_sha512(void)
+{
+ char *p;
+ unsigned int i;
+ struct crypto_tfm *tfm;
+ struct sha512_testvec *sha512_tv;
+ struct scatterlist sg[2];
+ unsigned int tsize;
+ char result[SHA512_DIGEST_SIZE];
+
+ printk("\ntesting sha512\n");
+
+ tsize = sizeof (sha512_tv_template);
+ if (tsize > TVMEMSIZE) {
+ printk("template (%u) too big for tvmem (%u)\n", tsize,
+ TVMEMSIZE);
+ return;
+ }
+
+ memcpy(tvmem, sha512_tv_template, tsize);
+ sha512_tv = (void *) tvmem;
+
+ tfm = crypto_alloc_tfm("sha512", 0);
+ if (tfm == NULL) {
+ printk("failed to load transform for sha512\n");
+ return;
+ }
+
+ for (i = 0; i < SHA512_TEST_VECTORS; i++) {
+ printk("test %u:\n", i + 1);
+ memset(result, 0, sizeof (result));
+
+ p = sha512_tv[i].plaintext;
+ sg[0].page = virt_to_page(p);
+ sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].length = strlen(sha512_tv[i].plaintext);
+
+ crypto_digest_init(tfm);
+ crypto_digest_update(tfm, sg, 1);
+ crypto_digest_final(tfm, result);
+
+ hexdump(result, crypto_tfm_alg_digestsize(tfm));
+ printk("%s\n",
+ memcmp(result, sha512_tv[i].digest,
+ crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+ "pass");
+ }
+
+ crypto_free_tfm(tfm);
+}
+
void
test_des(void)
{
@@ -2117,6 +2221,8 @@ do_test(void)
test_twofish();
test_serpent();
test_aes();
+ test_sha384();
+ test_sha512();
#ifdef CONFIG_CRYPTO_HMAC
test_hmac_md5();
test_hmac_sha1();
@@ -2163,7 +2269,15 @@ do_test(void)
case 10:
test_aes();
break;
+
+ case 11:
+ test_sha384();
+ break;
+ case 12:
+ test_sha512();
+ break;
+
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac_md5();
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 3fbd49ed18ac..b8e328e90545 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -20,6 +20,8 @@
#define MD4_DIGEST_SIZE 16
#define SHA1_DIGEST_SIZE 20
#define SHA256_DIGEST_SIZE 32
+#define SHA384_DIGEST_SIZE 48
+#define SHA512_DIGEST_SIZE 64
/*
* MD4 test vectors from RFC1320
@@ -591,6 +593,113 @@ struct sha256_testvec {
};
/*
+ * SHA384 test vectors from from NIST and kerneli
+ */
+#define SHA384_TEST_VECTORS 4
+
+struct sha384_testvec {
+ char plaintext[128];
+ char digest[SHA384_DIGEST_SIZE];
+} sha384_tv_template[] = {
+
+ { "abc",
+ { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
+ 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
+ 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+ 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
+ 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
+ 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
+ },
+
+ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
+ 0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
+ 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
+ 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
+ 0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
+ 0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b }
+ },
+
+ { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
+ 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
+ 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
+ 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
+ 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
+ 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
+ },
+
+ { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+ "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+ { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb,
+ 0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a,
+ 0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc,
+ 0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a,
+ 0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a,
+ 0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 }
+ },
+};
+
+/*
+ * SHA512 test vectors from from NIST and kerneli
+ */
+#define SHA512_TEST_VECTORS 4
+
+struct sha512_testvec {
+ char plaintext[128];
+ char digest[SHA512_DIGEST_SIZE];
+} sha512_tv_template[] = {
+
+ { "abc",
+ { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
+ 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+ 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+ 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+ 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
+ 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+ 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
+ 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
+ },
+
+ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
+ 0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
+ 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
+ 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
+ 0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
+ 0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
+ 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
+ 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 }
+ },
+
+ { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
+ 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
+ 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
+ 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
+ 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
+ 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
+ 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
+ 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
+ },
+
+ { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+ "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+ { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11,
+ 0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d,
+ 0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c,
+ 0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d,
+ 0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67,
+ 0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe,
+ 0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8,
+ 0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9
+ }
+ },
+};
+
+/*
* DES test vectors.
*/
#define DES_ENC_TEST_VECTORS 5
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index d2305841c676..9b8e1bf03917 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -22,12 +22,14 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/apm_bios.h>
+#include <linux/kbd_kern.h>
+#include <linux/timer.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/i8k.h>
-#define I8K_VERSION "1.7 21/11/2001"
+#define I8K_VERSION "1.13 14/05/2002"
#define I8K_SMM_FN_STATUS 0x0025
#define I8K_SMM_POWER_STATUS 0x0069
@@ -55,6 +57,19 @@
#define DELL_SIGNATURE "Dell Computer"
+/* Interval between polling of keys, in jiffies. */
+#define I8K_POLL_INTERVAL (HZ/20)
+#define I8K_REPEAT_DELAY 250 /* 250 ms */
+#define I8K_REPEAT_RATE 10
+
+/*
+ * (To be escaped) Scancodes for the keys. These were chosen to match other
+ * "Internet" keyboards.
+ */
+#define I8K_KEYS_UP_SCANCODE 0x30
+#define I8K_KEYS_DOWN_SCANCODE 0x2e
+#define I8K_KEYS_MUTE_SCANCODE 0x20
+
static char *supported_models[] = {
"Inspiron",
"Latitude",
@@ -67,19 +82,34 @@ static char bios_version [4] = "?";
static char serial_number[16] = "?";
static int force = 0;
+static int restricted = 0;
+static int handle_buttons = 0;
+static int repeat_delay = I8K_REPEAT_DELAY;
+static int repeat_rate = I8K_REPEAT_RATE;
static int power_status = 0;
+static struct timer_list i8k_keys_timer;
+
MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
MODULE_LICENSE("GPL");
MODULE_PARM(force, "i");
+MODULE_PARM(restricted, "i");
+MODULE_PARM(handle_buttons, "i");
+MODULE_PARM(repeat_delay, "i");
+MODULE_PARM(repeat_rate, "i");
MODULE_PARM(power_status, "i");
MODULE_PARM_DESC(force, "Force loading without checking for supported models");
+MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
+MODULE_PARM_DESC(handle_buttons, "Generate keyboard events for i8k buttons");
+MODULE_PARM_DESC(repeat_delay, "I8k buttons repeat delay (ms)");
+MODULE_PARM_DESC(repeat_rate, "I8k buttons repeat rate");
MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
static ssize_t i8k_read(struct file *, char *, size_t, loff_t *);
static int i8k_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
+static void i8k_keys_set_timer(void);
static struct file_operations i8k_fops = {
.read = i8k_read,
@@ -370,6 +400,9 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
break;
case I8K_SET_FAN:
+ if (restricted && !capable(CAP_SYS_ADMIN)) {
+ return -EPERM;
+ }
if (copy_from_user(&val, (int *)arg, sizeof(int))) {
return -EFAULT;
}
@@ -483,6 +516,61 @@ static ssize_t i8k_read(struct file *f, char *buffer, size_t len, loff_t *fpos)
return len;
}
+/*
+ * i8k_keys stuff. Thanks to David Bustos <bustos@caltech.edu>
+ */
+
+static unsigned char i8k_keys_make_scancode(int x) {
+ switch (x) {
+ case I8K_FN_UP: return I8K_KEYS_UP_SCANCODE;
+ case I8K_FN_DOWN: return I8K_KEYS_DOWN_SCANCODE;
+ case I8K_FN_MUTE: return I8K_KEYS_MUTE_SCANCODE;
+ }
+
+ return 0;
+}
+
+static void i8k_keys_poll(unsigned long data) {
+ static int last = 0;
+ static int repeat = 0;
+
+ int curr;
+
+ curr = i8k_get_fn_status();
+ if (curr >= 0) {
+ if (curr != last) {
+ repeat = jiffies + (HZ * repeat_delay / 1000);
+
+ if (last != 0) {
+ handle_scancode(0xe0, 0);
+ handle_scancode(i8k_keys_make_scancode(last), 0);
+ }
+
+ if (curr != 0) {
+ handle_scancode(0xe0, 1);
+ handle_scancode(i8k_keys_make_scancode(curr), 1);
+ }
+ } else {
+ /* Generate keyboard repeat events with current scancode -- dz */
+ if ((curr) && (repeat_rate > 0) && (jiffies >= repeat)) {
+ repeat = jiffies + (HZ / repeat_rate);
+ handle_scancode(0xe0, 1);
+ handle_scancode(i8k_keys_make_scancode(curr), 1);
+ }
+ }
+
+ last = curr;
+ }
+
+ /* Reset the timer. */
+ i8k_keys_set_timer();
+}
+
+static void i8k_keys_set_timer() {
+ i8k_keys_timer.expires = jiffies + I8K_POLL_INTERVAL;
+ add_timer(&i8k_keys_timer);
+}
+
static char* __init string_trim(char *s, int size)
{
int len;
@@ -757,6 +845,16 @@ int __init i8k_init(void)
"Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
I8K_VERSION);
+ /* Register the i8k_keys timer. */
+ if (handle_buttons) {
+ printk(KERN_INFO
+ "i8k: enabling buttons events, delay=%d, rate=%d\n",
+ repeat_delay, repeat_rate);
+ init_timer(&i8k_keys_timer);
+ i8k_keys_timer.function = i8k_keys_poll;
+ i8k_keys_set_timer();
+ }
+
return 0;
}
@@ -771,6 +869,11 @@ void cleanup_module(void)
/* Remove the proc entry */
remove_proc_entry("i8k", NULL);
+ /* Unregister the i8k_keys timer. */
+ while (handle_buttons && !del_timer(&i8k_keys_timer)) {
+ schedule_timeout(I8K_POLL_INTERVAL);
+ }
+
printk(KERN_INFO "i8k: module unloaded\n");
}
#endif
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index d39c31afe0e4..68a000ff62a9 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1836,6 +1836,8 @@ static void __do_SAK(void *arg)
#else
struct tty_struct *tty = arg;
struct task_struct *p;
+ struct list_head *l;
+ struct pid *pid;
int session;
int i;
struct file *filp;
@@ -1848,9 +1850,8 @@ static void __do_SAK(void *arg)
if (tty->driver.flush_buffer)
tty->driver.flush_buffer(tty);
read_lock(&tasklist_lock);
- for_each_process(p) {
- if ((p->tty == tty) ||
- ((session > 0) && (p->session == session))) {
+ for_each_task_pid(session, PIDTYPE_SID, p, l, pid) {
+ if (p->tty == tty || session > 0) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): p->session==tty->session\n",
p->pid, p->comm);
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
index b509fb731454..68bcc26aecf4 100644
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/char/watchdog/acquirewdt.c
@@ -24,24 +24,18 @@
#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>
-#include <linux/slab.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/spinlock.h>
-#include <linux/smp_lock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
static int acq_is_open;
static spinlock_t acq_lock;
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
index f994c8fc5e69..f8d265607111 100644
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/char/watchdog/advantechwdt.c
@@ -13,64 +13,49 @@
* 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.
+ *
+ * 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@redhat.com>
*
- * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
- * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- * Added timeout module option to override default
+ * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
*/
#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>
-#include <linux/slab.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/spinlock.h>
-#include <linux/smp_lock.h>
-static int advwdt_is_open;
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+static unsigned long advwdt_is_open;
static char adv_expect_close;
-static spinlock_t advwdt_lock;
/*
* You must set these - there is no sane way to probe for this board.
*
* To enable or restart, write the timeout value in seconds (1 to 63)
- * to I/O port WDT_START. To disable, read I/O port WDT_STOP.
+ * to I/O port wdt_start. To disable, read I/O port wdt_stop.
* Both are 0x443 for most boards (tested on a PCA-6276VE-00B1), but
* check your manual (at least the PCA-6159 seems to be different -
- * the manual says WDT_STOP is 0x43, not 0x443).
+ * the manual says wdt_stop is 0x43, not 0x443).
* (0x43 is also a write-only control register for the 8254 timer!)
- *
- * TODO: module parameters to set the I/O port addresses
*/
-#define WDT_STOP 0x443
-#define WDT_START 0x443
-
-#define WD_TIMO 60 /* 1 minute */
+static int wdt_stop = 0x443;
+static int wdt_start = 0x443;
-static int timeout = WD_TIMO; /* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=60)");
+static int wd_margin = 60; /* 60 sec default timeout */
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
@@ -84,12 +69,44 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
/*
* Kernel methods.
*/
-
+
+#ifndef MODULE
+
+static int __init adv_setup(char *str)
+{
+ int ints[4];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ if(ints[0] > 0){
+ wdt_stop = ints[1];
+ if(ints[0] > 1)
+ wdt_start = ints[2];
+ }
+
+ return 1;
+}
+
+__setup("advwdt=", adv_setup);
+
+#endif /* !MODULE */
+
+MODULE_PARM(wdt_stop, "i");
+MODULE_PARM_DESC(wdt_stop, "Advantech WDT 'stop' io port (default 0x443)");
+MODULE_PARM(wdt_start, "i");
+MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)");
+
static void
advwdt_ping(void)
{
/* Write a watchdog value */
- outb_p(timeout, WDT_START);
+ outb_p(wd_margin, wdt_start);
+}
+
+static void
+advwdt_disable(void)
+{
+ inb_p(wdt_stop);
}
static ssize_t
@@ -118,16 +135,11 @@ advwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
return count;
}
-static ssize_t
-advwdt_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-{
- return -EINVAL;
-}
-
static int
advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ int new_margin;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
@@ -139,16 +151,47 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
return -EFAULT;
break;
-
+
case WDIOC_GETSTATUS:
- if (copy_to_user((int *)arg, &advwdt_is_open, sizeof(int)))
- return -EFAULT;
- break;
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, (int *)arg);
case WDIOC_KEEPALIVE:
advwdt_ping();
break;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_margin, (int *)arg))
+ return -EFAULT;
+ if ((new_margin < 1) || (new_margin > 63))
+ return -EINVAL;
+ wd_margin = new_margin;
+ advwdt_ping();
+ /* Fall */
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(wd_margin, (int *)arg);
+
+ case WDIOC_SETOPTIONS:
+ {
+ int options, retval = -EINVAL;
+
+ if (get_user(options, (int *)arg))
+ return -EFAULT;
+
+ if (options & WDIOS_DISABLECARD) {
+ advwdt_disable();
+ retval = 0;
+ }
+
+ if (options & WDIOS_ENABLECARD) {
+ advwdt_ping();
+ retval = 0;
+ }
+
+ return retval;
+ }
+
default:
return -ENOTTY;
}
@@ -158,37 +201,27 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int
advwdt_open(struct inode *inode, struct file *file)
{
- if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
- spin_lock(&advwdt_lock);
- if (advwdt_is_open) {
- spin_unlock(&advwdt_lock);
- return -EBUSY;
- }
-
- if (nowayout)
- MOD_INC_USE_COUNT;
+ if (test_and_set_bit(0, &advwdt_is_open))
+ return -EBUSY;
+ /*
+ * Activate
+ */
- /* Activate */
- advwdt_is_open = 1;
- advwdt_ping();
- spin_unlock(&advwdt_lock);
- return 0;
- } else {
- return -ENODEV;
- }
+ advwdt_ping();
+ return 0;
}
static int
advwdt_close(struct inode *inode, struct file *file)
{
- if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
- spin_lock(&advwdt_lock);
- if (!nowayout)
- inb_p(WDT_STOP);
-
- advwdt_is_open = 0;
- spin_unlock(&advwdt_lock);
+ if (adv_expect_close == 42) {
+ advwdt_disable();
+ } else {
+ printk(KERN_CRIT "advancetechwdt: Unexpected close, not stopping watchdog!\n");
+ advwdt_ping();
}
+ clear_bit(0, &advwdt_is_open);
+ adv_expect_close = 0;
return 0;
}
@@ -200,10 +233,10 @@ static int
advwdt_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
- if (code == SYS_DOWN || code == SYS_HALT)
+ if (code == SYS_DOWN || code == SYS_HALT) {
/* Turn the WDT off */
- inb_p(WDT_STOP);
-
+ advwdt_disable();
+ }
return NOTIFY_DONE;
}
@@ -213,7 +246,6 @@ advwdt_notify_sys(struct notifier_block *this, unsigned long code,
static struct file_operations advwdt_fops = {
.owner = THIS_MODULE,
- .read = advwdt_read,
.write = advwdt_write,
.ioctl = advwdt_ioctl,
.open = advwdt_open,
@@ -237,35 +269,22 @@ static struct notifier_block advwdt_notifier = {
.priority = 0
};
-static void __init
-advwdt_validate_timeout(void)
-{
- if (timeout < 1 || timeout > 63) {
- timeout = WD_TIMO;
- printk(KERN_INFO "advantechwdt: timeout value must be 1 <= x <= 63, using %d\n", timeout);
- }
-}
-
static int __init
advwdt_init(void)
{
- printk("WDT driver for Advantech single board computer initialising.\n");
+ printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
- advwdt_validate_timeout();
- spin_lock_init(&advwdt_lock);
if (misc_register(&advwdt_miscdev))
return -ENODEV;
-#if WDT_START != WDT_STOP
- if (!request_region(WDT_STOP, 1, "Advantech WDT")) {
- misc_deregister(&advwdt_miscdev);
+ if (wdt_stop != wdt_start)
+ if (!request_region(wdt_stop, 1, "Advantech WDT")) {
+ misc_deregister(&advwdt_miscdev);
return -EIO;
}
-#endif
- if (!request_region(WDT_START, 1, "Advantech WDT")) {
+ if (!request_region(wdt_start, 1, "Advantech WDT")) {
misc_deregister(&advwdt_miscdev);
-#if WDT_START != WDT_STOP
- release_region(WDT_STOP, 1);
-#endif
+ if (wdt_stop != wdt_start)
+ release_region(wdt_stop, 1);
return -EIO;
}
register_reboot_notifier(&advwdt_notifier);
@@ -277,14 +296,15 @@ advwdt_exit(void)
{
misc_deregister(&advwdt_miscdev);
unregister_reboot_notifier(&advwdt_notifier);
-#if WDT_START != WDT_STOP
- release_region(WDT_STOP,1);
-#endif
- release_region(WDT_START,1);
+ if(wdt_stop != wdt_start)
+ release_region(wdt_stop,1);
+ release_region(wdt_start,1);
}
module_init(advwdt_init);
module_exit(advwdt_exit);
MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marek Michalkiewicz <marekm@linux.org.pl>");
+MODULE_DESCRIPTION("Advantech Single Board Computer WDT driver");
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index 653ae2d767fe..126384bc4094 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -30,26 +30,20 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/timer.h>
-#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.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/pci.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
#define OUR_NAME "alim7101_wdt"
#define WDT_ENABLE 0x9C
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index 46c015c372a9..d7378c9102be 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -3,78 +3,82 @@
*
* (c) Copyright 2001 Ascensit <support@ascensit.com>
* (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
+ * (c) Copyright 2002 Rob Radez <rob@osinvestor.com>
*
* Based on wdt.c.
* Original copyright messages:
*
- * (c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
- * http://www.redhat.com
+ * (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.
+ * 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.
+ * 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>
+ * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>*
+ */
+
+/* Changelog:
+ *
+ * 2002/04/25 - Rob Radez
+ * clean up #includes
+ * clean up locking
+ * make __setup param unique
+ * proper options in watchdog_info
+ * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
+ * add expect_close support
*
- * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
- * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- * Added timeout module option to override default
+ * 2001 - Rodolfo Giometti
+ * Initial release
+ *
+ * 2002.05.30 - Joel Becker <joel.becker@oracle.com>
+ * Added Matt Domsch's nowayout module option.
*/
#include <linux/config.h>
#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
-#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
-static int eurwdt_is_open;
-static spinlock_t eurwdt_lock;
+static unsigned long eurwdt_is_open;
+static int eurwdt_timeout;
static char eur_expect_close;
-
+
/*
* You must set these - there is no sane way to probe for this board.
- * You can use wdt=x,y to set these now.
+ * You can use eurwdt=x,y to set these now.
*/
static int io = 0x3f0;
static int irq = 10;
static char *ev = "int";
-#define WDT_TIMEOUT 60 /* 1 minute */
-static int timeout = WDT_TIMEOUT;
-
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Eurotech WDT timeout in seconds (default=60)");
+#define WDT_TIMEOUT 60 /* 1 minute */
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
#else
static int nowayout = 0;
#endif
+
MODULE_PARM(nowayout,"i");
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
-
/*
* Some symbolic names
*/
@@ -115,7 +119,7 @@ str = get_options (str, ARRAY_SIZE(ints), ints);
return 1;
}
-__setup("wdt=", eurwdt_setup);
+__setup("eurwdt=", eurwdt_setup);
#endif /* !MODULE */
@@ -124,22 +128,13 @@ MODULE_PARM_DESC(io, "Eurotech WDT io port (default=0x3f0)");
MODULE_PARM(irq, "i");
MODULE_PARM_DESC(irq, "Eurotech WDT irq (default=10)");
MODULE_PARM(ev, "s");
-MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `reboot')");
+MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `int')");
/*
* Programming support
*/
-static void __init eurwdt_validate_timeout(void)
-{
- if (timeout < 0 || timeout > 255) {
- timeout = WDT_TIMEOUT;
- printk(KERN_INFO "eurwdt: timeout must be 0 < x < 255, using %d\n",
- timeout);
- }
-}
-
static inline void eurwdt_write_reg(u8 index, u8 data)
{
outb(index, io);
@@ -214,7 +209,7 @@ void eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void eurwdt_ping(void)
{
/* Write the watchdog default value */
- eurwdt_set_timeout(timeout);
+ eurwdt_set_timeout(eurwdt_timeout);
}
/**
@@ -250,10 +245,9 @@ loff_t *ppos)
}
}
eurwdt_ping(); /* the default timeout */
- return 1;
}
- return 0;
+ return count;
}
/**
@@ -271,12 +265,13 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
static struct watchdog_info ident = {
- .options = WDIOF_CARDRESET,
+ .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
.identity = "WDT Eurotech CPU-1220/1410",
};
int time;
+ int options, retval = -EINVAL;
switch(cmd) {
default:
@@ -286,6 +281,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
return copy_to_user((struct watchdog_info *)arg, &ident,
sizeof(ident)) ? -EFAULT : 0;
+ case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0, (int *) arg);
@@ -301,9 +297,26 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
if (time < 0 || time > 255)
return -EINVAL;
- timeout = time;
+ eurwdt_timeout = time;
eurwdt_set_timeout(time);
- return 0;
+ /* Fall */
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(eurwdt_timeout, (int *)arg);
+
+ case WDIOC_SETOPTIONS:
+ if (get_user(options, (int *)arg))
+ return -EFAULT;
+ if (options & WDIOS_DISABLECARD) {
+ eurwdt_disable_timer();
+ retval = 0;
+ }
+ if (options & WDIOS_ENABLECARD) {
+ eurwdt_activate_timer();
+ eurwdt_ping();
+ retval = 0;
+ }
+ return retval;
}
}
@@ -318,32 +331,12 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
static int eurwdt_open(struct inode *inode, struct file *file)
{
- switch (minor(inode->i_rdev)) {
- case WATCHDOG_MINOR:
- spin_lock(&eurwdt_lock);
- if (eurwdt_is_open) {
- spin_unlock(&eurwdt_lock);
- return -EBUSY;
- }
- if (nowayout)
- MOD_INC_USE_COUNT;
-
- eurwdt_is_open = 1;
-
- /* Activate the WDT */
- eurwdt_activate_timer();
-
- spin_unlock(&eurwdt_lock);
-
- MOD_INC_USE_COUNT;
- return 0;
-
- case TEMP_MINOR:
- return 0;
-
- default:
- return -ENODEV;
- }
+ if (test_and_set_bit(0, &eurwdt_is_open))
+ return -EBUSY;
+ eurwdt_timeout = WDT_TIMEOUT; /* initial timeout */
+ /* Activate the WDT */
+ eurwdt_activate_timer();
+ return 0;
}
/**
@@ -360,14 +353,14 @@ static int eurwdt_open(struct inode *inode, struct file *file)
static int eurwdt_release(struct inode *inode, struct file *file)
{
- if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
- if (!nowayout)
- eurwdt_disable_timer();
-
- eurwdt_is_open = 0;
- MOD_DEC_USE_COUNT;
- }
-
+ if (eur_expect_close == 42) {
+ eurwdt_disable_timer();
+ } else {
+ printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
+ eurwdt_ping();
+ }
+ clear_bit(0, &eurwdt_is_open);
+ eur_expect_close = 0;
return 0;
}
@@ -456,7 +449,6 @@ static int __init eurwdt_init(void)
{
int ret;
- eurwdt_validate_timeout();
ret = misc_register(&eurwdt_miscdev);
if (ret) {
printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
@@ -489,8 +481,6 @@ static int __init eurwdt_init(void)
" - timeout event: %s\n",
io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
- spin_lock_init(&eurwdt_lock);
-
out:
return ret;
diff --git a/drivers/char/watchdog/i810-tco.c b/drivers/char/watchdog/i810-tco.c
index f24465c0a8d5..8f571d22fd58 100644
--- a/drivers/char/watchdog/i810-tco.c
+++ b/drivers/char/watchdog/i810-tco.c
@@ -47,9 +47,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
index 68a9454a6dae..4f1a5916c229 100644
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/char/watchdog/ib700wdt.c
@@ -33,24 +33,18 @@
#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>
-#include <linux/slab.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/spinlock.h>
-#include <linux/smp_lock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
static int ibwdt_is_open;
static spinlock_t ibwdt_lock;
@@ -92,15 +86,32 @@ static int expect_close = 0;
*
*/
+static int wd_times[] = {
+ 30, /* 0x0 */
+ 28, /* 0x1 */
+ 26, /* 0x2 */
+ 24, /* 0x3 */
+ 22, /* 0x4 */
+ 20, /* 0x5 */
+ 18, /* 0x6 */
+ 16, /* 0x7 */
+ 14, /* 0x8 */
+ 12, /* 0x9 */
+ 10, /* 0xA */
+ 8, /* 0xB */
+ 6, /* 0xC */
+ 4, /* 0xD */
+ 2, /* 0xE */
+ 0, /* 0xF */
+};
+
#define WDT_STOP 0x441
#define WDT_START 0x443
+/* Default timeout */
#define WD_TIMO 0 /* 30 seconds +/- 20%, from table */
-static int timeout_val = WD_TIMO; /* value in table */
-static int timeout = 30; /* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, 0 < n < 30, must be even (default=30)");
+static int wd_margin = WD_TIMO;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
@@ -111,22 +122,16 @@ static int nowayout = 0;
MODULE_PARM(nowayout,"i");
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
/*
* Kernel methods.
*/
-static void __init
-ibwdt_validate_timeout(void)
-{
- timeout_val = (30 - timeout) / 2;
- if (timeout_val < 0 || timeout_val > 0xF) timeout_val = WD_TIMO;
-}
-
static void
ibwdt_ping(void)
{
/* Write a watchdog value */
- outb_p(timeout_val, WDT_START);
+ outb_p(wd_times[wd_margin], WDT_START);
}
static ssize_t
@@ -145,7 +150,6 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
for (i = 0; i != count; i++) {
char c;
-
if (get_user(c, buf + i))
return -EFAULT;
if (c == 'V')
@@ -168,6 +172,8 @@ static int
ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ int i, new_margin;
+
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
@@ -189,6 +195,22 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
ibwdt_ping();
break;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_margin, (int *)arg))
+ return -EFAULT;
+ if ((new_margin < 0) || (new_margin > 30))
+ return -EINVAL;
+ for (i = 0x0F; i > -1; i--)
+ if (wd_times[i] > new_margin)
+ break;
+ wd_margin = i;
+ ibwdt_ping();
+ /* Fall */
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(wd_times[wd_margin], (int *)arg);
+ break;
+
default:
return -ENOTTY;
}
@@ -223,7 +245,7 @@ ibwdt_close(struct inode *inode, struct file *file)
if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
spin_lock(&ibwdt_lock);
if (expect_close)
- outb_p(timeout_val, WDT_STOP);
+ outb_p(wd_times[wd_margin], WDT_STOP);
else
printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n");
@@ -243,7 +265,7 @@ ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
{
if (code == SYS_DOWN || code == SYS_HALT) {
/* Turn the WDT off */
- outb_p(timeout_val, WDT_STOP);
+ outb_p(wd_times[wd_margin], WDT_STOP);
}
return NOTIFY_DONE;
}
@@ -283,7 +305,6 @@ ibwdt_init(void)
{
printk("WDT driver for IB700 single board computer initialising.\n");
- ibwdt_validate_timeout();
spin_lock_init(&ibwdt_lock);
if (misc_register(&ibwdt_miscdev))
return -ENODEV;
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
index c41dac5b6b07..23697570bcdb 100644
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/char/watchdog/indydog.c
@@ -19,7 +19,6 @@
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/sgi/sgimc.h>
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 3d78c2f37ec6..7a67ceeac45f 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -30,25 +30,19 @@
#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/timer.h>
#include <linux/jiffies.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.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 <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
/* ports */
#define ZF_IOBASE 0x218
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index f19a5d9230ef..e207ef305c2c 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -38,15 +38,11 @@
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index be2bcd00c5fa..1c36b8c4fe24 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -45,27 +45,17 @@
*/
#include <linux/module.h>
-
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
#include <linux/timer.h>
#include <linux/config.h>
-#include <linux/kernel.h>
#include <linux/wait.h>
-#include <linux/string.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
#include <linux/watchdog.h>
#include <linux/init.h>
-#include <linux/proc_fs.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index 874539eb4309..8af274c64eaa 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -24,7 +24,6 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/hardware.h>
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
index 4b61d1a8db40..15fbbd831cc4 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -56,25 +56,20 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.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 <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
#define OUR_NAME "sbc60xxwdt"
/*
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index 005cdaa5c4cf..20133a652d3e 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -28,21 +28,20 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
-#include <linux/ioport.h>
-#include <asm/semaphore.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/pci.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
#define SC1200_MODULE_VER "build 20020303"
#define SC1200_MODULE_NAME "sc1200wdt"
#define PFX SC1200_MODULE_NAME ": "
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 1d30c4ef4f29..3a98c8b6d760 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -49,25 +49,19 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/timer.h>
-#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.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 <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
/*
* The SC520 can timeout anywhere from 492us to 32.21s.
* If we reset the watchdog every ~250ms we should be safe.
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
index eba57eb21513..6d02fe2edfcd 100644
--- a/drivers/char/watchdog/scx200_wdt.c
+++ b/drivers/char/watchdog/scx200_wdt.c
@@ -19,19 +19,17 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/pci.h>
+#include <linux/scx200.h>
+
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <linux/scx200.h>
-
#define NAME "scx200_wdt"
MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
index 2f32ebc5708e..f5ae26556a31 100644
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/char/watchdog/shwdt.c
@@ -16,7 +16,6 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index 7abbabad53fc..658414d74ee7 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -27,21 +27,21 @@
* 19980911 Alan Cox
* Made SMP safe for 2.3.x
*
- * 20011214 Matt Domsch <Matt_Domsch@dell.com>
- * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- * Didn't add timeout option, as soft_margin option already exists.
+ * 20011127 Joel Becker (jlbec@evilplan.org>
+ * Added soft_noboot; Allows testing the softdog trigger without
+ * requiring a recompile.
+ * Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
+ *
+ * 20020530 Joel Becker <joel.becker@oracle.com>
+ * Added Matt Domsch's nowayout module option.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@ -49,8 +49,15 @@
static int expect_close = 0;
static int soft_margin = TIMER_MARGIN; /* in seconds */
+#ifdef ONLY_TESTING
+static int soft_noboot = 1;
+#else
+static int soft_noboot = 0;
+#endif /* ONLY_TESTING */
MODULE_PARM(soft_margin,"i");
+MODULE_PARM(soft_noboot,"i");
+MODULE_LICENSE("GPL");
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
@@ -60,7 +67,6 @@ static int nowayout = 0;
MODULE_PARM(nowayout,"i");
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
-MODULE_LICENSE("GPL");
/*
* Our timer
@@ -70,7 +76,7 @@ static void watchdog_fire(unsigned long);
static struct timer_list watchdog_ticktock =
TIMER_INITIALIZER(watchdog_fire, 0, 0);
-static int timer_alive;
+static unsigned long timer_alive;
/*
@@ -79,13 +85,14 @@ static int timer_alive;
static void watchdog_fire(unsigned long data)
{
-#ifdef ONLY_TESTING
- printk(KERN_CRIT "SOFTDOG: Would Reboot.\n");
-#else
- printk(KERN_CRIT "SOFTDOG: Initiating system reboot.\n");
- machine_restart(NULL);
- printk("WATCHDOG: Reboot didn't ?????\n");
-#endif
+ if (soft_noboot)
+ printk(KERN_CRIT "SOFTDOG: Triggered - Reboot ignored.\n");
+ else
+ {
+ printk(KERN_CRIT "SOFTDOG: Initiating system reboot.\n");
+ machine_restart(NULL);
+ printk("SOFTDOG: Reboot didn't ?????\n");
+ }
}
/*
@@ -94,7 +101,7 @@ static void watchdog_fire(unsigned long data)
static int softdog_open(struct inode *inode, struct file *file)
{
- if(timer_alive)
+ if(test_and_set_bit(0, &timer_alive))
return -EBUSY;
if (nowayout) {
MOD_INC_USE_COUNT;
@@ -103,7 +110,6 @@ static int softdog_open(struct inode *inode, struct file *file)
* Activate timer
*/
mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
- timer_alive=1;
return 0;
}
@@ -113,12 +119,12 @@ static int softdog_release(struct inode *inode, struct file *file)
* Shut off the timer.
* Lock it in if it's a module and we set nowayout
*/
- if(!nowayout) {
+ if (expect_close) {
del_timer(&watchdog_ticktock);
} else {
printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly. WDT will not stop!\n");
}
- timer_alive=0;
+ clear_bit(0, &timer_alive);
return 0;
}
@@ -156,6 +162,7 @@ static ssize_t softdog_write(struct file *file, const char *data, size_t len, lo
static int softdog_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ int new_margin;
static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.identity = "Software Watchdog",
@@ -173,6 +180,16 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
case WDIOC_KEEPALIVE:
mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
return 0;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_margin, (int *)arg))
+ return -EFAULT;
+ if (new_margin < 1)
+ return -EINVAL;
+ soft_margin = new_margin;
+ mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ return put_user(soft_margin, (int *)arg);
}
}
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
index 152c5cf41311..5a852f657b5b 100644
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/char/watchdog/w83877f_wdt.c
@@ -42,24 +42,18 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.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 <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
#define OUR_NAME "w83877f_wdt"
@@ -220,6 +214,8 @@ static int fop_open(struct inode * inode, struct file * file)
case WATCHDOG_MINOR:
/* Just in case we're already talking to someone... */
if(test_and_set_bit(0, &wdt_is_open)) {
+ /* Davej: Is this unlock bogus? */
+ spin_unlock(&wdt_spinlock);
return -EBUSY;
}
/* Good, fire up the show */
@@ -242,7 +238,7 @@ static int fop_close(struct inode * inode, struct file * file)
printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
}
}
- wdt_is_open = 0;
+ clear_bit(0, &wdt_is_open);
return 0;
}
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
index dc611c96835e..858713e435f5 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -27,16 +27,15 @@
*/
#include <linux/module.h>
-#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
static unsigned long wafwdt_is_open;
static spinlock_t wafwdt_lock;
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
index f50fd376e0ec..6b7a2ea9f054 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -27,22 +27,17 @@
* Tim Hockin : Added insmod parameters, comment cleanup
* Parameterized timeout
* Tigran Aivazian : Restructured wdt_init() to handle failures
- * Matt Domsch : added nowayout and timeout module options
+ * Joel Becker : Added WDIOC_GET/SETTIMEOUT
+ * Matt Domsch : Added nowayout module option
*/
#include <linux/config.h>
#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include "wd501p.h"
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
@@ -50,6 +45,7 @@
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
+#include "wd501p.h"
static unsigned long wdt_is_open;
static int expect_close;
@@ -62,12 +58,10 @@ static int expect_close;
static int io=0x240;
static int irq=11;
+/* Default margin */
#define WD_TIMO (100*60) /* 1 minute */
-static int timeout_val = WD_TIMO; /* value passed to card */
-static int timeout = 60; /* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=60)");
+static int wd_margin = WD_TIMO;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
@@ -78,12 +72,6 @@ static int nowayout = 0;
MODULE_PARM(nowayout,"i");
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
-static void __init
-wdt_validate_timeout(void)
-{
- timeout_val = timeout * 100;
-}
-
#ifndef MODULE
/**
@@ -238,7 +226,7 @@ static void wdt_ping(void)
/* Write a watchdog value */
inb_p(WDT_DC);
wdt_ctr_mode(1,2);
- wdt_ctr_load(1,timeout_val); /* Timeout */
+ wdt_ctr_load(1,wd_margin); /* Timeout */
outb_p(0, WDT_DC);
}
@@ -329,6 +317,8 @@ static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *ptr)
static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ int new_margin;
+
static struct watchdog_info ident=
{
.options = WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER
@@ -353,6 +343,17 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case WDIOC_KEEPALIVE:
wdt_ping();
return 0;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_margin, (int *)arg))
+ return -EFAULT;
+ /* Arbitrary, can't find the card's limits */
+ if ((new_margin < 0) || (new_margin > 60))
+ return -EINVAL;
+ wd_margin = new_margin * 100;
+ wdt_ping();
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ return put_user(wd_margin / 100, (int *)arg);
}
}
@@ -375,19 +376,17 @@ static int wdt_open(struct inode *inode, struct file *file)
case WATCHDOG_MINOR:
if(test_and_set_bit(0, &wdt_is_open))
return -EBUSY;
- if (nowayout) {
- MOD_INC_USE_COUNT;
- }
/*
* Activate
*/
+ wdt_is_open=1;
inb_p(WDT_DC); /* Disable */
wdt_ctr_mode(0,3);
wdt_ctr_mode(1,2);
wdt_ctr_mode(2,0);
wdt_ctr_load(0, 8948); /* count at 100Hz */
- wdt_ctr_load(1,timeout_val); /* Timeout */
+ wdt_ctr_load(1,wd_margin); /* Timeout 120 seconds */
wdt_ctr_load(2,65535);
outb_p(0, WDT_DC); /* Enable */
return 0;
@@ -525,7 +524,6 @@ static int __init wdt_init(void)
{
int ret;
- wdt_validate_timeout();
ret = misc_register(&wdt_miscdev);
if (ret) {
printk(KERN_ERR "wdt: can't misc_register on minor=%d\n", WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/char/watchdog/wdt285.c
index 639ab2aa4edc..c9a6fac7404d 100644
--- a/drivers/char/watchdog/wdt285.c
+++ b/drivers/char/watchdog/wdt285.c
@@ -25,7 +25,6 @@
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -124,10 +123,10 @@ static ssize_t watchdog_write(struct file *file, const char *data, size_t len, l
static int watchdog_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int i;
+ int i, new_margin;
static struct watchdog_info ident=
{
- 0,
+ WDIOF_SETTIMEOUT,
0,
"Footbridge Watchdog"
};
@@ -145,6 +144,17 @@ static int watchdog_ioctl(struct inode *inode, struct file *file,
case WDIOC_KEEPALIVE:
watchdog_ping();
return 0;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_margin, (int *)arg))
+ return -EFAULT;
+ /* Arbitrary, can't find the card's limits */
+ if ((new_marg < 0) || (new_margin > 60))
+ return -EINVAL;
+ soft_margin = new_margin;
+ watchdog_ping();
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ return put_user(soft_margin, (int *)arg);
}
}
@@ -166,10 +176,15 @@ static struct miscdevice watchdog_miscdev=
static int __init footbridge_watchdog_init(void)
{
+ int retval;
+
if (machine_is_netwinder())
return -ENODEV;
- misc_register(&watchdog_miscdev);
+ retval = misc_register(&watchdog_miscdev);
+ if(retval < 0)
+ return retval;
+
printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
soft_margin);
if (machine_is_cats())
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index 28c9e5842917..5b12542844b5 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -25,7 +25,6 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/watchdog.h>
#include <asm/io.h>
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index 588f369ede0d..1e8b81c91969 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -30,21 +30,18 @@
* Alan Cox : Split ISA and PCI cards into two drivers
* Jeff Garzik : PCI cleanups
* Tigran Aivazian : Restructured wdtpci_init_one() to handle failures
- * Matt Domsch : added nowayout and timeout module options
+ * Joel Becker : Added WDIOC_GET/SETTIMEOUT
+ * Zwane Mwaikambo : Magic char closing, locking changes, cleanups
+ * Matt Domsch : nowayout module option
*/
#include <linux/config.h>
#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/fcntl.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
@@ -72,23 +69,18 @@
#define PCI_DEVICE_ID_WDG_CSM 0x22c0
#endif
-static unsigned long wdt_is_open;
+static struct semaphore open_sem;
+static spinlock_t wdtpci_lock;
static int expect_close = 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;
+static int io;
+static int irq;
+/* Default timeout */
#define WD_TIMO (100*60) /* 1 minute */
+#define WD_TIMO_MAX (WD_TIMO*60) /* 1 hour(?) */
-static int timeout_val = WD_TIMO; /* value passed to card */
-static int timeout = 60; /* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=60)");
+static int wd_margin = WD_TIMO;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
@@ -99,43 +91,6 @@ static int nowayout = 0;
MODULE_PARM(nowayout,"i");
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
-static void __init
-wdtpci_validate_timeout(void)
-{
- timeout_val = timeout * 100;
-}
-
-#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
*/
@@ -251,11 +206,15 @@ static void wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void wdtpci_ping(void)
{
+ unsigned long flags;
+
/* Write a watchdog value */
+ spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC);
wdtpci_ctr_mode(1,2);
- wdtpci_ctr_load(1,timeout_val); /* Timeout */
+ wdtpci_ctr_load(1,wd_margin); /* Timeout */
outb_p(0, WDT_DC);
+ spin_unlock_irqrestore(&wdtpci_lock, flags);
}
/**
@@ -275,10 +234,12 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo
if (ppos != &file->f_pos)
return -ESPIPE;
- if(count)
- {
+ if (count) {
if (!nowayout) {
size_t i;
+
+ expect_close = 0;
+
for (i = 0; i != count; i++) {
char c;
if(get_user(c, buf+i))
@@ -288,9 +249,9 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo
}
}
wdtpci_ping();
- return 1;
}
- return 0;
+
+ return count;
}
/**
@@ -342,6 +303,7 @@ static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *p
static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ int new_margin;
static struct watchdog_info ident = {
.options = WDIOF_OVERHEAT | WDIOF_POWERUNDER |
WDIOF_POWEROVER | WDIOF_EXTERN1 |
@@ -366,6 +328,18 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case WDIOC_KEEPALIVE:
wdtpci_ping();
return 0;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_margin, (int *)arg))
+ return -EFAULT;
+ /* Arbitrary, can't find the card's limits */
+ new_margin *= 100;
+ if ((new_margin < 0) || (new_margin > WD_TIMO_MAX))
+ return -EINVAL;
+ wd_margin = new_margin;
+ wdtpci_ping();
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ return put_user(wd_margin / 100, (int *)arg);
}
}
@@ -383,20 +357,22 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
static int wdtpci_open(struct inode *inode, struct file *file)
{
+ unsigned long flags;
+
switch(minor(inode->i_rdev))
{
case WATCHDOG_MINOR:
- if( test_and_set_bit(0,&wdt_is_open) )
- {
+ if (down_trylock(&open_sem))
return -EBUSY;
- }
+
if (nowayout) {
MOD_INC_USE_COUNT;
}
/*
* Activate
*/
-
+ spin_lock_irqsave(&wdtpci_lock, flags);
+
inb_p(WDT_DC); /* Disable */
/*
@@ -418,9 +394,10 @@ static int wdtpci_open(struct inode *inode, struct file *file)
wdtpci_ctr_mode(1,2);
wdtpci_ctr_mode(2,1);
wdtpci_ctr_load(0,20833); /* count at 100Hz */
- wdtpci_ctr_load(1,timeout_val); /* Timeout */
+ wdtpci_ctr_load(1,wd_margin);/* Timeout 60 seconds */
/* DO NOT LOAD CTR2 on PCI card! -- JPN */
outb_p(0, WDT_DC); /* Enable */
+ spin_unlock_irqrestore(&wdtpci_lock, flags);
return 0;
case TEMP_MINOR:
return 0;
@@ -443,13 +420,19 @@ static int wdtpci_open(struct inode *inode, struct file *file)
static int wdtpci_release(struct inode *inode, struct file *file)
{
- if(minor(inode->i_rdev)==WATCHDOG_MINOR)
- {
- if (!nowayout) {
+
+ if (minor(inode->i_rdev)==WATCHDOG_MINOR) {
+ unsigned long flags;
+ if (expect_close) {
+ spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC); /* Disable counters */
wdtpci_ctr_load(2,0); /* 0 length reset pulses now */
+ spin_unlock_irqrestore(&wdtpci_lock, flags);
+ } else {
+ printk(KERN_CRIT PFX "Unexpected close, not stopping timer!");
+ wdtpci_ping();
}
- clear_bit(0, &wdt_is_open );
+ up(&open_sem);
}
return 0;
}
@@ -469,11 +452,14 @@ static int wdtpci_release(struct inode *inode, struct file *file)
static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
- if(code==SYS_DOWN || code==SYS_HALT)
- {
+ unsigned long flags;
+
+ if (code==SYS_DOWN || code==SYS_HALT) {
/* Turn the card off */
+ spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC);
wdtpci_ctr_load(2,0);
+ spin_unlock_irqrestore(&wdtpci_lock, flags);
}
return NOTIFY_DONE;
}
@@ -533,6 +519,9 @@ static int __init wdtpci_init_one (struct pci_dev *dev,
if (pci_enable_device (dev))
goto out;
+ sema_init(&open_sem, 1);
+ spin_lock_init(&wdtpci_lock);
+
irq = dev->irq;
io = pci_resource_start (dev, 2);
printk ("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X "
@@ -650,8 +639,6 @@ static int __init wdtpci_init(void)
if (rc < 1)
return -ENODEV;
-
- wdtpci_validate_timeout();
return 0;
}
diff --git a/drivers/hotplug/acpiphp_glue.c b/drivers/hotplug/acpiphp_glue.c
index 6c16481c4102..7350c4071228 100644
--- a/drivers/hotplug/acpiphp_glue.c
+++ b/drivers/hotplug/acpiphp_glue.c
@@ -712,8 +712,9 @@ find_p2p_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
/* find hot-pluggable slots, and then find P2P bridge */
-static int add_bridges (acpi_handle *handle)
+static int add_bridges(struct acpi_device *device)
{
+ acpi_handle *handle = device->handle;
acpi_status status;
unsigned long tmp;
int seg, bus;
@@ -767,36 +768,6 @@ static int add_bridges (acpi_handle *handle)
}
-/* callback routine to enumerate all the bridges in ACPI namespace */
-static acpi_status
-find_host_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- acpi_status status;
- struct acpi_device_info info;
- char objname[5];
- struct acpi_buffer buffer = { .length = sizeof(objname),
- .pointer = objname };
-
- status = acpi_get_object_info(handle, &info);
- if (ACPI_FAILURE(status)) {
- dbg("%s: failed to get bridge information\n", __FUNCTION__);
- return AE_OK; /* continue */
- }
-
- info.hardware_id[sizeof(info.hardware_id)-1] = '\0';
-
- /* TBD use acpi_get_devices() API */
- if (info.current_status &&
- (info.valid & ACPI_VALID_HID) &&
- strcmp(info.hardware_id, ACPI_PCI_HOST_HID) == 0) {
- acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
- dbg("checking PCI-hotplug capable bridges under [%s]\n", objname);
- add_bridges(handle);
- }
- return AE_OK;
-}
-
-
static int power_on_slot (struct acpiphp_slot *slot)
{
acpi_status status;
@@ -1157,6 +1128,14 @@ static void handle_hotplug_event_func (acpi_handle handle, u32 type, void *conte
}
}
+static struct acpi_driver acpi_pci_hp_driver = {
+ .name = "pci_hp",
+ .class = "",
+ .ids = ACPI_PCI_HOST_HID,
+ .ops = {
+ .add = add_bridges,
+ }
+};
/**
* acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
@@ -1169,9 +1148,7 @@ int acpiphp_glue_init (void)
if (list_empty(&pci_root_buses))
return -1;
- status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, find_host_bridge,
- NULL, NULL);
+ status = acpi_bus_register_driver(&acpi_pci_hp_driver);
if (ACPI_FAILURE(status)) {
err("%s: acpi_walk_namespace() failed\n", __FUNCTION__);
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index cd971f0d27b0..27d327707358 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -768,7 +768,7 @@ static void sunsab_set_termios(struct uart_port *port, struct termios *termios,
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
unsigned long flags;
- int baud = uart_get_baud_rate(port, termios);
+ int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
spin_lock_irqsave(&up->port.lock, flags);
sunsab_convert_to_sab(up, termios->c_cflag, termios->c_iflag, baud);
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 377e6ba931e9..c4d53718daa8 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -417,7 +417,7 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
struct buffer_head *bitmap_bh = NULL;
struct buffer_head *bh2;
int group;
- ino_t ino;
+ unsigned long ino;
struct inode * inode;
struct ext3_group_desc * gdp;
struct ext3_super_block * es;
@@ -463,7 +463,7 @@ repeat:
BUFFER_TRACE(bitmap_bh, "get_write_access");
err = ext3_journal_get_write_access(handle, bitmap_bh);
if (err) goto fail;
-
+
if (ext3_set_bit(ino, bitmap_bh->b_data)) {
ext3_error (sb, "ext3_new_inode",
"bit already set for inode %lu", ino);
@@ -619,19 +619,18 @@ fail2:
}
/* Verify that we are loading a valid orphan from disk */
-struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino)
+struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
{
- ino_t max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
+ unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
unsigned long block_group;
int bit;
struct buffer_head *bitmap_bh = NULL;
struct inode *inode = NULL;
-
+
/* Error cases - e2fsck has already cleaned up for us */
if (ino > max_ino) {
ext3_warning(sb, __FUNCTION__,
- "bad orphan ino %lu! e2fsck was run?\n",
- (unsigned long) ino);
+ "bad orphan ino %lu! e2fsck was run?\n", ino);
goto out;
}
@@ -640,8 +639,7 @@ struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino)
bitmap_bh = read_inode_bitmap(sb, block_group);
if (!bitmap_bh) {
ext3_warning(sb, __FUNCTION__,
- "inode bitmap error for orphan %lu\n",
- (unsigned long) ino);
+ "inode bitmap error for orphan %lu\n", ino);
goto out;
}
@@ -653,19 +651,17 @@ struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino)
!(inode = iget(sb, ino)) || is_bad_inode(inode) ||
NEXT_ORPHAN(inode) > max_ino) {
ext3_warning(sb, __FUNCTION__,
- "bad orphan inode %lu! e2fsck was run?\n", (unsigned long)ino);
+ "bad orphan inode %lu! e2fsck was run?\n", ino);
printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
- bit,
- (unsigned long long)bitmap_bh->b_blocknr,
- ext3_test_bit(bit, bitmap_bh->b_data));
+ bit, (unsigned long long)bitmap_bh->b_blocknr,
+ ext3_test_bit(bit, bitmap_bh->b_data));
printk(KERN_NOTICE "inode=%p\n", inode);
if (inode) {
printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
is_bad_inode(inode));
- printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%d\n",
+ printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
NEXT_ORPHAN(inode));
- printk(KERN_NOTICE "max_ino=%lu\n",
- (unsigned long) max_ino);
+ printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
}
/* Avoid freeing blocks if we got a bad deleted inode */
if (inode && inode->i_nlink == 0)
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index a5e85ef29d2c..ccdb52c9cc77 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1098,20 +1098,14 @@ out:
return ret;
}
-static int journal_dirty_sync_data(handle_t *handle, struct buffer_head *bh)
-{
- return ext3_journal_dirty_data(handle, bh, 0);
-}
-
-/*
- * For ext3_writepage(). We also brelse() the buffer to account for
- * the bget() which ext3_writepage() performs.
- */
-static int journal_dirty_async_data(handle_t *handle, struct buffer_head *bh)
+static int
+ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
{
- int ret = ext3_journal_dirty_data(handle, bh, 1);
- __brelse(bh);
- return ret;
+ int err = journal_dirty_data(handle, bh);
+ if (err)
+ ext3_journal_abort_handle(__FUNCTION__, __FUNCTION__,
+ bh, handle,err);
+ return err;
}
/* For commit_write() in data=journal mode */
@@ -1154,7 +1148,7 @@ static int ext3_commit_write(struct file *file, struct page *page,
} else {
if (ext3_should_order_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
- from, to, NULL, journal_dirty_sync_data);
+ from, to, NULL, ext3_journal_dirty_data);
}
/* Be careful here if generic_commit_write becomes a
* required invocation after block_prepare_write. */
@@ -1228,7 +1222,13 @@ static sector_t ext3_bmap(struct address_space *mapping, sector_t block)
static int bget_one(handle_t *handle, struct buffer_head *bh)
{
- atomic_inc(&bh->b_count);
+ get_bh(bh);
+ return 0;
+}
+
+static int bput_one(handle_t *handle, struct buffer_head *bh)
+{
+ put_bh(bh);
return 0;
}
@@ -1348,7 +1348,9 @@ static int ext3_writepage(struct page *page, struct writeback_control *wbc)
/* And attach them to the current transaction */
if (order_data) {
err = walk_page_buffers(handle, page_bufs,
- 0, PAGE_CACHE_SIZE, NULL, journal_dirty_async_data);
+ 0, PAGE_CACHE_SIZE, NULL, ext3_journal_dirty_data);
+ walk_page_buffers(handle, page_bufs, 0,
+ PAGE_CACHE_SIZE, NULL, bput_one);
if (!ret)
ret = err;
}
@@ -1587,7 +1589,7 @@ static int ext3_block_truncate_page(handle_t *handle,
err = ext3_journal_dirty_metadata(handle, bh);
} else {
if (ext3_should_order_data(inode))
- err = ext3_journal_dirty_data(handle, bh, 0);
+ err = ext3_journal_dirty_data(handle, bh);
mark_buffer_dirty(bh);
}
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 630dbff4001c..055dee6f64c8 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1871,10 +1871,10 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
struct list_head *prev;
struct ext3_inode_info *ei = EXT3_I(inode);
struct ext3_sb_info *sbi;
- ino_t ino_next;
+ unsigned long ino_next;
struct ext3_iloc iloc;
int err = 0;
-
+
lock_super(inode->i_sb);
if (list_empty(&ei->i_orphan)) {
unlock_super(inode->i_sb);
@@ -1885,7 +1885,7 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
prev = ei->i_orphan.prev;
sbi = EXT3_SB(inode->i_sb);
- jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
+ jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
list_del_init(&ei->i_orphan);
@@ -1895,13 +1895,13 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
* list in memory. */
if (!handle)
goto out;
-
+
err = ext3_reserve_inode_write(handle, inode, &iloc);
if (err)
goto out_err;
if (prev == &sbi->s_orphan) {
- jbd_debug(4, "superblock will point to %ld\n", ino_next);
+ jbd_debug(4, "superblock will point to %lu\n", ino_next);
BUFFER_TRACE(sbi->s_sbh, "get_write_access");
err = ext3_journal_get_write_access(handle, sbi->s_sbh);
if (err)
@@ -1912,8 +1912,8 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
struct ext3_iloc iloc2;
struct inode *i_prev =
&list_entry(prev, struct ext3_inode_info, i_orphan)->vfs_inode;
-
- jbd_debug(4, "orphan inode %ld will point to %ld\n",
+
+ jbd_debug(4, "orphan inode %lu will point to %lu\n",
i_prev->i_ino, ino_next);
err = ext3_reserve_inode_write(handle, i_prev, &iloc2);
if (err)
@@ -1928,7 +1928,7 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
if (err)
goto out_brelse;
-out_err:
+out_err:
ext3_std_error(inode->i_sb, err);
out:
unlock_super(inode->i_sb);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 204e264a1783..bb8bf302da95 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -457,11 +457,8 @@ static struct address_space_operations hugetlbfs_aops = {
};
struct file_operations hugetlbfs_file_operations = {
- .read = generic_file_read,
- .write = generic_file_write,
.mmap = hugetlbfs_file_mmap,
.fsync = simple_sync_file,
- .sendfile = generic_file_sendfile,
};
static struct inode_operations hugetlbfs_dir_inode_operations = {
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index d640e23a1bf1..79b606822382 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -585,7 +585,6 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
J_ASSERT (transaction->t_ilist == NULL);
J_ASSERT (transaction->t_buffers == NULL);
J_ASSERT (transaction->t_sync_datalist == NULL);
- J_ASSERT (transaction->t_async_datalist == NULL);
J_ASSERT (transaction->t_forget == NULL);
J_ASSERT (transaction->t_iobuf_list == NULL);
J_ASSERT (transaction->t_shadow_list == NULL);
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index f61bce34d072..12d4a744f07f 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -264,37 +264,6 @@ write_out_data_locked:
goto write_out_data_locked;
sync_datalist_empty:
- /*
- * Wait for all the async writepage data. As they become unlocked
- * in end_buffer_async_write(), the only place where they can be
- * reaped is in try_to_free_buffers(), and we're locked against
- * that.
- */
- while ((jh = commit_transaction->t_async_datalist)) {
- struct buffer_head *bh = jh2bh(jh);
- if (buffer_locked(bh)) {
- spin_unlock(&journal_datalist_lock);
- unlock_journal(journal);
- wait_on_buffer(bh);
- lock_journal(journal);
- spin_lock(&journal_datalist_lock);
- continue; /* List may have changed */
- }
- if (jh->b_next_transaction) {
- /*
- * For writepage() buffers in journalled data mode: a
- * later transaction may want the buffer for "metadata"
- */
- __journal_refile_buffer(jh);
- } else {
- BUFFER_TRACE(bh, "finished async writeout: unfile");
- __journal_unfile_buffer(jh);
- jh->b_transaction = NULL;
- __journal_remove_journal_head(bh);
- BUFFER_TRACE(bh, "finished async writeout: refile");
- __brelse(bh);
- }
- }
spin_unlock(&journal_datalist_lock);
/*
@@ -304,7 +273,6 @@ sync_datalist_empty:
* clean by now, so check that it is in fact empty.
*/
J_ASSERT (commit_transaction->t_sync_datalist == NULL);
- J_ASSERT (commit_transaction->t_async_datalist == NULL);
jbd_debug (3, "JBD: commit phase 3\n");
@@ -629,7 +597,6 @@ skip_commit: /* The journal should be unlocked by now. */
jbd_debug(3, "JBD: commit phase 7\n");
J_ASSERT(commit_transaction->t_sync_datalist == NULL);
- J_ASSERT(commit_transaction->t_async_datalist == NULL);
J_ASSERT(commit_transaction->t_buffers == NULL);
J_ASSERT(commit_transaction->t_checkpoint_list == NULL);
J_ASSERT(commit_transaction->t_iobuf_list == NULL);
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index f7e4c3a0c627..e62a542396a6 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -578,9 +578,6 @@ static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
* part of the transaction, that is).
*
* Returns an error code or 0 on success.
- *
- * In full data journalling mode the buffer may be of type BJ_AsyncData,
- * because we're write()ing a buffer which is also part of a shared mapping.
*/
static int
@@ -949,26 +946,16 @@ out:
* The buffer is placed on the transaction's data list and is marked as
* belonging to the transaction.
*
- * If `async' is set then the writebabk will be initiated by the caller
- * using submit_bh -> end_buffer_async_write. We put the buffer onto
- * t_async_datalist.
- *
* Returns error number or 0 on success.
*
* journal_dirty_data() can be called via page_launder->ext3_writepage
* by kswapd. So it cannot block. Happily, there's nothing here
* which needs lock_journal if `async' is set.
- *
- * When the buffer is on the current transaction we freely move it
- * between BJ_AsyncData and BJ_SyncData according to who tried to
- * change its state last.
*/
-
-int journal_dirty_data (handle_t *handle, struct buffer_head *bh, int async)
+int journal_dirty_data (handle_t *handle, struct buffer_head *bh)
{
journal_t *journal = handle->h_transaction->t_journal;
int need_brelse = 0;
- int wanted_jlist = async ? BJ_AsyncData : BJ_SyncData;
struct journal_head *jh;
if (is_handle_aborted(handle))
@@ -1046,8 +1033,7 @@ int journal_dirty_data (handle_t *handle, struct buffer_head *bh, int async)
* the write() data.
*/
if (jh->b_jlist != BJ_None &&
- jh->b_jlist != BJ_SyncData &&
- jh->b_jlist != BJ_AsyncData) {
+ jh->b_jlist != BJ_SyncData) {
JBUFFER_TRACE(jh, "Not stealing");
goto no_journal;
}
@@ -1058,7 +1044,7 @@ int journal_dirty_data (handle_t *handle, struct buffer_head *bh, int async)
* again because that can cause the write-out loop in
* commit to never terminate.
*/
- if (!async && buffer_dirty(bh)) {
+ if (buffer_dirty(bh)) {
atomic_inc(&bh->b_count);
spin_unlock(&journal_datalist_lock);
need_brelse = 1;
@@ -1084,18 +1070,18 @@ int journal_dirty_data (handle_t *handle, struct buffer_head *bh, int async)
* committing transaction, so might still be left on that
* transaction's metadata lists.
*/
- if (jh->b_jlist != wanted_jlist) {
+ if (jh->b_jlist != BJ_SyncData) {
JBUFFER_TRACE(jh, "not on correct data list: unfile");
J_ASSERT_JH(jh, jh->b_jlist != BJ_Shadow);
__journal_unfile_buffer(jh);
jh->b_transaction = NULL;
JBUFFER_TRACE(jh, "file as data");
__journal_file_buffer(jh, handle->h_transaction,
- wanted_jlist);
+ BJ_SyncData);
}
} else {
JBUFFER_TRACE(jh, "not on a transaction");
- __journal_file_buffer(jh, handle->h_transaction, wanted_jlist);
+ __journal_file_buffer(jh, handle->h_transaction, BJ_SyncData);
}
no_journal:
spin_unlock(&journal_datalist_lock);
@@ -1559,12 +1545,12 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh)
* Remove a buffer from the appropriate transaction list.
*
* Note that this function can *change* the value of
- * bh->b_transaction->t_sync_datalist, t_async_datalist, t_buffers, t_forget,
+ * bh->b_transaction->t_sync_datalist, t_buffers, t_forget,
* t_iobuf_list, t_shadow_list, t_log_list or t_reserved_list. If the caller
* is holding onto a copy of one of thee pointers, it could go bad.
* Generally the caller needs to re-read the pointer from the transaction_t.
*
- * If bh->b_jlist is BJ_SyncData or BJ_AsyncData then we may have been called
+ * If bh->b_jlist is BJ_SyncData then we may have been called
* via journal_try_to_free_buffer() or journal_clean_data_list(). In that
* case, journal_datalist_lock will be held, and the journal may not be locked.
*/
@@ -1590,9 +1576,6 @@ void __journal_unfile_buffer(struct journal_head *jh)
case BJ_SyncData:
list = &transaction->t_sync_datalist;
break;
- case BJ_AsyncData:
- list = &transaction->t_async_datalist;
- break;
case BJ_Metadata:
transaction->t_nr_buffers--;
J_ASSERT_JH(jh, transaction->t_nr_buffers >= 0);
@@ -1658,7 +1641,7 @@ static inline int __journal_try_to_free_buffer(struct buffer_head *bh)
goto out;
if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
- if (jh->b_jlist == BJ_SyncData || jh->b_jlist==BJ_AsyncData) {
+ if (jh->b_jlist == BJ_SyncData) {
/* A written-back ordered data buffer */
JBUFFER_TRACE(jh, "release data");
__journal_unfile_buffer(jh);
@@ -1994,9 +1977,6 @@ void __journal_file_buffer(struct journal_head *jh,
case BJ_SyncData:
list = &transaction->t_sync_datalist;
break;
- case BJ_AsyncData:
- list = &transaction->t_async_datalist;
- break;
case BJ_Metadata:
transaction->t_nr_buffers++;
list = &transaction->t_buffers;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 089790f3b34a..62af20aecec2 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -221,7 +221,6 @@ out_fail:
int proc_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * root_inode;
- struct task_struct *p;
s->s_blocksize = 1024;
s->s_blocksize_bits = 10;
@@ -234,11 +233,7 @@ int proc_fill_super(struct super_block *s, void *data, int silent)
/*
* Fixup the root inode's nlink value
*/
- read_lock(&tasklist_lock);
- for_each_process(p)
- if (p->pid)
- root_inode->i_nlink++;
- read_unlock(&tasklist_lock);
+ root_inode->i_nlink += nr_processes();
s->s_root = d_alloc_root(root_inode);
if (!s->s_root)
goto out_no_root;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index fff23ee7ca2b..ba036340fcd1 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -140,9 +140,10 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
struct page_state ps;
unsigned long inactive;
unsigned long active;
+ unsigned long free;
get_page_state(&ps);
- get_zone_counts(&active, &inactive);
+ get_zone_counts(&active, &inactive, &free);
/*
* display in kilobytes.
diff --git a/fs/xfs/linux/xfs_linux.h b/fs/xfs/linux/xfs_linux.h
index efcff94b19dd..70496e24ff69 100644
--- a/fs/xfs/linux/xfs_linux.h
+++ b/fs/xfs/linux/xfs_linux.h
@@ -42,6 +42,7 @@
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/major.h>
+#include <linux/pagemap.h>
#include <linux/vfs.h>
#include <asm/page.h>
@@ -169,7 +170,6 @@ typedef struct xfs_dirent { /* data from readdir() */
#define DEFAULT_PROJID 0
#define dfltprid DEFAULT_PROJID
-#define MAXNAMELEN 256
#define MAXPATHLEN 1024
#define FINVIS 0x0100 /* don't update timestamps - XFS */
diff --git a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
index b1fed677d5ed..d08561facca0 100644
--- a/fs/xfs/linux/xfs_lrw.c
+++ b/fs/xfs/linux/xfs_lrw.c
@@ -872,13 +872,12 @@ XFS_log_write_unmount_ro(bhv_desc_t *bdp)
int error;
mp = XFS_BHVTOM(bdp);
- xfs_binval(mp->m_ddev_targp);
+ pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT, &pincount);
+ xfs_finish_reclaim_all(mp);
do {
- xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC);
VFS_SYNC(XFS_MTOVFS(mp), SYNC_ATTR|SYNC_WAIT, NULL, error);
- pagebuf_delwri_flush(mp->m_ddev_targp,
- PBDF_WAIT, &pincount);
+ pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT, &pincount);
if (pincount == 0) {delay(50); count++;}
} while (count < 2);
diff --git a/fs/xfs/linux/xfs_vnode.h b/fs/xfs/linux/xfs_vnode.h
index 5e094d8bc810..abd56b0bc175 100644
--- a/fs/xfs/linux/xfs_vnode.h
+++ b/fs/xfs/linux/xfs_vnode.h
@@ -671,13 +671,14 @@ extern void vn_rele(struct vnode *);
#define VN_HOLD(vp) ((void)vn_hold(vp))
#define VN_RELE(vp) (iput(LINVFS_GET_IP(vp)))
-#endif /* ! (defined(CONFIG_XFS_VNODE_TRACING) */
+#endif /* ! (defined(CONFIG_XFS_VNODE_TRACING)) */
/*
* Vname handling macros.
*/
#define VNAME(dentry) ((char *) (dentry)->d_name.name)
#define VNAMELEN(dentry) ((dentry)->d_name.len)
+#define VNAME_TO_VNODE(dentry) (LINVFS_GET_VP((dentry)->d_inode))
/*
* Vnode spinlock manipulation.
diff --git a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
index 76f6d213b013..905dfcf757a6 100644
--- a/fs/xfs/pagebuf/page_buf.c
+++ b/fs/xfs/pagebuf/page_buf.c
@@ -1108,7 +1108,7 @@ _pagebuf_wait_unpin(
* pagebuf_iodone
*
* pagebuf_iodone marks a buffer for which I/O is in progress
- * done with respect to that I/O. The pb_done routine, if
+ * done with respect to that I/O. The pb_iodone routine, if
* present, will be called as a side-effect.
*/
void
@@ -1173,7 +1173,7 @@ pagebuf_ioerror( /* mark/clear buffer error flag */
* pagebuf_iostart initiates I/O on a buffer, based on the flags supplied.
* If necessary, it will arrange for any disk space allocation required,
* and it will break up the request if the block mappings require it.
- * An pb_iodone routine in the buffer supplied will only be called
+ * The pb_iodone routine in the buffer supplied will only be called
* when all of the subsidiary I/O requests, if any, have been completed.
* pagebuf_iostart calls the pagebuf_ioinitiate routine or
* pagebuf_iorequest, if the former routine is not defined, to start
@@ -1317,7 +1317,7 @@ pagebuf_iorequest( /* start real I/O */
/* Set the count to 1 initially, this will stop an I/O
* completion callout which happens before we have started
- * all the I/O from calling iodone too early
+ * all the I/O from calling pagebuf_iodone too early.
*/
atomic_set(&pb->pb_io_remaining, 1);
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index d6fe5d8b6983..cbedf29d7586 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -41,7 +41,10 @@ static char message[256]; /* keep it off the stack */
static spinlock_t xfs_err_lock = SPIN_LOCK_UNLOCKED;
/* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */
-static char *err_level[8] = {KERN_EMERG, KERN_ALERT, KERN_CRIT,
+#define XFS_MAX_ERR_LEVEL 7
+#define XFS_ERR_MASK ((1 << 3) - 1)
+static char *err_level[XFS_MAX_ERR_LEVEL+1] =
+ {KERN_EMERG, KERN_ALERT, KERN_CRIT,
KERN_ERR, KERN_WARNING, KERN_NOTICE,
KERN_INFO, KERN_DEBUG};
@@ -82,15 +85,22 @@ void
cmn_err(register int level, char *fmt, ...)
{
char *fp = fmt;
- va_list ap;
+ int len;
+ int flags;
+ va_list ap;
- spin_lock(&xfs_err_lock);
+ level &= XFS_ERR_MASK;
+ if (level > XFS_MAX_ERR_LEVEL)
+ level = XFS_MAX_ERR_LEVEL;
+ spin_lock_irqsave(&xfs_err_lock,flags);
va_start(ap, fmt);
if (*fmt == '!') fp++;
- vsprintf(message, fp, ap);
- printk("%s%s\n", err_level[level], message);
+ len = vsprintf(message, fp, ap);
+ if (message[len-1] != '\n')
+ strcat(message, "\n");
+ printk("%s%s", err_level[level], message);
va_end(ap);
- spin_unlock(&xfs_err_lock);
+ spin_unlock_irqrestore(&xfs_err_lock,flags);
if (level == CE_PANIC)
BUG();
@@ -100,10 +110,18 @@ cmn_err(register int level, char *fmt, ...)
void
icmn_err(register int level, char *fmt, va_list ap)
{
- spin_lock(&xfs_err_lock);
- vsprintf(message, fmt, ap);
- spin_unlock(&xfs_err_lock);
- printk("%s%s\n", err_level[level], message);
+ int len;
+ int flags;
+
+ level &= XFS_ERR_MASK;
+ if(level > XFS_MAX_ERR_LEVEL)
+ level = XFS_MAX_ERR_LEVEL;
+ spin_lock_irqsave(&xfs_err_lock,flags);
+ len = vsprintf(message, fmt, ap);
+ if (message[len-1] != '\n')
+ strcat(message, "\n");
+ spin_unlock_irqrestore(&xfs_err_lock,flags);
+ printk("%s%s", err_level[level], message);
if (level == CE_PANIC)
BUG();
}
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
index ddb243978027..0631c9c1deb3 100644
--- a/fs/xfs/xfs_dir.c
+++ b/fs/xfs/xfs_dir.c
@@ -386,9 +386,6 @@ xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
int retval;
ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
- if (namelen >= MAXNAMELEN) {
- return(XFS_ERROR(EINVAL));
- }
XFS_STATS_INC(xfsstats.xs_dir_lookup);
/*
@@ -479,9 +476,6 @@ xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
int retval;
ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
- if (namelen >= MAXNAMELEN) {
- return(XFS_ERROR(EINVAL));
- }
if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
return retval;
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index b47e2a939415..766cbdfa4099 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -232,10 +232,8 @@ xfs_dir2_lookup(
int v; /* type-checking value */
ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
- if (namelen >= MAXNAMELEN) {
- return XFS_ERROR(EINVAL);
- }
XFS_STATS_INC(xfsstats.xs_dir_lookup);
+
/*
* Fill in the arg structure for this request.
*/
@@ -395,9 +393,7 @@ xfs_dir2_replace(
int v; /* type-checking value */
ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
- if (namelen >= MAXNAMELEN) {
- return XFS_ERROR(EINVAL);
- }
+
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
return rval;
}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index d0720edd79cd..79227f00b1a1 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -414,11 +414,9 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
* max file offset is 2^(31+PAGE_SHIFT) - 1 (due to linux page cache)
*
* NOTE: XFS itself can handle 2^63 - 1 (largest positive value of xfs_fsize_t)
- * but Linux can't go above 2^(31+PAGE_SHIFT)-1: the Linux VM uses a 32 bit
- * signed variable to index cache data, so 2^31 * PAGE_SIZE is as big as
- * you can go.
+ * but this is the Linux limit.
*/
-#define XFS_MAX_FILE_OFFSET ((long long)((1ULL<<(31+PAGE_SHIFT))-1ULL))
+#define XFS_MAX_FILE_OFFSET MAX_LFS_FILESIZE
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ITOV)
struct vnode *xfs_itov(xfs_inode_t *ip);
@@ -483,6 +481,7 @@ void xfs_iunlock_map_shared(xfs_inode_t *, uint);
void xfs_ifunlock(xfs_inode_t *);
void xfs_ireclaim(xfs_inode_t *);
int xfs_finish_reclaim(xfs_inode_t *, int, int);
+int xfs_finish_reclaim_all(struct xfs_mount *);
/*
* xfs_inode.c prototypes.
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 9a72b4036048..617eead8f16d 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2952,7 +2952,6 @@ xlog_recover_process_iunlinks(xlog_t *log)
if (!error) {
ASSERT(ip->i_d.di_nlink == 0);
- ASSERT(ip->i_d.di_mode != 0);
/* setup for the next pass */
agino = INT_GET(dip->di_next_unlinked,
@@ -2970,7 +2969,9 @@ xlog_recover_process_iunlinks(xlog_t *log)
ip->i_d.di_dmevmask = 0;
/*
- * Drop our reference to the
+ * If this is a new inode, handle
+ * it specially. Otherwise,
+ * just drop our reference to the
* inode. If there are no
* other references, this will
* send the inode to
@@ -2978,7 +2979,10 @@ xlog_recover_process_iunlinks(xlog_t *log)
* truncate the file and free
* the inode.
*/
- VN_RELE(XFS_ITOV(ip));
+ if (ip->i_d.di_mode == 0)
+ xfs_iput_new(ip, 0);
+ else
+ VN_RELE(XFS_ITOV(ip));
} else {
/*
* We can't read in the inode
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index f329e8133bf1..aad9dbbcc205 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -72,14 +72,13 @@ int xfs_rename_skip, xfs_rename_nskip;
* We are renaming dp1/name1 to dp2/name2.
*
* Return ENOENT if dp1 does not exist, other lookup errors, or 0 for success.
- * Return EAGAIN if the caller needs to try again.
*/
STATIC int
xfs_lock_for_rename(
xfs_inode_t *dp1, /* old (source) directory inode */
xfs_inode_t *dp2, /* new (target) directory inode */
- vname_t *dentry1, /* old entry name */
- vname_t *dentry2, /* new entry name */
+ vname_t *vname1,/* old entry name */
+ vname_t *vname2,/* new entry name */
xfs_inode_t **ipp1, /* inode of old entry */
xfs_inode_t **ipp2, /* inode of new entry, if it
already exists, NULL otherwise. */
@@ -102,7 +101,7 @@ xfs_lock_for_rename(
* to see if we still have the right inodes, directories, etc.
*/
lock_mode = xfs_ilock_map_shared(dp1);
- error = xfs_get_dir_entry(dentry1, &ip1);
+ error = xfs_get_dir_entry(vname1, &ip1);
if (error) {
xfs_iunlock_map_shared(dp1, lock_mode);
return error;
@@ -123,7 +122,7 @@ xfs_lock_for_rename(
}
error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode,
- dentry2, &inum2, &ip2);
+ vname2, &inum2, &ip2);
if (error == ENOENT) { /* target does not need to exist. */
inum2 = 0;
} else if (error) {
@@ -213,20 +212,15 @@ xfs_lock_for_rename(
int rename_which_error_return = 0;
-#ifdef DEBUG
-int xfs_rename_agains;
-int xfs_renames;
-#endif
-
/*
* xfs_rename
*/
int
xfs_rename(
bhv_desc_t *src_dir_bdp,
- vname_t *src_dentry,
+ vname_t *src_vname,
vnode_t *target_dir_vp,
- vname_t *target_dentry,
+ vname_t *target_vname,
cred_t *credp)
{
xfs_trans_t *tp;
@@ -246,15 +240,11 @@ xfs_rename(
int spaceres;
int target_link_zero = 0;
int num_inodes;
- char *src_name = VNAME(src_dentry);
- char *target_name = VNAME(target_dentry);
- int src_namelen;
- int target_namelen;
-#ifdef DEBUG
- int retries;
+ char *src_name = VNAME(src_vname);
+ char *target_name = VNAME(target_vname);
+ int src_namelen = VNAMELEN(src_vname);
+ int target_namelen = VNAMELEN(target_vname);
- xfs_renames++;
-#endif
src_dir_vp = BHV_TO_VNODE(src_dir_bdp);
vn_trace_entry(src_dir_vp, "xfs_rename", (inst_t *)__return_address);
vn_trace_entry(target_dir_vp, "xfs_rename", (inst_t *)__return_address);
@@ -268,14 +258,10 @@ xfs_rename(
if (target_dir_bdp == NULL) {
return XFS_ERROR(EXDEV);
}
- src_namelen = VNAMELEN(src_dentry);
- if (src_namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
- target_namelen = VNAMELEN(target_dentry);
- if (target_namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
+
src_dp = XFS_BHVTOI(src_dir_bdp);
target_dp = XFS_BHVTOI(target_dir_bdp);
+
if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
target_dp, DM_EVENT_RENAME)) {
@@ -290,9 +276,6 @@ xfs_rename(
}
/* Return through std_return after this point. */
-#ifdef DEBUG
- retries = 0;
-#endif
/*
* Lock all the participating inodes. Depending upon whether
* the target_name exists in the target directory, and
@@ -302,15 +285,9 @@ xfs_rename(
* does not exist in the source directory.
*/
tp = NULL;
- do {
- error = xfs_lock_for_rename(src_dp, target_dp, src_dentry,
- target_dentry, &src_ip, &target_ip, inodes,
- &num_inodes);
-#ifdef DEBUG
- if (error == EAGAIN)
- xfs_rename_agains++;
-#endif
- } while (error == EAGAIN);
+ error = xfs_lock_for_rename(src_dp, target_dp, src_vname,
+ target_vname, &src_ip, &target_ip, inodes,
+ &num_inodes);
if (error) {
rename_which_error_return = __LINE__;
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 380f14d076eb..9059b4261e89 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -47,9 +47,7 @@ xfs_get_dir_entry(
vnode_t *vp;
bhv_desc_t *bdp;
- ASSERT(dentry->d_inode);
-
- vp = LINVFS_GET_VP(dentry->d_inode);
+ vp = VNAME_TO_VNODE(dentry);
bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);
if (!bdp) {
*ipp = NULL;
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index a7e011fdd76a..f86e0f65def0 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -926,7 +926,7 @@ xfs_syncsub(
IPOINTER_CLR; \
}
-#define PREEMPT_MASK 0x7f
+#define XFS_PREEMPT_MASK 0x7f
if (bypassed)
*bypassed = 0;
@@ -1395,7 +1395,7 @@ xfs_syncsub(
* if we have looped many times without dropping the
* lock.
*/
- if ((++preempt & PREEMPT_MASK) == 0) {
+ if ((++preempt & XFS_PREEMPT_MASK) == 0) {
if (mount_locked) {
IPOINTER_INSERT(ip, mp);
}
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 10a84831f40d..c1b5ad834e2c 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -82,7 +82,7 @@ xfs_open(
/*
* xfs_getattr
*/
-int
+STATIC int
xfs_getattr(
bhv_desc_t *bdp,
vattr_t *vap,
@@ -1935,8 +1935,6 @@ xfs_create(
dm_di_mode = vap->va_mode|VTTOIF(vap->va_type);
namelen = VNAMELEN(dentry);
- if (namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
error = dm_send_namesp_event(DM_EVENT_CREATE,
@@ -2433,8 +2431,7 @@ xfs_remove(
return XFS_ERROR(EIO);
namelen = VNAMELEN(dentry);
- if (namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
+
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
error = dm_send_namesp_event(DM_EVENT_REMOVE, dir_bdp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
@@ -2668,8 +2665,6 @@ xfs_link(
vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
target_namelen = VNAMELEN(dentry);
- if (target_namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
if (src_vp->v_type == VDIR)
return XFS_ERROR(EPERM);
@@ -2857,8 +2852,6 @@ xfs_mkdir(
return XFS_ERROR(EIO);
dir_namelen = VNAMELEN(dentry);
- if (dir_namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
tp = NULL;
dp_joined_to_trans = B_FALSE;
@@ -3100,8 +3093,6 @@ xfs_rmdir(
if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount))
return XFS_ERROR(EIO);
namelen = VNAMELEN(dentry);
- if (namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
error = dm_send_namesp_event(DM_EVENT_REMOVE,
@@ -3415,8 +3406,7 @@ xfs_symlink(
return XFS_ERROR(EIO);
link_namelen = VNAMELEN(dentry);
- if (link_namelen >= MAXNAMELEN)
- return XFS_ERROR(ENAMETOOLONG);
+
/*
* Check component lengths of the target path name.
*/
@@ -4070,6 +4060,49 @@ xfs_finish_reclaim(
return 0;
}
+int
+xfs_finish_reclaim_all(xfs_mount_t *mp)
+{
+ int purged;
+ xfs_inode_t *ip;
+ vnode_t *vp;
+ int done = 0;
+
+ while (!done) {
+ purged = 0;
+ XFS_MOUNT_ILOCK(mp);
+ ip = mp->m_inodes;
+ if (ip == NULL) {
+ break;
+ }
+ do {
+ /* Make sure we skip markers inserted by sync */
+ if (ip->i_mount == NULL) {
+ ip = ip->i_mnext;
+ continue;
+ }
+
+ /*
+ * It's up to our caller to purge the root
+ * and quota vnodes later.
+ */
+ vp = XFS_ITOV_NULL(ip);
+
+ if (!vp) {
+ XFS_MOUNT_IUNLOCK(mp);
+ xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
+ purged = 1;
+ break;
+ }
+ } while (ip != mp->m_inodes);
+
+ done = !purged;
+ }
+
+ XFS_MOUNT_IUNLOCK(mp);
+ return 0;
+}
+
/*
* xfs_alloc_file_space()
* This routine allocates disk space for the given file.
diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h
index e872974aa009..79204592dd68 100644
--- a/include/asm-arm/ide.h
+++ b/include/asm-arm/ide.h
@@ -36,8 +36,6 @@
* The following are not needed for the non-m68k ports
*/
#define ide_ack_intr(hwif) (1)
-#define ide_release_lock(lock) do {} while (0)
-#define ide_get_lock(lock, hdlr, data) do {} while (0)
#endif /* __KERNEL__ */
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index a5dc6bb96720..4aaab2f3bb00 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -1,7 +1,7 @@
/*
* linux/include/asm-arm/unistd.h
*
- * Copyright (C) 2001 Russell King
+ * Copyright (C) 2001-2003 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -32,7 +32,7 @@
#define __NR_write (__NR_SYSCALL_BASE+ 4)
#define __NR_open (__NR_SYSCALL_BASE+ 5)
#define __NR_close (__NR_SYSCALL_BASE+ 6)
-#define __NR_waitpid (__NR_SYSCALL_BASE+ 7)
+#define __NR_waitpid (__NR_SYSCALL_BASE+ 7) /* removed */
#define __NR_creat (__NR_SYSCALL_BASE+ 8)
#define __NR_link (__NR_SYSCALL_BASE+ 9)
#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
@@ -42,8 +42,8 @@
#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
-#define __NR_break (__NR_SYSCALL_BASE+ 17)
-
+#define __NR_break (__NR_SYSCALL_BASE+ 17) /* removed */
+ /* 18 was sys_stat */
#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
#define __NR_mount (__NR_SYSCALL_BASE+ 21)
@@ -56,11 +56,11 @@
#define __NR_pause (__NR_SYSCALL_BASE+ 29)
#define __NR_utime (__NR_SYSCALL_BASE+ 30)
-#define __NR_stty (__NR_SYSCALL_BASE+ 31)
-#define __NR_gtty (__NR_SYSCALL_BASE+ 32)
+#define __NR_stty (__NR_SYSCALL_BASE+ 31) /* removed */
+#define __NR_gtty (__NR_SYSCALL_BASE+ 32) /* removed */
#define __NR_access (__NR_SYSCALL_BASE+ 33)
#define __NR_nice (__NR_SYSCALL_BASE+ 34)
-#define __NR_ftime (__NR_SYSCALL_BASE+ 35)
+#define __NR_ftime (__NR_SYSCALL_BASE+ 35) /* removed */
#define __NR_sync (__NR_SYSCALL_BASE+ 36)
#define __NR_kill (__NR_SYSCALL_BASE+ 37)
#define __NR_rename (__NR_SYSCALL_BASE+ 38)
@@ -69,22 +69,22 @@
#define __NR_dup (__NR_SYSCALL_BASE+ 41)
#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
#define __NR_times (__NR_SYSCALL_BASE+ 43)
-#define __NR_prof (__NR_SYSCALL_BASE+ 44)
+#define __NR_prof (__NR_SYSCALL_BASE+ 44) /* removed */
#define __NR_brk (__NR_SYSCALL_BASE+ 45)
#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
-#define __NR_signal (__NR_SYSCALL_BASE+ 48)
+#define __NR_signal (__NR_SYSCALL_BASE+ 48) /* removed */
#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
#define __NR_acct (__NR_SYSCALL_BASE+ 51)
#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
-#define __NR_lock (__NR_SYSCALL_BASE+ 53)
+#define __NR_lock (__NR_SYSCALL_BASE+ 53) /* removed */
#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
-#define __NR_mpx (__NR_SYSCALL_BASE+ 56)
+#define __NR_mpx (__NR_SYSCALL_BASE+ 56) /* removed */
#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
-#define __NR_ulimit (__NR_SYSCALL_BASE+ 58)
-
+#define __NR_ulimit (__NR_SYSCALL_BASE+ 58) /* removed */
+ /* 59 was sys_olduname */
#define __NR_umask (__NR_SYSCALL_BASE+ 60)
#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
@@ -93,8 +93,8 @@
#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
-#define __NR_sgetmask (__NR_SYSCALL_BASE+ 68)
-#define __NR_ssetmask (__NR_SYSCALL_BASE+ 69)
+#define __NR_sgetmask (__NR_SYSCALL_BASE+ 68) /* removed */
+#define __NR_ssetmask (__NR_SYSCALL_BASE+ 69) /* removed */
#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
@@ -109,7 +109,7 @@
#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
#define __NR_select (__NR_SYSCALL_BASE+ 82)
#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
-
+ /* 84 was sys_lstat */
#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
@@ -123,7 +123,7 @@
#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
-#define __NR_profil (__NR_SYSCALL_BASE+ 98)
+#define __NR_profil (__NR_SYSCALL_BASE+ 98) /* removed */
#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
#define __NR_ioperm (__NR_SYSCALL_BASE+101)
@@ -134,8 +134,8 @@
#define __NR_stat (__NR_SYSCALL_BASE+106)
#define __NR_lstat (__NR_SYSCALL_BASE+107)
#define __NR_fstat (__NR_SYSCALL_BASE+108)
-
-
+ /* 109 was sys_uname */
+ /* 110 was sys_iopl */
#define __NR_vhangup (__NR_SYSCALL_BASE+111)
#define __NR_idle (__NR_SYSCALL_BASE+112)
#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
@@ -152,10 +152,10 @@
#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
#define __NR_mprotect (__NR_SYSCALL_BASE+125)
#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
-#define __NR_create_module (__NR_SYSCALL_BASE+127)
+#define __NR_create_module (__NR_SYSCALL_BASE+127) /* removed */
#define __NR_init_module (__NR_SYSCALL_BASE+128)
#define __NR_delete_module (__NR_SYSCALL_BASE+129)
-#define __NR_get_kernel_syms (__NR_SYSCALL_BASE+130)
+#define __NR_get_kernel_syms (__NR_SYSCALL_BASE+130) /* removed */
#define __NR_quotactl (__NR_SYSCALL_BASE+131)
#define __NR_getpgid (__NR_SYSCALL_BASE+132)
#define __NR_fchdir (__NR_SYSCALL_BASE+133)
@@ -191,8 +191,8 @@
#define __NR_mremap (__NR_SYSCALL_BASE+163)
#define __NR_setresuid (__NR_SYSCALL_BASE+164)
#define __NR_getresuid (__NR_SYSCALL_BASE+165)
-#define __NR_vm86 (__NR_SYSCALL_BASE+166)
-#define __NR_query_module (__NR_SYSCALL_BASE+167)
+#define __NR_vm86 (__NR_SYSCALL_BASE+166) /* removed */
+#define __NR_query_module (__NR_SYSCALL_BASE+167) /* removed */
#define __NR_poll (__NR_SYSCALL_BASE+168)
#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
#define __NR_setresgid (__NR_SYSCALL_BASE+170)
@@ -264,6 +264,24 @@
#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
#define __NR_tkill (__NR_SYSCALL_BASE+238)
+#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
+#define __NR_futex (__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
+#define __NR_io_setup (__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
+#define __NR_io_submit (__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
+#define __NR_exit_group (__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
+ /* 254 for set_thread_area */
+ /* 255 for get_thread_area */
+ /* 256 for set_tid_address */
/*
* The following SWIs are ARM private.
diff --git a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h
index 7acd49b93509..603ada787ac2 100644
--- a/include/asm-sparc64/bug.h
+++ b/include/asm-sparc64/bug.h
@@ -13,5 +13,8 @@ extern void do_BUG(const char *file, int line);
#define BUG() __builtin_trap()
#endif
+#define PAGE_BUG(page) do { \
+ BUG(); \
+} while (0)
#endif
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index f909a967778e..0612ce8e8274 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -707,7 +707,7 @@ extern int ext3fs_dirhash(const char *name, int len, struct
/* ialloc.c */
extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
extern void ext3_free_inode (handle_t *, struct inode *);
-extern struct inode * ext3_orphan_get (struct super_block *, ino_t);
+extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
extern unsigned long ext3_count_free_inodes (struct super_block *);
extern unsigned long ext3_count_dirs (struct super_block *);
extern void ext3_check_inodes_bitmap (struct super_block *);
diff --git a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
index 1985ecee6a3f..13508f6053b9 100644
--- a/include/linux/ext3_jbd.h
+++ b/include/linux/ext3_jbd.h
@@ -132,16 +132,6 @@ __ext3_journal_get_write_access(const char *where,
return err;
}
-static inline int
-__ext3_journal_dirty_data(const char *where,
- handle_t *handle, struct buffer_head *bh, int async)
-{
- int err = journal_dirty_data(handle, bh, async);
- if (err)
- ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
- return err;
-}
-
static inline void
ext3_journal_forget(handle_t *handle, struct buffer_head *bh)
{
@@ -183,8 +173,6 @@ __ext3_journal_dirty_metadata(const char *where,
__ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh))
#define ext3_journal_get_write_access(handle, bh) \
__ext3_journal_get_write_access(__FUNCTION__, (handle), (bh))
-#define ext3_journal_dirty_data(handle, bh, async) \
- __ext3_journal_dirty_data(__FUNCTION__, (handle), (bh), (async))
#define ext3_journal_revoke(handle, blocknr, bh) \
__ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh))
#define ext3_journal_get_create_access(handle, bh) \
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index f3e44482a298..47a20ce63fa8 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -360,13 +360,6 @@ struct transaction_s
*/
struct journal_head * t_sync_datalist;
- /*
- * Doubly-linked circular list of all writepage data buffers
- * still to be written before this transaction can be committed.
- * Protected by journal_datalist_lock.
- */
- struct journal_head * t_async_datalist;
-
/* Doubly-linked circular list of all forget buffers (superseded
buffers which we can un-checkpoint once this transaction
commits) */
@@ -654,8 +647,7 @@ extern int journal_extend (handle_t *, int nblocks);
extern int journal_get_write_access (handle_t *, struct buffer_head *);
extern int journal_get_create_access (handle_t *, struct buffer_head *);
extern int journal_get_undo_access (handle_t *, struct buffer_head *);
-extern int journal_dirty_data (handle_t *,
- struct buffer_head *, int async);
+extern int journal_dirty_data (handle_t *, struct buffer_head *);
extern int journal_dirty_metadata (handle_t *, struct buffer_head *);
extern void journal_release_buffer (handle_t *, struct buffer_head *);
extern void journal_forget (handle_t *, struct buffer_head *);
@@ -806,14 +798,13 @@ extern int journal_blocks_per_page(struct inode *inode);
/* journaling buffer types */
#define BJ_None 0 /* Not journaled */
#define BJ_SyncData 1 /* Normal data: flush before commit */
-#define BJ_AsyncData 2 /* writepage data: wait on it before commit */
-#define BJ_Metadata 3 /* Normal journaled metadata */
-#define BJ_Forget 4 /* Buffer superseded by this transaction */
-#define BJ_IO 5 /* Buffer is for temporary IO use */
-#define BJ_Shadow 6 /* Buffer contents being shadowed to the log */
-#define BJ_LogCtl 7 /* Buffer contains log descriptors */
-#define BJ_Reserved 8 /* Buffer is reserved for access by journal */
-#define BJ_Types 9
+#define BJ_Metadata 2 /* Normal journaled metadata */
+#define BJ_Forget 3 /* Buffer superseded by this transaction */
+#define BJ_IO 4 /* Buffer is for temporary IO use */
+#define BJ_Shadow 5 /* Buffer contents being shadowed to the log */
+#define BJ_LogCtl 6 /* Buffer contains log descriptors */
+#define BJ_Reserved 7 /* Buffer is reserved for access by journal */
+#define BJ_Types 8
extern int jbd_blocks_per_page(struct inode *inode);
@@ -860,8 +851,7 @@ static inline int buffer_jdirty(struct buffer_head *bh)
static inline int buffer_jbd_data(struct buffer_head *bh)
{
return SPLICE_LOCK(buffer_jbd(bh),
- bh2jh(bh)->b_jlist == BJ_SyncData ||
- bh2jh(bh)->b_jlist == BJ_AsyncData);
+ bh2jh(bh)->b_jlist == BJ_SyncData);
}
#ifdef CONFIG_SMP
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 396d4178b14c..b7b3da409f8a 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -18,6 +18,7 @@
#define RTC_MINOR 135
#define EFI_RTC_MINOR 136 /* EFI Time services */
#define SUN_OPENPROM_MINOR 139
+#define DMAPI_MINOR 140 /* DMAPI */
#define NVRAM_MINOR 144
#define I2O_MINOR 166
#define MICROCODE_MINOR 184
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 14ce2049de71..bcb57ed21a8d 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -193,7 +193,8 @@ typedef struct pglist_data {
extern int numnodes;
extern struct pglist_data *pgdat_list;
-void get_zone_counts(unsigned long *active, unsigned long *inactive);
+void get_zone_counts(unsigned long *active, unsigned long *inactive,
+ unsigned long *free);
void build_all_zonelists(void);
void wakeup_kswapd(struct zone *zone);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1295d071376a..931cdf559eb2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -27,6 +27,7 @@
#include <linux/compiler.h>
#include <linux/completion.h>
#include <linux/pid.h>
+#include <linux/percpu.h>
struct exec_domain;
@@ -87,6 +88,8 @@ extern unsigned long avenrun[]; /* Load averages */
extern int nr_threads;
extern int last_pid;
+DECLARE_PER_CPU(unsigned long, process_counts);
+extern int nr_processes(void);
extern unsigned long nr_running(void);
extern unsigned long nr_uninterruptible(void);
extern unsigned long nr_iowait(void);
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index a7eb1b4188bd..9e967b58ee2e 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -4,7 +4,7 @@
Extended attributes handling.
Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
- Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
+ Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
*/
#ifndef _LINUX_XATTR_H
#define _LINUX_XATTR_H
diff --git a/kernel/exit.c b/kernel/exit.c
index 1841978bfa4c..743ed76ed243 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -41,6 +41,8 @@ static struct dentry * __unhash_process(struct task_struct *p)
if (thread_group_leader(p)) {
detach_pid(p, PIDTYPE_PGID);
detach_pid(p, PIDTYPE_SID);
+ if (p->pid)
+ per_cpu(process_counts, smp_processor_id())--;
}
REMOVE_LINKS(p);
@@ -191,7 +193,7 @@ int is_orphaned_pgrp(int pgrp)
return will_become_orphaned_pgrp(pgrp, 0);
}
-static inline int __has_stopped_jobs(int pgrp)
+static inline int has_stopped_jobs(int pgrp)
{
int retval = 0;
struct task_struct *p;
@@ -207,17 +209,6 @@ static inline int __has_stopped_jobs(int pgrp)
return retval;
}
-static inline int has_stopped_jobs(int pgrp)
-{
- int retval;
-
- read_lock(&tasklist_lock);
- retval = __has_stopped_jobs(pgrp);
- read_unlock(&tasklist_lock);
-
- return retval;
-}
-
/**
* reparent_to_init() - Reparent the calling kernel thread to the init task.
*
@@ -504,7 +495,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
(p->session == father->session)) {
int pgrp = p->pgrp;
- if (__will_become_orphaned_pgrp(pgrp, 0) && __has_stopped_jobs(pgrp)) {
+ if (__will_become_orphaned_pgrp(pgrp, 0) && has_stopped_jobs(pgrp)) {
__kill_pg_info(SIGHUP, (void *)1, pgrp);
__kill_pg_info(SIGCONT, (void *)1, pgrp);
}
@@ -589,7 +580,7 @@ static void exit_notify(void)
if ((t->pgrp != current->pgrp) &&
(t->session == current->session) &&
__will_become_orphaned_pgrp(current->pgrp, current) &&
- __has_stopped_jobs(current->pgrp)) {
+ has_stopped_jobs(current->pgrp)) {
__kill_pg_info(SIGHUP, (void *)1, current->pgrp);
__kill_pg_info(SIGCONT, (void *)1, current->pgrp);
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 115a5eae0d6b..0ba9e64b5821 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -48,6 +48,8 @@ int nr_threads;
int max_threads;
unsigned long total_forks; /* Handle normal Linux uptimes. */
+DEFINE_PER_CPU(unsigned long, process_counts) = 0;
+
rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */
/*
@@ -57,6 +59,18 @@ rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */
*/
static task_t *task_cache[NR_CPUS] __cacheline_aligned;
+int nr_processes(void)
+{
+ int cpu;
+ int total = 0;
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (cpu_online(cpu))
+ total += per_cpu(process_counts, cpu);
+ }
+ return total;
+}
+
void __put_task_struct(struct task_struct *tsk)
{
if (tsk != current) {
@@ -931,6 +945,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
attach_pid(p, PIDTYPE_TGID, p->tgid);
attach_pid(p, PIDTYPE_PGID, p->pgrp);
attach_pid(p, PIDTYPE_SID, p->session);
+ if (p->pid)
+ per_cpu(process_counts, smp_processor_id())++;
} else
link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1c8015736d61..3969ad493b35 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -776,15 +776,18 @@ void get_full_page_state(struct page_state *ret)
__get_page_state(ret, sizeof(*ret) / sizeof(unsigned long));
}
-void get_zone_counts(unsigned long *active, unsigned long *inactive)
+void get_zone_counts(unsigned long *active,
+ unsigned long *inactive, unsigned long *free)
{
struct zone *zone;
*active = 0;
*inactive = 0;
+ *free = 0;
for_each_zone(zone) {
*active += zone->nr_active;
*inactive += zone->nr_inactive;
+ *free += zone->free_pages;
}
}
@@ -838,6 +841,7 @@ void show_free_areas(void)
int cpu, temperature;
unsigned long active;
unsigned long inactive;
+ unsigned long free;
struct zone *zone;
for_each_zone(zone) {
@@ -863,7 +867,7 @@ void show_free_areas(void)
}
get_page_state(&ps);
- get_zone_counts(&active, &inactive);
+ get_zone_counts(&active, &inactive, &free);
printk("\nFree pages: %11ukB (%ukB HighMem)\n",
K(nr_free_pages()),
diff --git a/mm/readahead.c b/mm/readahead.c
index 00de3dcc2829..bd28c3b4f1ca 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -477,7 +477,8 @@ unsigned long max_sane_readahead(unsigned long nr)
{
unsigned long active;
unsigned long inactive;
+ unsigned long free;
- get_zone_counts(&active, &inactive);
- return min(nr, inactive / 2);
+ get_zone_counts(&active, &inactive, &free);
+ return min(nr, (inactive + free) / 2);
}