summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS6
-rw-r--r--Documentation/s390/crypto/crypto-API.txt83
-rw-r--r--arch/alpha/kernel/irq.c14
-rw-r--r--arch/alpha/kernel/traps.c12
-rw-r--r--arch/arm26/kernel/traps.c12
-rw-r--r--arch/cris/kernel/traps.c8
-rw-r--r--arch/h8300/kernel/traps.c6
-rw-r--r--arch/i386/kernel/i8259.c2
-rw-r--r--arch/i386/kernel/nmi.c3
-rw-r--r--arch/i386/kernel/traps.c10
-rw-r--r--arch/mips/kernel/traps.c5
-rw-r--r--arch/parisc/kernel/traps.c5
-rw-r--r--arch/ppc64/kernel/process.c6
-rw-r--r--arch/s390/Makefile2
-rw-r--r--arch/s390/crypto/Makefile8
-rw-r--r--arch/s390/crypto/crypt_z990.h374
-rw-r--r--arch/s390/crypto/crypt_z990_query.c111
-rw-r--r--arch/s390/crypto/crypto_des.h18
-rw-r--r--arch/s390/crypto/des_check_key.c130
-rw-r--r--arch/s390/crypto/des_z990.c284
-rw-r--r--arch/s390/crypto/sha1_z990.c167
-rw-r--r--arch/s390/defconfig48
-rw-r--r--arch/s390/kernel/binfmt_elf32.c2
-rw-r--r--arch/s390/kernel/compat_linux.c88
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/entry.S6
-rw-r--r--arch/s390/kernel/entry64.S6
-rw-r--r--arch/s390/kernel/setup.c4
-rw-r--r--arch/s390/kernel/smp.c4
-rw-r--r--arch/s390/kernel/traps.c11
-rw-r--r--arch/sh/kernel/traps.c6
-rw-r--r--arch/sparc64/kernel/traps.c7
-rw-r--r--arch/um/kernel/sysrq.c11
-rw-r--r--arch/v850/kernel/process.c7
-rw-r--r--arch/x86_64/kernel/traps.c10
-rw-r--r--crypto/Kconfig12
-rw-r--r--drivers/cdrom/viocd.c87
-rw-r--r--drivers/char/viotape.c41
-rw-r--r--drivers/firmware/edd.c2
-rw-r--r--drivers/input/serio/Kconfig10
-rw-r--r--drivers/input/serio/Makefile1
-rw-r--r--drivers/input/serio/i8042-io.h2
-rw-r--r--drivers/input/serio/i8042-ip22io.h76
-rw-r--r--drivers/input/serio/i8042-jazzio.h69
-rw-r--r--drivers/input/serio/i8042.h8
-rw-r--r--drivers/input/serio/maceps2.c160
-rw-r--r--drivers/pci/Makefile3
-rw-r--r--drivers/s390/block/dasd.c15
-rw-r--r--drivers/s390/block/dasd_3990_erp.c3
-rw-r--r--drivers/s390/block/dasd_eckd.c5
-rw-r--r--drivers/s390/block/dasd_int.h6
-rw-r--r--drivers/s390/char/raw3270.c4
-rw-r--r--drivers/s390/cio/cio.c67
-rw-r--r--drivers/s390/cio/device_fsm.c3
-rw-r--r--drivers/s390/cio/qdio.c12
-rw-r--r--drivers/s390/net/iucv.c7
-rw-r--r--drivers/s390/net/netiucv.c18
-rw-r--r--drivers/s390/net/qeth.h5
-rw-r--r--drivers/s390/net/qeth_main.c326
-rw-r--r--drivers/s390/scsi/zfcp_aux.c16
-rw-r--r--drivers/s390/scsi/zfcp_def.h15
-rw-r--r--drivers/s390/scsi/zfcp_erp.c25
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c41
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c11
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c6
-rw-r--r--drivers/video/fbcmap.c2
-rw-r--r--fs/Kconfig.binfmt2
-rw-r--r--fs/compat.c2
-rw-r--r--include/asm-ppc/processor.h2
-rw-r--r--include/asm-ppc64/processor.h2
-rw-r--r--include/linux/proc_fs.h2
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/sunrpc/svcauth_gss.h1
-rw-r--r--init/Kconfig2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c1
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c7
76 files changed, 1997 insertions, 561 deletions
diff --git a/CREDITS b/CREDITS
index 1d61e296472d..f30565f12cf2 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1944,6 +1944,12 @@ S: 8786 Niwot Road
S: Niwot, Colorado 80503
S: USA
+N: Pete Popov
+E: pete_popov@yahoo.com
+D: Linux/MIPS AMD/Alchemy Port and mips hacking and debugging
+S: San Jose, CA 95134
+S: USA
+
N: Robert M. Love
E: rml@tech9.net
E: rml@ufl.edu
diff --git a/Documentation/s390/crypto/crypto-API.txt b/Documentation/s390/crypto/crypto-API.txt
new file mode 100644
index 000000000000..78a77624a716
--- /dev/null
+++ b/Documentation/s390/crypto/crypto-API.txt
@@ -0,0 +1,83 @@
+crypto-API support for z990 Message Security Assist (MSA) instructions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+AUTHOR: Thomas Spatzier (tspat@de.ibm.com)
+
+
+1. Introduction crypto-API
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+See Documentation/crypto/api-intro.txt for an introduction/description of the
+kernel crypto API.
+According to api-intro.txt support for z990 crypto instructions has been added
+in the algorithm api layer of the crypto API. Several files containing z990
+optimized implementations of crypto algorithms are placed in the
+arch/s390/crypto directory.
+
+
+2. Probing for availability of MSA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It should be possible to use Kernels with the z990 crypto implementations both
+on machines with MSA available an on those without MSA (pre z990 or z990
+without MSA). Therefore a simple probing mechanisms has been implemented:
+In the init function of each crypto module the availability of MSA and of the
+respective crypto algorithm in particular will be tested. If the algorithm is
+available the module will load and register its algorithm with the crypto API.
+
+If the respective crypto algorithm is not available, the init function will
+return -ENOSYS. In that case a fallback to the standard software implementation
+of the crypto algorithm must be taken ( -> the standard crypto modules are
+also build when compiling the kernel).
+
+
+3. Ensuring z990 crypto module preference
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If z990 crypto instructions are available the optimized modules should be
+preferred instead of standard modules.
+
+3.1. compiled-in modules
+~~~~~~~~~~~~~~~~~~~~~~~~
+For compiled-in modules it has to be ensured that the z990 modules are linked
+before the standard crypto modules. Then, on system startup the init functions
+of z990 crypto modules will be called first and query for availability of z990
+crypto instructions. If instruction is available, the z990 module will register
+its crypto algorithm implementation -> the load of the standard module will fail
+since the algorithm is already registered.
+If z990 crypto instruction is not available the load of the z990 module will
+fail -> the standard module will load and register its algorithm.
+
+3.2. dynamic modules
+~~~~~~~~~~~~~~~~~~~~
+A system administrator has to take care of giving preference to z990 crypto
+modules. If MSA is available appropriate lines have to be added to
+/etc/modprobe.conf.
+
+Example: z990 crypto instruction for SHA1 algorithm is available
+
+ add the following line to /etc/modprobe.conf (assuming the
+ z990 crypto modules for SHA1 is called sha1_z990):
+
+ alias sha1 sha1_z990
+
+ -> when the sha1 algorithm is requested through the crypto API
+ (which has a module autoloader) the z990 module will be loaded.
+
+TBD: a userspace module probin mechanism
+ something like 'probe sha1 sha1_z990 sha1' in modprobe.conf
+ -> try module sha1_z990, if it fails to load load standard module sha1
+ the 'probe' statement is currently not supported in modprobe.conf
+
+
+4. Currently implemented z990 crypto algorithms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The following crypto algorithms with z990 MSA support are currently implemented.
+The name of each algorithm under which it is registered in crypto API and the
+name of the respective module is given in square brackets.
+
+- SHA1 Digest Algorithm [sha1 -> sha1_z990]
+- DES Encrypt/Decrypt Algorithm (64bit key) [des -> des_z990]
+- Tripple DES Encrypt/Decrypt Algorithm (128bit key) [des3_ede128 -> des_z990]
+- Tripple DES Encrypt/Decrypt Algorithm (192bit key) [des3_ede -> des_z990]
+
+In order to load, for example, the sha1_z990 module when the sha1 algorithm is
+requested (see 3.2.) add 'alias sha1 sha1_z990' to /etc/modprobe.conf.
+
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 0e317230f81e..c51bf8dbfc8a 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -415,16 +415,12 @@ init_irq_proc (void)
#endif
/*
- * Create entries for all existing IRQs. If the number of IRQs
- * is greater the 1/4 the total dynamic inode space for /proc,
- * don't pollute the inode space
+ * Create entries for all existing IRQs.
*/
- if (ACTUAL_NR_IRQS < (PROC_NDYNAMIC / 4)) {
- for (i = 0; i < ACTUAL_NR_IRQS; i++) {
- if (irq_desc[i].handler == &no_irq_type)
- continue;
- register_irq_proc(i);
- }
+ for (i = 0; i < ACTUAL_NR_IRQS; i++) {
+ if (irq_desc[i].handler == &no_irq_type)
+ continue;
+ register_irq_proc(i);
}
}
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 8906f66b65e7..52348791ce1e 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -137,18 +137,6 @@ dik_show_trace(unsigned long *sp)
printk("\n");
}
-void show_trace_task(struct task_struct * tsk)
-{
- struct thread_info *ti = tsk->thread_info;
- unsigned long fp, sp = ti->pcb.ksp, base = (unsigned long) ti;
-
- if (sp > base && sp+6*8 < base + 16*1024) {
- fp = ((unsigned long*)sp)[6];
- if (fp > sp && fp < base + 16*1024)
- dik_show_trace((unsigned long *)fp);
- }
-}
-
static int kstack_depth_to_print = 24;
void show_stack(struct task_struct *task, unsigned long *sp)
diff --git a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c
index d2ffd9016c07..f0a49fec0d9e 100644
--- a/arch/arm26/kernel/traps.c
+++ b/arch/arm26/kernel/traps.c
@@ -165,18 +165,6 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
c_backtrace(fp, processor_mode(regs));
}
-/*
- * This is called from SysRq-T (show_task) to display the current
- * call trace for each process. Very useful.
- */
-void show_trace_task(struct task_struct *tsk)
-{
- if (tsk != current) {
- unsigned int fp = thread_saved_fp(tsk);
- c_backtrace(fp, 0x10);
- }
-}
-
/* FIXME - this is probably wrong.. */
void show_stack(struct task_struct *task, unsigned long *sp) {
dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task->thread_info);
diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c
index 2a757b825c44..d9e6565655f4 100644
--- a/arch/cris/kernel/traps.c
+++ b/arch/cris/kernel/traps.c
@@ -60,14 +60,6 @@ void show_trace(unsigned long * stack)
}
}
-void show_trace_task(struct task_struct *tsk)
-{
- /* TODO, this is not really useful since its called from
- * SysRq-T and we don't have a keyboard.. :)
- */
-}
-
-
/*
* These constants are for searching for possible module text
* segments. MODULE_RANGE is a guess of how much space is likely
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
index 300e3279ca5a..253c87bc5b32 100644
--- a/arch/h8300/kernel/traps.c
+++ b/arch/h8300/kernel/traps.c
@@ -156,14 +156,8 @@ void show_stack(struct task_struct *task, unsigned long *esp)
printk("\n");
}
-void show_trace_task(struct task_struct *tsk)
-{
- show_stack(tsk,(unsigned long *)tsk->thread.esp0);
-}
-
void dump_stack(void)
{
show_stack(NULL,NULL);
}
-
EXPORT_SYMBOL(dump_stack);
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index f424fc369fb1..0be8d6b87cf7 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -445,5 +445,5 @@ void __init init_IRQ(void)
if (boot_cpu_data.hard_math && !cpu_has_fpu)
setup_irq(FPU_IRQ, &fpu_irq);
- irq_ctx_init(current_thread_info()->cpu);
+ irq_ctx_init(smp_processor_id());
}
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index d74fb46abd31..574ae5814333 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -462,8 +462,7 @@ void nmi_watchdog_tick (struct pt_regs * regs)
/* Only P6 based Pentium M need to re-unmask
* the apic vector but it doesn't hurt
* other P6 variant */
- apic_write(APIC_LVTPC,
- apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
+ apic_write(APIC_LVTPC, APIC_DM_NMI);
}
wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index cf8da7ba4cdb..c770d878cbcf 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -123,16 +123,6 @@ void show_trace(struct task_struct *task, unsigned long * stack)
printk("\n");
}
-void show_trace_task(struct task_struct *tsk)
-{
- unsigned long esp = tsk->thread.esp;
-
- /* User space on another CPU? */
- if ((esp ^ (unsigned long)tsk->thread_info) & ~(THREAD_SIZE - 1))
- return;
- show_trace(tsk, (unsigned long *)esp);
-}
-
void show_stack(struct task_struct *task, unsigned long *esp)
{
unsigned long *stack;
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index d72026927fec..752dbd3e93fb 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -126,11 +126,6 @@ void show_trace(struct task_struct *task, unsigned long *stack)
printk("\n");
}
-void show_trace_task(struct task_struct *tsk)
-{
- show_trace(tsk, (long *)tsk->thread.reg29);
-}
-
/*
* The architecture-independent dump_stack generator
*/
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index f83053a37644..6f1f6f738d6c 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -202,11 +202,6 @@ void show_trace(struct task_struct *task, unsigned long *stack)
printk("\n");
}
-void show_trace_task(struct task_struct *tsk)
-{
- show_trace(tsk, (unsigned long *)tsk->thread.regs.ksp);
-}
-
void die_if_kernel(char *str, struct pt_regs *regs, long err)
{
if (user_mode(regs)) {
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index f74b14d7e58e..7c153dc24895 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -536,10 +536,4 @@ void dump_stack(void)
{
show_stack(current, (unsigned long *)__get_SP());
}
-
EXPORT_SYMBOL(dump_stack);
-
-void show_trace_task(struct task_struct *tsk)
-{
- show_stack(tsk, (unsigned long *)tsk->thread.ksp);
-}
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 9525ee20aa0e..a4a727aab6f7 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -44,7 +44,7 @@ head-$(CONFIG_ARCH_S390_31) += arch/$(ARCH)/kernel/head.o
head-$(CONFIG_ARCH_S390X) += arch/$(ARCH)/kernel/head64.o
head-y += arch/$(ARCH)/kernel/init_task.o
-core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ \
+core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \
arch/$(ARCH)/appldata/
libs-y += arch/$(ARCH)/lib/
drivers-y += drivers/s390/
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile
new file mode 100644
index 000000000000..96a05e6b51e0
--- /dev/null
+++ b/arch/s390/crypto/Makefile
@@ -0,0 +1,8 @@
+#
+# Cryptographic API
+#
+
+obj-$(CONFIG_CRYPTO_SHA1_Z990) += sha1_z990.o
+obj-$(CONFIG_CRYPTO_DES_Z990) += des_z990.o des_check_key.o
+
+obj-$(CONFIG_CRYPTO_TEST) += crypt_z990_query.o
diff --git a/arch/s390/crypto/crypt_z990.h b/arch/s390/crypto/crypt_z990.h
new file mode 100644
index 000000000000..4df660b99e5a
--- /dev/null
+++ b/arch/s390/crypto/crypt_z990.h
@@ -0,0 +1,374 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for z990 cryptographic instructions.
+ *
+ * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation
+ * Author(s): Thomas Spatzier (tspat@de.ibm.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.
+ *
+ */
+#ifndef _CRYPTO_ARCH_S390_CRYPT_Z990_H
+#define _CRYPTO_ARCH_S390_CRYPT_Z990_H
+
+#include <asm/errno.h>
+
+#define CRYPT_Z990_OP_MASK 0xFF00
+#define CRYPT_Z990_FUNC_MASK 0x00FF
+
+
+/*z990 cryptographic operations*/
+enum crypt_z990_operations {
+ CRYPT_Z990_KM = 0x0100,
+ CRYPT_Z990_KMC = 0x0200,
+ CRYPT_Z990_KIMD = 0x0300,
+ CRYPT_Z990_KLMD = 0x0400,
+ CRYPT_Z990_KMAC = 0x0500
+};
+
+/*function codes for KM (CIPHER MESSAGE) instruction*/
+enum crypt_z990_km_func {
+ KM_QUERY = CRYPT_Z990_KM | 0,
+ KM_DEA_ENCRYPT = CRYPT_Z990_KM | 1,
+ KM_DEA_DECRYPT = CRYPT_Z990_KM | 1 | 0x80, //modifier bit->decipher
+ KM_TDEA_128_ENCRYPT = CRYPT_Z990_KM | 2,
+ KM_TDEA_128_DECRYPT = CRYPT_Z990_KM | 2 | 0x80,
+ KM_TDEA_192_ENCRYPT = CRYPT_Z990_KM | 3,
+ KM_TDEA_192_DECRYPT = CRYPT_Z990_KM | 3 | 0x80,
+};
+
+/*function codes for KMC (CIPHER MESSAGE WITH CHAINING) instruction*/
+enum crypt_z990_kmc_func {
+ KMC_QUERY = CRYPT_Z990_KMC | 0,
+ KMC_DEA_ENCRYPT = CRYPT_Z990_KMC | 1,
+ KMC_DEA_DECRYPT = CRYPT_Z990_KMC | 1 | 0x80, //modifier bit->decipher
+ KMC_TDEA_128_ENCRYPT = CRYPT_Z990_KMC | 2,
+ KMC_TDEA_128_DECRYPT = CRYPT_Z990_KMC | 2 | 0x80,
+ KMC_TDEA_192_ENCRYPT = CRYPT_Z990_KMC | 3,
+ KMC_TDEA_192_DECRYPT = CRYPT_Z990_KMC | 3 | 0x80,
+};
+
+/*function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) instruction*/
+enum crypt_z990_kimd_func {
+ KIMD_QUERY = CRYPT_Z990_KIMD | 0,
+ KIMD_SHA_1 = CRYPT_Z990_KIMD | 1,
+};
+
+/*function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) instruction*/
+enum crypt_z990_klmd_func {
+ KLMD_QUERY = CRYPT_Z990_KLMD | 0,
+ KLMD_SHA_1 = CRYPT_Z990_KLMD | 1,
+};
+
+/*function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) instruction*/
+enum crypt_z990_kmac_func {
+ KMAC_QUERY = CRYPT_Z990_KMAC | 0,
+ KMAC_DEA = CRYPT_Z990_KMAC | 1,
+ KMAC_TDEA_128 = CRYPT_Z990_KMAC | 2,
+ KMAC_TDEA_192 = CRYPT_Z990_KMAC | 3
+};
+
+/*status word for z990 crypto instructions' QUERY functions*/
+struct crypt_z990_query_status {
+ u64 high;
+ u64 low;
+};
+
+/*
+ * Standard fixup and ex_table sections for crypt_z990 inline functions.
+ * label 0: the z990 crypto operation
+ * label 1: just after 1 to catch illegal operation exception on non-z990
+ * label 6: the return point after fixup
+ * label 7: set error value if exception _in_ crypto operation
+ * label 8: set error value if illegal operation exception
+ * [ret] is the variable to receive the error code
+ * [ERR] is the error code value
+ */
+#ifndef __s390x__
+#define __crypt_z990_fixup \
+ ".section .fixup,\"ax\" \n" \
+ "7: lhi %0,%h[e1] \n" \
+ " bras 1,9f \n" \
+ " .long 6b \n" \
+ "8: lhi %0,%h[e2] \n" \
+ " bras 1,9f \n" \
+ " .long 6b \n" \
+ "9: l 1,0(1) \n" \
+ " br 1 \n" \
+ ".previous \n" \
+ ".section __ex_table,\"a\" \n" \
+ " .align 4 \n" \
+ " .long 0b,7b \n" \
+ " .long 1b,8b \n" \
+ ".previous"
+#else /* __s390x__ */
+#define __crypt_z990_fixup \
+ ".section .fixup,\"ax\" \n" \
+ "7: lhi %0,%h[e1] \n" \
+ " jg 6b \n" \
+ "8: lhi %0,%h[e2] \n" \
+ " jg 6b \n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\" \n" \
+ " .align 8 \n" \
+ " .quad 0b,7b \n" \
+ " .quad 1b,8b \n" \
+ ".previous"
+#endif /* __s390x__ */
+
+/*
+ * Standard code for setting the result of z990 crypto instructions.
+ * %0: the register which will receive the result
+ * [result]: the register containing the result (e.g. second operand length
+ * to compute number of processed bytes].
+ */
+#ifndef __s390x__
+#define __crypt_z990_set_result \
+ " lr %0,%[result] \n"
+#else /* __s390x__ */
+#define __crypt_z990_set_result \
+ " lgr %0,%[result] \n"
+#endif
+
+/*
+ * Executes the KM (CIPHER MESSAGE) operation of the z990 CPU.
+ * @param func: the function code passed to KM; see crypt_z990_km_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param dest: address of destination memory area
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * for encryption/decryption funcs
+ */
+static inline int
+crypt_z990_km(long func, void* param, u8* dest, const u8* src, long src_len)
+{
+ register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
+ register void* __param asm("1") = param;
+ register u8* __dest asm("4") = dest;
+ register const u8* __src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ int ret;
+
+ ret = 0;
+ __asm__ __volatile__ (
+ "0: .insn rre,0xB92E0000,%1,%2 \n" //KM opcode
+ "1: brc 1,0b \n" //handle partial completion
+ __crypt_z990_set_result
+ "6: \n"
+ __crypt_z990_fixup
+ : "+d" (ret), "+a" (__dest), "+a" (__src),
+ [result] "+d" (__src_len)
+ : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+ "a" (__param)
+ : "cc", "memory"
+ );
+ if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
+ ret = src_len - ret;
+ }
+ return ret;
+}
+
+/*
+ * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the z990 CPU.
+ * @param func: the function code passed to KM; see crypt_z990_kmc_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param dest: address of destination memory area
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * for encryption/decryption funcs
+ */
+static inline int
+crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
+{
+ register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
+ register void* __param asm("1") = param;
+ register u8* __dest asm("4") = dest;
+ register const u8* __src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ int ret;
+
+ ret = 0;
+ __asm__ __volatile__ (
+ "0: .insn rre,0xB92F0000,%1,%2 \n" //KMC opcode
+ "1: brc 1,0b \n" //handle partial completion
+ __crypt_z990_set_result
+ "6: \n"
+ __crypt_z990_fixup
+ : "+d" (ret), "+a" (__dest), "+a" (__src),
+ [result] "+d" (__src_len)
+ : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+ "a" (__param)
+ : "cc", "memory"
+ );
+ if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
+ ret = src_len - ret;
+ }
+ return ret;
+}
+
+/*
+ * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
+ * of the z990 CPU.
+ * @param func: the function code passed to KM; see crypt_z990_kimd_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * for digest funcs
+ */
+static inline int
+crypt_z990_kimd(long func, void* param, const u8* src, long src_len)
+{
+ register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
+ register void* __param asm("1") = param;
+ register const u8* __src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ int ret;
+
+ ret = 0;
+ __asm__ __volatile__ (
+ "0: .insn rre,0xB93E0000,%1,%1 \n" //KIMD opcode
+ "1: brc 1,0b \n" /*handle partical completion of kimd*/
+ __crypt_z990_set_result
+ "6: \n"
+ __crypt_z990_fixup
+ : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
+ : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+ "a" (__param)
+ : "cc", "memory"
+ );
+ if (ret >= 0 && (func & CRYPT_Z990_FUNC_MASK)){
+ ret = src_len - ret;
+ }
+ return ret;
+}
+
+/*
+ * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the z990 CPU.
+ * @param func: the function code passed to KM; see crypt_z990_klmd_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * for digest funcs
+ */
+static inline int
+crypt_z990_klmd(long func, void* param, const u8* src, long src_len)
+{
+ register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
+ register void* __param asm("1") = param;
+ register const u8* __src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ int ret;
+
+ ret = 0;
+ __asm__ __volatile__ (
+ "0: .insn rre,0xB93F0000,%1,%1 \n" //KLMD opcode
+ "1: brc 1,0b \n" /*handle partical completion of klmd*/
+ __crypt_z990_set_result
+ "6: \n"
+ __crypt_z990_fixup
+ : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
+ : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+ "a" (__param)
+ : "cc", "memory"
+ );
+ if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
+ ret = src_len - ret;
+ }
+ return ret;
+}
+
+/*
+ * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
+ * of the z990 CPU.
+ * @param func: the function code passed to KM; see crypt_z990_klmd_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * for digest funcs
+ */
+static inline int
+crypt_z990_kmac(long func, void* param, const u8* src, long src_len)
+{
+ register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
+ register void* __param asm("1") = param;
+ register const u8* __src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ int ret;
+
+ ret = 0;
+ __asm__ __volatile__ (
+ "0: .insn rre,0xB91E0000,%5,%5 \n" //KMAC opcode
+ "1: brc 1,0b \n" /*handle partical completion of klmd*/
+ __crypt_z990_set_result
+ "6: \n"
+ __crypt_z990_fixup
+ : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
+ : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+ "a" (__param)
+ : "cc", "memory"
+ );
+ if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
+ ret = src_len - ret;
+ }
+ return ret;
+}
+
+/**
+ * Tests if a specific z990 crypto function is implemented on the machine.
+ * @param func: the function code of the specific function; 0 if op in general
+ * @return 1 if func available; 0 if func or op in general not available
+ */
+static inline int
+crypt_z990_func_available(int func)
+{
+ int ret;
+
+ struct crypt_z990_query_status status = {
+ .high = 0,
+ .low = 0
+ };
+ switch (func & CRYPT_Z990_OP_MASK){
+ case CRYPT_Z990_KM:
+ ret = crypt_z990_km(KM_QUERY, &status, NULL, NULL, 0);
+ break;
+ case CRYPT_Z990_KMC:
+ ret = crypt_z990_kmc(KMC_QUERY, &status, NULL, NULL, 0);
+ break;
+ case CRYPT_Z990_KIMD:
+ ret = crypt_z990_kimd(KIMD_QUERY, &status, NULL, 0);
+ break;
+ case CRYPT_Z990_KLMD:
+ ret = crypt_z990_klmd(KLMD_QUERY, &status, NULL, 0);
+ break;
+ case CRYPT_Z990_KMAC:
+ ret = crypt_z990_kmac(KMAC_QUERY, &status, NULL, 0);
+ break;
+ default:
+ ret = 0;
+ return ret;
+ }
+ if (ret >= 0){
+ func &= CRYPT_Z990_FUNC_MASK;
+ func &= 0x7f; //mask modifier bit
+ if (func < 64){
+ ret = (status.high >> (64 - func - 1)) & 0x1;
+ } else {
+ ret = (status.low >> (128 - func - 1)) & 0x1;
+ }
+ } else {
+ ret = 0;
+ }
+ return ret;
+}
+
+
+#endif // _CRYPTO_ARCH_S390_CRYPT_Z990_H
diff --git a/arch/s390/crypto/crypt_z990_query.c b/arch/s390/crypto/crypt_z990_query.c
new file mode 100644
index 000000000000..7133983d1384
--- /dev/null
+++ b/arch/s390/crypto/crypt_z990_query.c
@@ -0,0 +1,111 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for z990 cryptographic instructions.
+ * Testing module for querying processor crypto capabilities.
+ *
+ * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Thomas Spatzier (tspat@de.ibm.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.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/errno.h>
+#include "crypt_z990.h"
+
+static void
+query_available_functions(void)
+{
+ printk(KERN_INFO "#####################\n");
+ //query available KM functions
+ printk(KERN_INFO "KM_QUERY: %d\n",
+ crypt_z990_func_available(KM_QUERY));
+ printk(KERN_INFO "KM_DEA: %d\n",
+ crypt_z990_func_available(KM_DEA_ENCRYPT));
+ printk(KERN_INFO "KM_TDEA_128: %d\n",
+ crypt_z990_func_available(KM_TDEA_128_ENCRYPT));
+ printk(KERN_INFO "KM_TDEA_192: %d\n",
+ crypt_z990_func_available(KM_TDEA_192_ENCRYPT));
+ //query available KMC functions
+ printk(KERN_INFO "KMC_QUERY: %d\n",
+ crypt_z990_func_available(KMC_QUERY));
+ printk(KERN_INFO "KMC_DEA: %d\n",
+ crypt_z990_func_available(KMC_DEA_ENCRYPT));
+ printk(KERN_INFO "KMC_TDEA_128: %d\n",
+ crypt_z990_func_available(KMC_TDEA_128_ENCRYPT));
+ printk(KERN_INFO "KMC_TDEA_192: %d\n",
+ crypt_z990_func_available(KMC_TDEA_192_ENCRYPT));
+ //query available KIMD fucntions
+ printk(KERN_INFO "KIMD_QUERY: %d\n",
+ crypt_z990_func_available(KIMD_QUERY));
+ printk(KERN_INFO "KIMD_SHA_1: %d\n",
+ crypt_z990_func_available(KIMD_SHA_1));
+ //query available KLMD functions
+ printk(KERN_INFO "KLMD_QUERY: %d\n",
+ crypt_z990_func_available(KLMD_QUERY));
+ printk(KERN_INFO "KLMD_SHA_1: %d\n",
+ crypt_z990_func_available(KLMD_SHA_1));
+ //query available KMAC functions
+ printk(KERN_INFO "KMAC_QUERY: %d\n",
+ crypt_z990_func_available(KMAC_QUERY));
+ printk(KERN_INFO "KMAC_DEA: %d\n",
+ crypt_z990_func_available(KMAC_DEA));
+ printk(KERN_INFO "KMAC_TDEA_128: %d\n",
+ crypt_z990_func_available(KMAC_TDEA_128));
+ printk(KERN_INFO "KMAC_TDEA_192: %d\n",
+ crypt_z990_func_available(KMAC_TDEA_192));
+}
+
+static int
+init(void)
+{
+ struct crypt_z990_query_status status = {
+ .high = 0,
+ .low = 0
+ };
+
+ printk(KERN_INFO "crypt_z990: querying available crypto functions\n");
+ crypt_z990_km(KM_QUERY, &status, NULL, NULL, 0);
+ printk(KERN_INFO "KM: %016llx %016llx\n",
+ (unsigned long long) status.high,
+ (unsigned long long) status.low);
+ status.high = status.low = 0;
+ crypt_z990_kmc(KMC_QUERY, &status, NULL, NULL, 0);
+ printk(KERN_INFO "KMC: %016llx %016llx\n",
+ (unsigned long long) status.high,
+ (unsigned long long) status.low);
+ status.high = status.low = 0;
+ crypt_z990_kimd(KIMD_QUERY, &status, NULL, 0);
+ printk(KERN_INFO "KIMD: %016llx %016llx\n",
+ (unsigned long long) status.high,
+ (unsigned long long) status.low);
+ status.high = status.low = 0;
+ crypt_z990_klmd(KLMD_QUERY, &status, NULL, 0);
+ printk(KERN_INFO "KLMD: %016llx %016llx\n",
+ (unsigned long long) status.high,
+ (unsigned long long) status.low);
+ status.high = status.low = 0;
+ crypt_z990_kmac(KMAC_QUERY, &status, NULL, 0);
+ printk(KERN_INFO "KMAC: %016llx %016llx\n",
+ (unsigned long long) status.high,
+ (unsigned long long) status.low);
+
+ query_available_functions();
+ return -1;
+}
+
+static void __exit
+cleanup(void)
+{
+}
+
+module_init(init);
+module_exit(cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/crypto_des.h b/arch/s390/crypto/crypto_des.h
new file mode 100644
index 000000000000..c964b64111dd
--- /dev/null
+++ b/arch/s390/crypto/crypto_des.h
@@ -0,0 +1,18 @@
+/*
+ * Cryptographic API.
+ *
+ * Function for checking keys for the DES and Tripple DES Encryption
+ * algorithms.
+ *
+ * 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.
+ *
+ */
+#ifndef __CRYPTO_DES_H__
+#define __CRYPTO_DES_H__
+
+extern int crypto_des_check_key(const u8*, unsigned int, u32*);
+
+#endif //__CRYPTO_DES_H__
diff --git a/arch/s390/crypto/des_check_key.c b/arch/s390/crypto/des_check_key.c
new file mode 100644
index 000000000000..e3f5c5f238fe
--- /dev/null
+++ b/arch/s390/crypto/des_check_key.c
@@ -0,0 +1,130 @@
+/*
+ * Cryptographic API.
+ *
+ * Function for checking keys for the DES and Tripple DES Encryption
+ * algorithms.
+ *
+ * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
+ * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
+ * Derived from Cryptoapi and Nettle implementations, adapted for in-place
+ * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL.
+ *
+ * s390 Version:
+ * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation
+ * Author(s): Thomas Spatzier (tspat@de.ibm.com)
+ *
+ * Derived from "crypto/des.c"
+ * Copyright (c) 1992 Dana L. How.
+ * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de>
+ * Copyright (c) Gisle Sflensminde <gisle@ii.uib.no>
+ * Copyright (C) 2001 Niels Mvller.
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+
+#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o))
+
+static const u8 parity[] = {
+ 8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
+ 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+ 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+ 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+ 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+ 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+ 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+ 4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
+};
+
+/*
+ * RFC2451: Weak key checks SHOULD be performed.
+ */
+int
+crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags)
+{
+ u32 n, w;
+
+ n = parity[key[0]]; n <<= 4;
+ n |= parity[key[1]]; n <<= 4;
+ n |= parity[key[2]]; n <<= 4;
+ n |= parity[key[3]]; n <<= 4;
+ n |= parity[key[4]]; n <<= 4;
+ n |= parity[key[5]]; n <<= 4;
+ n |= parity[key[6]]; n <<= 4;
+ n |= parity[key[7]];
+ w = 0x88888888L;
+
+ if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
+ && !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */
+ if (n < 0x41415151) {
+ if (n < 0x31312121) {
+ if (n < 0x14141515) {
+ /* 01 01 01 01 01 01 01 01 */
+ if (n == 0x11111111) goto weak;
+ /* 01 1F 01 1F 01 0E 01 0E */
+ if (n == 0x13131212) goto weak;
+ } else {
+ /* 01 E0 01 E0 01 F1 01 F1 */
+ if (n == 0x14141515) goto weak;
+ /* 01 FE 01 FE 01 FE 01 FE */
+ if (n == 0x16161616) goto weak;
+ }
+ } else {
+ if (n < 0x34342525) {
+ /* 1F 01 1F 01 0E 01 0E 01 */
+ if (n == 0x31312121) goto weak;
+ /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
+ if (n == 0x33332222) goto weak;
+ } else {
+ /* 1F E0 1F E0 0E F1 0E F1 */
+ if (n == 0x34342525) goto weak;
+ /* 1F FE 1F FE 0E FE 0E FE */
+ if (n == 0x36362626) goto weak;
+ }
+ }
+ } else {
+ if (n < 0x61616161) {
+ if (n < 0x44445555) {
+ /* E0 01 E0 01 F1 01 F1 01 */
+ if (n == 0x41415151) goto weak;
+ /* E0 1F E0 1F F1 0E F1 0E */
+ if (n == 0x43435252) goto weak;
+ } else {
+ /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
+ if (n == 0x44445555) goto weak;
+ /* E0 FE E0 FE F1 FE F1 FE */
+ if (n == 0x46465656) goto weak;
+ }
+ } else {
+ if (n < 0x64646565) {
+ /* FE 01 FE 01 FE 01 FE 01 */
+ if (n == 0x61616161) goto weak;
+ /* FE 1F FE 1F FE 0E FE 0E */
+ if (n == 0x63636262) goto weak;
+ } else {
+ /* FE E0 FE E0 FE F1 FE F1 */
+ if (n == 0x64646565) goto weak;
+ /* FE FE FE FE FE FE FE FE */
+ if (n == 0x66666666) goto weak;
+ }
+ }
+ }
+ }
+ return 0;
+weak:
+ *flags |= CRYPTO_TFM_RES_WEAK_KEY;
+ return -EINVAL;
+}
+
+EXPORT_SYMBOL(crypto_des_check_key);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Key Check function for DES & DES3 Cipher Algorithms");
diff --git a/arch/s390/crypto/des_z990.c b/arch/s390/crypto/des_z990.c
new file mode 100644
index 000000000000..813cf37b1177
--- /dev/null
+++ b/arch/s390/crypto/des_z990.c
@@ -0,0 +1,284 @@
+/*
+ * Cryptographic API.
+ *
+ * z990 implementation of the DES Cipher Algorithm.
+ *
+ * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Thomas Spatzier (tspat@de.ibm.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.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+#include "crypt_z990.h"
+#include "crypto_des.h"
+
+#define DES_BLOCK_SIZE 8
+#define DES_KEY_SIZE 8
+
+#define DES3_128_KEY_SIZE (2 * DES_KEY_SIZE)
+#define DES3_128_BLOCK_SIZE DES_BLOCK_SIZE
+
+#define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE)
+#define DES3_192_BLOCK_SIZE DES_BLOCK_SIZE
+
+struct crypt_z990_des_ctx {
+ u8 iv[DES_BLOCK_SIZE];
+ u8 key[DES_KEY_SIZE];
+};
+
+struct crypt_z990_des3_128_ctx {
+ u8 iv[DES_BLOCK_SIZE];
+ u8 key[DES3_128_KEY_SIZE];
+};
+
+struct crypt_z990_des3_192_ctx {
+ u8 iv[DES_BLOCK_SIZE];
+ u8 key[DES3_192_KEY_SIZE];
+};
+
+static int
+des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ struct crypt_z990_des_ctx *dctx;
+ int ret;
+
+ dctx = ctx;
+ //test if key is valid (not a weak key)
+ ret = crypto_des_check_key(key, keylen, flags);
+ if (ret == 0){
+ memcpy(dctx->key, key, keylen);
+ }
+ return ret;
+}
+
+
+static void
+des_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct crypt_z990_des_ctx *dctx;
+
+ dctx = ctx;
+ crypt_z990_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+}
+
+static void
+des_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct crypt_z990_des_ctx *dctx;
+
+ dctx = ctx;
+ crypt_z990_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+}
+
+static struct crypto_alg des_alg = {
+ .cra_name = "des",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_z990_des_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = DES_KEY_SIZE,
+ .cia_max_keysize = DES_KEY_SIZE,
+ .cia_setkey = des_setkey,
+ .cia_encrypt = des_encrypt,
+ .cia_decrypt = des_decrypt } }
+};
+
+/*
+ * RFC2451:
+ *
+ * For DES-EDE3, there is no known need to reject weak or
+ * complementation keys. Any weakness is obviated by the use of
+ * multiple keys.
+ *
+ * However, if the two independent 64-bit keys are equal,
+ * then the DES3 operation is simply the same as DES.
+ * Implementers MUST reject keys that exhibit this property.
+ *
+ */
+static int
+des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ int i, ret;
+ struct crypt_z990_des3_128_ctx *dctx;
+ const u8* temp_key = key;
+
+ dctx = ctx;
+ if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
+
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
+ return -EINVAL;
+ }
+ for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
+ ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
+ if (ret < 0)
+ return ret;
+ }
+ memcpy(dctx->key, key, keylen);
+ return 0;
+}
+
+static void
+des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct crypt_z990_des3_128_ctx *dctx;
+
+ dctx = ctx;
+ crypt_z990_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
+ DES3_128_BLOCK_SIZE);
+}
+
+static void
+des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct crypt_z990_des3_128_ctx *dctx;
+
+ dctx = ctx;
+ crypt_z990_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
+ DES3_128_BLOCK_SIZE);
+}
+
+static struct crypto_alg des3_128_alg = {
+ .cra_name = "des3_ede128",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES3_128_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_z990_des3_128_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = DES3_128_KEY_SIZE,
+ .cia_max_keysize = DES3_128_KEY_SIZE,
+ .cia_setkey = des3_128_setkey,
+ .cia_encrypt = des3_128_encrypt,
+ .cia_decrypt = des3_128_decrypt } }
+};
+
+/*
+ * RFC2451:
+ *
+ * For DES-EDE3, there is no known need to reject weak or
+ * complementation keys. Any weakness is obviated by the use of
+ * multiple keys.
+ *
+ * However, if the first two or last two independent 64-bit keys are
+ * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
+ * same as DES. Implementers MUST reject keys that exhibit this
+ * property.
+ *
+ */
+static int
+des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ int i, ret;
+ struct crypt_z990_des3_192_ctx *dctx;
+ const u8* temp_key;
+
+ dctx = ctx;
+ temp_key = key;
+ if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
+ memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
+ DES_KEY_SIZE))) {
+
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
+ return -EINVAL;
+ }
+ for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
+ ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
+ if (ret < 0){
+ return ret;
+ }
+ }
+ memcpy(dctx->key, key, keylen);
+ return 0;
+}
+
+static void
+des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct crypt_z990_des3_192_ctx *dctx;
+
+ dctx = ctx;
+ crypt_z990_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
+ DES3_192_BLOCK_SIZE);
+}
+
+static void
+des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct crypt_z990_des3_192_ctx *dctx;
+
+ dctx = ctx;
+ crypt_z990_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
+ DES3_192_BLOCK_SIZE);
+}
+
+static struct crypto_alg des3_192_alg = {
+ .cra_name = "des3_ede",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES3_192_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_z990_des3_192_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = DES3_192_KEY_SIZE,
+ .cia_max_keysize = DES3_192_KEY_SIZE,
+ .cia_setkey = des3_192_setkey,
+ .cia_encrypt = des3_192_encrypt,
+ .cia_decrypt = des3_192_decrypt } }
+};
+
+
+
+static int
+init(void)
+{
+ int ret;
+
+ if (!crypt_z990_func_available(KM_DEA_ENCRYPT) ||
+ !crypt_z990_func_available(KM_TDEA_128_ENCRYPT) ||
+ !crypt_z990_func_available(KM_TDEA_192_ENCRYPT)){
+ return -ENOSYS;
+ }
+
+ ret = 0;
+ ret |= (crypto_register_alg(&des_alg) == 0)? 0:1;
+ ret |= (crypto_register_alg(&des3_128_alg) == 0)? 0:2;
+ ret |= (crypto_register_alg(&des3_192_alg) == 0)? 0:4;
+ if (ret){
+ crypto_unregister_alg(&des3_192_alg);
+ crypto_unregister_alg(&des3_128_alg);
+ crypto_unregister_alg(&des_alg);
+ return -EEXIST;
+ }
+
+ printk(KERN_INFO "crypt_z990: des_z990 loaded.\n");
+ return 0;
+}
+
+static void __exit
+fini(void)
+{
+ crypto_unregister_alg(&des3_192_alg);
+ crypto_unregister_alg(&des3_128_alg);
+ crypto_unregister_alg(&des_alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_ALIAS("des");
+MODULE_ALIAS("des3_ede");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
diff --git a/arch/s390/crypto/sha1_z990.c b/arch/s390/crypto/sha1_z990.c
new file mode 100644
index 000000000000..298174ddf5b1
--- /dev/null
+++ b/arch/s390/crypto/sha1_z990.c
@@ -0,0 +1,167 @@
+/*
+ * Cryptographic API.
+ *
+ * z990 implementation of the SHA1 Secure Hash Algorithm.
+ *
+ * Derived from cryptoapi implementation, adapted for in-place
+ * scatterlist interface. Originally based on the public domain
+ * implementation written by Steve Reid.
+ *
+ * s390 Version:
+ * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation
+ * Author(s): Thomas Spatzier (tspat@de.ibm.com)
+ *
+ * Derived from "crypto/sha1.c"
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.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 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+#include "crypt_z990.h"
+
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_BLOCK_SIZE 64
+
+struct crypt_z990_sha1_ctx {
+ u64 count;
+ u32 state[5];
+ u32 buf_len;
+ u8 buffer[2 * SHA1_BLOCK_SIZE];
+};
+
+static void
+sha1_init(void *ctx)
+{
+ static const struct crypt_z990_sha1_ctx initstate = {
+ .state = {
+ 0x67452301,
+ 0xEFCDAB89,
+ 0x98BADCFE,
+ 0x10325476,
+ 0xC3D2E1F0
+ },
+ };
+ memcpy(ctx, &initstate, sizeof(initstate));
+}
+
+static void
+sha1_update(void *ctx, const u8 *data, unsigned int len)
+{
+ struct crypt_z990_sha1_ctx *sctx;
+ long imd_len;
+
+ sctx = ctx;
+ sctx->count += len * 8; //message bit length
+
+ //anything in buffer yet? -> must be completed
+ if (sctx->buf_len && (sctx->buf_len + len) >= SHA1_BLOCK_SIZE) {
+ //complete full block and hash
+ memcpy(sctx->buffer + sctx->buf_len, data,
+ SHA1_BLOCK_SIZE - sctx->buf_len);
+ crypt_z990_kimd(KIMD_SHA_1, sctx->state, sctx->buffer,
+ SHA1_BLOCK_SIZE);
+ data += SHA1_BLOCK_SIZE - sctx->buf_len;
+ len -= SHA1_BLOCK_SIZE - sctx->buf_len;
+ sctx->buf_len = 0;
+ }
+
+ //rest of data contains full blocks?
+ imd_len = len & ~0x3ful;
+ if (imd_len){
+ crypt_z990_kimd(KIMD_SHA_1, sctx->state, data, imd_len);
+ data += imd_len;
+ len -= imd_len;
+ }
+ //anything left? store in buffer
+ if (len){
+ memcpy(sctx->buffer + sctx->buf_len , data, len);
+ sctx->buf_len += len;
+ }
+}
+
+
+static void
+pad_message(struct crypt_z990_sha1_ctx* sctx)
+{
+ int index;
+
+ index = sctx->buf_len;
+ sctx->buf_len = (sctx->buf_len < 56)?
+ SHA1_BLOCK_SIZE:2 * SHA1_BLOCK_SIZE;
+ //start pad with 1
+ sctx->buffer[index] = 0x80;
+ //pad with zeros
+ index++;
+ memset(sctx->buffer + index, 0x00, sctx->buf_len - index);
+ //append length
+ memcpy(sctx->buffer + sctx->buf_len - 8, &sctx->count,
+ sizeof sctx->count);
+}
+
+/* Add padding and return the message digest. */
+static void
+sha1_final(void* ctx, u8 *out)
+{
+ struct crypt_z990_sha1_ctx *sctx = ctx;
+
+ //must perform manual padding
+ pad_message(sctx);
+ crypt_z990_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len);
+ //copy digest to out
+ memcpy(out, sctx->state, SHA1_DIGEST_SIZE);
+ /* Wipe context */
+ memset(sctx, 0, sizeof *sctx);
+}
+
+static struct crypto_alg alg = {
+ .cra_name = "sha1",
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_z990_sha1_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(alg.cra_list),
+ .cra_u = { .digest = {
+ .dia_digestsize = SHA1_DIGEST_SIZE,
+ .dia_init = sha1_init,
+ .dia_update = sha1_update,
+ .dia_final = sha1_final } }
+};
+
+static int
+init(void)
+{
+ int ret = -ENOSYS;
+
+ if (crypt_z990_func_available(KIMD_SHA_1)){
+ ret = crypto_register_alg(&alg);
+ if (ret == 0){
+ printk(KERN_INFO "crypt_z990: sha1_z990 loaded.\n");
+ }
+ }
+ return ret;
+}
+
+static void __exit
+fini(void)
+{
+ crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_ALIAS("sha1");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 574c1b2a9d06..8e95f1a00b11 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -18,8 +18,10 @@ CONFIG_STANDALONE=y
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HOTPLUG=y
CONFIG_IKCONFIG=y
@@ -31,6 +33,7 @@ CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
#
@@ -231,8 +234,6 @@ CONFIG_IPV6=y
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
# CONFIG_NETFILTER is not set
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
@@ -242,7 +243,9 @@ CONFIG_XFRM=y
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
@@ -286,6 +289,11 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
@@ -305,20 +313,16 @@ CONFIG_NET_ETHERNET=y
#
# Ethernet (10000 Mbit)
#
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
#
-# Wireless LAN (non-hamradio)
+# Token Ring devices
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
#
-# Token Ring devices
+# Wireless LAN (non-hamradio)
#
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
+# CONFIG_NET_RADIO is not set
#
# Wan interfaces
@@ -341,23 +345,10 @@ CONFIG_QETH=y
# CONFIG_QETH_IPV6 is not set
# CONFIG_QETH_PERF_STATS is not set
CONFIG_CCWGROUP=y
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
# File systems
@@ -397,6 +388,7 @@ CONFIG_FS_MBCACHE=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
@@ -493,9 +485,11 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_Z990 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_DES_Z990 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index 0cc8e5be48ba..b68ace7e2e4f 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -33,6 +33,8 @@
#define NUM_ACRS 16
#define TASK31_SIZE (0x80000000UL)
+#undef TASK_SIZE
+#define TASK_SIZE TASK31_SIZE
/* For SVR4/S390 the function pointer to be registered with `atexit` is
passed in R14. */
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 566277b9409c..df06185d54c2 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -297,64 +297,46 @@ static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
*/
asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
{
- if(call >> 16) /* hack for backward compatibility */
+ if (call >> 16) /* hack for backward compatibility */
return -EINVAL;
call &= 0xffff;
- if (call <= SEMTIMEDOP)
- switch (call) {
- case SEMTIMEDOP:
- if (third)
- return compat_sys_semtimedop(first,
- compat_ptr(ptr), second,
- compat_ptr(third));
- /* else fall through for normal semop() */
- case SEMOP:
- /* struct sembuf is the same on 32 and 64bit :)) */
- return sys_semtimedop (first, compat_ptr(ptr),
- second, NULL);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL:
- return compat_sys_semctl (first, second, third,
- compat_ptr(ptr));
- default:
- return -EINVAL;
- };
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return compat_sys_msgsnd (first, second, third,
- compat_ptr(ptr));
- case MSGRCV:
- return compat_sys_msgrcv (first, second, 0, third,
- 0, compat_ptr(ptr));
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return compat_sys_msgctl (first, second,
- compat_ptr(ptr));
- default:
- return -EINVAL;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- return compat_sys_shmat (first, second, third,
- 0, compat_ptr(ptr));
- case SHMDT:
- return sys_shmdt(compat_ptr(ptr));
- case SHMGET:
- return sys_shmget(first, second, third);
- case SHMCTL:
- return compat_sys_shmctl(first, second,
- compat_ptr(ptr));
- default:
- return -EINVAL;
- }
+ switch (call) {
+ case SEMTIMEDOP:
+ return compat_sys_semtimedop(first, compat_ptr(ptr),
+ second, compat_ptr(third));
+ case SEMOP:
+ /* struct sembuf is the same on 32 and 64bit :)) */
+ return sys_semtimedop(first, compat_ptr(ptr),
+ second, NULL);
+ case SEMGET:
+ return sys_semget(first, second, third);
+ case SEMCTL:
+ return compat_sys_semctl(first, second, third,
+ compat_ptr(ptr));
+ case MSGSND:
+ return compat_sys_msgsnd(first, second, third,
+ compat_ptr(ptr));
+ case MSGRCV:
+ return compat_sys_msgrcv(first, second, 0, third,
+ 0, compat_ptr(ptr));
+ case MSGGET:
+ return sys_msgget((key_t) first, second);
+ case MSGCTL:
+ return compat_sys_msgctl(first, second, compat_ptr(ptr));
+ case SHMAT:
+ return compat_sys_shmat(first, second, third,
+ 0, compat_ptr(ptr));
+ case SHMDT:
+ return sys_shmdt(compat_ptr(ptr));
+ case SHMGET:
+ return sys_shmget(first, second, third);
+ case SHMCTL:
+ return compat_sys_shmctl(first, second, compat_ptr(ptr));
+ }
- return -EINVAL;
+ return -ENOSYS;
}
asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low)
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 043c25b7b8f9..66861b95da68 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1361,7 +1361,7 @@ compat_sys_mq_open_wrapper:
llgtr %r5,%r5 # struct compat_mq_attr *
jg compat_sys_mq_open
- .globl sys_mq_unlink_wrapper
+ .globl sys32_mq_unlink_wrapper
sys32_mq_unlink_wrapper:
llgtr %r2,%r2 # const char *
jg sys_mq_unlink
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 37520c7e71be..d5a9e1cdac09 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -198,7 +198,8 @@ __switch_to_noper:
*/
.global do_call_softirq
do_call_softirq:
- stm %r12,%r15,24(%r15)
+ stnsm 24(%r15),0xfc
+ stm %r12,%r15,28(%r15)
lr %r12,%r15
basr %r13,0
do_call_base:
@@ -211,7 +212,8 @@ do_call_base:
st %r12,0(%r15) # store backchain
l %r1,.Ldo_softirq-do_call_base(%r13)
basr %r14,%r1
- lm %r12,%r15,24(%r12)
+ lm %r12,%r15,28(%r12)
+ ssm 24(%r15)
br %r14
__critical_start:
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 89c52f6b35fe..e94e694d512c 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -186,7 +186,8 @@ __switch_to_noper:
*/
.global do_call_softirq
do_call_softirq:
- stmg %r12,%r15,48(%r15)
+ stnsm 48(%r15),0xfc
+ stmg %r12,%r15,56(%r15)
lgr %r12,%r15
lg %r0,__LC_ASYNC_STACK
slgr %r0,%r15
@@ -196,7 +197,8 @@ do_call_softirq:
0: aghi %r15,-STACK_FRAME_OVERHEAD
stg %r12,0(%r15) # store back chain
brasl %r14,do_softirq
- lmg %r12,%r15,48(%r12)
+ lmg %r12,%r15,56(%r12)
+ ssm 48(%r15)
br %r14
__critical_start:
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 7f0e45e001f0..7ca8a8706cca 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -254,13 +254,13 @@ void (*_machine_power_off)(void) = machine_power_off_smp;
/*
* Reboot, halt and power_off routines for non SMP.
*/
-extern void do_reipl(unsigned long devno);
+extern void reipl(unsigned long devno);
static void do_machine_restart_nonsmp(char * __unused)
{
if (MACHINE_IS_VM)
cpcmd ("IPL", NULL, 0);
else
- do_reipl (0x10000 | S390_lowcore.ipl_device);
+ reipl (0x10000 | S390_lowcore.ipl_device);
}
static void do_machine_halt_nonsmp(void)
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 2ee07a475716..de99f63ec951 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(cpu_online_map);
extern char vmhalt_cmd[];
extern char vmpoff_cmd[];
-extern void do_reipl(unsigned long devno);
+extern void reipl(unsigned long devno);
static void smp_ext_bitcall(int, ec_bit_sig);
static void smp_ext_bitcall_others(ec_bit_sig);
@@ -278,7 +278,7 @@ static void do_machine_restart(void * __unused)
if (MACHINE_IS_VM)
cpcmd ("IPL", NULL, 0);
else
- do_reipl (0x10000 | S390_lowcore.ipl_device);
+ reipl (0x10000 | S390_lowcore.ipl_device);
}
signal_processor(smp_processor_id(), sigp_stop);
}
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index d778f98a2c7c..016eb6cd48c9 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -105,17 +105,6 @@ void show_trace(struct task_struct *task, unsigned long * stack)
printk("\n");
}
-void show_trace_task(struct task_struct *tsk)
-{
- /*
- * We can't print the backtrace of a running process. It is
- * unreliable at best and can cause kernel oopses.
- */
- if (tsk->state == TASK_RUNNING)
- return;
- show_trace(tsk, (unsigned long *) tsk->thread.ksp);
-}
-
void show_stack(struct task_struct *task, unsigned long *sp)
{
unsigned long *stack;
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 5211a375afa8..3e63d8a70ed3 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -705,14 +705,8 @@ void show_task(unsigned long *sp)
show_stack(NULL, sp);
}
-void show_trace_task(struct task_struct *tsk)
-{
- show_task((unsigned long *)tsk->thread.sp);
-}
-
void dump_stack(void)
{
show_stack(NULL, NULL);
}
-
EXPORT_SYMBOL(dump_stack);
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 3cf8af39ac95..47d685193ade 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1760,13 +1760,6 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
#endif
}
-void show_trace_task(struct task_struct *tsk)
-{
- if (tsk)
- show_stack(tsk,
- (unsigned long *) tsk->thread_info->ksp);
-}
-
void dump_stack(void)
{
unsigned long *ksp;
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 078dc11132d3..ce108f7d6971 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -42,19 +42,8 @@ void dump_stack(void)
show_trace(&stack);
}
-
EXPORT_SYMBOL(dump_stack);
-void show_trace_task(struct task_struct *tsk)
-{
- unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
-
- /* User space on another CPU? */
- if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
- return;
- show_trace((unsigned long *)esp);
-}
-
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index 977d75772d81..2fccb4cc7b82 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -234,10 +234,3 @@ unsigned long get_wchan (struct task_struct *p)
return 0;
}
-
-void show_trace_task (struct task_struct *t)
-{
- /* blarg XXX */
- printk ("show_trace_task: KSP = 0x%lx, USP = 0x%lx, UPC = 0x%lx\n",
- t->thread.ksp, KSTK_ESP (t), KSTK_EIP (t));
-}
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 5afe235c0474..2efdbaa1ecfa 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -197,16 +197,6 @@ void show_trace(unsigned long *stack)
printk("\n");
}
-void show_trace_task(struct task_struct *tsk)
-{
- unsigned long rsp = tsk->thread.rsp;
-
- /* User space on another CPU? */
- if ((rsp ^ (unsigned long)tsk->thread_info) & (PAGE_MASK<<1))
- return;
- show_trace((unsigned long *)rsp);
-}
-
void show_stack(struct task_struct *tsk, unsigned long * rsp)
{
unsigned long *stack;
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4b0925ea142b..d7c9d552fd8b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -40,6 +40,12 @@ config CRYPTO_SHA1
help
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
+config CRYPTO_SHA1_Z990
+ tristate "SHA1 digest algorithm for IBM zSeries z990"
+ depends on CRYPTO && ARCH_S390
+ help
+ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
+
config CRYPTO_SHA256
tristate "SHA256 digest algorithm"
depends on CRYPTO
@@ -67,6 +73,12 @@ config CRYPTO_DES
help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
+config CRYPTO_DES_Z990
+ tristate "DES and Triple DES cipher algorithms for IBM zSeries z990"
+ depends on CRYPTO && ARCH_S390
+ help
+ DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
+
config CRYPTO_BLOWFISH
tristate "Blowfish cipher algorithm"
depends on CRYPTO
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index b1d5dfa351ff..9d2759d8aa92 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -39,6 +39,8 @@
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/completion.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <asm/bug.h>
@@ -132,7 +134,12 @@ struct cdrom_info {
char type[4];
char model[3];
};
-static struct cdrom_info viocd_unitinfo[VIOCD_MAX_CD];
+/*
+ * This needs to be allocated since it is passed to the
+ * Hypervisor and we may be a module.
+ */
+static struct cdrom_info *viocd_unitinfo;
+static dma_addr_t unitinfo_dmaaddr;
struct disk_info {
struct gendisk *viocd_disk;
@@ -141,13 +148,39 @@ struct disk_info {
static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
#define DEVICE_NR(di) ((di) - &viocd_diskinfo[0])
-#define VIOCDI viocd_diskinfo[deviceno].viocd_info
static request_queue_t *viocd_queue;
static spinlock_t viocd_reqlock;
#define MAX_CD_REQ 1
+/* procfs support */
+static int proc_viocd_show(struct seq_file *m, void *v)
+{
+ int i;
+
+ for (i = 0; i < viocd_numdev; i++) {
+ seq_printf(m, "viocd device %d is iSeries resource %10.10s"
+ "type %4.4s, model %3.3s\n",
+ i, viocd_unitinfo[i].rsrcname,
+ viocd_unitinfo[i].type,
+ viocd_unitinfo[i].model);
+ }
+ return 0;
+}
+
+static int proc_viocd_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_viocd_show, NULL);
+}
+
+static struct file_operations proc_viocd_operations = {
+ .open = proc_viocd_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int viocd_blk_open(struct inode *inode, struct file *file)
{
struct disk_info *di = inode->i_bdev->bd_disk->private_data;
@@ -184,18 +217,20 @@ struct block_device_operations viocd_fops = {
/* Get info on CD devices from OS/400 */
static void __init get_viocd_info(void)
{
- dma_addr_t dmaaddr;
HvLpEvent_Rc hvrc;
int i;
struct viocd_waitevent we;
- dmaaddr = dma_map_single(iSeries_vio_dev, viocd_unitinfo,
- sizeof(viocd_unitinfo), DMA_FROM_DEVICE);
- if (dmaaddr == (dma_addr_t)-1) {
- printk(VIOCD_KERN_WARNING "error allocating tce\n");
+ viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev,
+ sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
+ &unitinfo_dmaaddr, GFP_ATOMIC);
+ if (viocd_unitinfo == NULL) {
+ printk(VIOCD_KERN_WARNING "error allocating unitinfo\n");
return;
}
+ memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD);
+
init_completion(&we.com);
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
@@ -204,29 +239,34 @@ static void __init get_viocd_info(void)
HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
viopath_sourceinst(viopath_hostLp),
viopath_targetinst(viopath_hostLp),
- (u64)&we, VIOVERSION << 16, dmaaddr, 0,
- sizeof(viocd_unitinfo), 0);
+ (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
+ sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0);
if (hvrc != HvLpEvent_Rc_Good) {
printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n",
(int)hvrc);
- return;
+ goto error_ret;
}
wait_for_completion(&we.com);
- dma_unmap_single(iSeries_vio_dev, dmaaddr, sizeof(viocd_unitinfo),
- DMA_FROM_DEVICE);
-
if (we.rc) {
const struct vio_error_entry *err =
vio_lookup_rc(viocd_err_table, we.sub_result);
printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n",
we.rc, we.sub_result, err->msg);
- return;
+ goto error_ret;
}
for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++)
viocd_numdev++;
+
+ return;
+
+error_ret:
+ dma_free_coherent(iSeries_vio_dev,
+ sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
+ viocd_unitinfo, unitinfo_dmaaddr);
+ viocd_unitinfo = NULL;
}
static int viocd_open(struct cdrom_device_info *cdi, int purpose)
@@ -307,10 +347,6 @@ static int send_request(struct request *req)
}
dmaaddr = sg_dma_address(&sg);
len = sg_dma_len(&sg);
- if (dmaaddr == (dma_addr_t)-1) {
- printk(VIOCD_KERN_WARNING "error allocating tce\n");
- return -1;
- }
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
HvLpEvent_Type_VirtualIo,
@@ -534,6 +570,7 @@ static int __init viocd_init(void)
struct gendisk *gendisk;
int deviceno;
int ret = 0;
+ struct proc_dir_entry *e;
if (viopath_hostLp == HvLpIndexInvalid) {
vio_set_hostlp();
@@ -604,7 +641,7 @@ static int __init viocd_init(void)
printk(VIOCD_KERN_WARNING
"Cannot create gendisk for %s!\n",
c->name);
- unregister_cdrom(&VIOCDI);
+ unregister_cdrom(c);
continue;
}
gendisk->major = VIOCD_MAJOR;
@@ -622,6 +659,12 @@ static int __init viocd_init(void)
add_disk(gendisk);
}
+ e = create_proc_entry("iSeries/viocd", S_IFREG|S_IRUGO, NULL);
+ if (e) {
+ e->owner = THIS_MODULE;
+ e->proc_fops = &proc_viocd_operations;
+ }
+
return 0;
out_undo_vio:
@@ -636,6 +679,7 @@ static void __exit viocd_exit(void)
{
int deviceno;
+ remove_proc_entry("iSeries/viocd", NULL);
for (deviceno = 0; deviceno < viocd_numdev; deviceno++) {
struct disk_info *d = &viocd_diskinfo[deviceno];
if (unregister_cdrom(&d->viocd_info) != 0)
@@ -646,7 +690,10 @@ static void __exit viocd_exit(void)
put_disk(d->viocd_disk);
}
blk_cleanup_queue(viocd_queue);
-
+ if (viocd_unitinfo != NULL)
+ dma_free_coherent(iSeries_vio_dev,
+ sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
+ viocd_unitinfo, unitinfo_dmaaddr);
viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
vio_clearHandler(viomajorsubtype_cdio);
unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE);
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 3f2b43fe4ac6..a5915c1e764b 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -47,6 +47,8 @@
#include <linux/devfs_fs_kernel.h>
#include <linux/major.h>
#include <linux/completion.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
@@ -56,7 +58,7 @@
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/HvLpConfig.h>
-#define VIOTAPE_VERSION "1.1"
+#define VIOTAPE_VERSION "1.2"
#define VIOTAPE_MAXREQ 1
#define VIOTAPE_KERN_WARN KERN_WARNING "viotape: "
@@ -269,6 +271,34 @@ static struct op_struct *op_struct_list;
/* forward declaration to resolve interdependence */
static int chg_state(int index, unsigned char new_state, struct file *file);
+/* procfs support */
+static int proc_viotape_show(struct seq_file *m, void *v)
+{
+ int i;
+
+ seq_printf(m, "viotape driver version " VIOTAPE_VERSION "\n");
+ for (i = 0; i < viotape_numdev; i++) {
+ seq_printf(m, "viotape device %d is iSeries resource %10.10s"
+ "type %4.4s, model %3.3s\n",
+ i, viotape_unitinfo[i].rsrcname,
+ viotape_unitinfo[i].type,
+ viotape_unitinfo[i].model);
+ }
+ return 0;
+}
+
+static int proc_viotape_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_viotape_show, NULL);
+}
+
+static struct file_operations proc_viotape_operations = {
+ .open = proc_viotape_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* Decode the device minor number into its parts */
void get_dev_info(struct inode *ino, struct viot_devinfo_struct *devi)
{
@@ -912,6 +942,7 @@ int __init viotap_init(void)
int ret;
char tapename[32];
int i;
+ struct proc_dir_entry *e;
op_struct_list = NULL;
if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) {
@@ -988,6 +1019,12 @@ int __init viotap_init(void)
viotape_unitinfo[i].model);
}
+ e = create_proc_entry("iSeries/viotape", S_IFREG|S_IRUGO, NULL);
+ if (e) {
+ e->owner = THIS_MODULE;
+ e->proc_fops = &proc_viotape_operations;
+ }
+
return 0;
unreg_class:
@@ -1029,6 +1066,8 @@ static void __exit viotap_exit(void)
{
int i, ret;
+ remove_proc_entry("iSeries/viotape", NULL);
+
for (i = 0; i < viotape_numdev; ++i) {
devfs_remove("iseries/nvt%d", i);
devfs_remove("iseries/vt%d", i);
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 79c9cb80fd0a..ac2246dd7646 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -86,7 +86,7 @@ static struct edd_device *edd_devices[EDDMAXNR];
#define EDD_DEVICE_ATTR(_name,_mode,_show,_test) \
struct edd_attribute edd_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.test = _test, \
};
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index 10a54ddd2540..cacd1f20ea5f 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -130,3 +130,13 @@ config SERIO_PCIPS2
To compile this driver as a module, choose M here: the
module will be called pcips2.
+
+config SERIO_MACEPS2
+ tristate "SGI O2 MACE PS/2 controller"
+ depends on SGI_IP32 && SERIO
+ help
+ Say Y here if you have SGI O2 workstation and want to use its
+ PS/2 ports.
+
+ To compile this driver as a module, choose M here: the
+ module will be called maceps2.
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 2eb86eba6ed9..a47dec2556e8 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o
obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o
obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o
obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
+obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index 6b434f8b62f1..9b36485fc605 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -69,7 +69,7 @@ static inline int i8042_platform_init(void)
* On ix86 platforms touching the i8042 data register region can do really
* bad things. Because of this the region is always reserved on ix86 boxes.
*/
-#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__)
+#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__) && !defined(__mips__)
if (!request_region(I8042_DATA_REG, 16, "i8042"))
return -1;
#endif
diff --git a/drivers/input/serio/i8042-ip22io.h b/drivers/input/serio/i8042-ip22io.h
new file mode 100644
index 000000000000..863b9c95fbb8
--- /dev/null
+++ b/drivers/input/serio/i8042-ip22io.h
@@ -0,0 +1,76 @@
+#ifndef _I8042_IP22_H
+#define _I8042_IP22_H
+
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/ip22.h>
+
+/*
+ * 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 published by
+ * the Free Software Foundation.
+ */
+
+/*
+ * Names.
+ */
+
+#define I8042_KBD_PHYS_DESC "hpc3ps2/serio0"
+#define I8042_AUX_PHYS_DESC "hpc3ps2/serio1"
+#define I8042_MUX_PHYS_DESC "hpc3ps2/serio%d"
+
+/*
+ * IRQs.
+ */
+
+#define I8042_KBD_IRQ SGI_KEYBD_IRQ
+#define I8042_AUX_IRQ SGI_KEYBD_IRQ
+
+/*
+ * Register numbers.
+ */
+
+#define I8042_COMMAND_REG ((unsigned long)&sgioc->kbdmouse.command)
+#define I8042_STATUS_REG ((unsigned long)&sgioc->kbdmouse.command)
+#define I8042_DATA_REG ((unsigned long)&sgioc->kbdmouse.data)
+
+static inline int i8042_read_data(void)
+{
+ return sgioc->kbdmouse.data;
+}
+
+static inline int i8042_read_status(void)
+{
+ return sgioc->kbdmouse.command;
+}
+
+static inline void i8042_write_data(int val)
+{
+ sgioc->kbdmouse.data = val;
+}
+
+static inline void i8042_write_command(int val)
+{
+ sgioc->kbdmouse.command = val;
+}
+
+static inline int i8042_platform_init(void)
+{
+#if 0
+ /* XXX sgi_kh is a virtual address */
+ if (!request_mem_region(sgi_kh, sizeof(struct hpc_keyb), "i8042"))
+ return 1;
+#endif
+
+ i8042_reset = 1;
+
+ return 0;
+}
+
+static inline void i8042_platform_exit(void)
+{
+#if 0
+ release_mem_region(JAZZ_KEYBOARD_ADDRESS, sizeof(struct hpc_keyb));
+#endif
+}
+
+#endif /* _I8042_IP22_H */
diff --git a/drivers/input/serio/i8042-jazzio.h b/drivers/input/serio/i8042-jazzio.h
new file mode 100644
index 000000000000..5c20ab131488
--- /dev/null
+++ b/drivers/input/serio/i8042-jazzio.h
@@ -0,0 +1,69 @@
+#ifndef _I8042_JAZZ_H
+#define _I8042_JAZZ_H
+
+#include <asm/jazz.h>
+
+/*
+ * 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 published by
+ * the Free Software Foundation.
+ */
+
+/*
+ * Names.
+ */
+
+#define I8042_KBD_PHYS_DESC "R4030/serio0"
+#define I8042_AUX_PHYS_DESC "R4030/serio1"
+#define I8042_MUX_PHYS_DESC "R4030/serio%d"
+
+/*
+ * IRQs.
+ */
+
+#define I8042_KBD_IRQ JAZZ_KEYBOARD_IRQ
+#define I8042_AUX_IRQ JAZZ_MOUSE_IRQ
+
+#define I8042_COMMAND_REG ((unsigned long)&jazz_kh->command)
+#define I8042_STATUS_REG ((unsigned long)&jazz_kh->command)
+#define I8042_DATA_REG ((unsigned long)&jazz_kh->data)
+
+static inline int i8042_read_data(void)
+{
+ return jazz_kh->data;
+}
+
+static inline int i8042_read_status(void)
+{
+ return jazz_kh->command;
+}
+
+static inline void i8042_write_data(int val)
+{
+ jazz_kh->data = val;
+}
+
+static inline void i8042_write_command(int val)
+{
+ jazz_kh->command = val;
+}
+
+static inline int i8042_platform_init(void)
+{
+#if 0
+ /* XXX JAZZ_KEYBOARD_ADDRESS is a virtual address */
+ if (!request_mem_region(JAZZ_KEYBOARD_ADDRESS, 2, "i8042"))
+ return 1;
+#endif
+
+ return 0;
+}
+
+static inline void i8042_platform_exit(void)
+{
+#if 0
+ release_mem_region(JAZZ_KEYBOARD_ADDRESS, 2);
+#endif
+}
+
+#endif /* _I8042_JAZZ_H */
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index 3d59eb2e05a7..f0f637483233 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -1,6 +1,8 @@
#ifndef _I8042_H
#define _I8042_H
+#include <linux/config.h>
+
/*
* Copyright (c) 1999-2002 Vojtech Pavlik
*
@@ -13,7 +15,11 @@
* Arch-dependent inline functions and defines.
*/
-#if defined(CONFIG_PPC)
+#if defined(CONFIG_MIPS_JAZZ)
+#include "i8042-jazzio.h"
+#elif defined(CONFIG_SGI_IP22)
+#include "i8042-ip22io.h"
+#elif defined(CONFIG_PPC)
#include "i8042-ppcio.h"
#elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
#include "i8042-sparcio.h"
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
new file mode 100644
index 000000000000..c7db1de49cfc
--- /dev/null
+++ b/drivers/input/serio/maceps2.c
@@ -0,0 +1,160 @@
+/*
+ * SGI O2 MACE PS2 controller driver for linux
+ *
+ * Copyright (C) 2002 Vivien Chappelier
+ *
+ * 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
+ * published by the Free Software Foundation
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org");
+MODULE_DESCRIPTION("SGI O2 MACE PS2 controller driver");
+MODULE_LICENSE("GPL");
+
+#define MACE_PS2_TIMEOUT 10000 /* in 50us unit */
+
+#define PS2_STATUS_CLOCK_SIGNAL BIT(0) /* external clock signal */
+#define PS2_STATUS_CLOCK_INHIBIT BIT(1) /* clken output signal */
+#define PS2_STATUS_TX_INPROGRESS BIT(2) /* transmission in progress */
+#define PS2_STATUS_TX_EMPTY BIT(3) /* empty transmit buffer */
+#define PS2_STATUS_RX_FULL BIT(4) /* full receive buffer */
+#define PS2_STATUS_RX_INPROGRESS BIT(5) /* reception in progress */
+#define PS2_STATUS_ERROR_PARITY BIT(6) /* parity error */
+#define PS2_STATUS_ERROR_FRAMING BIT(7) /* framing error */
+
+#define PS2_CONTROL_TX_CLOCK_DISABLE BIT(0) /* inhibit clock signal after TX */
+#define PS2_CONTROL_TX_ENABLE BIT(1) /* transmit enable */
+#define PS2_CONTROL_TX_INT_ENABLE BIT(2) /* enable transmit interrupt */
+#define PS2_CONTROL_RX_INT_ENABLE BIT(3) /* enable receive interrupt */
+#define PS2_CONTROL_RX_CLOCK_ENABLE BIT(4) /* pause reception if set to 0 */
+#define PS2_CONTROL_RESET BIT(5) /* reset */
+
+
+struct maceps2_data {
+ struct mace_ps2port *port;
+ int irq;
+};
+
+static int maceps2_write(struct serio *dev, unsigned char val)
+{
+ struct mace_ps2port *port = ((struct maceps2_data *)dev->driver)->port;
+ unsigned int timeout = MACE_PS2_TIMEOUT;
+
+ do {
+ if (mace_read(port->status) & PS2_STATUS_TX_EMPTY) {
+ mace_write(val, port->tx);
+ return 0;
+ }
+ udelay(50);
+ } while (timeout--);
+
+ return -1;
+}
+
+static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ struct serio *dev = dev_id;
+ struct mace_ps2port *port = ((struct maceps2_data *)dev->driver)->port;
+ unsigned int byte;
+
+ if (mace_read(port->status) & PS2_STATUS_RX_FULL) {
+ byte = mace_read(port->rx);
+ serio_interrupt(dev, byte & 0xff, 0, regs);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int maceps2_open(struct serio *dev)
+{
+ struct maceps2_data *data = (struct maceps2_data *)dev->driver;
+
+ if (request_irq(data->irq, maceps2_interrupt, 0, "PS/2 port", dev)) {
+ printk(KERN_ERR "Could not allocate PS/2 IRQ\n");
+ return -EBUSY;
+ }
+
+ /* Reset port */
+ mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
+ data->port->control);
+ udelay(100);
+
+ /* Enable interrupts */
+ mace_write(PS2_CONTROL_RX_CLOCK_ENABLE | PS2_CONTROL_TX_ENABLE |
+ PS2_CONTROL_RX_INT_ENABLE, data->port->control);
+
+ return 0;
+}
+
+static void maceps2_close(struct serio *dev)
+{
+ struct maceps2_data *data = (struct maceps2_data *)dev->driver;
+
+ mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
+ data->port->control);
+ udelay(100);
+ free_irq(data->irq, dev);
+}
+
+static struct maceps2_data port0_data, port1_data;
+
+static struct serio maceps2_port0 =
+{
+ .type = SERIO_8042,
+ .open = maceps2_open,
+ .close = maceps2_close,
+ .write = maceps2_write,
+ .name = "MACE PS/2 port0",
+ .phys = "mace/serio0",
+ .driver = &port0_data,
+};
+
+static struct serio maceps2_port1 =
+{
+ .type = SERIO_8042,
+ .open = maceps2_open,
+ .close = maceps2_close,
+ .write = maceps2_write,
+ .name = "MACE PS/2 port1",
+ .phys = "mace/serio1",
+ .driver = &port1_data,
+};
+
+static int __init maceps2_init(void)
+{
+ port0_data.port = &mace->perif.ps2.keyb;
+ port0_data.irq = MACEISA_KEYB_IRQ;
+ port1_data.port = &mace->perif.ps2.mouse;
+ port1_data.irq = MACEISA_MOUSE_IRQ;
+ serio_register_port(&maceps2_port0);
+ serio_register_port(&maceps2_port1);
+
+ return 0;
+}
+
+static void __exit maceps2_exit(void)
+{
+ serio_unregister_port(&maceps2_port0);
+ serio_unregister_port(&maceps2_port1);
+}
+
+module_init(maceps2_init);
+module_exit(maceps2_exit);
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 87fa182a06b3..260b12b34779 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -24,8 +24,7 @@ obj-$(CONFIG_PARISC) += setup-bus.o
obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
obj-$(CONFIG_PPC32) += setup-irq.o
obj-$(CONFIG_PPC64) += setup-bus.o
-obj-$(CONFIG_SGI_IP27) += setup-irq.o
-obj-$(CONFIG_SGI_IP32) += setup-irq.o
+obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
obj-$(CONFIG_X86_VISWS) += setup-irq.o
obj-$(CONFIG_PCI_USE_VECTOR) += msi.o
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index d0ab034fa0c1..ab9f28443436 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -7,7 +7,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
*
- * $Revision: 1.136 $
+ * $Revision: 1.139 $
*/
#include <linux/config.h>
@@ -74,6 +74,8 @@ dasd_alloc_device(void)
if (device == NULL)
return ERR_PTR(-ENOMEM);
memset(device, 0, sizeof (struct dasd_device));
+ /* open_count = 0 means device online but not in use */
+ atomic_set(&device->open_count, -1);
/* Get two pages for normal block device operations. */
device->ccw_mem = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 1);
@@ -549,6 +551,7 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize,
}
strncpy((char *) &cqr->magic, magic, 4);
ASCEBC((char *) &cqr->magic, 4);
+ set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
dasd_get_device(device);
return cqr;
}
@@ -597,6 +600,7 @@ dasd_smalloc_request(char *magic, int cplength, int datasize,
}
strncpy((char *) &cqr->magic, magic, 4);
ASCEBC((char *) &cqr->magic, 4);
+ set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
dasd_get_device(device);
return cqr;
}
@@ -688,9 +692,10 @@ dasd_term_IO(struct dasd_ccw_req * cqr)
rc = ccw_device_clear(device->cdev, (long) cqr);
switch (rc) {
case 0: /* termination successful */
- if (cqr->retries > 0)
+ if (cqr->retries > 0) {
+ cqr->retries--;
cqr->status = DASD_CQR_QUEUED;
- else
+ } else
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock();
break;
@@ -982,6 +987,8 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
irb->scsw.cstat == 0 &&
!irb->esw.esw0.erw.cons)
era = dasd_era_none;
+ else if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags))
+ era = dasd_era_fatal; /* don't recover this request */
else if (irb->esw.esw0.erw.cons)
era = device->discipline->examine_error(cqr, irb);
else
@@ -1875,7 +1882,7 @@ dasd_generic_set_offline (struct ccw_device *cdev)
* the blkdev_get in dasd_scan_partitions. We are only interested
* in the other openers.
*/
- max_count = device->bdev ? 1 : 0;
+ max_count = device->bdev ? 0 : -1;
if (atomic_read(&device->open_count) > max_count) {
printk (KERN_WARNING "Can't offline dasd device with open"
" count = %i.\n",
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index c6b26e729aaa..e90c1c93e19a 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -5,7 +5,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
*
- * $Revision: 1.28 $
+ * $Revision: 1.30 $
*/
#include <linux/timer.h>
@@ -1763,6 +1763,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
erp->magic = default_erp->magic;
erp->expires = 0;
erp->retries = 256;
+ cqr->buildclk = get_clock();
erp->status = DASD_CQR_FILLED;
/* remove the default erp */
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 1490f1e4a4ec..e7afb426b539 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -7,7 +7,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.53 $
+ * $Revision: 1.54 $
*/
#include <linux/config.h>
@@ -1130,6 +1130,7 @@ dasd_eckd_release(struct block_device *bdev, int no, long args)
cqr->cpaddr->count = 32;
cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
cqr->device = device;
+ clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
cqr->retries = 0;
cqr->expires = 2 * HZ;
cqr->buildclk = get_clock();
@@ -1173,6 +1174,7 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args)
cqr->cpaddr->count = 32;
cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
cqr->device = device;
+ clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
cqr->retries = 0;
cqr->expires = 2 * HZ;
cqr->buildclk = get_clock();
@@ -1215,6 +1217,7 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
cqr->cpaddr->count = 32;
cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
cqr->device = device;
+ clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
cqr->retries = 0;
cqr->expires = 2 * HZ;
cqr->buildclk = get_clock();
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 70ccb1110d07..9967c082c0ad 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -6,7 +6,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.56 $
+ * $Revision: 1.57 $
*/
#ifndef DASD_INT_H
@@ -159,6 +159,7 @@ struct dasd_ccw_req {
struct ccw1 *cpaddr; /* address of channel program */
char status; /* status of this request */
short retries; /* A retry counter */
+ unsigned long flags; /* flags of this request */
/* ... and how */
unsigned long starttime; /* jiffies time of request start */
@@ -192,6 +193,9 @@ struct dasd_ccw_req {
#define DASD_CQR_ERROR 0x04 /* request is completed with error */
#define DASD_CQR_FAILED 0x05 /* request is finally failed */
+/* per dasd_ccw_req flags */
+#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */
+
/* Signature for error recovery functions. */
typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index ef0f996fa798..ecba07756cbb 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -381,6 +381,8 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
return; /* Sucessfully restarted. */
break;
case RAW3270_IO_STOP:
+ if (!rq)
+ break;
raw3270_halt_io_nolock(rp, rq);
rq->rc = -EIO;
break;
@@ -881,7 +883,7 @@ raw3270_activate_view(struct raw3270_view *view)
if (rc) {
/* Didn't work. Try to reactivate the old view. */
rp->view = oldview;
- if (oldview->fn->activate(oldview) != 0) {
+ if (!oldview || oldview->fn->activate(oldview) != 0) {
/* Didn't work as well. Try any other view. */
list_for_each_entry(nv, &rp->view_list, list)
if (nv != view && nv != oldview) {
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index cffeda66520e..ccdf053b3dfd 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,7 +1,7 @@
/*
* drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls
- * $Revision: 1.117 $
+ * $Revision: 1.121 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
@@ -783,3 +783,68 @@ cio_get_console_subchannel(void)
}
#endif
+static inline int
+__disable_subchannel_easy(unsigned int schid, struct schib *schib)
+{
+ int retry, cc;
+
+ cc = 0;
+ for (retry=0;retry<3;retry++) {
+ schib->pmcw.ena = 0;
+ cc = msch(schid, schib);
+ if (cc)
+ return (cc==3?-ENODEV:-EBUSY);
+ stsch(schid, schib);
+ if (!schib->pmcw.ena)
+ return 0;
+ }
+ return -EBUSY; /* uhm... */
+}
+
+static inline int
+__clear_subchannel_easy(unsigned int schid)
+{
+ int retry;
+
+ if (csch(schid))
+ return -ENODEV;
+ for (retry=0;retry<20;retry++) {
+ struct tpi_info ti;
+
+ if (tpi(&ti)) {
+ tsch(schid, (struct irb *)__LC_IRB);
+ return 0;
+ }
+ udelay(100);
+ }
+ return -EBUSY;
+}
+
+extern void do_reipl(unsigned long devno);
+/* Make sure all subchannels are quiet before we re-ipl an lpar. */
+void
+reipl(unsigned long devno)
+{
+ unsigned int schid;
+
+ local_irq_disable();
+ for (schid=0;schid<=highest_subchannel;schid++) {
+ struct schib schib;
+ if (stsch(schid, &schib))
+ goto out;
+ if (!schib.pmcw.ena)
+ continue;
+ switch(__disable_subchannel_easy(schid, &schib)) {
+ case 0:
+ case -ENODEV:
+ break;
+ default: /* -EBUSY */
+ if (__clear_subchannel_easy(schid))
+ break; /* give up... */
+ stsch(schid, &schib);
+ __disable_subchannel_easy(schid, &schib);
+ }
+ }
+out:
+ do_reipl(devno);
+}
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index eac048a1991c..763056eede77 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -440,12 +440,14 @@ ccw_device_nopath_notify(void *data)
if (!ret) {
if (get_device(&sch->dev)) {
/* Driver doesn't want to keep device. */
+ cio_disable_subchannel(sch);
device_unregister(&sch->dev);
sch->schib.pmcw.intparm = 0;
cio_modify(sch);
put_device(&sch->dev);
}
} else {
+ cio_disable_subchannel(sch);
ccw_device_set_timeout(cdev, 0);
cdev->private->state = DEV_STATE_DISCONNECTED;
wake_up(&cdev->private->wait_q);
@@ -787,6 +789,7 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
struct subchannel *sch;
sch = to_subchannel(cdev->dev.parent);
+ ccw_device_set_timeout(cdev, 0);
/* OK, i/o is dead now. Call interrupt handler. */
cdev->private->state = DEV_STATE_ONLINE;
if (cdev->handler)
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 3188cde89326..f4c9779d2d4a 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
#include "ioasm.h"
#include "chsc.h"
-#define VERSION_QDIO_C "$Revision: 1.79 $"
+#define VERSION_QDIO_C "$Revision: 1.80 $"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -461,12 +461,12 @@ check_next:
switch(slsb[f_mod_no]) {
- /* the hydra has not fetched the output yet */
+ /* the adapter has not fetched the output yet */
case SLSB_CU_OUTPUT_PRIMED:
QDIO_DBF_TEXT5(0,trace,"outpprim");
break;
- /* the hydra got it */
+ /* the adapter got it */
case SLSB_P_OUTPUT_EMPTY:
atomic_dec(&q->number_of_buffers_used);
f++;
@@ -919,7 +919,7 @@ qdio_is_inbound_q_done(struct qdio_q *q)
no_used=atomic_read(&q->number_of_buffers_used);
/*
- * we need that one for synchronization with Hydra, as Hydra
+ * we need that one for synchronization with the adapter, as it
* does a kind of PCI avoidance
*/
SYNC_MEMORY;
@@ -1069,7 +1069,7 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set)
}
/*
* maybe we have to do work on our outbound queues... at least
- * we have to check Hydra outbound-int-capable thinint-capable
+ * we have to check the outbound-int-capable thinint-capable
* queues
*/
if (q->hydra_gives_outbound_pcis) {
@@ -2027,7 +2027,7 @@ tiqdio_check_chsc_availability(void)
goto exit;
}
- /* Check for hydra thin interrupts (bit 67). */
+ /* Check for OSA/FCP thin interrupts (bit 67). */
hydra_thinints = ((scsc_area->general_char[2] & 0x10000000)
== 0x10000000);
sprintf(dbf_text,"hydrati%1x", hydra_thinints);
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index 601453f1a6b9..5771fb36360f 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -1,5 +1,5 @@
/*
- * $Id: iucv.c,v 1.27 2004/03/22 07:43:43 braunu Exp $
+ * $Id: iucv.c,v 1.28 2004/04/15 06:34:58 braunu Exp $
*
* IUCV network driver
*
@@ -29,7 +29,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.27 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.28 $
*
*/
@@ -351,7 +351,7 @@ do { \
static void
iucv_banner(void)
{
- char vbuf[] = "$Revision: 1.27 $";
+ char vbuf[] = "$Revision: 1.28 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
@@ -800,6 +800,7 @@ iucv_register_program (__u8 pgmname[16],
if (iucv_pathid_table == NULL) {
printk(KERN_WARNING "%s: iucv_pathid_table storage "
"allocation failed\n", __FUNCTION__);
+ kfree(new_handler);
return NULL;
}
memset (iucv_pathid_table, 0, max_connections * sizeof(handler *));
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index fb30461252ab..a65ef7677beb 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,5 +1,5 @@
/*
- * $Id: netiucv.c,v 1.48 2004/04/01 13:42:09 braunu Exp $
+ * $Id: netiucv.c,v 1.49 2004/04/15 06:37:54 braunu Exp $
*
* IUCV network driver
*
@@ -30,7 +30,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: IUCV network driver $Revision: 1.48 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.49 $
*
*/
@@ -601,11 +601,12 @@ conn_action_txdone(fsm_instance *fi, int event, void *arg)
if ((skb = skb_dequeue(&conn->commit_queue))) {
atomic_dec(&skb->users);
dev_kfree_skb_any(skb);
- }
- if (privptr) {
- privptr->stats.tx_packets++;
- privptr->stats.tx_bytes +=
- (skb->len - NETIUCV_HDRLEN - NETIUCV_HDRLEN);
+ if (privptr) {
+ privptr->stats.tx_packets++;
+ privptr->stats.tx_bytes +=
+ (skb->len - NETIUCV_HDRLEN
+ - NETIUCV_HDRLEN);
+ }
}
}
conn->tx_buff->data = conn->tx_buff->tail = conn->tx_buff->head;
@@ -1078,6 +1079,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
"%s: Could not allocate tx_skb\n",
conn->netdev->name);
rc = -ENOMEM;
+ return rc;
} else {
skb_reserve(nskb, NETIUCV_HDRLEN);
memcpy(skb_put(nskb, skb->len),
@@ -1880,7 +1882,7 @@ static struct device_driver netiucv_driver = {
static void
netiucv_banner(void)
{
- char vbuf[] = "$Revision: 1.48 $";
+ char vbuf[] = "$Revision: 1.49 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 1175c1e8deac..74b167b0f29a 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -23,7 +23,7 @@
#include "qeth_mpc.h"
-#define VERSION_QETH_H "$Revision: 1.98 $"
+#define VERSION_QETH_H "$Revision: 1.100 $"
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
@@ -423,14 +423,12 @@ struct qeth_qdio_out_q {
struct qeth_qdio_out_buffer bufs[QDIO_MAX_BUFFERS_PER_Q];
int queue_no;
struct qeth_card *card;
- struct tasklet_struct tasklet;
spinlock_t lock;
volatile int do_pack;
/*
* index of buffer to be filled by driver; state EMPTY or PACKING
*/
volatile int next_buf_to_fill;
- volatile int next_buf_to_flush;
/*
* number of buffers that are currently filled (PRIMED)
* -> these buffers are hardware-owned
@@ -447,7 +445,6 @@ struct qeth_qdio_info {
struct qeth_qdio_buffer_pool in_buf_pool;
struct qeth_qdio_buffer_pool init_pool;
int in_buf_size;
- struct tasklet_struct in_tasklet;
/* output */
int no_out_queues;
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 414d9c3de0d5..4ee0592f21d0 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.77 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.82 $)
*
* Linux on zSeries OSA Express and HiperSockets support
*
@@ -12,7 +12,7 @@
* Frank Pavlic (pavlic@de.ibm.com) and
* Thomas Spatzier <tspat@de.ibm.com>
*
- * $Revision: 1.77 $ $Date: 2004/04/06 14:38:19 $
+ * $Revision: 1.82 $ $Date: 2004/04/21 08:27:21 $
*
* 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
@@ -78,7 +78,7 @@ qeth_eyecatcher(void)
#include "qeth_mpc.h"
#include "qeth_fs.h"
-#define VERSION_QETH_C "$Revision: 1.77 $"
+#define VERSION_QETH_C "$Revision: 1.82 $"
static const char *version = "qeth S/390 OSA-Express driver ("
VERSION_QETH_C "/" VERSION_QETH_H "/" VERSION_QETH_MPC_H
QETH_VERSION_IPV6 QETH_VERSION_VLAN ")";
@@ -486,6 +486,7 @@ qeth_remove_device(struct ccwgroup_device *cgdev)
list_del(&card->list);
write_unlock_irqrestore(&qeth_card_list.rwlock, flags);
unregister_netdev(card->dev);
+ qeth_remove_device_attributes(&cgdev->dev);
qeth_free_card(card);
cgdev->dev.driver_data = NULL;
put_device(&cgdev->dev);
@@ -822,7 +823,7 @@ qeth_register_mc_addresses(void *ptr)
struct qeth_card *card;
card = (struct qeth_card *) ptr;
- daemonize("getmcaddr");
+ daemonize("qeth_reg_mcaddrs");
QETH_DBF_TEXT(trace,4,"regmcth1");
if (!qeth_do_run_thread(card, QETH_SET_MC_THREAD))
return 0;
@@ -843,7 +844,7 @@ qeth_register_ip_address(void *ptr)
struct qeth_card *card;
card = (struct qeth_card *) ptr;
- daemonize("regip");
+ daemonize("qeth_reg_ip");
QETH_DBF_TEXT(trace,4,"regipth1");
if (!qeth_do_run_thread(card, QETH_SET_IP_THREAD))
return 0;
@@ -860,7 +861,7 @@ qeth_recover(void *ptr)
int rc = 0;
card = (struct qeth_card *) ptr;
- daemonize("recover");
+ daemonize("qeth_recover");
QETH_DBF_TEXT(trace,2,"recover1");
QETH_DBF_HEX(trace, 2, &card, sizeof(void *));
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
@@ -1969,45 +1970,6 @@ qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf,
return rc;
}
-static void
-qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
- unsigned int qdio_err, unsigned int siga_err,
- unsigned int queue, int first_element, int count,
- unsigned long card_ptr)
-{
- struct net_device *net_dev;
- struct qeth_card *card;
- struct qeth_qdio_buffer *buffer;
- int i;
-
- QETH_DBF_TEXT(trace, 6, "qdinput");
- card = (struct qeth_card *) card_ptr;
- net_dev = card->dev;
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.inbound_start_time = qeth_get_micros();
-#endif
- if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
- if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
- QETH_DBF_TEXT(trace, 1,"qdinchk");
- QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
- QETH_DBF_TEXT_(trace,1,"%04X%04X",first_element,count);
- QETH_DBF_TEXT_(trace,1,"%04X%04X", queue, status);
- qeth_schedule_recovery(card);
- return;
- }
- }
- for (i = first_element; i < (first_element + count); ++i) {
- buffer = &card->qdio.in_q->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
- if ((status == QDIO_STATUS_LOOK_FOR_ERROR) &&
- qeth_check_for_inbound_error(buffer, qdio_err, siga_err))
- buffer->state = QETH_QDIO_BUF_ERROR;
- else
- buffer->state = QETH_QDIO_BUF_PRIMED;
- }
-
- tasklet_schedule(&card->qdio.in_tasklet);
-}
-
static inline struct sk_buff *
qeth_get_skb(unsigned int length)
{
@@ -2127,7 +2089,6 @@ qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
return htons(ETH_P_802_2);
}
-
static inline void
qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr)
@@ -2193,7 +2154,6 @@ qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb,
#endif /* CONFIG_QETH_VLAN */
}
-
static inline void
qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr)
@@ -2241,6 +2201,38 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
qeth_rebuild_skb_vlan(card, skb, hdr);
}
+static inline void
+qeth_process_inbound_buffer(struct qeth_card *card,
+ struct qeth_qdio_buffer *buf, int index)
+{
+ struct qdio_buffer_element *element;
+ int offset;
+ struct sk_buff *skb;
+ struct qeth_hdr *hdr;
+ int rxrc;
+
+ /* get first element of current buffer */
+ element = (struct qdio_buffer_element *)&buf->buffer->element[0];
+ offset = 0;
+#ifdef CONFIG_QETH_PERF_STATS
+ card->perf_stats.bufs_rec++;
+#endif
+ while((skb = qeth_get_next_skb(card, buf->buffer, &element,
+ &offset, &hdr))){
+ qeth_rebuild_skb(card, skb, hdr);
+
+#ifdef CONFIG_QETH_PERF_STATS
+ card->perf_stats.inbound_time += qeth_get_micros() -
+ card->perf_stats.inbound_start_time;
+ card->perf_stats.inbound_cnt++;
+#endif
+ skb->dev = card->dev;
+ rxrc = netif_rx(skb);
+ card->dev->last_rx = jiffies;
+ card->stats.rx_packets++;
+ card->stats.rx_bytes += skb->len;
+ }
+}
static inline struct qeth_buffer_pool_entry *
qeth_get_buffer_pool_entry(struct qeth_card *card)
@@ -2284,7 +2276,7 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
buf->state = QETH_QDIO_BUF_EMPTY;
}
-static void
+static inline void
qeth_clear_output_buffer(struct qeth_card *card,
struct qeth_qdio_out_buffer *buf)
{
@@ -2355,61 +2347,43 @@ qeth_put_buffer_pool_entry(struct qeth_card *card,
}
static void
-qeth_qdio_input_tasklet(unsigned long data)
+qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
+ unsigned int qdio_err, unsigned int siga_err,
+ unsigned int queue, int first_element, int count,
+ unsigned long card_ptr)
{
- struct qeth_card *card = (struct qeth_card *) data;
- int current_buf = card->qdio.in_q->next_buf_to_process;
- struct qeth_qdio_buffer *buf;
- struct qdio_buffer_element *element;
- int offset;
- struct sk_buff *skb;
- struct qeth_hdr *hdr;
- int rxrc;
-
- QETH_DBF_TEXT(trace,6,"qdintlet");
- buf = &card->qdio.in_q->bufs[current_buf];
- while((buf->state == QETH_QDIO_BUF_PRIMED) ||
- (buf->state == QETH_QDIO_BUF_ERROR)){
- if (buf->state == QETH_QDIO_BUF_ERROR)
- goto clear_buffer;
- if (netif_queue_stopped(card->dev))
- goto clear_buffer;
- /* get first element of current buffer */
- element = (struct qdio_buffer_element *)
- &buf->buffer->element[0];
- offset = 0;
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.bufs_rec++;
-#endif
- while((skb = qeth_get_next_skb(card, buf->buffer, &element,
- &offset, &hdr))){
+ struct net_device *net_dev;
+ struct qeth_card *card;
+ struct qeth_qdio_buffer *buffer;
+ int index;
+ int i;
- qeth_rebuild_skb(card, skb, hdr);
+ QETH_DBF_TEXT(trace, 6, "qdinput");
+ card = (struct qeth_card *) card_ptr;
+ net_dev = card->dev;
#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.inbound_time += qeth_get_micros() -
- card->perf_stats.inbound_start_time;
- card->perf_stats.inbound_cnt++;
+ card->perf_stats.inbound_start_time = qeth_get_micros();
#endif
- skb->dev = card->dev;
- if (netif_queue_stopped(card->dev)) {
- dev_kfree_skb_irq(skb);
- card->stats.rx_dropped++;
- } else {
- rxrc = netif_rx(skb);
- card->dev->last_rx = jiffies;
- card->stats.rx_packets++;
- card->stats.rx_bytes += skb->len;
- }
+ if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
+ if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
+ QETH_DBF_TEXT(trace, 1,"qdinchk");
+ QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
+ QETH_DBF_TEXT_(trace,1,"%04X%04X",first_element,count);
+ QETH_DBF_TEXT_(trace,1,"%04X%04X", queue, status);
+ qeth_schedule_recovery(card);
+ return;
}
-clear_buffer:
- qeth_put_buffer_pool_entry(card, buf->pool_entry);
- /* give buffer back to hardware */
- qeth_queue_input_buffer(card, current_buf);
- current_buf = (current_buf + 1) % QDIO_MAX_BUFFERS_PER_Q;
- buf = &card->qdio.in_q->bufs[current_buf];
}
- /* set index for next time the tasklet is scheduled */
- card->qdio.in_q->next_buf_to_process = current_buf;
+ for (i = first_element; i < (first_element + count); ++i) {
+ index = i % QDIO_MAX_BUFFERS_PER_Q;
+ buffer = &card->qdio.in_q->bufs[index];
+ if (!((status == QDIO_STATUS_LOOK_FOR_ERROR) &&
+ qeth_check_for_inbound_error(buffer, qdio_err, siga_err)))
+ qeth_process_inbound_buffer(card, buffer, index);
+ /* clear buffer and give back to hardware */
+ qeth_put_buffer_pool_entry(card, buffer->pool_entry);
+ qeth_queue_input_buffer(card, index);
+ }
}
static inline int
@@ -2524,10 +2498,11 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
* switches between PACKING and non-PACKING state if needed.
* has to be called holding queue->lock
*/
-static inline void
+static inline int
qeth_switch_packing_state(struct qeth_qdio_out_q *queue)
{
struct qeth_qdio_out_buffer *buffer;
+ int flush_count = 0;
QETH_DBF_TEXT(trace, 6, "swipack");
if (!queue->do_pack) {
@@ -2554,6 +2529,7 @@ qeth_switch_packing_state(struct qeth_qdio_out_q *queue)
BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
if (buffer->next_element_to_fill > 0) {
buffer->state = QETH_QDIO_BUF_PRIMED;
+ flush_count++;
atomic_inc(&queue->used_buffers);
queue->next_buf_to_fill =
(queue->next_buf_to_fill + 1) %
@@ -2561,6 +2537,25 @@ qeth_switch_packing_state(struct qeth_qdio_out_q *queue)
}
}
}
+ return flush_count;
+}
+
+static inline void
+qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue, int under_int)
+{
+ struct qeth_qdio_out_buffer *buffer;
+
+ buffer = &queue->bufs[queue->next_buf_to_fill];
+ BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
+ if (buffer->next_element_to_fill > 0){
+ /* it's a packing buffer */
+ buffer->state = QETH_QDIO_BUF_PRIMED;
+ atomic_inc(&queue->used_buffers);
+ qeth_flush_buffers(queue, under_int, queue->next_buf_to_fill,
+ 1);
+ queue->next_buf_to_fill =
+ (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q;
+ }
}
static void
@@ -2603,58 +2598,12 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
atomic_dec(&queue->set_pci_flags_count);
qeth_clear_output_buffer(card, buffer);
+ atomic_dec(&queue->used_buffers);
}
- atomic_sub(count, &queue->used_buffers);
-
- //if (!atomic_read(&queue->set_pci_flags_count))
- tasklet_schedule(&queue->tasklet);
netif_wake_queue(card->dev);
}
-static void
-qeth_qdio_output_tasklet(unsigned long data)
-{
- struct qeth_qdio_out_q *queue = (struct qeth_qdio_out_q *) data;
- struct qeth_qdio_out_buffer *buffer;
- int index;
- int count;
-
- QETH_DBF_TEXT(trace, 6, "outtlet");
-
- /* flush all PRIMED buffers */
- index = queue->next_buf_to_flush;
- count = 0;
- while (queue->bufs[index].state == QETH_QDIO_BUF_PRIMED) {
- count++;
- index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
- }
- qeth_flush_buffers(queue, 0, queue->next_buf_to_flush, count);
- queue->next_buf_to_flush = index;
-
- /* flush a buffer with data, if no more PCIs are
- * outstanding */
- if (!atomic_read(&queue->set_pci_flags_count)){
- spin_lock(&queue->lock);
- buffer = &queue->bufs[index];
- if (buffer->state == QETH_QDIO_BUF_PRIMED){
- qeth_flush_buffers(queue, 0, index, 1);
- index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
- queue->next_buf_to_flush = index;
- } else if (buffer->next_element_to_fill > 0){
- /* it's a packing buffer */
- BUG_ON(index != queue->next_buf_to_fill);
- buffer->state = QETH_QDIO_BUF_PRIMED;
- atomic_inc(&queue->used_buffers);
- qeth_flush_buffers(queue, 0, index, 1);
- index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
- queue->next_buf_to_flush = index;
- queue->next_buf_to_fill = index;
- }
- spin_unlock(&queue->lock);
- }
-}
-
static char*
qeth_create_qib_param_field(struct qeth_card *card)
{
@@ -2858,8 +2807,6 @@ qeth_init_qdio_info(struct qeth_card *card)
card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
- card->qdio.in_tasklet.data = (unsigned long) card;
- card->qdio.in_tasklet.func = qeth_qdio_input_tasklet;
/* outbound */
card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
@@ -2903,13 +2850,9 @@ qeth_init_qdio_queues(struct qeth_card *card)
}
card->qdio.out_qs[i]->card = card;
card->qdio.out_qs[i]->next_buf_to_fill = 0;
- card->qdio.out_qs[i]->next_buf_to_flush = 0;
card->qdio.out_qs[i]->do_pack = 0;
atomic_set(&card->qdio.out_qs[i]->used_buffers,0);
atomic_set(&card->qdio.out_qs[i]->set_pci_flags_count, 0);
- card->qdio.out_qs[i]->tasklet.data =
- (unsigned long) card->qdio.out_qs[i];
- card->qdio.out_qs[i]->tasklet.func = qeth_qdio_output_tasklet;
spin_lock_init(&card->qdio.out_qs[i]->lock);
}
return 0;
@@ -3653,6 +3596,8 @@ qeth_do_send_packet(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr;
struct qeth_qdio_out_buffer *buffer;
int elements_needed;
+ int start_index;
+ int flush_count = 0;
int rc;
QETH_DBF_TEXT(trace, 6, "dosndpkt");
@@ -3671,9 +3616,7 @@ qeth_do_send_packet(struct qeth_card *card, struct sk_buff *skb,
}
spin_lock(&queue->lock);
- /* check if we need to switch packing state of this queue */
- if (card->info.type != QETH_CARD_TYPE_IQD)
- qeth_switch_packing_state(queue);
+ start_index = queue->next_buf_to_fill;
buffer = &queue->bufs[queue->next_buf_to_fill];
BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
if (queue->do_pack){
@@ -3682,6 +3625,7 @@ qeth_do_send_packet(struct qeth_card *card, struct sk_buff *skb,
< elements_needed){
/* ... no -> set state PRIMED */
buffer->state = QETH_QDIO_BUF_PRIMED;
+ flush_count++;
atomic_inc(&queue->used_buffers);
queue->next_buf_to_fill =
(queue->next_buf_to_fill + 1) %
@@ -3695,18 +3639,24 @@ qeth_do_send_packet(struct qeth_card *card, struct sk_buff *skb,
PRINT_WARN("qeth_do_send_packet: error during "
"qeth_fill_buffer.");
card->stats.tx_dropped++;
- spin_unlock(&queue->lock);
- return rc;
- }
- if (buffer->state == QETH_QDIO_BUF_PRIMED){
+ } else if (buffer->state == QETH_QDIO_BUF_PRIMED){
/* next time fill the next buffer */
+ flush_count++;
atomic_inc(&queue->used_buffers);
queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
}
- spin_unlock(&queue->lock);
+ /* check if we need to switch packing state of this queue */
+ if (card->info.type != QETH_CARD_TYPE_IQD)
+ flush_count += qeth_switch_packing_state(queue);
+
+ if (flush_count)
+ qeth_flush_buffers(queue, 0, start_index, flush_count);
- tasklet_schedule(&queue->tasklet);
+ if (!atomic_read(&queue->set_pci_flags_count))
+ qeth_flush_buffers_on_no_pci(queue, 0);
+
+ spin_unlock(&queue->lock);
return rc;
}
@@ -4424,6 +4374,10 @@ qeth_delete_mc_addresses(struct qeth_card *card)
if (!ipm->is_multicast)
continue;
iptodo = qeth_get_addr_buffer(ipm->proto);
+ if (!iptodo) {
+ QETH_DBF_TEXT(trace, 2, "dmcnomem");
+ continue;
+ }
memcpy(iptodo, ipm, sizeof(struct qeth_ipaddr));
iptodo->users = iptodo->users * -1;
if (!__qeth_insert_ip_todo(card, iptodo, 0))
@@ -4694,14 +4648,14 @@ qeth_register_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
if (addr->proto == QETH_PROT_IPV4) {
QETH_DBF_TEXT(trace, 2,"setaddr4");
- QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, sizeof(int));
+ QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
} else if (addr->proto == QETH_PROT_IPV6) {
QETH_DBF_TEXT(trace, 2, "setaddr6");
- QETH_DBF_HEX(trace,4,&addr->u.a6.addr,4);
- QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+4,4);
+ QETH_DBF_HEX(trace,3,&addr->u.a6.addr,8);
+ QETH_DBF_HEX(trace,3,((char *)&addr->u.a6.addr)+8,8);
} else {
QETH_DBF_TEXT(trace, 2, "setaddr?");
- QETH_DBF_HEX(trace, 4, addr, sizeof(struct qeth_ipaddr));
+ QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
}
do {
if (addr->is_multicast)
@@ -4732,14 +4686,14 @@ qeth_deregister_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
if (addr->proto == QETH_PROT_IPV4) {
QETH_DBF_TEXT(trace, 2,"deladdr4");
- QETH_DBF_HEX(trace, 2, &addr->u.a4.addr, sizeof(int));
+ QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
} else if (addr->proto == QETH_PROT_IPV6) {
QETH_DBF_TEXT(trace, 2, "deladdr6");
- QETH_DBF_HEX(trace, 2, &addr->u.a6.addr,
- sizeof(struct in6_addr));
+ QETH_DBF_HEX(trace,3,&addr->u.a6.addr,8);
+ QETH_DBF_HEX(trace,3,((char *)&addr->u.a6.addr)+8,8);
} else {
QETH_DBF_TEXT(trace, 2, "deladdr?");
- QETH_DBF_HEX(trace, 2, addr, sizeof(struct qeth_ipaddr));
+ QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
}
if (addr->is_multicast)
rc = qeth_send_setdelmc(card, addr, IPA_CMD_DELIPM);
@@ -6515,26 +6469,24 @@ qeth_ip_event(struct notifier_block *this,
addr->u.a4.addr = ifa->ifa_address;
addr->u.a4.mask = ifa->ifa_mask;
addr->type = QETH_IP_TYPE_NORMAL;
- }
+ } else
+ goto out;
+
switch(event) {
case NETDEV_UP:
- if (addr) {
- if (!qeth_add_ip(card, addr))
- kfree(addr);
- }
+ if (!qeth_add_ip(card, addr))
+ kfree(addr);
break;
case NETDEV_DOWN:
- if (addr) {
- if (!qeth_delete_ip(card, addr))
- kfree(addr);
- }
+ if (!qeth_delete_ip(card, addr))
+ kfree(addr);
break;
default:
break;
}
qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
schedule_work(&card->kernel_thread_starter);
-
+out:
return NOTIFY_DONE;
}
@@ -6570,26 +6522,24 @@ qeth_ip6_event(struct notifier_block *this,
memcpy(&addr->u.a6.addr, &ifa->addr, sizeof(struct in6_addr));
addr->u.a6.pfxlen = ifa->prefix_len;
addr->type = QETH_IP_TYPE_NORMAL;
- }
+ } else
+ goto out;
+
switch(event) {
case NETDEV_UP:
- if (addr){
- if (!qeth_add_ip(card, addr))
- kfree(addr);
- }
+ if (!qeth_add_ip(card, addr))
+ kfree(addr);
break;
case NETDEV_DOWN:
- if (addr){
- if (!qeth_delete_ip(card, addr))
- kfree(addr);
- }
+ if (!qeth_delete_ip(card, addr))
+ kfree(addr);
break;
default:
break;
}
qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
schedule_work(&card->kernel_thread_starter);
-
+out:
return NOTIFY_DONE;
}
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 31eb79a84c58..a6f1156440bf 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -29,7 +29,7 @@
*/
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_AUX_REVISION "$Revision: 1.105 $"
+#define ZFCP_AUX_REVISION "$Revision: 1.107 $"
#include "zfcp_ext.h"
@@ -1078,17 +1078,6 @@ zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
{
char dbf_name[20];
- /* debug feature area which records fsf request sequence numbers */
- sprintf(dbf_name, ZFCP_REQ_DBF_NAME "%s",
- zfcp_get_busid_by_adapter(adapter));
- adapter->req_dbf = debug_register(dbf_name,
- ZFCP_REQ_DBF_INDEX,
- ZFCP_REQ_DBF_AREAS,
- ZFCP_REQ_DBF_LENGTH);
- debug_register_view(adapter->req_dbf, &debug_hex_ascii_view);
- debug_set_level(adapter->req_dbf, ZFCP_REQ_DBF_LEVEL);
- debug_text_event(adapter->req_dbf, 1, "zzz");
-
/* debug feature area which records SCSI command failures (hostbyte) */
rwlock_init(&adapter->cmd_dbf_lock);
sprintf(dbf_name, ZFCP_CMD_DBF_NAME "%s",
@@ -1131,7 +1120,7 @@ zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);
debug_set_level(adapter->erp_dbf, ZFCP_ERP_DBF_LEVEL);
- if (adapter->req_dbf && adapter->cmd_dbf && adapter->abort_dbf &&
+ if (adapter->cmd_dbf && adapter->abort_dbf &&
adapter->in_els_dbf && adapter->erp_dbf)
return 0;
@@ -1147,7 +1136,6 @@ void
zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
{
debug_unregister(adapter->erp_dbf);
- debug_unregister(adapter->req_dbf);
debug_unregister(adapter->cmd_dbf);
debug_unregister(adapter->abort_dbf);
debug_unregister(adapter->in_els_dbf);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 00de5d6f0733..e4bc663cea4a 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -33,7 +33,7 @@
#define ZFCP_DEF_H
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_DEF_REVISION "$Revision: 1.71 $"
+#define ZFCP_DEF_REVISION "$Revision: 1.72 $"
/*************************** INCLUDES *****************************************/
@@ -450,19 +450,12 @@ struct zfcp_ls_rnid_acc {
#define ZFCP_ERP_DBF_LEVEL 3
#define ZFCP_ERP_DBF_NAME "zfcperp"
-#define ZFCP_REQ_DBF_INDEX 1
-#define ZFCP_REQ_DBF_AREAS 1
-#define ZFCP_REQ_DBF_LENGTH 8
-#define ZFCP_REQ_DBF_LEVEL 1
-#define ZFCP_REQ_DBF_NAME "zfcpreq"
-
#define ZFCP_CMD_DBF_INDEX 2
#define ZFCP_CMD_DBF_AREAS 1
#define ZFCP_CMD_DBF_LENGTH 8
#define ZFCP_CMD_DBF_LEVEL 3
#define ZFCP_CMD_DBF_NAME "zfcpcmd"
-
#define ZFCP_ABORT_DBF_INDEX 2
#define ZFCP_ABORT_DBF_AREAS 1
#define ZFCP_ABORT_DBF_LENGTH 8
@@ -475,11 +468,6 @@ struct zfcp_ls_rnid_acc {
#define ZFCP_IN_ELS_DBF_LEVEL 6
#define ZFCP_IN_ELS_DBF_NAME "zfcpels"
-#define ZFCP_ADAPTER_REQ_DBF_INDEX 4
-#define ZFCP_ADAPTER_REQ_DBF_AREAS 1
-#define ZFCP_ADAPTER_REQ_DBF_LENGTH 8
-#define ZFCP_ADAPTER_REQ_DBF_LEVEL 6
-
/******************** LOGGING MACROS AND DEFINES *****************************/
/*
@@ -986,7 +974,6 @@ struct zfcp_adapter {
struct zfcp_port *nameserver_port; /* adapter's nameserver */
debug_info_t *erp_dbf; /* S/390 debug features */
debug_info_t *abort_dbf;
- debug_info_t *req_dbf;
debug_info_t *in_els_dbf;
debug_info_t *cmd_dbf;
rwlock_t cmd_dbf_lock;
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index ccac73ed538f..045d04ba8497 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -31,7 +31,7 @@
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_ERP_REVISION "$Revision: 1.49 $"
+#define ZFCP_ERP_REVISION "$Revision: 1.51 $"
#include "zfcp_ext.h"
@@ -1865,6 +1865,7 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
case ZFCP_ERP_FAILED :
atomic_inc(&port->erp_counter);
if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
+ zfcp_erp_port_failed(port);
break;
case ZFCP_ERP_EXIT :
/* nothing */
@@ -1874,7 +1875,6 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {
zfcp_erp_port_block(port, 0); /* for ZFCP_ERP_SUCCEEDED */
result = ZFCP_ERP_EXIT;
- zfcp_erp_port_failed(port);
}
return result;
@@ -2397,8 +2397,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed "
"(retval=%d)\n", retval_cleanup);
}
- else
- debug_text_event(adapter->req_dbf, 1, "q_clean");
failed_qdio_establish:
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
@@ -2468,10 +2466,8 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed on "
"adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
- } else {
+ } else
ZFCP_LOG_DEBUG("queues cleaned up\n");
- debug_text_event(adapter->req_dbf, 1, "q_clean");
- }
/*
* First we had to stop QDIO operation.
@@ -2834,9 +2830,10 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
/* nameserver port may live again */
atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
&adapter->nameserver_port->status);
- zfcp_erp_port_reopen(adapter->nameserver_port, 0);
- erp_action->step = ZFCP_ERP_STEP_NAMESERVER_OPEN;
- retval = ZFCP_ERP_CONTINUES;
+ if (zfcp_erp_port_reopen(adapter->nameserver_port, 0) >= 0) {
+ erp_action->step = ZFCP_ERP_STEP_NAMESERVER_OPEN;
+ retval = ZFCP_ERP_CONTINUES;
+ } else retval = ZFCP_ERP_FAILED;
break;
}
/* else nameserver port is already open, fall through */
@@ -2972,6 +2969,10 @@ zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action
debug_text_event(adapter->erp_dbf, 3, "p_pstnsw_w");
debug_event(adapter->erp_dbf, 3,
&erp_action->port->wwpn, sizeof (wwn_t));
+ if (atomic_test_mask(
+ ZFCP_STATUS_COMMON_ERP_FAILED,
+ &adapter->nameserver_port->status))
+ zfcp_erp_port_failed(erp_action->port);
zfcp_erp_action_ready(erp_action);
}
}
@@ -3357,7 +3358,7 @@ zfcp_erp_action_enqueue(int action,
struct zfcp_adapter *adapter,
struct zfcp_port *port, struct zfcp_unit *unit)
{
- int retval = -1;
+ int retval = 1;
struct zfcp_erp_action *erp_action = NULL;
int stronger_action = 0;
u32 status = 0;
@@ -3376,7 +3377,7 @@ zfcp_erp_action_enqueue(int action,
if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
&adapter->status))
- goto out;
+ return -EIO;
debug_event(adapter->erp_dbf, 4, &action, sizeof (int));
/* check whether we really need this */
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index c4faf9ec2b89..79bb0bab483f 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -29,7 +29,7 @@
*/
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_FSF_C_REVISION "$Revision: 1.43 $"
+#define ZFCP_FSF_C_REVISION "$Revision: 1.45 $"
#include "zfcp_ext.h"
@@ -379,13 +379,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
zfcp_get_busid_by_adapter(adapter),
fsf_req->qtcb->prefix.prot_status_qual.
sequence_error.exp_req_seq_no);
- debug_text_event(adapter->req_dbf, 1, "exp_seq!");
- debug_event(adapter->req_dbf, 1,
- &fsf_req->qtcb->prefix.prot_status_qual.
- sequence_error.exp_req_seq_no, 4);
- debug_text_event(adapter->req_dbf, 1, "qtcb_seq!");
- debug_exception(adapter->req_dbf, 1,
- &fsf_req->qtcb->prefix.req_seq_no, 4);
debug_text_exception(adapter->erp_dbf, 0, "prot_seq_err");
/* restart operation on this adapter */
zfcp_erp_adapter_reopen(adapter, 0);
@@ -891,7 +884,6 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags)
ZFCP_LOG_TRACE("Status Read request initiated (adapter%s)\n",
zfcp_get_busid_by_adapter(adapter));
- debug_text_event(adapter->req_dbf, 1, "unso");
goto out;
failed_req_send:
@@ -1277,10 +1269,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
case FSF_FCP_COMMAND_DOES_NOT_EXIST:
ZFCP_LOG_FLAGS(2, "FSF_FCP_COMMAND_DOES_NOT_EXIST\n");
retval = 0;
- debug_text_event(new_fsf_req->adapter->req_dbf, 3, "no_exist");
- debug_event(new_fsf_req->adapter->req_dbf, 3,
- &new_fsf_req->qtcb->bottom.support.req_handle,
- sizeof (unsigned long));
debug_text_event(new_fsf_req->adapter->erp_dbf, 3,
"fsf_s_no_exist");
new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED;
@@ -3373,10 +3361,6 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
* (need this for look up on normal command completion)
*/
fsf_req->data.send_fcp_command_task.scsi_cmnd = scsi_cmnd;
- debug_text_event(adapter->req_dbf, 3, "fsf/sc");
- debug_event(adapter->req_dbf, 3, &fsf_req, sizeof (unsigned long));
- debug_event(adapter->req_dbf, 3, &scsi_cmnd, sizeof (unsigned long));
-
fsf_req->data.send_fcp_command_task.start_jiffies = jiffies;
fsf_req->data.send_fcp_command_task.unit = unit;
ZFCP_LOG_DEBUG("unit=%p, fcp_lun=0x%016Lx\n", unit, unit->fcp_lun);
@@ -3517,12 +3501,9 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
send_failed:
no_fit:
failed_scsi_cmnd:
- /* dequeue new FSF request previously enqueued */
- debug_text_event(adapter->req_dbf, 3, "fail_sc");
- debug_event(adapter->req_dbf, 3, &scsi_cmnd, sizeof (unsigned long));
-
zfcp_fsf_req_free(fsf_req);
fsf_req = NULL;
+ scsi_cmnd->host_scribble = NULL;
success:
failed_req_create:
write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
@@ -4267,14 +4248,9 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
* the new eh
*/
/* always call back */
- debug_text_event(fsf_req->adapter->req_dbf, 2, "ok_done:");
- debug_event(fsf_req->adapter->req_dbf, 2, &scpnt,
- sizeof (unsigned long));
- debug_event(fsf_req->adapter->req_dbf, 2, &scpnt->scsi_done,
- sizeof (unsigned long));
- debug_event(fsf_req->adapter->req_dbf, 2, &fsf_req,
- sizeof (unsigned long));
+
(scpnt->scsi_done) (scpnt);
+
/*
* We must hold this lock until scsi_done has been called.
* Otherwise we may call scsi_done after abort regarding this
@@ -4954,15 +4930,6 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
"to request queue.\n");
} else {
req_queue->distance_from_int = new_distance_from_int;
- debug_text_event(adapter->req_dbf, 1, "o:a/seq");
- debug_event(adapter->req_dbf, 1, &fsf_req,
- sizeof (unsigned long));
- if (likely(inc_seq_no)) {
- debug_event(adapter->req_dbf, 1,
- &adapter->fsf_req_seq_no, sizeof (u32));
- } else {
- debug_text_event(adapter->req_dbf, 1, "nocb");
- }
/*
* increase FSF sequence counter -
* this must only be done for request successfully enqueued to
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 1e72bd18796b..ca238c054d5d 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -28,7 +28,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define ZFCP_QDIO_C_REVISION "$Revision: 1.16 $"
+#define ZFCP_QDIO_C_REVISION "$Revision: 1.18 $"
#include "zfcp_ext.h"
@@ -485,10 +485,6 @@ zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
struct zfcp_fsf_req *fsf_req;
int retval = 0;
- /* Note: seq is entered later */
- debug_text_event(adapter->req_dbf, 1, "i:a/seq");
- debug_event(adapter->req_dbf, 1, &sbale_addr, sizeof (unsigned long));
-
/* invalid (per convention used in this driver) */
if (unlikely(!sbale_addr)) {
ZFCP_LOG_NORMAL("bug: invalid reqid\n");
@@ -506,11 +502,6 @@ zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
retval = -EINVAL;
goto out;
}
- /* debug feature stuff (test for QTCB: remember new unsol. status!) */
- if (likely(fsf_req->qtcb)) {
- debug_event(adapter->req_dbf, 1,
- &fsf_req->qtcb->prefix.req_seq_no, sizeof (u32));
- }
ZFCP_LOG_TRACE("fsf_req at %p, QTCB at %p\n", fsf_req, fsf_req->qtcb);
if (likely(fsf_req->qtcb)) {
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 071007e0f181..ed9ebd166acc 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -31,7 +31,7 @@
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_SCSI_REVISION "$Revision: 1.59 $"
+#define ZFCP_SCSI_REVISION "$Revision: 1.60 $"
#include <linux/blkdev.h>
@@ -297,10 +297,6 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit,
if (unlikely(tmp < 0)) {
ZFCP_LOG_DEBUG("error: initiation of Send FCP Cmnd failed\n");
retval = SCSI_MLQUEUE_HOST_BUSY;
- } else {
- debug_text_event(adapter->req_dbf, 3, "q_scpnt");
- debug_event(adapter->req_dbf, 3, &scpnt,
- sizeof (unsigned long));
}
out:
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index daee75c13a46..482693db18a0 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -207,7 +207,7 @@ int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
/**
* fb_set_cmap - set the colormap
* @cmap: frame buffer colormap structure
- * @kspc: boolean, 0 copy local, 1 get_user() function
+ * @kspc: boolean, 1 copy local, 0 get_user() function
* @info: frame buffer info structure
*
* Sets the colormap @cmap for a screen of device @info.
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index bd6eb4940d3c..9875025aa650 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -44,7 +44,7 @@ config BINFMT_SHARED_FLAT
config BINFMT_AOUT
tristate "Kernel support for a.out and ECOFF binaries"
- depends on (X86 && !X86_64) || ALPHA || ARM || M68K || MIPS || SPARC32
+ depends on (X86 && !X86_64) || ALPHA || ARM || M68K || SPARC32
---help---
A.out (Assembler.OUTput) is a set of formats for libraries and
executables used in the earliest versions of UNIX. Linux used
diff --git a/fs/compat.c b/fs/compat.c
index 40023e684520..b628d2e315f1 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -235,7 +235,7 @@ out:
return error;
}
-/* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64 */
+/* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64, MIPS */
#define IOCTL_HASHSIZE 256
struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index e7c7fd2265cd..0439ec64301c 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -121,6 +121,8 @@ struct thread_struct {
#endif /* CONFIG_ALTIVEC */
};
+#define ARCH_MIN_TASKALIGN 16
+
#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
#define INIT_THREAD { \
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index ea8bf67f7007..d3e83108c064 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -553,6 +553,8 @@ struct thread_struct {
#endif /* CONFIG_ALTIVEC */
};
+#define ARCH_MIN_TASKALIGN 16
+
#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
#define INIT_THREAD { \
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 0b12bd800fd1..2d439a8390c0 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -24,8 +24,6 @@ enum {
PROC_ROOT_INO = 1,
};
-/* Finally, the dynamically allocatable proc entries are reserved: */
-
#define PROC_SUPER_MAGIC 0x9fa0
/*
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 428b48964fc8..e414003e872b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -151,7 +151,6 @@ extern void init_idle(task_t *idle, int cpu);
extern void show_state(void);
extern void show_regs(struct pt_regs *);
-extern void show_trace_task(task_t *tsk);
/*
* TASK is a pointer to the task whose backtrace we want to see (or NULL for current
diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h
index a444c9edb9e9..3a2206f61de0 100644
--- a/include/linux/sunrpc/svcauth_gss.h
+++ b/include/linux/sunrpc/svcauth_gss.h
@@ -20,6 +20,7 @@
#include <linux/sunrpc/auth_gss.h>
int gss_svc_init(void);
+void gss_svc_shutdown(void);
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
#endif /* __KERNEL__ */
diff --git a/init/Kconfig b/init/Kconfig
index 55261afdc3bf..337feb1026ea 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -149,7 +149,7 @@ config AUDIT
config AUDITSYSCALL
bool "Enable system-call auditing support"
- depends on AUDIT && (X86 || PPC64)
+ depends on AUDIT && (X86 || PPC64 || ARCH_S390)
default y if SECURITY_SELINUX
default n
help
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index b1b922f09257..971124109c8c 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -984,6 +984,7 @@ out:
static void __exit exit_rpcsec_gss(void)
{
+ gss_svc_shutdown();
gss_mech_unregister_all();
rpcauth_unregister(&authgss_ops);
}
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index a60a541e9f5e..dae18e9792a6 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1063,3 +1063,10 @@ gss_svc_init(void)
svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
return 0;
}
+
+void
+gss_svc_shutdown(void)
+{
+ cache_unregister(&rsc_cache);
+ cache_unregister(&rsi_cache);
+}