Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 Mar 2009 23:04:22 +0000 (16:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 Mar 2009 23:04:22 +0000 (16:04 -0700)
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (81 commits)
  [S390] remove duplicated #includes
  [S390] cpumask: use mm_cpumask() wrapper
  [S390] cpumask: Use accessors code.
  [S390] cpumask: prepare for iterators to only go to nr_cpu_ids/nr_cpumask_bits.
  [S390] cpumask: remove cpu_coregroup_map
  [S390] fix clock comparator save area usage
  [S390] Add hwcap flag for the etf3 enhancement facility
  [S390] Ensure that ipl panic notifier is called late.
  [S390] fix dfp elf hwcap/facility bit detection
  [S390] smp: perform initial cpu reset before starting a cpu
  [S390] smp: fix memory leak on __cpu_up
  [S390] ipl: Improve checking logic and remove switch defaults.
  [S390] s390dbf: Remove needless check for NULL pointer.
  [S390] s390dbf: Remove redundant initilizations.
  [S390] use kzfree()
  [S390] BUG to BUG_ON changes
  [S390] zfcpdump: Prevent zcore from beeing built as a kernel module.
  [S390] Use csum_partial in checksum.h
  [S390] cleanup lowcore.h
  [S390] eliminate ipl_device from lowcore
  ...

99 files changed:
Documentation/kernel-parameters.txt
MAINTAINERS
arch/s390/Kconfig
arch/s390/crypto/prng.c
arch/s390/include/asm/bitops.h
arch/s390/include/asm/crw.h [new file with mode: 0644]
arch/s390/include/asm/dasd.h
arch/s390/include/asm/idals.h
arch/s390/include/asm/lowcore.h
arch/s390/include/asm/mmu_context.h
arch/s390/include/asm/nmi.h [new file with mode: 0644]
arch/s390/include/asm/processor.h
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/qdio.h
arch/s390/include/asm/smp.h
arch/s390/include/asm/string.h
arch/s390/include/asm/sysinfo.h
arch/s390/include/asm/tlbflush.h
arch/s390/include/asm/topology.h
arch/s390/include/asm/vtoc.h
arch/s390/kernel/Makefile
arch/s390/kernel/bitmap.S [deleted file]
arch/s390/kernel/bitmap.c [new file with mode: 0644]
arch/s390/kernel/compat_ptrace.h
arch/s390/kernel/debug.c
arch/s390/kernel/early.c
arch/s390/kernel/head.S
arch/s390/kernel/head31.S
arch/s390/kernel/head64.S
arch/s390/kernel/ipl.c
arch/s390/kernel/module.c
arch/s390/kernel/nmi.c [moved from drivers/s390/s390mach.c with 62% similarity]
arch/s390/kernel/process.c
arch/s390/kernel/processor.c
arch/s390/kernel/reipl64.S
arch/s390/kernel/s390_ksyms.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/kernel/sysinfo.c [moved from drivers/s390/sysinfo.c with 88% similarity]
arch/s390/kernel/time.c
arch/s390/kernel/topology.c
arch/s390/kernel/traps.c
arch/s390/kernel/vdso.c
arch/s390/kernel/vmlinux.lds.S
arch/s390/kvm/kvm-s390.c
arch/s390/lib/delay.c
arch/s390/lib/string.c
arch/s390/mm/fault.c
arch/s390/mm/init.c
arch/s390/mm/pgtable.c
drivers/char/hvc_iucv.c
drivers/s390/Makefile
drivers/s390/block/dasd.c
drivers/s390/block/dasd_3990_erp.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_eckd.h
drivers/s390/block/dasd_eer.c
drivers/s390/block/dasd_erp.c
drivers/s390/block/dasd_fba.c
drivers/s390/block/dasd_genhd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_ioctl.c
drivers/s390/block/dasd_proc.c
drivers/s390/char/tape.h
drivers/s390/char/tape_34xx.c
drivers/s390/char/tape_3590.c
drivers/s390/char/tape_block.c
drivers/s390/char/tape_char.c
drivers/s390/char/tape_core.c
drivers/s390/char/tape_proc.c
drivers/s390/char/tape_std.c
drivers/s390/char/zcore.c
drivers/s390/cio/Makefile
drivers/s390/cio/airq.c
drivers/s390/cio/blacklist.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/chp.c
drivers/s390/cio/chsc.c
drivers/s390/cio/cio.c
drivers/s390/cio/crw.c [new file with mode: 0644]
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/device.h
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_ops.c
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_setup.c
drivers/s390/cio/qdio_thinint.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_pcixcc.c
drivers/s390/ebcdic.c [deleted file]
drivers/s390/net/qeth_core_main.c
drivers/s390/s390mach.h [deleted file]
fs/partitions/ibm.c

index 1a29ff3df3c58231a3c8a639758a9f9e7557ea6b..954b23cecfd19bc98f996c26ecfbd7bf8f0f44e9 100644 (file)
@@ -830,6 +830,9 @@ and is between 256 and 4096 characters. It is defined in the file
 
        hvc_iucv=       [S390] Number of z/VM IUCV hypervisor console (HVC)
                               terminal devices. Valid values: 0..8
+       hvc_iucv_allow= [S390] Comma-separated list of z/VM user IDs.
+                              If specified, z/VM IUCV HVC accepts connections
+                              from listed z/VM user IDs only.
 
        i8042.debug     [HW] Toggle i8042 debug mode
        i8042.direct    [HW] Put keyboard port into non-translated mode
index bc919b645f379cf52cc688dcbde4ef7aa4c9a5c2..4dacdfcdbe6e6ed34a689cf35851503606255942 100644 (file)
@@ -3745,6 +3745,15 @@ L:       linux-s390@vger.kernel.org
 W:     http://www.ibm.com/developerworks/linux/linux390/
 S:     Supported
 
+S390 ZCRYPT DRIVER
+P:     Felix Beck
+M:     felix.beck@de.ibm.com
+P:     Ralph Wuerthner
+M:     ralph.wuerthner@de.ibm.com
+M:     linux390@de.ibm.com
+L:     linux-s390@vger.kernel.org
+S:     Supported
+
 S390 ZFCP DRIVER
 P:     Christof Schmitt
 M:     christof.schmitt@de.ibm.com
index 6b0a3538dc63b9ab8ff62344904f186b01876702..2a8af5e16345d45f778e657a2f4c24363946edf3 100644 (file)
@@ -343,13 +343,6 @@ source "mm/Kconfig"
 
 comment "I/O subsystem configuration"
 
-config MACHCHK_WARNING
-       bool "Process warning machine checks"
-       help
-         Select this option if you want the machine check handler on IBM S/390 or
-         zSeries to process warning machine checks (e.g. on power failures).
-         If unsure, say "Y".
-
 config QDIO
        tristate "QDIO support"
        ---help---
@@ -521,7 +514,7 @@ config APPLDATA_OS
 
 config APPLDATA_NET_SUM
        tristate "Monitor overall network statistics"
-       depends on APPLDATA_BASE
+       depends on APPLDATA_BASE && NET
        help
          This provides network related data to the Linux - VM Monitor Stream,
          currently there is only a total sum of network I/O statistics, no
@@ -552,7 +545,7 @@ config KEXEC
          but is independent of hardware/microcode support.
 
 config ZFCPDUMP
-       tristate "zfcpdump support"
+       bool "zfcpdump support"
        select SMP
        default n
        help
index eca724d229ecd26d7102dfd7c7d4be37af98d19f..b49c00ce65e92f4e0e9b584ce0c61e3aaaf37da1 100644 (file)
@@ -201,8 +201,7 @@ out_free:
 static void __exit prng_exit(void)
 {
        /* wipe me */
-       memset(p->buf, 0, prng_chunk_size);
-       kfree(p->buf);
+       kzfree(p->buf);
        kfree(p);
 
        misc_deregister(&prng_dev);
index 8e9243ae0c19d13524a700c3ffea8aa4961665c8..b30606f6d5230e45b4eb8f4e3f009eb929d02a84 100644 (file)
@@ -57,7 +57,7 @@
  * with operation of the form "set_bit(bitnr, flags)".
  */
 
-/* bitmap tables from arch/S390/kernel/bitmap.S */
+/* bitmap tables from arch/s390/kernel/bitmap.c */
 extern const char _oi_bitmap[];
 extern const char _ni_bitmap[];
 extern const char _zb_findmap[];
@@ -525,16 +525,16 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr,
 static inline unsigned long __ffz_word(unsigned long nr, unsigned long word)
 {
 #ifdef __s390x__
-       if (likely((word & 0xffffffff) == 0xffffffff)) {
+       if ((word & 0xffffffff) == 0xffffffff) {
                word >>= 32;
                nr += 32;
        }
 #endif
-       if (likely((word & 0xffff) == 0xffff)) {
+       if ((word & 0xffff) == 0xffff) {
                word >>= 16;
                nr += 16;
        }
-       if (likely((word & 0xff) == 0xff)) {
+       if ((word & 0xff) == 0xff) {
                word >>= 8;
                nr += 8;
        }
@@ -549,16 +549,16 @@ static inline unsigned long __ffz_word(unsigned long nr, unsigned long word)
 static inline unsigned long __ffs_word(unsigned long nr, unsigned long word)
 {
 #ifdef __s390x__
-       if (likely((word & 0xffffffff) == 0)) {
+       if ((word & 0xffffffff) == 0) {
                word >>= 32;
                nr += 32;
        }
 #endif
-       if (likely((word & 0xffff) == 0)) {
+       if ((word & 0xffff) == 0) {
                word >>= 16;
                nr += 16;
        }
-       if (likely((word & 0xff) == 0)) {
+       if ((word & 0xff) == 0) {
                word >>= 8;
                nr += 8;
        }
diff --git a/arch/s390/include/asm/crw.h b/arch/s390/include/asm/crw.h
new file mode 100644 (file)
index 0000000..2185a6d
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *   Data definitions for channel report processing
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ *              Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *              Cornelia Huck <cornelia.huck@de.ibm.com>,
+ *              Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#ifndef _ASM_S390_CRW_H
+#define _ASM_S390_CRW_H
+
+#include <linux/types.h>
+
+/*
+ * Channel Report Word
+ */
+struct crw {
+       __u32 res1 :  1;   /* reserved zero */
+       __u32 slct :  1;   /* solicited */
+       __u32 oflw :  1;   /* overflow */
+       __u32 chn  :  1;   /* chained */
+       __u32 rsc  :  4;   /* reporting source code */
+       __u32 anc  :  1;   /* ancillary report */
+       __u32 res2 :  1;   /* reserved zero */
+       __u32 erc  :  6;   /* error-recovery code */
+       __u32 rsid : 16;   /* reporting-source ID */
+} __attribute__ ((packed));
+
+typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
+
+extern int crw_register_handler(int rsc, crw_handler_t handler);
+extern void crw_unregister_handler(int rsc);
+extern void crw_handle_channel_report(void);
+
+#define NR_RSCS 16
+
+#define CRW_RSC_MONITOR  0x2  /* monitoring facility */
+#define CRW_RSC_SCH     0x3  /* subchannel */
+#define CRW_RSC_CPATH   0x4  /* channel path */
+#define CRW_RSC_CONFIG  0x9  /* configuration-alert facility */
+#define CRW_RSC_CSS     0xB  /* channel subsystem */
+
+#define CRW_ERC_EVENT   0x00 /* event information pending */
+#define CRW_ERC_AVAIL   0x01 /* available */
+#define CRW_ERC_INIT    0x02 /* initialized */
+#define CRW_ERC_TERROR  0x03 /* temporary error */
+#define CRW_ERC_IPARM   0x04 /* installed parm initialized */
+#define CRW_ERC_TERM    0x05 /* terminal */
+#define CRW_ERC_PERRN   0x06 /* perm. error, fac. not init */
+#define CRW_ERC_PERRI   0x07 /* perm. error, facility init */
+#define CRW_ERC_PMOD    0x08 /* installed parameters modified */
+
+static inline int stcrw(struct crw *pcrw)
+{
+       int ccode;
+
+       asm volatile(
+               "       stcrw   0(%2)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
+               : "=d" (ccode), "=m" (*pcrw)
+               : "a" (pcrw)
+               : "cc" );
+       return ccode;
+}
+
+#endif /* _ASM_S390_CRW_H */
index e2db6f16d9c8bd6273ba0b26e56d9f2efe8c62e4..218bce81ec70f05db21fde6b512ac7e6fe83447c 100644 (file)
@@ -162,15 +162,15 @@ typedef struct dasd_profile_info_t {
         unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
 } dasd_profile_info_t;
 
-/* 
+/*
  * struct format_data_t
  * represents all data necessary to format a dasd
  */
 typedef struct format_data_t {
-       int start_unit; /* from track */
-       int stop_unit;  /* to track */
-       int blksize;    /* sectorsize */
-        int intensity;  
+       unsigned int start_unit; /* from track */
+       unsigned int stop_unit;  /* to track */
+       unsigned int blksize;    /* sectorsize */
+       unsigned int intensity;
 } format_data_t;
 
 /*
index e82c10efe65aee289c94fe59f761ce8c4c49acbb..aae276d00383cc90660f1e1771d0aee11ae36949 100644 (file)
@@ -44,24 +44,18 @@ idal_is_needed(void *vaddr, unsigned int length)
 /*
  * Return the number of idal words needed for an address/length pair.
  */
-static inline unsigned int
-idal_nr_words(void *vaddr, unsigned int length)
+static inline unsigned int idal_nr_words(void *vaddr, unsigned int length)
 {
-#ifdef __s390x__
-       if (idal_is_needed(vaddr, length))
-               return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length + 
-                       (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
-#endif
-       return 0;
+       return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
+               (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
 }
 
 /*
  * Create the list of idal words for an address/length pair.
  */
-static inline unsigned long *
-idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
+static inline unsigned long *idal_create_words(unsigned long *idaws,
+                                              void *vaddr, unsigned int length)
 {
-#ifdef __s390x__
        unsigned long paddr;
        unsigned int cidaw;
 
@@ -74,7 +68,6 @@ idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
                paddr += IDA_BLOCK_SIZE;
                *idaws++ = paddr;
        }
-#endif
        return idaws;
 }
 
index f3720defdd164de6e47cc5524cc9f5f67564f3b9..b349f1c7fdfab9dc73d91bcb9e177e38c74dc538 100644 (file)
 #ifndef _ASM_S390_LOWCORE_H
 #define _ASM_S390_LOWCORE_H
 
-#ifndef __s390x__
-#define __LC_EXT_OLD_PSW                0x018
-#define __LC_SVC_OLD_PSW                0x020
-#define __LC_PGM_OLD_PSW                0x028
-#define __LC_MCK_OLD_PSW                0x030
-#define __LC_IO_OLD_PSW                 0x038
-#define __LC_EXT_NEW_PSW                0x058
-#define __LC_SVC_NEW_PSW                0x060
-#define __LC_PGM_NEW_PSW                0x068
-#define __LC_MCK_NEW_PSW                0x070
-#define __LC_IO_NEW_PSW                 0x078
-#else /* !__s390x__ */
-#define __LC_EXT_OLD_PSW                0x0130
-#define __LC_SVC_OLD_PSW                0x0140
-#define __LC_PGM_OLD_PSW                0x0150
-#define __LC_MCK_OLD_PSW                0x0160
-#define __LC_IO_OLD_PSW                 0x0170
-#define __LC_EXT_NEW_PSW                0x01b0
-#define __LC_SVC_NEW_PSW                0x01c0
-#define __LC_PGM_NEW_PSW                0x01d0
-#define __LC_MCK_NEW_PSW                0x01e0
-#define __LC_IO_NEW_PSW                 0x01f0
-#endif /* !__s390x__ */
-
-#define __LC_IPL_PARMBLOCK_PTR         0x014
-#define __LC_EXT_PARAMS                 0x080
-#define __LC_CPU_ADDRESS                0x084
-#define __LC_EXT_INT_CODE               0x086
-
-#define __LC_SVC_ILC                    0x088
-#define __LC_SVC_INT_CODE               0x08A
-#define __LC_PGM_ILC                    0x08C
-#define __LC_PGM_INT_CODE               0x08E
+#define __LC_IPL_PARMBLOCK_PTR         0x0014
+#define __LC_EXT_PARAMS                        0x0080
+#define __LC_CPU_ADDRESS               0x0084
+#define __LC_EXT_INT_CODE              0x0086
 
-#define __LC_PER_ATMID                 0x096
-#define __LC_PER_ADDRESS               0x098
-#define __LC_PER_ACCESS_ID             0x0A1
-#define __LC_AR_MODE_ID                        0x0A3
+#define __LC_SVC_ILC                   0x0088
+#define __LC_SVC_INT_CODE              0x008a
+#define __LC_PGM_ILC                   0x008c
+#define __LC_PGM_INT_CODE              0x008e
 
-#define __LC_SUBCHANNEL_ID              0x0B8
-#define __LC_SUBCHANNEL_NR              0x0BA
-#define __LC_IO_INT_PARM                0x0BC
-#define __LC_IO_INT_WORD                0x0C0
-#define __LC_MCCK_CODE                  0x0E8
+#define __LC_PER_ATMID                 0x0096
+#define __LC_PER_ADDRESS               0x0098
+#define __LC_PER_ACCESS_ID             0x00a1
+#define __LC_AR_MODE_ID                        0x00a3
 
-#define __LC_LAST_BREAK                0x110
-
-#define __LC_RETURN_PSW                 0x200
-
-#define __LC_SAVE_AREA                  0xC00
-
-#ifndef __s390x__
-#define __LC_IRB                       0x208
-#define __LC_SYNC_ENTER_TIMER          0x248
-#define __LC_ASYNC_ENTER_TIMER         0x250
-#define __LC_EXIT_TIMER                        0x258
-#define __LC_USER_TIMER                        0x260
-#define __LC_SYSTEM_TIMER              0x268
-#define __LC_STEAL_TIMER               0x270
-#define __LC_LAST_UPDATE_TIMER         0x278
-#define __LC_LAST_UPDATE_CLOCK         0x280
-#define __LC_RETURN_MCCK_PSW            0x288
-#define __LC_KERNEL_STACK               0xC40
-#define __LC_THREAD_INFO               0xC44
-#define __LC_ASYNC_STACK                0xC48
-#define __LC_KERNEL_ASCE               0xC4C
-#define __LC_USER_ASCE                 0xC50
-#define __LC_PANIC_STACK                0xC54
-#define __LC_CPUID                      0xC60
-#define __LC_CPUADDR                    0xC68
-#define __LC_IPLDEV                     0xC7C
-#define __LC_CURRENT                   0xC90
-#define __LC_INT_CLOCK                 0xC98
-#else /* __s390x__ */
-#define __LC_IRB                       0x210
-#define __LC_SYNC_ENTER_TIMER          0x250
-#define __LC_ASYNC_ENTER_TIMER         0x258
-#define __LC_EXIT_TIMER                        0x260
-#define __LC_USER_TIMER                        0x268
-#define __LC_SYSTEM_TIMER              0x270
-#define __LC_STEAL_TIMER               0x278
-#define __LC_LAST_UPDATE_TIMER         0x280
-#define __LC_LAST_UPDATE_CLOCK         0x288
-#define __LC_RETURN_MCCK_PSW            0x290
-#define __LC_KERNEL_STACK               0xD40
-#define __LC_THREAD_INFO               0xD48
-#define __LC_ASYNC_STACK                0xD50
-#define __LC_KERNEL_ASCE               0xD58
-#define __LC_USER_ASCE                 0xD60
-#define __LC_PANIC_STACK                0xD68
-#define __LC_CPUID                     0xD80
-#define __LC_CPUADDR                   0xD88
-#define __LC_IPLDEV                     0xDB8
-#define __LC_CURRENT                   0xDD8
-#define __LC_INT_CLOCK                 0xDE8
-#define __LC_VDSO_PER_CPU              0xE38
-#endif /* __s390x__ */
+#define __LC_SUBCHANNEL_ID             0x00b8
+#define __LC_SUBCHANNEL_NR             0x00ba
+#define __LC_IO_INT_PARM               0x00bc
+#define __LC_IO_INT_WORD               0x00c0
+#define __LC_MCCK_CODE                 0x00e8
 
-#define __LC_PASTE                     0xE40
+#define __LC_DUMP_REIPL                        0x0e00
 
-#define __LC_PANIC_MAGIC               0xE00
 #ifndef __s390x__
-#define __LC_PFAULT_INTPARM             0x080
-#define __LC_CPU_TIMER_SAVE_AREA        0x0D8
-#define __LC_CLOCK_COMP_SAVE_AREA      0x0E0
-#define __LC_PSW_SAVE_AREA             0x100
-#define __LC_PREFIX_SAVE_AREA          0x108
-#define __LC_AREGS_SAVE_AREA            0x120
-#define __LC_FPREGS_SAVE_AREA          0x160
-#define __LC_GPREGS_SAVE_AREA           0x180
-#define __LC_CREGS_SAVE_AREA            0x1C0
+#define __LC_EXT_OLD_PSW               0x0018
+#define __LC_SVC_OLD_PSW               0x0020
+#define __LC_PGM_OLD_PSW               0x0028
+#define __LC_MCK_OLD_PSW               0x0030
+#define __LC_IO_OLD_PSW                        0x0038
+#define __LC_EXT_NEW_PSW               0x0058
+#define __LC_SVC_NEW_PSW               0x0060
+#define __LC_PGM_NEW_PSW               0x0068
+#define __LC_MCK_NEW_PSW               0x0070
+#define __LC_IO_NEW_PSW                        0x0078
+#define __LC_SAVE_AREA                 0x0200
+#define __LC_RETURN_PSW                        0x0240
+#define __LC_RETURN_MCCK_PSW           0x0248
+#define __LC_SYNC_ENTER_TIMER          0x0250
+#define __LC_ASYNC_ENTER_TIMER         0x0258
+#define __LC_EXIT_TIMER                        0x0260
+#define __LC_USER_TIMER                        0x0268
+#define __LC_SYSTEM_TIMER              0x0270
+#define __LC_STEAL_TIMER               0x0278
+#define __LC_LAST_UPDATE_TIMER         0x0280
+#define __LC_LAST_UPDATE_CLOCK         0x0288
+#define __LC_CURRENT                   0x0290
+#define __LC_THREAD_INFO               0x0294
+#define __LC_KERNEL_STACK              0x0298
+#define __LC_ASYNC_STACK               0x029c
+#define __LC_PANIC_STACK               0x02a0
+#define __LC_KERNEL_ASCE               0x02a4
+#define __LC_USER_ASCE                 0x02a8
+#define __LC_USER_EXEC_ASCE            0x02ac
+#define __LC_CPUID                     0x02b0
+#define __LC_INT_CLOCK                 0x02c8
+#define __LC_IRB                       0x0300
+#define __LC_PFAULT_INTPARM            0x0080
+#define __LC_CPU_TIMER_SAVE_AREA       0x00d8
+#define __LC_CLOCK_COMP_SAVE_AREA      0x00e0
+#define __LC_PSW_SAVE_AREA             0x0100
+#define __LC_PREFIX_SAVE_AREA          0x0108
+#define __LC_AREGS_SAVE_AREA           0x0120
+#define __LC_FPREGS_SAVE_AREA          0x0160
+#define __LC_GPREGS_SAVE_AREA          0x0180
+#define __LC_CREGS_SAVE_AREA           0x01c0
 #else /* __s390x__ */
-#define __LC_PFAULT_INTPARM             0x11B8
+#define __LC_LAST_BREAK                        0x0110
+#define __LC_EXT_OLD_PSW               0x0130
+#define __LC_SVC_OLD_PSW               0x0140
+#define __LC_PGM_OLD_PSW               0x0150
+#define __LC_MCK_OLD_PSW               0x0160
+#define __LC_IO_OLD_PSW                        0x0170
+#define __LC_EXT_NEW_PSW               0x01b0
+#define __LC_SVC_NEW_PSW               0x01c0
+#define __LC_PGM_NEW_PSW               0x01d0
+#define __LC_MCK_NEW_PSW               0x01e0
+#define __LC_IO_NEW_PSW                        0x01f0
+#define __LC_SAVE_AREA                 0x0200
+#define __LC_RETURN_PSW                        0x0280
+#define __LC_RETURN_MCCK_PSW           0x0290
+#define __LC_SYNC_ENTER_TIMER          0x02a0
+#define __LC_ASYNC_ENTER_TIMER         0x02a8
+#define __LC_EXIT_TIMER                        0x02b0
+#define __LC_USER_TIMER                        0x02b8
+#define __LC_SYSTEM_TIMER              0x02c0
+#define __LC_STEAL_TIMER               0x02c8
+#define __LC_LAST_UPDATE_TIMER         0x02d0
+#define __LC_LAST_UPDATE_CLOCK         0x02d8
+#define __LC_CURRENT                   0x02e0
+#define __LC_THREAD_INFO               0x02e8
+#define __LC_KERNEL_STACK              0x02f0
+#define __LC_ASYNC_STACK               0x02f8
+#define __LC_PANIC_STACK               0x0300
+#define __LC_KERNEL_ASCE               0x0308
+#define __LC_USER_ASCE                 0x0310
+#define __LC_USER_EXEC_ASCE            0x0318
+#define __LC_CPUID                     0x0320
+#define __LC_INT_CLOCK                 0x0340
+#define __LC_VDSO_PER_CPU              0x0350
+#define __LC_IRB                       0x0380
+#define __LC_PASTE                     0x03c0
+#define __LC_PFAULT_INTPARM            0x11b8
 #define __LC_FPREGS_SAVE_AREA          0x1200
-#define __LC_GPREGS_SAVE_AREA           0x1280
+#define __LC_GPREGS_SAVE_AREA          0x1280
 #define __LC_PSW_SAVE_AREA             0x1300
 #define __LC_PREFIX_SAVE_AREA          0x1318
-#define __LC_FP_CREG_SAVE_AREA         0x131C
+#define __LC_FP_CREG_SAVE_AREA         0x131c
 #define __LC_TODREG_SAVE_AREA          0x1324
-#define __LC_CPU_TIMER_SAVE_AREA        0x1328
+#define __LC_CPU_TIMER_SAVE_AREA       0x1328
 #define __LC_CLOCK_COMP_SAVE_AREA      0x1331
-#define __LC_AREGS_SAVE_AREA            0x1340
-#define __LC_CREGS_SAVE_AREA            0x1380
+#define __LC_AREGS_SAVE_AREA           0x1340
+#define __LC_CREGS_SAVE_AREA           0x1380
 #endif /* __s390x__ */
 
 #ifndef __ASSEMBLY__
@@ -198,222 +187,240 @@ union save_area {
 struct _lowcore
 {
 #ifndef __s390x__
-        /* prefix area: defined by architecture */
-       psw_t        restart_psw;              /* 0x000 */
-       __u32        ccw2[4];                  /* 0x008 */
-       psw_t        external_old_psw;         /* 0x018 */
-       psw_t        svc_old_psw;              /* 0x020 */
-       psw_t        program_old_psw;          /* 0x028 */
-       psw_t        mcck_old_psw;             /* 0x030 */
-       psw_t        io_old_psw;               /* 0x038 */
-       __u8         pad1[0x58-0x40];          /* 0x040 */
-       psw_t        external_new_psw;         /* 0x058 */
-       psw_t        svc_new_psw;              /* 0x060 */
-       psw_t        program_new_psw;          /* 0x068 */
-       psw_t        mcck_new_psw;             /* 0x070 */
-       psw_t        io_new_psw;               /* 0x078 */
-       __u32        ext_params;               /* 0x080 */
-       __u16        cpu_addr;                 /* 0x084 */
-       __u16        ext_int_code;             /* 0x086 */
-        __u16        svc_ilc;                  /* 0x088 */
-        __u16        svc_code;                 /* 0x08a */
-        __u16        pgm_ilc;                  /* 0x08c */
-        __u16        pgm_code;                 /* 0x08e */
-       __u32        trans_exc_code;           /* 0x090 */
-       __u16        mon_class_num;            /* 0x094 */
-       __u16        per_perc_atmid;           /* 0x096 */
-       __u32        per_address;              /* 0x098 */
-       __u32        monitor_code;             /* 0x09c */
-       __u8         exc_access_id;            /* 0x0a0 */
-       __u8         per_access_id;            /* 0x0a1 */
-       __u8         pad2[0xB8-0xA2];          /* 0x0a2 */
-       __u16        subchannel_id;            /* 0x0b8 */
-       __u16        subchannel_nr;            /* 0x0ba */
-       __u32        io_int_parm;              /* 0x0bc */
-       __u32        io_int_word;              /* 0x0c0 */
-       __u8         pad3[0xc8-0xc4];          /* 0x0c4 */
-       __u32        stfl_fac_list;            /* 0x0c8 */
-       __u8         pad4[0xd4-0xcc];          /* 0x0cc */
-       __u32        extended_save_area_addr;  /* 0x0d4 */
-       __u32        cpu_timer_save_area[2];   /* 0x0d8 */
-       __u32        clock_comp_save_area[2];  /* 0x0e0 */
-       __u32        mcck_interruption_code[2]; /* 0x0e8 */
-       __u8         pad5[0xf4-0xf0];          /* 0x0f0 */
-       __u32        external_damage_code;     /* 0x0f4 */
-       __u32        failing_storage_address;  /* 0x0f8 */
-       __u8         pad6[0x100-0xfc];         /* 0x0fc */
-       __u32        st_status_fixed_logout[4];/* 0x100 */
-       __u8         pad7[0x120-0x110];        /* 0x110 */
-       __u32        access_regs_save_area[16];/* 0x120 */
-       __u32        floating_pt_save_area[8]; /* 0x160 */
-       __u32        gpregs_save_area[16];     /* 0x180 */
-       __u32        cregs_save_area[16];      /* 0x1c0 */      
-
-        psw_t        return_psw;               /* 0x200 */
-       __u8         irb[64];                  /* 0x208 */
-       __u64        sync_enter_timer;         /* 0x248 */
-       __u64        async_enter_timer;        /* 0x250 */
-       __u64        exit_timer;               /* 0x258 */
-       __u64        user_timer;               /* 0x260 */
-       __u64        system_timer;             /* 0x268 */
-       __u64        steal_timer;              /* 0x270 */
-       __u64        last_update_timer;        /* 0x278 */
-       __u64        last_update_clock;        /* 0x280 */
-        psw_t        return_mcck_psw;          /* 0x288 */
-       __u8         pad8[0xc00-0x290];        /* 0x290 */
-
-        /* System info area */
-       __u32        save_area[16];            /* 0xc00 */
-       __u32        kernel_stack;             /* 0xc40 */
-       __u32        thread_info;              /* 0xc44 */
-       __u32        async_stack;              /* 0xc48 */
-       __u32        kernel_asce;              /* 0xc4c */
-       __u32        user_asce;                /* 0xc50 */
-       __u32        panic_stack;              /* 0xc54 */
-       __u32        user_exec_asce;           /* 0xc58 */
-       __u8         pad10[0xc60-0xc5c];       /* 0xc5c */
-       /* entry.S sensitive area start */
-       struct       cpuinfo_S390 cpu_data;    /* 0xc60 */
-       __u32        ipl_device;               /* 0xc7c */
-       /* entry.S sensitive area end */
-
-        /* SMP info area: defined by DJB */
-       __u64        clock_comparator;         /* 0xc80 */
-       __u32        ext_call_fast;            /* 0xc88 */
-       __u32        percpu_offset;            /* 0xc8c */
-       __u32        current_task;             /* 0xc90 */
-       __u32        softirq_pending;          /* 0xc94 */
-       __u64        int_clock;                /* 0xc98 */
-        __u8         pad11[0xe00-0xca0];       /* 0xca0 */
-
-        /* 0xe00 is used as indicator for dump tools */
-        /* whether the kernel died with panic() or not */
-        __u32        panic_magic;              /* 0xe00 */
-
-        /* Align to the top 1k of prefix area */
-       __u8         pad12[0x1000-0xe04];      /* 0xe04 */
+       /* 0x0000 - 0x01ff: defined by architecture */
+       psw_t   restart_psw;                    /* 0x0000 */
+       __u32   ccw2[4];                        /* 0x0008 */
+       psw_t   external_old_psw;               /* 0x0018 */
+       psw_t   svc_old_psw;                    /* 0x0020 */
+       psw_t   program_old_psw;                /* 0x0028 */
+       psw_t   mcck_old_psw;                   /* 0x0030 */
+       psw_t   io_old_psw;                     /* 0x0038 */
+       __u8    pad_0x0040[0x0058-0x0040];      /* 0x0040 */
+       psw_t   external_new_psw;               /* 0x0058 */
+       psw_t   svc_new_psw;                    /* 0x0060 */
+       psw_t   program_new_psw;                /* 0x0068 */
+       psw_t   mcck_new_psw;                   /* 0x0070 */
+       psw_t   io_new_psw;                     /* 0x0078 */
+       __u32   ext_params;                     /* 0x0080 */
+       __u16   cpu_addr;                       /* 0x0084 */
+       __u16   ext_int_code;                   /* 0x0086 */
+       __u16   svc_ilc;                        /* 0x0088 */
+       __u16   svc_code;                       /* 0x008a */
+       __u16   pgm_ilc;                        /* 0x008c */
+       __u16   pgm_code;                       /* 0x008e */
+       __u32   trans_exc_code;                 /* 0x0090 */
+       __u16   mon_class_num;                  /* 0x0094 */
+       __u16   per_perc_atmid;                 /* 0x0096 */
+       __u32   per_address;                    /* 0x0098 */
+       __u32   monitor_code;                   /* 0x009c */
+       __u8    exc_access_id;                  /* 0x00a0 */
+       __u8    per_access_id;                  /* 0x00a1 */
+       __u8    pad_0x00a2[0x00b8-0x00a2];      /* 0x00a2 */
+       __u16   subchannel_id;                  /* 0x00b8 */
+       __u16   subchannel_nr;                  /* 0x00ba */
+       __u32   io_int_parm;                    /* 0x00bc */
+       __u32   io_int_word;                    /* 0x00c0 */
+       __u8    pad_0x00c4[0x00c8-0x00c4];      /* 0x00c4 */
+       __u32   stfl_fac_list;                  /* 0x00c8 */
+       __u8    pad_0x00cc[0x00d4-0x00cc];      /* 0x00cc */
+       __u32   extended_save_area_addr;        /* 0x00d4 */
+       __u32   cpu_timer_save_area[2];         /* 0x00d8 */
+       __u32   clock_comp_save_area[2];        /* 0x00e0 */
+       __u32   mcck_interruption_code[2];      /* 0x00e8 */
+       __u8    pad_0x00f0[0x00f4-0x00f0];      /* 0x00f0 */
+       __u32   external_damage_code;           /* 0x00f4 */
+       __u32   failing_storage_address;        /* 0x00f8 */
+       __u8    pad_0x00fc[0x0100-0x00fc];      /* 0x00fc */
+       __u32   st_status_fixed_logout[4];      /* 0x0100 */
+       __u8    pad_0x0110[0x0120-0x0110];      /* 0x0110 */
+
+       /* CPU register save area: defined by architecture */
+       __u32   access_regs_save_area[16];      /* 0x0120 */
+       __u32   floating_pt_save_area[8];       /* 0x0160 */
+       __u32   gpregs_save_area[16];           /* 0x0180 */
+       __u32   cregs_save_area[16];            /* 0x01c0 */
+
+       /* Return psws. */
+       __u32   save_area[16];                  /* 0x0200 */
+       psw_t   return_psw;                     /* 0x0240 */
+       psw_t   return_mcck_psw;                /* 0x0248 */
+
+       /* CPU time accounting values */
+       __u64   sync_enter_timer;               /* 0x0250 */
+       __u64   async_enter_timer;              /* 0x0258 */
+       __u64   exit_timer;                     /* 0x0260 */
+       __u64   user_timer;                     /* 0x0268 */
+       __u64   system_timer;                   /* 0x0270 */
+       __u64   steal_timer;                    /* 0x0278 */
+       __u64   last_update_timer;              /* 0x0280 */
+       __u64   last_update_clock;              /* 0x0288 */
+
+       /* Current process. */
+       __u32   current_task;                   /* 0x0290 */
+       __u32   thread_info;                    /* 0x0294 */
+       __u32   kernel_stack;                   /* 0x0298 */
+
+       /* Interrupt and panic stack. */
+       __u32   async_stack;                    /* 0x029c */
+       __u32   panic_stack;                    /* 0x02a0 */
+
+       /* Address space pointer. */
+       __u32   kernel_asce;                    /* 0x02a4 */
+       __u32   user_asce;                      /* 0x02a8 */
+       __u32   user_exec_asce;                 /* 0x02ac */
+
+       /* SMP info area */
+       cpuid_t cpu_id;                         /* 0x02b0 */
+       __u32   cpu_nr;                         /* 0x02b8 */
+       __u32   softirq_pending;                /* 0x02bc */
+       __u32   percpu_offset;                  /* 0x02c0 */
+       __u32   ext_call_fast;                  /* 0x02c4 */
+       __u64   int_clock;                      /* 0x02c8 */
+       __u64   clock_comparator;               /* 0x02d0 */
+       __u8    pad_0x02d8[0x0300-0x02d8];      /* 0x02d8 */
+
+       /* Interrupt response block */
+       __u8    irb[64];                        /* 0x0300 */
+
+       __u8    pad_0x0400[0x0e00-0x0400];      /* 0x0400 */
+
+       /*
+        * 0xe00 contains the address of the IPL Parameter Information
+        * block. Dump tools need IPIB for IPL after dump.
+        * Note: do not change the position of any fields in 0x0e00-0x0f00
+        */
+       __u32   ipib;                           /* 0x0e00 */
+       __u32   ipib_checksum;                  /* 0x0e04 */
+
+       /* Align to the top 1k of prefix area */
+       __u8    pad_0x0e08[0x1000-0x0e08];      /* 0x0e08 */
 #else /* !__s390x__ */
-        /* prefix area: defined by architecture */
-       __u32        ccw1[2];                  /* 0x000 */
-       __u32        ccw2[4];                  /* 0x008 */
-       __u8         pad1[0x80-0x18];          /* 0x018 */
-       __u32        ext_params;               /* 0x080 */
-       __u16        cpu_addr;                 /* 0x084 */
-       __u16        ext_int_code;             /* 0x086 */
-        __u16        svc_ilc;                  /* 0x088 */
-        __u16        svc_code;                 /* 0x08a */
-        __u16        pgm_ilc;                  /* 0x08c */
-        __u16        pgm_code;                 /* 0x08e */
-       __u32        data_exc_code;            /* 0x090 */
-       __u16        mon_class_num;            /* 0x094 */
-       __u16        per_perc_atmid;           /* 0x096 */
-       addr_t       per_address;              /* 0x098 */
-       __u8         exc_access_id;            /* 0x0a0 */
-       __u8         per_access_id;            /* 0x0a1 */
-       __u8         op_access_id;             /* 0x0a2 */
-       __u8         ar_access_id;             /* 0x0a3 */
-       __u8         pad2[0xA8-0xA4];          /* 0x0a4 */
-       addr_t       trans_exc_code;           /* 0x0A0 */
-       addr_t       monitor_code;             /* 0x09c */
-       __u16        subchannel_id;            /* 0x0b8 */
-       __u16        subchannel_nr;            /* 0x0ba */
-       __u32        io_int_parm;              /* 0x0bc */
-       __u32        io_int_word;              /* 0x0c0 */
-       __u8         pad3[0xc8-0xc4];          /* 0x0c4 */
-       __u32        stfl_fac_list;            /* 0x0c8 */
-       __u8         pad4[0xe8-0xcc];          /* 0x0cc */
-       __u32        mcck_interruption_code[2]; /* 0x0e8 */
-       __u8         pad5[0xf4-0xf0];          /* 0x0f0 */
-       __u32        external_damage_code;     /* 0x0f4 */
-       addr_t       failing_storage_address;  /* 0x0f8 */
-       __u8         pad6[0x120-0x100];        /* 0x100 */
-       psw_t        restart_old_psw;          /* 0x120 */
-       psw_t        external_old_psw;         /* 0x130 */
-       psw_t        svc_old_psw;              /* 0x140 */
-       psw_t        program_old_psw;          /* 0x150 */
-       psw_t        mcck_old_psw;             /* 0x160 */
-       psw_t        io_old_psw;               /* 0x170 */
-       __u8         pad7[0x1a0-0x180];        /* 0x180 */
-       psw_t        restart_psw;              /* 0x1a0 */
-       psw_t        external_new_psw;         /* 0x1b0 */
-       psw_t        svc_new_psw;              /* 0x1c0 */
-       psw_t        program_new_psw;          /* 0x1d0 */
-       psw_t        mcck_new_psw;             /* 0x1e0 */
-       psw_t        io_new_psw;               /* 0x1f0 */
-        psw_t        return_psw;               /* 0x200 */
-       __u8         irb[64];                  /* 0x210 */
-       __u64        sync_enter_timer;         /* 0x250 */
-       __u64        async_enter_timer;        /* 0x258 */
-       __u64        exit_timer;               /* 0x260 */
-       __u64        user_timer;               /* 0x268 */
-       __u64        system_timer;             /* 0x270 */
-       __u64        steal_timer;              /* 0x278 */
-       __u64        last_update_timer;        /* 0x280 */
-       __u64        last_update_clock;        /* 0x288 */
-        psw_t        return_mcck_psw;          /* 0x290 */
-        __u8         pad8[0xc00-0x2a0];        /* 0x2a0 */
-        /* System info area */
-       __u64        save_area[16];            /* 0xc00 */
-        __u8         pad9[0xd40-0xc80];        /* 0xc80 */
-       __u64        kernel_stack;             /* 0xd40 */
-       __u64        thread_info;              /* 0xd48 */
-       __u64        async_stack;              /* 0xd50 */
-       __u64        kernel_asce;              /* 0xd58 */
-       __u64        user_asce;                /* 0xd60 */
-       __u64        panic_stack;              /* 0xd68 */
-       __u64        user_exec_asce;           /* 0xd70 */
-       __u8         pad10[0xd80-0xd78];       /* 0xd78 */
-       /* entry.S sensitive area start */
-       struct       cpuinfo_S390 cpu_data;    /* 0xd80 */
-       __u32        ipl_device;               /* 0xdb8 */
-       __u32        pad11;                    /* 0xdbc */
-       /* entry.S sensitive area end */
-
-        /* SMP info area: defined by DJB */
-       __u64        clock_comparator;         /* 0xdc0 */
-       __u64        ext_call_fast;            /* 0xdc8 */
-       __u64        percpu_offset;            /* 0xdd0 */
-       __u64        current_task;             /* 0xdd8 */
-       __u32        softirq_pending;          /* 0xde0 */
-       __u32        pad_0x0de4;               /* 0xde4 */
-       __u64        int_clock;                /* 0xde8 */
-        __u8         pad12[0xe00-0xdf0];       /* 0xdf0 */
-
-        /* 0xe00 is used as indicator for dump tools */
-        /* whether the kernel died with panic() or not */
-        __u32        panic_magic;              /* 0xe00 */
+       /* 0x0000 - 0x01ff: defined by architecture */
+       __u32   ccw1[2];                        /* 0x0000 */
+       __u32   ccw2[4];                        /* 0x0008 */
+       __u8    pad_0x0018[0x0080-0x0018];      /* 0x0018 */
+       __u32   ext_params;                     /* 0x0080 */
+       __u16   cpu_addr;                       /* 0x0084 */
+       __u16   ext_int_code;                   /* 0x0086 */
+       __u16   svc_ilc;                        /* 0x0088 */
+       __u16   svc_code;                       /* 0x008a */
+       __u16   pgm_ilc;                        /* 0x008c */
+       __u16   pgm_code;                       /* 0x008e */
+       __u32   data_exc_code;                  /* 0x0090 */
+       __u16   mon_class_num;                  /* 0x0094 */
+       __u16   per_perc_atmid;                 /* 0x0096 */
+       addr_t  per_address;                    /* 0x0098 */
+       __u8    exc_access_id;                  /* 0x00a0 */
+       __u8    per_access_id;                  /* 0x00a1 */
+       __u8    op_access_id;                   /* 0x00a2 */
+       __u8    ar_access_id;                   /* 0x00a3 */
+       __u8    pad_0x00a4[0x00a8-0x00a4];      /* 0x00a4 */
+       addr_t  trans_exc_code;                 /* 0x00a8 */
+       addr_t  monitor_code;                   /* 0x00b0 */
+       __u16   subchannel_id;                  /* 0x00b8 */
+       __u16   subchannel_nr;                  /* 0x00ba */
+       __u32   io_int_parm;                    /* 0x00bc */
+       __u32   io_int_word;                    /* 0x00c0 */
+       __u8    pad_0x00c4[0x00c8-0x00c4];      /* 0x00c4 */
+       __u32   stfl_fac_list;                  /* 0x00c8 */
+       __u8    pad_0x00cc[0x00e8-0x00cc];      /* 0x00cc */
+       __u32   mcck_interruption_code[2];      /* 0x00e8 */
+       __u8    pad_0x00f0[0x00f4-0x00f0];      /* 0x00f0 */
+       __u32   external_damage_code;           /* 0x00f4 */
+       addr_t  failing_storage_address;        /* 0x00f8 */
+       __u8    pad_0x0100[0x0120-0x0100];      /* 0x0100 */
+       psw_t   restart_old_psw;                /* 0x0120 */
+       psw_t   external_old_psw;               /* 0x0130 */
+       psw_t   svc_old_psw;                    /* 0x0140 */
+       psw_t   program_old_psw;                /* 0x0150 */
+       psw_t   mcck_old_psw;                   /* 0x0160 */
+       psw_t   io_old_psw;                     /* 0x0170 */
+       __u8    pad_0x0180[0x01a0-0x0180];      /* 0x0180 */
+       psw_t   restart_psw;                    /* 0x01a0 */
+       psw_t   external_new_psw;               /* 0x01b0 */
+       psw_t   svc_new_psw;                    /* 0x01c0 */
+       psw_t   program_new_psw;                /* 0x01d0 */
+       psw_t   mcck_new_psw;                   /* 0x01e0 */
+       psw_t   io_new_psw;                     /* 0x01f0 */
+
+       /* Entry/exit save area & return psws. */
+       __u64   save_area[16];                  /* 0x0200 */
+       psw_t   return_psw;                     /* 0x0280 */
+       psw_t   return_mcck_psw;                /* 0x0290 */
+
+       /* CPU accounting and timing values. */
+       __u64   sync_enter_timer;               /* 0x02a0 */
+       __u64   async_enter_timer;              /* 0x02a8 */
+       __u64   exit_timer;                     /* 0x02b0 */
+       __u64   user_timer;                     /* 0x02b8 */
+       __u64   system_timer;                   /* 0x02c0 */
+       __u64   steal_timer;                    /* 0x02c8 */
+       __u64   last_update_timer;              /* 0x02d0 */
+       __u64   last_update_clock;              /* 0x02d8 */
+
+       /* Current process. */
+       __u64   current_task;                   /* 0x02e0 */
+       __u64   thread_info;                    /* 0x02e8 */
+       __u64   kernel_stack;                   /* 0x02f0 */
+
+       /* Interrupt and panic stack. */
+       __u64   async_stack;                    /* 0x02f8 */
+       __u64   panic_stack;                    /* 0x0300 */
+
+       /* Address space pointer. */
+       __u64   kernel_asce;                    /* 0x0308 */
+       __u64   user_asce;                      /* 0x0310 */
+       __u64   user_exec_asce;                 /* 0x0318 */
+
+       /* SMP info area */
+       cpuid_t cpu_id;                         /* 0x0320 */
+       __u32   cpu_nr;                         /* 0x0328 */
+       __u32   softirq_pending;                /* 0x032c */
+       __u64   percpu_offset;                  /* 0x0330 */
+       __u64   ext_call_fast;                  /* 0x0338 */
+       __u64   int_clock;                      /* 0x0340 */
+       __u64   clock_comparator;               /* 0x0348 */
+       __u64   vdso_per_cpu_data;              /* 0x0350 */
+       __u8    pad_0x0358[0x0380-0x0358];      /* 0x0358 */
+
+       /* Interrupt response block. */
+       __u8    irb[64];                        /* 0x0380 */
 
        /* Per cpu primary space access list */
-       __u8         pad_0xe04[0xe38-0xe04];   /* 0xe04 */
-       __u64        vdso_per_cpu_data;        /* 0xe38 */
-       __u32        paste[16];                /* 0xe40 */
-
-       __u8         pad13[0x11b8-0xe80];      /* 0xe80 */
-
-       /* 64 bit extparam used for pfault, diag 250 etc  */
-       __u64        ext_params2;               /* 0x11B8 */
-
-       __u8         pad14[0x1200-0x11C0];      /* 0x11C0 */
-
-        /* System info area */ 
-
-       __u64        floating_pt_save_area[16]; /* 0x1200 */
-       __u64        gpregs_save_area[16];      /* 0x1280 */
-       __u32        st_status_fixed_logout[4]; /* 0x1300 */
-       __u8         pad15[0x1318-0x1310];      /* 0x1310 */
-       __u32        prefixreg_save_area;       /* 0x1318 */
-       __u32        fpt_creg_save_area;        /* 0x131c */
-       __u8         pad16[0x1324-0x1320];      /* 0x1320 */
-       __u32        tod_progreg_save_area;     /* 0x1324 */
-       __u32        cpu_timer_save_area[2];    /* 0x1328 */
-       __u32        clock_comp_save_area[2];   /* 0x1330 */
-       __u8         pad17[0x1340-0x1338];      /* 0x1338 */
-       __u32        access_regs_save_area[16]; /* 0x1340 */ 
-       __u64        cregs_save_area[16];       /* 0x1380 */
+       __u32   paste[16];                      /* 0x03c0 */
+
+       __u8    pad_0x0400[0x0e00-0x0400];      /* 0x0400 */
+
+       /*
+        * 0xe00 contains the address of the IPL Parameter Information
+        * block. Dump tools need IPIB for IPL after dump.
+        * Note: do not change the position of any fields in 0x0e00-0x0f00
+        */
+       __u64   ipib;                           /* 0x0e00 */
+       __u32   ipib_checksum;                  /* 0x0e08 */
+       __u8    pad_0x0e0c[0x11b8-0x0e0c];      /* 0x0e0c */
+
+       /* 64 bit extparam used for pfault/diag 250: defined by architecture */
+       __u64   ext_params2;                    /* 0x11B8 */
+       __u8    pad_0x11c0[0x1200-0x11C0];      /* 0x11C0 */
+
+       /* CPU register save area: defined by architecture */
+       __u64   floating_pt_save_area[16];      /* 0x1200 */
+       __u64   gpregs_save_area[16];           /* 0x1280 */
+       __u32   st_status_fixed_logout[4];      /* 0x1300 */
+       __u8    pad_0x1310[0x1318-0x1310];      /* 0x1310 */
+       __u32   prefixreg_save_area;            /* 0x1318 */
+       __u32   fpt_creg_save_area;             /* 0x131c */
+       __u8    pad_0x1320[0x1324-0x1320];      /* 0x1320 */
+       __u32   tod_progreg_save_area;          /* 0x1324 */
+       __u32   cpu_timer_save_area[2];         /* 0x1328 */
+       __u32   clock_comp_save_area[2];        /* 0x1330 */
+       __u8    pad_0x1338[0x1340-0x1338];      /* 0x1338 */
+       __u32   access_regs_save_area[16];      /* 0x1340 */
+       __u64   cregs_save_area[16];            /* 0x1380 */
 
        /* align to the top of the prefix area */
-
-       __u8         pad18[0x2000-0x1400];      /* 0x1400 */
+       __u8    pad_0x1400[0x2000-0x1400];      /* 0x1400 */
 #endif /* !__s390x__ */
 } __attribute__((packed)); /* End structure*/
 
@@ -433,8 +440,6 @@ static inline __u32 store_prefix(void)
        return address;
 }
 
-#define __PANIC_MAGIC           0xDEADC0DE
-
 #endif
 
 #endif
index 28ec870655af01fba9750fbc1d9e3105f41579fc..fc7edd6f41b6c736382df3339434caeb4b6da5d7 100644 (file)
@@ -74,7 +74,7 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                             struct task_struct *tsk)
 {
-       cpu_set(smp_processor_id(), next->cpu_vm_mask);
+       cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
        update_mm(next, tsk);
 }
 
diff --git a/arch/s390/include/asm/nmi.h b/arch/s390/include/asm/nmi.h
new file mode 100644 (file)
index 0000000..f4b6044
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *   Machine check handler definitions
+ *
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ *              Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *              Cornelia Huck <cornelia.huck@de.ibm.com>,
+ *              Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#ifndef _ASM_S390_NMI_H
+#define _ASM_S390_NMI_H
+
+#include <linux/types.h>
+
+struct mci {
+       __u32 sd :  1; /* 00 system damage */
+       __u32 pd :  1; /* 01 instruction-processing damage */
+       __u32 sr :  1; /* 02 system recovery */
+       __u32    :  1; /* 03 */
+       __u32 cd :  1; /* 04 timing-facility damage */
+       __u32 ed :  1; /* 05 external damage */
+       __u32    :  1; /* 06 */
+       __u32 dg :  1; /* 07 degradation */
+       __u32 w  :  1; /* 08 warning pending */
+       __u32 cp :  1; /* 09 channel-report pending */
+       __u32 sp :  1; /* 10 service-processor damage */
+       __u32 ck :  1; /* 11 channel-subsystem damage */
+       __u32    :  2; /* 12-13 */
+       __u32 b  :  1; /* 14 backed up */
+       __u32    :  1; /* 15 */
+       __u32 se :  1; /* 16 storage error uncorrected */
+       __u32 sc :  1; /* 17 storage error corrected */
+       __u32 ke :  1; /* 18 storage-key error uncorrected */
+       __u32 ds :  1; /* 19 storage degradation */
+       __u32 wp :  1; /* 20 psw mwp validity */
+       __u32 ms :  1; /* 21 psw mask and key validity */
+       __u32 pm :  1; /* 22 psw program mask and cc validity */
+       __u32 ia :  1; /* 23 psw instruction address validity */
+       __u32 fa :  1; /* 24 failing storage address validity */
+       __u32    :  1; /* 25 */
+       __u32 ec :  1; /* 26 external damage code validity */
+       __u32 fp :  1; /* 27 floating point register validity */
+       __u32 gr :  1; /* 28 general register validity */
+       __u32 cr :  1; /* 29 control register validity */
+       __u32    :  1; /* 30 */
+       __u32 st :  1; /* 31 storage logical validity */
+       __u32 ie :  1; /* 32 indirect storage error */
+       __u32 ar :  1; /* 33 access register validity */
+       __u32 da :  1; /* 34 delayed access exception */
+       __u32    :  7; /* 35-41 */
+       __u32 pr :  1; /* 42 tod programmable register validity */
+       __u32 fc :  1; /* 43 fp control register validity */
+       __u32 ap :  1; /* 44 ancillary report */
+       __u32    :  1; /* 45 */
+       __u32 ct :  1; /* 46 cpu timer validity */
+       __u32 cc :  1; /* 47 clock comparator validity */
+       __u32    : 16; /* 47-63 */
+};
+
+struct pt_regs;
+
+extern void s390_handle_mcck(void);
+extern void s390_do_machine_check(struct pt_regs *regs);
+
+#endif /* _ASM_S390_NMI_H */
index db4523fe38ac918d6ce29f1698f6f489ca6e5af2..61862b3ac7941132db66c23d04ca33122b33b7b6 100644 (file)
@@ -42,22 +42,8 @@ static inline void get_cpu_id(cpuid_t *ptr)
        asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
 }
 
-struct cpuinfo_S390
-{
-        cpuid_t  cpu_id;
-        __u16    cpu_addr;
-        __u16    cpu_nr;
-        unsigned long loops_per_jiffy;
-        unsigned long *pgd_quick;
-#ifdef __s390x__
-        unsigned long *pmd_quick;
-#endif /* __s390x__ */
-        unsigned long *pte_quick;
-        unsigned long pgtable_cache_sz;
-};
-
 extern void s390_adjust_jiffies(void);
-extern void print_cpu_info(struct cpuinfo_S390 *);
+extern void print_cpu_info(void);
 extern int get_cpu_capability(unsigned int *);
 
 /*
index 8920025c3c02ed3bb95919861bf4b16b823a731f..f1b051630c50c50fbf83ee82e42a16ecbae3a184 100644 (file)
 #define NUM_CRS                16
 #define NUM_ACRS       16
 
+#define NUM_CR_WORDS   3
+
 #define FPR_SIZE       8
 #define FPC_SIZE       4
 #define FPC_PAD_SIZE   4 /* gcc insists on aligning the fpregs */
@@ -334,7 +336,7 @@ struct pt_regs
  */
 typedef struct
 {
-       unsigned long cr[3];
+       unsigned long cr[NUM_CR_WORDS];
 } per_cr_words;
 
 #define PER_EM_MASK 0xE8000000UL
index 27fc1746de1578a7611f97ce92e252d2227ed3c4..402d6dcf0d26dbff39470e728432b4bbd0896911 100644 (file)
@@ -314,6 +314,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
                            int, int, unsigned long);
 
 /* qdio errors reported to the upper-layer program */
+#define QDIO_ERROR_SIGA_TARGET                 0x02
 #define QDIO_ERROR_SIGA_ACCESS_EXCEPTION       0x10
 #define QDIO_ERROR_SIGA_BUSY                   0x20
 #define QDIO_ERROR_ACTIVATE_CHECK_CONDITION    0x40
index 024b91e06239293b38be4f6598a81631eebd4702..2009158a4502cf859e242ab5068efd74eb75949f 100644 (file)
@@ -50,12 +50,7 @@ extern void machine_power_off_smp(void);
  
 #define PROC_CHANGE_PENALTY    20              /* Schedule penalty */
 
-#define raw_smp_processor_id() (S390_lowcore.cpu_data.cpu_nr)
-
-static inline __u16 hard_smp_processor_id(void)
-{
-       return stap();
-}
+#define raw_smp_processor_id() (S390_lowcore.cpu_nr)
 
 /*
  * returns 1 if cpu is in stopped/check stopped state or not operational
index d074673a6d9b500010e3c7f4ad25cfbaea5b2d68..cd0241db5a4688b754d6838497cfc06768b4025e 100644 (file)
@@ -100,6 +100,7 @@ static inline char *strcat(char *dst, const char *src)
 
 static inline char *strcpy(char *dst, const char *src)
 {
+#if __GNUC__ < 4
        register int r0 asm("0") = 0;
        char *ret = dst;
 
@@ -109,10 +110,14 @@ static inline char *strcpy(char *dst, const char *src)
                : "+&a" (dst), "+&a" (src) : "d" (r0)
                : "cc", "memory");
        return ret;
+#else
+       return __builtin_strcpy(dst, src);
+#endif
 }
 
 static inline size_t strlen(const char *s)
 {
+#if __GNUC__ < 4
        register unsigned long r0 asm("0") = 0;
        const char *tmp = s;
 
@@ -121,6 +126,9 @@ static inline size_t strlen(const char *s)
                "       jo      0b"
                : "+d" (r0), "+a" (tmp) :  : "cc");
        return r0 - (unsigned long) s;
+#else
+       return __builtin_strlen(s);
+#endif
 }
 
 static inline size_t strnlen(const char * s, size_t n)
@@ -135,7 +143,13 @@ static inline size_t strnlen(const char * s, size_t n)
                : "+a" (end), "+a" (tmp) : "d" (r0)  : "cc");
        return end - s;
 }
-
+#else /* IN_ARCH_STRING_C */
+void *memchr(const void * s, int c, size_t n);
+void *memscan(void *s, int c, size_t n);
+char *strcat(char *dst, const char *src);
+char *strcpy(char *dst, const char *src);
+size_t strlen(const char *s);
+size_t strnlen(const char * s, size_t n);
 #endif /* !IN_ARCH_STRING_C */
 
 #endif /* __KERNEL__ */
index ad93212d9e16a3099087f846edb942612de0694c..9d70057d828c604796082b21d61535eebcd19f87 100644 (file)
@@ -100,6 +100,7 @@ struct sysinfo_3_2_2 {
                char reserved_1[24];
 
        } vm[8];
+       char reserved_544[3552];
 };
 
 static inline int stsi(void *sysinfo, int fc, int sel1, int sel2)
index d60394b9745ef60387ad385013f18f23d622980c..304cffa623e158041e128c738999abbed1d3aa5b 100644 (file)
@@ -51,7 +51,7 @@ static inline void __tlb_flush_full(struct mm_struct *mm)
         * If the process only ran on the local cpu, do a local flush.
         */
        local_cpumask = cpumask_of_cpu(smp_processor_id());
-       if (cpus_equal(mm->cpu_vm_mask, local_cpumask))
+       if (cpumask_equal(mm_cpumask(mm), &local_cpumask))
                __tlb_flush_local();
        else
                __tlb_flush_global();
@@ -73,7 +73,7 @@ static inline void __tlb_flush_idte(unsigned long asce)
 
 static inline void __tlb_flush_mm(struct mm_struct * mm)
 {
-       if (unlikely(cpus_empty(mm->cpu_vm_mask)))
+       if (unlikely(cpumask_empty(mm_cpumask(mm))))
                return;
        /*
         * If the machine has IDTE we prefer to do a per mm flush
index c979c3b56ab062f1c4ddc7515b21ca464c38f40b..5e0ad618dc45d2b3ea111f8f494c95e6fa8b99e9 100644 (file)
@@ -5,7 +5,6 @@
 
 #define mc_capable()   (1)
 
-cpumask_t cpu_coregroup_map(unsigned int cpu);
 const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
 
 extern cpumask_t cpu_core_map[NR_CPUS];
index 3a5267d90d29921e9b3e6b60999ab928fa1c087a..8406a2b3157a2d98f16bc4485d83d452a58e9cc5 100644 (file)
@@ -39,7 +39,7 @@ struct vtoc_labeldate
        __u16 day;
 } __attribute__ ((packed));
 
-struct vtoc_volume_label
+struct vtoc_volume_label_cdl
 {
        char volkey[4];         /* volume key = volume label */
        char vollbl[4];         /* volume label */
@@ -56,6 +56,14 @@ struct vtoc_volume_label
        char res3[29];          /* reserved */
 } __attribute__ ((packed));
 
+struct vtoc_volume_label_ldl {
+       char vollbl[4];         /* volume label */
+       char volid[6];          /* volume identifier */
+       char res3[69];          /* reserved */
+       char ldl_version;       /* version number, valid for ldl format */
+       __u64 formatted_blocks; /* valid when ldl_version >= f2  */
+} __attribute__ ((packed));
+
 struct vtoc_extent
 {
        __u8 typeind;                   /* extent type indicator */
@@ -140,7 +148,11 @@ struct vtoc_format4_label
        char res2[10];          /* reserved */
        __u8 DS4EFLVL;          /* extended free-space management level */
        struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */
-       char res3[9];           /* reserved */
+       char res3;              /* reserved */
+       __u32 DS4DCYL;          /* number of logical cyls */
+       char res4[2];           /* reserved */
+       __u8 DS4DEVF2;          /* device flags */
+       char res5;              /* reserved */
 } __attribute__ ((packed));
 
 struct vtoc_ds5ext
index 3edc6c6f258b2a06b9f7bb09591964ebbce7ebd3..228e3105ded772da7d975faf6afaddb73a4e1e9e 100644 (file)
@@ -17,10 +17,12 @@ CFLAGS_smp.o        := -Wno-nonnull
 #
 CFLAGS_ptrace.o                += -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
+CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
+
 obj-y  :=  bitmap.o traps.o time.o process.o base.o early.o setup.o \
            processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
            s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
-           vdso.o vtime.o
+           vdso.o vtime.o sysinfo.o nmi.o
 
 obj-y  += $(if $(CONFIG_64BIT),entry64.o,entry.o)
 obj-y  += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff --git a/arch/s390/kernel/bitmap.S b/arch/s390/kernel/bitmap.S
deleted file mode 100644 (file)
index dfb41f9..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  arch/s390/kernel/bitmap.S
- *    Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
- *    See include/asm-s390/{bitops.h|posix_types.h} for details
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- */
-
-         .globl _oi_bitmap
-_oi_bitmap:
-         .byte  0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
-
-         .globl _ni_bitmap
-_ni_bitmap:
-         .byte  0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F
-
-         .globl _zb_findmap
-_zb_findmap:
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4 
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8
-
-         .globl _sb_findmap
-_sb_findmap:
-         .byte  8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-
diff --git a/arch/s390/kernel/bitmap.c b/arch/s390/kernel/bitmap.c
new file mode 100644 (file)
index 0000000..3ae4757
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *    Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
+ *    See include/asm/{bitops.h|posix_types.h} for details
+ *
+ *    Copyright IBM Corp. 1999,2009
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ */
+
+#include <linux/bitops.h>
+#include <linux/module.h>
+
+const char _oi_bitmap[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+EXPORT_SYMBOL(_oi_bitmap);
+
+const char _ni_bitmap[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
+EXPORT_SYMBOL(_ni_bitmap);
+
+const char _zb_findmap[] = {
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 };
+EXPORT_SYMBOL(_zb_findmap);
+
+const char _sb_findmap[] = {
+       8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 };
+EXPORT_SYMBOL(_sb_findmap);
index a2be3a978d5c43281e3cf3115e2dfb19d473307f..123dd660d7fbed3793ed34a6dee6add2bc25c05a 100644 (file)
@@ -1,10 +1,11 @@
 #ifndef _PTRACE32_H
 #define _PTRACE32_H
 
+#include <asm/ptrace.h>    /* needed for NUM_CR_WORDS */
 #include "compat_linux.h"  /* needed for psw_compat_t */
 
 typedef struct {
-       __u32 cr[3];
+       __u32 cr[NUM_CR_WORDS];
 } per_cr_words32;
 
 typedef struct {
index ba03fc0a3a569777fc3b1936cbe6f54d254d6e34..be8bceaf37d96660e9b5e3ecd56d689fd86bc3e6 100644 (file)
@@ -603,7 +603,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length,
 static int
 debug_open(struct inode *inode, struct file *file)
 {
-       int i = 0, rc = 0;
+       int i, rc = 0;
        file_private_info_t *p_info;
        debug_info_t *debug_info, *debug_info_snapshot;
 
@@ -642,8 +642,7 @@ found:
        p_info = kmalloc(sizeof(file_private_info_t),
                                                GFP_KERNEL);
        if(!p_info){
-               if(debug_info_snapshot)
-                       debug_info_free(debug_info_snapshot);
+               debug_info_free(debug_info_snapshot);
                rc = -ENOMEM;
                goto out;
        }
@@ -698,8 +697,7 @@ debug_info_t *debug_register_mode(const char *name, int pages_per_area,
        if ((uid != 0) || (gid != 0))
                pr_warning("Root becomes the owner of all s390dbf files "
                           "in sysfs\n");
-       if (!initialized)
-               BUG();
+       BUG_ON(!initialized);
        mutex_lock(&debug_mutex);
 
         /* create new debug_info */
@@ -1156,7 +1154,6 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view)
        else {
                debugfs_remove(id->debugfs_entries[i]);
                id->views[i] = NULL;
-               rc = 0;
        }
        spin_unlock_irqrestore(&id->lock, flags);
 out:
index 2a2ca268b1dd6e6bc38115496674ee965f8ef29a..4d221c81c84941a13f3350a4f539b231d05cc8d2 100644 (file)
@@ -6,6 +6,7 @@
  *              Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -20,6 +21,7 @@
 #include <asm/processor.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
+#include <asm/sysinfo.h>
 #include <asm/cpcmd.h>
 #include <asm/sclp.h>
 #include "entry.h"
@@ -173,19 +175,21 @@ static noinline __init void init_kernel_storage_key(void)
                page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
 }
 
+static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
+
 static noinline __init void detect_machine_type(void)
 {
-       struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
-
-       get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
-
-       /* Running under z/VM ? */
-       if (cpuinfo->cpu_id.version == 0xff)
-               machine_flags |= MACHINE_FLAG_VM;
+       /* No VM information? Looks like LPAR */
+       if (stsi(&vmms, 3, 2, 2) == -ENOSYS)
+               return;
+       if (!vmms.count)
+               return;
 
-       /* Running under KVM ? */
-       if (cpuinfo->cpu_id.version == 0xfe)
+       /* Running under KVM? If not we assume z/VM */
+       if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3))
                machine_flags |= MACHINE_FLAG_KVM;
+       else
+               machine_flags |= MACHINE_FLAG_VM;
 }
 
 static __init void early_pgm_check_handler(void)
@@ -348,7 +352,6 @@ static void __init setup_boot_command_line(void)
 
        /* copy arch command line */
        strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
-       boot_command_line[ARCH_COMMAND_LINE_SIZE - 1] = 0;
 
        /* append IPL PARM data to the boot command line */
        if (MACHINE_IS_VM) {
index ec7e35f6055b238dc3c18eaeff09054ec7ecfb3f..1046c2c9f8d139b723ce32fbeded0b71fc1f388b 100644 (file)
@@ -469,6 +469,8 @@ start:
        .org    0x10000
 startup:basr   %r13,0                  # get base
 .LPG0:
+       xc      0x200(256),0x200        # partially clear lowcore
+       xc      0x300(256),0x300
 
 #ifndef CONFIG_MARCH_G5
        # check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
index db476d114caabd5c79b016110f503d507de2f312..2ced846065b7a61e340fc88d9b390a4416ead542 100644 (file)
@@ -20,7 +20,6 @@ startup_continue:
        lctl    %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
        l       %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
                                        # move IPL device to lowcore
-       mvc     __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
 #
 # Setup stack
 #
index f9f70aa15244152423cd3ff0182224e6158197ab..65667b2e65cee6fdd3ed71f104ee326d4ec13d86 100644 (file)
@@ -86,7 +86,6 @@ startup_continue:
        lctlg   %c0,%c15,.Lctl-.LPG1(%r13)      # load control registers
        lg      %r12,.Lparmaddr-.LPG1(%r13)     # pointer to parameter area
                                        # move IPL device to lowcore
-       mvc     __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
        lghi    %r0,__LC_PASTE
        stg     %r0,__LC_VDSO_PER_CPU
 #
index 2dcf590faba69cca7b36f3d2731611c1ed4acc00..6f3711a0eaaa108bd2e9b1b1796096cedd906963 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/ebcdic.h>
 #include <asm/reset.h>
 #include <asm/sclp.h>
-#include <asm/setup.h>
+#include <asm/checksum.h>
 
 #define IPL_PARM_BLOCK_VERSION 0
 
@@ -56,13 +56,14 @@ struct shutdown_trigger {
 };
 
 /*
- * Five shutdown action types are supported:
+ * The following shutdown action types are supported:
  */
 #define SHUTDOWN_ACTION_IPL_STR                "ipl"
 #define SHUTDOWN_ACTION_REIPL_STR      "reipl"
 #define SHUTDOWN_ACTION_DUMP_STR       "dump"
 #define SHUTDOWN_ACTION_VMCMD_STR      "vmcmd"
 #define SHUTDOWN_ACTION_STOP_STR       "stop"
+#define SHUTDOWN_ACTION_DUMP_REIPL_STR "dump_reipl"
 
 struct shutdown_action {
        char *name;
@@ -146,6 +147,7 @@ static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
 static struct ipl_parameter_block *reipl_block_fcp;
 static struct ipl_parameter_block *reipl_block_ccw;
 static struct ipl_parameter_block *reipl_block_nss;
+static struct ipl_parameter_block *reipl_block_actual;
 
 static int dump_capabilities = DUMP_TYPE_NONE;
 static enum dump_type dump_type = DUMP_TYPE_NONE;
@@ -835,6 +837,7 @@ static int reipl_set_type(enum ipl_type type)
                        reipl_method = REIPL_METHOD_CCW_VM;
                else
                        reipl_method = REIPL_METHOD_CCW_CIO;
+               reipl_block_actual = reipl_block_ccw;
                break;
        case IPL_TYPE_FCP:
                if (diag308_set_works)
@@ -843,6 +846,7 @@ static int reipl_set_type(enum ipl_type type)
                        reipl_method = REIPL_METHOD_FCP_RO_VM;
                else
                        reipl_method = REIPL_METHOD_FCP_RO_DIAG;
+               reipl_block_actual = reipl_block_fcp;
                break;
        case IPL_TYPE_FCP_DUMP:
                reipl_method = REIPL_METHOD_FCP_DUMP;
@@ -852,6 +856,7 @@ static int reipl_set_type(enum ipl_type type)
                        reipl_method = REIPL_METHOD_NSS_DIAG;
                else
                        reipl_method = REIPL_METHOD_NSS;
+               reipl_block_actual = reipl_block_nss;
                break;
        case IPL_TYPE_UNKNOWN:
                reipl_method = REIPL_METHOD_DEFAULT;
@@ -960,7 +965,6 @@ static void reipl_run(struct shutdown_trigger *trigger)
                diag308(DIAG308_IPL, NULL);
                break;
        case REIPL_METHOD_FCP_DUMP:
-       default:
                break;
        }
        disabled_wait((unsigned long) __builtin_return_address(0));
@@ -1069,10 +1073,12 @@ static int __init reipl_fcp_init(void)
 {
        int rc;
 
-       if ((!diag308_set_works) && (ipl_info.type != IPL_TYPE_FCP))
-               return 0;
-       if ((!diag308_set_works) && (ipl_info.type == IPL_TYPE_FCP))
-               make_attrs_ro(reipl_fcp_attrs);
+       if (!diag308_set_works) {
+               if (ipl_info.type == IPL_TYPE_FCP)
+                       make_attrs_ro(reipl_fcp_attrs);
+               else
+                       return 0;
+       }
 
        reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
        if (!reipl_block_fcp)
@@ -1253,7 +1259,6 @@ static void dump_run(struct shutdown_trigger *trigger)
                diag308(DIAG308_DUMP, NULL);
                break;
        case DUMP_METHOD_NONE:
-       default:
                return;
        }
        printk(KERN_EMERG "Dump failed!\n");
@@ -1332,6 +1337,49 @@ static struct shutdown_action __refdata dump_action = {
        .init   = dump_init,
 };
 
+static void dump_reipl_run(struct shutdown_trigger *trigger)
+{
+       preempt_disable();
+       /*
+        * Bypass dynamic address translation (DAT) when storing IPL parameter
+        * information block address and checksum into the prefix area
+        * (corresponding to absolute addresses 0-8191).
+        * When enhanced DAT applies and the STE format control in one,
+        * the absolute address is formed without prefixing. In this case a
+        * normal store (stg/st) into the prefix area would no more match to
+        * absolute addresses 0-8191.
+        */
+#ifdef CONFIG_64BIT
+       asm volatile("sturg %0,%1"
+               :: "a" ((unsigned long) reipl_block_actual),
+               "a" (&lowcore_ptr[smp_processor_id()]->ipib));
+#else
+       asm volatile("stura %0,%1"
+               :: "a" ((unsigned long) reipl_block_actual),
+               "a" (&lowcore_ptr[smp_processor_id()]->ipib));
+#endif
+       asm volatile("stura %0,%1"
+               :: "a" (csum_partial(reipl_block_actual,
+                                    reipl_block_actual->hdr.len, 0)),
+               "a" (&lowcore_ptr[smp_processor_id()]->ipib_checksum));
+       preempt_enable();
+       dump_run(trigger);
+}
+
+static int __init dump_reipl_init(void)
+{
+       if (!diag308_set_works)
+               return -EOPNOTSUPP;
+       else
+               return 0;
+}
+
+static struct shutdown_action __refdata dump_reipl_action = {
+       .name   = SHUTDOWN_ACTION_DUMP_REIPL_STR,
+       .fn     = dump_reipl_run,
+       .init   = dump_reipl_init,
+};
+
 /*
  * vmcmd shutdown action: Trigger vm command on shutdown.
  */
@@ -1421,7 +1469,8 @@ static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
 /* action list */
 
 static struct shutdown_action *shutdown_actions_list[] = {
-       &ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action};
+       &ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
+       &vmcmd_action, &stop_action};
 #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
 
 /*
@@ -1434,11 +1483,11 @@ static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
                       size_t len)
 {
        int i;
+
        for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
                if (!shutdown_actions_list[i])
                        continue;
-               if (strncmp(buf, shutdown_actions_list[i]->name,
-                           strlen(shutdown_actions_list[i]->name)) == 0) {
+               if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
                        trigger->action = shutdown_actions_list[i];
                        return len;
                }
@@ -1672,7 +1721,7 @@ static int on_panic_notify(struct notifier_block *self,
 
 static struct notifier_block on_panic_nb = {
        .notifier_call = on_panic_notify,
-       .priority = 0,
+       .priority = INT_MIN,
 };
 
 void __init setup_ipl(void)
@@ -1696,7 +1745,6 @@ void __init setup_ipl(void)
                        sizeof(ipl_info.data.nss.name));
                break;
        case IPL_TYPE_UNKNOWN:
-       default:
                /* We have no info to copy */
                break;
        }
index 59b4e796680af3e3f376285b7fbaa5500092d602..eed4a00cb676238f7fdbc3b1ccc9dbde7ecb0b98 100644 (file)
@@ -310,15 +310,20 @@ apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
                        info->plt_initialized = 1;
                }
                if (r_type == R_390_PLTOFF16 ||
-                   r_type == R_390_PLTOFF32
-                   || r_type == R_390_PLTOFF64
-                       )
+                   r_type == R_390_PLTOFF32 ||
+                   r_type == R_390_PLTOFF64)
                        val = me->arch.plt_offset - me->arch.got_offset +
                                info->plt_offset + rela->r_addend;
-               else
-                       val =  (Elf_Addr) me->module_core +
-                               me->arch.plt_offset + info->plt_offset + 
-                               rela->r_addend - loc;
+               else {
+                       if (!((r_type == R_390_PLT16DBL &&
+                              val - loc + 0xffffUL < 0x1ffffeUL) ||
+                             (r_type == R_390_PLT32DBL &&
+                              val - loc + 0xffffffffULL < 0x1fffffffeULL)))
+                               val = (Elf_Addr) me->module_core +
+                                       me->arch.plt_offset +
+                                       info->plt_offset;
+                       val += rela->r_addend - loc;
+               }
                if (r_type == R_390_PLT16DBL)
                        *(unsigned short *) loc = val >> 1;
                else if (r_type == R_390_PLTOFF16)
similarity index 62%
rename from drivers/s390/s390mach.c
rename to arch/s390/kernel/nmi.c
index 92b0417f8e12069403f1d50bbfb5653913b5a8f9..4bfdc421d7e92c65868d4a4b7c9783175aed9920 100644 (file)
 /*
- *  drivers/s390/s390mach.c
- *   S/390 machine check handler
+ *   Machine check handler
  *
- *    Copyright IBM Corp. 2000,2008
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *              Martin Schwidefsky (schwidefsky@de.ibm.com)
- *              Cornelia Huck <cornelia.huck@de.ibm.com>
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ *              Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *              Cornelia Huck <cornelia.huck@de.ibm.com>,
+ *              Heiko Carstens <heiko.carstens@de.ibm.com>,
  */
 
 #include <linux/init.h>
-#include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/workqueue.h>
 #include <linux/time.h>
-#include <linux/device.h>
-#include <linux/kthread.h>
-#include <asm/etr.h>
+#include <linux/module.h>
 #include <asm/lowcore.h>
-#include <asm/cio.h>
+#include <asm/smp.h>
+#include <asm/etr.h>
 #include <asm/cpu.h>
-#include "s390mach.h"
-
-static struct semaphore m_sem;
-
-static NORET_TYPE void
-s390_handle_damage(char *msg)
-{
-#ifdef CONFIG_SMP
-       smp_send_stop();
-#endif
-       disabled_wait((unsigned long) __builtin_return_address(0));
-       for(;;);
-}
-
-static crw_handler_t crw_handlers[NR_RSCS];
-
-/**
- * s390_register_crw_handler() - register a channel report word handler
- * @rsc: reporting source code to handle
- * @handler: handler to be registered
- *
- * Returns %0 on success and a negative error value otherwise.
- */
-int s390_register_crw_handler(int rsc, crw_handler_t handler)
-{
-       if ((rsc < 0) || (rsc >= NR_RSCS))
-               return -EINVAL;
-       if (!cmpxchg(&crw_handlers[rsc], NULL, handler))
-               return 0;
-       return -EBUSY;
-}
-
-/**
- * s390_unregister_crw_handler() - unregister a channel report word handler
- * @rsc: reporting source code to handle
- */
-void s390_unregister_crw_handler(int rsc)
-{
-       if ((rsc < 0) || (rsc >= NR_RSCS))
-               return;
-       xchg(&crw_handlers[rsc], NULL);
-       synchronize_sched();
-}
-
-/*
- * Retrieve CRWs and call function to handle event.
- */
-static int s390_collect_crw_info(void *param)
-{
-       struct crw crw[2];
-       int ccode;
-       struct semaphore *sem;
-       unsigned int chain;
-       int ignore;
-
-       sem = (struct semaphore *)param;
-repeat:
-       ignore = down_interruptible(sem);
-       chain = 0;
-       while (1) {
-               if (unlikely(chain > 1)) {
-                       struct crw tmp_crw;
-
-                       printk(KERN_WARNING"%s: Code does not support more "
-                              "than two chained crws; please report to "
-                              "linux390@de.ibm.com!\n", __func__);
-                       ccode = stcrw(&tmp_crw);
-                       printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
-                              "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
-                              __func__, tmp_crw.slct, tmp_crw.oflw,
-                              tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
-                              tmp_crw.erc, tmp_crw.rsid);
-                       printk(KERN_WARNING"%s: This was crw number %x in the "
-                              "chain\n", __func__, chain);
-                       if (ccode != 0)
-                               break;
-                       chain = tmp_crw.chn ? chain + 1 : 0;
-                       continue;
-               }
-               ccode = stcrw(&crw[chain]);
-               if (ccode != 0)
-                       break;
-               printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
-                      "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
-                      crw[chain].slct, crw[chain].oflw, crw[chain].chn,
-                      crw[chain].rsc, crw[chain].anc, crw[chain].erc,
-                      crw[chain].rsid);
-               /* Check for overflows. */
-               if (crw[chain].oflw) {
-                       int i;
-
-                       pr_debug("%s: crw overflow detected!\n", __func__);
-                       for (i = 0; i < NR_RSCS; i++) {
-                               if (crw_handlers[i])
-                                       crw_handlers[i](NULL, NULL, 1);
-                       }
-                       chain = 0;
-                       continue;
-               }
-               if (crw[0].chn && !chain) {
-                       chain++;
-                       continue;
-               }
-               if (crw_handlers[crw[chain].rsc])
-                       crw_handlers[crw[chain].rsc](&crw[0],
-                                                    chain ? &crw[1] : NULL,
-                                                    0);
-               /* chain is always 0 or 1 here. */
-               chain = crw[chain].chn ? chain + 1 : 0;
-       }
-       goto repeat;
-       return 0;
-}
+#include <asm/nmi.h>
+#include <asm/crw.h>
 
 struct mcck_struct {
        int kill_task;
@@ -142,12 +28,18 @@ struct mcck_struct {
 
 static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
 
+static NORET_TYPE void s390_handle_damage(char *msg)
+{
+       smp_send_stop();
+       disabled_wait((unsigned long) __builtin_return_address(0));
+       while (1);
+}
+
 /*
  * Main machine check handler function. Will be called with interrupts enabled
  * or disabled and machine checks enabled or disabled.
  */
-void
-s390_handle_mcck(void)
+void s390_handle_mcck(void)
 {
        unsigned long flags;
        struct mcck_struct mcck;
@@ -166,29 +58,24 @@ s390_handle_mcck(void)
        local_irq_restore(flags);
 
        if (mcck.channel_report)
-               up(&m_sem);
-
-#ifdef CONFIG_MACHCHK_WARNING
-/*
- * The warning may remain for a prolonged period on the bare iron.
- * (actually till the machine is powered off, or until the problem is gone)
- * So we just stop listening for the WARNING MCH and prevent continuously
- * being interrupted.  One caveat is however, that we must do this per
- * processor and cannot use the smp version of ctl_clear_bit().
- * On VM we only get one interrupt per virtally presented machinecheck.
- * Though one suffices, we may get one interrupt per (virtual) processor.
- */
+               crw_handle_channel_report();
+       /*
+        * A warning may remain for a prolonged period on the bare iron.
+        * (actually until the machine is powered off, or the problem is gone)
+        * So we just stop listening for the WARNING MCH and avoid continuously
+        * being interrupted.  One caveat is however, that we must do this per
+        * processor and cannot use the smp version of ctl_clear_bit().
+        * On VM we only get one interrupt per virtally presented machinecheck.
+        * Though one suffices, we may get one interrupt per (virtual) cpu.
+        */
        if (mcck.warning) {     /* WARNING pending ? */
                static int mchchk_wng_posted = 0;
-               /*
-                * Use single machine clear, as we cannot handle smp right now
-                */
+
+               /* Use single cpu clear, as we cannot handle smp here. */
                __ctl_clear_bit(14, 24);        /* Disable WARNING MCH */
                if (xchg(&mchchk_wng_posted, 1) == 0)
                        kill_cad_pid(SIGPWR, 1);
        }
-#endif
-
        if (mcck.kill_task) {
                local_irq_enable();
                printk(KERN_EMERG "mcck: Terminating task because of machine "
@@ -204,8 +91,7 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
  * returns 0 if all registers could be validated
  * returns 1 otherwise
  */
-static int
-s390_revalidate_registers(struct mci *mci)
+static int notrace s390_revalidate_registers(struct mci *mci)
 {
        int kill_task;
        u64 tmpclock;
@@ -214,22 +100,21 @@ s390_revalidate_registers(struct mci *mci)
 
        kill_task = 0;
        zero = 0;
-       /* General purpose registers */
-       if (!mci->gr)
+
+       if (!mci->gr) {
                /*
                 * General purpose registers couldn't be restored and have
                 * unknown contents. Process needs to be terminated.
                 */
                kill_task = 1;
-
-       /* Revalidate floating point registers */
-       if (!mci->fp)
+       }
+       if (!mci->fp) {
                /*
                 * Floating point registers can't be restored and
                 * therefore the process needs to be terminated.
                 */
                kill_task = 1;
-
+       }
 #ifndef CONFIG_64BIT
        asm volatile(
                "       ld      0,0(%0)\n"
@@ -245,9 +130,8 @@ s390_revalidate_registers(struct mci *mci)
                fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
 #else
                fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
-               fpt_creg_save_area = fpt_save_area+128;
+               fpt_creg_save_area = fpt_save_area + 128;
 #endif
-               /* Floating point control register */
                if (!mci->fc) {
                        /*
                         * Floating point control register can't be restored.
@@ -278,26 +162,25 @@ s390_revalidate_registers(struct mci *mci)
                        "       ld      15,120(%0)\n"
                        : : "a" (fpt_save_area));
        }
-
        /* Revalidate access registers */
        asm volatile(
                "       lam     0,15,0(%0)"
                : : "a" (&S390_lowcore.access_regs_save_area));
-       if (!mci->ar)
+       if (!mci->ar) {
                /*
                 * Access registers have unknown contents.
                 * Terminating task.
                 */
                kill_task = 1;
-
+       }
        /* Revalidate control registers */
-       if (!mci->cr)
+       if (!mci->cr) {
                /*
                 * Control registers have unknown contents.
                 * Can't recover and therefore stopping machine.
                 */
                s390_handle_damage("invalid control registers.");
-       else
+       } else {
 #ifdef CONFIG_64BIT
                asm volatile(
                        "       lctlg   0,15,0(%0)"
@@ -307,12 +190,11 @@ s390_revalidate_registers(struct mci *mci)
                        "       lctl    0,15,0(%0)"
                        : : "a" (&S390_lowcore.cregs_save_area));
 #endif
-
+       }
        /*
         * We don't even try to revalidate the TOD register, since we simply
         * can't write something sensible into that register.
         */
-
 #ifdef CONFIG_64BIT
        /*
         * See if we can revalidate the TOD programmable register with its
@@ -330,7 +212,6 @@ s390_revalidate_registers(struct mci *mci)
                        : : "a" (&S390_lowcore.tod_progreg_save_area)
                        : "0", "cc");
 #endif
-
        /* Revalidate clock comparator register */
        asm volatile(
                "       stck    0(%1)\n"
@@ -354,32 +235,35 @@ s390_revalidate_registers(struct mci *mci)
 #define MAX_IPD_COUNT  29
 #define MAX_IPD_TIME   (5 * 60 * USEC_PER_SEC) /* 5 minutes */
 
+#define ED_STP_ISLAND  6       /* External damage STP island check */
+#define ED_STP_SYNC    7       /* External damage STP sync check */
+#define ED_ETR_SYNC    12      /* External damage ETR sync check */
+#define ED_ETR_SWITCH  13      /* External damage ETR switch to local */
+
 /*
  * machine check handler.
  */
-void
-s390_do_machine_check(struct pt_regs *regs)
+void notrace s390_do_machine_check(struct pt_regs *regs)
 {
+       static int ipd_count;
        static DEFINE_SPINLOCK(ipd_lock);
        static unsigned long long last_ipd;
-       static int ipd_count;
+       struct mcck_struct *mcck;
        unsigned long long tmp;
        struct mci *mci;
-       struct mcck_struct *mcck;
        int umode;
 
        lockdep_off();
-
        s390_idle_check();
 
        mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
        mcck = &__get_cpu_var(cpu_mcck);
        umode = user_mode(regs);
 
-       if (mci->sd)
+       if (mci->sd) {
                /* System damage -> stopping machine */
                s390_handle_damage("received system damage machine check.");
-
+       }
        if (mci->pd) {
                if (mci->b) {
                        /* Processing backup -> verify if we can survive this */
@@ -409,24 +293,17 @@ s390_do_machine_check(struct pt_regs *regs)
                         * Nullifying exigent condition, therefore we might
                         * retry this instruction.
                         */
-
                        spin_lock(&ipd_lock);
-
                        tmp = get_clock();
-
                        if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
                                ipd_count++;
                        else
                                ipd_count = 1;
-
                        last_ipd = tmp;
-
                        if (ipd_count == MAX_IPD_COUNT)
                                s390_handle_damage("too many ipd retries.");
-
                        spin_unlock(&ipd_lock);
-               }
-               else {
+               } else {
                        /* Processing damage -> stopping machine */
                        s390_handle_damage("received instruction processing "
                                           "damage machine check.");
@@ -441,20 +318,18 @@ s390_do_machine_check(struct pt_regs *regs)
                        mcck->kill_task = 1;
                        mcck->mcck_code = *(unsigned long long *) mci;
                        set_thread_flag(TIF_MCCK_PENDING);
-               }
-               else
+               } else {
                        /*
                         * Couldn't restore all register contents while in
                         * kernel mode -> stopping machine.
                         */
                        s390_handle_damage("unable to revalidate registers.");
+               }
        }
-
        if (mci->cd) {
                /* Timing facility damage */
                s390_handle_damage("TOD clock damaged");
        }
-
        if (mci->ed && mci->ec) {
                /* External damage */
                if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
@@ -466,28 +341,23 @@ s390_do_machine_check(struct pt_regs *regs)
                if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))
                        stp_island_check();
        }
-
        if (mci->se)
                /* Storage error uncorrected */
                s390_handle_damage("received storage error uncorrected "
                                   "machine check.");
-
        if (mci->ke)
                /* Storage key-error uncorrected */
                s390_handle_damage("received storage key-error uncorrected "
                                   "machine check.");
-
        if (mci->ds && mci->fa)
                /* Storage degradation */
                s390_handle_damage("received storage degradation machine "
                                   "check.");
-
        if (mci->cp) {
                /* Channel report word pending */
                mcck->channel_report = 1;
                set_thread_flag(TIF_MCCK_PENDING);
        }
-
        if (mci->w) {
                /* Warning pending */
                mcck->warning = 1;
@@ -496,43 +366,11 @@ s390_do_machine_check(struct pt_regs *regs)
        lockdep_on();
 }
 
-/*
- * s390_init_machine_check
- *
- * initialize machine check handling
- */
-static int
-machine_check_init(void)
+static int __init machine_check_init(void)
 {
-       init_MUTEX_LOCKED(&m_sem);
        ctl_set_bit(14, 25);    /* enable external damage MCH */
-       ctl_set_bit(14, 27);    /* enable system recovery MCH */
-#ifdef CONFIG_MACHCHK_WARNING
+       ctl_set_bit(14, 27);    /* enable system recovery MCH */
        ctl_set_bit(14, 24);    /* enable warning MCH */
-#endif
        return 0;
 }
-
-/*
- * Initialize the machine check handler really early to be able to
- * catch all machine checks that happen during boot
- */
 arch_initcall(machine_check_init);
-
-/*
- * Machine checks for the channel subsystem must be enabled
- * after the channel subsystem is initialized
- */
-static int __init
-machine_check_crw_init (void)
-{
-       struct task_struct *task;
-
-       task = kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
-       if (IS_ERR(task))
-               return PTR_ERR(task);
-       ctl_set_bit(14, 28);    /* enable channel report MCH */
-       return 0;
-}
-
-device_initcall (machine_check_crw_init);
index 5cd38a90e64d743443baa2bc1cb95e26070d0d9e..b48e961a38f6ee08f0a12b5e7ffc1348fd7c4dcb 100644 (file)
@@ -1,18 +1,10 @@
 /*
- *  arch/s390/kernel/process.c
+ * This file handles the architecture dependent parts of process handling.
  *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Hartmut Penner (hp@de.ibm.com),
- *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
- *
- *  Derived from "arch/i386/kernel/process.c"
- *    Copyright (C) 1995, Linus Torvalds
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
+ *    Copyright IBM Corp. 1999,2009
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *              Hartmut Penner <hp@de.ibm.com>,
+ *              Denis Joseph Barrow,
  */
 
 #include <linux/compiler.h>
@@ -47,6 +39,7 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/timer.h>
+#include <asm/nmi.h>
 #include "entry.h"
 
 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -76,7 +69,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
        return sf->gprs[8];
 }
 
-extern void s390_handle_mcck(void);
 /*
  * The idle loop on a S390...
  */
@@ -149,6 +141,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
        return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
                       0, &regs, 0, NULL, NULL);
 }
+EXPORT_SYMBOL(kernel_thread);
 
 /*
  * Free current thread data structures etc..
@@ -168,34 +161,35 @@ void release_thread(struct task_struct *dead_task)
 }
 
 int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
-       unsigned long unused,
-        struct task_struct * p, struct pt_regs * regs)
+               unsigned long unused,
+               struct task_struct *p, struct pt_regs *regs)
 {
-        struct fake_frame
-          {
-           struct stack_frame sf;
-            struct pt_regs childregs;
-          } *frame;
-
-        frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
-        p->thread.ksp = (unsigned long) frame;
+       struct thread_info *ti;
+       struct fake_frame
+       {
+               struct stack_frame sf;
+               struct pt_regs childregs;
+       } *frame;
+
+       frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
+       p->thread.ksp = (unsigned long) frame;
        /* Store access registers to kernel stack of new process. */
-        frame->childregs = *regs;
+       frame->childregs = *regs;
        frame->childregs.gprs[2] = 0;   /* child returns 0 on fork. */
-        frame->childregs.gprs[15] = new_stackp;
-        frame->sf.back_chain = 0;
+       frame->childregs.gprs[15] = new_stackp;
+       frame->sf.back_chain = 0;
 
-        /* new return point is ret_from_fork */
-        frame->sf.gprs[8] = (unsigned long) ret_from_fork;
+       /* new return point is ret_from_fork */
+       frame->sf.gprs[8] = (unsigned long) ret_from_fork;
 
-        /* fake return stack for resume(), don't go back to schedule */
-        frame->sf.gprs[9] = (unsigned long) frame;
+       /* fake return stack for resume(), don't go back to schedule */
+       frame->sf.gprs[9] = (unsigned long) frame;
 
        /* Save access registers to new thread structure. */
        save_access_regs(&p->thread.acrs[0]);
 
 #ifndef CONFIG_64BIT
-        /*
+       /*
         * save fprs to current->thread.fp_regs to merge them with
         * the emulated registers and then copy the result to the child.
         */
@@ -220,10 +214,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
 #endif /* CONFIG_64BIT */
        /* start new process with ar4 pointing to the correct address space */
        p->thread.mm_segment = get_fs();
-        /* Don't copy debug registers */
-        memset(&p->thread.per_info,0,sizeof(p->thread.per_info));
-
-        return 0;
+       /* Don't copy debug registers */
+       memset(&p->thread.per_info, 0, sizeof(p->thread.per_info));
+       /* Initialize per thread user and system timer values */
+       ti = task_thread_info(p);
+       ti->user_timer = 0;
+       ti->system_timer = 0;
+       return 0;
 }
 
 SYSCALL_DEFINE0(fork)
@@ -311,7 +308,7 @@ out:
 int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
 {
 #ifndef CONFIG_64BIT
-        /*
+       /*
         * save fprs to current->thread.fp_regs to merge them with
         * the emulated registers and then copy the result to the dump.
         */
@@ -322,6 +319,7 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
 #endif /* CONFIG_64BIT */
        return 1;
 }
+EXPORT_SYMBOL(dump_fpu);
 
 unsigned long get_wchan(struct task_struct *p)
 {
@@ -346,4 +344,3 @@ unsigned long get_wchan(struct task_struct *p)
        }
        return 0;
 }
-
index 82c1872cfe804c03d838b5625c54add169b7cce9..802c8ab247f30cc25bda2e67569991a2919f0ad1 100644 (file)
 #include <asm/lowcore.h>
 #include <asm/param.h>
 
-void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
+void __cpuinit print_cpu_info(void)
 {
        pr_info("Processor %d started, address %d, identification %06X\n",
-               cpuinfo->cpu_nr, cpuinfo->cpu_addr, cpuinfo->cpu_id.ident);
+               S390_lowcore.cpu_nr, S390_lowcore.cpu_addr,
+               S390_lowcore.cpu_id.ident);
 }
 
 /*
@@ -30,48 +31,46 @@ void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
 
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
-       static const char *hwcap_str[8] = {
+       static const char *hwcap_str[9] = {
                "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
-               "edat"
+               "edat", "etf3eh"
        };
-       struct cpuinfo_S390 *cpuinfo;
-       unsigned long n = (unsigned long) v - 1;
-       int i;
+       struct _lowcore *lc;
+       unsigned long n = (unsigned long) v - 1;
+       int i;
 
-       s390_adjust_jiffies();
-       preempt_disable();
-       if (!n) {
-              seq_printf(m, "vendor_id       : IBM/S390\n"
-                         "# processors    : %i\n"
-                         "bogomips per cpu: %lu.%02lu\n",
-                         num_online_cpus(), loops_per_jiffy/(500000/HZ),
-                         (loops_per_jiffy/(5000/HZ))%100);
-              seq_puts(m, "features\t: ");
-              for (i = 0; i < 8; i++)
-                      if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
-                              seq_printf(m, "%s ", hwcap_str[i]);
-              seq_puts(m, "\n");
-       }
+       s390_adjust_jiffies();
+       preempt_disable();
+       if (!n) {
+               seq_printf(m, "vendor_id       : IBM/S390\n"
+                          "# processors    : %i\n"
+                          "bogomips per cpu: %lu.%02lu\n",
+                          num_online_cpus(), loops_per_jiffy/(500000/HZ),
+                          (loops_per_jiffy/(5000/HZ))%100);
+               seq_puts(m, "features\t: ");
+               for (i = 0; i < 9; i++)
+                       if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
+                               seq_printf(m, "%s ", hwcap_str[i]);
+               seq_puts(m, "\n");
+       }
 
-       if (cpu_online(n)) {
+       if (cpu_online(n)) {
 #ifdef CONFIG_SMP
-              if (smp_processor_id() == n)
-                      cpuinfo = &S390_lowcore.cpu_data;
-              else
-                      cpuinfo = &lowcore_ptr[n]->cpu_data;
+               lc = (smp_processor_id() == n) ?
+                       &S390_lowcore : lowcore_ptr[n];
 #else
-              cpuinfo = &S390_lowcore.cpu_data;
+               lc = &S390_lowcore;
 #endif
-              seq_printf(m, "processor %li: "
-                         "version = %02X,  "
-                         "identification = %06X,  "
-                         "machine = %04X\n",
-                         n, cpuinfo->cpu_id.version,
-                         cpuinfo->cpu_id.ident,
-                         cpuinfo->cpu_id.machine);
-       }
-       preempt_enable();
-       return 0;
+               seq_printf(m, "processor %li: "
+                          "version = %02X,  "
+                          "identification = %06X,  "
+                          "machine = %04X\n",
+                          n, lc->cpu_id.version,
+                          lc->cpu_id.ident,
+                          lc->cpu_id.machine);
+       }
+       preempt_enable();
+       return 0;
 }
 
 static void *c_start(struct seq_file *m, loff_t *pos)
index c41930499a5f1d0ca921e69e820c3810dcf4a216..774147824c3dc8a6643ad3d786a8e2207f7ca478 100644 (file)
@@ -1,10 +1,7 @@
 /*
- *  arch/s390/kernel/reipl.S
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com)
-                Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ *    Copyright IBM Corp 2000,2009
+ *    Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
+ *              Denis Joseph Barrow,
  */
 
 #include <asm/lowcore.h>
@@ -30,7 +27,7 @@ do_reipl_asm: basr    %r13,0
                mvc     __LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10)
                stfpc   __LC_FP_CREG_SAVE_AREA-0x1000(%r1)
                stckc   .Lclkcmp-.Lpg0(%r13)
-               mvc     __LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13)
+               mvc     __LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13)
                stpt    __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
                stg     %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
 
index 46b90cb03707305bdc4713653479a2f8376d0b3f..656fcbb9bd83267c3c6a8a509997d8839462914e 100644 (file)
@@ -1,49 +1,5 @@
-/*
- *  arch/s390/kernel/s390_ksyms.c
- *
- *  S390 version
- */
-#include <linux/highuid.h>
 #include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/syscalls.h>
-#include <linux/interrupt.h>
-#include <asm/checksum.h>
-#include <asm/cpcmd.h>
-#include <asm/delay.h>
-#include <asm/pgalloc.h>
-#include <asm/setup.h>
 #include <asm/ftrace.h>
-#ifdef CONFIG_IP_MULTICAST
-#include <net/arp.h>
-#endif
-
-/*
- * memory management
- */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(_sb_findmap);
-
-/*
- * binfmt_elf loader 
- */
-extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs);
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(empty_zero_page);
-
-/*
- * misc.
- */
-EXPORT_SYMBOL(machine_flags);
-EXPORT_SYMBOL(__udelay);
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(csum_fold);
-EXPORT_SYMBOL(console_mode);
-EXPORT_SYMBOL(console_devno);
-EXPORT_SYMBOL(console_irq);
 
 #ifdef CONFIG_FUNCTION_TRACER
 EXPORT_SYMBOL(_mcount);
