linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch/s390 00/46] s390 features patches for 2.6.30
@ 2009-02-25 15:06 Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 01/46] fix dump_stack vs. %p and (null) Martin Schwidefsky
                   ` (45 more replies)
  0 siblings, 46 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens

Greetings,
there are 46 patches in the features branch of git390 for the
upcoming merge window of 2.6.30. Three highlights:

 * A new shutdown action for automatic ipl after dump.
 * Large volume support for the dasd driver.
 * High performance ficon support for the dasd driver.

The other patches are the usual collection of non-critical bug
fixes and cleanups. As always nitpicks and reviews are welcome.

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 01/46] fix dump_stack vs. %p and (null)
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 02/46] Automatic IPL after dump Martin Schwidefsky
                   ` (44 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Christian Borntraeger, Martin Schwidefsky

[-- Attachment #1: 100-dump-stack.diff --]
[-- Type: text/plain, Size: 1900 bytes --]

From: Christian Borntraeger <borntraeger@de.ibm.com>

The s390 implemenation of dump_stack uses %p to display stack content.
Since d97106ab53f812910a62d18afb9dbe882819c1ba (Make %p print '(null)'
for NULL pointers) this causes a strange output for dump_stack:

[...]
Process basename (pid: 8822, task: 00000000b2ece038, ksp: 00000000b24d7b38)
04000000b5685c00 00000000b24d7760 0000000000000002 (null)
00000000b24d7800 00000000b24d7778 00000000b24d7778 00000000001052fe
(null) 00000000b24d7b38 (null) 000000000000000a
000000000000000d (null) 00000000b24d7760 00000000b24d77d8
000000000051a7e8 00000000001052fe 00000000b24d7760 00000000b24d77b0
Call Trace:
[...]

This patch changes our dump_stack to use the appropriate %x format.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/traps.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: quilt-2.6/arch/s390/kernel/traps.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/traps.c
+++ quilt-2.6/arch/s390/kernel/traps.c
@@ -61,9 +61,11 @@ extern pgm_check_handler_t do_asce_excep
 #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
 			break;
 		if (i && ((i * sizeof (long) % 32) == 0))
 			printk("\n       ");
-		printk("%p ", (void *)*stack++);
+		printk(LONG, *stack++);
 	}
 	printk("\n");
 	show_trace(task, sp);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 02/46] Automatic IPL after dump
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 01/46] fix dump_stack vs. %p and (null) Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 03/46] page fault: invoke oom-killer Martin Schwidefsky
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Frank Munzert, Martin Schwidefsky

[-- Attachment #1: 101-reipl-after-dump.diff --]
[-- Type: text/plain, Size: 13250 bytes --]

From: Frank Munzert <munzert@de.ibm.com>

Provide new shutdown action "dump_reipl" for automatic ipl after dump.

Signed-off-by: Frank Munzert <munzert@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

 arch/s390/include/asm/lowcore.h |   24 +++++-----
 arch/s390/include/asm/system.h  |   16 +++++++
 arch/s390/kernel/ipl.c          |   56 +++++++++++++++++++++++--
 arch/s390/kernel/setup.c        |    5 ++
 arch/s390/kernel/smp.c          |    9 ----
 drivers/s390/char/zcore.c       |   88 +++++++++++++++++++++++++++++++++++++++-
 6 files changed, 172 insertions(+), 26 deletions(-)

Index: quilt-2.6/arch/s390/include/asm/lowcore.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/lowcore.h
+++ quilt-2.6/arch/s390/include/asm/lowcore.h
@@ -111,7 +111,7 @@
 
 #define __LC_PASTE			0xE40
 
-#define __LC_PANIC_MAGIC		0xE00
+#define __LC_DUMP_REIPL			0xE00
 #ifndef __s390x__
 #define __LC_PFAULT_INTPARM             0x080
 #define __LC_CPU_TIMER_SAVE_AREA        0x0D8
@@ -286,12 +286,14 @@ struct _lowcore
 	__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 */
+	/* 0xe00 contains the address of the IPL Parameter */
+	/* Information block. Dump tools need IPIB for IPL */
+	/* after dump.					   */
+	__u32	     ipib;		       /* 0xe00 */
+	__u32	     ipib_checksum;	       /* 0xe04 */
 
         /* Align to the top 1k of prefix area */
-	__u8         pad12[0x1000-0xe04];      /* 0xe04 */
+	__u8	     pad12[0x1000-0xe08];      /* 0xe08 */
 #else /* !__s390x__ */
         /* prefix area: defined by architecture */
 	__u32        ccw1[2];                  /* 0x000 */
@@ -379,12 +381,14 @@ struct _lowcore
 	__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 */
+	/* 0xe00 contains the address of the IPL Parameter */
+	/* Information block. Dump tools need IPIB for IPL */
+	/* after dump.					   */
+	__u64	     ipib;		       /* 0xe00 */
+	__u32	     ipib_checksum;	       /* 0xe08 */
 
 	/* Per cpu primary space access list */
-	__u8	     pad_0xe04[0xe38-0xe04];   /* 0xe04 */
+	__u8	     pad_0xe0c[0xe38-0xe0c];   /* 0xe0c */
 	__u64	     vdso_per_cpu_data;	       /* 0xe38 */
 	__u32	     paste[16];		       /* 0xe40 */
 
@@ -433,8 +437,6 @@ static inline __u32 store_prefix(void)
 	return address;
 }
 
-#define __PANIC_MAGIC           0xDEADC0DE
-
 #endif
 
 #endif
Index: quilt-2.6/arch/s390/include/asm/system.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/system.h
+++ quilt-2.6/arch/s390/include/asm/system.h
@@ -458,6 +458,22 @@ static inline unsigned short stap(void)
 	return cpu_address;
 }
 
+static inline u32 cksm(void *addr, unsigned long len)
+{
+	register unsigned long _addr asm("0") = (unsigned long) addr;
+	register unsigned long _len asm("1") = len;
+	unsigned long accu = 0;
+
+	asm volatile(
+		"0:\n"
+		"	cksm	%0,%1\n"
+		"	jnz	0b\n"
+		: "+d" (accu), "+d" (_addr), "+d" (_len)
+		:
+		: "cc", "memory");
+	return accu;
+}
+
 extern void (*_machine_restart)(char *command);
 extern void (*_machine_halt)(void);
 extern void (*_machine_power_off)(void);
Index: quilt-2.6/arch/s390/kernel/ipl.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/ipl.c
+++ quilt-2.6/arch/s390/kernel/ipl.c
@@ -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 = RE
 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 
 			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 
 			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 
 			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;
@@ -1332,6 +1337,48 @@ static struct shutdown_action __refdata 
 	.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" (cksm(reipl_block_actual, reipl_block_actual->hdr.len)),
+		"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 +1468,8 @@ static struct shutdown_action stop_actio
 /* 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 +1482,11 @@ static int set_trigger(const char *buf, 
 		       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;
 		}
Index: quilt-2.6/arch/s390/kernel/setup.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/setup.c
+++ quilt-2.6/arch/s390/kernel/setup.c
@@ -86,6 +86,10 @@ volatile int __cpu_logical_map[NR_CPUS];
 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
@@ -434,6 +438,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
Index: quilt-2.6/arch/s390/kernel/smp.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/smp.c
+++ quilt-2.6/arch/s390/kernel/smp.c
@@ -50,12 +50,6 @@
 #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;
@@ -82,9 +76,6 @@ 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;
-
 	/* stop all processors */
 	for_each_online_cpu(cpu) {
 		if (cpu == smp_processor_id())
Index: quilt-2.6/drivers/s390/char/zcore.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/zcore.c
+++ quilt-2.6/drivers/s390/char/zcore.c
@@ -5,7 +5,7 @@
  *
  * For more information please refer to Documentation/s390/zfcpdump.txt
  *
- * Copyright IBM Corp. 2003,2007
+ * Copyright IBM Corp. 2003,2008
  * Author(s): Michael Holzheu
  */
 
@@ -48,12 +48,19 @@ struct sys_info {
 	union save_area	lc_mask;
 };
 
+struct ipib_info {
+	unsigned long	ipib;
+	u32		checksum;
+}  __attribute__((packed));
+
 static struct sys_info sys_info;
 static struct debug_info *zcore_dbf;
 static int hsa_available;
 static struct dentry *zcore_dir;
 static struct dentry *zcore_file;
 static struct dentry *zcore_memmap_file;
+static struct dentry *zcore_reipl_file;
+static struct ipl_parameter_block *ipl_block;
 
 /*
  * Copy memory from HSA to kernel or user memory (not reentrant):
@@ -527,6 +534,33 @@ static const struct file_operations zcor
 	.release	= zcore_memmap_release,
 };
 
+static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
+				 size_t count, loff_t *ppos)
+{
+	if (ipl_block) {
+		diag308(DIAG308_SET, ipl_block);
+		diag308(DIAG308_IPL, NULL);
+	}
+	return count;
+}
+
+static int zcore_reipl_open(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static int zcore_reipl_release(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static const struct file_operations zcore_reipl_fops = {
+	.owner		= THIS_MODULE,
+	.write		= zcore_reipl_write,
+	.open		= zcore_reipl_open,
+	.release	= zcore_reipl_release,
+};
+
 
 static void __init set_s390_lc_mask(union save_area *map)
 {
@@ -645,6 +679,39 @@ static int __init zcore_header_init(int 
 	return 0;
 }
 
+/*
+ * Provide IPL parameter information block from either HSA or memory
+ * for future reipl
+ */
+static int __init zcore_reipl_init(void)
+{
+	struct ipib_info ipib_info;
+	int rc;
+
+	rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
+	if (rc)
+		return rc;
+	if (ipib_info.ipib == 0)
+		return 0;
+	ipl_block = (void *) __get_free_page(GFP_KERNEL);
+	if (!ipl_block)
+		return -ENOMEM;
+	if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
+		rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
+	else
+		rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE);
+	if (rc) {
+		free_page((unsigned long) ipl_block);
+		return rc;
+	}
+	if (cksm(ipl_block, ipl_block->hdr.len) != ipib_info.checksum) {
+		TRACE("Checksum does not match\n");
+		free_page((unsigned long) ipl_block);
+		ipl_block = NULL;
+	}
+	return 0;
+}
+
 static int __init zcore_init(void)
 {
 	unsigned char arch;
@@ -690,6 +757,10 @@ static int __init zcore_init(void)
 	if (rc)
 		goto fail;
 
+	rc = zcore_reipl_init();
+	if (rc)
+		goto fail;
+
 	zcore_dir = debugfs_create_dir("zcore" , NULL);
 	if (!zcore_dir) {
 		rc = -ENOMEM;
@@ -707,9 +778,17 @@ static int __init zcore_init(void)
 		rc = -ENOMEM;
 		goto fail_file;
 	}
+	zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
+						NULL, &zcore_reipl_fops);
+	if (!zcore_reipl_file) {
+		rc = -ENOMEM;
+		goto fail_memmap_file;
+	}
 	hsa_available = 1;
 	return 0;
 
+fail_memmap_file:
+	debugfs_remove(zcore_memmap_file);
 fail_file:
 	debugfs_remove(zcore_file);
 fail_dir:
@@ -723,10 +802,15 @@ static void __exit zcore_exit(void)
 {
 	debug_unregister(zcore_dbf);
 	sclp_sdias_exit();
+	free_page((unsigned long) ipl_block);
+	debugfs_remove(zcore_reipl_file);
+	debugfs_remove(zcore_memmap_file);
+	debugfs_remove(zcore_file);
+	debugfs_remove(zcore_dir);
 	diag308(DIAG308_REL_HSA, NULL);
 }
 
-MODULE_AUTHOR("Copyright IBM Corp. 2003,2007");
+MODULE_AUTHOR("Copyright IBM Corp. 2003,2008");
 MODULE_DESCRIPTION("zcore module for zfcpdump support");
 MODULE_LICENSE("GPL");
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 03/46] page fault: invoke oom-killer
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 01/46] fix dump_stack vs. %p and (null) Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 02/46] Automatic IPL after dump Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 04/46] dasd: enable compat ioctls Martin Schwidefsky
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 102-oom.diff --]
[-- Type: text/plain, Size: 1968 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

s390 arch backend for 1c0fe6e3bda0464728c23c8d84aa47567e8b716c
"mm: invoke oom-killer from page fault".

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/mm/fault.c |   28 ++--------------------------
 1 file changed, 2 insertions(+), 26 deletions(-)

Index: quilt-2.6/arch/s390/mm/fault.c
===================================================================
--- quilt-2.6.orig/arch/s390/mm/fault.c
+++ quilt-2.6/arch/s390/mm/fault.c
@@ -200,29 +200,6 @@ static void do_low_address(struct pt_reg
 	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);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 04/46] dasd: enable compat ioctls
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (2 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 03/46] page fault: invoke oom-killer Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 05/46] dasd_eckd / Write format R0 is now allowed BB Martin Schwidefsky
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 103-dasd-ioctl.diff --]
[-- Type: text/plain, Size: 1805 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

All of the ioctls are compatible. Just enable them.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/block/dasd.c       |    3 ++-
 drivers/s390/block/dasd_ioctl.c |   17 ++++++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

Index: quilt-2.6/drivers/s390/block/dasd.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd.c
+++ quilt-2.6/drivers/s390/block/dasd.c
@@ -2101,7 +2101,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,
 };
 
Index: quilt-2.6/drivers/s390/block/dasd_ioctl.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_ioctl.c
+++ quilt-2.6/drivers/s390/block/dasd_ioctl.c
@@ -365,9 +365,9 @@ static int dasd_ioctl_readall_cmb(struct
 	return ret;
 }
 
-int
-dasd_ioctl(struct block_device *bdev, fmode_t mode,
-	   unsigned int cmd, unsigned long arg)
+static int
+dasd_do_ioctl(struct block_device *bdev, fmode_t mode,
+	      unsigned int cmd, unsigned long arg)
 {
 	struct dasd_block *block = bdev->bd_disk->private_data;
 	void __user *argp = (void __user *)arg;
@@ -420,3 +420,14 @@ dasd_ioctl(struct block_device *bdev, fm
 		return -EINVAL;
 	}
 }
+
+int dasd_ioctl(struct block_device *bdev, fmode_t mode,
+	       unsigned int cmd, unsigned long arg)
+{
+	int rc;
+
+	lock_kernel();
+	rc = dasd_do_ioctl(bdev, mode, cmd, arg);
+	unlock_kernel();
+	return rc;
+}

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 05/46] dasd_eckd / Write format R0 is now allowed BB
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (3 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 04/46] dasd: enable compat ioctls Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 06/46] dasd: add large volume support Martin Schwidefsky
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Jean-Baptiste Joret, Martin Schwidefsky

[-- Attachment #1: 104-dasd-track0.diff --]
[-- Type: text/plain, Size: 3480 bytes --]

From: Jean-Baptiste Joret <joret@de.ibm.com>

Permission is now granted to the subsystem to format write R0 with:
* an ID = CCHHR, where CC = physical cylinder number,
  HH = physical head number, and R = 0
* a key length of zero
* a data length of eight
* a data field containing all zeros

Signed-off-by: Jean-Baptiste Joret <joret@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/block/dasd_eckd.c |   25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

Index: quilt-2.6/drivers/s390/block/dasd_eckd.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_eckd.c
+++ quilt-2.6/drivers/s390/block/dasd_eckd.c
@@ -1265,6 +1265,8 @@ dasd_eckd_format_device(struct dasd_devi
 	int rpt, cyl, head;
 	int cplength, datasize;
 	int i;
+	int intensity = 0;
+	int r0_perm;
 
 	private = (struct dasd_eckd_private *) device->private;
 	rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
@@ -1296,9 +1298,17 @@ dasd_eckd_format_device(struct dasd_devi
 	 *   Bit 1: write home address, currently not supported
 	 *   Bit 2: invalidate tracks
 	 *   Bit 3: use OS/390 compatible disk layout (cdl)
+	 *   Bit 4: do not allow storage subsystem to modify record zero
 	 * Only some bit combinations do make sense.
 	 */
-	switch (fdata->intensity) {
+	if (fdata->intensity & 0x10) {
+		r0_perm = 0;
+		intensity = fdata->intensity & ~0x10;
+	} else {
+		r0_perm = 1;
+		intensity = fdata->intensity;
+	}
+	switch (intensity) {
 	case 0x00:	/* Normal format */
 	case 0x08:	/* Normal format, use cdl. */
 		cplength = 2 + rpt;
@@ -1335,11 +1345,14 @@ dasd_eckd_format_device(struct dasd_devi
 	data = fcp->data;
 	ccw = fcp->cpaddr;
 
-	switch (fdata->intensity & ~0x08) {
+	switch (intensity & ~0x08) {
 	case 0x00: /* Normal format. */
 		define_extent(ccw++, (struct DE_eckd_data *) data,
 			      fdata->start_unit, fdata->start_unit,
 			      DASD_ECKD_CCW_WRITE_CKD, device);
+		/* grant subsystem permission to format R0 */
+		if (r0_perm)
+			((struct DE_eckd_data *)data)->ga_extended |= 0x04;
 		data += sizeof(struct DE_eckd_data);
 		ccw[-1].flags |= CCW_FLAG_CC;
 		locate_record(ccw++, (struct LO_eckd_data *) data,
@@ -1373,7 +1386,7 @@ dasd_eckd_format_device(struct dasd_devi
 		data += sizeof(struct LO_eckd_data);
 		break;
 	}
-	if (fdata->intensity & 0x01) {	/* write record zero */
+	if (intensity & 0x01) {	/* write record zero */
 		ect = (struct eckd_count *) data;
 		data += sizeof(struct eckd_count);
 		ect->cyl = cyl;
@@ -1388,7 +1401,7 @@ dasd_eckd_format_device(struct dasd_devi
 		ccw->cda = (__u32)(addr_t) ect;
 		ccw++;
 	}
-	if ((fdata->intensity & ~0x08) & 0x04) {	/* erase track */
+	if ((intensity & ~0x08) & 0x04) {	/* erase track */
 		ect = (struct eckd_count *) data;
 		data += sizeof(struct eckd_count);
 		ect->cyl = cyl;
@@ -1411,14 +1424,14 @@ dasd_eckd_format_device(struct dasd_devi
 			ect->kl = 0;
 			ect->dl = fdata->blksize;
 			/* Check for special tracks 0-1 when formatting CDL */
-			if ((fdata->intensity & 0x08) &&
+			if ((intensity & 0x08) &&
 			    fdata->start_unit == 0) {
 				if (i < 3) {
 					ect->kl = 4;
 					ect->dl = sizes_trk0[i] - 4;
 				}
 			}
-			if ((fdata->intensity & 0x08) &&
+			if ((intensity & 0x08) &&
 			    fdata->start_unit == 1) {
 				ect->kl = 44;
 				ect->dl = LABEL_SIZE - 44;

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 06/46] dasd: add large volume support
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (4 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 05/46] dasd_eckd / Write format R0 is now allowed BB Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 07/46] dasd: message cleanup Martin Schwidefsky
                   ` (39 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Stefan Weinhuber, Martin Schwidefsky

[-- Attachment #1: 105-dasd-large-volume.diff --]
[-- Type: text/plain, Size: 20558 bytes --]

From: Stefan Weinhuber <wein@de.ibm.com>

The dasd device driver will now support ECKD devices with more then
65520 cylinders.
In the traditional ECKD adressing scheme each track is addressed
by a 16-bit cylinder and 16-bit head number. The new addressing
scheme makes use of the fact that the actual number of heads is
never larger then 15, so 12 bits of the head number can be redefined
to be part of the cylinder address.

Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/dasd.h    |   10 +--
 arch/s390/include/asm/vtoc.h    |   16 ++++-
 drivers/s390/block/dasd_eckd.c  |  126 +++++++++++++++++++++-------------------
 drivers/s390/block/dasd_eckd.h  |    9 ++
 drivers/s390/block/dasd_int.h   |    2 
 drivers/s390/block/dasd_ioctl.c |    4 -
 drivers/s390/block/dasd_proc.c  |    2 
 fs/partitions/ibm.c             |  101 ++++++++++++++++++++++----------
 8 files changed, 171 insertions(+), 99 deletions(-)

Index: quilt-2.6/arch/s390/include/asm/dasd.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/dasd.h
+++ quilt-2.6/arch/s390/include/asm/dasd.h
@@ -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: quilt-2.6/arch/s390/include/asm/vtoc.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/vtoc.h
+++ quilt-2.6/arch/s390/include/asm/vtoc.h
@@ -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: quilt-2.6/drivers/s390/block/dasd_eckd.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_eckd.c
+++ quilt-2.6/drivers/s390/block/dasd_eckd.c
@@ -159,6 +159,14 @@ recs_per_track(struct dasd_eckd_characte
 	return 0;
 }
 
+static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
+{
+	geo->cyl = (__u16) cyl;
+	geo->head = cyl >> 16;
+	geo->head <<= 4;
+	geo->head |= head;
+}
+
 static int
 check_XRC (struct ccw1         *de_ccw,
            struct DE_eckd_data *data,
@@ -186,11 +194,12 @@ check_XRC (struct ccw1         *de_ccw,
 }
 
 static int
-define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
-	      int totrk, int cmd, struct dasd_device * device)
+define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
+	      unsigned int totrk, int cmd, struct dasd_device *device)
 {
 	struct dasd_eckd_private *private;
-	struct ch_t geo, beg, end;
+	u32 begcyl, endcyl;
+	u16 heads, beghead, endhead;
 	int rc = 0;
 
 	private = (struct dasd_eckd_private *) device->private;
@@ -248,27 +257,24 @@ define_extent(struct ccw1 * ccw, struct 
 	    && !(private->uses_cdl && trk < 2))
 		data->ga_extended |= 0x40; /* Regular Data Format Mode */
 
-	geo.cyl = private->rdc_data.no_cyl;
-	geo.head = private->rdc_data.trk_per_cyl;
-	beg.cyl = trk / geo.head;
-	beg.head = trk % geo.head;
-	end.cyl = totrk / geo.head;
-	end.head = totrk % geo.head;
+	heads = private->rdc_data.trk_per_cyl;
+	begcyl = trk / heads;
+	beghead = trk % heads;
+	endcyl = totrk / heads;
+	endhead = totrk % heads;
 
 	/* check for sequential prestage - enhance cylinder range */
 	if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
 	    data->attributes.operation == DASD_SEQ_ACCESS) {
 
-		if (end.cyl + private->attrib.nr_cyl < geo.cyl)
-			end.cyl += private->attrib.nr_cyl;
+		if (endcyl + private->attrib.nr_cyl < private->real_cyl)
+			endcyl += private->attrib.nr_cyl;
 		else
-			end.cyl = (geo.cyl - 1);
+			endcyl = (private->real_cyl - 1);
 	}
 
-	data->beg_ext.cyl = beg.cyl;
-	data->beg_ext.head = beg.head;
-	data->end_ext.cyl = end.cyl;
-	data->end_ext.head = end.head;
+	set_ch_t(&data->beg_ext, begcyl, beghead);
+	set_ch_t(&data->end_ext, endcyl, endhead);
 	return rc;
 }
 
@@ -294,13 +300,14 @@ static int check_XRC_on_prefix(struct PF
 	return rc;
 }
 
-static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
-		  int totrk, int cmd, struct dasd_device *basedev,
-		  struct dasd_device *startdev)
+static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+		  unsigned int trk, unsigned int totrk, int cmd,
+		  struct dasd_device *basedev, struct dasd_device *startdev)
 {
 	struct dasd_eckd_private *basepriv, *startpriv;
 	struct DE_eckd_data *data;
-	struct ch_t geo, beg, end;
+	u32 begcyl, endcyl;
+	u16 heads, beghead, endhead;
 	int rc = 0;
 
 	basepriv = (struct dasd_eckd_private *) basedev->private;
@@ -374,33 +381,30 @@ static int prefix(struct ccw1 *ccw, stru
 	    && !(basepriv->uses_cdl && trk < 2))
 		data->ga_extended |= 0x40; /* Regular Data Format Mode */
 
-	geo.cyl = basepriv->rdc_data.no_cyl;
-	geo.head = basepriv->rdc_data.trk_per_cyl;
-	beg.cyl = trk / geo.head;
-	beg.head = trk % geo.head;
-	end.cyl = totrk / geo.head;
-	end.head = totrk % geo.head;
+	heads = basepriv->rdc_data.trk_per_cyl;
+	begcyl = trk / heads;
+	beghead = trk % heads;
+	endcyl = totrk / heads;
+	endhead = totrk % heads;
 
 	/* check for sequential prestage - enhance cylinder range */
 	if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
 	    data->attributes.operation == DASD_SEQ_ACCESS) {
 
-		if (end.cyl + basepriv->attrib.nr_cyl < geo.cyl)
-			end.cyl += basepriv->attrib.nr_cyl;
+		if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+			endcyl += basepriv->attrib.nr_cyl;
 		else
-			end.cyl = (geo.cyl - 1);
+			endcyl = (basepriv->real_cyl - 1);
 	}
 
-	data->beg_ext.cyl = beg.cyl;
-	data->beg_ext.head = beg.head;
-	data->end_ext.cyl = end.cyl;
-	data->end_ext.head = end.head;
+	set_ch_t(&data->beg_ext, begcyl, beghead);
+	set_ch_t(&data->end_ext, endcyl, endhead);
 	return rc;
 }
 
 static void
-locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
-	      int rec_on_trk, int no_rec, int cmd,
+locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
+	      unsigned int rec_on_trk, int no_rec, int cmd,
 	      struct dasd_device * device, int reclen)
 {
 	struct dasd_eckd_private *private;
@@ -493,10 +497,11 @@ locate_record(struct ccw1 *ccw, struct L
 	default:
 		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
 	}
-	data->seek_addr.cyl = data->search_arg.cyl =
-		trk / private->rdc_data.trk_per_cyl;
-	data->seek_addr.head = data->search_arg.head =
-		trk % private->rdc_data.trk_per_cyl;
+	set_ch_t(&data->seek_addr,
+		 trk / private->rdc_data.trk_per_cyl,
+		 trk % private->rdc_data.trk_per_cyl);
+	data->search_arg.cyl = data->seek_addr.cyl;
+	data->search_arg.head = data->seek_addr.head;
 	data->search_arg.record = rec_on_trk;
 }
 
@@ -1002,13 +1007,20 @@ dasd_eckd_check_characteristics(struct d
 			    "rc=%d", rc);
 		goto out_err3;
 	}
+	/* find the vaild cylinder size */
+	if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
+	    private->rdc_data.long_no_cyl)
+		private->real_cyl = private->rdc_data.long_no_cyl;
+	else
+		private->real_cyl = private->rdc_data.no_cyl;
+
 	DEV_MESSAGE(KERN_INFO, device,
 		    "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
 		    private->rdc_data.dev_type,
 		    private->rdc_data.dev_model,
 		    private->rdc_data.cu_type,
 		    private->rdc_data.cu_model.model,
-		    private->rdc_data.no_cyl,
+		    private->real_cyl,
 		    private->rdc_data.trk_per_cyl,
 		    private->rdc_data.sec_per_trk);
 	return 0;
@@ -1157,8 +1169,6 @@ dasd_eckd_end_analysis(struct dasd_block
 	}
 
 	private->uses_cdl = 1;
-	/* Calculate number of blocks/records per track. */
-	blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
 	/* Check Track 0 for Compatible Disk Layout */
 	count_area = NULL;
 	for (i = 0; i < 3; i++) {
@@ -1200,14 +1210,14 @@ dasd_eckd_end_analysis(struct dasd_block
 		block->s2b_shift++;
 
 	blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
-	block->blocks = (private->rdc_data.no_cyl *
+	block->blocks = (private->real_cyl *
 			  private->rdc_data.trk_per_cyl *
 			  blk_per_trk);
 
 	DEV_MESSAGE(KERN_INFO, device,
 		    "(%dkB blks): %dkB at %dkB/trk %s",
 		    (block->bp_block >> 10),
-		    ((private->rdc_data.no_cyl *
+		    ((private->real_cyl *
 		      private->rdc_data.trk_per_cyl *
 		      blk_per_trk * (block->bp_block >> 9)) >> 1),
 		    ((blk_per_trk * block->bp_block) >> 10),
@@ -1262,7 +1272,8 @@ dasd_eckd_format_device(struct dasd_devi
 	struct eckd_count *ect;
 	struct ccw1 *ccw;
 	void *data;
-	int rpt, cyl, head;
+	int rpt;
+	struct ch_t address;
 	int cplength, datasize;
 	int i;
 	int intensity = 0;
@@ -1270,24 +1281,25 @@ dasd_eckd_format_device(struct dasd_devi
 
 	private = (struct dasd_eckd_private *) device->private;
 	rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
-	cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;
-	head = fdata->start_unit % private->rdc_data.trk_per_cyl;
+	set_ch_t(&address,
+		 fdata->start_unit / private->rdc_data.trk_per_cyl,
+		 fdata->start_unit % private->rdc_data.trk_per_cyl);
 
 	/* Sanity checks. */
 	if (fdata->start_unit >=
-	    (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) {
-		DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!",
+	    (private->real_cyl * private->rdc_data.trk_per_cyl)) {
+		DEV_MESSAGE(KERN_INFO, device, "Track no %u too big!",
 			    fdata->start_unit);
 		return ERR_PTR(-EINVAL);
 	}
 	if (fdata->start_unit > fdata->stop_unit) {
-		DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.",
+		DEV_MESSAGE(KERN_INFO, device, "Track %u reached! ending.",
 			    fdata->start_unit);
 		return ERR_PTR(-EINVAL);
 	}
 	if (dasd_check_blocksize(fdata->blksize) != 0) {
 		DEV_MESSAGE(KERN_WARNING, device,
-			    "Invalid blocksize %d...terminating!",
+			    "Invalid blocksize %u...terminating!",
 			    fdata->blksize);
 		return ERR_PTR(-EINVAL);
 	}
@@ -1389,8 +1401,8 @@ dasd_eckd_format_device(struct dasd_devi
 	if (intensity & 0x01) {	/* write record zero */
 		ect = (struct eckd_count *) data;
 		data += sizeof(struct eckd_count);
-		ect->cyl = cyl;
-		ect->head = head;
+		ect->cyl = address.cyl;
+		ect->head = address.head;
 		ect->record = 0;
 		ect->kl = 0;
 		ect->dl = 8;
@@ -1404,8 +1416,8 @@ dasd_eckd_format_device(struct dasd_devi
 	if ((intensity & ~0x08) & 0x04) {	/* erase track */
 		ect = (struct eckd_count *) data;
 		data += sizeof(struct eckd_count);
-		ect->cyl = cyl;
-		ect->head = head;
+		ect->cyl = address.cyl;
+		ect->head = address.head;
 		ect->record = 1;
 		ect->kl = 0;
 		ect->dl = 0;
@@ -1418,8 +1430,8 @@ dasd_eckd_format_device(struct dasd_devi
 		for (i = 0; i < rpt; i++) {
 			ect = (struct eckd_count *) data;
 			data += sizeof(struct eckd_count);
-			ect->cyl = cyl;
-			ect->head = head;
+			ect->cyl = address.cyl;
+			ect->head = address.head;
 			ect->record = i + 1;
 			ect->kl = 0;
 			ect->dl = fdata->blksize;
Index: quilt-2.6/drivers/s390/block/dasd_eckd.h
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_eckd.h
+++ quilt-2.6/drivers/s390/block/dasd_eckd.h
@@ -48,6 +48,11 @@
 #define PSF_ORDER_PRSSD 0x18
 #define PSF_ORDER_SSC	0x1D
 
+/*
+ * Size that is reportet for large volumes in the old 16-bit no_cyl field
+ */
+#define LV_COMPAT_CYL 0xFFFE
+
 /*****************************************************************************
  * SECTION: Type Definitions
  ****************************************************************************/
@@ -228,7 +233,8 @@ struct dasd_eckd_characteristics {
 	__u8 factor7;
 	__u8 factor8;
 	__u8 reserved2[3];
-	__u8 reserved3[10];
+	__u8 reserved3[6];
+	__u32 long_no_cyl;
 } __attribute__ ((packed));
 
 /* elements of the configuration data */
@@ -406,6 +412,7 @@ struct dasd_eckd_private {
 	int uses_cdl;
 	struct attrib_data_t attrib;	/* e.g. cache operations */
 	struct dasd_rssd_features features;
+	u32 real_cyl;
 
 	/* alias managemnet */
 	struct dasd_uid uid;
Index: quilt-2.6/drivers/s390/block/dasd_int.h
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_int.h
+++ quilt-2.6/drivers/s390/block/dasd_int.h
@@ -378,7 +378,7 @@ struct dasd_block {
 	struct block_device *bdev;
 	atomic_t open_count;
 
-	unsigned long blocks;	   /* size of volume in blocks */
+	unsigned long long blocks; /* size of volume in blocks */
 	unsigned int bp_block;	   /* bytes per block */
 	unsigned int s2b_shift;	   /* log2 (bp_block/512) */
 
Index: quilt-2.6/drivers/s390/block/dasd_ioctl.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_ioctl.c
+++ quilt-2.6/drivers/s390/block/dasd_ioctl.c
@@ -146,7 +146,7 @@ static int dasd_format(struct dasd_block
 	}
 
 	DBF_DEV_EVENT(DBF_NOTICE, base,
-		      "formatting units %d to %d (%d B blocks) flags %d",
+		      "formatting units %u to %u (%u B blocks) flags %u",
 		      fdata->start_unit,
 		      fdata->stop_unit, fdata->blksize, fdata->intensity);
 
@@ -170,7 +170,7 @@ static int dasd_format(struct dasd_block
 		if (rc) {
 			if (rc != -ERESTARTSYS)
 				DEV_MESSAGE(KERN_ERR, base,
-					    " Formatting of unit %d failed "
+					    " Formatting of unit %u failed "
 					    "with rc = %d",
 					    fdata->start_unit, rc);
 			return rc;
Index: quilt-2.6/drivers/s390/block/dasd_proc.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_proc.c
+++ quilt-2.6/drivers/s390/block/dasd_proc.c
@@ -112,7 +112,7 @@ dasd_devices_show(struct seq_file *m, vo
 			seq_printf(m, "n/f	 ");
 		else
 			seq_printf(m,
-				   "at blocksize: %d, %ld blocks, %ld MB",
+				   "at blocksize: %d, %lld blocks, %lld MB",
 				   block->bp_block, block->blocks,
 				   ((block->bp_block >> 9) *
 				    block->blocks) >> 11);
Index: quilt-2.6/fs/partitions/ibm.c
===================================================================
--- quilt-2.6.orig/fs/partitions/ibm.c
+++ quilt-2.6/fs/partitions/ibm.c
@@ -21,20 +21,38 @@
  * compute the block number from a
  * cyl-cyl-head-head structure
  */
-static inline int
+static sector_t
 cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) {
-        return ptr->cc * geo->heads * geo->sectors +
-	       ptr->hh * geo->sectors;
+
+	sector_t cyl;
+	__u16 head;
+
+	/*decode cylinder and heads for large volumes */
+	cyl = ptr->hh & 0xFFF0;
+	cyl <<= 12;
+	cyl |= ptr->cc;
+	head = ptr->hh & 0x000F;
+	return cyl * geo->heads * geo->sectors +
+	       head * geo->sectors;
 }
 
 /*
  * compute the block number from a
  * cyl-cyl-head-head-block structure
  */
-static inline int
+static sector_t
 cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
-        return ptr->cc * geo->heads * geo->sectors +
-		ptr->hh * geo->sectors +
+
+	sector_t cyl;
+	__u16 head;
+
+	/*decode cylinder and heads for large volumes */
+	cyl = ptr->hh & 0xFFF0;
+	cyl <<= 12;
+	cyl |= ptr->cc;
+	head = ptr->hh & 0x000F;
+	return	cyl * geo->heads * geo->sectors +
+		head * geo->sectors +
 		ptr->b;
 }
 
@@ -43,14 +61,15 @@ cchhb2blk (struct vtoc_cchhb *ptr, struc
 int
 ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
-	int blocksize, offset, size,res;
-	loff_t i_size;
+	int blocksize, res;
+	loff_t i_size, offset, size, fmt_size;
 	dasd_information2_t *info;
 	struct hd_geometry *geo;
 	char type[5] = {0,};
 	char name[7] = {0,};
 	union label_t {
-		struct vtoc_volume_label vol;
+		struct vtoc_volume_label_cdl vol;
+		struct vtoc_volume_label_ldl lnx;
 		struct vtoc_cms_label cms;
 	} *label;
 	unsigned char *data;
@@ -85,14 +104,16 @@ ibm_partition(struct parsed_partitions *
 	if (data == NULL)
 		goto out_readerr;
 
-	strncpy (type, data, 4);
-	if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD")))
-		strncpy(name, data + 8, 6);
-	else
-		strncpy(name, data + 4, 6);
 	memcpy(label, data, sizeof(union label_t));
 	put_dev_sector(sect);
 
+	if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
+		strncpy(type, label->vol.vollbl, 4);
+		strncpy(name, label->vol.volid, 6);
+	} else {
+		strncpy(type, label->lnx.vollbl, 4);
+		strncpy(name, label->lnx.volid, 6);
+	}
 	EBCASC(type, 4);
 	EBCASC(name, 6);
 
@@ -110,36 +131,54 @@ ibm_partition(struct parsed_partitions *
 			/*
 			 * VM style CMS1 labeled disk
 			 */
+			blocksize = label->cms.block_size;
 			if (label->cms.disk_offset != 0) {
 				printk("CMS1/%8s(MDSK):", name);
 				/* disk is reserved minidisk */
-				blocksize = label->cms.block_size;
 				offset = label->cms.disk_offset;
 				size = (label->cms.block_count - 1)
 					* (blocksize >> 9);
 			} else {
 				printk("CMS1/%8s:", name);
 				offset = (info->label_block + 1);
-				size = i_size >> 9;
+				size = label->cms.block_count
+					* (blocksize >> 9);
 			}
+			put_partition(state, 1, offset*(blocksize >> 9),
+				      size-offset*(blocksize >> 9));
 		} else {
-			/*
-			 * Old style LNX1 or unlabeled disk
-			 */
-			if (strncmp(type, "LNX1", 4) == 0)
-				printk ("LNX1/%8s:", name);
-			else
+			if (strncmp(type, "LNX1", 4) == 0) {
+				printk("LNX1/%8s:", name);
+				if (label->lnx.ldl_version == 0xf2) {
+					fmt_size = label->lnx.formatted_blocks
+						* (blocksize >> 9);
+				} else if (!strcmp(info->type, "ECKD")) {
+					/* formated w/o large volume support */
+					fmt_size = geo->cylinders * geo->heads
+					      * geo->sectors * (blocksize >> 9);
+				} else {
+					/* old label and no usable disk geometry
+					 * (e.g. DIAG) */
+					fmt_size = i_size >> 9;
+				}
+				size = i_size >> 9;
+				if (fmt_size < size)
+					size = fmt_size;
+				offset = (info->label_block + 1);
+			} else {
+				/* unlabeled disk */
 				printk("(nonl)");
-			offset = (info->label_block + 1);
-			size = i_size >> 9;
-		}
-		put_partition(state, 1, offset*(blocksize >> 9),
+				size = i_size >> 9;
+				offset = (info->label_block + 1);
+			}
+			put_partition(state, 1, offset*(blocksize >> 9),
 				      size-offset*(blocksize >> 9));
+		}
 	} else if (info->format == DASD_FORMAT_CDL) {
 		/*
 		 * New style CDL formatted disk
 		 */
-		unsigned int blk;
+		sector_t blk;
 		int counter;
 
 		/*
@@ -166,7 +205,8 @@ ibm_partition(struct parsed_partitions *
 				/* skip FMT4 / FMT5 / FMT7 labels */
 				if (f1.DS1FMTID == _ascebc['4']
 				    || f1.DS1FMTID == _ascebc['5']
-				    || f1.DS1FMTID == _ascebc['7']) {
+				    || f1.DS1FMTID == _ascebc['7']
+				    || f1.DS1FMTID == _ascebc['9']) {
 					blk++;
 					data = read_dev_sector(bdev, blk *
 							       (blocksize/512),
@@ -174,8 +214,9 @@ ibm_partition(struct parsed_partitions *
 					continue;
 				}
 
-				/* only FMT1 valid at this point */
-				if (f1.DS1FMTID != _ascebc['1'])
+				/* only FMT1 and 8 labels valid at this point */
+				if (f1.DS1FMTID != _ascebc['1'] &&
+				    f1.DS1FMTID != _ascebc['8'])
 					break;
 
 				/* OK, we got valid partition data */

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 07/46] dasd: message cleanup
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (5 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 06/46] dasd: add large volume support Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 08/46] dasd: add High Performance FICON support Martin Schwidefsky
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Stefan Haberland, Martin Schwidefsky

[-- Attachment #1: 106-kmsg-dasd.diff --]
[-- Type: text/plain, Size: 93716 bytes --]

From: Stefan Haberland <stefan.haberland@de.ibm.com>

Moved some Messages into s390 debugfeature and changed remaining 
messages to use the dev_xxx and pr_xxx macros.

Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/block/dasd.c          |  159 ++++----
 drivers/s390/block/dasd_3990_erp.c |  730 ++++++++++++++++++-------------------
 drivers/s390/block/dasd_alias.c    |   10 
 drivers/s390/block/dasd_diag.c     |   57 +-
 drivers/s390/block/dasd_eckd.c     |  171 +++++---
 drivers/s390/block/dasd_erp.c      |   19 
 drivers/s390/block/dasd_fba.c      |   48 +-
 drivers/s390/block/dasd_int.h      |    6 
 drivers/s390/block/dasd_ioctl.c    |   27 -
 9 files changed, 650 insertions(+), 577 deletions(-)

Index: quilt-2.6/drivers/s390/block/dasd_3990_erp.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_3990_erp.c
+++ quilt-2.6/drivers/s390/block/dasd_3990_erp.c
@@ -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_cc
 	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_re
 	} 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
 
 	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
 		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 *
 					  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_r
 	/* 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_r
 	} 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_r
 			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_cc
 	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_cc
 			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_cc
 		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_cc
 		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_cc
 		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_re
 	/* 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_re
 		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_re
 	} 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_cc
 	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_cc
 
 	} 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_cc
 	} 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
 	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
 
 	} 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
 
 	} 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
 
 	} else {
 		/* all other data checks */
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Uncorrectable data check with retry count "
 			    "exhausted...");
 
@@ -1212,7 +1221,7 @@ dasd_3990_erp_overrun(struct dasd_ccw_re
 
 	erp->function = dasd_3990_erp_overrun;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "Overrun - service overrun or overrun"
 		    " error requested by channel");
 
@@ -1243,7 +1252,7 @@ dasd_3990_erp_inv_format(struct dasd_ccw
 
 	if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Track format error when destaging or "
 			    "staging data");
 
@@ -1252,8 +1261,10 @@ dasd_3990_erp_inv_format(struct dasd_ccw
 		erp = dasd_3990_erp_action_4(erp, sense);
 
 	} else {
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Invalid Track Format - Fatal error");
+		/* internal error 06 - The track format is not valid*/
+		dev_err(&device->cdev->dev,
+			"An error occurred in the DASD device driver, "
+			"reason=%s\n", "06");
 
 		erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 	}
@@ -1279,8 +1290,8 @@ dasd_3990_erp_EOC(struct dasd_ccw_req * 
 
 	struct dasd_device *device = default_erp->startdev;
 
-	DEV_MESSAGE(KERN_ERR, device, "%s",
-		    "End-of-Cylinder - must never happen");
+	dev_err(&device->cdev->dev,
+		"The cylinder data for accessing the DASD is inconsistent\n");
 
 	/* implement action 7 - BUG */
 	return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1306,7 +1317,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_r
 
 	erp->function = dasd_3990_erp_env_data;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s", "Environmental data present");
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Environmental data present");
 
 	dasd_3990_handle_env_data(erp, sense);
 
@@ -1339,8 +1350,8 @@ dasd_3990_erp_no_rec(struct dasd_ccw_req
 
 	struct dasd_device *device = default_erp->startdev;
 
-	DEV_MESSAGE(KERN_ERR, device, "%s",
-		    "No Record Found - Fatal error ");
+	dev_err(&device->cdev->dev,
+		    "The specified record was not found\n");
 
 	return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
 
@@ -1365,7 +1376,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_
 
 	struct dasd_device *device = erp->startdev;
 
-	DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected");
+	dev_err(&device->cdev->dev, "Accessing the DASD failed because of "
+		"a hardware error\n");
 
 	return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 
@@ -1394,7 +1406,7 @@ static struct dasd_ccw_req *dasd_3990_er
 	if (cqr->block &&
 	    (cqr->block->base != cqr->startdev)) {
 		if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
-			DEV_MESSAGE(KERN_ERR, cqr->startdev,
+			DBF_DEV_EVENT(DBF_ERR, cqr->startdev,
 				    "ERP on alias device for request %p,"
 				    " recover on base device %s", cqr,
 				    dev_name(&cqr->block->base->cdev->dev));
@@ -1511,7 +1523,7 @@ dasd_3990_erp_action_10_32(struct dasd_c
 	erp->retries = 256;
 	erp->function = dasd_3990_erp_action_10_32;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Perform logging requested");
 
 	return erp;
 
@@ -1549,7 +1561,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	char *LO_data;		/* LO_eckd_data_t */
 	struct ccw1 *ccw, *oldccw;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "Write not finished because of unexpected condition");
 
 	default_erp->function = dasd_3990_erp_action_1B_32;
@@ -1563,8 +1575,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 
 	/* for imprecise ending just do default erp */
 	if (sense[1] & 0x01) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Imprecise ending is set - just retry");
 
 		return default_erp;
@@ -1575,8 +1586,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	cpa = default_erp->refers->irb.scsw.cmd.cpa;
 
 	if (cpa == 0) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Unable to determine address of the CCW "
 			    "to be restarted");
 
@@ -1590,7 +1600,9 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 				     sizeof(struct LO_eckd_data), device);
 
 	if (IS_ERR(erp)) {
-		DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");
+		/* internal error 01 - Unable to allocate ERP */
+		dev_err(&device->cdev->dev, "An error occurred in the DASD "
+			"device driver, reason=%s\n", "01");
 		return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
 	}
 
@@ -1608,10 +1620,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	LO_data = erp->data + sizeof(struct DE_eckd_data);
 
 	if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "BUG - this should not happen");
-
+		/* should not */
 		return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
 	}
 
@@ -1701,7 +1710,7 @@ dasd_3990_update_1B(struct dasd_ccw_req 
 	char *LO_data;		/* struct LO_eckd_data */
 	struct ccw1 *ccw;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "Write not finished because of unexpected condition"
 		    " - follow on");
 
@@ -1714,8 +1723,7 @@ dasd_3990_update_1B(struct dasd_ccw_req 
 
 	/* for imprecise ending just do default erp */
 	if (sense[1] & 0x01) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Imprecise ending is set - just retry");
 
 		previous_erp->status = DASD_CQR_FILLED;
@@ -1728,10 +1736,10 @@ dasd_3990_update_1B(struct dasd_ccw_req 
 	cpa = previous_erp->irb.scsw.cmd.cpa;
 
 	if (cpa == 0) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
-			    "Unable to determine address of the CCW "
-			    "to be restarted");
+		/* internal error 02 -
+		   Unable to determine address of the CCW to be restarted */
+		dev_err(&device->cdev->dev, "An error occurred in the DASD "
+			"device driver, reason=%s\n", "02");
 
 		previous_erp->status = DASD_CQR_FAILED;
 
@@ -1744,10 +1752,7 @@ dasd_3990_update_1B(struct dasd_ccw_req 
 	LO_data = erp->data + sizeof(struct DE_eckd_data);
 
 	if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "BUG - this should not happen");
-
+		/* should not happen */
 		previous_erp->status = DASD_CQR_FAILED;
 
 		return previous_erp;
@@ -1935,14 +1940,13 @@ dasd_3990_erp_compound_config(struct das
 
 	if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) {
 
-		/* set to suspended duplex state then restart */
+		/* set to suspended duplex state then restart
+		   internal error 05 - Set device to suspended duplex state
+		   should be done */
 		struct dasd_device *device = erp->startdev;
-
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Set device to suspended duplex state should be "
-			    "done!\n"
-			    "This is not implemented yet (for compound ERP)"
-			    " - please report to linux390@de.ibm.com");
+		dev_err(&device->cdev->dev,
+			"An error occurred in the DASD device driver, "
+			"reason=%s\n", "05");
 
 	}
 
@@ -2012,15 +2016,14 @@ dasd_3990_erp_handle_sim(struct dasd_dev
 {
 	/* print message according to log or message to operator mode */
 	if ((sense[24] & DASD_SIM_MSG_TO_OP) || (sense[1] & 0x10)) {
-
 		/* print SIM SRC from RefCode */
-		DEV_MESSAGE(KERN_ERR, device, "SIM - SRC: "
-			    "%02x%02x%02x%02x", sense[22],
+		dev_err(&device->cdev->dev, "SIM - SRC: "
+			    "%02x%02x%02x%02x\n", sense[22],
 			    sense[23], sense[11], sense[12]);
 	} else if (sense[24] & DASD_SIM_LOG) {
 		/* print SIM SRC Refcode */
-		DEV_MESSAGE(KERN_WARNING, device, "SIM - SRC: "
-			    "%02x%02x%02x%02x", sense[22],
+		dev_warn(&device->cdev->dev, "log SIM - SRC: "
+			    "%02x%02x%02x%02x\n", sense[22],
 			    sense[23], sense[11], sense[12]);
 	}
 }
@@ -2063,14 +2066,14 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 		switch (sense[25]) {
 
 		case 0x00:	/* success - use default ERP for retries */
-		        DEV_MESSAGE(KERN_DEBUG, device, "%s",
+			DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
 				    "ERP called for successful request"
 				    " - just retry");
 			break;
 
 		case 0x01:	/* fatal error */
-			DEV_MESSAGE(KERN_ERR, device, "%s",
-				    "Retry not recommended - Fatal error");
+			dev_err(&device->cdev->dev,
+				    "ERP failed for the DASD\n");
 
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
@@ -2080,13 +2083,10 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			erp = dasd_3990_erp_int_req(erp);
 			break;
 
-		case 0x0F:  /* length mismatch during update write command */
-			DEV_MESSAGE(KERN_ERR, device, "%s",
-				    "update write command error - should not "
-				    "happen;\n"
-				    "Please send this message together with "
-				    "the above sense data to linux390@de."
-				    "ibm.com");
+		case 0x0F:  /* length mismatch during update write command
+			       internal error 08 - update write command error*/
+			dev_err(&device->cdev->dev, "An error occurred in the "
+				"DASD device driver, reason=%s\n", "08");
 
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
@@ -2095,13 +2095,12 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			erp = dasd_3990_erp_action_10_32(erp, sense);
 			break;
 
-		case 0x15:	/* next track outside defined extend */
-			DEV_MESSAGE(KERN_ERR, device, "%s",
-				    "next track outside defined extend - "
-				    "should not happen;\n"
-				    "Please send this message together with "
-				    "the above sense data to linux390@de."
-				    "ibm.com");
+		case 0x15:	/* next track outside defined extend
+				   internal error 07 - The next track is not
+				   within the defined storage extent */
+			dev_err(&device->cdev->dev,
+				"An error occurred in the DASD device driver, "
+				"reason=%s\n", "07");
 
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
@@ -2112,9 +2111,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			break;
 
 		case 0x1C:	/* invalid data */
-			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
@@ -2123,7 +2122,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			break;
 
 		case 0x1D:	/* state-change pending */
-			DEV_MESSAGE(KERN_DEBUG, device, "%s",
+			DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 				    "A State change pending condition exists "
 				    "for the subsystem or device");
 
@@ -2131,7 +2130,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			break;
 
 		case 0x1E:	/* busy */
-                        DEV_MESSAGE(KERN_DEBUG, device, "%s",
+			DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 				    "Busy condition exists "
 				    "for the subsystem or device");
                         erp = dasd_3990_erp_action_4(erp, sense);
@@ -2173,7 +2172,7 @@ dasd_3990_erp_control_check(struct dasd_
 
 	if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
 					   | SCHN_STAT_CHN_CTRL_CHK)) {
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "channel or interface control check");
 		erp = dasd_3990_erp_action_4(erp, NULL);
 	}
@@ -2252,12 +2251,12 @@ dasd_3990_erp_add_erp(struct dasd_ccw_re
 	erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device);
 	if (IS_ERR(erp)) {
                 if (cqr->retries <= 0) {
-		        DEV_MESSAGE(KERN_ERR, device, "%s",
+			DBF_DEV_EVENT(DBF_ERR, device, "%s",
 				    "Unable to allocate ERP request");
 			cqr->status = DASD_CQR_FAILED;
                         cqr->stopclk = get_clock ();
 		} else {
-                        DEV_MESSAGE (KERN_ERR, device,
+			DBF_DEV_EVENT(DBF_ERR, device,
                                      "Unable to allocate ERP request "
 				     "(%i retries left)",
                                      cqr->retries);
@@ -2471,7 +2470,7 @@ dasd_3990_erp_further_erp(struct dasd_cc
 					break;
 				}
 			default:
-				DEV_MESSAGE(KERN_DEBUG, device,
+				DBF_DEV_EVENT(DBF_WARNING, device,
 					    "invalid subcommand modifier 0x%x "
 					    "for Diagnostic Control Command",
 					    sense[25]);
@@ -2487,11 +2486,12 @@ dasd_3990_erp_further_erp(struct dasd_cc
 		erp = dasd_3990_erp_compound(erp, sense);
 
 	} else {
-		/* No retry left and no additional special handling */
-		/*necessary */
-		DEV_MESSAGE(KERN_ERR, device,
-			    "no retries left for erp %p - "
-			    "set status to FAILED", erp);
+		/*
+		 * No retry left and no additional special handling
+		 * necessary
+		 */
+		dev_err(&device->cdev->dev,
+			"ERP %p has run out of retries and failed\n", erp);
 
 		erp->status = DASD_CQR_FAILED;
 	}
@@ -2565,7 +2565,7 @@ dasd_3990_erp_handle_match_erp(struct da
 
 		} else {
 			/* simple retry	  */
-			DEV_MESSAGE(KERN_DEBUG, device,
+			DBF_DEV_EVENT(DBF_DEBUG, device,
 				    "%i retries left for erp %p",
 				    erp->retries, erp);
 
@@ -2609,13 +2609,13 @@ dasd_3990_erp_action(struct dasd_ccw_req
 
 	if (device->features & DASD_FEATURE_ERPLOG) {
 		/* print current erp_chain */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "ERP chain at BEGINNING of ERP-ACTION");
+		dev_err(&device->cdev->dev,
+			    "ERP chain at BEGINNING of ERP-ACTION\n");
 		for (temp_erp = cqr;
 		     temp_erp != NULL; temp_erp = temp_erp->refers) {
 
-			DEV_MESSAGE(KERN_ERR, device,
-				    "   erp %p (%02x) refers to %p",
+			dev_err(&device->cdev->dev,
+				    "ERP %p (%02x) refers to %p\n",
 				    temp_erp, temp_erp->status,
 				    temp_erp->refers);
 		}
@@ -2626,7 +2626,7 @@ dasd_3990_erp_action(struct dasd_ccw_req
 	    (cqr->irb.scsw.cmd.dstat ==
 	     (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
 
-		DEV_MESSAGE(KERN_DEBUG, device,
+		DBF_DEV_EVENT(DBF_DEBUG, device,
 			    "ERP called for successful request %p"
 			    " - NO ERP necessary", cqr);
 
@@ -2648,13 +2648,13 @@ dasd_3990_erp_action(struct dasd_ccw_req
 
 	if (device->features & DASD_FEATURE_ERPLOG) {
 		/* print current erp_chain */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "ERP chain at END of ERP-ACTION");
+		dev_err(&device->cdev->dev,
+			    "ERP chain at END of ERP-ACTION\n");
 		for (temp_erp = erp;
 		     temp_erp != NULL; temp_erp = temp_erp->refers) {
 
-			DEV_MESSAGE(KERN_ERR, device,
-				    "   erp %p (%02x) refers to %p",
+			dev_err(&device->cdev->dev,
+				    "ERP %p (%02x) refers to %p\n",
 				    temp_erp, temp_erp->status,
 				    temp_erp->refers);
 		}
@@ -2667,6 +2667,8 @@ dasd_3990_erp_action(struct dasd_ccw_req
 		list_add_tail(&erp->blocklist, &cqr->blocklist);
 	}
 
+
+
 	return erp;
 
 }				/* end dasd_3990_erp_action */
Index: quilt-2.6/drivers/s390/block/dasd_alias.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_alias.c
+++ quilt-2.6/drivers/s390/block/dasd_alias.c
@@ -503,7 +503,7 @@ static void lcu_update_work(struct work_
 	 */
 	spin_lock_irqsave(&lcu->lock, flags);
 	if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
-		DEV_MESSAGE(KERN_WARNING, device, "could not update"
+		DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
 			    " alias data in lcu (rc = %d), retry later", rc);
 		schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
 	} else {
@@ -859,12 +859,12 @@ void dasd_alias_handle_summary_unit_chec
 	private = (struct dasd_eckd_private *) device->private;
 
 	reason = irb->ecw[8];
-	DEV_MESSAGE(KERN_WARNING, device, "%s %x",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s %x",
 		    "eckd handle summary unit check: reason", reason);
 
 	lcu = private->lcu;
 	if (!lcu) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "device not ready to handle summary"
 			    " unit check (no lcu structure)");
 		return;
@@ -877,7 +877,7 @@ void dasd_alias_handle_summary_unit_chec
 	 * the next interrupt on a different device
 	 */
 	if (list_empty(&device->alias_list)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "device is in offline processing,"
 			    " don't do summary unit check handling");
 		spin_unlock(&lcu->lock);
@@ -885,7 +885,7 @@ void dasd_alias_handle_summary_unit_chec
 	}
 	if (lcu->suc_data.device) {
 		/* already scheduled or running */
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "previous instance of summary unit check worker"
 			    " still pending");
 		spin_unlock(&lcu->lock);
Index: quilt-2.6/drivers/s390/block/dasd.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd.c
+++ quilt-2.6/drivers/s390/block/dasd.c
@@ -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>
@@ -221,7 +224,7 @@ static int dasd_state_known_to_basic(str
 			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 +765,7 @@ static inline int dasd_check_cqr(struct 
 		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 +785,7 @@ int dasd_term_IO(struct dasd_ccw_req *cq
 {
 	struct dasd_device *device;
 	int retries, rc;
+	char errorstring[ERRORLENGTH];
 
 	/* Check the cqr */
 	rc = dasd_check_cqr(cqr);
@@ -815,10 +819,10 @@ int dasd_term_IO(struct dasd_ccw_req *cq
 				      "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 +840,7 @@ int dasd_start_IO(struct dasd_ccw_req *c
 {
 	struct dasd_device *device;
 	int rc;
+	char errorstring[ERRORLENGTH];
 
 	/* Check the cqr */
 	rc = dasd_check_cqr(cqr);
@@ -843,9 +848,8 @@ int dasd_start_IO(struct dasd_ccw_req *c
 		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);
+		dev_err(&device->cdev->dev, "start_IO run out of retries "
+			"and failed with request %s\n", cqr);
 		cqr->status = DASD_CQR_ERROR;
 		return -EIO;
 	}
@@ -862,11 +866,11 @@ int dasd_start_IO(struct dasd_ccw_req *c
 			      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 +880,21 @@ int dasd_start_IO(struct dasd_ccw_req *c
 		 * 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:
 	case -EIO:
-		DBF_DEV_EVENT(DBF_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
 			      "start_IO: 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;
 	}
@@ -996,11 +1002,11 @@ void dasd_int_handler(struct ccw_device 
 		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,10 +1015,6 @@ void dasd_int_handler(struct ccw_device 
 
 	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) &&
@@ -1055,8 +1057,7 @@ void dasd_int_handler(struct ccw_device 
 			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) &&
@@ -1071,18 +1072,23 @@ void dasd_int_handler(struct ccw_device 
 		}
 	} 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 +1099,6 @@ void dasd_int_handler(struct ccw_device 
 	    (!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 +1171,7 @@ static void __dasd_device_process_final_
 	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 +1192,11 @@ static void __dasd_device_process_final_
 			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 +1221,17 @@ static void __dasd_device_check_expire(s
 	    (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->expires/HZ), cqr);
 			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->expires/HZ),
+				cqr, cqr->retries);
 		}
 	}
 }
@@ -1290,10 +1293,9 @@ int dasd_flush_device_queue(struct dasd_
 			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 +1539,9 @@ int dasd_cancel_req(struct dasd_ccw_req 
 		/* 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 +1618,7 @@ static inline void __dasd_block_process_
 	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);
 }
@@ -2043,8 +2044,9 @@ static int dasd_open(struct block_device
 	}
 
 	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;
 	}
@@ -2144,14 +2146,14 @@ int dasd_generic_probe(struct ccw_device
 
 	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;
@@ -2167,9 +2169,7 @@ int dasd_generic_probe(struct ccw_device
 	    (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;
 }
@@ -2233,10 +2233,9 @@ int dasd_generic_set_online(struct ccw_d
 	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;
 		}
@@ -2257,10 +2256,9 @@ int dasd_generic_set_online(struct ccw_d
 	/* 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);
@@ -2269,9 +2267,8 @@ int dasd_generic_set_online(struct ccw_d
 
 	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)
@@ -2315,13 +2312,13 @@ int dasd_generic_set_offline(struct ccw_
 		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;
@@ -2394,8 +2391,10 @@ static struct dasd_ccw_req *dasd_generic
 	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;
 	}
 
@@ -2473,7 +2472,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: quilt-2.6/drivers/s390/block/dasd_diag.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_diag.c
+++ quilt-2.6/drivers/s390/block/dasd_diag.c
@@ -8,6 +8,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -144,8 +146,8 @@ dasd_diag_erp(struct dasd_device *device
 	mdsk_term_io(device);
 	rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
 	if (rc)
-		DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, "
-			    "rc=%d", rc);
+		dev_warn(&device->cdev->dev, "DIAG ERP failed with "
+			    "rc=%d\n", rc);
 }
 
 /* Start a given request at the device. Return zero on success, non-zero
@@ -160,7 +162,7 @@ dasd_start_diag(struct dasd_ccw_req * cq
 
 	device = cqr->startdev;
 	if (cqr->retries < 0) {
-		DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p "
+		DBF_DEV_EVENT(DBF_ERR, device, "DIAG start_IO: request %p "
 			    "- no retry left)", cqr);
 		cqr->status = DASD_CQR_ERROR;
 		return -EIO;
@@ -195,7 +197,7 @@ dasd_start_diag(struct dasd_ccw_req * cq
 		break;
 	default: /* Error condition */
 		cqr->status = DASD_CQR_QUEUED;
-		DEV_MESSAGE(KERN_WARNING, device, "dia250 returned rc=%d", rc);
+		DBF_DEV_EVENT(DBF_WARNING, device, "dia250 returned rc=%d", rc);
 		dasd_diag_erp(device);
 		rc = -EIO;
 		break;
@@ -249,7 +251,7 @@ dasd_ext_handler(__u16 code)
 	cqr = (struct dasd_ccw_req *) ip;
 	device = (struct dasd_device *) cqr->startdev;
 	if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-		DEV_MESSAGE(KERN_WARNING, device,
+		DBF_DEV_EVENT(DBF_WARNING, device,
 			    " magic number of dasd_ccw_req 0x%08X doesn't"
 			    " match discipline 0x%08X",
 			    cqr->magic, *(int *) (&device->discipline->name));
@@ -281,15 +283,11 @@ dasd_ext_handler(__u16 code)
 				rc = dasd_start_diag(next);
 				if (rc == 0)
 					expires = next->expires;
-				else if (rc != -EACCES)
-					DEV_MESSAGE(KERN_WARNING, device, "%s",
-						    "Interrupt fastpath "
-						    "failed!");
 			}
 		}
 	} else {
 		cqr->status = DASD_CQR_QUEUED;
-		DEV_MESSAGE(KERN_WARNING, device, "interrupt status for "
+		DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
 			    "request %p was %d (%d retries left)", cqr, status,
 			    cqr->retries);
 		dasd_diag_erp(device);
@@ -322,8 +320,9 @@ dasd_diag_check_device(struct dasd_devic
 	if (private == NULL) {
 		private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
 		if (private == NULL) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				"memory allocation failed for private data");
+			DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+				"Allocating memory for private DASD data "
+				      "failed\n");
 			return -ENOMEM;
 		}
 		ccw_device_get_id(device->cdev, &private->dev_id);
@@ -331,7 +330,7 @@ dasd_diag_check_device(struct dasd_devic
 	}
 	block = dasd_alloc_block();
 	if (IS_ERR(block)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "could not allocate dasd block structure");
 		device->private = NULL;
 		kfree(private);
@@ -347,7 +346,7 @@ dasd_diag_check_device(struct dasd_devic
 
 	rc = diag210((struct diag210 *) rdc_data);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device "
+		DBF_DEV_EVENT(DBF_WARNING, device, "failed to retrieve device "
 			    "information (rc=%d)", rc);
 		rc = -EOPNOTSUPP;
 		goto out;
@@ -362,8 +361,8 @@ dasd_diag_check_device(struct dasd_devic
 		private->pt_block = 2;
 		break;
 	default:
-		DEV_MESSAGE(KERN_WARNING, device, "unsupported device class "
-			    "(class=%d)", private->rdc_data.vdev_class);
+		dev_warn(&device->cdev->dev, "Device type %d is not supported "
+			    "in DIAG mode\n", private->rdc_data.vdev_class);
 		rc = -EOPNOTSUPP;
 		goto out;
 	}
@@ -380,7 +379,7 @@ dasd_diag_check_device(struct dasd_devic
 	/* figure out blocksize of device */
 	label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
 	if (label == NULL)  {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "No memory to allocate initialization request");
 		rc = -ENOMEM;
 		goto out;
@@ -404,8 +403,8 @@ dasd_diag_check_device(struct dasd_devic
 		private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
 		rc = dia250(&private->iob, RW_BIO);
 		if (rc == 3) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				"DIAG call failed");
+			dev_warn(&device->cdev->dev,
+				"A 64-bit DIAG call failed\n");
 			rc = -EOPNOTSUPP;
 			goto out_label;
 		}
@@ -414,8 +413,8 @@ dasd_diag_check_device(struct dasd_devic
 			break;
 	}
 	if (bsize > PAGE_SIZE) {
-		DEV_MESSAGE(KERN_WARNING, device, "device access failed "
-			    "(rc=%d)", rc);
+		dev_warn(&device->cdev->dev, "Accessing the DASD failed because"
+			 " of an incorrect format (rc=%d)\n", rc);
 		rc = -EIO;
 		goto out_label;
 	}
@@ -433,15 +432,15 @@ dasd_diag_check_device(struct dasd_devic
 		block->s2b_shift++;
 	rc = mdsk_init_io(device, block->bp_block, 0, NULL);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
-			"failed (rc=%d)", rc);
+		dev_warn(&device->cdev->dev, "DIAG initialization "
+			"failed with rc=%d\n", rc);
 		rc = -EIO;
 	} else {
-		DEV_MESSAGE(KERN_INFO, device,
-			    "(%ld B/blk): %ldkB",
-			    (unsigned long) block->bp_block,
-			    (unsigned long) (block->blocks <<
-				block->s2b_shift) >> 1);
+		dev_info(&device->cdev->dev,
+			 "New DASD with %ld byte/block, total size %ld KB\n",
+			 (unsigned long) block->bp_block,
+			 (unsigned long) (block->blocks <<
+					  block->s2b_shift) >> 1);
 	}
 out_label:
 	free_page((long) label);
@@ -595,7 +594,7 @@ static void
 dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		     struct irb *stat)
 {
-	DEV_MESSAGE(KERN_ERR, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "dump sense not available for DIAG data");
 }
 
Index: quilt-2.6/drivers/s390/block/dasd_eckd.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_eckd.c
+++ quilt-2.6/drivers/s390/block/dasd_eckd.c
@@ -11,6 +11,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -84,7 +86,7 @@ dasd_eckd_probe (struct ccw_device *cdev
 	/* set ECKD specific ccw-device options */
 	ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
 	if (ret) {
-		printk(KERN_WARNING
+		DBF_EVENT(DBF_WARNING,
 		       "dasd_eckd_probe: could not set ccw-device options "
 		       "for %s\n", dev_name(&cdev->dev));
 		return ret;
@@ -245,7 +247,8 @@ define_extent(struct ccw1 *ccw, struct D
 		rc = check_XRC (ccw, data, device);
 		break;
 	default:
-		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
+		dev_err(&device->cdev->dev,
+			"0x%x is not a known command\n", cmd);
 		break;
 	}
 
@@ -369,7 +372,8 @@ static int prefix(struct ccw1 *ccw, stru
 		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
 	default:
-		DEV_MESSAGE(KERN_ERR, basedev, "unknown opcode 0x%x", cmd);
+		DBF_DEV_EVENT(DBF_ERR, basedev, "unknown prefix opcode 0x%x",
+			      cmd);
 		break;
 	}
 
@@ -495,7 +499,8 @@ locate_record(struct ccw1 *ccw, struct L
 		data->operation.operation = 0x0b;
 		break;
 	default:
-		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
+		DBF_DEV_EVENT(DBF_ERR, device, "unknown locate record "
+			      "opcode 0x%x", cmd);
 	}
 	set_ch_t(&data->seek_addr,
 		 trk / private->rdc_data.trk_per_cyl,
@@ -590,8 +595,8 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device);
 
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "Could not allocate RCD request");
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "Could not allocate RCD request");
 		return cqr;
 	}
 
@@ -741,14 +746,16 @@ static int dasd_eckd_read_conf(struct da
 			rc = dasd_eckd_read_conf_lpm(device, &conf_data,
 						     &conf_len, lpm);
 			if (rc && rc != -EOPNOTSUPP) {	/* -EOPNOTSUPP is ok */
-				MESSAGE(KERN_WARNING,
-					"Read configuration data returned "
-					"error %d", rc);
+				DBF_EVENT(DBF_WARNING,
+					  "Read configuration data returned "
+					  "error %d for device: %s", rc,
+					  dev_name(&device->cdev->dev));
 				return rc;
 			}
 			if (conf_data == NULL) {
-				MESSAGE(KERN_WARNING, "%s", "No configuration "
-					"data retrieved");
+				DBF_EVENT(DBF_WARNING, "No configuration "
+					  "data retrieved for device: %s",
+					  dev_name(&device->cdev->dev));
 				continue;	/* no error */
 			}
 			/* save first valid configuration data */
@@ -795,8 +802,9 @@ static int dasd_eckd_read_features(struc
 				    sizeof(struct dasd_rssd_features)),
 				   device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "Could not allocate initialization request");
+		DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
+			  "request for device: %s",
+			  dev_name(&device->cdev->dev));
 		return PTR_ERR(cqr);
 	}
 	cqr->startdev = device;
@@ -856,7 +864,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 				  device);
 
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			   "Could not allocate PSF-SSC request");
 		return cqr;
 	}
@@ -918,10 +926,10 @@ static int dasd_eckd_validate_server(str
 	/* may be requested feature is not available on server,
 	 * therefore just report error and go ahead */
 	private = (struct dasd_eckd_private *) device->private;
-	DEV_MESSAGE(KERN_INFO, device,
-		    "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d",
-		    private->uid.vendor, private->uid.serial,
-		    private->uid.ssid, rc);
+	DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x "
+		  "returned rc=%d for device: %s",
+		  private->uid.vendor, private->uid.serial,
+		  private->uid.ssid, rc, dev_name(&device->cdev->dev));
 	/* RE-Read Configuration Data */
 	return dasd_eckd_read_conf(device);
 }
@@ -943,9 +951,9 @@ dasd_eckd_check_characteristics(struct d
 		private = kzalloc(sizeof(struct dasd_eckd_private),
 				  GFP_KERNEL | GFP_DMA);
 		if (private == NULL) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "memory allocation failed for private "
-				    "data");
+			dev_warn(&device->cdev->dev,
+				 "Allocating memory for private DASD data "
+				 "failed\n");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
@@ -970,8 +978,9 @@ dasd_eckd_check_characteristics(struct d
 	if (private->uid.type == UA_BASE_DEVICE) {
 		block = dasd_alloc_block();
 		if (IS_ERR(block)) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "could not allocate dasd block structure");
+			DBF_EVENT(DBF_WARNING, "could not allocate dasd "
+				  "block structure for device: %s",
+				  dev_name(&device->cdev->dev));
 			rc = PTR_ERR(block);
 			goto out_err1;
 		}
@@ -1002,9 +1011,9 @@ dasd_eckd_check_characteristics(struct d
 	memset(rdc_data, 0, sizeof(rdc_data));
 	rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device,
-			    "Read device characteristics returned "
-			    "rc=%d", rc);
+		DBF_EVENT(DBF_WARNING,
+			  "Read device characteristics failed, rc=%d for "
+			  "device: %s", rc, dev_name(&device->cdev->dev));
 		goto out_err3;
 	}
 	/* find the vaild cylinder size */
@@ -1014,15 +1023,15 @@ dasd_eckd_check_characteristics(struct d
 	else
 		private->real_cyl = private->rdc_data.no_cyl;
 
-	DEV_MESSAGE(KERN_INFO, device,
-		    "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
-		    private->rdc_data.dev_type,
-		    private->rdc_data.dev_model,
-		    private->rdc_data.cu_type,
-		    private->rdc_data.cu_model.model,
+	dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
+		 "with %d cylinders, %d heads, %d sectors\n",
+		 private->rdc_data.dev_type,
+		 private->rdc_data.dev_model,
+		 private->rdc_data.cu_type,
+		 private->rdc_data.cu_model.model,
 		    private->real_cyl,
-		    private->rdc_data.trk_per_cyl,
-		    private->rdc_data.sec_per_trk);
+		 private->rdc_data.trk_per_cyl,
+		 private->rdc_data.sec_per_trk);
 	return 0;
 
 out_err3:
@@ -1163,8 +1172,8 @@ dasd_eckd_end_analysis(struct dasd_block
 	status = private->init_cqr_status;
 	private->init_cqr_status = -1;
 	if (status != DASD_CQR_DONE) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "volume analysis returned unformatted disk");
+		dev_warn(&device->cdev->dev,
+			    "The DASD is not formatted\n");
 		return -EMEDIUMTYPE;
 	}
 
@@ -1192,8 +1201,8 @@ dasd_eckd_end_analysis(struct dasd_block
 			count_area = &private->count_area[0];
 	} else {
 		if (private->count_area[3].record == 1)
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "Trk 0: no records after VTOC!");
+			dev_warn(&device->cdev->dev,
+				 "Track 0 has no records following the VTOC\n");
 	}
 	if (count_area != NULL && count_area->kl == 0) {
 		/* we found notthing violating our disk layout */
@@ -1201,8 +1210,8 @@ dasd_eckd_end_analysis(struct dasd_block
 			block->bp_block = count_area->dl;
 	}
 	if (block->bp_block == 0) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "Volume has incompatible disk layout");
+		dev_warn(&device->cdev->dev,
+			 "The disk layout of the DASD is not supported\n");
 		return -EMEDIUMTYPE;
 	}
 	block->s2b_shift = 0;	/* bits to shift 512 to get a block */
@@ -1214,15 +1223,15 @@ dasd_eckd_end_analysis(struct dasd_block
 			  private->rdc_data.trk_per_cyl *
 			  blk_per_trk);
 
-	DEV_MESSAGE(KERN_INFO, device,
-		    "(%dkB blks): %dkB at %dkB/trk %s",
-		    (block->bp_block >> 10),
-		    ((private->real_cyl *
-		      private->rdc_data.trk_per_cyl *
-		      blk_per_trk * (block->bp_block >> 9)) >> 1),
-		    ((blk_per_trk * block->bp_block) >> 10),
-		    private->uses_cdl ?
-		    "compatible disk layout" : "linux disk layout");
+	dev_info(&device->cdev->dev,
+		 "DASD with %d KB/block, %d KB total size, %d KB/track, "
+		 "%s\n", (block->bp_block >> 10),
+		 ((private->real_cyl *
+		   private->rdc_data.trk_per_cyl *
+		   blk_per_trk * (block->bp_block >> 9)) >> 1),
+		 ((blk_per_trk * block->bp_block) >> 10),
+		 private->uses_cdl ?
+		 "compatible disk layout" : "linux disk layout");
 
 	return 0;
 }
@@ -1288,19 +1297,19 @@ dasd_eckd_format_device(struct dasd_devi
 	/* Sanity checks. */
 	if (fdata->start_unit >=
 	    (private->real_cyl * private->rdc_data.trk_per_cyl)) {
-		DEV_MESSAGE(KERN_INFO, device, "Track no %u too big!",
-			    fdata->start_unit);
+		dev_warn(&device->cdev->dev, "Start track number %d used in "
+			 "formatting is too big\n", fdata->start_unit);
 		return ERR_PTR(-EINVAL);
 	}
 	if (fdata->start_unit > fdata->stop_unit) {
-		DEV_MESSAGE(KERN_INFO, device, "Track %u reached! ending.",
-			    fdata->start_unit);
+		dev_warn(&device->cdev->dev, "Start track %d used in "
+			 "formatting exceeds end track\n", fdata->start_unit);
 		return ERR_PTR(-EINVAL);
 	}
 	if (dasd_check_blocksize(fdata->blksize) != 0) {
-		DEV_MESSAGE(KERN_WARNING, device,
-			    "Invalid blocksize %u...terminating!",
-			    fdata->blksize);
+		dev_warn(&device->cdev->dev,
+			 "The DASD cannot be formatted with block size %d\n",
+			 fdata->blksize);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -1344,8 +1353,8 @@ dasd_eckd_format_device(struct dasd_devi
 			sizeof(struct eckd_count);
 		break;
 	default:
-		DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
-			    fdata->intensity);
+		dev_warn(&device->cdev->dev, "An I/O control call used "
+			 "incorrect flags 0x%x\n", fdata->intensity);
 		return ERR_PTR(-EINVAL);
 	}
 	/* Allocate the format ccw request. */
@@ -1539,13 +1548,14 @@ static void dasd_eckd_handle_unsolicited
 
 	if (!(irb->esw.esw0.erw.cons)) {
 		/* just report other unsolicited interrupts */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_ERR, device, "%s",
 			    "unsolicited interrupt received");
 	} else {
-		DEV_MESSAGE(KERN_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_ERR, device, "%s",
 			    "unsolicited interrupt received "
 			    "(sense available)");
-		device->discipline->dump_sense(device, NULL, irb);
+		device->discipline->dump_sense_dbf(device, NULL, irb,
+						   "unsolicited");
 	}
 
 	dasd_schedule_device_bh(device);
@@ -1893,7 +1903,7 @@ dasd_eckd_release(struct dasd_device *de
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
@@ -1934,7 +1944,7 @@ dasd_eckd_reserve(struct dasd_device *de
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
@@ -1974,7 +1984,7 @@ dasd_eckd_steal_lock(struct dasd_device 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
@@ -2015,7 +2025,7 @@ dasd_eckd_performance(struct dasd_device
 				    sizeof(struct dasd_rssd_perf_stats_t)),
 				   device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
@@ -2105,9 +2115,9 @@ dasd_eckd_set_attrib(struct dasd_device 
 		return -EFAULT;
 	private->attrib = attrib;
 
-	DEV_MESSAGE(KERN_INFO, device,
-		    "cache operation mode set to %x (%i cylinder prestage)",
-		    private->attrib.operation, private->attrib.nr_cyl);
+	dev_info(&device->cdev->dev,
+		 "The DASD cache mode was set to %x (%i cylinder prestage)\n",
+		 private->attrib.operation, private->attrib.nr_cyl);
 	return 0;
 }
 
@@ -2158,7 +2168,7 @@ static int dasd_symm_io(struct dasd_devi
 	/* setup CCWs for PSF + RSSD */
 	cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			"Could not allocate initialization request");
 		rc = PTR_ERR(cqr);
 		goto out_free;
@@ -2267,6 +2277,24 @@ dasd_eckd_dump_ccw_range(struct ccw1 *fr
 	return len;
 }
 
+static void
+dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+			 struct irb *irb, char *reason)
+{
+	int sl;
+	if (irb->esw.esw0.erw.cons) {
+		for (sl = 0; sl < 4; sl++) {
+			DBF_DEV_EVENT(DBF_EMERG, device,
+				      "%s: %08x %08x %08x %08x",
+				      reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
+				      irb->ecw[8 * 2], irb->ecw[8 * 3]);
+		}
+	} else {
+		DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+			      "SORRY - NO VALID SENSE AVAILABLE\n");
+	}
+}
+
 /*
  * Print sense data and related channel program.
  * Parts are printed because printk buffer is only 1024 bytes.
@@ -2280,8 +2308,8 @@ static void dasd_eckd_dump_sense(struct 
 
 	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		DEV_MESSAGE(KERN_ERR, device, " %s",
-			    "No memory to dump sense data");
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "No memory to dump sense data\n");
 		return;
 	}
 	/* dump the sense data */
@@ -2400,6 +2428,7 @@ static struct dasd_discipline dasd_eckd_
 	.build_cp = dasd_eckd_build_alias_cp,
 	.free_cp = dasd_eckd_free_alias_cp,
 	.dump_sense = dasd_eckd_dump_sense,
+	.dump_sense_dbf = dasd_eckd_dump_sense_dbf,
 	.fill_info = dasd_eckd_fill_info,
 	.ioctl = dasd_eckd_ioctl,
 };
Index: quilt-2.6/drivers/s390/block/dasd_erp.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_erp.c
+++ quilt-2.6/drivers/s390/block/dasd_erp.c
@@ -91,14 +91,14 @@ dasd_default_erp_action(struct dasd_ccw_
 
         /* just retry - there is nothing to save ... I got no sense data.... */
         if (cqr->retries > 0) {
-		DEV_MESSAGE (KERN_DEBUG, device,
+		DBF_DEV_EVENT(DBF_DEBUG, device,
                              "default ERP called (%i retries left)",
                              cqr->retries);
 		cqr->lpm    = LPM_ANYPATH;
 		cqr->status = DASD_CQR_FILLED;
         } else {
-                DEV_MESSAGE (KERN_WARNING, device, "%s",
-			     "default ERP called (NO retry left)");
+		dev_warn(&device->cdev->dev,
+			     "default ERP called (NO retry left)\n");
 		cqr->status = DASD_CQR_FAILED;
 		cqr->stopclk = get_clock();
         }
@@ -162,8 +162,21 @@ dasd_log_sense(struct dasd_ccw_req *cqr,
 		device->discipline->dump_sense(device, cqr, irb);
 }
 
+void
+dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb)
+{
+	struct dasd_device *device;
+
+	device = cqr->startdev;
+	/* dump sense data to s390 debugfeature*/
+	if (device->discipline && device->discipline->dump_sense_dbf)
+		device->discipline->dump_sense_dbf(device, cqr, irb, "log");
+}
+EXPORT_SYMBOL(dasd_log_sense_dbf);
+
 EXPORT_SYMBOL(dasd_default_erp_action);
 EXPORT_SYMBOL(dasd_default_erp_postaction);
 EXPORT_SYMBOL(dasd_alloc_erp_request);
 EXPORT_SYMBOL(dasd_free_erp_request);
 EXPORT_SYMBOL(dasd_log_sense);
+
Index: quilt-2.6/drivers/s390/block/dasd_fba.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_fba.c
+++ quilt-2.6/drivers/s390/block/dasd_fba.c
@@ -128,17 +128,17 @@ dasd_fba_check_characteristics(struct da
 		private = kzalloc(sizeof(struct dasd_fba_private),
 				  GFP_KERNEL | GFP_DMA);
 		if (private == NULL) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "memory allocation failed for private "
-				    "data");
+			dev_warn(&device->cdev->dev,
+				 "memory allocation failed for private data");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
 	}
 	block = dasd_alloc_block();
 	if (IS_ERR(block)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "could not allocate dasd block structure");
+		DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
+			  "structure for device: %s",
+			  dev_name(&device->cdev->dev));
 		device->private = NULL;
 		kfree(private);
 		return PTR_ERR(block);
@@ -150,9 +150,9 @@ dasd_fba_check_characteristics(struct da
 	rdc_data = (void *) &(private->rdc_data);
 	rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device,
-			    "Read device characteristics returned error %d",
-			    rc);
+		DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
+			  "error %d for device: %s",
+			  rc, dev_name(&device->cdev->dev));
 		device->block = NULL;
 		dasd_free_block(block);
 		device->private = NULL;
@@ -160,7 +160,7 @@ dasd_fba_check_characteristics(struct da
 		return rc;
 	}
 
-	DEV_MESSAGE(KERN_INFO, device,
+	dev_info(&device->cdev->dev,
 		    "%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)",
 		    cdev->id.dev_type,
 		    cdev->id.dev_model,
@@ -180,7 +180,7 @@ static int dasd_fba_do_analysis(struct d
 	private = (struct dasd_fba_private *) block->base->private;
 	rc = dasd_check_blocksize(private->rdc_data.blk_size);
 	if (rc) {
-		DEV_MESSAGE(KERN_INFO, block->base, "unknown blocksize %d",
+		DBF_DEV_EVENT(DBF_WARNING, block->base, "unknown blocksize %d",
 			    private->rdc_data.blk_size);
 		return rc;
 	}
@@ -215,7 +215,7 @@ dasd_fba_erp_postaction(struct dasd_ccw_
 	if (cqr->function == dasd_default_erp_action)
 		return dasd_default_erp_postaction;
 
-	DEV_MESSAGE(KERN_WARNING, cqr->startdev, "unknown ERP action %p",
+	DBF_DEV_EVENT(DBF_WARNING, cqr->startdev, "unknown ERP action %p",
 		    cqr->function);
 	return NULL;
 }
@@ -233,9 +233,9 @@ static void dasd_fba_handle_unsolicited_
 	}
 
 	/* check for unsolicited interrupts */
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "unsolicited interrupt received");
-	device->discipline->dump_sense(device, NULL, irb);
+	device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited");
 	dasd_schedule_device_bh(device);
 	return;
 };
@@ -437,6 +437,25 @@ dasd_fba_fill_info(struct dasd_device * 
 }
 
 static void
+dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+			 struct irb *irb, char *reason)
+{
+	int sl;
+	if (irb->esw.esw0.erw.cons) {
+		for (sl = 0; sl < 4; sl++) {
+			DBF_DEV_EVENT(DBF_EMERG, device,
+				      "%s: %08x %08x %08x %08x",
+				      reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
+				      irb->ecw[8 * 2], irb->ecw[8 * 3]);
+		}
+	} else {
+		DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+			      "SORRY - NO VALID SENSE AVAILABLE\n");
+	}
+}
+
+
+static void
 dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		    struct irb *irb)
 {
@@ -446,7 +465,7 @@ dasd_fba_dump_sense(struct dasd_device *
 
 	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		DEV_MESSAGE(KERN_ERR, device, " %s",
+		dev_err(&device->cdev->dev,
 			    "No memory to dump sense data");
 		return;
 	}
@@ -576,6 +595,7 @@ static struct dasd_discipline dasd_fba_d
 	.build_cp = dasd_fba_build_cp,
 	.free_cp = dasd_fba_free_cp,
 	.dump_sense = dasd_fba_dump_sense,
+	.dump_sense_dbf = dasd_fba_dump_sense_dbf,
 	.fill_info = dasd_fba_fill_info,
 };
 
Index: quilt-2.6/drivers/s390/block/dasd_int.h
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_int.h
+++ quilt-2.6/drivers/s390/block/dasd_int.h
@@ -112,6 +112,9 @@ do { \
 				d_data); \
 } while(0)
 
+/* limit size for an errorstring */
+#define ERRORLENGTH 30
+
 /* definition of dbf debug levels */
 #define	DBF_EMERG	0	/* system is unusable			*/
 #define	DBF_ALERT	1	/* action must be taken immediately	*/
@@ -280,6 +283,8 @@ struct dasd_discipline {
 	dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
 	void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
 			    struct irb *);
+	void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *,
+			    struct irb *, char *);
 
 	void (*handle_unsolicited_interrupt) (struct dasd_device *,
 					      struct irb *);
@@ -623,6 +628,7 @@ struct dasd_ccw_req *dasd_alloc_erp_requ
 					    struct dasd_device *);
 void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
 void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
+void dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb);
 
 /* externals in dasd_3990_erp.c */
 struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *);
Index: quilt-2.6/drivers/s390/block/dasd_ioctl.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_ioctl.c
+++ quilt-2.6/drivers/s390/block/dasd_ioctl.c
@@ -9,6 +9,9 @@
  *
  * i/o controls for the dasd driver.
  */
+
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/interrupt.h>
 #include <linux/major.h>
 #include <linux/fs.h>
@@ -94,7 +97,8 @@ static int dasd_ioctl_quiesce(struct das
 	if (!capable (CAP_SYS_ADMIN))
 		return -EACCES;
 
-	DEV_MESSAGE(KERN_DEBUG, base, "%s", "Quiesce IO on device");
+	dev_info(&base->cdev->dev, "The DASD has been put in the quiesce "
+		 "state\n");
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
 	base->stopped |= DASD_STOPPED_QUIESCE;
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -103,7 +107,7 @@ static int dasd_ioctl_quiesce(struct das
 
 
 /*
- * Quiesce device.
+ * Resume device.
  */
 static int dasd_ioctl_resume(struct dasd_block *block)
 {
@@ -114,7 +118,8 @@ static int dasd_ioctl_resume(struct dasd
 	if (!capable (CAP_SYS_ADMIN))
 		return -EACCES;
 
-	DEV_MESSAGE(KERN_DEBUG, base, "%s", "resume IO on device");
+	dev_info(&base->cdev->dev, "I/O operations have been resumed "
+		 "on the DASD\n");
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
 	base->stopped &= ~DASD_STOPPED_QUIESCE;
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -140,8 +145,8 @@ static int dasd_format(struct dasd_block
 		return -EPERM;
 
 	if (base->state != DASD_STATE_BASIC) {
-		DEV_MESSAGE(KERN_WARNING, base, "%s",
-			    "dasd_format: device is not disabled! ");
+		dev_warn(&base->cdev->dev,
+			 "The DASD cannot be formatted while it is enabled\n");
 		return -EBUSY;
 	}
 
@@ -169,10 +174,9 @@ static int dasd_format(struct dasd_block
 		dasd_sfree_request(cqr, cqr->memdev);
 		if (rc) {
 			if (rc != -ERESTARTSYS)
-				DEV_MESSAGE(KERN_ERR, base,
-					    " Formatting of unit %u failed "
-					    "with rc = %d",
-					    fdata->start_unit, rc);
+				dev_err(&base->cdev->dev,
+					"Formatting unit %d failed with "
+					"rc=%d\n", fdata->start_unit, rc);
 			return rc;
 		}
 		fdata->start_unit++;
@@ -199,8 +203,9 @@ dasd_ioctl_format(struct block_device *b
 	if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
 		return -EFAULT;
 	if (bdev != bdev->bd_contains) {
-		DEV_MESSAGE(KERN_WARNING, block->base, "%s",
-			    "Cannot low-level format a partition");
+		dev_warn(&block->base->cdev->dev,
+			 "The specified DASD is a partition and cannot be "
+			 "formatted\n");
 		return -EINVAL;
 	}
 	return dasd_format(block, &fdata);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 08/46] dasd: add High Performance FICON support
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (6 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 07/46] dasd: message cleanup Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 09/46] move sysinfo.c from drivers/s390 to arch/s390/kernel Martin Schwidefsky
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Stefan Weinhuber, Martin Schwidefsky

[-- Attachment #1: 107-dasd-hpf.diff --]
[-- Type: text/plain, Size: 63993 bytes --]

From: Stefan Weinhuber <wein@de.ibm.com>

To support High Performance FICON, the DASD device driver has to
translate I/O requests into the new transport mode control words (TCW)
instead of the traditional (command mode) CCW requests.

Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/idals.h      |   17 
 drivers/s390/block/dasd.c          |   70 ++
 drivers/s390/block/dasd_3990_erp.c |  141 +++--
 drivers/s390/block/dasd_alias.c    |   25 
 drivers/s390/block/dasd_devmap.c   |    7 
 drivers/s390/block/dasd_eckd.c     |  970 +++++++++++++++++++++++++++++++++----
 drivers/s390/block/dasd_eckd.h     |   40 +
 drivers/s390/block/dasd_eer.c      |   21 
 drivers/s390/block/dasd_int.h      |    5 
 9 files changed, 1121 insertions(+), 175 deletions(-)

Index: quilt-2.6/arch/s390/include/asm/idals.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/idals.h
+++ quilt-2.6/arch/s390/include/asm/idals.h
@@ -44,24 +44,18 @@ idal_is_needed(void *vaddr, unsigned int
 /*
  * 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, 
 		paddr += IDA_BLOCK_SIZE;
 		*idaws++ = paddr;
 	}
-#endif
 	return idaws;
 }
 
Index: quilt-2.6/drivers/s390/block/dasd_3990_erp.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_3990_erp.c
+++ quilt-2.6/drivers/s390/block/dasd_3990_erp.c
@@ -1573,6 +1573,13 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 		cqr = cqr->refers;
 	}
 
+	if (scsw_is_tm(&cqr->irb.scsw)) {
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "32 bit sense, action 1B is not defined"
+			      " in transport mode - just retry");
+		return default_erp;
+	}
+
 	/* for imprecise ending just do default erp */
 	if (sense[1] & 0x01) {
 		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
@@ -1611,7 +1618,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	oldccw = cqr->cpaddr;
 	if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
 		PFX_data = cqr->data;
-		memcpy(DE_data, &PFX_data->define_extend,
+		memcpy(DE_data, &PFX_data->define_extent,
 		       sizeof(struct DE_eckd_data));
 	} else
 		memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
@@ -1721,6 +1728,13 @@ dasd_3990_update_1B(struct dasd_ccw_req 
 		cqr = cqr->refers;
 	}
 
+	if (scsw_is_tm(&cqr->irb.scsw)) {
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "32 bit sense, action 1B, update,"
+			      " in transport mode - just retry");
+		return previous_erp;
+	}
+
 	/* for imprecise ending just do default erp */
 	if (sense[1] & 0x01) {
 		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
@@ -2170,7 +2184,7 @@ dasd_3990_erp_control_check(struct dasd_
 {
 	struct dasd_device *device = erp->startdev;
 
-	if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
+	if (scsw_cstat(&erp->refers->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK
 					   | SCHN_STAT_CHN_CTRL_CHK)) {
 		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "channel or interface control check");
@@ -2192,21 +2206,23 @@ dasd_3990_erp_control_check(struct dasd_
  *   erp_new		contens was possibly modified
  */
 static struct dasd_ccw_req *
-dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
+dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
 {
 
 	struct dasd_ccw_req *erp_new = NULL;
-	/* sense data are located in the refers record of the */
-	/* already set up new ERP !			      */
-	char *sense = erp->refers->irb.ecw;
+	char *sense;
 
 	/* if this problem occured on an alias retry on base */
 	erp_new = dasd_3990_erp_inspect_alias(erp);
 	if (erp_new)
 		return erp_new;
 
-	/* check if no concurrent sens is available */
-	if (!erp->refers->irb.esw.esw0.erw.cons)
+	/* sense data are located in the refers record of the
+	 * already set up new ERP !
+	 * check if concurrent sens is available
+	 */
+	sense = dasd_get_sense(&erp->refers->irb);
+	if (!sense)
 		erp_new = dasd_3990_erp_control_check(erp);
 	/* distinguish between 24 and 32 byte sense data */
 	else if (sense[27] & DASD_SENSE_BIT_0) {
@@ -2230,7 +2246,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_re
  * DESCRIPTION
  *   This funtion adds an additional request block (ERP) to the head of
  *   the given cqr (or erp).
- *   This erp is initialized as an default erp (retry TIC)
+ *   For a command mode cqr the erp is initialized as an default erp
+ *   (retry TIC).
+ *   For transport mode we make a copy of the original TCW (points to
+ *   the original TCCB, TIDALs, etc.) but give it a fresh
+ *   TSB so the original sense data will not be changed.
  *
  * PARAMETER
  *   cqr		head of the current ERP-chain (or single cqr if
@@ -2238,17 +2258,27 @@ dasd_3990_erp_inspect(struct dasd_ccw_re
  * RETURN VALUES
  *   erp		pointer to new ERP-chain head
  */
-static struct dasd_ccw_req *
-dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
+static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
 {
 
 	struct dasd_device *device = cqr->startdev;
 	struct ccw1 *ccw;
-
-	/* allocate additional request block */
 	struct dasd_ccw_req *erp;
+	int cplength, datasize;
+	struct tcw *tcw;
+	struct tsb *tsb;
+
+	if (cqr->cpmode == 1) {
+		cplength = 0;
+		datasize = sizeof(struct tcw) + sizeof(struct tsb);
+	} else {
+		cplength = 2;
+		datasize = 0;
+	}
 
-	erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device);
+	/* allocate additional request block */
+	erp = dasd_alloc_erp_request((char *) &cqr->magic,
+				     cplength, datasize, device);
 	if (IS_ERR(erp)) {
                 if (cqr->retries <= 0) {
 			DBF_DEV_EVENT(DBF_ERR, device, "%s",
@@ -2265,13 +2295,24 @@ dasd_3990_erp_add_erp(struct dasd_ccw_re
 		return cqr;
 	}
 
-	/* initialize request with default TIC to current ERP/CQR */
-	ccw = erp->cpaddr;
-	ccw->cmd_code = CCW_CMD_NOOP;
-	ccw->flags = CCW_FLAG_CC;
-	ccw++;
-	ccw->cmd_code = CCW_CMD_TIC;
-	ccw->cda      = (long)(cqr->cpaddr);
+	if (cqr->cpmode == 1) {
+		/* make a shallow copy of the original tcw but set new tsb */
+		erp->cpmode = 1;
+		erp->cpaddr = erp->data;
+		tcw = erp->data;
+		tsb = (struct tsb *) &tcw[1];
+		*tcw = *((struct tcw *)cqr->cpaddr);
+		tcw->tsb = (long)tsb;
+	} else {
+		/* initialize request with default TIC to current ERP/CQR */
+		ccw = erp->cpaddr;
+		ccw->cmd_code = CCW_CMD_NOOP;
+		ccw->flags = CCW_FLAG_CC;
+		ccw++;
+		ccw->cmd_code = CCW_CMD_TIC;
+		ccw->cda      = (long)(cqr->cpaddr);
+	}
+
 	erp->function = dasd_3990_erp_add_erp;
 	erp->refers   = cqr;
 	erp->startdev = device;
@@ -2281,7 +2322,6 @@ dasd_3990_erp_add_erp(struct dasd_ccw_re
 	erp->expires  = 0;
 	erp->retries  = 256;
 	erp->buildclk = get_clock();
-
 	erp->status = DASD_CQR_FILLED;
 
 	return erp;
@@ -2339,28 +2379,33 @@ dasd_3990_erp_additional_erp(struct dasd
  *   match		'boolean' for match found
  *			returns 1 if match found, otherwise 0.
  */
-static int
-dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
+static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1,
+				     struct dasd_ccw_req *cqr2)
 {
+	char *sense1, *sense2;
 
 	if (cqr1->startdev != cqr2->startdev)
 		return 0;
 
-	if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
-		return 0;
+	sense1 = dasd_get_sense(&cqr1->irb);
+	sense2 = dasd_get_sense(&cqr2->irb);
 
-	if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
-	    (cqr2->irb.esw.esw0.erw.cons == 0))	{
-		if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
-					     SCHN_STAT_CHN_CTRL_CHK)) ==
-		    (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
-					     SCHN_STAT_CHN_CTRL_CHK)))
+	/* one request has sense data, the other not -> no match, return 0 */
+	if (!sense1 != !sense2)
+		return 0;
+	/* no sense data in both cases -> check cstat for IFCC */
+	if (!sense1 && !sense2)	{
+		if ((scsw_cstat(&cqr1->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+						    SCHN_STAT_CHN_CTRL_CHK)) ==
+		    (scsw_cstat(&cqr2->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+						    SCHN_STAT_CHN_CTRL_CHK)))
 			return 1; /* match with ifcc*/
 	}
 	/* check sense data; byte 0-2,25,27 */
-	if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
-	      (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
-	      (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) {
+	if (!(sense1 && sense2 &&
+	      (memcmp(sense1, sense2, 3) == 0) &&
+	      (sense1[27] == sense2[27]) &&
+	      (sense1[25] == sense2[25]))) {
 
 		return 0;	/* sense doesn't match */
 	}
@@ -2433,7 +2478,7 @@ dasd_3990_erp_further_erp(struct dasd_cc
 {
 
 	struct dasd_device *device = erp->startdev;
-	char *sense = erp->irb.ecw;
+	char *sense = dasd_get_sense(&erp->irb);
 
 	/* check for 24 byte sense ERP */
 	if ((erp->function == dasd_3990_erp_bus_out) ||
@@ -2448,7 +2493,7 @@ dasd_3990_erp_further_erp(struct dasd_cc
 		/* prepare erp for retry on different channel path */
 		erp = dasd_3990_erp_action_1(erp);
 
-		if (!(sense[2] & DASD_SENSE_BIT_0)) {
+		if (sense && !(sense[2] & DASD_SENSE_BIT_0)) {
 
 			/* issue a Diagnostic Control command with an
 			 * Inhibit Write subcommand */
@@ -2478,10 +2523,11 @@ dasd_3990_erp_further_erp(struct dasd_cc
 		}
 
 		/* check for 32 byte sense ERP */
-	} else if ((erp->function == dasd_3990_erp_compound_retry) ||
-		   (erp->function == dasd_3990_erp_compound_path) ||
-		   (erp->function == dasd_3990_erp_compound_code) ||
-		   (erp->function == dasd_3990_erp_compound_config)) {
+	} else if (sense &&
+		   ((erp->function == dasd_3990_erp_compound_retry) ||
+		    (erp->function == dasd_3990_erp_compound_path) ||
+		    (erp->function == dasd_3990_erp_compound_code) ||
+		    (erp->function == dasd_3990_erp_compound_config))) {
 
 		erp = dasd_3990_erp_compound(erp, sense);
 
@@ -2548,18 +2594,19 @@ dasd_3990_erp_handle_match_erp(struct da
 
 	if (erp->retries > 0) {
 
-		char *sense = erp->refers->irb.ecw;
+		char *sense = dasd_get_sense(&erp->refers->irb);
 
 		/* check for special retries */
-		if (erp->function == dasd_3990_erp_action_4) {
+		if (sense && erp->function == dasd_3990_erp_action_4) {
 
 			erp = dasd_3990_erp_action_4(erp, sense);
 
-		} else if (erp->function == dasd_3990_erp_action_1B_32) {
+		} else if (sense &&
+			   erp->function == dasd_3990_erp_action_1B_32) {
 
 			erp = dasd_3990_update_1B(erp, sense);
 
-		} else if (erp->function == dasd_3990_erp_int_req) {
+		} else if (sense && erp->function == dasd_3990_erp_int_req) {
 
 			erp = dasd_3990_erp_int_req(erp);
 
@@ -2622,8 +2669,8 @@ dasd_3990_erp_action(struct dasd_ccw_req
 	}
 
 	/* double-check if current erp/cqr was successful */
-	if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
-	    (cqr->irb.scsw.cmd.dstat ==
+	if ((scsw_cstat(&cqr->irb.scsw) == 0x00) &&
+	    (scsw_dstat(&cqr->irb.scsw) ==
 	     (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
 
 		DBF_DEV_EVENT(DBF_DEBUG, device,
Index: quilt-2.6/drivers/s390/block/dasd_alias.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_alias.c
+++ quilt-2.6/drivers/s390/block/dasd_alias.c
@@ -646,14 +646,16 @@ static int reset_summary_unit_check(stru
 {
 	struct dasd_ccw_req *cqr;
 	int rc = 0;
+	struct ccw1 *ccw;
 
 	cqr = lcu->rsu_cqr;
 	strncpy((char *) &cqr->magic, "ECKD", 4);
 	ASCEBC((char *) &cqr->magic, 4);
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK;
-	cqr->cpaddr->flags = 0 ;
-	cqr->cpaddr->count = 16;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_RSCK;
+	ccw->flags = 0 ;
+	ccw->count = 16;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	((char *)cqr->data)[0] = reason;
 
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -855,12 +857,21 @@ void dasd_alias_handle_summary_unit_chec
 	struct alias_lcu *lcu;
 	char reason;
 	struct dasd_eckd_private *private;
+	char *sense;
 
 	private = (struct dasd_eckd_private *) device->private;
 
-	reason = irb->ecw[8];
-	DBF_DEV_EVENT(DBF_WARNING, device, "%s %x",
-		    "eckd handle summary unit check: reason", reason);
+	sense = dasd_get_sense(irb);
+	if (sense) {
+		reason = sense[8];
+		DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
+			    "eckd handle summary unit check: reason", reason);
+	} else {
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			    "eckd handle summary unit check:"
+			    " no reason code available");
+		return;
+	}
 
 	lcu = private->lcu;
 	if (!lcu) {
Index: quilt-2.6/drivers/s390/block/dasd.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd.c
+++ quilt-2.6/drivers/s390/block/dasd.c
@@ -25,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:"
@@ -856,8 +857,13 @@ int dasd_start_IO(struct dasd_ccw_req *c
 	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;
@@ -885,9 +891,12 @@ int dasd_start_IO(struct dasd_ccw_req *c
 			      " 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_DEBUG, device, "%s",
-			      "start_IO: device gone, retry");
+			      "start_IO: -EIO device gone, retry");
 		break;
 	default:
 		/* internal error 11 - unknown rc */
@@ -1017,9 +1026,9 @@ void dasd_int_handler(struct ccw_device 
 
 	/* 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);
@@ -1042,7 +1051,7 @@ void dasd_int_handler(struct ccw_device 
 
 	/* 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);
@@ -1050,7 +1059,7 @@ void dasd_int_handler(struct ccw_device 
 		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",
@@ -1060,8 +1069,8 @@ void dasd_int_handler(struct ccw_device 
 
 	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;
@@ -1992,8 +2001,11 @@ static void dasd_setup_queue(struct dasd
 	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);
 }
 
@@ -2431,6 +2443,40 @@ int dasd_generic_read_dev_chars(struct d
 }
 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;
Index: quilt-2.6/drivers/s390/block/dasd_devmap.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_devmap.c
+++ quilt-2.6/drivers/s390/block/dasd_devmap.c
@@ -67,6 +67,8 @@ int dasd_probeonly =  0;	/* is true, whe
 int dasd_autodetect = 0;	/* is true, when autodetection is active */
 int dasd_nopav = 0;		/* is true, when PAV is disabled */
 EXPORT_SYMBOL_GPL(dasd_nopav);
+int dasd_nofcx;			/* disable High Performance Ficon */
+EXPORT_SYMBOL_GPL(dasd_nofcx);
 
 /*
  * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -272,6 +274,11 @@ dasd_parse_keyword( char *parsestring ) 
 		}
 		return residual_str;
 	}
+	if (strncmp("nofcx", parsestring, length) == 0) {
+		dasd_nofcx = 1;
+		MESSAGE(KERN_INFO, "%s", "disable High Performance Ficon");
+		return residual_str;
+	}
 	if (strncmp("fixedbuffers", parsestring, length) == 0) {
 		if (dasd_page_cache)
 			return residual_str;
Index: quilt-2.6/drivers/s390/block/dasd_eckd.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_eckd.c
+++ quilt-2.6/drivers/s390/block/dasd_eckd.c
@@ -29,9 +29,12 @@
 #include <asm/uaccess.h>
 #include <asm/cio.h>
 #include <asm/ccwdev.h>
+#include <asm/itcw.h>
 
 #include "dasd_int.h"
 #include "dasd_eckd.h"
+#include "../cio/chsc.h"
+
 
 #ifdef PRINTK_HEADER
 #undef PRINTK_HEADER
@@ -292,30 +295,145 @@ static int check_XRC_on_prefix(struct PF
 		return 0;
 
 	/* switch on System Time Stamp - needed for XRC Support */
-	pfxdata->define_extend.ga_extended |= 0x08; /* 'Time Stamp Valid'   */
-	pfxdata->define_extend.ga_extended |= 0x02; /* 'Extended Parameter' */
+	pfxdata->define_extent.ga_extended |= 0x08; /* 'Time Stamp Valid'   */
+	pfxdata->define_extent.ga_extended |= 0x02; /* 'Extended Parameter' */
 	pfxdata->validity.time_stamp = 1;	    /* 'Time Stamp Valid'   */
 
-	rc = get_sync_clock(&pfxdata->define_extend.ep_sys_time);
+	rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
 	/* Ignore return code if sync clock is switched off. */
 	if (rc == -ENOSYS || rc == -EACCES)
 		rc = 0;
 	return rc;
 }
 
-static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
-		  unsigned int trk, unsigned int totrk, int cmd,
-		  struct dasd_device *basedev, struct dasd_device *startdev)
+static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
+			  unsigned int rec_on_trk, int count, int cmd,
+			  struct dasd_device *device, unsigned int reclen,
+			  unsigned int tlf)
+{
+	struct dasd_eckd_private *private;
+	int sector;
+	int dn, d;
+
+	private = (struct dasd_eckd_private *) device->private;
+
+	memset(data, 0, sizeof(*data));
+	sector = 0;
+	if (rec_on_trk) {
+		switch (private->rdc_data.dev_type) {
+		case 0x3390:
+			dn = ceil_quot(reclen + 6, 232);
+			d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
+			sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+			break;
+		case 0x3380:
+			d = 7 + ceil_quot(reclen + 12, 32);
+			sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+			break;
+		}
+	}
+	data->sector = sector;
+	/* note: meaning of count depends on the operation
+	 *	 for record based I/O it's the number of records, but for
+	 *	 track based I/O it's the number of tracks
+	 */
+	data->count = count;
+	switch (cmd) {
+	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
+		data->operation.orientation = 0x3;
+		data->operation.operation = 0x03;
+		break;
+	case DASD_ECKD_CCW_READ_HOME_ADDRESS:
+		data->operation.orientation = 0x3;
+		data->operation.operation = 0x16;
+		break;
+	case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
+		data->operation.orientation = 0x1;
+		data->operation.operation = 0x03;
+		data->count++;
+		break;
+	case DASD_ECKD_CCW_READ_RECORD_ZERO:
+		data->operation.orientation = 0x3;
+		data->operation.operation = 0x16;
+		data->count++;
+		break;
+	case DASD_ECKD_CCW_WRITE:
+	case DASD_ECKD_CCW_WRITE_MT:
+	case DASD_ECKD_CCW_WRITE_KD:
+	case DASD_ECKD_CCW_WRITE_KD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x01;
+		break;
+	case DASD_ECKD_CCW_WRITE_CKD:
+	case DASD_ECKD_CCW_WRITE_CKD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x03;
+		break;
+	case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;	/* not tlf, as one might think */
+		data->operation.operation = 0x3F;
+		data->extended_operation = 0x23;
+		break;
+	case DASD_ECKD_CCW_READ:
+	case DASD_ECKD_CCW_READ_MT:
+	case DASD_ECKD_CCW_READ_KD:
+	case DASD_ECKD_CCW_READ_KD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x06;
+		break;
+	case DASD_ECKD_CCW_READ_CKD:
+	case DASD_ECKD_CCW_READ_CKD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x16;
+		break;
+	case DASD_ECKD_CCW_READ_COUNT:
+		data->operation.operation = 0x06;
+		break;
+	case DASD_ECKD_CCW_READ_TRACK_DATA:
+		data->auxiliary.length_valid = 0x1;
+		data->length = tlf;
+		data->operation.operation = 0x0C;
+		break;
+	case DASD_ECKD_CCW_ERASE:
+		data->length = reclen;
+		data->auxiliary.length_valid = 0x1;
+		data->operation.operation = 0x0b;
+		break;
+	default:
+		DBF_DEV_EVENT(DBF_ERR, device,
+			    "fill LRE unknown opcode 0x%x", cmd);
+		BUG();
+	}
+	set_ch_t(&data->seek_addr,
+		 trk / private->rdc_data.trk_per_cyl,
+		 trk % private->rdc_data.trk_per_cyl);
+	data->search_arg.cyl = data->seek_addr.cyl;
+	data->search_arg.head = data->seek_addr.head;
+	data->search_arg.record = rec_on_trk;
+}
+
+static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+		      unsigned int trk, unsigned int totrk, int cmd,
+		      struct dasd_device *basedev, struct dasd_device *startdev,
+		      unsigned char format, unsigned int rec_on_trk, int count,
+		      unsigned int blksize, unsigned int tlf)
 {
 	struct dasd_eckd_private *basepriv, *startpriv;
-	struct DE_eckd_data *data;
+	struct DE_eckd_data *dedata;
+	struct LRE_eckd_data *lredata;
 	u32 begcyl, endcyl;
 	u16 heads, beghead, endhead;
 	int rc = 0;
 
 	basepriv = (struct dasd_eckd_private *) basedev->private;
 	startpriv = (struct dasd_eckd_private *) startdev->private;
-	data = &pfxdata->define_extend;
+	dedata = &pfxdata->define_extent;
+	lredata = &pfxdata->locate_record;
 
 	ccw->cmd_code = DASD_ECKD_CCW_PFX;
 	ccw->flags = 0;
@@ -324,10 +442,16 @@ static int prefix(struct ccw1 *ccw, stru
 
 	memset(pfxdata, 0, sizeof(*pfxdata));
 	/* prefix data */
-	pfxdata->format = 0;
+	if (format > 1) {
+		DBF_DEV_EVENT(DBF_ERR, basedev,
+			      "PFX LRE unknown format 0x%x", format);
+		BUG();
+		return -EINVAL;
+	}
+	pfxdata->format = format;
 	pfxdata->base_address = basepriv->ned->unit_addr;
 	pfxdata->base_lss = basepriv->ned->ID;
-	pfxdata->validity.define_extend = 1;
+	pfxdata->validity.define_extent = 1;
 
 	/* private uid is kept up to date, conf_data may be outdated */
 	if (startpriv->uid.type != UA_BASE_DEVICE) {
@@ -347,43 +471,55 @@ static int prefix(struct ccw1 *ccw, stru
 	case DASD_ECKD_CCW_READ_KD:
 	case DASD_ECKD_CCW_READ_KD_MT:
 	case DASD_ECKD_CCW_READ_COUNT:
-		data->mask.perm = 0x1;
-		data->attributes.operation = basepriv->attrib.operation;
+		dedata->mask.perm = 0x1;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		break;
+	case DASD_ECKD_CCW_READ_TRACK_DATA:
+		dedata->mask.perm = 0x1;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = 0;
 		break;
 	case DASD_ECKD_CCW_WRITE:
 	case DASD_ECKD_CCW_WRITE_MT:
 	case DASD_ECKD_CCW_WRITE_KD:
 	case DASD_ECKD_CCW_WRITE_KD_MT:
-		data->mask.perm = 0x02;
-		data->attributes.operation = basepriv->attrib.operation;
+		dedata->mask.perm = 0x02;
+		dedata->attributes.operation = basepriv->attrib.operation;
 		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
 	case DASD_ECKD_CCW_WRITE_CKD:
 	case DASD_ECKD_CCW_WRITE_CKD_MT:
-		data->attributes.operation = DASD_BYPASS_CACHE;
+		dedata->attributes.operation = DASD_BYPASS_CACHE;
 		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
 	case DASD_ECKD_CCW_ERASE:
 	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
 	case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
-		data->mask.perm = 0x3;
-		data->mask.auth = 0x1;
-		data->attributes.operation = DASD_BYPASS_CACHE;
+		dedata->mask.perm = 0x3;
+		dedata->mask.auth = 0x1;
+		dedata->attributes.operation = DASD_BYPASS_CACHE;
 		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
-	default:
-		DBF_DEV_EVENT(DBF_ERR, basedev, "unknown prefix opcode 0x%x",
-			      cmd);
+	case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+		dedata->mask.perm = 0x02;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = blksize;
+		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
+	default:
+		DBF_DEV_EVENT(DBF_ERR, basedev,
+			    "PFX LRE unknown opcode 0x%x", cmd);
+		BUG();
+		return -EINVAL;
 	}
 
-	data->attributes.mode = 0x3;	/* ECKD */
+	dedata->attributes.mode = 0x3;	/* ECKD */
 
 	if ((basepriv->rdc_data.cu_type == 0x2105 ||
 	     basepriv->rdc_data.cu_type == 0x2107 ||
 	     basepriv->rdc_data.cu_type == 0x1750)
 	    && !(basepriv->uses_cdl && trk < 2))
-		data->ga_extended |= 0x40; /* Regular Data Format Mode */
+		dedata->ga_extended |= 0x40; /* Regular Data Format Mode */
 
 	heads = basepriv->rdc_data.trk_per_cyl;
 	begcyl = trk / heads;
@@ -392,8 +528,8 @@ static int prefix(struct ccw1 *ccw, stru
 	endhead = totrk % heads;
 
 	/* check for sequential prestage - enhance cylinder range */
-	if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
-	    data->attributes.operation == DASD_SEQ_ACCESS) {
+	if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+	    dedata->attributes.operation == DASD_SEQ_ACCESS) {
 
 		if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
 			endcyl += basepriv->attrib.nr_cyl;
@@ -401,11 +537,25 @@ static int prefix(struct ccw1 *ccw, stru
 			endcyl = (basepriv->real_cyl - 1);
 	}
 
-	set_ch_t(&data->beg_ext, begcyl, beghead);
-	set_ch_t(&data->end_ext, endcyl, endhead);
+	set_ch_t(&dedata->beg_ext, begcyl, beghead);
+	set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+	if (format == 1) {
+		fill_LRE_data(lredata, trk, rec_on_trk, count, cmd,
+			      basedev, blksize, tlf);
+	}
+
 	return rc;
 }
 
+static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+		  unsigned int trk, unsigned int totrk, int cmd,
+		  struct dasd_device *basedev, struct dasd_device *startdev)
+{
+	return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
+			  0, 0, 0, 0, 0);
+}
+
 static void
 locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
 	      unsigned int rec_on_trk, int no_rec, int cmd,
@@ -853,7 +1003,8 @@ static int dasd_eckd_read_features(struc
 /*
  * Build CP for Perform Subsystem Function - SSC.
  */
-static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
+static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
+						    int enable_pav)
 {
 	struct dasd_ccw_req *cqr;
 	struct dasd_psf_ssc_data *psf_ssc_data;
@@ -870,9 +1021,11 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	}
 	psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
 	psf_ssc_data->order = PSF_ORDER_SSC;
-	psf_ssc_data->suborder = 0x88;
-	psf_ssc_data->reserved[0] = 0x88;
-
+	psf_ssc_data->suborder = 0x40;
+	if (enable_pav) {
+		psf_ssc_data->suborder |= 0x88;
+		psf_ssc_data->reserved[0] = 0x88;
+	}
 	ccw = cqr->cpaddr;
 	ccw->cmd_code = DASD_ECKD_CCW_PSF;
 	ccw->cda = (__u32)(addr_t)psf_ssc_data;
@@ -893,12 +1046,12 @@ static struct dasd_ccw_req *dasd_eckd_bu
  * call might change behaviour of DASD devices.
  */
 static int
-dasd_eckd_psf_ssc(struct dasd_device *device)
+dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
 
-	cqr = dasd_eckd_build_psf_ssc(device);
+	cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
 	if (IS_ERR(cqr))
 		return PTR_ERR(cqr);
 
@@ -917,12 +1070,13 @@ static int dasd_eckd_validate_server(str
 {
 	int rc;
 	struct dasd_eckd_private *private;
+	int enable_pav;
 
-	/* Currently PAV is the only reason to 'validate' server on LPAR */
 	if (dasd_nopav || MACHINE_IS_VM)
-		return 0;
-
-	rc = dasd_eckd_psf_ssc(device);
+		enable_pav = 0;
+	else
+		enable_pav = 1;
+	rc = dasd_eckd_psf_ssc(device, enable_pav);
 	/* may be requested feature is not available on server,
 	 * therefore just report error and go ahead */
 	private = (struct dasd_eckd_private *) device->private;
@@ -1513,40 +1667,41 @@ static void dasd_eckd_handle_unsolicited
 						   struct irb *irb)
 {
 	char mask;
+	char *sense = NULL;
 
 	/* first of all check for state change pending interrupt */
 	mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
-	if ((irb->scsw.cmd.dstat & mask) == mask) {
+	if ((scsw_dstat(&irb->scsw) & mask) == mask) {
 		dasd_generic_handle_state_change(device);
 		return;
 	}
 
 	/* summary unit check */
-	if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
+	if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
 	    (irb->ecw[7] == 0x0D)) {
 		dasd_alias_handle_summary_unit_check(device, irb);
 		return;
 	}
 
-
+	sense = dasd_get_sense(irb);
 	/* service information message SIM */
-	if (irb->esw.esw0.erw.cons && !(irb->ecw[27] & DASD_SENSE_BIT_0) &&
-	    ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
-		dasd_3990_erp_handle_sim(device, irb->ecw);
+	if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
+	    ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
+		dasd_3990_erp_handle_sim(device, sense);
 		dasd_schedule_device_bh(device);
 		return;
 	}
 
-	if ((irb->scsw.cmd.cc == 1) &&
-	    (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
-	    (irb->scsw.cmd.actl & SCSW_ACTL_START_PEND) &&
-	    (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND)) {
+	if ((scsw_cc(&irb->scsw) == 1) &&
+	    (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+	    (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) &&
+	    (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) {
 		/* fake irb do nothing, they are handled elsewhere */
 		dasd_schedule_device_bh(device);
 		return;
 	}
 
-	if (!(irb->esw.esw0.erw.cons)) {
+	if (!sense) {
 		/* just report other unsolicited interrupts */
 		DBF_DEV_EVENT(DBF_ERR, device, "%s",
 			    "unsolicited interrupt received");
@@ -1562,9 +1717,19 @@ static void dasd_eckd_handle_unsolicited
 	return;
 };
 
-static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
+					       struct dasd_device *startdev,
 					       struct dasd_block *block,
-					       struct request *req)
+					       struct request *req,
+					       sector_t first_rec,
+					       sector_t last_rec,
+					       sector_t first_trk,
+					       sector_t last_trk,
+					       unsigned int first_offs,
+					       unsigned int last_offs,
+					       unsigned int blk_per_trk,
+					       unsigned int blksize)
 {
 	struct dasd_eckd_private *private;
 	unsigned long *idaws;
@@ -1574,11 +1739,9 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	struct req_iterator iter;
 	struct bio_vec *bv;
 	char *dst;
-	unsigned int blksize, blk_per_trk, off;
+	unsigned int off;
 	int count, cidaw, cplength, datasize;
-	sector_t recid, first_rec, last_rec;
-	sector_t first_trk, last_trk;
-	unsigned int first_offs, last_offs;
+	sector_t recid;
 	unsigned char cmd, rcmd;
 	int use_prefix;
 	struct dasd_device *basedev;
@@ -1591,15 +1754,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 		cmd = DASD_ECKD_CCW_WRITE_MT;
 	else
 		return ERR_PTR(-EINVAL);
-	/* Calculate number of blocks/records per track. */
-	blksize = block->bp_block;
-	blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
-	/* Calculate record id of first and last block. */
-	first_rec = first_trk = req->sector >> block->s2b_shift;
-	first_offs = sector_div(first_trk, blk_per_trk);
-	last_rec = last_trk =
-		(req->sector + req->nr_sectors - 1) >> block->s2b_shift;
-	last_offs = sector_div(last_trk, blk_per_trk);
+
 	/* Check struct bio and count the number of blocks for the request. */
 	count = 0;
 	cidaw = 0;
@@ -1749,6 +1904,497 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	return cqr;
 }
 
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
+					       struct dasd_device *startdev,
+					       struct dasd_block *block,
+					       struct request *req,
+					       sector_t first_rec,
+					       sector_t last_rec,
+					       sector_t first_trk,
+					       sector_t last_trk,
+					       unsigned int first_offs,
+					       unsigned int last_offs,
+					       unsigned int blk_per_trk,
+					       unsigned int blksize)
+{
+	struct dasd_eckd_private *private;
+	unsigned long *idaws;
+	struct dasd_ccw_req *cqr;
+	struct ccw1 *ccw;
+	struct req_iterator iter;
+	struct bio_vec *bv;
+	char *dst, *idaw_dst;
+	unsigned int cidaw, cplength, datasize;
+	unsigned int tlf;
+	sector_t recid;
+	unsigned char cmd;
+	struct dasd_device *basedev;
+	unsigned int trkcount, count, count_to_trk_end;
+	unsigned int idaw_len, seg_len, part_len, len_to_track_end;
+	unsigned char new_track, end_idaw;
+	sector_t trkid;
+	unsigned int recoffs;
+
+	basedev = block->base;
+	private = (struct dasd_eckd_private *) basedev->private;
+	if (rq_data_dir(req) == READ)
+		cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+	else if (rq_data_dir(req) == WRITE)
+		cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+	else
+		return ERR_PTR(-EINVAL);
+
+	/* Track based I/O needs IDAWs for each page, and not just for
+	 * 64 bit addresses. We need additional idals for pages
+	 * that get filled from two tracks, so we use the number
+	 * of records as upper limit.
+	 */
+	cidaw = last_rec - first_rec + 1;
+	trkcount = last_trk - first_trk + 1;
+
+	/* 1x prefix + one read/write ccw per track */
+	cplength = 1 + trkcount;
+
+	/* on 31-bit we need space for two 32 bit addresses per page
+	 * on 64-bit one 64 bit address
+	 */
+	datasize = sizeof(struct PFX_eckd_data) +
+		cidaw * sizeof(unsigned long long);
+
+	/* Allocate the ccw request. */
+	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+				   cplength, datasize, startdev);
+	if (IS_ERR(cqr))
+		return cqr;
+	ccw = cqr->cpaddr;
+	/* transfer length factor: how many bytes to read from the last track */
+	if (first_trk == last_trk)
+		tlf = last_offs - first_offs + 1;
+	else
+		tlf = last_offs + 1;
+	tlf *= blksize;
+
+	if (prefix_LRE(ccw++, cqr->data, first_trk,
+		       last_trk, cmd, basedev, startdev,
+		       1 /* format */, first_offs + 1,
+		       trkcount, blksize,
+		       tlf) == -EAGAIN) {
+		/* Clock not in sync and XRC is enabled.
+		 * Try again later.
+		 */
+		dasd_sfree_request(cqr, startdev);
+		return ERR_PTR(-EAGAIN);
+	}
+
+	/*
+	 * The translation of request into ccw programs must meet the
+	 * following conditions:
+	 * - all idaws but the first and the last must address full pages
+	 *   (or 2K blocks on 31-bit)
+	 * - the scope of a ccw and it's idal ends with the track boundaries
+	 */
+	idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
+	recid = first_rec;
+	new_track = 1;
+	end_idaw = 0;
+	len_to_track_end = 0;
+	idaw_dst = 0;
+	idaw_len = 0;
+	rq_for_each_segment(bv, req, iter) {
+		dst = page_address(bv->bv_page) + bv->bv_offset;
+		seg_len = bv->bv_len;
+		while (seg_len) {
+			if (new_track) {
+				trkid = recid;
+				recoffs = sector_div(trkid, blk_per_trk);
+				count_to_trk_end = blk_per_trk - recoffs;
+				count = min((last_rec - recid + 1),
+					    (sector_t)count_to_trk_end);
+				len_to_track_end = count * blksize;
+				ccw[-1].flags |= CCW_FLAG_CC;
+				ccw->cmd_code = cmd;
+				ccw->count = len_to_track_end;
+				ccw->cda = (__u32)(addr_t)idaws;
+				ccw->flags = CCW_FLAG_IDA;
+				ccw++;
+				recid += count;
+				new_track = 0;
+			}
+			/* If we start a new idaw, everything is fine and the
+			 * start of the new idaw is the start of this segment.
+			 * If we continue an idaw, we must make sure that the
+			 * current segment begins where the so far accumulated
+			 * idaw ends
+			 */
+			if (!idaw_dst)
+				idaw_dst = dst;
+			if ((idaw_dst + idaw_len) != dst) {
+				dasd_sfree_request(cqr, startdev);
+				return ERR_PTR(-ERANGE);
+			}
+			part_len = min(seg_len, len_to_track_end);
+			seg_len -= part_len;
+			dst += part_len;
+			idaw_len += part_len;
+			len_to_track_end -= part_len;
+			/* collected memory area ends on an IDA_BLOCK border,
+			 * -> create an idaw
+			 * idal_create_words will handle cases where idaw_len
+			 * is larger then IDA_BLOCK_SIZE
+			 */
+			if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
+				end_idaw = 1;
+			/* We also need to end the idaw at track end */
+			if (!len_to_track_end) {
+				new_track = 1;
+				end_idaw = 1;
+			}
+			if (end_idaw) {
+				idaws = idal_create_words(idaws, idaw_dst,
+							  idaw_len);
+				idaw_dst = 0;
+				idaw_len = 0;
+				end_idaw = 0;
+			}
+		}
+	}
+
+	if (blk_noretry_request(req) ||
+	    block->base->features & DASD_FEATURE_FAILFAST)
+		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+	cqr->startdev = startdev;
+	cqr->memdev = startdev;
+	cqr->block = block;
+	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */
+	cqr->lpm = private->path_data.ppm;
+	cqr->retries = 256;
+	cqr->buildclk = get_clock();
+	cqr->status = DASD_CQR_FILLED;
+	return cqr;
+}
+
+static int prepare_itcw(struct itcw *itcw,
+			unsigned int trk, unsigned int totrk, int cmd,
+			struct dasd_device *basedev,
+			struct dasd_device *startdev,
+			unsigned int rec_on_trk, int count,
+			unsigned int blksize,
+			unsigned int total_data_size,
+			unsigned int tlf,
+			unsigned int blk_per_trk)
+{
+	struct PFX_eckd_data pfxdata;
+	struct dasd_eckd_private *basepriv, *startpriv;
+	struct DE_eckd_data *dedata;
+	struct LRE_eckd_data *lredata;
+	struct dcw *dcw;
+
+	u32 begcyl, endcyl;
+	u16 heads, beghead, endhead;
+	u8 pfx_cmd;
+
+	int rc = 0;
+	int sector = 0;
+	int dn, d;
+
+
+	/* setup prefix data */
+	basepriv = (struct dasd_eckd_private *) basedev->private;
+	startpriv = (struct dasd_eckd_private *) startdev->private;
+	dedata = &pfxdata.define_extent;
+	lredata = &pfxdata.locate_record;
+
+	memset(&pfxdata, 0, sizeof(pfxdata));
+	pfxdata.format = 1; /* PFX with LRE */
+	pfxdata.base_address = basepriv->ned->unit_addr;
+	pfxdata.base_lss = basepriv->ned->ID;
+	pfxdata.validity.define_extent = 1;
+
+	/* private uid is kept up to date, conf_data may be outdated */
+	if (startpriv->uid.type != UA_BASE_DEVICE) {
+		pfxdata.validity.verify_base = 1;
+		if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
+			pfxdata.validity.hyper_pav = 1;
+	}
+
+	switch (cmd) {
+	case DASD_ECKD_CCW_READ_TRACK_DATA:
+		dedata->mask.perm = 0x1;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = blksize;
+		dedata->ga_extended |= 0x42;
+		lredata->operation.orientation = 0x0;
+		lredata->operation.operation = 0x0C;
+		lredata->auxiliary.check_bytes = 0x01;
+		pfx_cmd = DASD_ECKD_CCW_PFX_READ;
+		break;
+	case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+		dedata->mask.perm = 0x02;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = blksize;
+		rc = check_XRC_on_prefix(&pfxdata, basedev);
+		dedata->ga_extended |= 0x42;
+		lredata->operation.orientation = 0x0;
+		lredata->operation.operation = 0x3F;
+		lredata->extended_operation = 0x23;
+		lredata->auxiliary.check_bytes = 0x2;
+		pfx_cmd = DASD_ECKD_CCW_PFX;
+		break;
+	default:
+		DBF_DEV_EVENT(DBF_ERR, basedev,
+			      "prepare itcw, unknown opcode 0x%x", cmd);
+		BUG();
+		break;
+	}
+	if (rc)
+		return rc;
+
+	dedata->attributes.mode = 0x3;	/* ECKD */
+
+	heads = basepriv->rdc_data.trk_per_cyl;
+	begcyl = trk / heads;
+	beghead = trk % heads;
+	endcyl = totrk / heads;
+	endhead = totrk % heads;
+
+	/* check for sequential prestage - enhance cylinder range */
+	if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+	    dedata->attributes.operation == DASD_SEQ_ACCESS) {
+
+		if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+			endcyl += basepriv->attrib.nr_cyl;
+		else
+			endcyl = (basepriv->real_cyl - 1);
+	}
+
+	set_ch_t(&dedata->beg_ext, begcyl, beghead);
+	set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+	dedata->ep_format = 0x20; /* records per track is valid */
+	dedata->ep_rec_per_track = blk_per_trk;
+
+	if (rec_on_trk) {
+		switch (basepriv->rdc_data.dev_type) {
+		case 0x3390:
+			dn = ceil_quot(blksize + 6, 232);
+			d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
+			sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+			break;
+		case 0x3380:
+			d = 7 + ceil_quot(blksize + 12, 32);
+			sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+			break;
+		}
+	}
+
+	lredata->auxiliary.length_valid = 1;
+	lredata->auxiliary.length_scope = 1;
+	lredata->auxiliary.imbedded_ccw_valid = 1;
+	lredata->length = tlf;
+	lredata->imbedded_ccw = cmd;
+	lredata->count = count;
+	lredata->sector = sector;
+	set_ch_t(&lredata->seek_addr, begcyl, beghead);
+	lredata->search_arg.cyl = lredata->seek_addr.cyl;
+	lredata->search_arg.head = lredata->seek_addr.head;
+	lredata->search_arg.record = rec_on_trk;
+
+	dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
+		     &pfxdata, sizeof(pfxdata), total_data_size);
+
+	return rc;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
+					       struct dasd_device *startdev,
+					       struct dasd_block *block,
+					       struct request *req,
+					       sector_t first_rec,
+					       sector_t last_rec,
+					       sector_t first_trk,
+					       sector_t last_trk,
+					       unsigned int first_offs,
+					       unsigned int last_offs,
+					       unsigned int blk_per_trk,
+					       unsigned int blksize)
+{
+	struct dasd_eckd_private *private;
+	struct dasd_ccw_req *cqr;
+	struct req_iterator iter;
+	struct bio_vec *bv;
+	char *dst;
+	unsigned int trkcount, ctidaw;
+	unsigned char cmd;
+	struct dasd_device *basedev;
+	unsigned int tlf;
+	struct itcw *itcw;
+	struct tidaw *last_tidaw = NULL;
+	int itcw_op;
+	size_t itcw_size;
+
+	basedev = block->base;
+	private = (struct dasd_eckd_private *) basedev->private;
+	if (rq_data_dir(req) == READ) {
+		cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+		itcw_op = ITCW_OP_READ;
+	} else if (rq_data_dir(req) == WRITE) {
+		cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+		itcw_op = ITCW_OP_WRITE;
+	} else
+		return ERR_PTR(-EINVAL);
+
+	/* trackbased I/O needs address all memory via TIDAWs,
+	 * not just for 64 bit addresses. This allows us to map
+	 * each segment directly to one tidaw.
+	 */
+	trkcount = last_trk - first_trk + 1;
+	ctidaw = 0;
+	rq_for_each_segment(bv, req, iter) {
+		++ctidaw;
+	}
+
+	/* Allocate the ccw request. */
+	itcw_size = itcw_calc_size(0, ctidaw, 0);
+	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+				   0, itcw_size, startdev);
+	if (IS_ERR(cqr))
+		return cqr;
+
+	cqr->cpmode = 1;
+	cqr->startdev = startdev;
+	cqr->memdev = startdev;
+	cqr->block = block;
+	cqr->expires = 100*HZ;
+	cqr->buildclk = get_clock();
+	cqr->status = DASD_CQR_FILLED;
+	cqr->retries = 10;
+
+	/* transfer length factor: how many bytes to read from the last track */
+	if (first_trk == last_trk)
+		tlf = last_offs - first_offs + 1;
+	else
+		tlf = last_offs + 1;
+	tlf *= blksize;
+
+	itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
+	cqr->cpaddr = itcw_get_tcw(itcw);
+
+	if (prepare_itcw(itcw, first_trk, last_trk,
+			 cmd, basedev, startdev,
+			 first_offs + 1,
+			 trkcount, blksize,
+			 (last_rec - first_rec + 1) * blksize,
+			 tlf, blk_per_trk) == -EAGAIN) {
+		/* Clock not in sync and XRC is enabled.
+		 * Try again later.
+		 */
+		dasd_sfree_request(cqr, startdev);
+		return ERR_PTR(-EAGAIN);
+	}
+
+	/*
+	 * A tidaw can address 4k of memory, but must not cross page boundaries
+	 * We can let the block layer handle this by setting
+	 * blk_queue_segment_boundary to page boundaries and
+	 * blk_max_segment_size to page size when setting up the request queue.
+	 */
+	rq_for_each_segment(bv, req, iter) {
+		dst = page_address(bv->bv_page) + bv->bv_offset;
+		last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
+		if (IS_ERR(last_tidaw))
+			return (struct dasd_ccw_req *)last_tidaw;
+	}
+
+	last_tidaw->flags |= 0x80;
+	itcw_finalize(itcw);
+
+	if (blk_noretry_request(req) ||
+	    block->base->features & DASD_FEATURE_FAILFAST)
+		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+	cqr->startdev = startdev;
+	cqr->memdev = startdev;
+	cqr->block = block;
+	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */
+	cqr->lpm = private->path_data.ppm;
+	cqr->retries = 256;
+	cqr->buildclk = get_clock();
+	cqr->status = DASD_CQR_FILLED;
+	return cqr;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+					       struct dasd_block *block,
+					       struct request *req)
+{
+	int tpm, cmdrtd, cmdwtd;
+	int use_prefix;
+
+	struct dasd_eckd_private *private;
+	int fcx_in_css, fcx_in_gneq, fcx_in_features;
+	struct dasd_device *basedev;
+	sector_t first_rec, last_rec;
+	sector_t first_trk, last_trk;
+	unsigned int first_offs, last_offs;
+	unsigned int blk_per_trk, blksize;
+	int cdlspecial;
+	struct dasd_ccw_req *cqr;
+
+	basedev = block->base;
+	private = (struct dasd_eckd_private *) basedev->private;
+
+	/* Calculate number of blocks/records per track. */
+	blksize = block->bp_block;
+	blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
+	/* Calculate record id of first and last block. */
+	first_rec = first_trk = req->sector >> block->s2b_shift;
+	first_offs = sector_div(first_trk, blk_per_trk);
+	last_rec = last_trk =
+		(req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+	last_offs = sector_div(last_trk, blk_per_trk);
+	cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
+
+	/* is transport mode supported ? */
+	fcx_in_css = css_general_characteristics.fcx;
+	fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
+	fcx_in_features = private->features.feature[40] & 0x80;
+	tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
+
+	/* is read track data and write track data in command mode supported? */
+	cmdrtd = private->features.feature[9] & 0x20;
+	cmdwtd = private->features.feature[12] & 0x40;
+	use_prefix = private->features.feature[8] & 0x01;
+
+	cqr = NULL;
+	if (cdlspecial || dasd_page_cache) {
+		/* do nothing, just fall through to the cmd mode single case */
+	} else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
+		cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
+						    first_rec, last_rec,
+						    first_trk, last_trk,
+						    first_offs, last_offs,
+						    blk_per_trk, blksize);
+		if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+			cqr = NULL;
+	} else if (use_prefix &&
+		   (((rq_data_dir(req) == READ) && cmdrtd) ||
+		    ((rq_data_dir(req) == WRITE) && cmdwtd))) {
+		cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
+						   first_rec, last_rec,
+						   first_trk, last_trk,
+						   first_offs, last_offs,
+						   blk_per_trk, blksize);
+		if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+			cqr = NULL;
+	}
+	if (!cqr)
+		cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
+						    first_rec, last_rec,
+						    first_trk, last_trk,
+						    first_offs, last_offs,
+						    blk_per_trk, blksize);
+	return cqr;
+}
+
 static int
 dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
 {
@@ -1802,7 +2448,7 @@ out:
 }
 
 /*
- * Modify ccw chain in cqr so it can be started on a base device.
+ * Modify ccw/tcw in cqr so it can be started on a base device.
  *
  * Note that this is not enough to restart the cqr!
  * Either reset cqr->startdev as well (summary unit check handling)
@@ -1812,13 +2458,24 @@ void dasd_eckd_reset_ccw_to_base_io(stru
 {
 	struct ccw1 *ccw;
 	struct PFX_eckd_data *pfxdata;
-
-	ccw = cqr->cpaddr;
-	pfxdata = cqr->data;
-
-	if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+	struct tcw *tcw;
+	struct tccb *tccb;
+	struct dcw *dcw;
+
+	if (cqr->cpmode == 1) {
+		tcw = cqr->cpaddr;
+		tccb = tcw_get_tccb(tcw);
+		dcw = (struct dcw *)&tccb->tca[0];
+		pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
 		pfxdata->validity.verify_base = 0;
 		pfxdata->validity.hyper_pav = 0;
+	} else {
+		ccw = cqr->cpaddr;
+		pfxdata = cqr->data;
+		if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+			pfxdata->validity.verify_base = 0;
+			pfxdata->validity.hyper_pav = 0;
+		}
 	}
 }
 
@@ -1896,6 +2553,7 @@ dasd_eckd_release(struct dasd_device *de
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
+	struct ccw1 *ccw;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -1907,10 +2565,11 @@ dasd_eckd_release(struct dasd_device *de
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
-        cqr->cpaddr->flags |= CCW_FLAG_SLI;
-        cqr->cpaddr->count = 32;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
+	ccw->flags |= CCW_FLAG_SLI;
+	ccw->count = 32;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	cqr->startdev = device;
 	cqr->memdev = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1937,6 +2596,7 @@ dasd_eckd_reserve(struct dasd_device *de
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
+	struct ccw1 *ccw;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -1948,10 +2608,11 @@ dasd_eckd_reserve(struct dasd_device *de
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
-        cqr->cpaddr->flags |= CCW_FLAG_SLI;
-        cqr->cpaddr->count = 32;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
+	ccw->flags |= CCW_FLAG_SLI;
+	ccw->count = 32;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	cqr->startdev = device;
 	cqr->memdev = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1977,6 +2638,7 @@ dasd_eckd_steal_lock(struct dasd_device 
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
+	struct ccw1 *ccw;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -1988,10 +2650,11 @@ dasd_eckd_steal_lock(struct dasd_device 
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
-        cqr->cpaddr->flags |= CCW_FLAG_SLI;
-        cqr->cpaddr->count = 32;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_SLCK;
+	ccw->flags |= CCW_FLAG_SLI;
+	ccw->count = 32;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	cqr->startdev = device;
 	cqr->memdev = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -2299,7 +2962,7 @@ dasd_eckd_dump_sense_dbf(struct dasd_dev
  * Print sense data and related channel program.
  * Parts are printed because printk buffer is only 1024 bytes.
  */
-static void dasd_eckd_dump_sense(struct dasd_device *device,
+static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
 				 struct dasd_ccw_req *req, struct irb *irb)
 {
 	char *page;
@@ -2318,7 +2981,7 @@ static void dasd_eckd_dump_sense(struct 
 		      dev_name(&device->cdev->dev));
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
-		       irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
+		       scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       " device %s: Failing CCW: %p\n",
 		       dev_name(&device->cdev->dev),
@@ -2394,6 +3057,147 @@ static void dasd_eckd_dump_sense(struct 
 	free_page((unsigned long) page);
 }
 
+
+/*
+ * Print sense data from a tcw.
+ */
+static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
+				 struct dasd_ccw_req *req, struct irb *irb)
+{
+	char *page;
+	int len, sl, sct, residual;
+
+	struct tsb *tsb;
+	u8 *sense;
+
+
+	page = (char *) get_zeroed_page(GFP_ATOMIC);
+	if (page == NULL) {
+		DEV_MESSAGE(KERN_ERR, device, " %s",
+			    "No memory to dump sense data");
+		return;
+	}
+	/* dump the sense data */
+	len = sprintf(page,  KERN_ERR PRINTK_HEADER
+		      " I/O status report for device %s:\n",
+		      dev_name(&device->cdev->dev));
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " in req: %p CS: 0x%02X DS: 0x%02X "
+		       "fcxs: 0x%02X schxs: 0x%02X\n", req,
+		       scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+		       irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " device %s: Failing TCW: %p\n",
+		       dev_name(&device->cdev->dev),
+		       (void *) (addr_t) irb->scsw.tm.tcw);
+
+	tsb = NULL;
+	sense = NULL;
+	if (irb->scsw.tm.tcw)
+		tsb = tcw_get_tsb(
+			(struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+
+	if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->length %d\n", tsb->length);
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->flags %x\n", tsb->flags);
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->dcw_offset %d\n", tsb->dcw_offset);
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->count %d\n", tsb->count);
+		residual = tsb->count - 28;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " residual %d\n", residual);
+
+		switch (tsb->flags & 0x07) {
+		case 1:	/* tsa_iostat */
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.dev_time %d\n",
+				       tsb->tsa.iostat.dev_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.def_time %d\n",
+				       tsb->tsa.iostat.def_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.queue_time %d\n",
+				       tsb->tsa.iostat.queue_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.dev_busy_time %d\n",
+				       tsb->tsa.iostat.dev_busy_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.dev_act_time %d\n",
+				       tsb->tsa.iostat.dev_act_time);
+			sense = tsb->tsa.iostat.sense;
+			break;
+		case 2: /* ts_ddpc */
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.ddpc.rcq:  ");
+			for (sl = 0; sl < 16; sl++) {
+				for (sct = 0; sct < 8; sct++) {
+					len += sprintf(page + len, " %02x",
+						       tsb->tsa.ddpc.rcq[sl]);
+				}
+				len += sprintf(page + len, "\n");
+			}
+			sense = tsb->tsa.ddpc.sense;
+			break;
+		case 3: /* tsa_intrg */
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+				      " tsb->tsa.intrg.: not supportet yet \n");
+			break;
+		}
+
+		if (sense) {
+			for (sl = 0; sl < 4; sl++) {
+				len += sprintf(page + len,
+					       KERN_ERR PRINTK_HEADER
+					       " Sense(hex) %2d-%2d:",
+					       (8 * sl), ((8 * sl) + 7));
+				for (sct = 0; sct < 8; sct++) {
+					len += sprintf(page + len, " %02x",
+						       sense[8 * sl + sct]);
+				}
+				len += sprintf(page + len, "\n");
+			}
+
+			if (sense[27] & DASD_SENSE_BIT_0) {
+				/* 24 Byte Sense Data */
+				sprintf(page + len, KERN_ERR PRINTK_HEADER
+					" 24 Byte: %x MSG %x, "
+					"%s MSGb to SYSOP\n",
+					sense[7] >> 4, sense[7] & 0x0f,
+					sense[1] & 0x10 ? "" : "no");
+			} else {
+				/* 32 Byte Sense Data */
+				sprintf(page + len, KERN_ERR PRINTK_HEADER
+					" 32 Byte: Format: %x "
+					"Exception class %x\n",
+					sense[6] & 0x0f, sense[22] >> 4);
+			}
+		} else {
+			sprintf(page + len, KERN_ERR PRINTK_HEADER
+				" SORRY - NO VALID SENSE AVAILABLE\n");
+		}
+	} else {
+		sprintf(page + len, KERN_ERR PRINTK_HEADER
+			" SORRY - NO TSB DATA AVAILABLE\n");
+	}
+	printk("%s", page);
+	free_page((unsigned long) page);
+}
+
+static void dasd_eckd_dump_sense(struct dasd_device *device,
+				 struct dasd_ccw_req *req, struct irb *irb)
+{
+	if (req && scsw_is_tm(&req->irb.scsw))
+		dasd_eckd_dump_sense_tcw(device, req, irb);
+	else
+		dasd_eckd_dump_sense_ccw(device, req, irb);
+}
+
+
 /*
  * max_blocks is dependent on the amount of storage that is available
  * in the static io buffer for each device. Currently each device has
Index: quilt-2.6/drivers/s390/block/dasd_eckd.h
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_eckd.h
+++ quilt-2.6/drivers/s390/block/dasd_eckd.h
@@ -38,8 +38,11 @@
 #define DASD_ECKD_CCW_RELEASE		 0x94
 #define DASD_ECKD_CCW_READ_CKD_MT	 0x9e
 #define DASD_ECKD_CCW_WRITE_CKD_MT	 0x9d
+#define DASD_ECKD_CCW_WRITE_TRACK_DATA	 0xA5
+#define DASD_ECKD_CCW_READ_TRACK_DATA	 0xA6
 #define DASD_ECKD_CCW_RESERVE		 0xB4
 #define DASD_ECKD_CCW_PFX		 0xE7
+#define DASD_ECKD_CCW_PFX_READ		 0xEA
 #define DASD_ECKD_CCW_RSCK		 0xF9
 
 /*
@@ -123,7 +126,9 @@ struct DE_eckd_data {
 	unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
 	__u8 ep_format;        /* Extended Parameter format byte       */
 	__u8 ep_prio;          /* Extended Parameter priority I/O byte */
-	__u8 ep_reserved[6];   /* Extended Parameter Reserved          */
+	__u8 ep_reserved1;     /* Extended Parameter Reserved	       */
+	__u8 ep_rec_per_track; /* Number of records on a track	       */
+	__u8 ep_reserved[4];   /* Extended Parameter Reserved	       */
 } __attribute__ ((packed));
 
 struct LO_eckd_data {
@@ -144,11 +149,37 @@ struct LO_eckd_data {
 	__u16 length;
 } __attribute__ ((packed));
 
+struct LRE_eckd_data {
+	struct {
+		unsigned char orientation:2;
+		unsigned char operation:6;
+	} __attribute__ ((packed)) operation;
+	struct {
+		unsigned char length_valid:1;
+		unsigned char length_scope:1;
+		unsigned char imbedded_ccw_valid:1;
+		unsigned char check_bytes:2;
+		unsigned char imbedded_count_valid:1;
+		unsigned char reserved:1;
+		unsigned char read_count_suffix:1;
+	} __attribute__ ((packed)) auxiliary;
+	__u8 imbedded_ccw;
+	__u8 count;
+	struct ch_t seek_addr;
+	struct chr_t search_arg;
+	__u8 sector;
+	__u16 length;
+	__u8 imbedded_count;
+	__u8 extended_operation;
+	__u16 extended_parameter_length;
+	__u8 extended_parameter[0];
+} __attribute__ ((packed));
+
 /* Prefix data for format 0x00 and 0x01 */
 struct PFX_eckd_data {
 	unsigned char format;
 	struct {
-		unsigned char define_extend:1;
+		unsigned char define_extent:1;
 		unsigned char time_stamp:1;
 		unsigned char verify_base:1;
 		unsigned char hyper_pav:1;
@@ -158,9 +189,8 @@ struct PFX_eckd_data {
 	__u8 aux;
 	__u8 base_lss;
 	__u8 reserved[7];
-	struct DE_eckd_data define_extend;
-	struct LO_eckd_data locate_record;
-	__u8 LO_extended_data[4];
+	struct DE_eckd_data define_extent;
+	struct LRE_eckd_data locate_record;
 } __attribute__ ((packed));
 
 struct dasd_eckd_characteristics {
Index: quilt-2.6/drivers/s390/block/dasd_eer.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_eer.c
+++ quilt-2.6/drivers/s390/block/dasd_eer.c
@@ -297,11 +297,12 @@ static void dasd_eer_write_standard_trig
 	struct dasd_eer_header header;
 	unsigned long flags;
 	struct eerbuffer *eerb;
+	char *sense;
 
 	/* go through cqr chain and count the valid sense data sets */
 	data_size = 0;
 	for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
-		if (temp_cqr->irb.esw.esw0.erw.cons)
+		if (dasd_get_sense(&temp_cqr->irb))
 			data_size += 32;
 
 	header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
@@ -316,9 +317,11 @@ static void dasd_eer_write_standard_trig
 	list_for_each_entry(eerb, &bufferlist, list) {
 		dasd_eer_start_record(eerb, header.total_size);
 		dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
-		for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
-			if (temp_cqr->irb.esw.esw0.erw.cons)
-				dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32);
+		for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
+			sense = dasd_get_sense(&temp_cqr->irb);
+			if (sense)
+				dasd_eer_write_buffer(eerb, sense, 32);
+		}
 		dasd_eer_write_buffer(eerb, "EOR", 4);
 	}
 	spin_unlock_irqrestore(&bufferlock, flags);
@@ -451,6 +454,7 @@ int dasd_eer_enable(struct dasd_device *
 {
 	struct dasd_ccw_req *cqr;
 	unsigned long flags;
+	struct ccw1 *ccw;
 
 	if (device->eer_cqr)
 		return 0;
@@ -468,10 +472,11 @@ int dasd_eer_enable(struct dasd_device *
 	cqr->expires = 10 * HZ;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
 
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS;
-	cqr->cpaddr->count = SNSS_DATA_SIZE;
-	cqr->cpaddr->flags = 0;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_SNSS;
+	ccw->count = SNSS_DATA_SIZE;
+	ccw->flags = 0;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
Index: quilt-2.6/drivers/s390/block/dasd_int.h
===================================================================
--- quilt-2.6.orig/drivers/s390/block/dasd_int.h
+++ quilt-2.6/drivers/s390/block/dasd_int.h
@@ -160,7 +160,8 @@ struct dasd_ccw_req {
 	struct dasd_block *block;	/* the originating block device */
 	struct dasd_device *memdev;	/* the device used to allocate this */
 	struct dasd_device *startdev;	/* device the request is started on */
-	struct ccw1 *cpaddr;		/* address of channel program */
+	void *cpaddr;			/* address of ccw or tcw */
+	unsigned char cpmode;		/* 0 = cmd mode, 1 = itcw */
 	char status;			/* status of this request */
 	short retries;			/* A retry counter */
 	unsigned long flags;        	/* flags of this request */
@@ -578,12 +579,14 @@ int dasd_generic_notify(struct ccw_devic
 void dasd_generic_handle_state_change(struct dasd_device *);
 
 int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
+char *dasd_get_sense(struct irb *);
 
 /* externals in dasd_devmap.c */
 extern int dasd_max_devindex;
 extern int dasd_probeonly;
 extern int dasd_autodetect;
 extern int dasd_nopav;
+extern int dasd_nofcx;
 
 int dasd_devmap_init(void);
 void dasd_devmap_exit(void);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 09/46] move sysinfo.c from drivers/s390 to arch/s390/kernel
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (7 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 08/46] dasd: add High Performance FICON support Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 10/46] delete drivers/s390/ebcdic.c Martin Schwidefsky
                   ` (36 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 108-move-sysinfo.diff --]
[-- Type: text/plain, Size: 28716 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

All in sysinfo.c is core kernel code and not driver code. So move it
to arch/s390/kernel. Also includes some small cleanups.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/Makefile  |    4 
 arch/s390/kernel/sysinfo.c |  428 +++++++++++++++++++++++++++++++++++++++++
 drivers/s390/Makefile      |    4 
 drivers/s390/sysinfo.c     |  469 ---------------------------------------------
 4 files changed, 432 insertions(+), 473 deletions(-)

Index: quilt-2.6/arch/s390/kernel/Makefile
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/Makefile
+++ quilt-2.6/arch/s390/kernel/Makefile
@@ -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
 
 obj-y	+= $(if $(CONFIG_64BIT),entry64.o,entry.o)
 obj-y	+= $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
Index: quilt-2.6/arch/s390/kernel/sysinfo.c
===================================================================
--- /dev/null
+++ quilt-2.6/arch/s390/kernel/sysinfo.c
@@ -0,0 +1,428 @@
+/*
+ *  Copyright IBM Corp. 2001, 2009
+ *  Author(s): Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
+ *	       Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <asm/ebcdic.h>
+#include <asm/sysinfo.h>
+#include <asm/cpcmd.h>
+
+/* Sigh, math-emu. Don't ask. */
+#include <asm/sfp-util.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+static inline int stsi_0(void)
+{
+	int rc = stsi(NULL, 0, 0, 0);
+	return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
+}
+
+static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
+{
+	if (stsi(info, 1, 1, 1) == -ENOSYS)
+		return len;
+
+	EBCASC(info->manufacturer, sizeof(info->manufacturer));
+	EBCASC(info->type, sizeof(info->type));
+	EBCASC(info->model, sizeof(info->model));
+	EBCASC(info->sequence, sizeof(info->sequence));
+	EBCASC(info->plant, sizeof(info->plant));
+	EBCASC(info->model_capacity, sizeof(info->model_capacity));
+	EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
+	EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
+	len += sprintf(page + len, "Manufacturer:         %-16.16s\n",
+		       info->manufacturer);
+	len += sprintf(page + len, "Type:                 %-4.4s\n",
+		       info->type);
+	if (info->model[0] != '\0')
+		/*
+		 * Sigh: the model field has been renamed with System z9
+		 * to model_capacity and a new model field has been added
+		 * after the plant field. To avoid confusing older programs
+		 * the "Model:" prints "model_capacity model" or just
+		 * "model_capacity" if the model string is empty .
+		 */
+		len += sprintf(page + len,
+			       "Model:                %-16.16s %-16.16s\n",
+			       info->model_capacity, info->model);
+	else
+		len += sprintf(page + len, "Model:                %-16.16s\n",
+			       info->model_capacity);
+	len += sprintf(page + len, "Sequence Code:        %-16.16s\n",
+		       info->sequence);
+	len += sprintf(page + len, "Plant:                %-4.4s\n",
+		       info->plant);
+	len += sprintf(page + len, "Model Capacity:       %-16.16s %08u\n",
+		       info->model_capacity, *(u32 *) info->model_cap_rating);
+	if (info->model_perm_cap[0] != '\0')
+		len += sprintf(page + len,
+			       "Model Perm. Capacity: %-16.16s %08u\n",
+			       info->model_perm_cap,
+			       *(u32 *) info->model_perm_cap_rating);
+	if (info->model_temp_cap[0] != '\0')
+		len += sprintf(page + len,
+			       "Model Temp. Capacity: %-16.16s %08u\n",
+			       info->model_temp_cap,
+			       *(u32 *) info->model_temp_cap_rating);
+	return len;
+}
+
+static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
+{
+	struct sysinfo_1_2_2_extension *ext;
+	int i;
+
+	if (stsi(info, 1, 2, 2) == -ENOSYS)
+		return len;
+	ext = (struct sysinfo_1_2_2_extension *)
+		((unsigned long) info + info->acc_offset);
+
+	len += sprintf(page + len, "\n");
+	len += sprintf(page + len, "CPUs Total:           %d\n",
+		       info->cpus_total);
+	len += sprintf(page + len, "CPUs Configured:      %d\n",
+		       info->cpus_configured);
+	len += sprintf(page + len, "CPUs Standby:         %d\n",
+		       info->cpus_standby);
+	len += sprintf(page + len, "CPUs Reserved:        %d\n",
+		       info->cpus_reserved);
+
+	if (info->format == 1) {
+		/*
+		 * Sigh 2. According to the specification the alternate
+		 * capability field is a 32 bit floating point number
+		 * if the higher order 8 bits are not zero. Printing
+		 * a floating point number in the kernel is a no-no,
+		 * always print the number as 32 bit unsigned integer.
+		 * The user-space needs to know about the strange
+		 * encoding of the alternate cpu capability.
+		 */
+		len += sprintf(page + len, "Capability:           %u %u\n",
+			       info->capability, ext->alt_capability);
+		for (i = 2; i <= info->cpus_total; i++)
+			len += sprintf(page + len,
+				       "Adjustment %02d-way:    %u %u\n",
+				       i, info->adjustment[i-2],
+				       ext->alt_adjustment[i-2]);
+
+	} else {
+		len += sprintf(page + len, "Capability:           %u\n",
+			       info->capability);
+		for (i = 2; i <= info->cpus_total; i++)
+			len += sprintf(page + len,
+				       "Adjustment %02d-way:    %u\n",
+				       i, info->adjustment[i-2]);
+	}
+
+	if (info->secondary_capability != 0)
+		len += sprintf(page + len, "Secondary Capability: %d\n",
+			       info->secondary_capability);
+	return len;
+}
+
+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));
+
+	len += sprintf(page + len, "\n");
+	len += sprintf(page + len, "LPAR Number:          %d\n",
+		       info->lpar_number);
+
+	len += sprintf(page + len, "LPAR Characteristics: ");
+	if (info->characteristics & LPAR_CHAR_DEDICATED)
+		len += sprintf(page + len, "Dedicated ");
+	if (info->characteristics & LPAR_CHAR_SHARED)
+		len += sprintf(page + len, "Shared ");
+	if (info->characteristics & LPAR_CHAR_LIMITED)
+		len += sprintf(page + len, "Limited ");
+	len += sprintf(page + len, "\n");
+
+	len += sprintf(page + len, "LPAR Name:            %-8.8s\n",
+		       info->name);
+
+	len += sprintf(page + len, "LPAR Adjustment:      %d\n",
+		       info->caf);
+
+	len += sprintf(page + len, "LPAR CPUs Total:      %d\n",
+		       info->cpus_total);
+	len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
+		       info->cpus_configured);
+	len += sprintf(page + len, "LPAR CPUs Standby:    %d\n",
+		       info->cpus_standby);
+	len += sprintf(page + len, "LPAR CPUs Reserved:   %d\n",
+		       info->cpus_reserved);
+	len += sprintf(page + len, "LPAR CPUs Dedicated:  %d\n",
+		       info->cpus_dedicated);
+	len += sprintf(page + len, "LPAR CPUs Shared:     %d\n",
+		       info->cpus_shared);
+	return len;
+}
+
+static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
+{
+	int i;
+
+	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));
+		len += sprintf(page + len, "\n");
+		len += sprintf(page + len, "VM%02d Name:            %-8.8s\n",
+			       i, info->vm[i].name);
+		len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
+			       i, info->vm[i].cpi);
+
+		len += sprintf(page + len, "VM%02d Adjustment:      %d\n",
+			       i, info->vm[i].caf);
+
+		len += sprintf(page + len, "VM%02d CPUs Total:      %d\n",
+			       i, info->vm[i].cpus_total);
+		len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
+			       i, info->vm[i].cpus_configured);
+		len += sprintf(page + len, "VM%02d CPUs Standby:    %d\n",
+			       i, info->vm[i].cpus_standby);
+		len += sprintf(page + len, "VM%02d CPUs Reserved:   %d\n",
+			       i, info->vm[i].cpus_reserved);
+	}
+	return len;
+}
+
+static int proc_read_sysinfo(char *page, char **start,
+			     off_t off, int count,
+			     int *eof, void *data)
+{
+	unsigned long info = get_zeroed_page(GFP_KERNEL);
+	int level, len;
+
+	if (!info)
+		return 0;
+
+	len = 0;
+	level = stsi_0();
+	if (level >= 1)
+		len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
+
+	if (level >= 1)
+		len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
+
+	if (level >= 2)
+		len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
+
+	if (level >= 3)
+		len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
+
+	free_page(info);
+	return len;
+}
+
+static __init int create_proc_sysinfo(void)
+{
+	create_proc_read_entry("sysinfo", 0444, NULL,
+			       proc_read_sysinfo, NULL);
+	return 0;
+}
+device_initcall(create_proc_sysinfo);
+
+/*
+ * Service levels interface.
+ */
+
+static DECLARE_RWSEM(service_level_sem);
+static LIST_HEAD(service_level_list);
+
+int register_service_level(struct service_level *slr)
+{
+	struct service_level *ptr;
+
+	down_write(&service_level_sem);
+	list_for_each_entry(ptr, &service_level_list, list)
+		if (ptr == slr) {
+			up_write(&service_level_sem);
+			return -EEXIST;
+		}
+	list_add_tail(&slr->list, &service_level_list);
+	up_write(&service_level_sem);
+	return 0;
+}
+EXPORT_SYMBOL(register_service_level);
+
+int unregister_service_level(struct service_level *slr)
+{
+	struct service_level *ptr, *next;
+	int rc = -ENOENT;
+
+	down_write(&service_level_sem);
+	list_for_each_entry_safe(ptr, next, &service_level_list, list) {
+		if (ptr != slr)
+			continue;
+		list_del(&ptr->list);
+		rc = 0;
+		break;
+	}
+	up_write(&service_level_sem);
+	return rc;
+}
+EXPORT_SYMBOL(unregister_service_level);
+
+static void *service_level_start(struct seq_file *m, loff_t *pos)
+{
+	down_read(&service_level_sem);
+	return seq_list_start(&service_level_list, *pos);
+}
+
+static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	return seq_list_next(p, &service_level_list, pos);
+}
+
+static void service_level_stop(struct seq_file *m, void *p)
+{
+	up_read(&service_level_sem);
+}
+
+static int service_level_show(struct seq_file *m, void *p)
+{
+	struct service_level *slr;
+
+	slr = list_entry(p, struct service_level, list);
+	slr->seq_print(m, slr);
+	return 0;
+}
+
+static const struct seq_operations service_level_seq_ops = {
+	.start		= service_level_start,
+	.next		= service_level_next,
+	.stop		= service_level_stop,
+	.show		= service_level_show
+};
+
+static int service_level_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &service_level_seq_ops);
+}
+
+static const struct file_operations service_level_ops = {
+	.open		= service_level_open,
+	.read		= seq_read,
+	.llseek 	= seq_lseek,
+	.release	= seq_release
+};
+
+static void service_level_vm_print(struct seq_file *m,
+				   struct service_level *slr)
+{
+	char *query_buffer, *str;
+
+	query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
+	if (!query_buffer)
+		return;
+	cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
+	str = strchr(query_buffer, '\n');
+	if (str)
+		*str = 0;
+	seq_printf(m, "VM: %s\n", query_buffer);
+	kfree(query_buffer);
+}
+
+static struct service_level service_level_vm = {
+	.seq_print = service_level_vm_print
+};
+
+static __init int create_proc_service_level(void)
+{
+	proc_create("service_levels", 0, NULL, &service_level_ops);
+	if (MACHINE_IS_VM)
+		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;
+	int rc;
+
+	info = (void *) get_zeroed_page(GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	rc = stsi(info, 1, 2, 2);
+	if (rc == -ENOSYS)
+		goto out;
+	rc = 0;
+	*capability = info->capability;
+out:
+	free_page((unsigned long) info);
+	return rc;
+}
+
+/*
+ * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
+ */
+void s390_adjust_jiffies(void)
+{
+	struct sysinfo_1_2_2 *info;
+	const unsigned int fmil = 0x4b189680;	/* 1e7 as 32-bit float. */
+	FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
+	FP_DECL_EX;
+	unsigned int capability;
+
+	info = (void *) get_zeroed_page(GFP_KERNEL);
+	if (!info)
+		return;
+
+	if (stsi(info, 1, 2, 2) != -ENOSYS) {
+		/*
+		 * Major sigh. The cpu capability encoding is "special".
+		 * If the first 9 bits of info->capability are 0 then it
+		 * is a 32 bit unsigned integer in the range 0 .. 2^23.
+		 * If the first 9 bits are != 0 then it is a 32 bit float.
+		 * In addition a lower value indicates a proportionally
+		 * higher cpu capacity. Bogomips are the other way round.
+		 * To get to a halfway suitable number we divide 1e7
+		 * by the cpu capability number. Yes, that means a floating
+		 * point division .. math-emu here we come :-)
+		 */
+		FP_UNPACK_SP(SA, &fmil);
+		if ((info->capability >> 23) == 0)
+			FP_FROM_INT_S(SB, info->capability, 32, int);
+		else
+			FP_UNPACK_SP(SB, &info->capability);
+		FP_DIV_S(SR, SA, SB);
+		FP_TO_INT_S(capability, SR, 32, 0);
+	} else
+		/*
+		 * Really old machine without stsi block for basic
+		 * cpu information. Report 42.0 bogomips.
+		 */
+		capability = 42;
+	loops_per_jiffy = capability * (500000/HZ);
+	free_page((unsigned long) info);
+}
+
+/*
+ * calibrate the delay loop
+ */
+void __cpuinit calibrate_delay(void)
+{
+	s390_adjust_jiffies();
+	/* Print the good old Bogomips line .. */
+	printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
+	       "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
+	       (loops_per_jiffy/(5000/HZ)) % 100);
+}
Index: quilt-2.6/drivers/s390/Makefile
===================================================================
--- quilt-2.6.orig/drivers/s390/Makefile
+++ quilt-2.6/drivers/s390/Makefile
@@ -2,9 +2,7 @@
 # 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 += s390mach.o
 obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
 
 drivers-y += drivers/s390/built-in.o
Index: quilt-2.6/drivers/s390/sysinfo.c
===================================================================
--- quilt-2.6.orig/drivers/s390/sysinfo.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- *  drivers/s390/sysinfo.c
- *
- *  Copyright IBM Corp. 2001, 2008
- *  Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com)
- *	       Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <asm/ebcdic.h>
-#include <asm/sysinfo.h>
-#include <asm/cpcmd.h>
-
-/* Sigh, math-emu. Don't ask. */
-#include <asm/sfp-util.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-static inline int stsi_0(void)
-{
-	int rc = stsi (NULL, 0, 0, 0);
-	return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
-}
-
-static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
-{
-	if (stsi(info, 1, 1, 1) == -ENOSYS)
-		return len;
-
-	EBCASC(info->manufacturer, sizeof(info->manufacturer));
-	EBCASC(info->type, sizeof(info->type));
-	EBCASC(info->model, sizeof(info->model));
-	EBCASC(info->sequence, sizeof(info->sequence));
-	EBCASC(info->plant, sizeof(info->plant));
-	EBCASC(info->model_capacity, sizeof(info->model_capacity));
-	EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
-	EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
-	len += sprintf(page + len, "Manufacturer:         %-16.16s\n",
-		       info->manufacturer);
-	len += sprintf(page + len, "Type:                 %-4.4s\n",
-		       info->type);
-	if (info->model[0] != '\0')
-		/*
-		 * Sigh: the model field has been renamed with System z9
-		 * to model_capacity and a new model field has been added
-		 * after the plant field. To avoid confusing older programs
-		 * the "Model:" prints "model_capacity model" or just
-		 * "model_capacity" if the model string is empty .
-		 */
-		len += sprintf(page + len,
-			       "Model:                %-16.16s %-16.16s\n",
-			       info->model_capacity, info->model);
-	else
-		len += sprintf(page + len, "Model:                %-16.16s\n",
-			       info->model_capacity);
-	len += sprintf(page + len, "Sequence Code:        %-16.16s\n",
-		       info->sequence);
-	len += sprintf(page + len, "Plant:                %-4.4s\n",
-		       info->plant);
-	len += sprintf(page + len, "Model Capacity:       %-16.16s %08u\n",
-		       info->model_capacity, *(u32 *) info->model_cap_rating);
-	if (info->model_perm_cap[0] != '\0')
-		len += sprintf(page + len,
-			       "Model Perm. Capacity: %-16.16s %08u\n",
-			       info->model_perm_cap,
-			       *(u32 *) info->model_perm_cap_rating);
-	if (info->model_temp_cap[0] != '\0')
-		len += sprintf(page + len,
-			       "Model Temp. Capacity: %-16.16s %08u\n",
-			       info->model_temp_cap,
-			       *(u32 *) info->model_temp_cap_rating);
-	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;
-	int i;
-
-	if (stsi(info, 1, 2, 2) == -ENOSYS)
-		return len;
-	ext = (struct sysinfo_1_2_2_extension *)
-		((unsigned long) info + info->acc_offset);
-
-	len += sprintf(page + len, "\n");
-	len += sprintf(page + len, "CPUs Total:           %d\n",
-		       info->cpus_total);
-	len += sprintf(page + len, "CPUs Configured:      %d\n",
-		       info->cpus_configured);
-	len += sprintf(page + len, "CPUs Standby:         %d\n",
-		       info->cpus_standby);
-	len += sprintf(page + len, "CPUs Reserved:        %d\n",
-		       info->cpus_reserved);
-
-	if (info->format == 1) {
-		/*
-		 * Sigh 2. According to the specification the alternate
-		 * capability field is a 32 bit floating point number
-		 * if the higher order 8 bits are not zero. Printing
-		 * a floating point number in the kernel is a no-no,
-		 * always print the number as 32 bit unsigned integer.
-		 * The user-space needs to know about the strange
-		 * encoding of the alternate cpu capability.
-		 */
-		len += sprintf(page + len, "Capability:           %u %u\n",
-			       info->capability, ext->alt_capability);
-		for (i = 2; i <= info->cpus_total; i++)
-			len += sprintf(page + len,
-				       "Adjustment %02d-way:    %u %u\n",
-				       i, info->adjustment[i-2],
-				       ext->alt_adjustment[i-2]);
-
-	} else {
-		len += sprintf(page + len, "Capability:           %u\n",
-			       info->capability);
-		for (i = 2; i <= info->cpus_total; i++)
-			len += sprintf(page + len,
-				       "Adjustment %02d-way:    %u\n",
-				       i, info->adjustment[i-2]);
-	}
-
-	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));
-
-	len += sprintf(page + len, "\n");
-	len += sprintf(page + len, "LPAR Number:          %d\n",
-		       info->lpar_number);
-
-	len += sprintf(page + len, "LPAR Characteristics: ");
-	if (info->characteristics & LPAR_CHAR_DEDICATED)
-		len += sprintf(page + len, "Dedicated ");
-	if (info->characteristics & LPAR_CHAR_SHARED)
-		len += sprintf(page + len, "Shared ");
-	if (info->characteristics & LPAR_CHAR_LIMITED)
-		len += sprintf(page + len, "Limited ");
-	len += sprintf(page + len, "\n");
-
-	len += sprintf(page + len, "LPAR Name:            %-8.8s\n",
-		       info->name);
-
-	len += sprintf(page + len, "LPAR Adjustment:      %d\n",
-		       info->caf);
-
-	len += sprintf(page + len, "LPAR CPUs Total:      %d\n",
-		       info->cpus_total);
-	len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
-		       info->cpus_configured);
-	len += sprintf(page + len, "LPAR CPUs Standby:    %d\n",
-		       info->cpus_standby);
-	len += sprintf(page + len, "LPAR CPUs Reserved:   %d\n",
-		       info->cpus_reserved);
-	len += sprintf(page + len, "LPAR CPUs Dedicated:  %d\n",
-		       info->cpus_dedicated);
-	len += sprintf(page + len, "LPAR CPUs Shared:     %d\n",
-		       info->cpus_shared);
-	return len;
-}
-
-static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
-{
-	int i;
-
-	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));
-		len += sprintf(page + len, "\n");
-		len += sprintf(page + len, "VM%02d Name:            %-8.8s\n",
-			       i, info->vm[i].name);
-		len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
-			       i, info->vm[i].cpi);
-
-		len += sprintf(page + len, "VM%02d Adjustment:      %d\n",
-			       i, info->vm[i].caf);
-
-		len += sprintf(page + len, "VM%02d CPUs Total:      %d\n",
-			       i, info->vm[i].cpus_total);
-		len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
-			       i, info->vm[i].cpus_configured);
-		len += sprintf(page + len, "VM%02d CPUs Standby:    %d\n",
-			       i, info->vm[i].cpus_standby);
-		len += sprintf(page + len, "VM%02d CPUs Reserved:   %d\n",
-			       i, info->vm[i].cpus_reserved);
-	}
-	return len;
-}
-
-
-static int proc_read_sysinfo(char *page, char **start,
-                             off_t off, int count,
-                             int *eof, void *data)
-{
-	unsigned long info = get_zeroed_page (GFP_KERNEL);
-	int level, len;
-	
-	if (!info)
-		return 0;
-
-	len = 0;
-	level = stsi_0();
-	if (level >= 1)
-		len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
-
-	if (level >= 1)
-		len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
-
-	if (level >= 2)
-		len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
-
-	if (level >= 3)
-		len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
-
-	free_page (info);
-        return len;
-}
-
-static __init int create_proc_sysinfo(void)
-{
-	create_proc_read_entry("sysinfo", 0444, NULL,
-			       proc_read_sysinfo, NULL);
-	return 0;
-}
-
-__initcall(create_proc_sysinfo);
-
-/*
- * Service levels interface.
- */
-
-static DECLARE_RWSEM(service_level_sem);
-static LIST_HEAD(service_level_list);
-
-int register_service_level(struct service_level *slr)
-{
-	struct service_level *ptr;
-
-	down_write(&service_level_sem);
-	list_for_each_entry(ptr, &service_level_list, list)
-		if (ptr == slr) {
-			up_write(&service_level_sem);
-			return -EEXIST;
-		}
-	list_add_tail(&slr->list, &service_level_list);
-	up_write(&service_level_sem);
-	return 0;
-}
-EXPORT_SYMBOL(register_service_level);
-
-int unregister_service_level(struct service_level *slr)
-{
-	struct service_level *ptr, *next;
-	int rc = -ENOENT;
-
-	down_write(&service_level_sem);
-	list_for_each_entry_safe(ptr, next, &service_level_list, list) {
-		if (ptr != slr)
-			continue;
-		list_del(&ptr->list);
-		rc = 0;
-		break;
-	}
-	up_write(&service_level_sem);
-	return rc;
-}
-EXPORT_SYMBOL(unregister_service_level);
-
-static void *service_level_start(struct seq_file *m, loff_t *pos)
-{
-	down_read(&service_level_sem);
-	return seq_list_start(&service_level_list, *pos);
-}
-
-static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
-{
-	return seq_list_next(p, &service_level_list, pos);
-}
-
-static void service_level_stop(struct seq_file *m, void *p)
-{
-	up_read(&service_level_sem);
-}
-
-static int service_level_show(struct seq_file *m, void *p)
-{
-	struct service_level *slr;
-
-	slr = list_entry(p, struct service_level, list);
-	slr->seq_print(m, slr);
-	return 0;
-}
-
-static const struct seq_operations service_level_seq_ops = {
-	.start		= service_level_start,
-	.next		= service_level_next,
-	.stop		= service_level_stop,
-	.show		= service_level_show
-};
-
-static int service_level_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &service_level_seq_ops);
-}
-
-static const struct file_operations service_level_ops = {
-	.open		= service_level_open,
-	.read		= seq_read,
-	.llseek 	= seq_lseek,
-	.release	= seq_release
-};
-
-static void service_level_vm_print(struct seq_file *m,
-				   struct service_level *slr)
-{
-	char *query_buffer, *str;
-
-	query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
-	if (!query_buffer)
-		return;
-	cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
-	str = strchr(query_buffer, '\n');
-	if (str)
-		*str = 0;
-	seq_printf(m, "VM: %s\n", query_buffer);
-	kfree(query_buffer);
-}
-
-static struct service_level service_level_vm = {
-	.seq_print = service_level_vm_print
-};
-
-static __init int create_proc_service_level(void)
-{
-	proc_create("service_levels", 0, NULL, &service_level_ops);
-	if (MACHINE_IS_VM)
-		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;
-	int rc;
-
-	info = (void *) get_zeroed_page(GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-	rc = stsi(info, 1, 2, 2);
-	if (rc == -ENOSYS)
-		goto out;
-	rc = 0;
-	*capability = info->capability;
-out:
-	free_page((unsigned long) info);
-	return rc;
-}
-
-/*
- * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
- */
-void s390_adjust_jiffies(void)
-{
-	struct sysinfo_1_2_2 *info;
-	const unsigned int fmil = 0x4b189680;	/* 1e7 as 32-bit float. */
-	FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
-	FP_DECL_EX;
-	unsigned int capability;
-
-	info = (void *) get_zeroed_page(GFP_KERNEL);
-	if (!info)
-		return;
-
-	if (stsi(info, 1, 2, 2) != -ENOSYS) {
-		/*
-		 * Major sigh. The cpu capability encoding is "special".
-		 * If the first 9 bits of info->capability are 0 then it
-		 * is a 32 bit unsigned integer in the range 0 .. 2^23.
-		 * If the first 9 bits are != 0 then it is a 32 bit float.
-		 * In addition a lower value indicates a proportionally
-		 * higher cpu capacity. Bogomips are the other way round.
-		 * To get to a halfway suitable number we divide 1e7
-		 * by the cpu capability number. Yes, that means a floating
-		 * point division .. math-emu here we come :-)
-		 */
-		FP_UNPACK_SP(SA, &fmil);
-		if ((info->capability >> 23) == 0)
-			FP_FROM_INT_S(SB, info->capability, 32, int);
-		else
-			FP_UNPACK_SP(SB, &info->capability);
-		FP_DIV_S(SR, SA, SB);
-		FP_TO_INT_S(capability, SR, 32, 0);
-	} else
-		/*
-		 * Really old machine without stsi block for basic
-		 * cpu information. Report 42.0 bogomips.
-		 */
-		capability = 42;
-	loops_per_jiffy = capability * (500000/HZ);
-	free_page((unsigned long) info);
-}
-
-/*
- * calibrate the delay loop
- */
-void __cpuinit calibrate_delay(void)
-{
-	s390_adjust_jiffies();
-	/* Print the good old Bogomips line .. */
-	printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
-	       "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
-	       (loops_per_jiffy/(5000/HZ)) % 100);
-}

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 10/46] delete drivers/s390/ebcdic.c
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (8 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 09/46] move sysinfo.c from drivers/s390 to arch/s390/kernel Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 11/46] arch/s390/kernel/process.c: fix whitespace damage Martin Schwidefsky
                   ` (35 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: 109-delete-ebcdic.diff --]
[-- Type: text/plain, Size: 11990 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Dead file. Seems to be a leftover from the 2.4->2.5 conversion.
The used and uptodate version of this file is in arch/s390/kernel.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/ebcdic.c |  246 --------------------------------------------------
 1 file changed, 246 deletions(-)

Index: quilt-2.6/drivers/s390/ebcdic.c
===================================================================
--- quilt-2.6.orig/drivers/s390/ebcdic.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- *  arch/s390/kernel/ebcdic.c
- *    ECBDIC -> ASCII, ASCII -> ECBDIC conversion tables.
- *
- *  S390 version
- *    Copyright (C) 1998 IBM Corporation
- *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <asm/types.h>
-
-/*
- * ASCII -> EBCDIC
- */
-__u8 _ascebc[256] =
-{
- /*00  NL    SH    SX    EX    ET    NQ    AK    BL */
-     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08  BS    HT    LF    VT    FF    CR    SO    SI */
-     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10  DL    D1    D2    D3    D4    NK    SN    EB */
-     0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
- /*18  CN    EM    SB    EC    FS    GS    RS    US */
-     0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20  SP     !     "     #     $     %     &     ' */
-     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28   (     )     *     +     ,     -    .      / */
-     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30   0     1     2     3     4     5     6     7 */
-     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38   8     9     :     ;     <     =     >     ? */
-     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40   @     A     B     C     D     E     F     G */
-     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48   H     I     J     K     L     M     N     O */
-     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50   P     Q     R     S     T     U     V     W */
-     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58   X     Y     Z     [     \     ]     ^     _ */
-     0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
- /*60   `     a     b     c     d     e     f     g */
-     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68   h     i     j     k     l     m     n     o */
-     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70   p     q     r     s     t     u     v     w */
-     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78   x     y     z     {     |     }     ~    DL */
-     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-/*
- * EBCDIC -> ASCII
- */
-__u8 _ebcasc[256] =
-{
- /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
-          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
-          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
-                                  -ENP  ->LF             */
-          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
-                                                    -IUS */
-          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
-                                  -INP                   */
-          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                       -SW                               */ 
-          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
-          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
-          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40    SP   RSP           ä              ----       */
-          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48                       .     <     (     +     | */
-          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50     &                                      ---- */
-          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58           ß     !     $     *     )     ;       */
-          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60     -     /  ----     Ä  ----  ----  ----       */
-          0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68              ----     ,     %     _     >     ? */ 
-          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
-          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78     *     `     :     #     @     '     =     " */
-          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80     *     a     b     c     d     e     f     g */
-          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88     h     i              ----  ----  ----       */
-          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90     °     j     k     l     m     n     o     p */
-          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98     q     r                    ----        ---- */
-          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0           ~     s     t     u     v     w     x */
-          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8     y     z              ----  ----  ----  ---- */
-          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0     ^                    ----     §  ----       */
-          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
-          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0     {     A     B     C     D     E     F     G */
-          0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8     H     I  ----           ö              ---- */
-          0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0     }     J     K     L     M     N     O     P */
-          0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8     Q     R  ----           ü                   */
-          0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0     \           S     T     U     V     W     X */
-          0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8     Y     Z        ----     Ö  ----  ----  ---- */
-          0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0     0     1     2     3     4     5     6     7 */
-          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8     8     9  ----  ----     Ü  ----  ----  ---- */
-          0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
-
-/*
- * EBCDIC (capitals) -> ASCII (small case)
- */
-__u8 _ebcasc_reduce_case[256] =
-{
- /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
-          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
-
- /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
-          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-
- /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
-                                  -ENP  ->LF             */
-          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
-
- /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
-                                                    -IUS */
-          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
-                                  -INP                   */
-          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
-
- /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                       -SW                               */ 
-          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
-
- /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
-          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
-
- /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
-          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
-
- /* 0x40    SP   RSP           ä              ----       */
-          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
-
- /* 0x48                       .     <     (     +     | */
-          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
-
- /* 0x50     &                                      ---- */
-          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
-
- /* 0x58           ß     !     $     *     )     ;       */
-          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
-
- /* 0x60     -     /  ----     Ä  ----  ----  ----       */
-          0x2D, 0x2F, 0x07, 0x84, 0x07, 0x07, 0x07, 0x8F,
-
- /* 0x68              ----     ,     %     _     >     ? */ 
-          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
-
- /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
-          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x78     *     `     :     #     @     '     =     " */
-          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
-
- /* 0x80     *     a     b     c     d     e     f     g */
-          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0x88     h     i              ----  ----  ----       */
-          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
-
- /* 0x90     °     j     k     l     m     n     o     p */
-          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0x98     q     r                    ----        ---- */
-          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
-
- /* 0xA0           ~     s     t     u     v     w     x */
-          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xA8     y     z              ----  ----  ----  ---- */
-          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xB0     ^                    ----     §  ----       */
-          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
-
- /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
-          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xC0     {     A     B     C     D     E     F     G */
-          0x7B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0xC8     H     I  ----           ö              ---- */
-          0x68, 0x69, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
-
- /* 0xD0     }     J     K     L     M     N     O     P */
-          0x7D, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0xD8     Q     R  ----           ü                   */
-          0x71, 0x72, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
-
- /* 0xE0     \           S     T     U     V     W     X */
-          0x5C, 0xF6, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xE8     Y     Z        ----     Ö  ----  ----  ---- */
-          0x79, 0x7A, 0xFD, 0x07, 0x94, 0x07, 0x07, 0x07,
-
- /* 0xF0     0     1     2     3     4     5     6     7 */
-          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-
- /* 0xF8     8     9  ----  ----     Ü  ----  ----  ---- */
-          0x38, 0x39, 0x07, 0x07, 0x81, 0x07, 0x07, 0x07
-};

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 11/46] arch/s390/kernel/process.c: fix whitespace damage
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (9 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 10/46] delete drivers/s390/ebcdic.c Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 12/46] cputime: initialize per thread timer values on fork Martin Schwidefsky
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 110-process-whitespace.diff --]
[-- Type: text/plain, Size: 4155 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Fix all the whitespace damage in process.c, especially copy_thread().
Next patch will add code to copy_thread() which needs to 'fixed' first.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/process.c |   62 ++++++++++++++++++---------------------------
 1 file changed, 26 insertions(+), 36 deletions(-)

Index: quilt-2.6/arch/s390/kernel/process.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/process.c
+++ quilt-2.6/arch/s390/kernel/process.c
@@ -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>
@@ -168,34 +160,34 @@ void release_thread(struct task_struct *
 }
 
 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;
+	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;
+	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 +212,9 @@ int copy_thread(int nr, unsigned long cl
 #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));
+	return 0;
 }
 
 SYSCALL_DEFINE0(fork)
@@ -311,7 +302,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.
 	 */
@@ -346,4 +337,3 @@ unsigned long get_wchan(struct task_stru
 	}
 	return 0;
 }
-

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 12/46] cputime: initialize per thread timer values on fork
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (10 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 11/46] arch/s390/kernel/process.c: fix whitespace damage Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 13/46] hvc_iucv: Update and add missing kernel messages Martin Schwidefsky
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 111-cputime-thread.diff --]
[-- Type: text/plain, Size: 1310 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Initialize per thread timer values instead of just copying them from
the parent. That way it is easily possible to tell how much time a
thread spent in user/system context.
Doesn't fix a bug, this is just for debugging purposes.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/process.c |    5 +++++
 1 file changed, 5 insertions(+)

Index: quilt-2.6/arch/s390/kernel/process.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/process.c
+++ quilt-2.6/arch/s390/kernel/process.c
@@ -163,6 +163,7 @@ int copy_thread(int nr, unsigned long cl
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
+	struct thread_info *ti;
 	struct fake_frame
 	{
 		struct stack_frame sf;
@@ -214,6 +215,10 @@ int copy_thread(int nr, unsigned long cl
 	p->thread.mm_segment = get_fs();
 	/* 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;
 }
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 13/46] hvc_iucv: Update and add missing kernel messages
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (11 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 12/46] cputime: initialize per thread timer values on fork Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 14/46] hvc_iucv: Provide IUCV z/VM user ID filtering Martin Schwidefsky
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Hendrik Brueckner, Martin Schwidefsky

[-- Attachment #1: 112-hvc_iucv-msg.diff --]
[-- Type: text/plain, Size: 1373 bytes --]

From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>

If the hvc_iucv= kernel parameter specifies a value that is not
valid, display an error message.
Minor changes to existing kernel messages.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/char/hvc_iucv.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Index: quilt-2.6/drivers/char/hvc_iucv.c
===================================================================
--- quilt-2.6.orig/drivers/char/hvc_iucv.c
+++ quilt-2.6/drivers/char/hvc_iucv.c
@@ -885,7 +885,7 @@ static int __init hvc_iucv_init(void)
 	unsigned int i;
 
 	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;
 	}
@@ -893,8 +893,11 @@ static int __init hvc_iucv_init(void)
 	if (!hvc_iucv_devices)
 		return -ENODEV;
 
-	if (hvc_iucv_devices > MAX_HVC_IUCV_LINES)
+	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);
 		return -EINVAL;
+	}
 
 	hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
 					   sizeof(struct iucv_tty_buffer),

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 14/46] hvc_iucv: Provide IUCV z/VM user ID filtering
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (12 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 13/46] hvc_iucv: Update and add missing kernel messages Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 15/46] lockdep: trace hardirq off in smp_send_stop Martin Schwidefsky
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Hendrik Brueckner, Martin Schwidefsky

[-- Attachment #1: 113-hvc_iucv-auth.diff --]
[-- Type: text/plain, Size: 10745 bytes --]

From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>

This patch introduces the kernel parameter hvc_iucv_allow= that specifies
a comma-separated list of z/VM user IDs.
If specified, the z/VM IUCV hypervisor console device driver accepts IUCV
connections from listed z/VM user IDs only.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 Documentation/kernel-parameters.txt |    3 
 drivers/char/hvc_iucv.c             |  254 ++++++++++++++++++++++++++++++++++--
 2 files changed, 249 insertions(+), 8 deletions(-)

Index: quilt-2.6/Documentation/kernel-parameters.txt
===================================================================
--- quilt-2.6.orig/Documentation/kernel-parameters.txt
+++ quilt-2.6/Documentation/kernel-parameters.txt
@@ -829,6 +829,9 @@ and is between 256 and 4096 characters. 
 
 	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: quilt-2.6/drivers/char/hvc_iucv.c
===================================================================
--- quilt-2.6.orig/drivers/char/hvc_iucv.c
+++ quilt-2.6/drivers/char/hvc_iucv.c
@@ -13,10 +13,11 @@
 
 #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 = 
 /* 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;
@@ -618,6 +625,27 @@ static void hvc_iucv_notifier_del(struct
 }
 
 /**
+ * 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)
  * @ipvmid:	z/VM system identifier of originator
@@ -641,6 +669,7 @@ static	int hvc_iucv_path_pending(struct 
 {
 	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 
 	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
@@ -877,6 +920,171 @@ static int __init hvc_iucv_alloc(int id,
 }
 
 /**
+ * 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
  */
 static int __init hvc_iucv_init(void)
@@ -884,19 +1092,44 @@ static int __init hvc_iucv_init(void)
 	int rc;
 	unsigned int i;
 
+	if (!hvc_iucv_devices)
+		return -ENODEV;
+
 	if (!MACHINE_IS_VM) {
 		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);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out_error;
+	}
+
+	/* 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,
@@ -904,7 +1137,8 @@ static int __init hvc_iucv_init(void)
 					   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,
@@ -912,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
@@ -956,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;
 }
 
@@ -971,3 +1208,4 @@ static	int __init hvc_iucv_config(char *
 
 device_initcall(hvc_iucv_init);
 __setup("hvc_iucv=", hvc_iucv_config);
+core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 15/46] lockdep: trace hardirq off in smp_send_stop
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (13 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 14/46] hvc_iucv: Provide IUCV z/VM user ID filtering Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 16/46] check addressing mode in s390_enable_sie Martin Schwidefsky
                   ` (30 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Christian Borntraeger, Martin Schwidefsky

[-- Attachment #1: 114-lockdep-send-stop.diff --]
[-- Type: text/plain, Size: 1641 bytes --]

From: Christian Borntraeger <borntraeger@de.ibm.com>

With lockdep we got the following trace after a panic:

Badness at /home/autobuild/BUILD/linux-2.6.28-20090204/kernel/lockdep.c:2878
[...]
Call Trace:
 [<0000000000176334>] lock_acquire+0x54/0xbc
 [<000000000050b4fe>] __atomic_notifier_call_chain+0x6e/0xdc
 [<000000000050b59c>] atomic_notifier_call_chain+0x30/0x44
 [<0000000000504274>] panic+0xd0/0x1e8
[...]
INFO: lockdep is turned off.
Last Breaking-Event-Address:
 [<0000000000170e62>] check_flags+0xae/0x15c
possible reason: unannotated irqs-off.

lockdep is right. We missed a trace_hardirq_off in our smp_send_stop
function and smp_send_stop is called before the panic call chain.

Reported-by: Mijo <Safradin mijo@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/smp.c |    2 ++
 1 file changed, 2 insertions(+)

Index: quilt-2.6/arch/s390/kernel/smp.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/smp.c
+++ quilt-2.6/arch/s390/kernel/smp.c
@@ -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>
@@ -75,6 +76,7 @@ void smp_send_stop(void)
 
 	/* Disable all interrupts/machine checks */
 	__load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
+	trace_hardirqs_off();
 
 	/* stop all processors */
 	for_each_online_cpu(cpu) {

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 16/46] check addressing mode in s390_enable_sie
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (14 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 15/46] lockdep: trace hardirq off in smp_send_stop Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 17/46] Fix hypervisor detection for KVM Martin Schwidefsky
                   ` (29 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Carsten Otte, Martin Schwidefsky

[-- Attachment #1: 115-kvm-amode-check.diff --]
[-- Type: text/plain, Size: 1012 bytes --]

From: Carsten Otte <cotte@de.ibm.com>

The sie instruction requires address spaces to be switched
to run proper. This patch verifies that this is the case
in s390_enable_sie, otherwise the kernel would crash badly
as soon as the process runs into sie.

Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/mm/pgtable.c |    4 ++++
 1 file changed, 4 insertions(+)

Index: quilt-2.6/arch/s390/mm/pgtable.c
===================================================================
--- quilt-2.6.orig/arch/s390/mm/pgtable.c
+++ quilt-2.6/arch/s390/mm/pgtable.c
@@ -256,6 +256,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;

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 17/46] Fix hypervisor detection for KVM
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (15 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 16/46] check addressing mode in s390_enable_sie Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 18/46] ftrace: dont trace machine check handler Martin Schwidefsky
                   ` (28 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Christian Borntraeger, Martin Schwidefsky

[-- Attachment #1: 116-kvm-detection.diff --]
[-- Type: text/plain, Size: 4105 bytes --]

From: Christian Borntraeger <borntraeger@de.ibm.com>

Currently we use the cpuid (via STIDP instruction) to recognize LPAR,
z/VM and KVM.
The architecture states, that bit 0-7 of STIDP returns all zero, and
if STIDP is executed in a virtual machine, the VM operating system
will replace bits 0-7 with FF.

KVM should not use FE to distinguish z/VM from KVM for interested
guests. The proper way to detect the hypervisor is the STSI (Store
System Information) instruction, which return information about the
hypervisors via function code 3, selector1=2, selector2=2.

This patch changes the detection routine of Linux to use STSI instead
of STIDP. This detection is earlier than bootmem, we have to use a
static buffer. Since STSI expects a 4kb block (4kb aligned) this
patch also changes the init.data alignment for s390. As this section
will be freed during boot, this should be no problem.

Patch is tested with LPAR, z/VM, KVM on LPAR, and KVM under z/VM.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/sysinfo.h |    1 +
 arch/s390/kernel/early.c        |   22 +++++++++++++---------
 arch/s390/kernel/vmlinux.lds.S  |    2 ++
 arch/s390/kvm/kvm-s390.c        |    2 +-
 4 files changed, 17 insertions(+), 10 deletions(-)

Index: quilt-2.6/arch/s390/include/asm/sysinfo.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/sysinfo.h
+++ quilt-2.6/arch/s390/include/asm/sysinfo.h
@@ -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: quilt-2.6/arch/s390/kernel/early.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/early.c
+++ quilt-2.6/arch/s390/kernel/early.c
@@ -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_
 		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)
Index: quilt-2.6/arch/s390/kernel/vmlinux.lds.S
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/vmlinux.lds.S
+++ quilt-2.6/arch/s390/kernel/vmlinux.lds.S
@@ -108,6 +108,8 @@ SECTIONS
 		EXIT_TEXT
 	}
 
+	/* early.c uses stsi, which requires page aligned data. */
+	. = ALIGN(PAGE_SIZE);
 	.init.data : {
 		INIT_DATA
 	}
Index: quilt-2.6/arch/s390/kvm/kvm-s390.c
===================================================================
--- quilt-2.6.orig/arch/s390/kvm/kvm-s390.c
+++ quilt-2.6/arch/s390/kvm/kvm-s390.c
@@ -286,7 +286,7 @@ int kvm_arch_vcpu_setup(struct kvm_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;
 }
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 18/46] ftrace: dont trace machine check handler
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (16 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 17/46] Fix hypervisor detection for KVM Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 19/46] Fix appldata build break with !NET Martin Schwidefsky
                   ` (27 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 117-ftrace-notrace.diff --]
[-- Type: text/plain, Size: 950 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

The ftrace code is currently not reentrant, so we better don't trace
our machine check handler. Machine checks are handled like NMIs on s390.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/s390mach.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Index: quilt-2.6/drivers/s390/s390mach.c
===================================================================
--- quilt-2.6.orig/drivers/s390/s390mach.c
+++ quilt-2.6/drivers/s390/s390mach.c
@@ -357,8 +357,7 @@ s390_revalidate_registers(struct mci *mc
 /*
  * machine check handler.
  */
-void
-s390_do_machine_check(struct pt_regs *regs)
+void notrace s390_do_machine_check(struct pt_regs *regs)
 {
 	static DEFINE_SPINLOCK(ipd_lock);
 	static unsigned long long last_ipd;

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 19/46] Fix appldata build break with !NET
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (17 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 18/46] ftrace: dont trace machine check handler Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 20/46] split/move machine check handler code Martin Schwidefsky
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Sachin Sant, Martin Schwidefsky

[-- Attachment #1: 118-appldata-build.diff --]
[-- Type: text/plain, Size: 1311 bytes --]

From: Sachin Sant <sachinp@in.ibm.com>

With CONFIG_NET not set appldata build breaks on s390.

arch/s390/appldata/built-in.o: In function appldata_get_net_sum_data:
appldata_net_sum.c:(.text+0x2684): undefined reference to dev_get_stats
appldata_net_sum.c:(.text+0x2688): undefined reference to init_net
appldata_net_sum.c:(.text+0x268c): undefined reference to init_net
appldata_net_sum.c:(.text+0x2694): undefined reference to dev_base_lock

The following patch fixes the issue for me.

Signed-off-by: Sachin Sant <sachinp@in.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/Kconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: quilt-2.6/arch/s390/Kconfig
===================================================================
--- quilt-2.6.orig/arch/s390/Kconfig
+++ quilt-2.6/arch/s390/Kconfig
@@ -521,7 +521,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

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 20/46] split/move machine check handler code
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (18 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 19/46] Fix appldata build break with !NET Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 21/46] Remove CONFIG_MACHCHK_WARNING Martin Schwidefsky
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 119-split-mcck.diff --]
[-- Type: text/plain, Size: 45258 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Split machine check handler code and move it to cio and kernel code
where it belongs to. No functional change.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/crw.h |   68 +++++
 arch/s390/include/asm/nmi.h |   66 +++++
 arch/s390/kernel/Makefile   |    2 
 arch/s390/kernel/nmi.c      |  383 +++++++++++++++++++++++++++++++
 arch/s390/kernel/process.c  |    2 
 arch/s390/kvm/kvm-s390.c    |    4 
 drivers/s390/Makefile       |    1 
 drivers/s390/cio/Makefile   |    2 
 drivers/s390/cio/chp.c      |    6 
 drivers/s390/cio/chsc.c     |    6 
 drivers/s390/cio/cio.c      |    3 
 drivers/s390/cio/crw.c      |  145 +++++++++++
 drivers/s390/cio/css.c      |    6 
 drivers/s390/s390mach.c     |  537 --------------------------------------------
 drivers/s390/s390mach.h     |  122 ---------
 15 files changed, 677 insertions(+), 676 deletions(-)

Index: quilt-2.6/arch/s390/include/asm/crw.h
===================================================================
--- /dev/null
+++ quilt-2.6/arch/s390/include/asm/crw.h
@@ -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: quilt-2.6/arch/s390/include/asm/nmi.h
===================================================================
--- /dev/null
+++ quilt-2.6/arch/s390/include/asm/nmi.h
@@ -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: quilt-2.6/arch/s390/kernel/Makefile
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/Makefile
+++ quilt-2.6/arch/s390/kernel/Makefile
@@ -22,7 +22,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -
 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 sysinfo.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)
Index: quilt-2.6/arch/s390/kernel/nmi.c
===================================================================
--- /dev/null
+++ quilt-2.6/arch/s390/kernel/nmi.c
@@ -0,0 +1,383 @@
+/*
+ *   Machine check handler
+ *
+ *    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/errno.h>
+#include <linux/time.h>
+#include <linux/module.h>
+#include <asm/lowcore.h>
+#include <asm/smp.h>
+#include <asm/etr.h>
+#include <asm/cpu.h>
+#include <asm/nmi.h>
+#include <asm/crw.h>
+
+struct mcck_struct {
+	int kill_task;
+	int channel_report;
+	int warning;
+	unsigned long long mcck_code;
+};
+
+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)
+{
+	unsigned long flags;
+	struct mcck_struct mcck;
+
+	/*
+	 * Disable machine checks and get the current state of accumulated
+	 * machine checks. Afterwards delete the old state and enable machine
+	 * checks again.
+	 */
+	local_irq_save(flags);
+	local_mcck_disable();
+	mcck = __get_cpu_var(cpu_mcck);
+	memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
+	clear_thread_flag(TIF_MCCK_PENDING);
+	local_mcck_enable();
+	local_irq_restore(flags);
+
+	if (mcck.channel_report)
+		crw_handle_channel_report();
+
+#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.
+ */
+	if (mcck.warning) {	/* WARNING pending ? */
+		static int mchchk_wng_posted = 0;
+		/*
+		 * Use single machine clear, as we cannot handle smp right now
+		 */
+		__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 "
+		       "malfunction (code 0x%016llx).\n", mcck.mcck_code);
+		printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
+		       current->comm, current->pid);
+		do_exit(SIGSEGV);
+	}
+}
+EXPORT_SYMBOL_GPL(s390_handle_mcck);
+
+/*
+ * returns 0 if all registers could be validated
+ * returns 1 otherwise
+ */
+static int notrace s390_revalidate_registers(struct mci *mci)
+{
+	int kill_task;
+	u64 tmpclock;
+	u64 zero;
+	void *fpt_save_area, *fpt_creg_save_area;
+
+	kill_task = 0;
+	zero = 0;
+
+	if (!mci->gr) {
+		/*
+		 * General purpose registers couldn't be restored and have
+		 * unknown contents. Process needs to be terminated.
+		 */
+		kill_task = 1;
+	}
+	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"
+		"	ld	2,8(%0)\n"
+		"	ld	4,16(%0)\n"
+		"	ld	6,24(%0)"
+		: : "a" (&S390_lowcore.floating_pt_save_area));
+#endif
+
+	if (MACHINE_HAS_IEEE) {
+#ifdef CONFIG_64BIT
+		fpt_save_area = &S390_lowcore.floating_pt_save_area;
+		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;
+#endif
+		if (!mci->fc) {
+			/*
+			 * Floating point control register can't be restored.
+			 * Task will be terminated.
+			 */
+			asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
+			kill_task = 1;
+
+		} else
+			asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
+
+		asm volatile(
+			"	ld	0,0(%0)\n"
+			"	ld	1,8(%0)\n"
+			"	ld	2,16(%0)\n"
+			"	ld	3,24(%0)\n"
+			"	ld	4,32(%0)\n"
+			"	ld	5,40(%0)\n"
+			"	ld	6,48(%0)\n"
+			"	ld	7,56(%0)\n"
+			"	ld	8,64(%0)\n"
+			"	ld	9,72(%0)\n"
+			"	ld	10,80(%0)\n"
+			"	ld	11,88(%0)\n"
+			"	ld	12,96(%0)\n"
+			"	ld	13,104(%0)\n"
+			"	ld	14,112(%0)\n"
+			"	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) {
+		/*
+		 * Access registers have unknown contents.
+		 * Terminating task.
+		 */
+		kill_task = 1;
+	}
+	/* Revalidate control registers */
+	if (!mci->cr) {
+		/*
+		 * Control registers have unknown contents.
+		 * Can't recover and therefore stopping machine.
+		 */
+		s390_handle_damage("invalid control registers.");
+	} else {
+#ifdef CONFIG_64BIT
+		asm volatile(
+			"	lctlg	0,15,0(%0)"
+			: : "a" (&S390_lowcore.cregs_save_area));
+#else
+		asm volatile(
+			"	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
+	 * old contents (should be zero) otherwise set it to zero.
+	 */
+	if (!mci->pr)
+		asm volatile(
+			"	sr	0,0\n"
+			"	sckpf"
+			: : : "0", "cc");
+	else
+		asm volatile(
+			"	l	0,0(%0)\n"
+			"	sckpf"
+			: : "a" (&S390_lowcore.tod_progreg_save_area)
+			: "0", "cc");
+#endif
+	/* Revalidate clock comparator register */
+	asm volatile(
+		"	stck	0(%1)\n"
+		"	sckc	0(%1)"
+		: "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
+
+	/* Check if old PSW is valid */
+	if (!mci->wp)
+		/*
+		 * Can't tell if we come from user or kernel mode
+		 * -> stopping machine.
+		 */
+		s390_handle_damage("old psw invalid.");
+
+	if (!mci->ms || !mci->pm || !mci->ia)
+		kill_task = 1;
+
+	return kill_task;
+}
+
+#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 notrace s390_do_machine_check(struct pt_regs *regs)
+{
+	static int ipd_count;
+	static DEFINE_SPINLOCK(ipd_lock);
+	static unsigned long long last_ipd;
+	struct mcck_struct *mcck;
+	unsigned long long tmp;
+	struct mci *mci;
+	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) {
+		/* 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 */
+			u64 z_mcic, o_mcic, t_mcic;
+#ifdef CONFIG_64BIT
+			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
+			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+				  1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
+				  1ULL<<16);
+#else
+			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
+				  1ULL<<29);
+			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+				  1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
+#endif
+			t_mcic = *(u64 *)mci;
+
+			if (((t_mcic & z_mcic) != 0) ||
+			    ((t_mcic & o_mcic) != o_mcic)) {
+				s390_handle_damage("processing backup machine "
+						   "check with damage.");
+			}
+
+			/*
+			 * 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 {
+			/* Processing damage -> stopping machine */
+			s390_handle_damage("received instruction processing "
+					   "damage machine check.");
+		}
+	}
+	if (s390_revalidate_registers(mci)) {
+		if (umode) {
+			/*
+			 * Couldn't restore all register contents while in
+			 * user mode -> mark task for termination.
+			 */
+			mcck->kill_task = 1;
+			mcck->mcck_code = *(unsigned long long *) mci;
+			set_thread_flag(TIF_MCCK_PENDING);
+		} 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))
+			etr_sync_check();
+		if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
+			etr_switch_to_local();
+		if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))
+			stp_sync_check();
+		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;
+		set_thread_flag(TIF_MCCK_PENDING);
+	}
+	lockdep_on();
+}
+
+static int __init machine_check_init(void)
+{
+	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, 24);	/* enable warning MCH */
+#endif
+	return 0;
+}
+arch_initcall(machine_check_init);
Index: quilt-2.6/arch/s390/kernel/process.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/process.c
+++ quilt-2.6/arch/s390/kernel/process.c
@@ -39,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");
@@ -68,7 +69,6 @@ unsigned long thread_saved_pc(struct tas
 	return sf->gprs[8];
 }
 
-extern void s390_handle_mcck(void);
 /*
  * The idle loop on a S390...
  */
Index: quilt-2.6/arch/s390/kvm/kvm-s390.c
===================================================================
--- quilt-2.6.orig/arch/s390/kvm/kvm-s390.c
+++ quilt-2.6/arch/s390/kvm/kvm-s390.c
@@ -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"
 
@@ -440,8 +440,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(stru
 	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: quilt-2.6/drivers/s390/cio/chp.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/chp.c
+++ quilt-2.6/drivers/s390/cio/chp.c
@@ -17,8 +17,8 @@
 #include <linux/errno.h>
 #include <asm/chpid.h>
 #include <asm/sclp.h>
+#include <asm/crw.h>
 
-#include "../s390mach.h"
 #include "cio.h"
 #include "css.h"
 #include "ioasm.h"
@@ -706,12 +706,12 @@ static int __init chp_init(void)
 	struct chp_id chpid;
 	int ret;
 
-	ret = s390_register_crw_handler(CRW_RSC_CPATH, chp_process_crw);
+	ret = crw_register_handler(CRW_RSC_CPATH, chp_process_crw);
 	if (ret)
 		return ret;
 	chp_wq = create_singlethread_workqueue("cio_chp");
 	if (!chp_wq) {
-		s390_unregister_crw_handler(CRW_RSC_CPATH);
+		crw_unregister_handler(CRW_RSC_CPATH);
 		return -ENOMEM;
 	}
 	INIT_WORK(&cfg_work, cfg_func);
Index: quilt-2.6/drivers/s390/cio/chsc.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/chsc.c
+++ quilt-2.6/drivers/s390/cio/chsc.c
@@ -19,8 +19,8 @@
 #include <asm/cio.h>
 #include <asm/chpid.h>
 #include <asm/chsc.h>
+#include <asm/crw.h>
 
-#include "../s390mach.h"
 #include "css.h"
 #include "cio.h"
 #include "cio_debug.h"
@@ -820,7 +820,7 @@ int __init chsc_alloc_sei_area(void)
 			      "chsc machine checks!\n");
 		return -ENOMEM;
 	}
-	ret = s390_register_crw_handler(CRW_RSC_CSS, chsc_process_crw);
+	ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw);
 	if (ret)
 		kfree(sei_page);
 	return ret;
@@ -828,7 +828,7 @@ int __init chsc_alloc_sei_area(void)
 
 void __init chsc_free_sei_area(void)
 {
-	s390_unregister_crw_handler(CRW_RSC_CSS);
+	crw_unregister_handler(CRW_RSC_CSS);
 	kfree(sei_page);
 }
 
Index: quilt-2.6/drivers/s390/cio/cio.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/cio.c
+++ quilt-2.6/drivers/s390/cio/cio.c
@@ -30,6 +30,8 @@
 #include <asm/isc.h>
 #include <asm/cpu.h>
 #include <asm/fcx.h>
+#include <asm/nmi.h>
+#include <asm/crw.h>
 #include "cio.h"
 #include "css.h"
 #include "chsc.h"
@@ -38,7 +40,6 @@
 #include "blacklist.h"
 #include "cio_debug.h"
 #include "chp.h"
-#include "../s390mach.h"
 
 debug_info_t *cio_debug_msg_id;
 debug_info_t *cio_debug_trace_id;
Index: quilt-2.6/drivers/s390/cio/crw.c
===================================================================
--- /dev/null
+++ quilt-2.6/drivers/s390/cio/crw.c
@@ -0,0 +1,145 @@
+/*
+ *   Channel report handling code
+ *
+ *    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/semaphore.h>
+#include <linux/kthread.h>
+#include <linux/init.h>
+#include <asm/crw.h>
+
+static struct semaphore crw_semaphore;
+static crw_handler_t crw_handlers[NR_RSCS];
+
+/**
+ * crw_register_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 crw_register_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;
+}
+
+/**
+ * crw_unregister_handler() - unregister a channel report word handler
+ * @rsc: reporting source code to handle
+ */
+void crw_unregister_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 crw_collect_info(void *unused)
+{
+	struct crw crw[2];
+	int ccode;
+	unsigned int chain;
+	int ignore;
+
+repeat:
+	ignore = down_interruptible(&crw_semaphore);
+	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;
+}
+
+void crw_handle_channel_report(void)
+{
+	up(&crw_semaphore);
+}
+
+/*
+ * Separate initcall needed for semaphore initialization since
+ * crw_handle_channel_report might be called before crw_machine_check_init.
+ */
+static int __init crw_init_semaphore(void)
+{
+	init_MUTEX_LOCKED(&crw_semaphore);
+	return 0;
+}
+pure_initcall(crw_init_semaphore);
+
+/*
+ * Machine checks for the channel subsystem must be enabled
+ * after the channel subsystem is initialized
+ */
+static int __init crw_machine_check_init(void)
+{
+	struct task_struct *task;
+
+	task = kthread_run(crw_collect_info, NULL, "kmcheck");
+	if (IS_ERR(task))
+		return PTR_ERR(task);
+	ctl_set_bit(14, 28);	/* enable channel report MCH */
+	return 0;
+}
+device_initcall(crw_machine_check_init);
Index: quilt-2.6/drivers/s390/cio/css.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/css.c
+++ quilt-2.6/drivers/s390/cio/css.c
@@ -18,8 +18,8 @@
 #include <linux/list.h>
 #include <linux/reboot.h>
 #include <asm/isc.h>
+#include <asm/crw.h>
 
-#include "../s390mach.h"
 #include "css.h"
 #include "cio.h"
 #include "cio_debug.h"
@@ -765,7 +765,7 @@ init_channel_subsystem (void)
 	if (ret)
 		goto out;
 
-	ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw);
+	ret = crw_register_handler(CRW_RSC_SCH, css_process_crw);
 	if (ret)
 		goto out;
 
@@ -845,7 +845,7 @@ out_unregister:
 out_bus:
 	bus_unregister(&css_bus_type);
 out:
-	s390_unregister_crw_handler(CRW_RSC_CSS);
+	crw_unregister_handler(CRW_RSC_CSS);
 	chsc_free_sei_area();
 	kfree(slow_subchannel_set);
 	pr_alert("The CSS device driver initialization failed with "
Index: quilt-2.6/drivers/s390/cio/Makefile
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/Makefile
+++ quilt-2.6/drivers/s390/cio/Makefile
@@ -3,7 +3,7 @@
 #
 
 obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \
-	fcx.o itcw.o
+	fcx.o itcw.o crw.o
 ccw_device-objs += device.o device_fsm.o device_ops.o
 ccw_device-objs += device_id.o device_pgid.o device_status.o
 obj-y += ccw_device.o cmf.o
Index: quilt-2.6/drivers/s390/Makefile
===================================================================
--- quilt-2.6.orig/drivers/s390/Makefile
+++ quilt-2.6/drivers/s390/Makefile
@@ -2,7 +2,6 @@
 # Makefile for the S/390 specific device drivers
 #
 
-obj-y += s390mach.o
 obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
 
 drivers-y += drivers/s390/built-in.o
Index: quilt-2.6/drivers/s390/s390mach.c
===================================================================
--- quilt-2.6.orig/drivers/s390/s390mach.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- *  drivers/s390/s390mach.c
- *   S/390 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>
- */
-
-#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 <asm/lowcore.h>
-#include <asm/cio.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;
-}
-
-struct mcck_struct {
-	int kill_task;
-	int channel_report;
-	int warning;
-	unsigned long long mcck_code;
-};
-
-static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
-
-/*
- * Main machine check handler function. Will be called with interrupts enabled
- * or disabled and machine checks enabled or disabled.
- */
-void
-s390_handle_mcck(void)
-{
-	unsigned long flags;
-	struct mcck_struct mcck;
-
-	/*
-	 * Disable machine checks and get the current state of accumulated
-	 * machine checks. Afterwards delete the old state and enable machine
-	 * checks again.
-	 */
-	local_irq_save(flags);
-	local_mcck_disable();
-	mcck = __get_cpu_var(cpu_mcck);
-	memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
-	clear_thread_flag(TIF_MCCK_PENDING);
-	local_mcck_enable();
-	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.
- */
-	if (mcck.warning) {	/* WARNING pending ? */
-		static int mchchk_wng_posted = 0;
-		/*
-		 * Use single machine clear, as we cannot handle smp right now
-		 */
-		__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 "
-		       "malfunction (code 0x%016llx).\n", mcck.mcck_code);
-		printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
-		       current->comm, current->pid);
-		do_exit(SIGSEGV);
-	}
-}
-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)
-{
-	int kill_task;
-	u64 tmpclock;
-	u64 zero;
-	void *fpt_save_area, *fpt_creg_save_area;
-
-	kill_task = 0;
-	zero = 0;
-	/* General purpose registers */
-	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)
-		/*
-		 * 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"
-		"	ld	2,8(%0)\n"
-		"	ld	4,16(%0)\n"
-		"	ld	6,24(%0)"
-		: : "a" (&S390_lowcore.floating_pt_save_area));
-#endif
-
-	if (MACHINE_HAS_IEEE) {
-#ifdef CONFIG_64BIT
-		fpt_save_area = &S390_lowcore.floating_pt_save_area;
-		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;
-#endif
-		/* Floating point control register */
-		if (!mci->fc) {
-			/*
-			 * Floating point control register can't be restored.
-			 * Task will be terminated.
-			 */
-			asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
-			kill_task = 1;
-
-		} else
-			asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
-
-		asm volatile(
-			"	ld	0,0(%0)\n"
-			"	ld	1,8(%0)\n"
-			"	ld	2,16(%0)\n"
-			"	ld	3,24(%0)\n"
-			"	ld	4,32(%0)\n"
-			"	ld	5,40(%0)\n"
-			"	ld	6,48(%0)\n"
-			"	ld	7,56(%0)\n"
-			"	ld	8,64(%0)\n"
-			"	ld	9,72(%0)\n"
-			"	ld	10,80(%0)\n"
-			"	ld	11,88(%0)\n"
-			"	ld	12,96(%0)\n"
-			"	ld	13,104(%0)\n"
-			"	ld	14,112(%0)\n"
-			"	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)
-		/*
-		 * Access registers have unknown contents.
-		 * Terminating task.
-		 */
-		kill_task = 1;
-
-	/* Revalidate control registers */
-	if (!mci->cr)
-		/*
-		 * Control registers have unknown contents.
-		 * Can't recover and therefore stopping machine.
-		 */
-		s390_handle_damage("invalid control registers.");
-	else
-#ifdef CONFIG_64BIT
-		asm volatile(
-			"	lctlg	0,15,0(%0)"
-			: : "a" (&S390_lowcore.cregs_save_area));
-#else
-		asm volatile(
-			"	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
-	 * old contents (should be zero) otherwise set it to zero.
-	 */
-	if (!mci->pr)
-		asm volatile(
-			"	sr	0,0\n"
-			"	sckpf"
-			: : : "0", "cc");
-	else
-		asm volatile(
-			"	l	0,0(%0)\n"
-			"	sckpf"
-			: : "a" (&S390_lowcore.tod_progreg_save_area)
-			: "0", "cc");
-#endif
-
-	/* Revalidate clock comparator register */
-	asm volatile(
-		"	stck	0(%1)\n"
-		"	sckc	0(%1)"
-		: "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
-
-	/* Check if old PSW is valid */
-	if (!mci->wp)
-		/*
-		 * Can't tell if we come from user or kernel mode
-		 * -> stopping machine.
-		 */
-		s390_handle_damage("old psw invalid.");
-
-	if (!mci->ms || !mci->pm || !mci->ia)
-		kill_task = 1;
-
-	return kill_task;
-}
-
-#define MAX_IPD_COUNT	29
-#define MAX_IPD_TIME	(5 * 60 * USEC_PER_SEC) /* 5 minutes */
-
-/*
- * machine check handler.
- */
-void notrace s390_do_machine_check(struct pt_regs *regs)
-{
-	static DEFINE_SPINLOCK(ipd_lock);
-	static unsigned long long last_ipd;
-	static int ipd_count;
-	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)
-		/* 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 */
-			u64 z_mcic, o_mcic, t_mcic;
-#ifdef CONFIG_64BIT
-			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
-			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
-				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
-				  1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
-				  1ULL<<16);
-#else
-			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
-				  1ULL<<29);
-			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
-				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
-				  1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
-#endif
-			t_mcic = *(u64 *)mci;
-
-			if (((t_mcic & z_mcic) != 0) ||
-			    ((t_mcic & o_mcic) != o_mcic)) {
-				s390_handle_damage("processing backup machine "
-						   "check with damage.");
-			}
-
-			/*
-			 * 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 {
-			/* Processing damage -> stopping machine */
-			s390_handle_damage("received instruction processing "
-					   "damage machine check.");
-		}
-	}
-	if (s390_revalidate_registers(mci)) {
-		if (umode) {
-			/*
-			 * Couldn't restore all register contents while in
-			 * user mode -> mark task for termination.
-			 */
-			mcck->kill_task = 1;
-			mcck->mcck_code = *(unsigned long long *) mci;
-			set_thread_flag(TIF_MCCK_PENDING);
-		}
-		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))
-			etr_sync_check();
-		if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
-			etr_switch_to_local();
-		if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))
-			stp_sync_check();
-		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;
-		set_thread_flag(TIF_MCCK_PENDING);
-	}
-	lockdep_on();
-}
-
-/*
- * s390_init_machine_check
- *
- * initialize machine check handling
- */
-static int
-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, 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: quilt-2.6/drivers/s390/s390mach.h
===================================================================
--- quilt-2.6.orig/drivers/s390/s390mach.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *  drivers/s390/s390mach.h
- *   S/390 data definitions for machine check processing
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390mach_h
-#define __s390mach_h
-
-#include <asm/types.h>
-
-struct mci {
-	__u32   sd              :  1; /* 00 system damage */
-	__u32   pd              :  1; /* 01 instruction-processing damage */
-	__u32   sr              :  1; /* 02 system recovery */
-	__u32   to_be_defined_1 :  1; /* 03 */
-	__u32   cd              :  1; /* 04 timing-facility damage */
-	__u32   ed              :  1; /* 05 external damage */
-	__u32   to_be_defined_2 :  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   to_be_defined_3 :  2; /* 12-13 */
-	__u32   b               :  1; /* 14 backed up */
-	__u32   to_be_defined_4 :  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   to_be_defined_5 :  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   to_be_defined_6 :  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   to_be_defined_7 :  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   to_be_defined_8 :  1; /* 45 */
-	__u32   ct              :  1; /* 46 cpu timer validity */
-	__u32   cc              :  1; /* 47 clock comparator validity */
-	__u32	to_be_defined_9 : 16; /* 47-63 */
-};
-
-/*
- * 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 s390_register_crw_handler(int rsc, crw_handler_t handler);
-extern void s390_unregister_crw_handler(int rsc);
-
-#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\t"
-		"ipm %0\n\t"
-		"srl %0,28\n\t"
-		: "=d" (ccode), "=m" (*pcrw)
-		: "a" (pcrw)
-		: "cc" );
-	return ccode;
-}
-
-#define ED_ETR_SYNC	12	/* External damage ETR sync check */
-#define ED_ETR_SWITCH	13	/* External damage ETR switch to local */
-
-#define ED_STP_SYNC	7	/* External damage STP sync check */
-#define ED_STP_ISLAND	6	/* External damage STP island check */
-
-struct pt_regs;
-
-void s390_handle_mcck(void);
-void s390_do_machine_check(struct pt_regs *regs);
-#endif /* __s390mach */

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 21/46] Remove CONFIG_MACHCHK_WARNING.
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (19 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 20/46] split/move machine check handler code Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 22/46] convert bitmap definitions to C Martin Schwidefsky
                   ` (24 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 120-machchk-warning.diff --]
[-- Type: text/plain, Size: 3168 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Everybody enables it so there is no point for an extra config option.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/Kconfig      |    7 -------
 arch/s390/kernel/nmi.c |   29 +++++++++++------------------
 2 files changed, 11 insertions(+), 25 deletions(-)

Index: quilt-2.6/arch/s390/Kconfig
===================================================================
--- quilt-2.6.orig/arch/s390/Kconfig
+++ quilt-2.6/arch/s390/Kconfig
@@ -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---
Index: quilt-2.6/arch/s390/kernel/nmi.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/nmi.c
+++ quilt-2.6/arch/s390/kernel/nmi.c
@@ -59,28 +59,23 @@ void s390_handle_mcck(void)
 
 	if (mcck.channel_report)
 		crw_handle_channel_report();
-
-#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.
- */
+	/*
+	 * 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 "
@@ -375,9 +370,7 @@ static int __init machine_check_init(voi
 {
 	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, 24);	/* enable warning MCH */
-#endif
 	return 0;
 }
 arch_initcall(machine_check_init);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 22/46] convert bitmap definitions to C
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (20 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 21/46] Remove CONFIG_MACHCHK_WARNING Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 23/46] move EXPORT_SYMBOLs to definitions Martin Schwidefsky
                   ` (23 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 121-bitmap-to-C.diff --]
[-- Type: text/plain, Size: 5165 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/bitops.h |    2 -
 arch/s390/kernel/bitmap.S      |   56 -----------------------------------------
 arch/s390/kernel/bitmap.c      |   49 +++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 57 deletions(-)

Index: quilt-2.6/arch/s390/include/asm/bitops.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/bitops.h
+++ quilt-2.6/arch/s390/include/asm/bitops.h
@@ -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[];
Index: quilt-2.6/arch/s390/kernel/bitmap.c
===================================================================
--- /dev/null
+++ quilt-2.6/arch/s390/kernel/bitmap.c
@@ -0,0 +1,49 @@
+/*
+ *    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>
+
+const char _oi_bitmap[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+
+const char _ni_bitmap[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
+
+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 };
+
+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 };
Index: quilt-2.6/arch/s390/kernel/bitmap.S
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/bitmap.S
+++ /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
-

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 23/46] move EXPORT_SYMBOLs to definitions
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (21 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 22/46] convert bitmap definitions to C Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 24/46] cio: Use unbind/bind instead of unregister/register Martin Schwidefsky
                   ` (22 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 122-export-symbols.diff --]
[-- Type: text/plain, Size: 5117 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Move all EXPORT_SYMBOLs to their corresponding definitions.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/bitmap.c     |    5 ++++
 arch/s390/kernel/process.c    |    2 +
 arch/s390/kernel/s390_ksyms.c |   44 ------------------------------------------
 arch/s390/kernel/setup.c      |    8 +++++++
 arch/s390/lib/delay.c         |    2 +
 arch/s390/mm/init.c           |    2 +
 6 files changed, 19 insertions(+), 44 deletions(-)

Index: quilt-2.6/arch/s390/kernel/bitmap.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/bitmap.c
+++ quilt-2.6/arch/s390/kernel/bitmap.c
@@ -7,10 +7,13 @@
  */
 
 #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,
@@ -29,6 +32,7 @@ const char _zb_findmap[] = {
 	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,
@@ -47,3 +51,4 @@ const char _sb_findmap[] = {
 	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: quilt-2.6/arch/s390/kernel/process.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/process.c
+++ quilt-2.6/arch/s390/kernel/process.c
@@ -141,6 +141,7 @@ int kernel_thread(int (*fn)(void *), voi
 	return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
 		       0, &regs, 0, NULL, NULL);
 }
+EXPORT_SYMBOL(kernel_thread);
 
 /*
  * Free current thread data structures etc..
@@ -318,6 +319,7 @@ int dump_fpu (struct pt_regs * regs, s39
 #endif /* CONFIG_64BIT */
 	return 1;
 }
+EXPORT_SYMBOL(dump_fpu);
 
 unsigned long get_wchan(struct task_struct *p)
 {
Index: quilt-2.6/arch/s390/kernel/s390_ksyms.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/s390_ksyms.c
+++ quilt-2.6/arch/s390/kernel/s390_ksyms.c
@@ -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: quilt-2.6/arch/s390/kernel/setup.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/setup.c
+++ quilt-2.6/arch/s390/kernel/setup.c
@@ -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];
 
Index: quilt-2.6/arch/s390/lib/delay.c
===================================================================
--- quilt-2.6.orig/arch/s390/lib/delay.c
+++ quilt-2.6/arch/s390/lib/delay.c
@@ -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: quilt-2.6/arch/s390/mm/init.c
===================================================================
--- quilt-2.6.orig/arch/s390/mm/init.c
+++ quilt-2.6/arch/s390/mm/init.c
@@ -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

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 24/46] cio: Use unbind/bind instead of unregister/register.
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (22 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 23/46] move EXPORT_SYMBOLs to definitions Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 25/46] cio: Try harder to disable subchannel Martin Schwidefsky
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Cornelia Huck, Martin Schwidefsky

[-- Attachment #1: 123-cio-dev-bind.diff --]
[-- Type: text/plain, Size: 3608 bytes --]

From: Cornelia Huck <cornelia.huck@de.ibm.com>

The common I/O layer may encounter a situation where the
device number of a ccw device has changed or a device
driver doesn't want to keep a formerly disconnected device
becoming operational again. Instead of using device_del()/
device_add() as now, we can just unbind the driver from the
device and rebind it to get the desired effect (rebinding)
with less overhead.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/device.c     |   27 +++++++--------------------
 drivers/s390/cio/device.h     |    2 +-
 drivers/s390/cio/device_fsm.c |    4 ++--
 3 files changed, 10 insertions(+), 23 deletions(-)

Index: quilt-2.6/drivers/s390/cio/device.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/device.c
+++ quilt-2.6/drivers/s390/cio/device.c
@@ -681,35 +681,22 @@ get_orphaned_ccwdev_by_dev_id(struct cha
 	return dev ? to_ccwdev(dev) : NULL;
 }
 
-static void
-ccw_device_add_changed(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	if (device_add(&cdev->dev)) {
-		put_device(&cdev->dev);
-		return;
-	}
-	set_bit(1, &cdev->private->registered);
-}
-
-void ccw_device_do_unreg_rereg(struct work_struct *work)
+void ccw_device_do_unbind_bind(struct work_struct *work)
 {
 	struct ccw_device_private *priv;
 	struct ccw_device *cdev;
 	struct subchannel *sch;
+	int ret;
 
 	priv = container_of(work, struct ccw_device_private, kick_work);
 	cdev = priv->cdev;
 	sch = to_subchannel(cdev->dev.parent);
 
-	ccw_device_unregister(cdev);
-	PREPARE_WORK(&cdev->private->kick_work,
-		     ccw_device_add_changed);
-	queue_work(ccw_device_work, &cdev->private->kick_work);
+	if (test_bit(1, &cdev->private->registered)) {
+		device_release_driver(&cdev->dev);
+		ret = device_attach(&cdev->dev);
+		WARN_ON(ret == -ENODEV);
+	}
 }
 
 static void
Index: quilt-2.6/drivers/s390/cio/device_fsm.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/device_fsm.c
+++ quilt-2.6/drivers/s390/cio/device_fsm.c
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device
 	    cdev->id.dev_type != cdev->private->senseid.dev_type ||
 	    cdev->id.dev_model != cdev->private->senseid.dev_model) {
 		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_do_unreg_rereg);
+			     ccw_device_do_unbind_bind);
 		queue_work(ccw_device_work, &cdev->private->kick_work);
 		return 0;
 	}
@@ -366,7 +366,7 @@ static void ccw_device_oper_notify(struc
 	}
 	/* Driver doesn't want device back. */
 	ccw_device_set_notoper(cdev);
-	PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg);
+	PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
 	queue_work(ccw_device_work, &cdev->private->kick_work);
 }
 
Index: quilt-2.6/drivers/s390/cio/device.h
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/device.h
+++ quilt-2.6/drivers/s390/cio/device.h
@@ -80,7 +80,7 @@ void io_subchannel_init_config(struct su
 
 int ccw_device_cancel_halt_clear(struct ccw_device *);
 
-void ccw_device_do_unreg_rereg(struct work_struct *);
+void ccw_device_do_unbind_bind(struct work_struct *);
 void ccw_device_move_to_orphanage(struct work_struct *);
 int ccw_device_is_orphan(struct ccw_device *);
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 25/46] cio: Try harder to disable subchannel.
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (23 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 24/46] cio: Use unbind/bind instead of unregister/register Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 26/46] cio: Use ccw_device_set_notoper() Martin Schwidefsky
                   ` (20 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Cornelia Huck, Martin Schwidefsky

[-- Attachment #1: 124-cio-sub-disable.diff --]
[-- Type: text/plain, Size: 2275 bytes --]

From: Cornelia Huck <cornelia.huck@de.ibm.com>

Acting upon the assumption that cio_disable_subchannel()
is only called when we really want to disable the subchannel
(a) remove the check for activity (it is already done in
    ccw_device_offline(), which is the place where it matters)
(b) collect pending status via tsch() and ignore it (it
    can't matter anymore since the subchannel will be disabled).

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/cio.c        |   18 ++++++++++--------
 drivers/s390/cio/device_fsm.c |    2 +-
 2 files changed, 11 insertions(+), 9 deletions(-)

Index: quilt-2.6/drivers/s390/cio/cio.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/cio.c
+++ quilt-2.6/drivers/s390/cio/cio.c
@@ -472,6 +472,7 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel)
 int cio_disable_subchannel(struct subchannel *sch)
 {
 	char dbf_txt[15];
+	int retry;
 	int ret;
 
 	CIO_TRACE_EVENT (2, "dissch");
@@ -482,16 +483,17 @@ int cio_disable_subchannel(struct subcha
 	if (cio_update_schib(sch))
 		return -ENODEV;
 
-	if (scsw_actl(&sch->schib.scsw) != 0)
-		/*
-		 * the disable function must not be called while there are
-		 *  requests pending for completion !
-		 */
-		return -EBUSY;
-
 	sch->config.ena = 0;
-	ret = cio_commit_config(sch);
 
+	for (retry = 0; retry < 3; retry++) {
+		ret = cio_commit_config(sch);
+		if (ret == -EBUSY) {
+			struct irb irb;
+			if (tsch(sch->schid, &irb) != 0)
+				break;
+		} else
+			break;
+	}
 	sprintf (dbf_txt, "ret:%d", ret);
 	CIO_TRACE_EVENT (2, dbf_txt);
 	return ret;
Index: quilt-2.6/drivers/s390/cio/device_fsm.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/device_fsm.c
+++ quilt-2.6/drivers/s390/cio/device_fsm.c
@@ -1052,7 +1052,7 @@ ccw_device_offline_irq(struct ccw_device
 	sch = to_subchannel(cdev->dev.parent);
 	/*
 	 * An interrupt in state offline means a previous disable was not
-	 * successful. Try again.
+	 * successful - should not happen, but we try to disable again.
 	 */
 	cio_disable_subchannel(sch);
 }

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 26/46] cio: Use ccw_device_set_notoper().
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (24 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 25/46] cio: Try harder to disable subchannel Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 27/46] cio: ccw device online store - report rc from ccw driver Martin Schwidefsky
                   ` (19 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Cornelia Huck, Martin Schwidefsky

[-- Attachment #1: 125-cio-set-notoper.diff --]
[-- Type: text/plain, Size: 1080 bytes --]

From: Cornelia Huck <cornelia.huck@de.ibm.com>

Use ccw_device_set_notoper() (which also deletes the device
timer and disables the subchannel) instead of simply setting
the state to DEV_STATE_NOT_OPER in the generic not operational
handling code. This prevents unexpected interrupts popping up
for devices that are deemed not operational.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/device_fsm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: quilt-2.6/drivers/s390/cio/device_fsm.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/device_fsm.c
+++ quilt-2.6/drivers/s390/cio/device_fsm.c
@@ -728,7 +728,7 @@ static void ccw_device_generic_notoper(s
 {
 	struct subchannel *sch;
 
-	cdev->private->state = DEV_STATE_NOT_OPER;
+	ccw_device_set_notoper(cdev);
 	sch = to_subchannel(cdev->dev.parent);
 	css_schedule_eval(sch->schid);
 }

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 27/46] cio: ccw device online store - report rc from ccw driver.
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (25 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 26/46] cio: Use ccw_device_set_notoper() Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 28/46] cio/crw: add/fix locking Martin Schwidefsky
                   ` (18 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Sebastian Ott, Martin Schwidefsky

[-- Attachment #1: 126-cio-online-rc.diff --]
[-- Type: text/plain, Size: 1774 bytes --]

From: Sebastian Ott <sebott@linux.vnet.ibm.com>

In case the ccw driver refuses to set a device offline, we should
transmit the return code to the caller.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/device.c |   14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

Index: quilt-2.6/drivers/s390/cio/device.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/device.c
+++ quilt-2.6/drivers/s390/cio/device.c
@@ -457,12 +457,13 @@ int ccw_device_set_online(struct ccw_dev
 	return (ret == 0) ? -ENODEV : ret;
 }
 
-static void online_store_handle_offline(struct ccw_device *cdev)
+static int online_store_handle_offline(struct ccw_device *cdev)
 {
 	if (cdev->private->state == DEV_STATE_DISCONNECTED)
 		ccw_device_remove_disconnected(cdev);
-	else if (cdev->drv && cdev->drv->set_offline)
-		ccw_device_set_offline(cdev);
+	else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+		return ccw_device_set_offline(cdev);
+	return 0;
 }
 
 static int online_store_recog_and_online(struct ccw_device *cdev)
@@ -530,13 +531,10 @@ static ssize_t online_store (struct devi
 		goto out;
 	switch (i) {
 	case 0:
-		online_store_handle_offline(cdev);
-		ret = count;
+		ret = online_store_handle_offline(cdev);
 		break;
 	case 1:
 		ret = online_store_handle_online(cdev, force);
-		if (!ret)
-			ret = count;
 		break;
 	default:
 		ret = -EINVAL;
@@ -545,7 +543,7 @@ out:
 	if (cdev->drv)
 		module_put(cdev->drv->owner);
 	atomic_set(&cdev->private->onoff, 0);
-	return ret;
+	return (ret < 0) ? ret : count;
 }
 
 static ssize_t

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 28/46] cio/crw: add/fix locking
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (26 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 27/46] cio: ccw device online store - report rc from ccw driver Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 29/46] cio: ensure single load of irq handler pointer Martin Schwidefsky
                   ` (17 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 127-cio-mutex.diff --]
[-- Type: text/plain, Size: 2843 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

The crw_unregister_handler uses xchg + synchronize_sched when
unregistering a crw_handler.
This doesn't protect crw_collect_info to potentially jump to NULL since
it has unlocked code like this:

if (crw_handlers[i])
        crw_handlers[i](NULL, NULL, 1);

So add a mutex which protects the crw handler array for changes.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/crw.c |   32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

Index: quilt-2.6/drivers/s390/cio/crw.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/crw.c
+++ quilt-2.6/drivers/s390/cio/crw.c
@@ -9,11 +9,13 @@
  */
 
 #include <linux/semaphore.h>
+#include <linux/mutex.h>
 #include <linux/kthread.h>
 #include <linux/init.h>
 #include <asm/crw.h>
 
 static struct semaphore crw_semaphore;
+static DEFINE_MUTEX(crw_handler_mutex);
 static crw_handler_t crw_handlers[NR_RSCS];
 
 /**
@@ -25,11 +27,17 @@ static crw_handler_t crw_handlers[NR_RSC
  */
 int crw_register_handler(int rsc, crw_handler_t handler)
 {
+	int rc = 0;
+
 	if ((rsc < 0) || (rsc >= NR_RSCS))
 		return -EINVAL;
-	if (!cmpxchg(&crw_handlers[rsc], NULL, handler))
-		return 0;
-	return -EBUSY;
+	mutex_lock(&crw_handler_mutex);
+	if (crw_handlers[rsc])
+		rc = -EBUSY;
+	else
+		crw_handlers[rsc] = handler;
+	mutex_unlock(&crw_handler_mutex);
+	return rc;
 }
 
 /**
@@ -40,8 +48,9 @@ void crw_unregister_handler(int rsc)
 {
 	if ((rsc < 0) || (rsc >= NR_RSCS))
 		return;
-	xchg(&crw_handlers[rsc], NULL);
-	synchronize_sched();
+	mutex_lock(&crw_handler_mutex);
+	crw_handlers[rsc] = NULL;
+	mutex_unlock(&crw_handler_mutex);
 }
 
 /*
@@ -58,6 +67,8 @@ repeat:
 	ignore = down_interruptible(&crw_semaphore);
 	chain = 0;
 	while (1) {
+		crw_handler_t handler;
+
 		if (unlikely(chain > 1)) {
 			struct crw tmp_crw;
 
@@ -90,10 +101,12 @@ repeat:
 			int i;
 
 			pr_debug("%s: crw overflow detected!\n", __func__);
+			mutex_lock(&crw_handler_mutex);
 			for (i = 0; i < NR_RSCS; i++) {
 				if (crw_handlers[i])
 					crw_handlers[i](NULL, NULL, 1);
 			}
+			mutex_unlock(&crw_handler_mutex);
 			chain = 0;
 			continue;
 		}
@@ -101,10 +114,11 @@ repeat:
 			chain++;
 			continue;
 		}
-		if (crw_handlers[crw[chain].rsc])
-			crw_handlers[crw[chain].rsc](&crw[0],
-						     chain ? &crw[1] : NULL,
-						     0);
+		mutex_lock(&crw_handler_mutex);
+		handler = crw_handlers[crw[chain].rsc];
+		if (handler)
+			handler(&crw[0], chain ? &crw[1] : NULL, 0);
+		mutex_unlock(&crw_handler_mutex);
 		/* chain is always 0 or 1 here. */
 		chain = crw[chain].chn ? chain + 1 : 0;
 	}

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 29/46] cio: ensure single load of irq handler pointer
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (27 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 28/46] cio/crw: add/fix locking Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 30/46] cio: device scan oom fallback Martin Schwidefsky
                   ` (16 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 128-cio-airq-barrier.diff --]
[-- Type: text/plain, Size: 873 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Add barrier to prevent compiler from reloading pointer to irq handler.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/airq.c |    2 ++
 1 file changed, 2 insertions(+)

Index: quilt-2.6/drivers/s390/cio/airq.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/airq.c
+++ quilt-2.6/drivers/s390/cio/airq.c
@@ -133,6 +133,8 @@ void do_adapter_IO(u8 isc)
 		while (word) {
 			if (word & INDICATOR_MASK) {
 				airq = airqs[isc][i];
+				/* Make sure gcc reads from airqs only once. */
+				barrier();
 				if (likely(airq))
 					airq->handler(&indicators[isc].byte[i],
 						      airq->drv_data);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 30/46] cio: device scan oom fallback.
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (28 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 29/46] cio: ensure single load of irq handler pointer Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 31/46] clock sync mode flags Martin Schwidefsky
                   ` (15 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Sebastian Ott, Martin Schwidefsky

[-- Attachment #1: 129-cio-scan-oom.diff --]
[-- Type: text/plain, Size: 1906 bytes --]

From: Sebastian Ott <sebott@linux.vnet.ibm.com>

Since some callers rely on for_each_subchannel_staged to not fail,
fall back to brute force scanning using get_subchannel_by_schid in
case of a oom situation.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/css.c |   31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

Index: quilt-2.6/drivers/s390/cio/css.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/css.c
+++ quilt-2.6/drivers/s390/cio/css.c
@@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct su
 	return rc;
 }
 
+static int call_fn_all_sch(struct subchannel_id schid, void *data)
+{
+	struct cb_data *cb = data;
+	struct subchannel *sch;
+	int rc = 0;
+
+	sch = get_subchannel_by_schid(schid);
+	if (sch) {
+		if (cb->fn_known_sch)
+			rc = cb->fn_known_sch(sch, cb->data);
+		put_device(&sch->dev);
+	} else {
+		if (cb->fn_unknown_sch)
+			rc = cb->fn_unknown_sch(schid, cb->data);
+	}
+
+	return rc;
+}
+
 int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
 			       int (*fn_unknown)(struct subchannel_id,
 			       void *), void *data)
@@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_
 	struct cb_data cb;
 	int rc;
 
-	cb.set = idset_sch_new();
-	if (!cb.set)
-		return -ENOMEM;
-	idset_fill(cb.set);
 	cb.data = data;
 	cb.fn_known_sch = fn_known;
 	cb.fn_unknown_sch = fn_unknown;
+
+	cb.set = idset_sch_new();
+	if (!cb.set)
+		/* fall back to brute force scanning in case of oom */
+		return for_each_subchannel(call_fn_all_sch, &cb);
+
+	idset_fill(cb.set);
+
 	/* Process registered subchannels. */
 	rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
 	if (rc)

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 31/46] clock sync mode flags
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (29 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 30/46] cio: device scan oom fallback Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 32/46] kernel: Disable switch_amode by default Martin Schwidefsky
                   ` (14 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 130-stp-hang.diff --]
[-- Type: text/plain, Size: 7121 bytes --]

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

The clock sync mode flag CLOCK_SYNC_STP is not cleared when stp
is set offline. In this case the get_sync_clock() function returns
-EACCESS and the dasd driver will block all i/o until stp is enabled
again. In addition get_sync_clock can return -EACCESS if the clock is
not in sync instead of -EAGAIN.

Rework the stp/etr online handling to fix these problems.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/time.c |   71 +++++++++++++++++++++++++++++-------------------
 1 file changed, 44 insertions(+), 27 deletions(-)

Index: quilt-2.6/arch/s390/kernel/time.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/time.c
+++ quilt-2.6/arch/s390/kernel/time.c
@@ -331,6 +331,7 @@ static unsigned long long adjust_time(un
 }
 
 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
 	 * 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_stru
 		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_stru
 		/* 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_stru
 	 * 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 s
 		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_
  */
 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_stru
 	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 s
 		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;
 }
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 32/46] kernel: Disable switch_amode by default
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (30 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 31/46] clock sync mode flags Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 33/46] Add zcrypt section in MAINTAINERS Martin Schwidefsky
                   ` (13 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Gerald Schaefer, Martin Schwidefsky

[-- Attachment #1: 131-amode-default.diff --]
[-- Type: text/plain, Size: 956 bytes --]

From: Gerald Schaefer <gerald.schaefer@de.ibm.com>

Disable switch_amode by default because pagetable walk on pre z9
hardware has negative performance impact.

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/setup.c |    4 ----
 1 file changed, 4 deletions(-)

Index: quilt-2.6/arch/s390/kernel/setup.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/setup.c
+++ quilt-2.6/arch/s390/kernel/setup.c
@@ -301,11 +301,7 @@ static int __init early_parse_mem(char *
 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,

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 33/46] Add zcrypt section in MAINTAINERS
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (31 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 32/46] kernel: Disable switch_amode by default Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 34/46] topology: define SD_MC_INIT to fix performance regression Martin Schwidefsky
                   ` (12 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Felix Beck, Ralph Wuerthner, Martin Schwidefsky

[-- Attachment #1: 132-zcrypt-maintainer.diff --]
[-- Type: text/plain, Size: 942 bytes --]

From: Felix Beck <felix.beck@de.ibm.com>

Add zcrypt section in S390 part of MAINTAINERS file.

Signed-off-by: Felix Beck <felix.beck@de.ibm.com>
Signed-off-by: Ralph Wuerthner <ralph.wuerthner@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 MAINTAINERS |    9 +++++++++
 1 file changed, 9 insertions(+)

Index: quilt-2.6/MAINTAINERS
===================================================================
--- quilt-2.6.orig/MAINTAINERS
+++ quilt-2.6/MAINTAINERS
@@ -3730,6 +3730,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

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 34/46] topology: define SD_MC_INIT to fix performance regression
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (32 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 33/46] Add zcrypt section in MAINTAINERS Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 35/46] qdio: add missing tiq_list locking Martin Schwidefsky
                   ` (11 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 133-sd-mc-init.diff --]
[-- Type: text/plain, Size: 942 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

The default values for SD_MC_INIT cause an additional cpu usage of up
to 40% on some network benchmarks compared to the plain SD_CPU_INIT
values. So just define SD_MC_INIT to SD_CPU_INIT.
More tuning needs to be done.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/topology.h |    2 ++
 1 file changed, 2 insertions(+)

Index: quilt-2.6/arch/s390/include/asm/topology.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/topology.h
+++ quilt-2.6/arch/s390/include/asm/topology.h
@@ -30,6 +30,8 @@ static inline void s390_init_cpu_topolog
 };
 #endif
 
+#define SD_MC_INIT SD_CPU_INIT
+
 #include <asm-generic/topology.h>
 
 #endif /* _ASM_S390_TOPOLOGY_H */

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 35/46] qdio: add missing tiq_list locking
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (33 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 34/46] topology: define SD_MC_INIT to fix performance regression Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 36/46] qdio: Dont call qdio_shutdown in case qdio_activate fails Martin Schwidefsky
                   ` (10 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Jan Glauber, Martin Schwidefsky

[-- Attachment #1: 134-qdio-tiq-lock.diff --]
[-- Type: text/plain, Size: 2147 bytes --]

From: Jan Glauber <jang@linux.vnet.ibm.com>

Add a mutex to protect the tiq_list. Although reading the list is done
using RCU adding and removing elements from the list must still
happen locked since multiple qdio devices may change the list in parallel
otherwise.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/qdio_main.c    |    1 +
 drivers/s390/cio/qdio_thinint.c |   10 +++++++---
 2 files changed, 8 insertions(+), 3 deletions(-)

Index: quilt-2.6/drivers/s390/cio/qdio_main.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_main.c
+++ quilt-2.6/drivers/s390/cio/qdio_main.c
@@ -1112,6 +1112,7 @@ int qdio_shutdown(struct ccw_device *cde
 	if (!irq_ptr)
 		return -ENODEV;
 
+	BUG_ON(irqs_disabled());
 	DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
 
 	mutex_lock(&irq_ptr->setup_mutex);
Index: quilt-2.6/drivers/s390/cio/qdio_thinint.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_thinint.c
+++ quilt-2.6/drivers/s390/cio/qdio_thinint.c
@@ -31,6 +31,7 @@
 
 /* list of thin interrupt input queues */
 static LIST_HEAD(tiq_list);
+DEFINE_MUTEX(tiq_list_lock);
 
 /* adapter local summary indicator */
 static unsigned char *tiqdio_alsi;
@@ -95,10 +96,10 @@ void tiqdio_add_input_queues(struct qdio
 	if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
 		css_qdio_omit_svs = 1;
 
-	for_each_input_queue(irq_ptr, q, i) {
+	mutex_lock(&tiq_list_lock);
+	for_each_input_queue(irq_ptr, q, i)
 		list_add_rcu(&q->entry, &tiq_list);
-		synchronize_rcu();
-	}
+	mutex_unlock(&tiq_list_lock);
 	xchg(irq_ptr->dsci, 1);
 	tasklet_schedule(&tiqdio_tasklet);
 }
@@ -118,7 +119,10 @@ void tiqdio_remove_input_queues(struct q
 		/* if establish triggered an error */
 		if (!q || !q->entry.prev || !q->entry.next)
 			continue;
+
+		mutex_lock(&tiq_list_lock);
 		list_del_rcu(&q->entry);
+		mutex_unlock(&tiq_list_lock);
 		synchronize_rcu();
 	}
 }

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 36/46] qdio: Dont call qdio_shutdown in case qdio_activate fails
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (34 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 35/46] qdio: add missing tiq_list locking Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:06 ` [patch/s390 37/46] qdio: proper kill of qdio tasklets Martin Schwidefsky
                   ` (9 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Jan Glauber, Martin Schwidefsky

[-- Attachment #1: 135-qdio-shutdown.diff --]
[-- Type: text/plain, Size: 1057 bytes --]

From: Jan Glauber <jang@linux.vnet.ibm.com>

Remove the call to qdio_shutdown from qdio_activate since the upper-layer
drivers are responsible to call qdio_shutdown when qdio_activate returns
with an error.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/qdio_main.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: quilt-2.6/drivers/s390/cio/qdio_main.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_main.c
+++ quilt-2.6/drivers/s390/cio/qdio_main.c
@@ -1404,9 +1404,8 @@ int qdio_activate(struct ccw_device *cde
 	switch (irq_ptr->state) {
 	case QDIO_IRQ_STATE_STOPPED:
 	case QDIO_IRQ_STATE_ERR:
-		mutex_unlock(&irq_ptr->setup_mutex);
-		qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
-		return -EIO;
+		rc = -EIO;
+		break;
 	default:
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE);
 		rc = 0;

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 37/46] qdio: proper kill of qdio tasklets
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (35 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 36/46] qdio: Dont call qdio_shutdown in case qdio_activate fails Martin Schwidefsky
@ 2009-02-25 15:06 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 38/46] qdio: call qdio_free also if qdio_shutdown fails Martin Schwidefsky
                   ` (8 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:06 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Jan Glauber, Martin Schwidefsky

[-- Attachment #1: 136-qdio-kill-tasklet.diff --]
[-- Type: text/plain, Size: 7789 bytes --]

From: Jan Glauber <jang@linux.vnet.ibm.com>

The queue tasklets were stopped with tasklet_disable. Although tasklet_disable
prevents the tasklet from beeing executed it is still possible that a tasklet
is scheduled on a CPU at that point. A following qdio_establish calls
tasklet_init which clears the tasklet count and the tasklet state leading to
the following Oops:

    <2>kernel BUG at kernel/softirq.c:392!
    <4>illegal operation: 0001 [#1] SMP
    <4>Modules linked in: iptable_filter ip_tables x_tables dm_round_robin dm_multipath scsi_dh sg sd_mod crc_t10dif nfs lockd nfs
_acl sunrpc fuse loop dm_mod qeth_l3 ipv6 zfcp qeth scsi_transport_fc qdio scsi_tgt scsi_mod chsc_sch ccwgroup dasd_eckd_mod dasdm
od ext3 mbcache jbd
    <4>Supported: Yes
    <4>CPU: 0 Not tainted 2.6.27.13-1.1.mz13-default #1
    <4>Process blast.LzS_64 (pid: 16445, task: 000000006cc02538, ksp: 000000006cb67998)
    <4>Krnl PSW : 0704c00180000000 00000000001399f4 (tasklet_action+0xc8/0x1d4)
    <4>           R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 EA:3
    <4>Krnl GPRS: ffffffff00000030 0000000000000002 0000000000000002 fffffffffffffffe
    <4>           000000000013aabe 00000000003b6a18 fffffffffffffffd 0000000000000000
    <4>           00000000006705a8 000000007d0914a8 000000007d0914b0 000000007fecfd30
    <4>           0000000000000000 00000000003b63e8 000000007fecfd90 000000007fecfd30
    <4>Krnl Code: 00000000001399e8: b9200021            cgr     %r2,%r1
    <4>           00000000001399ec: a7740004            brc     7,1399f4
    <4>           00000000001399f0: a7f40001            brc     15,1399f2
    <4>          >00000000001399f4: c0100027e8ee        larl    %r1,636bd0
    <4>           00000000001399fa: bf1f1008            icm     %r1,15,8(%r1)
    <4>           00000000001399fe: a7840019            brc     8,139a30
    <4>           0000000000139a02: c0300027e8ef        larl    %r3,636be0
    <4>           0000000000139a08: e3c030000004        lg      %r12,0(%r3)
    <4>Call Trace:
    <4>([<0000000000139c12>] tasklet_hi_action+0x112/0x1d4)
    <4> [<000000000013aabe>] __do_softirq+0xde/0x1c4
    <4> [<000000000010fa2e>] do_softirq+0x96/0xb0
    <4> [<000000000013a8d8>] irq_exit+0x70/0xcc
    <4> [<000000000010d1d8>] do_extint+0xf0/0x110
    <4> [<0000000000113b10>] ext_no_vtime+0x16/0x1a
    <4> [<000003e0000a3662>] ext3_dirty_inode+0xe6/0xe8 [ext3]
    <4>([<00000000001f6cf2>] __mark_inode_dirty+0x52/0x1d4)
    <4> [<000003e0000a44f0>] ext3_ordered_write_end+0x138/0x190 [ext3]
    <4> [<000000000018d5ec>] generic_perform_write+0x174/0x230
    <4> [<0000000000190144>] generic_file_buffered_write+0xb4/0x194
    <4> [<0000000000190864>] __generic_file_aio_write_nolock+0x418/0x454
    <4> [<0000000000190ee2>] generic_file_aio_write+0x76/0xe4
    <4> [<000003e0000a05c2>] ext3_file_write+0x3e/0xc8 [ext3]
    <4> [<00000000001cc2fe>] do_sync_write+0xd6/0x120
    <4> [<00000000001ccfc8>] vfs_write+0xac/0x184
    <4> [<00000000001cd218>] SyS_write+0x68/0xe0
    <4> [<0000000000113402>] sysc_noemu+0x10/0x16
    <4> [<0000020000043188>] 0x20000043188
    <4>Last Breaking-Event-Address:
    <4> [<00000000001399f0>] tasklet_action+0xc4/0x1d4
    <6>qdio: 0.0.c61b ZFCP on SC f67 using AI:1 QEBSM:0 PCI:1 TDD:1 SIGA: W AOP
    <4> <0>Kernel panic - not syncing: Fatal exception in interrupt

Use tasklet_kill instead of tasklet_disbale. Since tasklet_schedule must not be
called after tasklet_kill use the QDIO_IRQ_STATE_STOPPED to inidicate that a
queue is going down and prevent further tasklet schedules in that case.

Remove superflous tasklet_schedule from input queue setup, at that time
the queues are not ready so the schedule results in a NOP.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/qdio_main.c    |   35 ++++++++++++++++++++++++-----------
 drivers/s390/cio/qdio_thinint.c |    8 ++++----
 2 files changed, 28 insertions(+), 15 deletions(-)

Index: quilt-2.6/drivers/s390/cio/qdio_main.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_main.c
+++ quilt-2.6/drivers/s390/cio/qdio_main.c
@@ -778,21 +778,17 @@ static void __qdio_outbound_processing(s
 
 	spin_unlock_irqrestore(&q->lock, flags);
 
-	if (queue_type(q) == QDIO_ZFCP_QFMT) {
+	if (queue_type(q) == QDIO_ZFCP_QFMT)
 		if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
-			tasklet_schedule(&q->tasklet);
-		return;
-	}
+			goto sched;
 
 	/* bail out for HiperSockets unicast queues */
 	if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
 		return;
 
 	if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
-	    (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
-		tasklet_schedule(&q->tasklet);
-		return;
-	}
+	    (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
+		goto sched;
 
 	if (q->u.out.pci_out_enabled)
 		return;
@@ -810,6 +806,12 @@ static void __qdio_outbound_processing(s
 			qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
 		}
 	}
+	return;
+
+sched:
+	if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
+	tasklet_schedule(&q->tasklet);
 }
 
 /* outbound tasklet */
@@ -822,6 +824,9 @@ void qdio_outbound_processing(unsigned l
 void qdio_outbound_timer(unsigned long data)
 {
 	struct qdio_q *q = (struct qdio_q *)data;
+
+	if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
 	tasklet_schedule(&q->tasklet);
 }
 
@@ -863,6 +868,9 @@ static void qdio_int_handler_pci(struct 
 	int i;
 	struct qdio_q *q;
 
+	if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
+
 	qdio_perf_stat_inc(&perf_stats.pci_int);
 
 	for_each_input_queue(irq_ptr, q, i)
@@ -1090,11 +1098,11 @@ static void qdio_shutdown_queues(struct 
 	int i;
 
 	for_each_input_queue(irq_ptr, q, i)
-		tasklet_disable(&q->tasklet);
+		tasklet_kill(&q->tasklet);
 
 	for_each_output_queue(irq_ptr, q, i) {
-		tasklet_disable(&q->tasklet);
 		del_timer(&q->u.out.timer);
+		tasklet_kill(&q->tasklet);
 	}
 }
 
@@ -1125,6 +1133,12 @@ int qdio_shutdown(struct ccw_device *cde
 		return 0;
 	}
 
+	/*
+	 * Indicate that the device is going down. Scheduling the queue
+	 * tasklets is forbidden from here on.
+	 */
+	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
+
 	tiqdio_remove_input_queues(irq_ptr);
 	qdio_shutdown_queues(cdev);
 	qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1556,7 +1570,6 @@ static void handle_outbound(struct qdio_
 		qdio_perf_stat_inc(&perf_stats.fast_requeue);
 	}
 out:
-	/* Fixme: could wait forever if called from process context */
 	tasklet_schedule(&q->tasklet);
 }
 
Index: quilt-2.6/drivers/s390/cio/qdio_thinint.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_thinint.c
+++ quilt-2.6/drivers/s390/cio/qdio_thinint.c
@@ -101,7 +101,6 @@ void tiqdio_add_input_queues(struct qdio
 		list_add_rcu(&q->entry, &tiq_list);
 	mutex_unlock(&tiq_list_lock);
 	xchg(irq_ptr->dsci, 1);
-	tasklet_schedule(&tiqdio_tasklet);
 }
 
 /*
@@ -159,7 +158,6 @@ static void __tiqdio_inbound_processing(
 	 */
 	qdio_check_outbound_after_thinint(q);
 
-again:
 	if (!qdio_inbound_q_moved(q))
 		return;
 
@@ -167,7 +165,8 @@ again:
 
 	if (!tiqdio_inbound_q_done(q)) {
 		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
-		goto again;
+		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+			tasklet_schedule(&q->tasklet);
 	}
 
 	qdio_stop_polling(q);
@@ -177,7 +176,8 @@ again:
 	 */
 	if (!tiqdio_inbound_q_done(q)) {
 		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
-		goto again;
+		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+			tasklet_schedule(&q->tasklet);
 	}
 }
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 38/46] qdio: call qdio_free also if qdio_shutdown fails
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (36 preceding siblings ...)
  2009-02-25 15:06 ` [patch/s390 37/46] qdio: proper kill of qdio tasklets Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 39/46] qdio: move ACK to newest buffer for devices without QEBSM Martin Schwidefsky
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Jan Glauber, Martin Schwidefsky

[-- Attachment #1: 137-qdio-free.diff --]
[-- Type: text/plain, Size: 1505 bytes --]

From: Jan Glauber <jang@linux.vnet.ibm.com>

qdio_cleanup is a wrapper function that should call qdio_shutdown and
qdio_free. qdio_free was not called if an error occured in qdio_shutdown
resulting in a missing free of allocated resources.

Call qdio_free regardless of the return value of qdio_shutdown.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/qdio_main.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Index: quilt-2.6/drivers/s390/cio/qdio_main.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_main.c
+++ quilt-2.6/drivers/s390/cio/qdio_main.c
@@ -1073,8 +1073,9 @@ EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
  * @cdev: associated ccw device
  * @how: use halt or clear to shutdown
  *
- * This function calls qdio_shutdown() for @cdev with method @how
- * and on success qdio_free() for @cdev.
+ * This function calls qdio_shutdown() for @cdev with method @how.
+ * and qdio_free(). The qdio_free() return value is ignored since
+ * !irq_ptr is already checked.
  */
 int qdio_cleanup(struct ccw_device *cdev, int how)
 {
@@ -1085,8 +1086,8 @@ int qdio_cleanup(struct ccw_device *cdev
 		return -ENODEV;
 
 	rc = qdio_shutdown(cdev, how);
-	if (rc == 0)
-		rc = qdio_free(cdev);
+
+	qdio_free(cdev);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(qdio_cleanup);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 39/46] qdio: move ACK to newest buffer for devices without QEBSM
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (37 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 38/46] qdio: call qdio_free also if qdio_shutdown fails Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 40/46] allow usage of string functions in linux/string.h Martin Schwidefsky
                   ` (6 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Jan Glauber, Martin Schwidefsky

[-- Attachment #1: 138-qdio-acks.diff --]
[-- Type: text/plain, Size: 1968 bytes --]

From: Jan Glauber <jang@linux.vnet.ibm.com>

The ACKnowledgement state should be set on the newest SBAL so an
adapter interrupt surpression check needs to scan fewer SBALs.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/cio/qdio_main.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

Index: quilt-2.6/drivers/s390/cio/qdio_main.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_main.c
+++ quilt-2.6/drivers/s390/cio/qdio_main.c
@@ -440,12 +440,16 @@ static inline void inbound_primed(struct
 		/* reset the previous ACK but first set the new one */
 		set_buf_state(q, new, SLSB_P_INPUT_ACK);
 		set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
-	}
-	else {
+	} else {
 		q->u.in.polling = 1;
-		set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK);
+		set_buf_state(q, new, SLSB_P_INPUT_ACK);
 	}
 
+	/*
+	 * last_move_ftc points to the ACK'ed buffer and not to the last turns
+	 * first_to_check like for qebsm. Since it is only used to check if
+	 * the queue front moved in qdio_inbound_q_done this is not a problem.
+	 */
 	q->last_move_ftc = new;
 	count--;
 	if (!count)
@@ -455,7 +459,7 @@ static inline void inbound_primed(struct
 	 * Need to change all PRIMED buffers to NOT_INIT, otherwise
 	 * we're loosing initiative in the thinint code.
 	 */
-	set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT,
+	set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT,
 		       count);
 }
 
@@ -1480,7 +1484,6 @@ static void handle_inbound(struct qdio_q
 			if (q->u.in.ack_count <= 0) {
 				q->u.in.polling = 0;
 				q->u.in.ack_count = 0;
-				/* TODO: must we set last_move_ftc to something meaningful? */
 				goto set;
 			}
 			q->last_move_ftc = add_buf(q->last_move_ftc, diff);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 40/46] allow usage of string functions in linux/string.h
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (38 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 39/46] qdio: move ACK to newest buffer for devices without QEBSM Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 41/46] s390: remove duplicate nul-termination of string Martin Schwidefsky
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Rusty Russell, Martin Schwidefsky

[-- Attachment #1: 139-string-protos.diff --]
[-- Type: text/plain, Size: 2170 bytes --]

From: Rusty Russell <rusty@rustcorp.com.au>

In introducing a trivial "strstarts()" function in linux/string.h, we
hit the following error on s390:

In file included from include/linux/bitmap.h:8,
                 from include/linux/cpumask.h:142,
                 from include/linux/smp.h:12,
                 from /home/rusty/devel/kernel/patches/linux-2.6/arch/s390/include/asm/spinlock.h:14,
                 from include/linux/spinlock.h:88,
                 from include/linux/seqlock.h:29,
                 from include/linux/time.h:8,
                 from include/linux/stat.h:60,
                 from include/linux/module.h:10,
                 from arch/s390/lib/string.c:13:
include/linux/string.h: In function 'strstarts':
include/linux/string.h:124: error: implicit declaration of function 'strlen'
include/linux/string.h:124: warning: incompatible implicit declaration of built-in function 'strlen'

Because when including asm/string.h from arch/s390/lib/string.c we
don't declare the string ops we are about to define, and
linux/string.h barfs.

The fix is to declare them in this IN_ARCH_STRING_C case, but in
general I wonder if there's a neater fix.

Reported-by: linux-next
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/string.h |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

Index: quilt-2.6/arch/s390/include/asm/string.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/string.h
+++ quilt-2.6/arch/s390/include/asm/string.h
@@ -135,7 +135,13 @@ static inline size_t strnlen(const char 
 		: "+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__ */

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 41/46] s390: remove duplicate nul-termination of string
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (39 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 40/46] allow usage of string functions in linux/string.h Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 42/46] bitops: remove likely annotations Martin Schwidefsky
                   ` (4 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390
  Cc: Heiko Carstens, Hendrik Brueckner, Martin Schwidefsky

[-- Attachment #1: 140-parm-nul-term.diff --]
[-- Type: text/plain, Size: 877 bytes --]

From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>

strlcpy() does already NUL-terminate the destination string.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/early.c |    1 -
 1 file changed, 1 deletion(-)

Index: quilt-2.6/arch/s390/kernel/early.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/early.c
+++ quilt-2.6/arch/s390/kernel/early.c
@@ -352,7 +352,6 @@ static void __init setup_boot_command_li
 
 	/* 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) {

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 42/46] bitops: remove likely annotations
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (40 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 41/46] s390: remove duplicate nul-termination of string Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 43/46] module function call optimization Martin Schwidefsky
                   ` (3 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 141-bitops-remove-likely.diff --]
[-- Type: text/plain, Size: 1717 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

likely/unlikely profiling revealed that none of the branches in bitops
is taken likely or unlikely. So remove the annotations.
In addition the generated code is shorter.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/bitops.h |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

Index: quilt-2.6/arch/s390/include/asm/bitops.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/bitops.h
+++ quilt-2.6/arch/s390/include/asm/bitops.h
@@ -525,16 +525,16 @@ static inline unsigned long __ffs_word_l
 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(u
 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;
 	}

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 43/46] module function call optimization
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (41 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 42/46] bitops: remove likely annotations Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 44/46] use compiler builtin versions of strlen/strcpy/strcat Martin Schwidefsky
                   ` (2 subsequent siblings)
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 142-module-branches.diff --]
[-- Type: text/plain, Size: 1615 bytes --]

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

Avoid the detour over the PLT if the branch target of a function call
in a module is in the range of the bras (16-bit) or brasl (32-bit)
instruction. The PLT is still generated but it is unused.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/module.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Index: quilt-2.6/arch/s390/kernel/module.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/module.c
+++ quilt-2.6/arch/s390/kernel/module.c
@@ -310,15 +310,20 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 			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)

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 44/46] use compiler builtin versions of strlen/strcpy/strcat
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (42 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 43/46] module function call optimization Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 45/46] ftrace/mcount: fix kernel stack backchain Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 46/46] tape message cleanup Martin Schwidefsky
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 143-string-builtin.diff --]
[-- Type: text/plain, Size: 3102 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Use builtin variants if gcc 4 or newer is used to compile the kernel.
Generates better code than the asm variants.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/include/asm/string.h |   12 ++++++++++++
 arch/s390/lib/string.c         |   12 ++++++++++++
 2 files changed, 24 insertions(+)

Index: quilt-2.6/arch/s390/include/asm/string.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/string.h
+++ quilt-2.6/arch/s390/include/asm/string.h
@@ -84,6 +84,7 @@ static inline void *memscan(void *s, int
 
 static inline char *strcat(char *dst, const char *src)
 {
+#if __GNUC__ < 4
 	register int r0 asm("0") = 0;
 	unsigned long dummy;
 	char *ret = dst;
@@ -96,10 +97,14 @@ static inline char *strcat(char *dst, co
 		: "=&a" (dummy), "+a" (dst), "+a" (src)
 		: "d" (r0), "0" (0) : "cc", "memory" );
 	return ret;
+#else
+	return __builtin_strcat(dst, src);
+#endif
 }
 
 static inline char *strcpy(char *dst, const char *src)
 {
+#if __GNUC__ < 4
 	register int r0 asm("0") = 0;
 	char *ret = dst;
 
@@ -109,10 +114,14 @@ static inline char *strcpy(char *dst, co
 		: "+&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 +130,9 @@ static inline size_t strlen(const char *
 		"	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)
Index: quilt-2.6/arch/s390/lib/string.c
===================================================================
--- quilt-2.6.orig/arch/s390/lib/string.c
+++ quilt-2.6/arch/s390/lib/string.c
@@ -44,7 +44,11 @@ static inline char *__strnend(const char
  */
 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);
 
@@ -132,6 +140,7 @@ EXPORT_SYMBOL(strncpy);
  */
 char *strcat(char *dest, const char *src)
 {
+#if __GNUC__ < 4
 	register int r0 asm("0") = 0;
 	unsigned long dummy;
 	char *ret = dest;
@@ -143,6 +152,9 @@ char *strcat(char *dest, const char *src
 		      : "=&a" (dummy), "+a" (dest), "+a" (src)
 		      : "d" (r0), "0" (0UL) : "cc", "memory" );
 	return ret;
+#else
+	return __builtin_strcat(dest, src);
+#endif
 }
 EXPORT_SYMBOL(strcat);
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 45/46] ftrace/mcount: fix kernel stack backchain
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (43 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 44/46] use compiler builtin versions of strlen/strcpy/strcat Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  2009-02-25 15:07 ` [patch/s390 46/46] tape message cleanup Martin Schwidefsky
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Martin Schwidefsky

[-- Attachment #1: 144-ftrace-mcount.diff --]
[-- Type: text/plain, Size: 1147 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

With packed stack the backchain is at a different location.
Just use __SF_BACKCHAIN as an offset to store the backchain.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/mcount.S |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Index: quilt-2.6/arch/s390/kernel/mcount.S
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/mcount.S
+++ quilt-2.6/arch/s390/kernel/mcount.S
@@ -5,6 +5,8 @@
  *
  */
 
+#include <asm/asm-offsets.h>
+
 #ifndef CONFIG_64BIT
 .globl _mcount
 _mcount:
@@ -14,7 +16,7 @@ _mcount:
 	ahi	%r15,-96
 	l	%r3,100(%r15)
 	la	%r2,0(%r14)
-	st	%r1,0(%r15)
+	st	%r1,__SF_BACKCHAIN(%r15)
 	la	%r3,0(%r3)
 	bras	%r14,0f
 	.long	ftrace_trace_function
@@ -38,7 +40,7 @@ _mcount:
 	stg	%r14,112(%r15)
 	lgr	%r1,%r15
 	aghi	%r15,-160
-	stg	%r1,0(%r15)
+	stg	%r1,__SF_BACKCHAIN(%r15)
 	lgr	%r2,%r14
 	lg	%r3,168(%r15)
 	larl	%r14,ftrace_trace_function

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [patch/s390 46/46] tape message cleanup
  2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
                   ` (44 preceding siblings ...)
  2009-02-25 15:07 ` [patch/s390 45/46] ftrace/mcount: fix kernel stack backchain Martin Schwidefsky
@ 2009-02-25 15:07 ` Martin Schwidefsky
  45 siblings, 0 replies; 47+ messages in thread
From: Martin Schwidefsky @ 2009-02-25 15:07 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Heiko Carstens, Carsten Otte, Martin Schwidefsky

[-- Attachment #1: 145-kmsg-tape.diff --]
[-- Type: text/plain, Size: 52936 bytes --]

From: Carsten Otte <cotte@de.ibm.com>

This is a cleanup of all the messages this driver prints. It uses the
dev_message macros now.

Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 drivers/s390/char/tape.h       |    2 
 drivers/s390/char/tape_34xx.c  |  161 +++++++-----------
 drivers/s390/char/tape_3590.c  |  364 ++++++++++++++++++++---------------------
 drivers/s390/char/tape_block.c |   18 --
 drivers/s390/char/tape_char.c  |    7 
 drivers/s390/char/tape_core.c  |   62 +-----
 drivers/s390/char/tape_proc.c  |    3 
 drivers/s390/char/tape_std.c   |   21 --
 8 files changed, 267 insertions(+), 371 deletions(-)

Index: quilt-2.6/drivers/s390/char/tape_34xx.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape_34xx.c
+++ quilt-2.6/drivers/s390/char/tape_34xx.c
@@ -8,6 +8,8 @@
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/bio.h>
@@ -18,8 +20,6 @@
 #include "tape.h"
 #include "tape_std.h"
 
-#define PRINTK_HEADER "TAPE_34XX: "
-
 /*
  * Pointer to debug area.
  */
@@ -203,8 +203,7 @@ tape_34xx_unsolicited_irq(struct tape_de
 		tape_34xx_schedule_work(device, TO_MSEN);
 	} else {
 		DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
-		PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
-		tape_dump_sense(device, NULL, irb);
+		tape_dump_sense_dbf(device, NULL, irb);
 	}
 	return TAPE_IO_SUCCESS;
 }
@@ -226,9 +225,7 @@ tape_34xx_erp_read_opposite(struct tape_
 		tape_std_read_backward(device, request);
 		return tape_34xx_erp_retry(request);
 	}
-	if (request->op != TO_RBA)
-		PRINT_ERR("read_opposite called with state:%s\n",
-			  tape_op_verbose[request->op]);
+
 	/*
 	 * We tried to read forward and backward, but hat no
 	 * success -> failed.
@@ -241,13 +238,9 @@ tape_34xx_erp_bug(struct tape_device *de
 		  struct irb *irb, int no)
 {
 	if (request->op != TO_ASSIGN) {
-		PRINT_WARN("An unexpected condition #%d was caught in "
-			   "tape error recovery.\n", no);
-		PRINT_WARN("Please report this incident.\n");
-		if (request)
-			PRINT_WARN("Operation of tape:%s\n",
-				   tape_op_verbose[request->op]);
-		tape_dump_sense(device, request, irb);
+		dev_err(&device->cdev->dev, "An unexpected condition %d "
+			"occurred in tape error recovery\n", no);
+		tape_dump_sense_dbf(device, request, irb);
 	}
 	return tape_34xx_erp_failed(request, -EIO);
 }
@@ -261,9 +254,8 @@ tape_34xx_erp_overrun(struct tape_device
 		      struct irb *irb)
 {
 	if (irb->ecw[3] == 0x40) {
-		PRINT_WARN ("Data overrun error between control-unit "
-			    "and drive. Use a faster channel connection, "
-			    "if possible! \n");
+		dev_warn (&device->cdev->dev, "A data overrun occurred between"
+			" the control unit and tape unit\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	}
 	return tape_34xx_erp_bug(device, request, irb, -1);
@@ -280,7 +272,8 @@ tape_34xx_erp_sequence(struct tape_devic
 		/*
 		 * cu detected incorrect block-id sequence on tape.
 		 */
-		PRINT_WARN("Illegal block-id sequence found!\n");
+		dev_warn (&device->cdev->dev, "The block ID sequence on the "
+			"tape is incorrect\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	}
 	/*
@@ -393,8 +386,6 @@ tape_34xx_unit_check(struct tape_device 
 			/* Writing at physical end of volume */
 			return tape_34xx_erp_failed(request, -ENOSPC);
 		default:
-			PRINT_ERR("Invalid op in %s:%i\n",
-				  __func__, __LINE__);
 			return tape_34xx_erp_failed(request, 0);
 		}
 	}
@@ -420,7 +411,8 @@ tape_34xx_unit_check(struct tape_device 
 							 irb, -4);
 
 			/* data check is permanent, CU recovery has failed */
-			PRINT_WARN("Permanent read error\n");
+			dev_warn (&device->cdev->dev, "A read error occurred "
+				"that cannot be recovered\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		case 0x25:
 			// a write data check occurred
@@ -433,22 +425,26 @@ tape_34xx_unit_check(struct tape_device 
 							 irb, -5);
 
 			// data check is permanent, cu-recovery has failed
-			PRINT_WARN("Permanent write error\n");
+			dev_warn (&device->cdev->dev, "A write error on the "
+				"tape cannot be recovered\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		case 0x26:
 			/* Data Check (read opposite) occurred. */
 			return tape_34xx_erp_read_opposite(device, request);
 		case 0x28:
 			/* ID-Mark at tape start couldn't be written */
-			PRINT_WARN("ID-Mark could not be written.\n");
+			dev_warn (&device->cdev->dev, "Writing the ID-mark "
+				"failed\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		case 0x31:
 			/* Tape void. Tried to read beyond end of device. */
-			PRINT_WARN("Read beyond end of recorded area.\n");
+			dev_warn (&device->cdev->dev, "Reading the tape beyond"
+				" the end of the recorded area failed\n");
 			return tape_34xx_erp_failed(request, -ENOSPC);
 		case 0x41:
 			/* Record sequence error. */
-			PRINT_WARN("Invalid block-id sequence found.\n");
+			dev_warn (&device->cdev->dev, "The tape contains an "
+				"incorrect block ID sequence\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		default:
 			/* all data checks for 3480 should result in one of
@@ -470,16 +466,12 @@ tape_34xx_unit_check(struct tape_device 
 	switch (sense[3]) {
 	case 0x00:
 		/* Unit check with erpa code 0. Report and ignore. */
-		PRINT_WARN("Non-error sense was found. "
-			   "Unit-check will be ignored.\n");
 		return TAPE_IO_SUCCESS;
 	case 0x21:
 		/*
 		 * Data streaming not operational. CU will switch to
 		 * interlock mode. Reissue the command.
 		 */
-		PRINT_WARN("Data streaming not operational. "
-			   "Switching to interlock-mode.\n");
 		return tape_34xx_erp_retry(request);
 	case 0x22:
 		/*
@@ -487,11 +479,8 @@ tape_34xx_unit_check(struct tape_device 
 		 * error on the lower interface, internal path not usable,
 		 * or error during cartridge load.
 		 */
-		PRINT_WARN("A path equipment check occurred. One of the "
-			   "following conditions occurred:\n");
-		PRINT_WARN("drive adapter error, buffer error on the lower "
-			   "interface, internal path not usable, error "
-			   "during cartridge load.\n");
+		dev_warn (&device->cdev->dev, "A path equipment check occurred"
+			" for the tape device\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x24:
 		/*
@@ -514,7 +503,6 @@ tape_34xx_unit_check(struct tape_device 
 		 * but the hardware isn't capable to do idrc, or a perform
 		 * subsystem func is issued and the CU is not on-line.
 		 */
-		PRINT_WARN ("Function incompatible. Try to switch off idrc\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x2a:
 		/*
@@ -552,23 +540,26 @@ tape_34xx_unit_check(struct tape_device 
 		 * reading the format id mark or that that format specified
 		 * is not supported by the drive.
 		 */
-		PRINT_WARN("Drive not capable processing the tape format!\n");
+		dev_warn (&device->cdev->dev, "The tape unit cannot process "
+			"the tape format\n");
 		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
 	case 0x30:
 		/* The medium is write protected. */
-		PRINT_WARN("Medium is write protected!\n");
+		dev_warn (&device->cdev->dev, "The tape medium is write-"
+			"protected\n");
 		return tape_34xx_erp_failed(request, -EACCES);
 	case 0x32:
 		// Tension loss. We cannot recover this, it's an I/O error.
-		PRINT_WARN("The drive lost tape tension.\n");
+		dev_warn (&device->cdev->dev, "The tape does not have the "
+			"required tape tension\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x33:
 		/*
 		 * Load Failure. The cartridge was not inserted correctly or
 		 * the tape is not threaded correctly.
 		 */
-		PRINT_WARN("Cartridge load failure. Reload the cartridge "
-			   "and try again.\n");
+		dev_warn (&device->cdev->dev, "The tape unit failed to load"
+			" the cartridge\n");
 		tape_34xx_delete_sbid_from(device, 0);
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x34:
@@ -576,8 +567,8 @@ tape_34xx_unit_check(struct tape_device 
 		 * Unload failure. The drive cannot maintain tape tension
 		 * and control tape movement during an unload operation.
 		 */
-		PRINT_WARN("Failure during cartridge unload. "
-			   "Please try manually.\n");
+		dev_warn (&device->cdev->dev, "Automatic unloading of the tape"
+			" cartridge failed\n");
 		if (request->op == TO_RUN)
 			return tape_34xx_erp_failed(request, -EIO);
 		return tape_34xx_erp_bug(device, request, irb, sense[3]);
@@ -589,8 +580,8 @@ tape_34xx_unit_check(struct tape_device 
 		 * - the cartridge loader does not respond correctly
 		 * - a failure occurs during an index, load, or unload cycle
 		 */
-		PRINT_WARN("Equipment check! Please check the drive and "
-			   "the cartridge loader.\n");
+		dev_warn (&device->cdev->dev, "An equipment check has occurred"
+			" on the tape unit\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x36:
 		if (device->cdev->id.driver_info == tape_3490)
@@ -603,7 +594,8 @@ tape_34xx_unit_check(struct tape_device 
 		 * Tape length error. The tape is shorter than reported in
 		 * the beginning-of-tape data.
 		 */
-		PRINT_WARN("Tape length error.\n");
+		dev_warn (&device->cdev->dev, "The tape information states an"
+			" incorrect length\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x38:
 		/*
@@ -620,12 +612,12 @@ tape_34xx_unit_check(struct tape_device 
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x3a:
 		/* Drive switched to not ready. */
-		PRINT_WARN("Drive not ready. Turn the ready/not ready switch "
-			   "to ready position and try again.\n");
+		dev_warn (&device->cdev->dev, "The tape unit is not ready\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x3b:
 		/* Manual rewind or unload. This causes an I/O error. */
-		PRINT_WARN("Medium was rewound or unloaded manually.\n");
+		dev_warn (&device->cdev->dev, "The tape medium has been "
+			"rewound or unloaded manually\n");
 		tape_34xx_delete_sbid_from(device, 0);
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x42:
@@ -633,7 +625,8 @@ tape_34xx_unit_check(struct tape_device 
 		 * Degraded mode. A condition that can cause degraded
 		 * performance is detected.
 		 */
-		PRINT_WARN("Subsystem is running in degraded mode.\n");
+		dev_warn (&device->cdev->dev, "The tape subsystem is running "
+			"in degraded mode\n");
 		return tape_34xx_erp_retry(request);
 	case 0x43:
 		/* Drive not ready. */
@@ -652,7 +645,6 @@ tape_34xx_unit_check(struct tape_device 
 					break;
 			}
 		}
-		PRINT_WARN("The drive is not ready.\n");
 		return tape_34xx_erp_failed(request, -ENOMEDIUM);
 	case 0x44:
 		/* Locate Block unsuccessful. */
@@ -663,7 +655,8 @@ tape_34xx_unit_check(struct tape_device 
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x45:
 		/* The drive is assigned to a different channel path. */
-		PRINT_WARN("The drive is assigned elsewhere.\n");
+		dev_warn (&device->cdev->dev, "The tape unit is already "
+			"assigned\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x46:
 		/*
@@ -671,11 +664,12 @@ tape_34xx_unit_check(struct tape_device 
 		 * the power supply may be switched off or
 		 * the drive address may not be set correctly.
 		 */
-		PRINT_WARN("The drive is not on-line.");
+		dev_warn (&device->cdev->dev, "The tape unit is not online\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x47:
 		/* Volume fenced. CU reports volume integrity is lost. */
-		PRINT_WARN("Volume fenced. The volume integrity is lost.\n");
+		dev_warn (&device->cdev->dev, "The control unit has fenced "
+			"access to the tape volume\n");
 		tape_34xx_delete_sbid_from(device, 0);
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x48:
@@ -683,20 +677,21 @@ tape_34xx_unit_check(struct tape_device 
 		return tape_34xx_erp_retry(request);
 	case 0x49:
 		/* Bus out check. A parity check error on the bus was found. */
-		PRINT_WARN("Bus out check. A data transfer over the bus "
-			   "has been corrupted.\n");
+		dev_warn (&device->cdev->dev, "A parity error occurred on the "
+			"tape bus\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x4a:
 		/* Control unit erp failed. */
-		PRINT_WARN("The control unit I/O error recovery failed.\n");
+		dev_warn (&device->cdev->dev, "I/O error recovery failed on "
+			"the tape control unit\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x4b:
 		/*
 		 * CU and drive incompatible. The drive requests micro-program
 		 * patches, which are not available on the CU.
 		 */
-		PRINT_WARN("The drive needs microprogram patches from the "
-			   "control unit, which are not available.\n");
+		dev_warn (&device->cdev->dev, "The tape unit requires a "
+			"firmware update\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x4c:
 		/*
@@ -721,8 +716,8 @@ tape_34xx_unit_check(struct tape_device 
 			 * the block to be written is larger than allowed for
 			 * buffered mode.
 			 */
-			PRINT_WARN("Maximum block size for buffered "
-				   "mode exceeded.\n");
+			dev_warn (&device->cdev->dev, "The maximum block size"
+				" for buffered mode is exceeded\n");
 			return tape_34xx_erp_failed(request, -ENOBUFS);
 		}
 		/* This erpa is reserved for 3480. */
@@ -759,22 +754,20 @@ tape_34xx_unit_check(struct tape_device 
 		return tape_34xx_erp_retry(request);
 	case 0x55:
 		/* Channel interface recovery (permanent). */
-		PRINT_WARN("A permanent channel interface error occurred.\n");
+		dev_warn (&device->cdev->dev, "A channel interface error cannot be"
+			" recovered\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x56:
 		/* Channel protocol error. */
-		PRINT_WARN("A channel protocol error occurred.\n");
+		dev_warn (&device->cdev->dev, "A channel protocol error "
+			"occurred\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x57:
 		if (device->cdev->id.driver_info == tape_3480) {
 			/* Attention intercept. */
-			PRINT_WARN("An attention intercept occurred, "
-				   "which will be recovered.\n");
 			return tape_34xx_erp_retry(request);
 		} else {
 			/* Global status intercept. */
-			PRINT_WARN("An global status intercept was received, "
-				   "which will be recovered.\n");
 			return tape_34xx_erp_retry(request);
 		}
 	case 0x5a:
@@ -782,42 +775,31 @@ tape_34xx_unit_check(struct tape_device 
 		 * Tape length incompatible. The tape inserted is too long,
 		 * which could cause damage to the tape or the drive.
 		 */
-		PRINT_WARN("Tape Length Incompatible\n");
-		PRINT_WARN("Tape length exceeds IBM enhanced capacity "
-			"cartdridge length or a medium\n");
-		PRINT_WARN("with EC-CST identification mark has been mounted "
-			"in a device that writes\n");
-		PRINT_WARN("3480 or 3480 XF format.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support "
+			"the tape length\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x5b:
 		/* Format 3480 XF incompatible */
 		if (sense[1] & SENSE_BEGINNING_OF_TAPE)
 			/* The tape will get overwritten. */
 			return tape_34xx_erp_retry(request);
-		PRINT_WARN("Format 3480 XF Incompatible\n");
-		PRINT_WARN("Medium has been created in 3480 format. "
-			"To change the format writes\n");
-		PRINT_WARN("must be issued at BOT.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support"
+			" format 3480 XF\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x5c:
 		/* Format 3480-2 XF incompatible */
-		PRINT_WARN("Format 3480-2 XF Incompatible\n");
-		PRINT_WARN("Device can only read 3480 or 3480 XF format.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support tape "
+			"format 3480-2 XF\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x5d:
 		/* Tape length violation. */
-		PRINT_WARN("Tape Length Violation\n");
-		PRINT_WARN("The mounted tape exceeds IBM Enhanced Capacity "
-			"Cartdridge System Tape length.\n");
-		PRINT_WARN("This may cause damage to the drive or tape when "
-			"processing to the EOV\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support"
+			" the current tape length\n");
 		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
 	case 0x5e:
 		/* Compaction algorithm incompatible. */
-		PRINT_WARN("Compaction Algorithm Incompatible\n");
-		PRINT_WARN("The volume is recorded using an incompatible "
-			"compaction algorithm,\n");
-		PRINT_WARN("which is not supported by the device.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support"
+			" the compaction algorithm\n");
 		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
 
 		/* The following erpas should have been covered earlier. */
@@ -848,7 +830,6 @@ tape_34xx_irq(struct tape_device *device
 	    (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
 	    (request->op == TO_WRI)) {
 		/* Write at end of volume */
-		PRINT_INFO("End of volume\n"); /* XXX */
 		return tape_34xx_erp_failed(request, -ENOSPC);
 	}
 
@@ -869,9 +850,7 @@ tape_34xx_irq(struct tape_device *device
 	}
 
 	DBF_EVENT(6, "xunknownirq\n");
-	PRINT_ERR("Unexpected interrupt.\n");
-	PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
-	tape_dump_sense(device, request, irb);
+	tape_dump_sense_dbf(device, request, irb);
 	return TAPE_IO_STOP;
 }
 
Index: quilt-2.6/drivers/s390/char/tape_3590.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape_3590.c
+++ quilt-2.6/drivers/s390/char/tape_3590.c
@@ -8,12 +8,15 @@
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/bio.h>
 #include <asm/ebcdic.h>
 
 #define TAPE_DBF_AREA	tape_3590_dbf
+#define BUFSIZE 512	/* size of buffers for dynamic generated messages */
 
 #include "tape.h"
 #include "tape_std.h"
@@ -36,7 +39,7 @@ EXPORT_SYMBOL(TAPE_DBF_AREA);
  * - Read Alternate:		 implemented
  *******************************************************************/
 
-#define PRINTK_HEADER "TAPE_3590: "
+#define KMSG_COMPONENT "tape"
 
 static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
 	[0x00] = "",
@@ -726,7 +729,7 @@ static void tape_3590_med_state_set(stru
 	}
 	c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
 	if (sense->flags & MSENSE_CRYPT_MASK) {
-		PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
+		DBF_EVENT(6, "Medium is encrypted (%04x)\n", sense->flags);
 		c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
 	} else	{
 		DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
@@ -847,8 +850,7 @@ tape_3590_unsolicited_irq(struct tape_de
 		tape_3590_schedule_work(device, TO_READ_ATTMSG);
 	} else {
 		DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
-		PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
-		tape_dump_sense(device, NULL, irb);
+		tape_dump_sense_dbf(device, NULL, irb);
 	}
 	/* check medium state */
 	tape_3590_schedule_work(device, TO_MSEN);
@@ -876,8 +878,6 @@ tape_3590_erp_basic(struct tape_device *
 	case SENSE_BRA_DRE:
 		return tape_3590_erp_failed(device, request, irb, rc);
 	default:
-		PRINT_ERR("Unknown BRA %x - This should not happen!\n",
-			  sense->bra);
 		BUG();
 		return TAPE_IO_STOP;
 	}
@@ -910,7 +910,8 @@ tape_3590_erp_swap(struct tape_device *d
 	 * should proceed with the new tape... this
 	 * should probably be done in user space!
 	 */
-	PRINT_WARN("(%s): Swap Tape Device!\n", dev_name(&device->cdev->dev));
+	dev_warn (&device->cdev->dev, "The tape medium must be loaded into a "
+		"different tape unit\n");
 	return tape_3590_erp_basic(device, request, irb, -EIO);
 }
 
@@ -985,8 +986,6 @@ tape_3590_erp_read_opposite(struct tape_
 		return tape_3590_erp_failed(device, request, irb, -EIO);
 		break;
 	default:
-		PRINT_WARN("read_opposite_recovery_called_with_op: %s\n",
-			   tape_op_verbose[request->op]);
 		return tape_3590_erp_failed(device, request, irb, -EIO);
 	}
 }
@@ -998,50 +997,61 @@ static void
 tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
 {
 	struct tape_3590_sense *sense;
+	char *exception, *service;
+
+	exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+	service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+	if (!exception || !service)
+		goto out_nomem;
 
 	sense = (struct tape_3590_sense *) irb->ecw;
 	/* Exception Message */
 	switch (sense->fmt.f70.emc) {
 	case 0x02:
-		PRINT_WARN("(%s): Data degraded\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Data degraded");
 		break;
 	case 0x03:
-		PRINT_WARN("(%s): Data degraded in partion %i\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+		snprintf(exception, BUFSIZE, "Data degraded in partion %i",
+			sense->fmt.f70.mp);
 		break;
 	case 0x04:
-		PRINT_WARN("(%s): Medium degraded\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Medium degraded");
 		break;
 	case 0x05:
-		PRINT_WARN("(%s): Medium degraded in partition %i\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+		snprintf(exception, BUFSIZE, "Medium degraded in partition %i",
+			sense->fmt.f70.mp);
 		break;
 	case 0x06:
-		PRINT_WARN("(%s): Block 0 Error\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Block 0 Error");
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): Medium Exception 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.md);
+		snprintf(exception, BUFSIZE, "Medium Exception 0x%02x",
+			sense->fmt.f70.md);
 		break;
 	default:
-		PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.emc);
+		snprintf(exception, BUFSIZE, "0x%02x",
+			sense->fmt.f70.emc);
 		break;
 	}
 	/* Service Message */
 	switch (sense->fmt.f70.smc) {
 	case 0x02:
-		PRINT_WARN("(%s): Reference Media maintenance procedure %i\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.md);
+		snprintf(service, BUFSIZE, "Reference Media maintenance "
+			"procedure %i", sense->fmt.f70.md);
 		break;
 	default:
-		PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.smc);
+		snprintf(service, BUFSIZE, "0x%02x",
+			sense->fmt.f70.smc);
 		break;
 	}
+
+	dev_warn (&device->cdev->dev, "Tape media information: exception %s, "
+		"service %s\n", exception, service);
+
+out_nomem:
+	kfree(exception);
+	kfree(service);
 }
 
 /*
@@ -1051,108 +1061,108 @@ static void
 tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb)
 {
 	struct tape_3590_sense *sense;
+	char *exception, *service;
+
+	exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+	service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+	if (!exception || !service)
+		goto out_nomem;
 
 	sense = (struct tape_3590_sense *) irb->ecw;
 	/* Exception Message */
 	switch (sense->fmt.f71.emc) {
 	case 0x01:
-		PRINT_WARN("(%s): Effect of failure is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Effect of failure is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): CU Exception - no performance impact\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "CU Exception - no performance "
+			"impact");
 		break;
 	case 0x03:
-		PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on channel "
+			"interface 0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x04:
-		PRINT_WARN("(%s): CU Exception on device path 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on device path "
+			"0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x05:
-		PRINT_WARN("(%s): CU Exception on library path 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on library path "
+			"0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x06:
-		PRINT_WARN("(%s): CU Exception on node 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on node 0x%02x",
+			sense->fmt.f71.md[0]);
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): CU Exception on partition 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on partition "
+			"0x%02x", sense->fmt.f71.md[0]);
 		break;
 	default:
-		PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+		snprintf(exception, BUFSIZE, "0x%02x",
+			sense->fmt.f71.emc);
 	}
 	/* Service Message */
 	switch (sense->fmt.f71.smc) {
 	case 0x01:
-		PRINT_WARN("(%s): Repair impact is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair impact is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): Repair will not impact cu performance\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will not impact cu "
+			"performance");
 		break;
 	case 0x03:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable node "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable node "
+				"0x%x on CU", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable nodes "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"nodes (0x%x-0x%x) on CU", sense->fmt.f71.md[1],
+				sense->fmt.f71.md[2]);
 		break;
 	case 0x04:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable cannel path "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"channel path 0x%x on CU",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable cannel paths "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable cannel"
+				" paths (0x%x-0x%x) on CU",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x05:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable device path "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable device"
+				" path 0x%x on CU", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable device paths "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable device"
+				" paths (0x%x-0x%x) on CU",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x06:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable library path "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"library path 0x%x on CU",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable library paths "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"library paths (0x%x-0x%x) on CU",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): Repair will disable access to CU\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will disable access to CU");
 		break;
 	default:
-		PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+		snprintf(service, BUFSIZE, "0x%02x",
+			sense->fmt.f71.smc);
 	}
+
+	dev_warn (&device->cdev->dev, "I/O subsystem information: exception"
+		" %s, service %s\n", exception, service);
+out_nomem:
+	kfree(exception);
+	kfree(service);
 }
 
 /*
@@ -1162,111 +1172,109 @@ static void
 tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb)
 {
 	struct tape_3590_sense *sense;
+	char *exception, *service;
+
+	exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+	service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+	if (!exception || !service)
+		goto out_nomem;
 
 	sense = (struct tape_3590_sense *) irb->ecw;
 	/* Exception Message */
 	switch (sense->fmt.f71.emc) {
 	case 0x01:
-		PRINT_WARN("(%s): Effect of failure is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Effect of failure is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): DV Exception - no performance impact\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "DV Exception - no performance"
+			" impact");
 		break;
 	case 0x03:
-		PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "DV Exception on channel "
+			"interface 0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x04:
-		PRINT_WARN("(%s): DV Exception on loader 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "DV Exception on loader 0x%02x",
+			sense->fmt.f71.md[0]);
 		break;
 	case 0x05:
-		PRINT_WARN("(%s): DV Exception on message display 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "DV Exception on message display"
+			" 0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x06:
-		PRINT_WARN("(%s): DV Exception in tape path\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "DV Exception in tape path");
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): DV Exception in drive\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "DV Exception in drive");
 		break;
 	default:
-		PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+		snprintf(exception, BUFSIZE, "0x%02x",
+			sense->fmt.f71.emc);
 	}
 	/* Service Message */
 	switch (sense->fmt.f71.smc) {
 	case 0x01:
-		PRINT_WARN("(%s): Repair impact is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair impact is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): Repair will not impact device performance\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will not impact device "
+			"performance");
 		break;
 	case 0x03:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable channel path "
-				   "0x%x on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"channel path 0x%x on DV",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable channel path "
-				   "(0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"channel path (0x%x-0x%x) on DV",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x04:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable interface 0x%x "
-				   "on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"interface 0x%x on DV", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable interfaces "
-				   "(0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"interfaces (0x%x-0x%x) on DV",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x05:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable loader 0x%x "
-				   "on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable loader"
+				" 0x%x on DV", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable loader "
-				   "(0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable loader"
+				" (0x%x-0x%x) on DV",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): Repair will disable access to DV\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will disable access to DV");
 		break;
 	case 0x08:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable message "
-				   "display 0x%x on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"message display 0x%x on DV",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable message "
-				   "displays (0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"message displays (0x%x-0x%x) on DV",
+				 sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x09:
-		PRINT_WARN("(%s): Clean DV\n", dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Clean DV");
 		break;
 	default:
-		PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+		snprintf(service, BUFSIZE, "0x%02x",
+			sense->fmt.f71.smc);
 	}
+
+	dev_warn (&device->cdev->dev, "Device subsystem information: exception"
+		" %s, service %s\n", exception, service);
+out_nomem:
+	kfree(exception);
+	kfree(service);
 }
 
 /*
@@ -1282,46 +1290,44 @@ tape_3590_print_era_msg(struct tape_devi
 		return;
 	if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) {
 		if (tape_3590_msg[sense->mc] != NULL)
-			PRINT_WARN("(%s): %s\n", dev_name(&device->cdev->dev),
-				   tape_3590_msg[sense->mc]);
-		else {
-			PRINT_WARN("(%s): Message Code 0x%x\n",
-				   dev_name(&device->cdev->dev), sense->mc);
-		}
+			dev_warn (&device->cdev->dev, "The tape unit has "
+				"issued sense message %s\n",
+				tape_3590_msg[sense->mc]);
+		else
+			dev_warn (&device->cdev->dev, "The tape unit has "
+				"issued an unknown sense message code 0x%x\n",
+				sense->mc);
 		return;
 	}
 	if (sense->mc == 0xf0) {
 		/* Standard Media Information Message */
-		PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, "
-			   "RC=%02x-%04x-%02x\n", dev_name(&device->cdev->dev),
-			   sense->fmt.f70.sev, sense->mc,
-			   sense->fmt.f70.emc, sense->fmt.f70.smc,
-			   sense->fmt.f70.refcode, sense->fmt.f70.mid,
-			   sense->fmt.f70.fid);
+		dev_warn (&device->cdev->dev, "MIM SEV=%i, MC=%02x, ES=%x/%x, "
+			"RC=%02x-%04x-%02x\n", sense->fmt.f70.sev, sense->mc,
+			sense->fmt.f70.emc, sense->fmt.f70.smc,
+			sense->fmt.f70.refcode, sense->fmt.f70.mid,
+			sense->fmt.f70.fid);
 		tape_3590_print_mim_msg_f0(device, irb);
 		return;
 	}
 	if (sense->mc == 0xf1) {
 		/* Standard I/O Subsystem Service Information Message */
-		PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, "
-			   "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.sev,
-			   device->cdev->id.dev_model,
-			   sense->mc, sense->fmt.f71.emc,
-			   sense->fmt.f71.smc, sense->fmt.f71.refcode1,
-			   sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+		dev_warn (&device->cdev->dev, "IOSIM SEV=%i, DEVTYPE=3590/%02x,"
+			" MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+			sense->fmt.f71.sev, device->cdev->id.dev_model,
+			sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+			sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+			sense->fmt.f71.refcode3);
 		tape_3590_print_io_sim_msg_f1(device, irb);
 		return;
 	}
 	if (sense->mc == 0xf2) {
 		/* Standard Device Service Information Message */
-		PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, "
-			   "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.sev,
-			   device->cdev->id.dev_model,
-			   sense->mc, sense->fmt.f71.emc,
-			   sense->fmt.f71.smc, sense->fmt.f71.refcode1,
-			   sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+		dev_warn (&device->cdev->dev, "DEVSIM SEV=%i, DEVTYPE=3590/%02x"
+			", MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+			sense->fmt.f71.sev, device->cdev->id.dev_model,
+			sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+			sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+			sense->fmt.f71.refcode3);
 		tape_3590_print_dev_sim_msg_f2(device, irb);
 		return;
 	}
@@ -1329,8 +1335,8 @@ tape_3590_print_era_msg(struct tape_devi
 		/* Standard Library Service Information Message */
 		return;
 	}
-	PRINT_WARN("(%s): Device Message(%x)\n",
-		   dev_name(&device->cdev->dev), sense->mc);
+	dev_warn (&device->cdev->dev, "The tape unit has issued an unknown "
+		"sense message code %x\n", sense->mc);
 }
 
 static int tape_3590_crypt_error(struct tape_device *device,
@@ -1355,9 +1361,8 @@ static int tape_3590_crypt_error(struct 
 		/* No connection to EKM */
 		return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
 
-	PRINT_ERR("(%s): Unable to get encryption key from EKM\n", bus_id);
-	PRINT_ERR("(%s): CU=%02X DRIVE=%06X EKM=%02X:%04X\n", bus_id, cu_rc,
-		drv_rc, ekm_rc1, ekm_rc2);
+	dev_err (&device->cdev->dev, "The tape unit failed to obtain the "
+		"encryption key from EKM\n");
 
 	return tape_3590_erp_basic(device, request, irb, -ENOKEY);
 }
@@ -1443,8 +1448,6 @@ tape_3590_unit_check(struct tape_device 
 		 * print additional msg since default msg
 		 * "device intervention" is not very meaningfull
 		 */
-		PRINT_WARN("(%s): Tape operation when medium not loaded\n",
-			   dev_name(&device->cdev->dev));
 		tape_med_state_set(device, MS_UNLOADED);
 		tape_3590_schedule_work(device, TO_CRYPT_OFF);
 		return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
@@ -1490,19 +1493,13 @@ tape_3590_unit_check(struct tape_device 
 		return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
 
 	case 0x6020:
-		PRINT_WARN("(%s): Cartridge of wrong type ?\n",
-			   dev_name(&device->cdev->dev));
 		return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
 
 	case 0x8011:
-		PRINT_WARN("(%s): Another host has reserved the tape device\n",
-			   dev_name(&device->cdev->dev));
 		return tape_3590_erp_basic(device, request, irb, -EPERM);
 	case 0x8013:
-		PRINT_WARN("(%s): Another host has privileged access to the "
-			   "tape device\n", dev_name(&device->cdev->dev));
-		PRINT_WARN("(%s): To solve the problem unload the current "
-			   "cartridge!\n", dev_name(&device->cdev->dev));
+		dev_warn (&device->cdev->dev, "A different host has privileged"
+			" access to the tape unit\n");
 		return tape_3590_erp_basic(device, request, irb, -EPERM);
 	default:
 		return tape_3590_erp_basic(device, request, irb, -EIO);
@@ -1552,9 +1549,7 @@ tape_3590_irq(struct tape_device *device
 	}
 
 	DBF_EVENT(6, "xunknownirq\n");
-	PRINT_ERR("Unexpected interrupt.\n");
-	PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
-	tape_dump_sense(device, request, irb);
+	tape_dump_sense_dbf(device, request, irb);
 	return TAPE_IO_STOP;
 }
 
@@ -1609,7 +1604,6 @@ tape_3590_setup_device(struct tape_devic
 	if (rc)
 		goto fail_rdc_data;
 	if (rdc_data->data[31] == 0x13) {
-		PRINT_INFO("Device has crypto support\n");
 		data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
 		tape_3592_disable_crypt(device);
 	} else {
Index: quilt-2.6/drivers/s390/char/tape_block.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape_block.c
+++ quilt-2.6/drivers/s390/char/tape_block.c
@@ -10,6 +10,8 @@
  *		 Stefan Bader <shbader@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/blkdev.h>
@@ -23,8 +25,6 @@
 
 #include "tape.h"
 
-#define PRINTK_HEADER "TAPE_BLOCK: "
-
 #define TAPEBLOCK_MAX_SEC	100
 #define TAPEBLOCK_MIN_REQUEUE	3
 
@@ -279,8 +279,6 @@ tapeblock_cleanup_device(struct tape_dev
 	tape_put_device(device);
 
 	if (!device->blk_data.disk) {
-		PRINT_ERR("(%s): No gendisk to clean up!\n",
-			dev_name(&device->cdev->dev));
 		goto cleanup_queue;
 	}
 
@@ -314,7 +312,8 @@ tapeblock_revalidate_disk(struct gendisk
 	if (!device->blk_data.medium_changed)
 		return 0;
 
-	PRINT_INFO("Detecting media size...\n");
+	dev_info(&device->cdev->dev, "Determining the size of the recorded "
+		"area...\n");
 	rc = tape_mtop(device, MTFSFM, 1);
 	if (rc)
 		return rc;
@@ -341,7 +340,8 @@ tapeblock_revalidate_disk(struct gendisk
 	device->bof = rc;
 	nr_of_blks -= rc;
 
-	PRINT_INFO("Found %i blocks on media\n", nr_of_blks);
+	dev_info(&device->cdev->dev, "The size of the recorded area is %i "
+		"blocks\n", nr_of_blks);
 	set_capacity(device->blk_data.disk,
 		nr_of_blks*(TAPEBLOCK_HSEC_SIZE/512));
 
@@ -376,8 +376,8 @@ tapeblock_open(struct block_device *bdev
 
 	if (device->required_tapemarks) {
 		DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
-		PRINT_ERR("TBLOCK: Refusing to open tape with missing"
-			" end of file marks.\n");
+		dev_warn(&device->cdev->dev, "Opening the tape failed because"
+			" of missing end-of-file marks\n");
 		rc = -EPERM;
 		goto put_device;
 	}
@@ -452,7 +452,6 @@ tapeblock_ioctl(
 			rc = -EINVAL;
 			break;
 		default:
-			PRINT_WARN("invalid ioctl 0x%x\n", command);
 			rc = -EINVAL;
 	}
 
@@ -474,7 +473,6 @@ tapeblock_init(void)
 
 	if (tapeblock_major == 0)
 		tapeblock_major = rc;
-	PRINT_INFO("tape gets major %d for block device\n", tapeblock_major);
 	return 0;
 }
 
Index: quilt-2.6/drivers/s390/char/tape_char.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape_char.c
+++ quilt-2.6/drivers/s390/char/tape_char.c
@@ -24,8 +24,6 @@
 #include "tape_std.h"
 #include "tape_class.h"
 
-#define PRINTK_HEADER "TAPE_CHAR: "
-
 #define TAPECHAR_MAJOR		0	/* get dynamic major */
 
 /*
@@ -102,8 +100,6 @@ tapechar_check_idalbuffer(struct tape_de
 	if (block_size > MAX_BLOCKSIZE) {
 		DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n",
 			block_size, MAX_BLOCKSIZE);
-		PRINT_ERR("Invalid blocksize (%zd> %d)\n",
-			block_size, MAX_BLOCKSIZE);
 		return -EINVAL;
 	}
 
@@ -485,7 +481,6 @@ tapechar_init (void)
 		return -1;
 
 	tapechar_major = MAJOR(dev);
-	PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev));
 
 	return 0;
 }
@@ -496,7 +491,5 @@ tapechar_init (void)
 void
 tapechar_exit(void)
 {
-	PRINT_INFO("tape releases major %d for character devices\n",
-		tapechar_major);
 	unregister_chrdev_region(MKDEV(tapechar_major, 0), 256);
 }
Index: quilt-2.6/drivers/s390/char/tape_core.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape_core.c
+++ quilt-2.6/drivers/s390/char/tape_core.c
@@ -11,6 +11,7 @@
  *		 Stefan Bader <shbader@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
 #include <linux/module.h>
 #include <linux/init.h>	     // for kernel parameters
 #include <linux/kmod.h>	     // for requesting modules
@@ -25,7 +26,6 @@
 #include "tape.h"
 #include "tape_std.h"
 
-#define PRINTK_HEADER "TAPE_CORE: "
 #define LONG_BUSY_TIMEOUT 180 /* seconds */
 
 static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
@@ -214,13 +214,13 @@ tape_med_state_set(struct tape_device *d
 	switch(newstate){
 	case MS_UNLOADED:
 		device->tape_generic_status |= GMT_DR_OPEN(~0);
-		PRINT_INFO("(%s): Tape is unloaded\n",
-			   dev_name(&device->cdev->dev));
+		dev_info(&device->cdev->dev, "The tape cartridge has been "
+			"successfully unloaded\n");
 		break;
 	case MS_LOADED:
 		device->tape_generic_status &= ~GMT_DR_OPEN(~0);
-		PRINT_INFO("(%s): Tape has been mounted\n",
-			   dev_name(&device->cdev->dev));
+		dev_info(&device->cdev->dev, "A tape cartridge has been "
+			"mounted\n");
 		break;
 	default:
 		// print nothing
@@ -333,7 +333,6 @@ tape_generic_online(struct tape_device *
 	/* Let the discipline have a go at the device. */
 	device->discipline = discipline;
 	if (!try_module_get(discipline->owner)) {
-		PRINT_ERR("Cannot get module. Module gone.\n");
 		return -EINVAL;
 	}
 
@@ -391,7 +390,6 @@ int
 tape_generic_offline(struct tape_device *device)
 {
 	if (!device) {
-		PRINT_ERR("tape_generic_offline: no such device\n");
 		return -ENODEV;
 	}
 
@@ -413,9 +411,6 @@ tape_generic_offline(struct tape_device 
 			DBF_EVENT(3, "(%08x): Set offline failed "
 				"- drive in use.\n",
 				device->cdev_id);
-			PRINT_WARN("(%s): Set offline failed "
-				"- drive in use.\n",
-				dev_name(&device->cdev->dev));
 			spin_unlock_irq(get_ccwdev_lock(device->cdev));
 			return -EBUSY;
 	}
@@ -435,14 +430,11 @@ tape_alloc_device(void)
 	device = kzalloc(sizeof(struct tape_device), GFP_KERNEL);
 	if (device == NULL) {
 		DBF_EXCEPTION(2, "ti:no mem\n");
-		PRINT_INFO ("can't allocate memory for "
-			    "tape info structure\n");
 		return ERR_PTR(-ENOMEM);
 	}
 	device->modeset_byte = kmalloc(1, GFP_KERNEL | GFP_DMA);
 	if (device->modeset_byte == NULL) {
 		DBF_EXCEPTION(2, "ti:no mem\n");
-		PRINT_INFO("can't allocate memory for modeset byte\n");
 		kfree(device);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -490,7 +482,6 @@ tape_put_device(struct tape_device *devi
 	} else {
 		if (remain < 0) {
 			DBF_EVENT(4, "put device without reference\n");
-			PRINT_ERR("put device without reference\n");
 		} else {
 			DBF_EVENT(4, "tape_free_device(%p)\n", device);
 			kfree(device->modeset_byte);
@@ -538,8 +529,6 @@ tape_generic_probe(struct ccw_device *cd
 	ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
 	if (ret) {
 		tape_put_device(device);
-		PRINT_ERR("probe failed for tape device %s\n",
-			  dev_name(&cdev->dev));
 		return ret;
 	}
 	cdev->dev.driver_data = device;
@@ -547,7 +536,6 @@ tape_generic_probe(struct ccw_device *cd
 	device->cdev = cdev;
 	ccw_device_get_id(cdev, &dev_id);
 	device->cdev_id = devid_to_int(&dev_id);
-	PRINT_INFO("tape device %s found\n", dev_name(&cdev->dev));
 	return ret;
 }
 
@@ -584,7 +572,6 @@ tape_generic_remove(struct ccw_device *c
 
 	device = cdev->dev.driver_data;
 	if (!device) {
-		PRINT_ERR("No device pointer in tape_generic_remove!\n");
 		return;
 	}
 	DBF_LH(3, "(%08x): tape_generic_remove(%p)\n", device->cdev_id, cdev);
@@ -615,10 +602,8 @@ tape_generic_remove(struct ccw_device *c
 			 */
 			DBF_EVENT(3, "(%08x): Drive in use vanished!\n",
 				device->cdev_id);
-			PRINT_WARN("(%s): Drive in use vanished - "
-				"expect trouble!\n",
-				dev_name(&device->cdev->dev));
-			PRINT_WARN("State was %i\n", device->tape_state);
+			dev_warn(&device->cdev->dev, "A tape unit was detached"
+				" while in use\n");
 			tape_state_set(device, TS_NOT_OPER);
 			__tape_discard_requests(device);
 			spin_unlock_irq(get_ccwdev_lock(device->cdev));
@@ -830,30 +815,6 @@ __tape_end_request(
 }
 
 /*
- * Write sense data to console/dbf
- */
-void
-tape_dump_sense(struct tape_device* device, struct tape_request *request,
-		struct irb *irb)
-{
-	unsigned int *sptr;
-
-	PRINT_INFO("-------------------------------------------------\n");
-	PRINT_INFO("DSTAT : %02x  CSTAT: %02x	CPA: %04x\n",
-		   irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
-	PRINT_INFO("DEVICE: %s\n", dev_name(&device->cdev->dev));
-	if (request != NULL)
-		PRINT_INFO("OP	  : %s\n", tape_op_verbose[request->op]);
-
-	sptr = (unsigned int *) irb->ecw;
-	PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
-		   sptr[0], sptr[1], sptr[2], sptr[3]);
-	PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
-		   sptr[4], sptr[5], sptr[6], sptr[7]);
-	PRINT_INFO("--------------------------------------------------\n");
-}
-
-/*
  * Write sense data to dbf
  */
 void
@@ -1051,8 +1012,6 @@ __tape_do_irq (struct ccw_device *cdev, 
 
 	device = (struct tape_device *) cdev->dev.driver_data;
 	if (device == NULL) {
-		PRINT_ERR("could not get device structure for %s "
-			  "in interrupt\n", dev_name(&cdev->dev));
 		return;
 	}
 	request = (struct tape_request *) intparm;
@@ -1064,13 +1023,13 @@ __tape_do_irq (struct ccw_device *cdev, 
 		/* FIXME: What to do with the request? */
 		switch (PTR_ERR(irb)) {
 			case -ETIMEDOUT:
-				PRINT_WARN("(%s): Request timed out\n",
+				DBF_LH(1, "(%s): Request timed out\n",
 					dev_name(&cdev->dev));
 			case -EIO:
 				__tape_end_request(device, request, -EIO);
 				break;
 			default:
-				PRINT_ERR("(%s): Unexpected i/o error %li\n",
+				DBF_LH(1, "(%s): Unexpected i/o error %li\n",
 					dev_name(&cdev->dev),
 					PTR_ERR(irb));
 		}
@@ -1182,8 +1141,6 @@ __tape_do_irq (struct ccw_device *cdev, 
 		default:
 			if (rc > 0) {
 				DBF_EVENT(6, "xunknownrc\n");
-				PRINT_ERR("Invalid return code from discipline "
-				  	"interrupt function.\n");
 				__tape_end_request(device, request, -EIO);
 			} else {
 				__tape_end_request(device, request, rc);
@@ -1323,7 +1280,6 @@ EXPORT_SYMBOL(tape_state_set);
 EXPORT_SYMBOL(tape_med_state_set);
 EXPORT_SYMBOL(tape_alloc_request);
 EXPORT_SYMBOL(tape_free_request);
-EXPORT_SYMBOL(tape_dump_sense);
 EXPORT_SYMBOL(tape_dump_sense_dbf);
 EXPORT_SYMBOL(tape_do_io);
 EXPORT_SYMBOL(tape_do_io_async);
Index: quilt-2.6/drivers/s390/char/tape.h
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape.h
+++ quilt-2.6/drivers/s390/char/tape.h
@@ -324,8 +324,6 @@ static inline void tape_proc_cleanup (vo
 #endif
 
 /* a function for dumping device sense info */
-extern void tape_dump_sense(struct tape_device *, struct tape_request *,
-			    struct irb *);
 extern void tape_dump_sense_dbf(struct tape_device *, struct tape_request *,
 				struct irb *);
 
Index: quilt-2.6/drivers/s390/char/tape_proc.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape_proc.c
+++ quilt-2.6/drivers/s390/char/tape_proc.c
@@ -20,8 +20,6 @@
 
 #include "tape.h"
 
-#define PRINTK_HEADER "TAPE_PROC: "
-
 static const char *tape_med_st_verbose[MS_SIZE] =
 {
 	[MS_UNKNOWN] = "UNKNOWN ",
@@ -128,7 +126,6 @@ tape_proc_init(void)
 		proc_create("tapedevices", S_IFREG | S_IRUGO | S_IWUSR, NULL,
 			    &tape_proc_ops);
 	if (tape_proc_devices == NULL) {
-		PRINT_WARN("tape: Cannot register procfs entry tapedevices\n");
 		return;
 	}
 }
Index: quilt-2.6/drivers/s390/char/tape_std.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/tape_std.c
+++ quilt-2.6/drivers/s390/char/tape_std.c
@@ -26,8 +26,6 @@
 #include "tape.h"
 #include "tape_std.h"
 
-#define PRINTK_HEADER "TAPE_STD: "
-
 /*
  * tape_std_assign
  */
@@ -46,9 +44,8 @@ tape_std_assign_timeout(unsigned long da
 			device->cdev_id);
 	rc = tape_cancel_io(device, request);
 	if(rc)
-		PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n",
+		DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n",
 			dev_name(&device->cdev->dev), rc);
-
 }
 
 int
@@ -82,8 +79,6 @@ tape_std_assign(struct tape_device *devi
 	del_timer(&timeout);
 
 	if (rc != 0) {
-		PRINT_WARN("%s: assign failed - device might be busy\n",
-			dev_name(&device->cdev->dev));
 		DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
 			device->cdev_id);
 	} else {
@@ -105,8 +100,6 @@ tape_std_unassign (struct tape_device *d
 	if (device->tape_state == TS_NOT_OPER) {
 		DBF_EVENT(3, "(%08x): Can't unassign device\n",
 			device->cdev_id);
-		PRINT_WARN("(%s): Can't unassign device - device gone\n",
-			dev_name(&device->cdev->dev));
 		return -EIO;
 	}
 
@@ -120,8 +113,6 @@ tape_std_unassign (struct tape_device *d
 
 	if ((rc = tape_do_io(device, request)) != 0) {
 		DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
-		PRINT_WARN("%s: Unassign failed\n",
-			   dev_name(&device->cdev->dev));
 	} else {
 		DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
 	}
@@ -242,8 +233,6 @@ tape_std_mtsetblk(struct tape_device *de
 	if (count > MAX_BLOCKSIZE) {
 		DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
 			count, MAX_BLOCKSIZE);
-		PRINT_ERR("Invalid block size (%d > %d) given.\n",
-			count, MAX_BLOCKSIZE);
 		return -EINVAL;
 	}
 
@@ -633,14 +622,6 @@ tape_std_mtcompression(struct tape_devic
 
 	if (mt_count < 0 || mt_count > 1) {
 		DBF_EXCEPTION(6, "xcom parm\n");
-		if (*device->modeset_byte & 0x08)
-			PRINT_INFO("(%s) Compression is currently on\n",
-				   dev_name(&device->cdev->dev));
-		else
-			PRINT_INFO("(%s) Compression is currently off\n",
-				   dev_name(&device->cdev->dev));
-		PRINT_INFO("Use 1 to switch compression on, 0 to "
-			   "switch it off\n");
 		return -EINVAL;
 	}
 	request = tape_alloc_request(2, 0);

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2009-02-25 15:27 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 01/46] fix dump_stack vs. %p and (null) Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 02/46] Automatic IPL after dump Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 03/46] page fault: invoke oom-killer Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 04/46] dasd: enable compat ioctls Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 05/46] dasd_eckd / Write format R0 is now allowed BB Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 06/46] dasd: add large volume support Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 07/46] dasd: message cleanup Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 08/46] dasd: add High Performance FICON support Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 09/46] move sysinfo.c from drivers/s390 to arch/s390/kernel Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 10/46] delete drivers/s390/ebcdic.c Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 11/46] arch/s390/kernel/process.c: fix whitespace damage Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 12/46] cputime: initialize per thread timer values on fork Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 13/46] hvc_iucv: Update and add missing kernel messages Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 14/46] hvc_iucv: Provide IUCV z/VM user ID filtering Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 15/46] lockdep: trace hardirq off in smp_send_stop Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 16/46] check addressing mode in s390_enable_sie Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 17/46] Fix hypervisor detection for KVM Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 18/46] ftrace: dont trace machine check handler Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 19/46] Fix appldata build break with !NET Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 20/46] split/move machine check handler code Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 21/46] Remove CONFIG_MACHCHK_WARNING Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 22/46] convert bitmap definitions to C Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 23/46] move EXPORT_SYMBOLs to definitions Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 24/46] cio: Use unbind/bind instead of unregister/register Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 25/46] cio: Try harder to disable subchannel Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 26/46] cio: Use ccw_device_set_notoper() Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 27/46] cio: ccw device online store - report rc from ccw driver Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 28/46] cio/crw: add/fix locking Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 29/46] cio: ensure single load of irq handler pointer Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 30/46] cio: device scan oom fallback Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 31/46] clock sync mode flags Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 32/46] kernel: Disable switch_amode by default Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 33/46] Add zcrypt section in MAINTAINERS Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 34/46] topology: define SD_MC_INIT to fix performance regression Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 35/46] qdio: add missing tiq_list locking Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 36/46] qdio: Dont call qdio_shutdown in case qdio_activate fails Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 37/46] qdio: proper kill of qdio tasklets Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 38/46] qdio: call qdio_free also if qdio_shutdown fails Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 39/46] qdio: move ACK to newest buffer for devices without QEBSM Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 40/46] allow usage of string functions in linux/string.h Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 41/46] s390: remove duplicate nul-termination of string Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 42/46] bitops: remove likely annotations Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 43/46] module function call optimization Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 44/46] use compiler builtin versions of strlen/strcpy/strcat Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 45/46] ftrace/mcount: fix kernel stack backchain Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 46/46] tape message cleanup Martin Schwidefsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).