index c5cfb6185eaca51eb5e9ee3667d1c4d06ee22a52..06201b93cbbf5623fa6247b25ee39edaab3f0da1 100644 (file)
@@ -74,9 +74,17 @@ EXPORT_SYMBOL(uaccess);
  * Machine setup..
  */
 unsigned int console_mode = 0;
+EXPORT_SYMBOL(console_mode);
+
 unsigned int console_devno = -1;
+EXPORT_SYMBOL(console_devno);
+
 unsigned int console_irq = -1;
+EXPORT_SYMBOL(console_irq);
+
 unsigned long machine_flags;
+EXPORT_SYMBOL(machine_flags);
+
 unsigned long elf_hwcap = 0;
 char elf_platform[ELF_PLATFORM_SIZE];
 
@@ -86,6 +94,10 @@ volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 int __initdata memory_end_set;
 unsigned long __initdata memory_end;
 
+/* An array with a pointer to the lowcore of every CPU. */
+struct _lowcore *lowcore_ptr[NR_CPUS];
+EXPORT_SYMBOL(lowcore_ptr);
+
 /*
  * This is set up by the setup-routine at boot-time
  * for S390 need to find out, what we have to setup
@@ -109,13 +121,10 @@ static struct resource data_resource = {
  */
 void __cpuinit cpu_init(void)
 {
-        int addr = hard_smp_processor_id();
-
         /*
          * Store processor id in lowcore (used e.g. in timer_interrupt)
          */
-       get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
-        S390_lowcore.cpu_data.cpu_addr = addr;
+       get_cpu_id(&S390_lowcore.cpu_id);
 
         /*
          * Force FPU initialization:
@@ -125,8 +134,7 @@ void __cpuinit cpu_init(void)
 
        atomic_inc(&init_mm.mm_count);
        current->active_mm = &init_mm;
-        if (current->mm)
-                BUG();
+       BUG_ON(current->mm);
         enter_lazy_tlb(&init_mm, current);
 }
 
@@ -217,7 +225,7 @@ static void __init conmode_default(void)
        }
 }
 
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
 static void __init setup_zfcpdump(unsigned int console_devno)
 {
        static char str[41];
@@ -289,11 +297,7 @@ static int __init early_parse_mem(char *p)
 early_param("mem", early_parse_mem);
 
 #ifdef CONFIG_S390_SWITCH_AMODE
-#ifdef CONFIG_PGSTE
-unsigned int switch_amode = 1;
-#else
 unsigned int switch_amode = 0;
-#endif
 EXPORT_SYMBOL_GPL(switch_amode);
 
 static int set_amode_and_uaccess(unsigned long user_amode,
@@ -414,7 +418,6 @@ setup_lowcore(void)
                PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
        lc->io_new_psw.mask = psw_kernel_bits;
        lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
-       lc->ipl_device = S390_lowcore.ipl_device;
        lc->clock_comparator = -1ULL;
        lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
        lc->async_stack = (unsigned long)
@@ -434,6 +437,7 @@ setup_lowcore(void)
        lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
 #endif
        set_prefix((u32)(unsigned long) lc);
+       lowcore_ptr[0] = lc;
 }
 
 static void __init
@@ -510,7 +514,7 @@ static void __init setup_memory_end(void)
        unsigned long max_mem;
        int i;
 
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
        if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
                memory_end = ZFCPDUMP_HSA_SIZE;
                memory_end_set = 1;
@@ -677,7 +681,6 @@ setup_memory(void)
 static void __init setup_hwcaps(void)
 {
        static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };
-       struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
        unsigned long long facility_list_extended;
        unsigned int facility_list;
        int i;
@@ -693,15 +696,22 @@ static void __init setup_hwcaps(void)
         *   Bit 17: the message-security assist is installed
         *   Bit 19: the long-displacement facility is installed
         *   Bit 21: the extended-immediate facility is installed
+        *   Bit 22: extended-translation facility 3 is installed
+        *   Bit 30: extended-translation facility 3 enhancement facility
         * These get translated to:
         *   HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1,
         *   HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3,
-        *   HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5.
+        *   HWCAP_S390_LDISP bit 4, HWCAP_S390_EIMM bit 5 and
+        *   HWCAP_S390_ETF3EH bit 8 (22 && 30).
         */
        for (i = 0; i < 6; i++)
                if (facility_list & (1UL << (31 - stfl_bits[i])))
                        elf_hwcap |= 1UL << i;
 
+       if ((facility_list & (1UL << (31 - 22)))
+           && (facility_list & (1UL << (31 - 30))))
+               elf_hwcap |= 1UL << 8;
+
        /*
         * Check for additional facilities with store-facility-list-extended.
         * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0
@@ -710,20 +720,22 @@ static void __init setup_hwcaps(void)
         * How many facility words are stored depends on the number of
         * doublewords passed to the instruction. The additional facilites
         * are:
-        *   Bit 43: decimal floating point facility is installed
+        *   Bit 42: decimal floating point facility is installed
+        *   Bit 44: perform floating point operation facility is installed
         * translated to:
-        *   HWCAP_S390_DFP bit 6.
+        *   HWCAP_S390_DFP bit 6 (42 && 44).
         */
        if ((elf_hwcap & (1UL << 2)) &&
            __stfle(&facility_list_extended, 1) > 0) {
-               if (facility_list_extended & (1ULL << (64 - 43)))
+               if ((facility_list_extended & (1ULL << (63 - 42)))
+                   && (facility_list_extended & (1ULL << (63 - 44))))
                        elf_hwcap |= 1UL << 6;
        }
 
        if (MACHINE_HAS_HPAGE)
                elf_hwcap |= 1UL << 7;
 
-       switch (cpuinfo->cpu_id.machine) {
+       switch (S390_lowcore.cpu_id.machine) {
        case 0x9672:
 #if !defined(CONFIG_64BIT)
        default:        /* Use "g5" as default for 31 bit kernels. */
@@ -816,7 +828,7 @@ setup_arch(char **cmdline_p)
        setup_lowcore();
 
         cpu_init();
-        __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
+       __cpu_logical_map[0] = stap();
        s390_init_cpu_topology();
 
        /*
index 2d337cbb9329c33e07f9dfccb2f51daa94269e30..006ed5016eb416d8dab512bd2a7e2625e0d498ed 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/cache.h>
 #include <linux/interrupt.h>
+#include <linux/irqflags.h>
 #include <linux/cpu.h>
 #include <linux/timex.h>
 #include <linux/bootmem.h>
 #include <asm/vdso.h>
 #include "entry.h"
 
-/*
- * An array with a pointer the lowcore of every CPU.
- */
-struct _lowcore *lowcore_ptr[NR_CPUS];
-EXPORT_SYMBOL(lowcore_ptr);
-
 static struct task_struct *current_set[NR_CPUS];
 
 static u8 smp_cpu_type;
@@ -81,9 +76,7 @@ void smp_send_stop(void)
 
        /* Disable all interrupts/machine checks */
        __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-
-       /* write magic number to zero page (absolute 0) */
-       lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
+       trace_hardirqs_off();
 
        /* stop all processors */
        for_each_online_cpu(cpu) {
@@ -233,7 +226,7 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
  */
 #define CPU_INIT_NO    1
 
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
 
 /*
  * zfcpdump_prefix_array holds prefix registers for the following scenario:
@@ -274,7 +267,7 @@ EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
 
 static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
 
-#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
+#endif /* CONFIG_ZFCPDUMP */
 
 static int cpu_stopped(int cpu)
 {
@@ -304,8 +297,8 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
 {
        int cpu_id, logical_cpu;
 
-       logical_cpu = first_cpu(avail);
-       if (logical_cpu == NR_CPUS)
+       logical_cpu = cpumask_first(&avail);
+       if (logical_cpu >= nr_cpu_ids)
                return 0;
        for (cpu_id = 0; cpu_id <= 65535; cpu_id++) {
                if (cpu_known(cpu_id))
@@ -316,8 +309,8 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
                        continue;
                cpu_set(logical_cpu, cpu_present_map);
                smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-               logical_cpu = next_cpu(logical_cpu, avail);
-               if (logical_cpu == NR_CPUS)
+               logical_cpu = cpumask_next(logical_cpu, &avail);
+               if (logical_cpu >= nr_cpu_ids)
                        break;
        }
        return 0;
@@ -329,8 +322,8 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
        int cpu_id, logical_cpu, cpu;
        int rc;
 
-       logical_cpu = first_cpu(avail);
-       if (logical_cpu == NR_CPUS)
+       logical_cpu = cpumask_first(&avail);
+       if (logical_cpu >= nr_cpu_ids)
                return 0;
        info = kmalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
@@ -351,8 +344,8 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
                        smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
                else
                        smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-               logical_cpu = next_cpu(logical_cpu, avail);
-               if (logical_cpu == NR_CPUS)
+               logical_cpu = cpumask_next(logical_cpu, &avail);
+               if (logical_cpu >= nr_cpu_ids)
                        break;
        }
 out:
@@ -379,7 +372,7 @@ static void __init smp_detect_cpus(void)
 
        c_cpus = 1;
        s_cpus = 0;
-       boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+       boot_cpu_addr = __cpu_logical_map[0];
        info = kmalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
                panic("smp_detect_cpus failed to allocate memory\n");
@@ -453,7 +446,7 @@ int __cpuinit start_secondary(void *cpuvoid)
        /* Switch on interrupts */
        local_irq_enable();
        /* Print info about this processor */
-       print_cpu_info(&S390_lowcore.cpu_data);
+       print_cpu_info();
        /* cpu_idle will call schedule for us */
        cpu_idle();
        return 0;
@@ -515,7 +508,6 @@ out:
        return -ENOMEM;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 static void smp_free_lowcore(int cpu)
 {
        struct _lowcore *lowcore;
@@ -534,7 +526,6 @@ static void smp_free_lowcore(int cpu)
        free_pages((unsigned long) lowcore, lc_order);
        lowcore_ptr[cpu] = NULL;
 }
-#endif /* CONFIG_HOTPLUG_CPU */
 
 /* Upping and downing of CPUs */
 int __cpuinit __cpu_up(unsigned int cpu)
@@ -543,16 +534,23 @@ int __cpuinit __cpu_up(unsigned int cpu)
        struct _lowcore *cpu_lowcore;
        struct stack_frame *sf;
        sigp_ccode ccode;
+       u32 lowcore;
 
        if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
                return -EIO;
        if (smp_alloc_lowcore(cpu))
                return -ENOMEM;
-
-       ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]),
-                                  cpu, sigp_set_prefix);
-       if (ccode)
-               return -EIO;
+       do {
+               ccode = signal_processor(cpu, sigp_initial_cpu_reset);
+               if (ccode == sigp_busy)
+                       udelay(10);
+               if (ccode == sigp_not_operational)
+                       goto err_out;
+       } while (ccode == sigp_busy);
+
+       lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
+       while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
+               udelay(10);
 
        idle = current_set[cpu];
        cpu_lowcore = lowcore_ptr[cpu];
@@ -571,9 +569,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
                : : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
        cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
        cpu_lowcore->current_task = (unsigned long) idle;
-       cpu_lowcore->cpu_data.cpu_nr = cpu;
+       cpu_lowcore->cpu_nr = cpu;
        cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
-       cpu_lowcore->ipl_device = S390_lowcore.ipl_device;
        eieio();
 
        while (signal_processor(cpu, sigp_restart) == sigp_busy)
@@ -582,6 +579,10 @@ int __cpuinit __cpu_up(unsigned int cpu)
        while (!cpu_online(cpu))
                cpu_relax();
        return 0;
+
+err_out:
+       smp_free_lowcore(cpu);
+       return -EIO;
 }
 
 static int __init setup_possible_cpus(char *s)
@@ -589,9 +590,8 @@ static int __init setup_possible_cpus(char *s)
        int pcpus, cpu;
 
        pcpus = simple_strtoul(s, NULL, 0);
-       cpu_possible_map = cpumask_of_cpu(0);
-       for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++)
-               cpu_set(cpu, cpu_possible_map);
+       for (cpu = 0; cpu < pcpus && cpu < nr_cpu_ids; cpu++)
+               set_cpu_possible(cpu, true);
        return 0;
 }
 early_param("possible_cpus", setup_possible_cpus);
@@ -663,7 +663,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        /* request the 0x1201 emergency signal external interrupt */
        if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
                panic("Couldn't request external interrupt 0x1201");
-       print_cpu_info(&S390_lowcore.cpu_data);
+       print_cpu_info();
 
        /* Reallocate current lowcore, but keep its contents. */
        lc_order = sizeof(long) == 8 ? 1 : 0;
similarity index 88%
rename from drivers/s390/sysinfo.c
rename to arch/s390/kernel/sysinfo.c
index 0eea90781385784ae4ab838dce905dcaf4942a89..b5e75e1061c82d35b40b63594f1889ce07d0453b 100644 (file)
@@ -1,9 +1,7 @@
 /*
- *  drivers/s390/sysinfo.c
- *
- *  Copyright IBM Corp. 2001, 2008
- *  Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com)
- *            Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *  Copyright IBM Corp. 2001, 2009
+ *  Author(s): Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
+ *            Martin Schwidefsky <schwidefsky@de.ibm.com>,
  */
 
 #include <linux/kernel.h>
@@ -24,7 +22,7 @@
 
 static inline int stsi_0(void)
 {
-       int rc = stsi (NULL, 0, 0, 0);
+       int rc = stsi(NULL, 0, 0, 0);
        return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
 }
 
@@ -78,23 +76,6 @@ static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
        return len;
 }
 
-#if 0 /* Currently unused */
-static int stsi_1_2_1(struct sysinfo_1_2_1 *info, char *page, int len)
-{
-       if (stsi(info, 1, 2, 1) == -ENOSYS)
-               return len;
-
-       len += sprintf(page + len, "\n");
-       EBCASC(info->sequence, sizeof(info->sequence));
-       EBCASC(info->plant, sizeof(info->plant));
-       len += sprintf(page + len, "Sequence Code of CPU: %-16.16s\n",
-                      info->sequence);
-       len += sprintf(page + len, "Plant of CPU:         %-16.16s\n",
-                      info->plant);
-       return len;
-}
-#endif
-
 static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
 {
        struct sysinfo_1_2_2_extension *ext;
@@ -145,33 +126,15 @@ static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
        if (info->secondary_capability != 0)
                len += sprintf(page + len, "Secondary Capability: %d\n",
                               info->secondary_capability);
-
        return len;
 }
 
-#if 0 /* Currently unused */
-static int stsi_2_2_1(struct sysinfo_2_2_1 *info, char *page, int len)
-{
-       if (stsi(info, 2, 2, 1) == -ENOSYS)
-               return len;
-
-       len += sprintf(page + len, "\n");
-       EBCASC (info->sequence, sizeof(info->sequence));
-       EBCASC (info->plant, sizeof(info->plant));
-       len += sprintf(page + len, "Sequence Code of logical CPU: %-16.16s\n",
-                      info->sequence);
-       len += sprintf(page + len, "Plant of logical CPU: %-16.16s\n",
-                      info->plant);
-       return len;
-}
-#endif
-
 static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
 {
        if (stsi(info, 2, 2, 2) == -ENOSYS)
                return len;
 
-       EBCASC (info->name, sizeof(info->name));
+       EBCASC(info->name, sizeof(info->name));
 
        len += sprintf(page + len, "\n");
        len += sprintf(page + len, "LPAR Number:          %d\n",
@@ -214,8 +177,8 @@ static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
        if (stsi(info, 3, 2, 2) == -ENOSYS)
                return len;
        for (i = 0; i < info->count; i++) {
-               EBCASC (info->vm[i].name, sizeof(info->vm[i].name));
-               EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi));
+               EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
+               EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi));
                len += sprintf(page + len, "\n");
                len += sprintf(page + len, "VM%02d Name:            %-8.8s\n",
                               i, info->vm[i].name);
@@ -237,14 +200,13 @@ static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
        return len;
 }
 
-
 static int proc_read_sysinfo(char *page, char **start,
-                             off_t off, int count,
-                             int *eof, void *data)
+                            off_t off, int count,
+                            int *eof, void *data)
 {
-       unsigned long info = get_zeroed_page (GFP_KERNEL);
+       unsigned long info = get_zeroed_page(GFP_KERNEL);
        int level, len;
-       
+
        if (!info)
                return 0;
 
@@ -262,8 +224,8 @@ static int proc_read_sysinfo(char *page, char **start,
        if (level >= 3)
                len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
 
-       free_page (info);
-        return len;
+       free_page(info);
+       return len;
 }
 
 static __init int create_proc_sysinfo(void)
@@ -272,8 +234,7 @@ static __init int create_proc_sysinfo(void)
                               proc_read_sysinfo, NULL);
        return 0;
 }
-
-__initcall(create_proc_sysinfo);
+device_initcall(create_proc_sysinfo);
 
 /*
  * Service levels interface.
@@ -387,13 +348,11 @@ static __init int create_proc_service_level(void)
                register_service_level(&service_level_vm);
        return 0;
 }
-
 subsys_initcall(create_proc_service_level);
 
 /*
  * Bogomips calculation based on cpu capability.
  */
-
 int get_cpu_capability(unsigned int *capability)
 {
        struct sysinfo_1_2_2 *info;
index fc468cae4460ace449d92250f777f70490a25380..f72d41068dc2d7177c0e5c7f70aebb75754a5edd 100644 (file)
@@ -331,6 +331,7 @@ static unsigned long long adjust_time(unsigned long long old,
 }
 
 static DEFINE_PER_CPU(atomic_t, clock_sync_word);
+static DEFINE_MUTEX(clock_sync_mutex);
 static unsigned long clock_sync_flags;
 
 #define CLOCK_SYNC_HAS_ETR     0
@@ -394,6 +395,20 @@ static void enable_sync_clock(void)
        atomic_set_mask(0x80000000, sw_ptr);
 }
 
+/*
+ * Function to check if the clock is in sync.
+ */
+static inline int check_sync_clock(void)
+{
+       atomic_t *sw_ptr;
+       int rc;
+
+       sw_ptr = &get_cpu_var(clock_sync_word);
+       rc = (atomic_read(sw_ptr) & 0x80000000U) != 0;
+       put_cpu_var(clock_sync_sync);
+       return rc;
+}
+
 /* Single threaded workqueue used for etr and stp sync events */
 static struct workqueue_struct *time_sync_wq;
 
@@ -485,6 +500,8 @@ static void etr_reset(void)
        if (etr_setr(&etr_eacr) == 0) {
                etr_tolec = get_clock();
                set_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags);
+               if (etr_port0_online && etr_port1_online)
+                       set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
        } else if (etr_port0_online || etr_port1_online) {
                pr_warning("The real or virtual hardware system does "
                           "not provide an ETR interface\n");
@@ -533,8 +550,7 @@ void etr_switch_to_local(void)
 {
        if (!etr_eacr.sl)
                return;
-       if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-               disable_sync_clock(NULL);
+       disable_sync_clock(NULL);
        set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events);
        queue_work(time_sync_wq, &etr_work);
 }
@@ -549,8 +565,7 @@ void etr_sync_check(void)
 {
        if (!etr_eacr.es)
                return;
-       if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-               disable_sync_clock(NULL);
+       disable_sync_clock(NULL);
        set_bit(ETR_EVENT_SYNC_CHECK, &etr_events);
        queue_work(time_sync_wq, &etr_work);
 }
@@ -914,7 +929,7 @@ static struct etr_eacr etr_handle_update(struct etr_aib *aib,
         * Do not try to get the alternate port aib if the clock
         * is not in sync yet.
         */
-       if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags) && !eacr.es)
+       if (!check_sync_clock())
                return eacr;
 
        /*
@@ -997,7 +1012,6 @@ static void etr_work_fn(struct work_struct *work)
                on_each_cpu(disable_sync_clock, NULL, 1);
                del_timer_sync(&etr_timer);
                etr_update_eacr(eacr);
-               clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
                goto out_unlock;
        }
 
@@ -1071,18 +1085,13 @@ static void etr_work_fn(struct work_struct *work)
                /* Both ports not usable. */
                eacr.es = eacr.sl = 0;
                sync_port = -1;
-               clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
        }
 
-       if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-               eacr.es = 0;
-
        /*
         * If the clock is in sync just update the eacr and return.
         * If there is no valid sync port wait for a port update.
         */
-       if (test_bit(CLOCK_SYNC_STP, &clock_sync_flags) ||
-           eacr.es || sync_port < 0) {
+       if (check_sync_clock() || sync_port < 0) {
                etr_update_eacr(eacr);
                etr_set_tolec_timeout(now);
                goto out_unlock;
@@ -1103,13 +1112,11 @@ static void etr_work_fn(struct work_struct *work)
         * and set up a timer to try again after 0.5 seconds
         */
        etr_update_eacr(eacr);
-       set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
        if (now < etr_tolec + (1600000 << 12) ||
            etr_sync_clock_stop(&aib, sync_port) != 0) {
                /* Sync failed. Try again in 1/2 second. */
                eacr.es = 0;
                etr_update_eacr(eacr);
-               clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
                etr_set_sync_timeout();
        } else
                etr_set_tolec_timeout(now);
@@ -1191,19 +1198,30 @@ static ssize_t etr_online_store(struct sys_device *dev,
                return -EINVAL;
        if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags))
                return -EOPNOTSUPP;
+       mutex_lock(&clock_sync_mutex);
        if (dev == &etr_port0_dev) {
                if (etr_port0_online == value)
-                       return count;   /* Nothing to do. */
+                       goto out;       /* Nothing to do. */
                etr_port0_online = value;
+               if (etr_port0_online && etr_port1_online)
+                       set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
+               else
+                       clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
                set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);
                queue_work(time_sync_wq, &etr_work);
        } else {
                if (etr_port1_online == value)
-                       return count;   /* Nothing to do. */
+                       goto out;       /* Nothing to do. */
                etr_port1_online = value;
+               if (etr_port0_online && etr_port1_online)
+                       set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
+               else
+                       clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
                set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);
                queue_work(time_sync_wq, &etr_work);
        }
+out:
+       mutex_unlock(&clock_sync_mutex);
        return count;
 }
 
@@ -1471,8 +1489,6 @@ static void stp_timing_alert(struct stp_irq_parm *intparm)
  */
 void stp_sync_check(void)
 {
-       if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
-               return;
        disable_sync_clock(NULL);
        queue_work(time_sync_wq, &stp_work);
 }
@@ -1485,8 +1501,6 @@ void stp_sync_check(void)
  */
 void stp_island_check(void)
 {
-       if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
-               return;
        disable_sync_clock(NULL);
        queue_work(time_sync_wq, &stp_work);
 }
@@ -1513,10 +1527,6 @@ static int stp_sync_clock(void *data)
 
        enable_sync_clock();
 
-       set_bit(CLOCK_SYNC_STP, &clock_sync_flags);
-       if (test_and_clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-               queue_work(time_sync_wq, &etr_work);
-
        rc = 0;
        if (stp_info.todoff[0] || stp_info.todoff[1] ||
            stp_info.todoff[2] || stp_info.todoff[3] ||
@@ -1535,9 +1545,6 @@ static int stp_sync_clock(void *data)
        if (rc) {
                disable_sync_clock(NULL);
                stp_sync->in_sync = -EAGAIN;
-               clear_bit(CLOCK_SYNC_STP, &clock_sync_flags);
-               if (etr_port0_online || etr_port1_online)
-                       queue_work(time_sync_wq, &etr_work);
        } else
                stp_sync->in_sync = 1;
        xchg(&first, 0);
@@ -1569,6 +1576,10 @@ static void stp_work_fn(struct work_struct *work)
        if (rc || stp_info.c == 0)
                goto out_unlock;
 
+       /* Skip synchronization if the clock is already in sync. */
+       if (check_sync_clock())
+               goto out_unlock;
+
        memset(&stp_sync, 0, sizeof(stp_sync));
        get_online_cpus();
        atomic_set(&stp_sync.cpus, num_online_cpus() - 1);
@@ -1684,8 +1695,14 @@ static ssize_t stp_online_store(struct sysdev_class *class,
                return -EINVAL;
        if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
                return -EOPNOTSUPP;
+       mutex_lock(&clock_sync_mutex);
        stp_online = value;
+       if (stp_online)
+               set_bit(CLOCK_SYNC_STP, &clock_sync_flags);
+       else
+               clear_bit(CLOCK_SYNC_STP, &clock_sync_flags);
        queue_work(time_sync_wq, &stp_work);
+       mutex_unlock(&clock_sync_mutex);
        return count;
 }
 
index cc362c9ea8f1acc42d001d957a35e881868b4e0b..3c72c9cf22b68f8f40a6b68d0da1972b9c112bf1 100644 (file)
@@ -74,7 +74,7 @@ static DEFINE_SPINLOCK(topology_lock);
 
 cpumask_t cpu_core_map[NR_CPUS];
 
-cpumask_t cpu_coregroup_map(unsigned int cpu)
+static cpumask_t cpu_coregroup_map(unsigned int cpu)
 {
        struct core_info *core = &core_info;
        unsigned long flags;
index 4584d81984c0f25dabb4bffc17371866081ed6a5..c2e42cc65ce7cb7798618e35ededbe685001d825 100644 (file)
@@ -61,9 +61,11 @@ extern pgm_check_handler_t do_asce_exception;
 #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
 
 #ifndef CONFIG_64BIT
+#define LONG "%08lx "
 #define FOURLONG "%08lx %08lx %08lx %08lx\n"
 static int kstack_depth_to_print = 12;
 #else /* CONFIG_64BIT */
+#define LONG "%016lx "
 #define FOURLONG "%016lx %016lx %016lx %016lx\n"
 static int kstack_depth_to_print = 20;
 #endif /* CONFIG_64BIT */
@@ -155,7 +157,7 @@ void show_stack(struct task_struct *task, unsigned long *sp)
                        break;
                if (i && ((i * sizeof (long) % 32) == 0))
                        printk("\n       ");
-               printk("%p ", (void *)*stack++);
+               printk(LONG, *stack++);
        }
        printk("\n");
        show_trace(task, sp);
index 690e17819686534c9061b03e5408354bdb00f5d8..89b2e7f1b7a9ca85c207880b54f7c220ac428728 100644 (file)
@@ -144,7 +144,6 @@ out:
        return -ENOMEM;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore)
 {
        unsigned long segment_table, page_table, page_frame;
@@ -163,7 +162,6 @@ void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore)
        free_page(page_table);
        free_pages(segment_table, SEGMENT_ORDER);
 }
-#endif /* CONFIG_HOTPLUG_CPU */
 
 static void __vdso_init_cr5(void *dummy)
 {
index d796d05c9c01ac1be6779682a730485d73502bd2..7a2063eb88f0ffac77a573d24d2653dc7aaf3c24 100644 (file)
@@ -108,6 +108,8 @@ SECTIONS
                EXIT_TEXT
        }
 
+       /* early.c uses stsi, which requires page aligned data. */
+       . = ALIGN(PAGE_SIZE);
        .init.data : {
                INIT_DATA
        }
index cbfe91e101208273d789585595f146a5878b0081..f4d56e9939c90949c1e886eaabf6cc7d35cab858 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/timer.h>
 #include <asm/lowcore.h>
 #include <asm/pgtable.h>
-
+#include <asm/nmi.h>
 #include "kvm-s390.h"
 #include "gaccess.h"
 
@@ -286,7 +286,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
        setup_timer(&vcpu->arch.ckc_timer, kvm_s390_idle_wakeup,
                 (unsigned long) vcpu);
        get_cpu_id(&vcpu->arch.cpu_id);
-       vcpu->arch.cpu_id.version = 0xfe;
+       vcpu->arch.cpu_id.version = 0xff;
        return 0;
 }
 
@@ -440,8 +440,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
        return -EINVAL; /* not implemented yet */
 }
 
-extern void s390_handle_mcck(void);
-
 static void __vcpu_run(struct kvm_vcpu *vcpu)
 {
        memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
index 6ccb9fab055a5b08abb129bbd8752d11f1a0dd8c..3f5f680726ed1e03bc74cc40a4217a93ab89e837 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/timex.h>
+#include <linux/module.h>
 #include <linux/irqflags.h>
 #include <linux/interrupt.h>
 
@@ -92,6 +93,7 @@ out:
        local_irq_restore(flags);
        preempt_enable();
 }
+EXPORT_SYMBOL(__udelay);
 
 /*
  * Simple udelay variant. To be used on startup and reboot
index ae5cf5d03d4165b7c98134830a8138b1b1ffe61b..4143b7c1909628fd7e8284b97acfc9392e158910 100644 (file)
@@ -44,7 +44,11 @@ static inline char *__strnend(const char *s, size_t n)
  */
 size_t strlen(const char *s)
 {
+#if __GNUC__ < 4
        return __strend(s) - s;
+#else
+       return __builtin_strlen(s);
+#endif
 }
 EXPORT_SYMBOL(strlen);
 
@@ -70,6 +74,7 @@ EXPORT_SYMBOL(strnlen);
  */
 char *strcpy(char *dest, const char *src)
 {
+#if __GNUC__ < 4
        register int r0 asm("0") = 0;
        char *ret = dest;
 
@@ -78,6 +83,9 @@ char *strcpy(char *dest, const char *src)
                      : "+&a" (dest), "+&a" (src) : "d" (r0)
                      : "cc", "memory" );
        return ret;
+#else
+       return __builtin_strcpy(dest, src);
+#endif
 }
 EXPORT_SYMBOL(strcpy);
 
index 4d537205e83c0013d159a9cd8fc5145e0dd80813..833e8366c351d08238466e21f660c66dc47e0845 100644 (file)
@@ -200,29 +200,6 @@ static void do_low_address(struct pt_regs *regs, unsigned long error_code)
        do_no_context(regs, error_code, 0);
 }
 
-/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
-static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
-                           unsigned long address)
-{
-       struct task_struct *tsk = current;
-       struct mm_struct *mm = tsk->mm;
-
-       up_read(&mm->mmap_sem);
-       if (is_global_init(tsk)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               return 1;
-       }
-       printk("VM: killing process %s\n", tsk->comm);
-       if (regs->psw.mask & PSW_MASK_PSTATE)
-               do_group_exit(SIGKILL);
-       do_no_context(regs, error_code, address);
-       return 0;
-}
-
 static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
                      unsigned long address)
 {
@@ -367,7 +344,6 @@ good_area:
                        goto bad_area;
        }
 
-survive:
        if (is_vm_hugetlb_page(vma))
                address &= HPAGE_MASK;
        /*
@@ -378,8 +354,8 @@ survive:
        fault = handle_mm_fault(mm, vma, address, write);
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM) {
-                       if (do_out_of_memory(regs, error_code, address))
-                               goto survive;
+                       up_read(&mm->mmap_sem);
+                       pagefault_out_of_memory();
                        return;
                } else if (fault & VM_FAULT_SIGBUS) {
                        do_sigbus(regs, error_code, address);
index f0258ca3b17ed0905bd8a80a42f15e4355a6fd87..c634dfbe92e9ad680f245617db440be322fcad27 100644 (file)
@@ -40,7 +40,9 @@
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
+
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
+EXPORT_SYMBOL(empty_zero_page);
 
 /*
  * paging_init() sets up the page tables
index 6b6ddc4ea02be082bf340c8ee662da7fe25d47a7..be6c1cf4ad5ae8922f039ab2100b2e50183553f2 100644 (file)
@@ -258,6 +258,10 @@ int s390_enable_sie(void)
        struct task_struct *tsk = current;
        struct mm_struct *mm, *old_mm;
 
+       /* Do we have switched amode? If no, we cannot do sie */
+       if (!switch_amode)
+               return -EINVAL;
+
        /* Do we have pgstes? if yes, we are done */
        if (tsk->mm->context.has_pgste)
                return 0;
@@ -292,7 +296,7 @@ int s390_enable_sie(void)
        tsk->mm = tsk->active_mm = mm;
        preempt_disable();
        update_mm(mm, tsk);
-       cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+       cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
        preempt_enable();
        task_unlock(tsk);
        mmput(old_mm);
index a53496828b76949a3e0b50c82fa4372d8c6f21dd..54481a8877699d40d22d3afceded64d70365cbe0 100644 (file)
 
 #include <linux/types.h>
 #include <asm/ebcdic.h>
+#include <linux/ctype.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/mempool.h>
-#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/tty.h>
 #include <linux/wait.h>
 #include <net/iucv/iucv.h>
@@ -95,6 +96,12 @@ static unsigned long hvc_iucv_devices = 1;
 /* Array of allocated hvc iucv tty lines... */
 static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
 #define IUCV_HVC_CON_IDX       (0)
+/* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
+#define MAX_VMID_FILTER                (500)
+static size_t hvc_iucv_filter_size;
+static void *hvc_iucv_filter;
+static const char *hvc_iucv_filter_string;
+static DEFINE_RWLOCK(hvc_iucv_filter_lock);
 
 /* Kmem cache and mempool for iucv_tty_buffer elements */
 static struct kmem_cache *hvc_iucv_buffer_cache;
@@ -617,6 +624,27 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
        }
 }
 
+/**
+ * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
+ * @ipvmid:    Originating z/VM user ID (right padded with blanks)
+ *
+ * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
+ * non-zero.
+ */
+static int hvc_iucv_filter_connreq(u8 ipvmid[8])
+{
+       size_t i;
+
+       /* Note: default policy is ACCEPT if no filter is set */
+       if (!hvc_iucv_filter_size)
+               return 0;
+
+       for (i = 0; i < hvc_iucv_filter_size; i++)
+               if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
+                       return 0;
+       return 1;
+}
+
 /**
  * hvc_iucv_path_pending() - IUCV handler to process a connection request.
  * @path:      Pending path (struct iucv_path)
@@ -641,6 +669,7 @@ static      int hvc_iucv_path_pending(struct iucv_path *path,
 {
        struct hvc_iucv_private *priv;
        u8 nuser_data[16];
+       u8 vm_user_id[9];
        int i, rc;
 
        priv = NULL;
@@ -653,6 +682,20 @@ static     int hvc_iucv_path_pending(struct iucv_path *path,
        if (!priv)
                return -ENODEV;
 
+       /* Enforce that ipvmid is allowed to connect to us */
+       read_lock(&hvc_iucv_filter_lock);
+       rc = hvc_iucv_filter_connreq(ipvmid);
+       read_unlock(&hvc_iucv_filter_lock);
+       if (rc) {
+               iucv_path_sever(path, ipuser);
+               iucv_path_free(path);
+               memcpy(vm_user_id, ipvmid, 8);
+               vm_user_id[8] = 0;
+               pr_info("A connection request from z/VM user ID %s "
+                       "was refused\n", vm_user_id);
+               return 0;
+       }
+
        spin_lock(&priv->lock);
 
        /* If the terminal is already connected or being severed, then sever
@@ -876,6 +919,171 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
        return 0;
 }
 
+/**
+ * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
+ * @filter:    String containing a comma-separated list of z/VM user IDs
+ */
+static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
+{
+       const char *nextdelim, *residual;
+       size_t len;
+
+       nextdelim = strchr(filter, ',');
+       if (nextdelim) {
+               len = nextdelim - filter;
+               residual = nextdelim + 1;
+       } else {
+               len = strlen(filter);
+               residual = filter + len;
+       }
+
+       if (len == 0)
+               return ERR_PTR(-EINVAL);
+
+       /* check for '\n' (if called from sysfs) */
+       if (filter[len - 1] == '\n')
+               len--;
+
+       if (len > 8)
+               return ERR_PTR(-EINVAL);
+
+       /* pad with blanks and save upper case version of user ID */
+       memset(dest, ' ', 8);
+       while (len--)
+               dest[len] = toupper(filter[len]);
+       return residual;
+}
+
+/**
+ * hvc_iucv_setup_filter() - Set up z/VM user ID filter
+ * @filter:    String consisting of a comma-separated list of z/VM user IDs
+ *
+ * The function parses the @filter string and creates an array containing
+ * the list of z/VM user ID filter entries.
+ * Return code 0 means success, -EINVAL if the filter is syntactically
+ * incorrect, -ENOMEM if there was not enough memory to allocate the
+ * filter list array, or -ENOSPC if too many z/VM user IDs have been specified.
+ */
+static int hvc_iucv_setup_filter(const char *val)
+{
+       const char *residual;
+       int err;
+       size_t size, count;
+       void *array, *old_filter;
+
+       count = strlen(val);
+       if (count == 0 || (count == 1 && val[0] == '\n')) {
+               size  = 0;
+               array = NULL;
+               goto out_replace_filter;        /* clear filter */
+       }
+
+       /* count user IDs in order to allocate sufficient memory */
+       size = 1;
+       residual = val;
+       while ((residual = strchr(residual, ',')) != NULL) {
+               residual++;
+               size++;
+       }
+
+       /* check if the specified list exceeds the filter limit */
+       if (size > MAX_VMID_FILTER)
+               return -ENOSPC;
+
+       array = kzalloc(size * 8, GFP_KERNEL);
+       if (!array)
+               return -ENOMEM;
+
+       count = size;
+       residual = val;
+       while (*residual && count) {
+               residual = hvc_iucv_parse_filter(residual,
+                                                array + ((size - count) * 8));
+               if (IS_ERR(residual)) {
+                       err = PTR_ERR(residual);
+                       kfree(array);
+                       goto out_err;
+               }
+               count--;
+       }
+
+out_replace_filter:
+       write_lock_bh(&hvc_iucv_filter_lock);
+       old_filter = hvc_iucv_filter;
+       hvc_iucv_filter_size = size;
+       hvc_iucv_filter = array;
+       write_unlock_bh(&hvc_iucv_filter_lock);
+       kfree(old_filter);
+
+       err = 0;
+out_err:
+       return err;
+}
+
+/**
+ * param_set_vmidfilter() - Set z/VM user ID filter parameter
+ * @val:       String consisting of a comma-separated list of z/VM user IDs
+ * @kp:                Kernel parameter pointing to hvc_iucv_filter array
+ *
+ * The function sets up the z/VM user ID filter specified as comma-separated
+ * list of user IDs in @val.
+ * Note: If it is called early in the boot process, @val is stored and
+ *      parsed later in hvc_iucv_init().
+ */
+static int param_set_vmidfilter(const char *val, struct kernel_param *kp)
+{
+       int rc;
+
+       if (!MACHINE_IS_VM || !hvc_iucv_devices)
+               return -ENODEV;
+
+       if (!val)
+               return -EINVAL;
+
+       rc = 0;
+       if (slab_is_available())
+               rc = hvc_iucv_setup_filter(val);
+       else
+               hvc_iucv_filter_string = val;   /* defer... */
+       return rc;
+}
+
+/**
+ * param_get_vmidfilter() - Get z/VM user ID filter
+ * @buffer:    Buffer to store z/VM user ID filter,
+ *             (buffer size assumption PAGE_SIZE)
+ * @kp:                Kernel parameter pointing to the hvc_iucv_filter array
+ *
+ * The function stores the filter as a comma-separated list of z/VM user IDs
+ * in @buffer. Typically, sysfs routines call this function for attr show.
+ */
+static int param_get_vmidfilter(char *buffer, struct kernel_param *kp)
+{
+       int rc;
+       size_t index, len;
+       void *start, *end;
+
+       if (!MACHINE_IS_VM || !hvc_iucv_devices)
+               return -ENODEV;
+
+       rc = 0;
+       read_lock_bh(&hvc_iucv_filter_lock);
+       for (index = 0; index < hvc_iucv_filter_size; index++) {
+               start = hvc_iucv_filter + (8 * index);
+               end   = memchr(start, ' ', 8);
+               len   = (end) ? end - start : 8;
+               memcpy(buffer + rc, start, len);
+               rc += len;
+               buffer[rc++] = ',';
+       }
+       read_unlock_bh(&hvc_iucv_filter_lock);
+       if (rc)
+               buffer[--rc] = '\0';    /* replace last comma and update rc */
+       return rc;
+}
+
+#define param_check_vmidfilter(name, p) __param_check(name, p, void)
+
 /**
  * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
  */
@@ -884,24 +1092,53 @@ static int __init hvc_iucv_init(void)
        int rc;
        unsigned int i;
 
+       if (!hvc_iucv_devices)
+               return -ENODEV;
+
        if (!MACHINE_IS_VM) {
-               pr_info("The z/VM IUCV HVC device driver cannot "
+               pr_notice("The z/VM IUCV HVC device driver cannot "
                           "be used without z/VM\n");
-               return -ENODEV;
+               rc = -ENODEV;
+               goto out_error;
        }
 
-       if (!hvc_iucv_devices)
-               return -ENODEV;
+       if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
+               pr_err("%lu is not a valid value for the hvc_iucv= "
+                       "kernel parameter\n", hvc_iucv_devices);
+               rc = -EINVAL;
+               goto out_error;
+       }
 
-       if (hvc_iucv_devices > MAX_HVC_IUCV_LINES)
-               return -EINVAL;
+       /* parse hvc_iucv_allow string and create z/VM user ID filter list */
+       if (hvc_iucv_filter_string) {
+               rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
+               switch (rc) {
+               case 0:
+                       break;
+               case -ENOMEM:
+                       pr_err("Allocating memory failed with "
+                               "reason code=%d\n", 3);
+                       goto out_error;
+               case -EINVAL:
+                       pr_err("hvc_iucv_allow= does not specify a valid "
+                               "z/VM user ID list\n");
+                       goto out_error;
+               case -ENOSPC:
+                       pr_err("hvc_iucv_allow= specifies too many "
+                               "z/VM user IDs\n");
+                       goto out_error;
+               default:
+                       goto out_error;
+               }
+       }
 
        hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
                                           sizeof(struct iucv_tty_buffer),
                                           0, 0, NULL);
        if (!hvc_iucv_buffer_cache) {
                pr_err("Allocating memory failed with reason code=%d\n", 1);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto out_error;
        }
 
        hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
@@ -909,7 +1146,8 @@ static int __init hvc_iucv_init(void)
        if (!hvc_iucv_mempool) {
                pr_err("Allocating memory failed with reason code=%d\n", 2);
                kmem_cache_destroy(hvc_iucv_buffer_cache);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto out_error;
        }
 
        /* register the first terminal device as console
@@ -953,6 +1191,8 @@ out_error_hvc:
 out_error_memory:
        mempool_destroy(hvc_iucv_mempool);
        kmem_cache_destroy(hvc_iucv_buffer_cache);
+out_error:
+       hvc_iucv_devices = 0; /* ensure that we do not provide any device */
        return rc;
 }
 
@@ -968,3 +1208,4 @@ static     int __init hvc_iucv_config(char *val)
 
 device_initcall(hvc_iucv_init);
 __setup("hvc_iucv=", hvc_iucv_config);
+core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
index d0eae59bc3667ce8d2ee56d484777d7cb5d32ccd..95bccfd3f169a8a3a167368f972cbbd08de7c869 100644 (file)
@@ -2,9 +2,6 @@
 # Makefile for the S/390 specific device drivers
 #
 
-CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
-
-obj-y += s390mach.o sysinfo.o
 obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
 
 drivers-y += drivers/s390/built-in.o
index 08c23a921012d4a771b2171b712fdd1b8f653c0f..2fd64e5a9ab267ae38d6b79454125a41d929ec74 100644 (file)
@@ -9,6 +9,9 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -22,6 +25,7 @@
 #include <asm/ebcdic.h>
 #include <asm/idals.h>
 #include <asm/todclk.h>
+#include <asm/itcw.h>
 
 /* This is ugly... */
 #define PRINTK_HEADER "dasd:"
@@ -221,7 +225,7 @@ static int dasd_state_known_to_basic(struct dasd_device *device)
                        return rc;
        }
        /* register 'device' debug area, used for all DBF_DEV_XXX calls */
-       device->debug_area = debug_register(dev_name(&device->cdev->dev), 1, 1,
+       device->debug_area = debug_register(dev_name(&device->cdev->dev), 4, 1,
                                            8 * sizeof(long));
        debug_register_view(device->debug_area, &debug_sprintf_view);
        debug_set_level(device->debug_area, DBF_WARNING);
@@ -762,7 +766,7 @@ static inline int dasd_check_cqr(struct dasd_ccw_req *cqr)
                return -EINVAL;
        device = cqr->startdev;
        if (strncmp((char *) &cqr->magic, device->discipline->ebcname, 4)) {
-               DEV_MESSAGE(KERN_WARNING, device,
+               DBF_DEV_EVENT(DBF_WARNING, device,
                            " dasd_ccw_req 0x%08x magic doesn't match"
                            " discipline 0x%08x",
                            cqr->magic,
@@ -782,6 +786,7 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
 {
        struct dasd_device *device;
        int retries, rc;
+       char errorstring[ERRORLENGTH];
 
        /* Check the cqr */
        rc = dasd_check_cqr(cqr);
@@ -815,10 +820,10 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
                                      "device busy, retry later");
                        break;
                default:
-                       DEV_MESSAGE(KERN_ERR, device,
-                                   "line %d unknown RC=%d, please "
-                                   "report to linux390@de.ibm.com",
-                                   __LINE__, rc);
+                       /* internal error 10 - unknown rc*/
+                       snprintf(errorstring, ERRORLENGTH, "10 %d", rc);
+                       dev_err(&device->cdev->dev, "An error occurred in the "
+                               "DASD device driver, reason=%s\n", errorstring);
                        BUG();
                        break;
                }
@@ -836,6 +841,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
 {
        struct dasd_device *device;
        int rc;
+       char errorstring[ERRORLENGTH];
 
        /* Check the cqr */
        rc = dasd_check_cqr(cqr);
@@ -843,17 +849,23 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
                return rc;
        device = (struct dasd_device *) cqr->startdev;
        if (cqr->retries < 0) {
-               DEV_MESSAGE(KERN_DEBUG, device,
-                           "start_IO: request %p (%02x/%i) - no retry left.",
-                           cqr, cqr->status, cqr->retries);
+               /* internal error 14 - start_IO run out of retries */
+               sprintf(errorstring, "14 %p", cqr);
+               dev_err(&device->cdev->dev, "An error occurred in the DASD "
+                       "device driver, reason=%s\n", errorstring);
                cqr->status = DASD_CQR_ERROR;
                return -EIO;
        }
        cqr->startclk = get_clock();
        cqr->starttime = jiffies;
        cqr->retries--;
-       rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
-                             cqr->lpm, 0);
+       if (cqr->cpmode == 1) {
+               rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
+                                        (long) cqr, cqr->lpm);
+       } else {
+               rc = ccw_device_start(device->cdev, cqr->cpaddr,
+                                     (long) cqr, cqr->lpm, 0);
+       }
        switch (rc) {
        case 0:
                cqr->status = DASD_CQR_IN_IO;
@@ -862,11 +874,11 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
                              cqr);
                break;
        case -EBUSY:
-               DBF_DEV_EVENT(DBF_ERR, device, "%s",
+               DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
                              "start_IO: device busy, retry later");
                break;
        case -ETIMEDOUT:
-               DBF_DEV_EVENT(DBF_ERR, device, "%s",
+               DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
                              "start_IO: request timeout, retry later");
                break;
        case -EACCES:
@@ -876,19 +888,24 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
                 * Do a retry with all available pathes.
                 */
                cqr->lpm = LPM_ANYPATH;
-               DBF_DEV_EVENT(DBF_ERR, device, "%s",
+               DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
                              "start_IO: selected pathes gone,"
                              " retry on all pathes");
                break;
        case -ENODEV:
+               DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+                             "start_IO: -ENODEV device gone, retry");
+               break;
        case -EIO:
-               DBF_DEV_EVENT(DBF_ERR, device, "%s",
-                             "start_IO: device gone, retry");
+               DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+                             "start_IO: -EIO device gone, retry");
                break;
        default:
-               DEV_MESSAGE(KERN_ERR, device,
-                           "line %d unknown RC=%d, please report"
-                           " to linux390@de.ibm.com", __LINE__, rc);
+               /* internal error 11 - unknown rc */
+               snprintf(errorstring, ERRORLENGTH, "11 %d", rc);
+               dev_err(&device->cdev->dev,
+                       "An error occurred in the DASD device driver, "
+                       "reason=%s\n", errorstring);
                BUG();
                break;
        }
@@ -945,7 +962,7 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
                return;
        cqr = (struct dasd_ccw_req *) intparm;
        if (cqr->status != DASD_CQR_IN_IO) {
-               MESSAGE(KERN_DEBUG,
+               DBF_EVENT(DBF_DEBUG,
                        "invalid status in handle_killed_request: "
                        "bus_id %s, status %02x",
                        dev_name(&cdev->dev), cqr->status);
@@ -956,8 +973,8 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
        if (device == NULL ||
            device != dasd_device_from_cdev_locked(cdev) ||
            strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-               MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
-                       dev_name(&cdev->dev));
+               DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+                             "bus_id %s", dev_name(&cdev->dev));
                return;
        }
 
@@ -996,11 +1013,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
                case -EIO:
                        break;
                case -ETIMEDOUT:
-                       printk(KERN_WARNING"%s(%s): request timed out\n",
+                       DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
                               __func__, dev_name(&cdev->dev));
                        break;
                default:
-                       printk(KERN_WARNING"%s(%s): unknown error %ld\n",
+                       DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
                               __func__, dev_name(&cdev->dev), PTR_ERR(irb));
                }
                dasd_handle_killed_request(cdev, intparm);
@@ -1009,15 +1026,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
 
        now = get_clock();
 
-       DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
-                 dev_name(&cdev->dev), ((irb->scsw.cmd.cstat << 8) |
-                 irb->scsw.cmd.dstat), (unsigned int) intparm);
-
        /* check for unsolicited interrupts */
        cqr = (struct dasd_ccw_req *) intparm;
-       if (!cqr || ((irb->scsw.cmd.cc == 1) &&
-                    (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
-                    (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
+       if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
+                    (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+                    (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) {
                if (cqr && cqr->status == DASD_CQR_IN_IO)
                        cqr->status = DASD_CQR_QUEUED;
                device = dasd_device_from_cdev_locked(cdev);
@@ -1033,14 +1046,14 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
        device = (struct dasd_device *) cqr->startdev;
        if (!device ||
            strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-               MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
-                       dev_name(&cdev->dev));
+               DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+                             "bus_id %s", dev_name(&cdev->dev));
                return;
        }
 
        /* Check for clear pending */
        if (cqr->status == DASD_CQR_CLEAR_PENDING &&
-           irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
+           scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
                cqr->status = DASD_CQR_CLEARED;
                dasd_device_clear_timer(device);
                wake_up(&dasd_flush_wq);
@@ -1048,19 +1061,17 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
                return;
        }
 
-       /* check status - the request might have been killed by dyn detach */
+       /* check status - the request might have been killed by dyn detach */
        if (cqr->status != DASD_CQR_IN_IO) {
-               MESSAGE(KERN_DEBUG,
-                       "invalid status: bus_id %s, status %02x",
-                       dev_name(&cdev->dev), cqr->status);
+               DBF_DEV_EVENT(DBF_DEBUG, device, "invalid status: bus_id %s, "
+                             "status %02x", dev_name(&cdev->dev), cqr->status);
                return;
        }
-       DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
-                     ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
+
        next = NULL;
        expires = 0;
-       if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
-           irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
+       if (scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
+           scsw_cstat(&irb->scsw) == 0) {
                /* request was completed successfully */
                cqr->status = DASD_CQR_SUCCESS;
                cqr->stopclk = now;
@@ -1071,18 +1082,23 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
                }
        } else {  /* error */
                memcpy(&cqr->irb, irb, sizeof(struct irb));
+               /* log sense for every failed I/O to s390 debugfeature */
+               dasd_log_sense_dbf(cqr, irb);
                if (device->features & DASD_FEATURE_ERPLOG) {
                        dasd_log_sense(cqr, irb);
                }
+
                /*
                 * If we don't want complex ERP for this request, then just
                 * reset this and retry it in the fastpath
                 */
                if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
                    cqr->retries > 0) {
-                       DEV_MESSAGE(KERN_DEBUG, device,
-                                   "default ERP in fastpath (%i retries left)",
-                                   cqr->retries);
+                       if (cqr->lpm == LPM_ANYPATH)
+                               DBF_DEV_EVENT(DBF_DEBUG, device,
+                                             "default ERP in fastpath "
+                                             "(%i retries left)",
+                                             cqr->retries);
                        cqr->lpm    = LPM_ANYPATH;
                        cqr->status = DASD_CQR_QUEUED;
                        next = cqr;
@@ -1093,10 +1109,6 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
            (!device->stopped)) {
                if (device->discipline->start_IO(next) == 0)
                        expires = next->expires;
-               else
-                       DEV_MESSAGE(KERN_DEBUG, device, "%s",
-                                   "Interrupt fastpath "
-                                   "failed!");
        }
        if (expires != 0)
                dasd_device_set_timer(device, expires);
@@ -1169,6 +1181,7 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
        struct dasd_block *block;
        void (*callback)(struct dasd_ccw_req *, void *data);
        void *callback_data;
+       char errorstring[ERRORLENGTH];
 
        list_for_each_safe(l, n, final_queue) {
                cqr = list_entry(l, struct dasd_ccw_req, devlist);
@@ -1189,10 +1202,11 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
                        cqr->status = DASD_CQR_TERMINATED;
                        break;
                default:
-                       DEV_MESSAGE(KERN_ERR, device,
-                                   "wrong cqr status in __dasd_process_final_queue "
-                                   "for cqr %p, status %x",
-                                   cqr, cqr->status);
+                       /* internal error 12 - wrong cqr status*/
+                       snprintf(errorstring, ERRORLENGTH, "12 %p %x02", cqr, cqr->status);
+                       dev_err(&device->cdev->dev,
+                               "An error occurred in the DASD device driver, "
+                               "reason=%s\n", errorstring);
                        BUG();
                }
                if (cqr->callback != NULL)
@@ -1217,18 +1231,17 @@ static void __dasd_device_check_expire(struct dasd_device *device)
            (time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
                if (device->discipline->term_IO(cqr) != 0) {
                        /* Hmpf, try again in 5 sec */
-                       DEV_MESSAGE(KERN_ERR, device,
-                                   "internal error - timeout (%is) expired "
-                                   "for cqr %p, termination failed, "
-                                   "retrying in 5s",
-                                   (cqr->expires/HZ), cqr);
+                       dev_err(&device->cdev->dev,
+                               "cqr %p timed out (%is) but cannot be "
+                               "ended, retrying in 5 s\n",
+                               cqr, (cqr->expires/HZ));
                        cqr->expires += 5*HZ;
                        dasd_device_set_timer(device, 5*HZ);
                } else {
-                       DEV_MESSAGE(KERN_ERR, device,
-                                   "internal error - timeout (%is) expired "
-                                   "for cqr %p (%i retries left)",
-                                   (cqr->expires/HZ), cqr, cqr->retries);
+                       dev_err(&device->cdev->dev,
+                               "cqr %p timed out (%is), %i retries "
+                               "remaining\n", cqr, (cqr->expires/HZ),
+                               cqr->retries);
                }
        }
 }
@@ -1290,10 +1303,9 @@ int dasd_flush_device_queue(struct dasd_device *device)
                        rc = device->discipline->term_IO(cqr);
                        if (rc) {
                                /* unable to terminate requeust */
-                               DEV_MESSAGE(KERN_ERR, device,
-                                           "dasd flush ccw_queue is unable "
-                                           " to terminate request %p",
-                                           cqr);
+                               dev_err(&device->cdev->dev,
+                                       "Flushing the DASD request queue "
+                                       "failed for request %p\n", cqr);
                                /* stop flush processing */
                                goto finished;
                        }
@@ -1537,10 +1549,9 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
                /* request in IO - terminate IO and release again */
                rc = device->discipline->term_IO(cqr);
                if (rc) {
-                       DEV_MESSAGE(KERN_ERR, device,
-                                   "dasd_cancel_req is unable "
-                                   " to terminate request %p, rc = %d",
-                                   cqr, rc);
+                       dev_err(&device->cdev->dev,
+                               "Cancelling request %p failed with rc=%d\n",
+                               cqr, rc);
                } else {
                        cqr->stopclk = get_clock();
                        rc = 1;
@@ -1617,7 +1628,7 @@ static inline void __dasd_block_process_erp(struct dasd_block *block,
        if (cqr->status == DASD_CQR_DONE)
                DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful");
        else
-               DEV_MESSAGE(KERN_ERR, device, "%s", "ERP unsuccessful");
+               dev_err(&device->cdev->dev, "ERP failed for the DASD\n");
        erp_fn = device->discipline->erp_postaction(cqr);
        erp_fn(cqr);
 }
@@ -1991,8 +2002,11 @@ static void dasd_setup_queue(struct dasd_block *block)
        blk_queue_max_sectors(block->request_queue, max);
        blk_queue_max_phys_segments(block->request_queue, -1L);
        blk_queue_max_hw_segments(block->request_queue, -1L);
-       blk_queue_max_segment_size(block->request_queue, -1L);
-       blk_queue_segment_boundary(block->request_queue, -1L);
+       /* with page sized segments we can translate each segement into
+        * one idaw/tidaw
+        */
+       blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
+       blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
        blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL);
 }
 
@@ -2043,8 +2057,9 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
        }
 
        if (dasd_probeonly) {
-               DEV_MESSAGE(KERN_INFO, base, "%s",
-                           "No access to device due to probeonly mode");
+               dev_info(&base->cdev->dev,
+                        "Accessing the DASD failed because it is in "
+                        "probeonly mode\n");
                rc = -EPERM;
                goto out;
        }
@@ -2101,7 +2116,8 @@ dasd_device_operations = {
        .owner          = THIS_MODULE,
        .open           = dasd_open,
        .release        = dasd_release,
-       .locked_ioctl   = dasd_ioctl,
+       .ioctl          = dasd_ioctl,
+       .compat_ioctl   = dasd_ioctl,
        .getgeo         = dasd_getgeo,
 };
 
@@ -2143,14 +2159,14 @@ int dasd_generic_probe(struct ccw_device *cdev,
 
        ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
        if (ret) {
-               printk(KERN_WARNING
+               DBF_EVENT(DBF_WARNING,
                       "dasd_generic_probe: could not set ccw-device options "
                       "for %s\n", dev_name(&cdev->dev));
                return ret;
        }
        ret = dasd_add_sysfs_files(cdev);
        if (ret) {
-               printk(KERN_WARNING
+               DBF_EVENT(DBF_WARNING,
                       "dasd_generic_probe: could not add sysfs entries "
                       "for %s\n", dev_name(&cdev->dev));
                return ret;
@@ -2166,9 +2182,7 @@ int dasd_generic_probe(struct ccw_device *cdev,
            (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
                ret = ccw_device_set_online(cdev);
        if (ret)
-               printk(KERN_WARNING
-                      "dasd_generic_probe: could not initially "
-                      "online ccw-device %s; return code: %d\n",
+               pr_warning("%s: Setting the DASD online failed with rc=%d\n",
                       dev_name(&cdev->dev), ret);
        return 0;
 }
@@ -2232,10 +2246,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
        discipline = base_discipline;
        if (device->features & DASD_FEATURE_USEDIAG) {
                if (!dasd_diag_discipline_pointer) {
-                       printk (KERN_WARNING
-                               "dasd_generic couldn't online device %s "
-                               "- discipline DIAG not available\n",
-                               dev_name(&cdev->dev));
+                       pr_warning("%s Setting the DASD online failed because "
+                                  "of missing DIAG discipline\n",
+                                  dev_name(&cdev->dev));
                        dasd_delete_device(device);
                        return -ENODEV;
                }
@@ -2256,10 +2269,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
        /* check_device will allocate block device if necessary */
        rc = discipline->check_device(device);
        if (rc) {
-               printk (KERN_WARNING
-                       "dasd_generic couldn't online device %s "
-                       "with discipline %s rc=%i\n",
-                       dev_name(&cdev->dev), discipline->name, rc);
+               pr_warning("%s Setting the DASD online with discipline %s "
+                          "failed with rc=%i\n",
+                          dev_name(&cdev->dev), discipline->name, rc);
                module_put(discipline->owner);
                module_put(base_discipline->owner);
                dasd_delete_device(device);
@@ -2268,9 +2280,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
 
        dasd_set_target_state(device, DASD_STATE_ONLINE);
        if (device->state <= DASD_STATE_KNOWN) {
-               printk (KERN_WARNING
-                       "dasd_generic discipline not found for %s\n",
-                       dev_name(&cdev->dev));
+               pr_warning("%s Setting the DASD online failed because of a "
+                          "missing discipline\n", dev_name(&cdev->dev));
                rc = -ENODEV;
                dasd_set_target_state(device, DASD_STATE_NEW);
                if (device->block)
@@ -2314,13 +2325,13 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
                open_count = atomic_read(&device->block->open_count);
                if (open_count > max_count) {
                        if (open_count > 0)
-                               printk(KERN_WARNING "Can't offline dasd "
-                                      "device with open count = %i.\n",
-                                      open_count);
+                               pr_warning("%s: The DASD cannot be set offline "
+                                          "with open count %i\n",
+                                          dev_name(&cdev->dev), open_count);
                        else
-                               printk(KERN_WARNING "%s",
-                                      "Can't offline dasd device due "
-                                      "to internal use\n");
+                               pr_warning("%s: The DASD cannot be set offline "
+                                          "while it is in use\n",
+                                          dev_name(&cdev->dev));
                        clear_bit(DASD_FLAG_OFFLINE, &device->flags);
                        dasd_put_device(device);
                        return -EBUSY;
@@ -2393,8 +2404,10 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
        cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
 
        if (IS_ERR(cqr)) {
-               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                           "Could not allocate RDC request");
+               /* internal error 13 - Allocating the RDC request failed*/
+               dev_err(&device->cdev->dev,
+                        "An error occurred in the DASD device driver, "
+                        "reason=%s\n", "13");
                return cqr;
        }
 
@@ -2431,6 +2444,40 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
 }
 EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars);
 
+/*
+ *   In command mode and transport mode we need to look for sense
+ *   data in different places. The sense data itself is allways
+ *   an array of 32 bytes, so we can unify the sense data access
+ *   for both modes.
+ */
+char *dasd_get_sense(struct irb *irb)
+{
+       struct tsb *tsb = NULL;
+       char *sense = NULL;
+
+       if (scsw_is_tm(&irb->scsw) && (irb->scsw.tm.fcxs == 0x01)) {
+               if (irb->scsw.tm.tcw)
+                       tsb = tcw_get_tsb((struct tcw *)(unsigned long)
+                                         irb->scsw.tm.tcw);
+               if (tsb && tsb->length == 64 && tsb->flags)
+                       switch (tsb->flags & 0x07) {
+                       case 1: /* tsa_iostat */
+                               sense = tsb->tsa.iostat.sense;
+                               break;
+                       case 2: /* tsa_ddpc */
+                               sense = tsb->tsa.ddpc.sense;
+                               break;
+                       default:
+                               /* currently we don't use interrogate data */
+                               break;
+                       }
+       } else if (irb->esw.esw0.erw.cons) {
+               sense = irb->ecw;
+       }
+       return sense;
+}
+EXPORT_SYMBOL_GPL(dasd_get_sense);
+
 static int __init dasd_init(void)
 {
        int rc;
@@ -2472,7 +2519,7 @@ static int __init dasd_init(void)
 
        return 0;
 failed:
-       MESSAGE(KERN_INFO, "%s", "initialization not performed due to errors");
+       pr_info("The DASD device driver could not be initialized\n");
        dasd_exit();
        return rc;
 }
index d82aad5224f0c6854fdf96999fb19185b9801c5e..27991b69205625cb9c8d11e12321647b8ee272b4 100644 (file)
@@ -7,6 +7,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <asm/idals.h>
@@ -75,7 +77,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
        struct dasd_device *device = erp->startdev;
        unsigned long flags;
 
-       DEV_MESSAGE(KERN_INFO, device,
+       DBF_DEV_EVENT(DBF_INFO, device,
                    "blocking request queue for %is", expires/HZ);
 
        spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
@@ -114,9 +116,9 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
        } else {
 
                /* issue a message and wait for 'device ready' interrupt */
-               DEV_MESSAGE(KERN_ERR, device, "%s",
+               dev_err(&device->cdev->dev,
                            "is offline or not installed - "
-                           "INTERVENTION REQUIRED!!");
+                           "INTERVENTION REQUIRED!!\n");
 
                dasd_3990_erp_block_queue(erp, 60*HZ);
        }
@@ -158,7 +160,7 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
 
        if ((erp->lpm & opm) != 0x00) {
 
-               DEV_MESSAGE(KERN_DEBUG, device,
+               DBF_DEV_EVENT(DBF_WARNING, device,
                            "try alternate lpm=%x (lpum=%x / opm=%x)",
                            erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm);
 
@@ -166,10 +168,9 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
                erp->status = DASD_CQR_FILLED;
                erp->retries = 10;
        } else {
-               DEV_MESSAGE(KERN_ERR, device,
-                           "No alternate channel path left (lpum=%x / "
-                           "opm=%x) -> permanent error",
-                           erp->irb.esw.esw0.sublog.lpum, opm);
+               dev_err(&device->cdev->dev,
+                       "The DASD cannot be reached on any path (lpum=%x"
+                       "/opm=%x)\n", erp->irb.esw.esw0.sublog.lpum, opm);
 
                /* post request with permanent error */
                erp->status = DASD_CQR_FAILED;
@@ -204,8 +205,8 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
                                          sizeof(struct DCTL_data),
                                          device);
        if (IS_ERR(dctl_cqr)) {
-               DEV_MESSAGE(KERN_ERR, device, "%s",
-                           "Unable to allocate DCTL-CQR");
+               dev_err(&device->cdev->dev,
+                           "Unable to allocate DCTL-CQR\n");
                erp->status = DASD_CQR_FAILED;
                return erp;
        }
@@ -294,7 +295,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
        /* interrupt (this enables easier enqueing of the cqr)      */
        if (erp->function != dasd_3990_erp_action_4) {
 
-               DEV_MESSAGE(KERN_INFO, device, "%s",
+               DBF_DEV_EVENT(DBF_INFO, device, "%s",
                            "dasd_3990_erp_action_4: first time retry");
 
                erp->retries = 256;
@@ -303,7 +304,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
        } else {
                if (sense && (sense[25] == 0x1D)) { /* state change pending */
 
-                       DEV_MESSAGE(KERN_INFO, device,
+                       DBF_DEV_EVENT(DBF_INFO, device,
                                    "waiting for state change pending "
                                    "interrupt, %d retries left",
                                    erp->retries);
@@ -311,15 +312,14 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
                        dasd_3990_erp_block_queue(erp, 30*HZ);
 
                } else if (sense && (sense[25] == 0x1E)) {      /* busy */
-                       DEV_MESSAGE(KERN_INFO, device,
+                       DBF_DEV_EVENT(DBF_INFO, device,
                                    "busy - redriving request later, "
                                    "%d retries left",
                                    erp->retries);
                         dasd_3990_erp_block_queue(erp, HZ);
                } else {
-
                        /* no state change pending - retry */
-                       DEV_MESSAGE (KERN_INFO, device,
+                       DBF_DEV_EVENT(DBF_INFO, device,
                                     "redriving request immediately, "
                                     "%d retries left",
                                     erp->retries);
@@ -384,6 +384,7 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
        struct dasd_device *device = erp->startdev;
        char msg_format = (sense[7] & 0xF0);
        char msg_no = (sense[7] & 0x0F);
+       char errorstring[ERRORLENGTH];
 
        switch (msg_format) {
        case 0x00:              /* Format 0 - Program or System Checks */
@@ -394,95 +395,97 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
                        case 0x00:      /* No Message */
                                break;
                        case 0x01:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Invalid Command");
+                               dev_warn(&device->cdev->dev,
+                                           "FORMAT 0 - Invalid Command\n");
                                break;
                        case 0x02:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Invalid Command "
-                                           "Sequence");
+                                           "Sequence\n");
                                break;
                        case 0x03:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - CCW Count less than "
-                                           "required");
+                                           "required\n");
                                break;
                        case 0x04:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Invalid Parameter");
+                               dev_warn(&device->cdev->dev,
+                                           "FORMAT 0 - Invalid Parameter\n");
                                break;
                        case 0x05:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Diagnostic of Sepecial"
-                                           " Command Violates File Mask");
+                               dev_warn(&device->cdev->dev,
+                                           "FORMAT 0 - Diagnostic of Special"
+                                           " Command Violates File Mask\n");
                                break;
                        case 0x07:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Channel Returned with "
-                                           "Incorrect retry CCW");
+                                           "Incorrect retry CCW\n");
                                break;
                        case 0x08:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Reset Notification");
+                               dev_warn(&device->cdev->dev,
+                                           "FORMAT 0 - Reset Notification\n");
                                break;
                        case 0x09:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Storage Path Restart");
+                               dev_warn(&device->cdev->dev,
+                                        "FORMAT 0 - Storage Path Restart\n");
                                break;
                        case 0x0A:
-                               DEV_MESSAGE(KERN_WARNING, device,
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Channel requested "
-                                           "... %02x", sense[8]);
+                                           "... %02x\n", sense[8]);
                                break;
                        case 0x0B:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Invalid Defective/"
-                                           "Alternate Track Pointer");
+                                           "Alternate Track Pointer\n");
                                break;
                        case 0x0C:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - DPS Installation "
-                                           "Check");
+                                           "Check\n");
                                break;
                        case 0x0E:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Command Invalid on "
-                                           "Secondary Address");
+                                           "Secondary Address\n");
                                break;
                        case 0x0F:
-                               DEV_MESSAGE(KERN_WARNING, device,
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Status Not As "
-                                           "Required: reason %02x", sense[8]);
+                                           "Required: reason %02x\n",
+                                        sense[8]);
                                break;
                        default:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Reseved");
+                               dev_warn(&device->cdev->dev,
+                                           "FORMAT 0 - Reserved\n");
                        }
                } else {
                        switch (msg_no) {
                        case 0x00:      /* No Message */
                                break;
                        case 0x01:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Device Error Source");
+                               dev_warn(&device->cdev->dev,
+                                        "FORMAT 0 - Device Error "
+                                        "Source\n");
                                break;
                        case 0x02:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Reserved");
+                               dev_warn(&device->cdev->dev,
+                                           "FORMAT 0 - Reserved\n");
                                break;
                        case 0x03:
-                               DEV_MESSAGE(KERN_WARNING, device,
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Device Fenced - "
-                                           "device = %02x", sense[4]);
+                                           "device = %02x\n", sense[4]);
                                break;
                        case 0x04:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               dev_warn(&device->cdev->dev,
                                            "FORMAT 0 - Data Pinned for "
-                                           "Device");
+                                           "Device\n");
                                break;
                        default:
-                               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                           "FORMAT 0 - Reserved");
+                               dev_warn(&device->cdev->dev,
+                                           "FORMAT 0 - Reserved\n");
                        }
                }
                break;
@@ -492,348 +495,352 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
                case 0x00:      /* No Message */
                        break;
                case 0x01:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 1 - Device Status 1 not as "
-                                   "expected");
+                                   "expected\n");
                        break;
                case 0x03:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Index missing");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 1 - Index missing\n");
                        break;
                case 0x04:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Interruption cannot be reset");
+                       dev_warn(&device->cdev->dev,
+                                "FORMAT 1 - Interruption cannot be "
+                                "reset\n");
                        break;
                case 0x05:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 1 - Device did not respond to "
-                                   "selection");
+                                   "selection\n");
                        break;
                case 0x06:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 1 - Device check-2 error or Set "
-                                   "Sector is not complete");
+                                   "Sector is not complete\n");
                        break;
                case 0x07:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 1 - Head address does not "
-                                   "compare");
+                                   "compare\n");
                        break;
                case 0x08:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Device status 1 not valid");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 1 - Device status 1 not valid\n");
                        break;
                case 0x09:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Device not ready");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 1 - Device not ready\n");
                        break;
                case 0x0A:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 1 - Track physical address did "
-                                   "not compare");
+                                   "not compare\n");
                        break;
                case 0x0B:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Missing device address bit");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 1 - Missing device address bit\n");
                        break;
                case 0x0C:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Drive motor switch is off");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 1 - Drive motor switch is off\n");
                        break;
                case 0x0D:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Seek incomplete");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 1 - Seek incomplete\n");
                        break;
                case 0x0E:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 1 - Cylinder address did not "
-                                   "compare");
+                                   "compare\n");
                        break;
                case 0x0F:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 1 - Offset active cannot be "
-                                   "reset");
+                                   "reset\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 1 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 1 - Reserved\n");
                }
                break;
 
        case 0x20:              /* Format 2 - 3990 Equipment Checks */
                switch (msg_no) {
                case 0x08:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 2 - 3990 check-2 error");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 2 - 3990 check-2 error\n");
                        break;
                case 0x0E:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 2 - Support facility errors");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 2 - Support facility errors\n");
                        break;
                case 0x0F:
-                       DEV_MESSAGE(KERN_WARNING, device,
-                                   "FORMAT 2 - Microcode detected error %02x",
-                                   sense[8]);
+                       dev_warn(&device->cdev->dev,
+                                "FORMAT 2 - Microcode detected error "
+                                "%02x\n",
+                                sense[8]);
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 2 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 2 - Reserved\n");
                }
                break;
 
        case 0x30:              /* Format 3 - 3990 Control Checks */
                switch (msg_no) {
                case 0x0F:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 3 - Allegiance terminated");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 3 - Allegiance terminated\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 3 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 3 - Reserved\n");
                }
                break;
 
        case 0x40:              /* Format 4 - Data Checks */
                switch (msg_no) {
                case 0x00:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 4 - Home address area error");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 4 - Home address area error\n");
                        break;
                case 0x01:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 4 - Count area error");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 4 - Count area error\n");
                        break;
                case 0x02:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 4 - Key area error");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 4 - Key area error\n");
                        break;
                case 0x03:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 4 - Data area error");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 4 - Data area error\n");
                        break;
                case 0x04:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - No sync byte in home address "
-                                   "area");
+                                   "area\n");
                        break;
                case 0x05:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - No sync byte in count address "
-                                   "area");
+                                   "area\n");
                        break;
                case 0x06:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 4 - No sync byte in key area");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 4 - No sync byte in key area\n");
                        break;
                case 0x07:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 4 - No sync byte in data area");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 4 - No sync byte in data area\n");
                        break;
                case 0x08:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - Home address area error; "
-                                   "offset active");
+                                   "offset active\n");
                        break;
                case 0x09:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - Count area error; offset "
-                                   "active");
+                                   "active\n");
                        break;
                case 0x0A:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - Key area error; offset "
-                                   "active");
+                                   "active\n");
                        break;
                case 0x0B:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - Data area error; "
-                                   "offset active");
+                                   "offset active\n");
                        break;
                case 0x0C:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - No sync byte in home "
-                                   "address area; offset active");
+                                   "address area; offset active\n");
                        break;
                case 0x0D:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - No syn byte in count "
-                                   "address area; offset active");
+                                   "address area; offset active\n");
                        break;
                case 0x0E:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - No sync byte in key area; "
-                                   "offset active");
+                                   "offset active\n");
                        break;
                case 0x0F:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 4 - No syn byte in data area; "
-                                   "offset active");
+                                   "offset active\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 4 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 4 - Reserved\n");
                }
                break;
 
        case 0x50:  /* Format 5 - Data Check with displacement information */
                switch (msg_no) {
                case 0x00:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 5 - Data Check in the "
-                                   "home address area");
+                                   "home address area\n");
                        break;
                case 0x01:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 5 - Data Check in the count area");
+                       dev_warn(&device->cdev->dev,
+                                "FORMAT 5 - Data Check in the count "
+                                "area\n");
                        break;
                case 0x02:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 5 - Data Check in the key area");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 5 - Data Check in the key area\n");
                        break;
                case 0x03:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 5 - Data Check in the data area");
+                       dev_warn(&device->cdev->dev,
+                                "FORMAT 5 - Data Check in the data "
+                                "area\n");
                        break;
                case 0x08:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 5 - Data Check in the "
-                                   "home address area; offset active");
+                                   "home address area; offset active\n");
                        break;
                case 0x09:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 5 - Data Check in the count area; "
-                                   "offset active");
+                                   "offset active\n");
                        break;
                case 0x0A:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 5 - Data Check in the key area; "
-                                   "offset active");
+                                   "offset active\n");
                        break;
                case 0x0B:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 5 - Data Check in the data area; "
-                                   "offset active");
+                                   "offset active\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 5 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 5 - Reserved\n");
                }
                break;
 
        case 0x60:  /* Format 6 - Usage Statistics/Overrun Errors */
                switch (msg_no) {
                case 0x00:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel A");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel A\n");
                        break;
                case 0x01:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel B");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel B\n");
                        break;
                case 0x02:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel C");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel C\n");
                        break;
                case 0x03:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel D");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel D\n");
                        break;
                case 0x04:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel E");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel E\n");
                        break;
                case 0x05:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel F");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel F\n");
                        break;
                case 0x06:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel G");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel G\n");
                        break;
                case 0x07:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Overrun on channel H");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Overrun on channel H\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 6 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 6 - Reserved\n");
                }
                break;
 
        case 0x70:  /* Format 7 - Device Connection Control Checks */
                switch (msg_no) {
                case 0x00:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - RCC initiated by a connection "
-                                   "check alert");
+                                   "check alert\n");
                        break;
                case 0x01:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - RCC 1 sequence not "
-                                   "successful");
+                                   "successful\n");
                        break;
                case 0x02:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - RCC 1 and RCC 2 sequences not "
-                                   "successful");
+                                   "successful\n");
                        break;
                case 0x03:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - Invalid tag-in during "
-                                   "selection sequence");
+                                   "selection sequence\n");
                        break;
                case 0x04:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 7 - extra RCC required");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 7 - extra RCC required\n");
                        break;
                case 0x05:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - Invalid DCC selection "
-                                   "response or timeout");
+                                   "response or timeout\n");
                        break;
                case 0x06:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - Missing end operation; device "
-                                   "transfer complete");
+                                   "transfer complete\n");
                        break;
                case 0x07:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - Missing end operation; device "
-                                   "transfer incomplete");
+                                   "transfer incomplete\n");
                        break;
                case 0x08:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - Invalid tag-in for an "
-                                   "immediate command sequence");
+                                   "immediate command sequence\n");
                        break;
                case 0x09:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - Invalid tag-in for an "
-                                   "extended command sequence");
+                                   "extended command sequence\n");
                        break;
                case 0x0A:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - 3990 microcode time out when "
-                                   "stopping selection");
+                                   "stopping selection\n");
                        break;
                case 0x0B:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - No response to selection "
-                                   "after a poll interruption");
+                                   "after a poll interruption\n");
                        break;
                case 0x0C:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - Permanent path error (DASD "
-                                   "controller not available)");
+                                   "controller not available)\n");
                        break;
                case 0x0D:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 7 - DASD controller not available"
-                                   " on disconnected command chain");
+                                   " on disconnected command chain\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 7 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 7 - Reserved\n");
                }
                break;
 
@@ -841,52 +848,52 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
                switch (msg_no) {
                case 0x00:      /* No Message */
                case 0x01:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - Error correction code "
-                                   "hardware fault");
+                                   "hardware fault\n");
                        break;
                case 0x03:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - Unexpected end operation "
-                                   "response code");
+                                   "response code\n");
                        break;
                case 0x04:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - End operation with transfer "
-                                   "count not zero");
+                                   "count not zero\n");
                        break;
                case 0x05:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - End operation with transfer "
-                                   "count zero");
+                                   "count zero\n");
                        break;
                case 0x06:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - DPS checks after a system "
-                                   "reset or selective reset");
+                                   "reset or selective reset\n");
                        break;
                case 0x07:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 8 - DPS cannot be filled");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 8 - DPS cannot be filled\n");
                        break;
                case 0x08:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - Short busy time-out during "
-                                   "device selection");
+                                   "device selection\n");
                        break;
                case 0x09:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - DASD controller failed to "
-                                   "set or reset the long busy latch");
+                                   "set or reset the long busy latch\n");
                        break;
                case 0x0A:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 8 - No interruption from device "
-                                   "during a command chain");
+                                   "during a command chain\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 8 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 8 - Reserved\n");
                }
                break;
 
@@ -895,97 +902,100 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
                case 0x00:
                        break;  /* No Message */
                case 0x06:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 9 - Device check-2 error");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 9 - Device check-2 error\n");
                        break;
                case 0x07:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 9 - Head address did not compare");
+                       dev_warn(&device->cdev->dev,
+                                "FORMAT 9 - Head address did not "
+                                "compare\n");
                        break;
                case 0x0A:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 9 - Track physical address did "
-                                   "not compare while oriented");
+                                   "not compare while oriented\n");
                        break;
                case 0x0E:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT 9 - Cylinder address did not "
-                                   "compare");
+                                   "compare\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT 9 - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT 9 - Reserved\n");
                }
                break;
 
        case 0xF0:              /* Format F - Cache Storage Checks */
                switch (msg_no) {
                case 0x00:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - Operation Terminated");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - Operation Terminated\n");
                        break;
                case 0x01:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - Subsystem Processing Error");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - Subsystem Processing Error\n");
                        break;
                case 0x02:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT F - Cache or nonvolatile storage "
-                                   "equipment failure");
+                                   "equipment failure\n");
                        break;
                case 0x04:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - Caching terminated");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - Caching terminated\n");
                        break;
                case 0x06:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT F - Cache fast write access not "
-                                   "authorized");
+                                   "authorized\n");
                        break;
                case 0x07:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - Track format incorrect");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - Track format incorrect\n");
                        break;
                case 0x09:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - Caching reinitiated");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - Caching reinitiated\n");
                        break;
                case 0x0A:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT F - Nonvolatile storage "
-                                   "terminated");
+                                   "terminated\n");
                        break;
                case 0x0B:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - Volume is suspended duplex");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - Volume is suspended duplex\n");
                        /* call extended error reporting (EER) */
                        dasd_eer_write(device, erp->refers,
                                       DASD_EER_PPRCSUSPEND);
                        break;
                case 0x0C:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - Subsystem status connot be "
-                                   "determined");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - Subsystem status cannot be "
+                                   "determined\n");
                        break;
                case 0x0D:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                       dev_warn(&device->cdev->dev,
                                    "FORMAT F - Caching status reset to "
-                                   "default");
+                                   "default\n");
                        break;
                case 0x0E:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT F - DASD Fast Write inhibited");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT F - DASD Fast Write inhibited\n");
                        break;
                default:
-                       DEV_MESSAGE(KERN_WARNING, device, "%s",
-                                   "FORMAT D - Reserved");
+                       dev_warn(&device->cdev->dev,
+                                   "FORMAT D - Reserved\n");
                }
                break;
 
-       default:        /* unknown message format - should not happen */
-               DEV_MESSAGE (KERN_WARNING, device,
-                             "unknown message format %02x",
-                             msg_format);
+       default:        /* unknown message format - should not happen
+                          internal error 03 - unknown message format */
+               snprintf(errorstring, ERRORLENGTH, "03 %x02", msg_format);
+               dev_err(&device->cdev->dev,
+                        "An error occurred in the DASD device driver, "
+                        "reason=%s\n", errorstring);
                break;
        }                       /* end switch message format */
 
@@ -1015,7 +1025,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
        /* env data present (ACTION 10 - retry should work) */
        if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                            "Command Reject - environmental data present");
 
                dasd_3990_handle_env_data(erp, sense);
@@ -1023,9 +1033,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
                erp->retries = 5;
 
        } else {
-               /* fatal error -  set status to FAILED */
-               DEV_MESSAGE(KERN_ERR, device, "%s",
-                           "Command Reject - Fatal error");
+               /* fatal error -  set status to FAILED
+                  internal error 09 - Command Reject */
+               dev_err(&device->cdev->dev, "An error occurred in the DASD "
+                       "device driver, reason=%s\n", "09");
 
                erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
        }
@@ -1061,7 +1072,7 @@ dasd_3990_erp_bus_out(struct dasd_ccw_req * erp)
        } else {
 
                /* issue a message and wait for 'device ready' interrupt */
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                            "bus out parity error or BOPC requested by "
                            "channel");
 
@@ -1093,21 +1104,19 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
        erp->function = dasd_3990_erp_equip_check;
 
        if (sense[1] & SNS1_WRITE_INHIBITED) {
+               dev_info(&device->cdev->dev,
+                           "Write inhibited path encountered\n");
 
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
-                           "Write inhibited path encountered");
-
-               /* vary path offline */
-               DEV_MESSAGE(KERN_ERR, device, "%s",
-                           "Path should be varied off-line. "
-                           "This is not implemented yet \n - please report "
-                           "to linux390@de.ibm.com");
+               /* vary path offline
+                  internal error 04 - Path should be varied off-line.*/
+               dev_err(&device->cdev->dev, "An error occurred in the DASD "
+                       "device driver, reason=%s\n", "04");
 
                erp = dasd_3990_erp_action_1(erp);
 
        } else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                            "Equipment Check - " "environmental data present");
 
                dasd_3990_handle_env_data(erp, sense);
@@ -1116,7 +1125,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
 
        } else if (sense[1] & SNS1_PERM_ERR) {
 
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                            "Equipment Check - retry exhausted or "
                            "undesirable");
 
@@ -1125,7 +1134,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
        } else {
                /* all other equipment checks - Action 5 */
                /* rest is done when retries == 0 */
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                            "Equipment check or processing error");
 
                erp = dasd_3990_erp_action_5(erp);
@@ -1156,9 +1165,9 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
        if (sense[2] & SNS2_CORRECTABLE) {      /* correctable data check */
 
                /* issue message that the data has been corrected */
-               DEV_MESSAGE(KERN_EMERG, device, "%s",
+               dev_emerg(&device->cdev->dev,
                            "Data recovered during retry with PCI "
-                           "fetch mode active");
+                           "fetch mode active\n");
 
                /* not possible to handle this situation in Linux */
                panic("No way to inform application about the possibly "
@@ -1166,7 +1175,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
 
        } else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                            "Uncorrectable data check recovered secondary "
                            "addr of duplex pair");
 
@@ -1174,7 +1183,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
 
        } else if (sense[1] & SNS1_PERM_ERR) {
 
-               DEV_MESSAGE(KERN_DEBUG, device, "%s",
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                            "Uncorrectable data check with internal "
                            "retry exhausted");
 
@@ -1182,7 +1191,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)</