aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-29 14:01:17 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-29 14:01:17 -0400
commitb026188e8214ce87790730a56f3017d0bd222751 (patch)
treeb4d1e482b1f77360768a5c8e565bfd311ed74232
parent1903ac54f8536b11478e4f01c339e10b538f59e0 (diff)
parent94bb063312d872d9269deb2e5c0c7c6d5b0318e1 (diff)
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: (28 commits) [S390] rework of channel measurement facility. [S390] appldata enhancements. [S390] Add vmpanic parameter. [S390] add PAV support to the dasd driver. [S390] remove export of sys_call_table [S390] remove unused macros from binfmt_elf32.c [S390] fix duplicate export of overflow{ug}id [S390] cio chpid offline. [S390] avenrun export in appdata_base.c Convert s390_collect_crw_info() in s390mach.c from being started [S390] dasd eer data format. [S390] preempt_count initialization. [S390] head.S code moving. [S390] dasd whitespace and other cosmetics. [S390] virtual cpu accounting vs. machine checks. [S390] add __cpuinit to appldata cpu hotplug notifier. [S390] dasd_eckd_dump_sense bug. [S390] missing check in dasd_eer_open. [S390] modular 3270 driver. [S390] console_unblank woes. ...
-rw-r--r--Documentation/kernel-parameters.txt9
-rw-r--r--arch/s390/appldata/appldata.h24
-rw-r--r--arch/s390/appldata/appldata_base.c42
-rw-r--r--arch/s390/appldata/appldata_mem.c5
-rw-r--r--arch/s390/appldata/appldata_net_sum.c5
-rw-r--r--arch/s390/appldata/appldata_os.c98
-rw-r--r--arch/s390/kernel/binfmt_elf32.c5
-rw-r--r--arch/s390/kernel/entry.S80
-rw-r--r--arch/s390/kernel/entry64.S80
-rw-r--r--arch/s390/kernel/head.S22
-rw-r--r--arch/s390/kernel/head31.S77
-rw-r--r--arch/s390/kernel/head64.S79
-rw-r--r--arch/s390/kernel/s390_ksyms.c2
-rw-r--r--arch/s390/kernel/setup.c55
-rw-r--r--arch/s390/kernel/traps.c8
-rw-r--r--drivers/s390/block/dasd.c105
-rw-r--r--drivers/s390/block/dasd_3370_erp.c27
-rw-r--r--drivers/s390/block/dasd_3990_erp.c189
-rw-r--r--drivers/s390/block/dasd_9336_erp.c27
-rw-r--r--drivers/s390/block/dasd_9343_erp.c2
-rw-r--r--drivers/s390/block/dasd_devmap.c102
-rw-r--r--drivers/s390/block/dasd_diag.c6
-rw-r--r--drivers/s390/block/dasd_diag.h2
-rw-r--r--drivers/s390/block/dasd_eckd.c337
-rw-r--r--drivers/s390/block/dasd_eckd.h24
-rw-r--r--drivers/s390/block/dasd_eer.c4
-rw-r--r--drivers/s390/block/dasd_erp.c8
-rw-r--r--drivers/s390/block/dasd_fba.c49
-rw-r--r--drivers/s390/block/dasd_fba.h2
-rw-r--r--drivers/s390/block/dasd_int.h39
-rw-r--r--drivers/s390/block/dasd_ioctl.c12
-rw-r--r--drivers/s390/char/raw3270.c67
-rw-r--r--drivers/s390/cio/blacklist.c35
-rw-r--r--drivers/s390/cio/ccwgroup.c17
-rw-r--r--drivers/s390/cio/chsc.c6
-rw-r--r--drivers/s390/cio/cmf.c623
-rw-r--r--drivers/s390/cio/css.c63
-rw-r--r--drivers/s390/cio/device.c4
-rw-r--r--drivers/s390/cio/device.h10
-rw-r--r--drivers/s390/cio/device_fsm.c20
-rw-r--r--drivers/s390/cio/device_ops.c10
-rw-r--r--drivers/s390/s390mach.c5
-rw-r--r--include/asm-s390/bitops.h42
-rw-r--r--include/asm-s390/cio.h2
-rw-r--r--include/asm-s390/cmb.h4
-rw-r--r--include/asm-s390/dasd.h8
-rw-r--r--include/asm-s390/thread_info.h1
-rw-r--r--include/asm-s390/unistd.h4
48 files changed, 1458 insertions, 989 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 0d189c93eeaf..25f8d20dac53 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1689,9 +1689,14 @@ running once the system is up.
1689 decrease the size and leave more room for directly 1689 decrease the size and leave more room for directly
1690 mapped kernel RAM. 1690 mapped kernel RAM.
1691 1691
1692 vmhalt= [KNL,S390] 1692 vmhalt= [KNL,S390] Perform z/VM CP command after system halt.
1693 Format: <command>
1693 1694
1694 vmpoff= [KNL,S390] 1695 vmpanic= [KNL,S390] Perform z/VM CP command after kernel panic.
1696 Format: <command>
1697
1698 vmpoff= [KNL,S390] Perform z/VM CP command after power off.
1699 Format: <command>
1695 1700
1696 waveartist= [HW,OSS] 1701 waveartist= [HW,OSS]
1697 Format: <io>,<irq>,<dma>,<dma2> 1702 Format: <io>,<irq>,<dma>,<dma2>
diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h
index e806a8922bbb..71d65eb30650 100644
--- a/arch/s390/appldata/appldata.h
+++ b/arch/s390/appldata/appldata.h
@@ -3,9 +3,9 @@
3 * 3 *
4 * Definitions and interface for Linux - z/VM Monitor Stream. 4 * Definitions and interface for Linux - z/VM Monitor Stream.
5 * 5 *
6 * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. 6 * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH.
7 * 7 *
8 * Author: Gerald Schaefer <geraldsc@de.ibm.com> 8 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
9 */ 9 */
10 10
11//#define APPLDATA_DEBUG /* Debug messages on/off */ 11//#define APPLDATA_DEBUG /* Debug messages on/off */
@@ -29,6 +29,22 @@
29#define CTL_APPLDATA_NET_SUM 2125 29#define CTL_APPLDATA_NET_SUM 2125
30#define CTL_APPLDATA_PROC 2126 30#define CTL_APPLDATA_PROC 2126
31 31
32#ifndef CONFIG_64BIT
33
34#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
35#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
36#define APPLDATA_GEN_EVENT_RECORD 0x02
37#define APPLDATA_START_CONFIG_REC 0x03
38
39#else
40
41#define APPLDATA_START_INTERVAL_REC 0x80
42#define APPLDATA_STOP_REC 0x81
43#define APPLDATA_GEN_EVENT_RECORD 0x82
44#define APPLDATA_START_CONFIG_REC 0x83
45
46#endif /* CONFIG_64BIT */
47
32#define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) 48#define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x)
33#define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) 49#define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x)
34#define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) 50#define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x)
@@ -53,7 +69,11 @@ struct appldata_ops {
53 void *data; /* record data */ 69 void *data; /* record data */
54 unsigned int size; /* size of record */ 70 unsigned int size; /* size of record */
55 struct module *owner; /* THIS_MODULE */ 71 struct module *owner; /* THIS_MODULE */
72 char mod_lvl[2]; /* modification level, EBCDIC */
56}; 73};
57 74
58extern int appldata_register_ops(struct appldata_ops *ops); 75extern int appldata_register_ops(struct appldata_ops *ops);
59extern void appldata_unregister_ops(struct appldata_ops *ops); 76extern void appldata_unregister_ops(struct appldata_ops *ops);
77extern int appldata_diag(char record_nr, u16 function, unsigned long buffer,
78 u16 length, char *mod_lvl);
79
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 54d35c130907..61bc44626c04 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -5,9 +5,9 @@
5 * Exports appldata_register_ops() and appldata_unregister_ops() for the 5 * Exports appldata_register_ops() and appldata_unregister_ops() for the
6 * data gathering modules. 6 * data gathering modules.
7 * 7 *
8 * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. 8 * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH.
9 * 9 *
10 * Author: Gerald Schaefer <geraldsc@de.ibm.com> 10 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
11 */ 11 */
12 12
13#include <linux/config.h> 13#include <linux/config.h>
@@ -40,22 +40,6 @@
40 40
41#define TOD_MICRO 0x01000 /* nr. of TOD clock units 41#define TOD_MICRO 0x01000 /* nr. of TOD clock units
42 for 1 microsecond */ 42 for 1 microsecond */
43#ifndef CONFIG_64BIT
44
45#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
46#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
47#define APPLDATA_GEN_EVENT_RECORD 0x02
48#define APPLDATA_START_CONFIG_REC 0x03
49
50#else
51
52#define APPLDATA_START_INTERVAL_REC 0x80
53#define APPLDATA_STOP_REC 0x81
54#define APPLDATA_GEN_EVENT_RECORD 0x82
55#define APPLDATA_START_CONFIG_REC 0x83
56
57#endif /* CONFIG_64BIT */
58
59 43
60/* 44/*
61 * Parameter list for DIAGNOSE X'DC' 45 * Parameter list for DIAGNOSE X'DC'
@@ -195,8 +179,8 @@ static void appldata_work_fn(void *data)
195 * 179 *
196 * prepare parameter list, issue DIAG 0xDC 180 * prepare parameter list, issue DIAG 0xDC
197 */ 181 */
198static int appldata_diag(char record_nr, u16 function, unsigned long buffer, 182int appldata_diag(char record_nr, u16 function, unsigned long buffer,
199 u16 length) 183 u16 length, char *mod_lvl)
200{ 184{
201 unsigned long ry; 185 unsigned long ry;
202 struct appldata_product_id { 186 struct appldata_product_id {
@@ -214,7 +198,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer,
214 .record_nr = record_nr, 198 .record_nr = record_nr,
215 .version_nr = {0xF2, 0xF6}, /* "26" */ 199 .version_nr = {0xF2, 0xF6}, /* "26" */
216 .release_nr = {0xF0, 0xF1}, /* "01" */ 200 .release_nr = {0xF0, 0xF1}, /* "01" */
217 .mod_lvl = {0xF0, 0xF0}, /* "00" */ 201 .mod_lvl = {mod_lvl[0], mod_lvl[1]},
218 }; 202 };
219 struct appldata_parameter_list appldata_parameter_list = { 203 struct appldata_parameter_list appldata_parameter_list = {
220 .diag = 0xDC, 204 .diag = 0xDC,
@@ -467,24 +451,25 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
467 module_put(ops->owner); 451 module_put(ops->owner);
468 return -ENODEV; 452 return -ENODEV;
469 } 453 }
470 ops->active = 1;
471 ops->callback(ops->data); // init record 454 ops->callback(ops->data); // init record
472 rc = appldata_diag(ops->record_nr, 455 rc = appldata_diag(ops->record_nr,
473 APPLDATA_START_INTERVAL_REC, 456 APPLDATA_START_INTERVAL_REC,
474 (unsigned long) ops->data, ops->size); 457 (unsigned long) ops->data, ops->size,
458 ops->mod_lvl);
475 if (rc != 0) { 459 if (rc != 0) {
476 P_ERROR("START DIAG 0xDC for %s failed, " 460 P_ERROR("START DIAG 0xDC for %s failed, "
477 "return code: %d\n", ops->name, rc); 461 "return code: %d\n", ops->name, rc);
478 module_put(ops->owner); 462 module_put(ops->owner);
479 ops->active = 0;
480 } else { 463 } else {
481 P_INFO("Monitoring %s data enabled, " 464 P_INFO("Monitoring %s data enabled, "
482 "DIAG 0xDC started.\n", ops->name); 465 "DIAG 0xDC started.\n", ops->name);
466 ops->active = 1;
483 } 467 }
484 } else if ((buf[0] == '0') && (ops->active == 1)) { 468 } else if ((buf[0] == '0') && (ops->active == 1)) {
485 ops->active = 0; 469 ops->active = 0;
486 rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, 470 rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
487 (unsigned long) ops->data, ops->size); 471 (unsigned long) ops->data, ops->size,
472 ops->mod_lvl);
488 if (rc != 0) { 473 if (rc != 0) {
489 P_ERROR("STOP DIAG 0xDC for %s failed, " 474 P_ERROR("STOP DIAG 0xDC for %s failed, "
490 "return code: %d\n", ops->name, rc); 475 "return code: %d\n", ops->name, rc);
@@ -633,7 +618,7 @@ appldata_offline_cpu(int cpu)
633 spin_unlock(&appldata_timer_lock); 618 spin_unlock(&appldata_timer_lock);
634} 619}
635 620
636static int 621static int __cpuinit
637appldata_cpu_notify(struct notifier_block *self, 622appldata_cpu_notify(struct notifier_block *self,
638 unsigned long action, void *hcpu) 623 unsigned long action, void *hcpu)
639{ 624{
@@ -710,7 +695,8 @@ static void __exit appldata_exit(void)
710 list_for_each(lh, &appldata_ops_list) { 695 list_for_each(lh, &appldata_ops_list) {
711 ops = list_entry(lh, struct appldata_ops, list); 696 ops = list_entry(lh, struct appldata_ops, list);
712 rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, 697 rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
713 (unsigned long) ops->data, ops->size); 698 (unsigned long) ops->data, ops->size,
699 ops->mod_lvl);
714 if (rc != 0) { 700 if (rc != 0) {
715 P_ERROR("STOP DIAG 0xDC for %s failed, " 701 P_ERROR("STOP DIAG 0xDC for %s failed, "
716 "return code: %d\n", ops->name, rc); 702 "return code: %d\n", ops->name, rc);
@@ -739,6 +725,7 @@ MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure");
739 725
740EXPORT_SYMBOL_GPL(appldata_register_ops); 726EXPORT_SYMBOL_GPL(appldata_register_ops);
741EXPORT_SYMBOL_GPL(appldata_unregister_ops); 727EXPORT_SYMBOL_GPL(appldata_unregister_ops);
728EXPORT_SYMBOL_GPL(appldata_diag);
742 729
743#ifdef MODULE 730#ifdef MODULE
744/* 731/*
@@ -779,7 +766,6 @@ unsigned long nr_iowait(void)
779#endif /* MODULE */ 766#endif /* MODULE */
780EXPORT_SYMBOL_GPL(si_swapinfo); 767EXPORT_SYMBOL_GPL(si_swapinfo);
781EXPORT_SYMBOL_GPL(nr_threads); 768EXPORT_SYMBOL_GPL(nr_threads);
782EXPORT_SYMBOL_GPL(avenrun);
783EXPORT_SYMBOL_GPL(get_full_page_state); 769EXPORT_SYMBOL_GPL(get_full_page_state);
784EXPORT_SYMBOL_GPL(nr_running); 770EXPORT_SYMBOL_GPL(nr_running);
785EXPORT_SYMBOL_GPL(nr_iowait); 771EXPORT_SYMBOL_GPL(nr_iowait);
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index f0e2fbed3d4c..7915a197d96d 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -4,9 +4,9 @@
4 * Data gathering module for Linux-VM Monitor Stream, Stage 1. 4 * Data gathering module for Linux-VM Monitor Stream, Stage 1.
5 * Collects data related to memory management. 5 * Collects data related to memory management.
6 * 6 *
7 * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. 7 * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH.
8 * 8 *
9 * Author: Gerald Schaefer <geraldsc@de.ibm.com> 9 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
10 */ 10 */
11 11
12#include <linux/config.h> 12#include <linux/config.h>
@@ -152,6 +152,7 @@ static struct appldata_ops ops = {
152 .callback = &appldata_get_mem_data, 152 .callback = &appldata_get_mem_data,
153 .data = &appldata_mem_data, 153 .data = &appldata_mem_data,
154 .owner = THIS_MODULE, 154 .owner = THIS_MODULE,
155 .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */
155}; 156};
156 157
157 158
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index 2a4c7432db4a..39b7bdecbf05 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -5,9 +5,9 @@
5 * Collects accumulated network statistics (Packets received/transmitted, 5 * Collects accumulated network statistics (Packets received/transmitted,
6 * dropped, errors, ...). 6 * dropped, errors, ...).
7 * 7 *
8 * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. 8 * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH.
9 * 9 *
10 * Author: Gerald Schaefer <geraldsc@de.ibm.com> 10 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
11 */ 11 */
12 12
13#include <linux/config.h> 13#include <linux/config.h>
@@ -152,6 +152,7 @@ static struct appldata_ops ops = {
152 .callback = &appldata_get_net_sum_data, 152 .callback = &appldata_get_net_sum_data,
153 .data = &appldata_net_sum_data, 153 .data = &appldata_net_sum_data,
154 .owner = THIS_MODULE, 154 .owner = THIS_MODULE,
155 .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */
155}; 156};
156 157
157 158
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index 99ddd3bf2fba..f2b44a2f1dec 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -4,9 +4,9 @@
4 * Data gathering module for Linux-VM Monitor Stream, Stage 1. 4 * Data gathering module for Linux-VM Monitor Stream, Stage 1.
5 * Collects misc. OS related data (CPU utilization, running processes). 5 * Collects misc. OS related data (CPU utilization, running processes).
6 * 6 *
7 * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. 7 * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH.
8 * 8 *
9 * Author: Gerald Schaefer <geraldsc@de.ibm.com> 9 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
10 */ 10 */
11 11
12#include <linux/config.h> 12#include <linux/config.h>
@@ -44,11 +44,14 @@ struct appldata_os_per_cpu {
44 u32 per_cpu_system; /* ... spent in kernel mode */ 44 u32 per_cpu_system; /* ... spent in kernel mode */
45 u32 per_cpu_idle; /* ... spent in idle mode */ 45 u32 per_cpu_idle; /* ... spent in idle mode */
46 46
47// New in 2.6 --> 47 /* New in 2.6 */
48 u32 per_cpu_irq; /* ... spent in interrupts */ 48 u32 per_cpu_irq; /* ... spent in interrupts */
49 u32 per_cpu_softirq; /* ... spent in softirqs */ 49 u32 per_cpu_softirq; /* ... spent in softirqs */
50 u32 per_cpu_iowait; /* ... spent while waiting for I/O */ 50 u32 per_cpu_iowait; /* ... spent while waiting for I/O */
51// <-- New in 2.6 51
52 /* New in modification level 01 */
53 u32 per_cpu_steal; /* ... stolen by hypervisor */
54 u32 cpu_id; /* number of this CPU */
52} __attribute__((packed)); 55} __attribute__((packed));
53 56
54struct appldata_os_data { 57struct appldata_os_data {
@@ -68,10 +71,9 @@ struct appldata_os_data {
68 u32 avenrun[3]; /* average nr. of running processes during */ 71 u32 avenrun[3]; /* average nr. of running processes during */
69 /* the last 1, 5 and 15 minutes */ 72 /* the last 1, 5 and 15 minutes */
70 73
71// New in 2.6 --> 74 /* New in 2.6 */
72 u32 nr_iowait; /* number of blocked threads 75 u32 nr_iowait; /* number of blocked threads
73 (waiting for I/O) */ 76 (waiting for I/O) */
74// <-- New in 2.6
75 77
76 /* per cpu data */ 78 /* per cpu data */
77 struct appldata_os_per_cpu os_cpu[0]; 79 struct appldata_os_per_cpu os_cpu[0];
@@ -79,6 +81,14 @@ struct appldata_os_data {
79 81
80static struct appldata_os_data *appldata_os_data; 82static struct appldata_os_data *appldata_os_data;
81 83
84static struct appldata_ops ops = {
85 .ctl_nr = CTL_APPLDATA_OS,
86 .name = "os",
87 .record_nr = APPLDATA_RECORD_OS_ID,
88 .owner = THIS_MODULE,
89 .mod_lvl = {0xF0, 0xF1}, /* EBCDIC "01" */
90};
91
82 92
83static inline void appldata_print_debug(struct appldata_os_data *os_data) 93static inline void appldata_print_debug(struct appldata_os_data *os_data)
84{ 94{
@@ -100,15 +110,17 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data)
100 P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus); 110 P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus);
101 for (i = 0; i < os_data->nr_cpus; i++) { 111 for (i = 0; i < os_data->nr_cpus; i++) {
102 P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, " 112 P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, "
103 "idle = %u, irq = %u, softirq = %u, iowait = %u\n", 113 "idle = %u, irq = %u, softirq = %u, iowait = %u, "
104 i, 114 "steal = %u\n",
115 os_data->os_cpu[i].cpu_id,
105 os_data->os_cpu[i].per_cpu_user, 116 os_data->os_cpu[i].per_cpu_user,
106 os_data->os_cpu[i].per_cpu_nice, 117 os_data->os_cpu[i].per_cpu_nice,
107 os_data->os_cpu[i].per_cpu_system, 118 os_data->os_cpu[i].per_cpu_system,
108 os_data->os_cpu[i].per_cpu_idle, 119 os_data->os_cpu[i].per_cpu_idle,
109 os_data->os_cpu[i].per_cpu_irq, 120 os_data->os_cpu[i].per_cpu_irq,
110 os_data->os_cpu[i].per_cpu_softirq, 121 os_data->os_cpu[i].per_cpu_softirq,
111 os_data->os_cpu[i].per_cpu_iowait); 122 os_data->os_cpu[i].per_cpu_iowait,
123 os_data->os_cpu[i].per_cpu_steal);
112 } 124 }
113 125
114 P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1); 126 P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1);
@@ -123,14 +135,13 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data)
123 */ 135 */
124static void appldata_get_os_data(void *data) 136static void appldata_get_os_data(void *data)
125{ 137{
126 int i, j; 138 int i, j, rc;
127 struct appldata_os_data *os_data; 139 struct appldata_os_data *os_data;
140 unsigned int new_size;
128 141
129 os_data = data; 142 os_data = data;
130 os_data->sync_count_1++; 143 os_data->sync_count_1++;
131 144
132 os_data->nr_cpus = num_online_cpus();
133
134 os_data->nr_threads = nr_threads; 145 os_data->nr_threads = nr_threads;
135 os_data->nr_running = nr_running(); 146 os_data->nr_running = nr_running();
136 os_data->nr_iowait = nr_iowait(); 147 os_data->nr_iowait = nr_iowait();
@@ -154,9 +165,44 @@ static void appldata_get_os_data(void *data)
154 cputime_to_jiffies(kstat_cpu(i).cpustat.softirq); 165 cputime_to_jiffies(kstat_cpu(i).cpustat.softirq);
155 os_data->os_cpu[j].per_cpu_iowait = 166 os_data->os_cpu[j].per_cpu_iowait =
156 cputime_to_jiffies(kstat_cpu(i).cpustat.iowait); 167 cputime_to_jiffies(kstat_cpu(i).cpustat.iowait);
168 os_data->os_cpu[j].per_cpu_steal =
169 cputime_to_jiffies(kstat_cpu(i).cpustat.steal);
170 os_data->os_cpu[j].cpu_id = i;
157 j++; 171 j++;
158 } 172 }
159 173
174 os_data->nr_cpus = j;
175
176 new_size = sizeof(struct appldata_os_data) +
177 (os_data->nr_cpus * sizeof(struct appldata_os_per_cpu));
178 if (ops.size != new_size) {
179 if (ops.active) {
180 rc = appldata_diag(APPLDATA_RECORD_OS_ID,
181 APPLDATA_START_INTERVAL_REC,
182 (unsigned long) ops.data, new_size,
183 ops.mod_lvl);
184 if (rc != 0) {
185 P_ERROR("os: START NEW DIAG 0xDC failed, "
186 "return code: %d, new size = %i\n", rc,
187 new_size);
188 P_INFO("os: stopping old record now\n");
189 } else
190 P_INFO("os: new record size = %i\n", new_size);
191
192 rc = appldata_diag(APPLDATA_RECORD_OS_ID,
193 APPLDATA_STOP_REC,
194 (unsigned long) ops.data, ops.size,
195 ops.mod_lvl);
196 if (rc != 0)
197 P_ERROR("os: STOP OLD DIAG 0xDC failed, "
198 "return code: %d, old size = %i\n", rc,
199 ops.size);
200 else
201 P_INFO("os: old record size = %i stopped\n",
202 ops.size);
203 }
204 ops.size = new_size;
205 }
160 os_data->timestamp = get_clock(); 206 os_data->timestamp = get_clock();
161 os_data->sync_count_2++; 207 os_data->sync_count_2++;
162#ifdef APPLDATA_DEBUG 208#ifdef APPLDATA_DEBUG
@@ -165,15 +211,6 @@ static void appldata_get_os_data(void *data)
165} 211}
166 212
167 213
168static struct appldata_ops ops = {
169 .ctl_nr = CTL_APPLDATA_OS,
170 .name = "os",
171 .record_nr = APPLDATA_RECORD_OS_ID,
172 .callback = &appldata_get_os_data,
173 .owner = THIS_MODULE,
174};
175
176
177/* 214/*
178 * appldata_os_init() 215 * appldata_os_init()
179 * 216 *
@@ -181,26 +218,25 @@ static struct appldata_ops ops = {
181 */ 218 */
182static int __init appldata_os_init(void) 219static int __init appldata_os_init(void)
183{ 220{
184 int rc, size; 221 int rc, max_size;
185 222
186 size = sizeof(struct appldata_os_data) + 223 max_size = sizeof(struct appldata_os_data) +
187 (NR_CPUS * sizeof(struct appldata_os_per_cpu)); 224 (NR_CPUS * sizeof(struct appldata_os_per_cpu));
188 if (size > APPLDATA_MAX_REC_SIZE) { 225 if (max_size > APPLDATA_MAX_REC_SIZE) {
189 P_ERROR("Size of record = %i, bigger than maximum (%i)!\n", 226 P_ERROR("Max. size of OS record = %i, bigger than maximum "
190 size, APPLDATA_MAX_REC_SIZE); 227 "record size (%i)\n", max_size, APPLDATA_MAX_REC_SIZE);
191 rc = -ENOMEM; 228 rc = -ENOMEM;
192 goto out; 229 goto out;
193 } 230 }
194 P_DEBUG("sizeof(os) = %i, sizeof(os_cpu) = %lu\n", size, 231 P_DEBUG("max. sizeof(os) = %i, sizeof(os_cpu) = %lu\n", max_size,
195 sizeof(struct appldata_os_per_cpu)); 232 sizeof(struct appldata_os_per_cpu));
196 233
197 appldata_os_data = kmalloc(size, GFP_DMA); 234 appldata_os_data = kzalloc(max_size, GFP_DMA);
198 if (appldata_os_data == NULL) { 235 if (appldata_os_data == NULL) {
199 P_ERROR("No memory for %s!\n", ops.name); 236 P_ERROR("No memory for %s!\n", ops.name);
200 rc = -ENOMEM; 237 rc = -ENOMEM;
201 goto out; 238 goto out;
202 } 239 }
203 memset(appldata_os_data, 0, size);
204 240
205 appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu); 241 appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu);
206 appldata_os_data->cpu_offset = offsetof(struct appldata_os_data, 242 appldata_os_data->cpu_offset = offsetof(struct appldata_os_data,
@@ -208,7 +244,7 @@ static int __init appldata_os_init(void)
208 P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset); 244 P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset);
209 245
210 ops.data = appldata_os_data; 246 ops.data = appldata_os_data;
211 ops.size = size; 247 ops.callback = &appldata_get_os_data;
212 rc = appldata_register_ops(&ops); 248 rc = appldata_register_ops(&ops);
213 if (rc != 0) { 249 if (rc != 0) {
214 P_ERROR("Error registering ops, rc = %i\n", rc); 250 P_ERROR("Error registering ops, rc = %i\n", rc);
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index 1f451c2cb071..12a6311e9838 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -177,11 +177,6 @@ struct elf_prpsinfo32
177 177
178#include <linux/highuid.h> 178#include <linux/highuid.h>
179 179
180#undef NEW_TO_OLD_UID
181#undef NEW_TO_OLD_GID
182#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
183#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
184
185#define elf_addr_t u32 180#define elf_addr_t u32
186/* 181/*
187#define init_elf_binfmt init_elf32_binfmt 182#define init_elf_binfmt init_elf32_binfmt
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b2448487854c..aa8b52c2140f 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -93,13 +93,22 @@ STACK_SIZE = 1 << STACK_SHIFT
93 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 93 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
94 .endm 94 .endm
95 95
96 .macro SAVE_ALL psworg,savearea,sync 96 .macro SAVE_ALL_SYNC psworg,savearea
97 la %r12,\psworg 97 la %r12,\psworg
98 .if \sync
99 tm \psworg+1,0x01 # test problem state bit 98 tm \psworg+1,0x01 # test problem state bit
100 bz BASED(2f) # skip stack setup save 99 bz BASED(2f) # skip stack setup save
101 l %r15,__LC_KERNEL_STACK # problem state -> load ksp 100 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
102 .else 101#ifdef CONFIG_CHECK_STACK
102 b BASED(3f)
1032: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
104 bz BASED(stack_overflow)
1053:
106#endif
1072:
108 .endm
109
110 .macro SAVE_ALL_ASYNC psworg,savearea
111 la %r12,\psworg
103 tm \psworg+1,0x01 # test problem state bit 112 tm \psworg+1,0x01 # test problem state bit
104 bnz BASED(1f) # from user -> load async stack 113 bnz BASED(1f) # from user -> load async stack
105 clc \psworg+4(4),BASED(.Lcritical_end) 114 clc \psworg+4(4),BASED(.Lcritical_end)
@@ -115,7 +124,6 @@ STACK_SIZE = 1 << STACK_SHIFT
115 sra %r14,STACK_SHIFT 124 sra %r14,STACK_SHIFT
116 be BASED(2f) 125 be BASED(2f)
1171: l %r15,__LC_ASYNC_STACK 1261: l %r15,__LC_ASYNC_STACK
118 .endif
119#ifdef CONFIG_CHECK_STACK 127#ifdef CONFIG_CHECK_STACK
120 b BASED(3f) 128 b BASED(3f)
1212: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 1292: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
@@ -196,7 +204,7 @@ system_call:
196 STORE_TIMER __LC_SYNC_ENTER_TIMER 204 STORE_TIMER __LC_SYNC_ENTER_TIMER
197sysc_saveall: 205sysc_saveall:
198 SAVE_ALL_BASE __LC_SAVE_AREA 206 SAVE_ALL_BASE __LC_SAVE_AREA
199 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 207 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
200 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 208 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
201 lh %r7,0x8a # get svc number from lowcore 209 lh %r7,0x8a # get svc number from lowcore
202#ifdef CONFIG_VIRT_CPU_ACCOUNTING 210#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -425,7 +433,7 @@ pgm_check_handler:
425 SAVE_ALL_BASE __LC_SAVE_AREA 433 SAVE_ALL_BASE __LC_SAVE_AREA
426 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 434 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
427 bnz BASED(pgm_per) # got per exception -> special case 435 bnz BASED(pgm_per) # got per exception -> special case
428 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 436 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
429 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 437 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
430#ifdef CONFIG_VIRT_CPU_ACCOUNTING 438#ifdef CONFIG_VIRT_CPU_ACCOUNTING
431 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 439 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -464,7 +472,7 @@ pgm_per:
464# Normal per exception 472# Normal per exception
465# 473#
466pgm_per_std: 474pgm_per_std:
467 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 475 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
468 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 476 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
469#ifdef CONFIG_VIRT_CPU_ACCOUNTING 477#ifdef CONFIG_VIRT_CPU_ACCOUNTING
470 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 478 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -490,7 +498,7 @@ pgm_no_vtime2:
490# it was a single stepped SVC that is causing all the trouble 498# it was a single stepped SVC that is causing all the trouble
491# 499#
492pgm_svcper: 500pgm_svcper:
493 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 501 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
494 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 502 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
495#ifdef CONFIG_VIRT_CPU_ACCOUNTING 503#ifdef CONFIG_VIRT_CPU_ACCOUNTING
496 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 504 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -519,7 +527,7 @@ io_int_handler:
519 STORE_TIMER __LC_ASYNC_ENTER_TIMER 527 STORE_TIMER __LC_ASYNC_ENTER_TIMER
520 stck __LC_INT_CLOCK 528 stck __LC_INT_CLOCK
521 SAVE_ALL_BASE __LC_SAVE_AREA+16 529 SAVE_ALL_BASE __LC_SAVE_AREA+16
522 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 530 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
523 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 531 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
524#ifdef CONFIG_VIRT_CPU_ACCOUNTING 532#ifdef CONFIG_VIRT_CPU_ACCOUNTING
525 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 533 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -631,7 +639,7 @@ ext_int_handler:
631 STORE_TIMER __LC_ASYNC_ENTER_TIMER 639 STORE_TIMER __LC_ASYNC_ENTER_TIMER
632 stck __LC_INT_CLOCK 640 stck __LC_INT_CLOCK
633 SAVE_ALL_BASE __LC_SAVE_AREA+16 641 SAVE_ALL_BASE __LC_SAVE_AREA+16
634 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 642 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
635 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 643 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
636#ifdef CONFIG_VIRT_CPU_ACCOUNTING 644#ifdef CONFIG_VIRT_CPU_ACCOUNTING
637 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 645 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -657,21 +665,31 @@ __critical_end:
657 .globl mcck_int_handler 665 .globl mcck_int_handler
658mcck_int_handler: 666mcck_int_handler:
659 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer 667 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
660 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
661 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs 668 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
662 SAVE_ALL_BASE __LC_SAVE_AREA+32 669 SAVE_ALL_BASE __LC_SAVE_AREA+32
663 la %r12,__LC_MCK_OLD_PSW 670 la %r12,__LC_MCK_OLD_PSW
664 tm __LC_MCCK_CODE,0x80 # system damage? 671 tm __LC_MCCK_CODE,0x80 # system damage?
665 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid 672 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid
666 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
667 bo BASED(0f)
668 spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer
669#ifdef CONFIG_VIRT_CPU_ACCOUNTING 673#ifdef CONFIG_VIRT_CPU_ACCOUNTING
670 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 674 mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
671 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 675 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
672 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 676 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
677 bo BASED(1f)
678 la %r14,__LC_SYNC_ENTER_TIMER
679 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
680 bl BASED(0f)
681 la %r14,__LC_ASYNC_ENTER_TIMER
6820: clc 0(8,%r14),__LC_EXIT_TIMER
683 bl BASED(0f)
684 la %r14,__LC_EXIT_TIMER
6850: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
686 bl BASED(0f)
687 la %r14,__LC_LAST_UPDATE_TIMER
6880: spt 0(%r14)
689 mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
6901:
673#endif 691#endif
6740: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 692 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
675 bno BASED(mcck_int_main) # no -> skip cleanup critical 693 bno BASED(mcck_int_main) # no -> skip cleanup critical
676 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 694 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
677 bnz BASED(mcck_int_main) # from user -> load async stack 695 bnz BASED(mcck_int_main) # from user -> load async stack
@@ -691,7 +709,7 @@ mcck_int_main:
691#ifdef CONFIG_VIRT_CPU_ACCOUNTING 709#ifdef CONFIG_VIRT_CPU_ACCOUNTING
692 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? 710 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
693 bno BASED(mcck_no_vtime) # no -> skip cleanup critical 711 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
694 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? 712 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
695 bz BASED(mcck_no_vtime) 713 bz BASED(mcck_no_vtime)
696 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 714 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
697 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 715 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -715,6 +733,20 @@ mcck_no_vtime:
715 l %r1,BASED(.Ls390_handle_mcck) 733 l %r1,BASED(.Ls390_handle_mcck)
716 basr %r14,%r1 # call machine check handler 734 basr %r14,%r1 # call machine check handler
717mcck_return: 735mcck_return:
736 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
737 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
738#ifdef CONFIG_VIRT_CPU_ACCOUNTING
739 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52
740 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
741 bno BASED(0f)
742 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
743 stpt __LC_EXIT_TIMER
744 lpsw __LC_RETURN_MCCK_PSW # back to caller
7450:
746#endif
747 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
748 lpsw __LC_RETURN_MCCK_PSW # back to caller
749
718 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 750 RESTORE_ALL __LC_RETURN_MCCK_PSW,0
719 751
720#ifdef CONFIG_SMP 752#ifdef CONFIG_SMP
@@ -781,6 +813,8 @@ cleanup_table_sysc_leave:
781 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 813 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
782cleanup_table_sysc_work_loop: 814cleanup_table_sysc_work_loop:
783 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 815 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
816cleanup_table_io_return:
817 .long io_return + 0x80000000, io_leave + 0x80000000
784cleanup_table_io_leave: 818cleanup_table_io_leave:
785 .long io_leave + 0x80000000, io_done + 0x80000000 819 .long io_leave + 0x80000000, io_done + 0x80000000
786cleanup_table_io_work_loop: 820cleanup_table_io_work_loop:
@@ -807,6 +841,11 @@ cleanup_critical:
807 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) 841 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
808 bl BASED(cleanup_sysc_return) 842 bl BASED(cleanup_sysc_return)
8090: 8430:
844 clc 4(4,%r12),BASED(cleanup_table_io_return)
845 bl BASED(0f)
846 clc 4(4,%r12),BASED(cleanup_table_io_return+4)
847 bl BASED(cleanup_io_return)
8480:
810 clc 4(4,%r12),BASED(cleanup_table_io_leave) 849 clc 4(4,%r12),BASED(cleanup_table_io_leave)
811 bl BASED(0f) 850 bl BASED(0f)
812 clc 4(4,%r12),BASED(cleanup_table_io_leave+4) 851 clc 4(4,%r12),BASED(cleanup_table_io_leave+4)
@@ -839,7 +878,7 @@ cleanup_system_call:
839 mvc __LC_SAVE_AREA(16),0(%r12) 878 mvc __LC_SAVE_AREA(16),0(%r12)
8400: st %r13,4(%r12) 8790: st %r13,4(%r12)
841 st %r12,__LC_SAVE_AREA+48 # argh 880 st %r12,__LC_SAVE_AREA+48 # argh
842 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 881 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
843 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 882 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
844 l %r12,__LC_SAVE_AREA+48 # argh 883 l %r12,__LC_SAVE_AREA+48 # argh
845 st %r15,12(%r12) 884 st %r15,12(%r12)
@@ -980,7 +1019,6 @@ cleanup_io_leave_insn:
980 .long cleanup_critical 1019 .long cleanup_critical
981 1020
982#define SYSCALL(esa,esame,emu) .long esa 1021#define SYSCALL(esa,esame,emu) .long esa
983 .globl sys_call_table
984sys_call_table: 1022sys_call_table:
985#include "syscalls.S" 1023#include "syscalls.S"
986#undef SYSCALL 1024#undef SYSCALL
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 2ac095bc0e25..f3222a1b2861 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -87,13 +87,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
87 larl %r13,system_call 87 larl %r13,system_call
88 .endm 88 .endm
89 89
90 .macro SAVE_ALL psworg,savearea,sync 90 .macro SAVE_ALL_SYNC psworg,savearea
91 la %r12,\psworg 91 la %r12,\psworg
92 .if \sync
93 tm \psworg+1,0x01 # test problem state bit 92 tm \psworg+1,0x01 # test problem state bit
94 jz 2f # skip stack setup save 93 jz 2f # skip stack setup save
95 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 94 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
96 .else 95#ifdef CONFIG_CHECK_STACK
96 j 3f
972: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
98 jz stack_overflow
993:
100#endif
1012:
102 .endm
103
104 .macro SAVE_ALL_ASYNC psworg,savearea
105 la %r12,\psworg
97 tm \psworg+1,0x01 # test problem state bit 106 tm \psworg+1,0x01 # test problem state bit
98 jnz 1f # from user -> load kernel stack 107 jnz 1f # from user -> load kernel stack
99 clc \psworg+8(8),BASED(.Lcritical_end) 108 clc \psworg+8(8),BASED(.Lcritical_end)
@@ -108,7 +117,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
108 srag %r14,%r14,STACK_SHIFT 117 srag %r14,%r14,STACK_SHIFT
109 jz 2f 118 jz 2f
1101: lg %r15,__LC_ASYNC_STACK # load async stack 1191: lg %r15,__LC_ASYNC_STACK # load async stack
111 .endif
112#ifdef CONFIG_CHECK_STACK 120#ifdef CONFIG_CHECK_STACK
113 j 3f 121 j 3f
1142: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 1222: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
@@ -187,7 +195,7 @@ system_call:
187 STORE_TIMER __LC_SYNC_ENTER_TIMER 195 STORE_TIMER __LC_SYNC_ENTER_TIMER
188sysc_saveall: 196sysc_saveall:
189 SAVE_ALL_BASE __LC_SAVE_AREA 197 SAVE_ALL_BASE __LC_SAVE_AREA
190 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 198 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
191 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 199 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
192 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 200 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
193#ifdef CONFIG_VIRT_CPU_ACCOUNTING 201#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -446,7 +454,7 @@ pgm_check_handler:
446 SAVE_ALL_BASE __LC_SAVE_AREA 454 SAVE_ALL_BASE __LC_SAVE_AREA
447 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 455 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
448 jnz pgm_per # got per exception -> special case 456 jnz pgm_per # got per exception -> special case
449 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 457 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
450 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 458 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
451#ifdef CONFIG_VIRT_CPU_ACCOUNTING 459#ifdef CONFIG_VIRT_CPU_ACCOUNTING
452 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 460 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -485,7 +493,7 @@ pgm_per:
485# Normal per exception 493# Normal per exception
486# 494#
487pgm_per_std: 495pgm_per_std:
488 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 496 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
489 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 497 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
490#ifdef CONFIG_VIRT_CPU_ACCOUNTING 498#ifdef CONFIG_VIRT_CPU_ACCOUNTING
491 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 499 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -511,7 +519,7 @@ pgm_no_vtime2:
511# it was a single stepped SVC that is causing all the trouble 519# it was a single stepped SVC that is causing all the trouble
512# 520#
513pgm_svcper: 521pgm_svcper:
514 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 522 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
515 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 523 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
516#ifdef CONFIG_VIRT_CPU_ACCOUNTING 524#ifdef CONFIG_VIRT_CPU_ACCOUNTING
517 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 525 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -539,7 +547,7 @@ io_int_handler:
539 STORE_TIMER __LC_ASYNC_ENTER_TIMER 547 STORE_TIMER __LC_ASYNC_ENTER_TIMER
540 stck __LC_INT_CLOCK 548 stck __LC_INT_CLOCK
541 SAVE_ALL_BASE __LC_SAVE_AREA+32 549 SAVE_ALL_BASE __LC_SAVE_AREA+32
542 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 550 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
543 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 551 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
544#ifdef CONFIG_VIRT_CPU_ACCOUNTING 552#ifdef CONFIG_VIRT_CPU_ACCOUNTING
545 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 553 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -647,7 +655,7 @@ ext_int_handler:
647 STORE_TIMER __LC_ASYNC_ENTER_TIMER 655 STORE_TIMER __LC_ASYNC_ENTER_TIMER
648 stck __LC_INT_CLOCK 656 stck __LC_INT_CLOCK
649 SAVE_ALL_BASE __LC_SAVE_AREA+32 657 SAVE_ALL_BASE __LC_SAVE_AREA+32
650 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 658 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
651 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 659 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
652#ifdef CONFIG_VIRT_CPU_ACCOUNTING 660#ifdef CONFIG_VIRT_CPU_ACCOUNTING
653 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 661 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -672,21 +680,32 @@ __critical_end:
672mcck_int_handler: 680mcck_int_handler:
673 la %r1,4095 # revalidate r1 681 la %r1,4095 # revalidate r1
674 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 682 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
675 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1)
676 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 683 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
677 SAVE_ALL_BASE __LC_SAVE_AREA+64 684 SAVE_ALL_BASE __LC_SAVE_AREA+64
678 la %r12,__LC_MCK_OLD_PSW 685 la %r12,__LC_MCK_OLD_PSW
679 tm __LC_MCCK_CODE,0x80 # system damage? 686 tm __LC_MCCK_CODE,0x80 # system damage?
680 jo mcck_int_main # yes -> rest of mcck code invalid 687 jo mcck_int_main # yes -> rest of mcck code invalid
681 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
682 jo 0f
683 spt __LC_LAST_UPDATE_TIMER
684#ifdef CONFIG_VIRT_CPU_ACCOUNTING 688#ifdef CONFIG_VIRT_CPU_ACCOUNTING
685 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 689 la %r14,4095
686 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 690 mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER
687 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 691 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14)
692 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
693 jo 1f
694 la %r14,__LC_SYNC_ENTER_TIMER
695 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
696 jl 0f
697 la %r14,__LC_ASYNC_ENTER_TIMER
6980: clc 0(8,%r14),__LC_EXIT_TIMER
699 jl 0f
700 la %r14,__LC_EXIT_TIMER
7010: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
702 jl 0f
703 la %r14,__LC_LAST_UPDATE_TIMER
7040: spt 0(%r14)
705 mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
7061:
688#endif 707#endif
6890: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 708 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
690 jno mcck_int_main # no -> skip cleanup critical 709 jno mcck_int_main # no -> skip cleanup critical
691 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 710 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
692 jnz mcck_int_main # from user -> load kernel stack 711 jnz mcck_int_main # from user -> load kernel stack
@@ -705,7 +724,7 @@ mcck_int_main:
705#ifdef CONFIG_VIRT_CPU_ACCOUNTING 724#ifdef CONFIG_VIRT_CPU_ACCOUNTING
706 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? 725 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
707 jno mcck_no_vtime # no -> no timer update 726 jno mcck_no_vtime # no -> no timer update
708 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? 727 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
709 jz mcck_no_vtime 728 jz mcck_no_vtime
710 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 729 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
711 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 730 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -727,7 +746,17 @@ mcck_no_vtime:
727 jno mcck_return 746 jno mcck_return
728 brasl %r14,s390_handle_mcck 747 brasl %r14,s390_handle_mcck
729mcck_return: 748mcck_return:
730 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 749 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
750 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
751 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15
752#ifdef CONFIG_VIRT_CPU_ACCOUNTING
753 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104
754 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
755 jno 0f
756 stpt __LC_EXIT_TIMER
7570:
758#endif
759 lpswe __LC_RETURN_MCCK_PSW # back to caller
731 760
732#ifdef CONFIG_SMP 761#ifdef CONFIG_SMP
733/* 762/*
@@ -789,6 +818,8 @@ cleanup_table_sysc_leave:
789 .quad sysc_leave, sysc_work_loop 818 .quad sysc_leave, sysc_work_loop
790cleanup_table_sysc_work_loop: 819cleanup_table_sysc_work_loop:
791 .quad sysc_work_loop, sysc_reschedule 820 .quad sysc_work_loop, sysc_reschedule
821cleanup_table_io_return:
822 .quad io_return, io_leave
792cleanup_table_io_leave: 823cleanup_table_io_leave:
793 .quad io_leave, io_done 824 .quad io_leave, io_done
794cleanup_table_io_work_loop: 825cleanup_table_io_work_loop:
@@ -815,6 +846,11 @@ cleanup_critical:
815 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) 846 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
816 jl cleanup_sysc_return 847 jl cleanup_sysc_return
8170: 8480:
849 clc 8(8,%r12),BASED(cleanup_table_io_return)
850 jl 0f
851 clc 8(8,%r12),BASED(cleanup_table_io_return+8)
852 jl cleanup_io_return
8530:
818 clc 8(8,%r12),BASED(cleanup_table_io_leave) 854 clc 8(8,%r12),BASED(cleanup_table_io_leave)
819 jl 0f 855 jl 0f
820 clc 8(8,%r12),BASED(cleanup_table_io_leave+8) 856 clc 8(8,%r12),BASED(cleanup_table_io_leave+8)
@@ -847,7 +883,7 @@ cleanup_system_call:
847 mvc __LC_SAVE_AREA(32),0(%r12) 883 mvc __LC_SAVE_AREA(32),0(%r12)
8480: stg %r13,8(%r12) 8840: stg %r13,8(%r12)
849 stg %r12,__LC_SAVE_AREA+96 # argh 885 stg %r12,__LC_SAVE_AREA+96 # argh
850 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 886 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
851 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 887 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
852 lg %r12,__LC_SAVE_AREA+96 # argh 888 lg %r12,__LC_SAVE_AREA+96 # argh
853 stg %r15,24(%r12) 889 stg %r15,24(%r12)
@@ -957,7 +993,6 @@ cleanup_io_leave_insn:
957 .quad __critical_end 993 .quad __critical_end
958 994
959#define SYSCALL(esa,esame,emu) .long esame 995#define SYSCALL(esa,esame,emu) .long esame
960 .globl sys_call_table
961sys_call_table: 996sys_call_table:
962#include "syscalls.S" 997#include "syscalls.S"
963#undef SYSCALL 998#undef SYSCALL
@@ -965,7 +1000,6 @@ sys_call_table:
965#ifdef CONFIG_COMPAT 1000#ifdef CONFIG_COMPAT
966 1001
967#define SYSCALL(esa,esame,emu) .long emu 1002#define SYSCALL(esa,esame,emu) .long emu
968 .globl sys_call_table_emu
969sys_call_table_emu: 1003sys_call_table_emu:
970#include "syscalls.S" 1004#include "syscalls.S"
971#undef SYSCALL 1005#undef SYSCALL
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index ea88d066bf04..538c82da49b1 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/s390/kernel/head.S 2 * arch/s390/kernel/head.S
3 * 3 *
4 * (C) Copyright IBM Corp. 1999, 2005 4 * Copyright (C) IBM Corp. 1999,2006
5 * 5 *
6 * Author(s): Hartmut Penner <hp@de.ibm.com> 6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -482,24 +482,23 @@ start:
482 482
483.macro GET_IPL_DEVICE 483.macro GET_IPL_DEVICE
484.Lget_ipl_device: 484.Lget_ipl_device:
485 basr %r12,0 485 l %r1,0xb8 # get sid
486.LGID: l %r1,0xb8 # get sid
487 sll %r1,15 # test if subchannel is enabled 486 sll %r1,15 # test if subchannel is enabled
488 srl %r1,31 487 srl %r1,31
489 ltr %r1,%r1 488 ltr %r1,%r1
490 bz 0(%r14) # subchannel disabled 489 bz 2f-.LPG1(%r13) # subchannel disabled
491 l %r1,0xb8 490 l %r1,0xb8
492 la %r5,.Lipl_schib-.LGID(%r12) 491 la %r5,.Lipl_schib-.LPG1(%r13)
493 stsch 0(%r5) # get schib of subchannel 492 stsch 0(%r5) # get schib of subchannel
494 bnz 0(%r14) # schib not available 493 bnz 2f-.LPG1(%r13) # schib not available
495 tm 5(%r5),0x01 # devno valid? 494 tm 5(%r5),0x01 # devno valid?
496 bno 0(%r14) 495 bno 2f-.LPG1(%r13)
497 la %r6,ipl_parameter_flags-.LGID(%r12) 496 la %r6,ipl_parameter_flags-.LPG1(%r13)
498 oi 3(%r6),0x01 # set flag 497 oi 3(%r6),0x01 # set flag
499 la %r2,ipl_devno-.LGID(%r12) 498 la %r2,ipl_devno-.LPG1(%r13)
500 mvc 0(2,%r2),6(%r5) # store devno 499 mvc 0(2,%r2),6(%r5) # store devno
501 tm 4(%r5),0x80 # qdio capable device? 500 tm 4(%r5),0x80 # qdio capable device?
502 bno 0(%r14) 501 bno 2f-.LPG1(%r13)
503 oi 3(%r6),0x02 # set flag 502 oi 3(%r6),0x02 # set flag
504 503
505 # copy ipl parameters 504 # copy ipl parameters
@@ -523,7 +522,7 @@ start:
523 ar %r2,%r1 522 ar %r2,%r1
524 sr %r0,%r4 523 sr %r0,%r4
525 jne 1b 524 jne 1b
526 b 0(%r14) 525 b 2f-.LPG1(%r13)
527 526
528 .align 4 527 .align 4
529.Lipl_schib: 528.Lipl_schib:
@@ -537,6 +536,7 @@ ipl_parameter_flags:
537 .globl ipl_devno 536 .globl ipl_devno
538ipl_devno: 537ipl_devno:
539 .word 0 538 .word 0
5392:
540.endm 540.endm
541 541
542#ifdef CONFIG_64BIT 542#ifdef CONFIG_64BIT
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 2d3b089bfb83..d00de17b3778 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/s390/kernel/head31.S 2 * arch/s390/kernel/head31.S
3 * 3 *
4 * (C) Copyright IBM Corp. 2005 4 * Copyright (C) IBM Corp. 2005,2006
5 * 5 *
6 * Author(s): Hartmut Penner <hp@de.ibm.com> 6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -16,12 +16,31 @@
16# or linload or SALIPL 16# or linload or SALIPL
17# 17#
18 .org 0x10000 18 .org 0x10000
19startup:basr %r13,0 # get base 19startup:basr %r13,0 # get base
20.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13) 20.LPG0: l %r13,0f-.LPG0(%r13)
21 basr %r14, %r1 21 b 0(%r13)
220: .long startup_continue
23
24#
25# params at 10400 (setup.h)
26#
27 .org PARMAREA
28 .long 0,0 # IPL_DEVICE
29 .long 0,RAMDISK_ORIGIN # INITRD_START
30 .long 0,RAMDISK_SIZE # INITRD_SIZE
31
32 .org COMMAND_LINE
33 .byte "root=/dev/ram0 ro"
34 .byte 0
35
36 .org 0x11000
37
38startup_continue:
39 basr %r13,0 # get base
40.LPG1: GET_IPL_DEVICE
22 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 41 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
23 la %r12,_pstart-.LPG1(%r13) # pointer to parameter area 42 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
24 # move IPL device to lowcore 43 # move IPL device to lowcore
25 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) 44 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
26 45
27# 46#
@@ -51,8 +70,8 @@ startup:basr %r13,0 # get base
51 a %r1,__LC_EXT_NEW_PSW+4 # set handler 70 a %r1,__LC_EXT_NEW_PSW+4 # set handler
52 st %r1,__LC_EXT_NEW_PSW+4 71 st %r1,__LC_EXT_NEW_PSW+4
53 72
54 la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff 73 l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff
55 la %r1, .Lsccb-PARMAREA(%r4) # our sccb 74 lr %r1,%r4 # our sccb
56 .insn rre,0xb2200000,%r2,%r1 # service call 75 .insn rre,0xb2200000,%r2,%r1 # service call
57 ipm %r1 76 ipm %r1
58 srl %r1,28 # get cc code 77 srl %r1,28 # get cc code
@@ -63,7 +82,7 @@ startup:basr %r13,0 # get base
63 be .Lservicecall-.LPG1(%r13) 82 be .Lservicecall-.LPG1(%r13)
64 lpsw .Lwaitsclp-.LPG1(%r13) 83 lpsw .Lwaitsclp-.LPG1(%r13)
65.Lsclph: 84.Lsclph:
66 lh %r1,.Lsccbr-PARMAREA(%r4) 85 lh %r1,.Lsccbr-.Lsccb(%r4)
67 chi %r1,0x10 # 0x0010 is the sucess code 86 chi %r1,0x10 # 0x0010 is the sucess code
68 je .Lprocsccb # let's process the sccb 87 je .Lprocsccb # let's process the sccb
69 chi %r1,0x1f0 88 chi %r1,0x1f0
@@ -74,7 +93,7 @@ startup:basr %r13,0 # get base
74 b .Lservicecall-.LPG1(%r13) 93 b .Lservicecall-.LPG1(%r13)
75.Lprocsccb: 94.Lprocsccb:
76 lhi %r1,0 95 lhi %r1,0
77 icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 96 icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
78 jnz .Lscnd 97 jnz .Lscnd
79 lhi %r1,0x800 # otherwise report 2GB 98 lhi %r1,0x800 # otherwise report 2GB
80.Lscnd: 99.Lscnd:
@@ -84,10 +103,10 @@ startup:basr %r13,0 # get base
84 lr %r1,%r3 103 lr %r1,%r3
85.Lno2gb: 104.Lno2gb:
86 xr %r3,%r3 # same logic 105 xr %r3,%r3 # same logic
87 ic %r3,.Lscpa1-PARMAREA(%r4) 106 ic %r3,.Lscpa1-.Lsccb(%r4)
88 chi %r3,0x00 107 chi %r3,0x00
89 jne .Lcompmem 108 jne .Lcompmem
90 l %r3,.Lscpa2-PARMAREA(%r13) 109 l %r3,.Lscpa2-.Lsccb(%r4)
91.Lcompmem: 110.Lcompmem:
92 mr %r2,%r1 # mem in MB on 128-bit 111 mr %r2,%r1 # mem in MB on 128-bit
93 l %r1,.Lonemb-.LPG1(%r13) 112 l %r1,.Lonemb-.LPG1(%r13)
@@ -95,8 +114,6 @@ startup:basr %r13,0 # get base
95 b .Lfchunk-.LPG1(%r13) 114 b .Lfchunk-.LPG1(%r13)
96 115
97 .align 4 116 .align 4
98.Lget_ipl_device_addr:
99 .long .Lget_ipl_device
100.Lpmask: 117.Lpmask:
101 .byte 0 118 .byte 0
102.align 8 119.align 8
@@ -242,6 +259,8 @@ startup:basr %r13,0 # get base
242 .long 0 # cr13: home space segment table 259 .long 0 # cr13: home space segment table
243 .long 0xc0000000 # cr14: machine check handling off 260 .long 0xc0000000 # cr14: machine check handling off
244 .long 0 # cr15: linkage stack operations 261 .long 0 # cr15: linkage stack operations
262.Lduct: .long 0,0,0,0,0,0,0,0
263 .long 0,0,0,0,0,0,0,0
245.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem 264.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem
246.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu 265.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
247.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp 266.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
@@ -252,25 +271,9 @@ startup:basr %r13,0 # get base
252.Lmflags:.long machine_flags 271.Lmflags:.long machine_flags
253.Lbss_bgn: .long __bss_start 272.Lbss_bgn: .long __bss_start
254.Lbss_end: .long _end 273.Lbss_end: .long _end
255 274.Lparmaddr: .long PARMAREA
256 .org PARMAREA-64 275.Lsccbaddr: .long .Lsccb
257.Lduct: .long 0,0,0,0,0,0,0,0 276 .align 4096
258 .long 0,0,0,0,0,0,0,0
259
260#
261# params at 10400 (setup.h)
262#
263 .org PARMAREA
264 .global _pstart
265_pstart:
266 .long 0,0 # IPL_DEVICE
267 .long 0,RAMDISK_ORIGIN # INITRD_START
268 .long 0,RAMDISK_SIZE # INITRD_SIZE
269
270 .org COMMAND_LINE
271 .byte "root=/dev/ram0 ro"
272 .byte 0
273 .org 0x11000
274.Lsccb: 277.Lsccb:
275 .hword 0x1000 # length, one page 278 .hword 0x1000 # length, one page
276 .byte 0x00,0x00,0x00 279 .byte 0x00,0x00,0x00
@@ -287,18 +290,14 @@ _pstart:
287.Lscpincr2: 290.Lscpincr2:
288 .quad 0x00 291 .quad 0x00
289 .fill 3984,1,0 292 .fill 3984,1,0
290 .org 0x12000 293 .align 4096
291 .global _pend
292_pend:
293
294 GET_IPL_DEVICE
295 294
296#ifdef CONFIG_SHARED_KERNEL 295#ifdef CONFIG_SHARED_KERNEL
297 .org 0x100000 296 .org 0x100000
298#endif 297#endif
299 298
300# 299#
301# startup-code, running in virtual mode 300# startup-code, running in absolute addressing mode
302# 301#
303 .globl _stext 302 .globl _stext
304_stext: basr %r13,0 # get base 303_stext: basr %r13,0 # get base
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index f08c06f45d5c..47744fcca930 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/s390/kernel/head64.S 2 * arch/s390/kernel/head64.S
3 * 3 *
4 * (C) Copyright IBM Corp. 1999,2005 4 * Copyright (C) IBM Corp. 1999,2006
5 * 5 *
6 * Author(s): Hartmut Penner <hp@de.ibm.com> 6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -15,18 +15,37 @@
15# this is called either by the ipl loader or directly by PSW restart 15# this is called either by the ipl loader or directly by PSW restart
16# or linload or SALIPL 16# or linload or SALIPL
17# 17#
18 .org 0x10000 18 .org 0x10000
19startup:basr %r13,0 # get base 19startup:basr %r13,0 # get base
20.LPG0: l %r13,0f-.LPG0(%r13)
21 b 0(%r13)
220: .long startup_continue
23
24#
25# params at 10400 (setup.h)
26#
27 .org PARMAREA
28 .quad 0 # IPL_DEVICE
29 .quad RAMDISK_ORIGIN # INITRD_START
30 .quad RAMDISK_SIZE # INITRD_SIZE
31
32 .org COMMAND_LINE
33 .byte "root=/dev/ram0 ro"
34 .byte 0
35
36 .org 0x11000
37
38startup_continue:
39 basr %r13,0 # get base
20.LPG1: sll %r13,1 # remove high order bit 40.LPG1: sll %r13,1 # remove high order bit
21 srl %r13,1 41 srl %r13,1
22 l %r1,.Lget_ipl_device_addr-.LPG1(%r13) 42 GET_IPL_DEVICE
23 basr %r14,%r1
24 lhi %r1,1 # mode 1 = esame 43 lhi %r1,1 # mode 1 = esame
25 slr %r0,%r0 # set cpuid to zero 44 slr %r0,%r0 # set cpuid to zero
26 sigp %r1,%r0,0x12 # switch to esame mode 45 sigp %r1,%r0,0x12 # switch to esame mode
27 sam64 # switch to 64 bit mode 46 sam64 # switch to 64 bit mode
28 lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 47 lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
29 larl %r12,_pstart # pointer to parameter area 48 lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area
30 # move IPL device to lowcore 49 # move IPL device to lowcore
31 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) 50 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
32 51
@@ -55,8 +74,8 @@ startup:basr %r13,0 # get base
55 larl %r1,.Lsclph 74 larl %r1,.Lsclph
56 stg %r1,__LC_EXT_NEW_PSW+8 # set handler 75 stg %r1,__LC_EXT_NEW_PSW+8 # set handler
57 76
58 larl %r4,_pstart # %r4 is our index for sccb stuff 77 larl %r4,.Lsccb # %r4 is our index for sccb stuff
59 la %r1,.Lsccb-PARMAREA(%r4) # our sccb 78 lgr %r1,%r4 # our sccb
60 .insn rre,0xb2200000,%r2,%r1 # service call 79 .insn rre,0xb2200000,%r2,%r1 # service call
61 ipm %r1 80 ipm %r1
62 srl %r1,28 # get cc code 81 srl %r1,28 # get cc code
@@ -67,7 +86,7 @@ startup:basr %r13,0 # get base
67 be .Lservicecall-.LPG1(%r13) 86 be .Lservicecall-.LPG1(%r13)
68 lpswe .Lwaitsclp-.LPG1(%r13) 87 lpswe .Lwaitsclp-.LPG1(%r13)
69.Lsclph: 88.Lsclph:
70 lh %r1,.Lsccbr-PARMAREA(%r4) 89 lh %r1,.Lsccbr-.Lsccb(%r4)
71 chi %r1,0x10 # 0x0010 is the sucess code 90 chi %r1,0x10 # 0x0010 is the sucess code
72 je .Lprocsccb # let's process the sccb 91 je .Lprocsccb # let's process the sccb
73 chi %r1,0x1f0 92 chi %r1,0x1f0
@@ -78,15 +97,15 @@ startup:basr %r13,0 # get base
78 b .Lservicecall-.LPG1(%r13) 97 b .Lservicecall-.LPG1(%r13)
79.Lprocsccb: 98.Lprocsccb:
80 lghi %r1,0 99 lghi %r1,0
81 icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 100 icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
82 jnz .Lscnd 101 jnz .Lscnd
83 lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one 102 lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one
84.Lscnd: 103.Lscnd:
85 xr %r3,%r3 # same logic 104 xr %r3,%r3 # same logic
86 ic %r3,.Lscpa1-PARMAREA(%r4) 105 ic %r3,.Lscpa1-.Lsccb(%r4)
87 chi %r3,0x00 106 chi %r3,0x00
88 jne .Lcompmem 107 jne .Lcompmem
89 l %r3,.Lscpa2-PARMAREA(%r13) 108 l %r3,.Lscpa2-.Lsccb(%r4)
90.Lcompmem: 109.Lcompmem:
91 mlgr %r2,%r1 # mem in MB on 128-bit 110 mlgr %r2,%r1 # mem in MB on 128-bit
92 l %r1,.Lonemb-.LPG1(%r13) 111 l %r1,.Lonemb-.LPG1(%r13)
@@ -94,8 +113,6 @@ startup:basr %r13,0 # get base
94 b .Lfchunk-.LPG1(%r13) 113 b .Lfchunk-.LPG1(%r13)
95 114
96 .align 4 115 .align 4
97.Lget_ipl_device_addr:
98 .long .Lget_ipl_device
99.Lpmask: 116.Lpmask:
100 .byte 0 117 .byte 0
101 .align 8 118 .align 8
@@ -242,29 +259,16 @@ startup:basr %r13,0 # get base
242 .quad 0 # cr13: home space segment table 259 .quad 0 # cr13: home space segment table
243 .quad 0xc0000000 # cr14: machine check handling off 260 .quad 0xc0000000 # cr14: machine check handling off
244 .quad 0 # cr15: linkage stack operations 261 .quad 0 # cr15: linkage stack operations
262.Lduct: .long 0,0,0,0,0,0,0,0
263 .long 0,0,0,0,0,0,0,0
245.Lpcmsk:.quad 0x0000000180000000 264.Lpcmsk:.quad 0x0000000180000000
246.L4malign:.quad 0xffffffffffc00000 265.L4malign:.quad 0xffffffffffc00000
247.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 266.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
248.Lnop: .long 0x07000700 267.Lnop: .long 0x07000700
268.Lparmaddr:
269 .quad PARMAREA
249 270
250 .org PARMAREA-64 271 .align 4096
251.Lduct: .long 0,0,0,0,0,0,0,0
252 .long 0,0,0,0,0,0,0,0
253
254#
255# params at 10400 (setup.h)
256#
257 .org PARMAREA
258 .global _pstart
259_pstart:
260 .quad 0 # IPL_DEVICE
261 .quad RAMDISK_ORIGIN # INITRD_START
262 .quad RAMDISK_SIZE # INITRD_SIZE
263
264 .org COMMAND_LINE
265 .byte "root=/dev/ram0 ro"
266 .byte 0
267 .org 0x11000
268.Lsccb: 272.Lsccb:
269 .hword 0x1000 # length, one page 273 .hword 0x1000 # length, one page
270 .byte 0x00,0x00,0x00 274 .byte 0x00,0x00,0x00
@@ -281,18 +285,14 @@ _pstart:
281.Lscpincr2: 285.Lscpincr2:
282 .quad 0x00 286 .quad 0x00
283 .fill 3984,1,0 287 .fill 3984,1,0
284 .org 0x12000 288 .align 4096
285 .global _pend
286_pend:
287
288 GET_IPL_DEVICE
289 289
290#ifdef CONFIG_SHARED_KERNEL 290#ifdef CONFIG_SHARED_KERNEL
291 .org 0x100000 291 .org 0x100000
292#endif 292#endif
293 293
294# 294#
295# startup-code, running in virtual mode 295# startup-code, running in absolute addressing mode
296# 296#
297 .globl _stext 297 .globl _stext
298_stext: basr %r13,0 # get base 298_stext: basr %r13,0 # get base
@@ -326,4 +326,3 @@ _stext: basr %r13,0 # get base
326 .align 8 326 .align 8
327.Ldw: .quad 0x0002000180000000,0x0000000000000000 327.Ldw: .quad 0x0002000180000000,0x0000000000000000
328.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 328.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
329
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 4176c77670c4..0886e739d122 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -46,8 +46,6 @@ EXPORT_SYMBOL(__down_interruptible);
46 */ 46 */
47extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); 47extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs);
48EXPORT_SYMBOL(dump_fpu); 48EXPORT_SYMBOL(dump_fpu);
49EXPORT_SYMBOL(overflowuid);
50EXPORT_SYMBOL(overflowgid);
51EXPORT_SYMBOL(empty_zero_page); 49EXPORT_SYMBOL(empty_zero_page);
52 50
53/* 51/*
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b282034452a4..2b2551e3510b 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -37,6 +37,7 @@
37#include <linux/seq_file.h> 37#include <linux/seq_file.h>
38#include <linux/kernel_stat.h> 38#include <linux/kernel_stat.h>
39#include <linux/device.h> 39#include <linux/device.h>
40#include <linux/notifier.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/system.h> 43#include <asm/system.h>
@@ -115,6 +116,7 @@ void __devinit cpu_init (void)
115 */ 116 */
116char vmhalt_cmd[128] = ""; 117char vmhalt_cmd[128] = "";
117char vmpoff_cmd[128] = ""; 118char vmpoff_cmd[128] = "";
119char vmpanic_cmd[128] = "";
118 120
119static inline void strncpy_skip_quote(char *dst, char *src, int n) 121static inline void strncpy_skip_quote(char *dst, char *src, int n)
120{ 122{
@@ -146,6 +148,38 @@ static int __init vmpoff_setup(char *str)
146 148
147__setup("vmpoff=", vmpoff_setup); 149__setup("vmpoff=", vmpoff_setup);
148 150
151static int vmpanic_notify(struct notifier_block *self, unsigned long event,
152 void *data)
153{
154 if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0)
155 cpcmd(vmpanic_cmd, NULL, 0, NULL);
156
157 return NOTIFY_OK;
158}
159
160#define PANIC_PRI_VMPANIC 0
161
162static struct notifier_block vmpanic_nb = {
163 .notifier_call = vmpanic_notify,
164 .priority = PANIC_PRI_VMPANIC
165};
166
167static int __init vmpanic_setup(char *str)
168{
169 static int register_done __initdata = 0;
170
171 strncpy_skip_quote(vmpanic_cmd, str, 127);
172 vmpanic_cmd[127] = 0;
173 if (!register_done) {
174 register_done = 1;
175 atomic_notifier_chain_register(&panic_notifier_list,
176 &vmpanic_nb);
177 }
178 return 1;
179}
180
181__setup("vmpanic=", vmpanic_setup);
182
149/* 183/*
150 * condev= and conmode= setup parameter. 184 * condev= and conmode= setup parameter.
151 */ 185 */
@@ -289,19 +323,34 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
289 323
290void machine_restart(char *command) 324void machine_restart(char *command)
291{ 325{
292 console_unblank(); 326 if (!in_interrupt() || oops_in_progress)
327 /*
328 * Only unblank the console if we are called in enabled
329 * context or a bust_spinlocks cleared the way for us.
330 */
331 console_unblank();
293 _machine_restart(command); 332 _machine_restart(command);
294} 333}
295 334
296void machine_halt(void) 335void machine_halt(void)
297{ 336{
298 console_unblank(); 337 if (!in_interrupt() || oops_in_progress)
338 /*
339 * Only unblank the console if we are called in enabled
340 * context or a bust_spinlocks cleared the way for us.
341 */
342 console_unblank();
299 _machine_halt(); 343 _machine_halt();
300} 344}
301 345
302void machine_power_off(void) 346void machine_power_off(void)
303{ 347{
304 console_unblank(); 348 if (!in_interrupt() || oops_in_progress)
349 /*
350 * Only unblank the console if we are called in enabled
351 * context or a bust_spinlocks cleared the way for us.
352 */
353 console_unblank();
305 _machine_power_off(); 354 _machine_power_off();
306} 355}
307 356
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a46793beeddd..b7630436f693 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -150,13 +150,11 @@ void show_stack(struct task_struct *task, unsigned long *sp)
150 unsigned long *stack; 150 unsigned long *stack;
151 int i; 151 int i;
152 152
153 // debugging aid: "show_stack(NULL);" prints the
154 // back trace for this cpu.
155
156 if (!sp) 153 if (!sp)
157 sp = task ? (unsigned long *) task->thread.ksp : __r15; 154 stack = task ? (unsigned long *) task->thread.ksp : __r15;
155 else
156 stack = sp;
158 157
159 stack = sp;
160 for (i = 0; i < kstack_depth_to_print; i++) { 158 for (i = 0; i < kstack_depth_to_print; i++) {
161 if (((addr_t) stack & (THREAD_SIZE-1)) == 0) 159 if (((addr_t) stack & (THREAD_SIZE-1)) == 0)
162 break; 160 break;
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index cfb1fff3787c..bafcd2f20ae2 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -95,7 +95,7 @@ dasd_alloc_device(void)
95 spin_lock_init(&device->mem_lock); 95 spin_lock_init(&device->mem_lock);
96 spin_lock_init(&device->request_queue_lock); 96 spin_lock_init(&device->request_queue_lock);
97 atomic_set (&device->tasklet_scheduled, 0); 97 atomic_set (&device->tasklet_scheduled, 0);
98 tasklet_init(&device->tasklet, 98 tasklet_init(&device->tasklet,
99 (void (*)(unsigned long)) dasd_tasklet, 99 (void (*)(unsigned long)) dasd_tasklet,
100 (unsigned long) device); 100 (unsigned long) device);
101 INIT_LIST_HEAD(&device->ccw_queue); 101 INIT_LIST_HEAD(&device->ccw_queue);
@@ -128,7 +128,7 @@ dasd_state_new_to_known(struct dasd_device *device)
128 int rc; 128 int rc;
129 129
130 /* 130 /*
131 * As long as the device is not in state DASD_STATE_NEW we want to 131 * As long as the device is not in state DASD_STATE_NEW we want to
132 * keep the reference count > 0. 132 * keep the reference count > 0.
133 */ 133 */
134 dasd_get_device(device); 134 dasd_get_device(device);
@@ -336,7 +336,7 @@ dasd_decrease_state(struct dasd_device *device)
336 if (device->state == DASD_STATE_ONLINE && 336 if (device->state == DASD_STATE_ONLINE &&
337 device->target <= DASD_STATE_READY) 337 device->target <= DASD_STATE_READY)
338 dasd_state_online_to_ready(device); 338 dasd_state_online_to_ready(device);
339 339
340 if (device->state == DASD_STATE_READY && 340 if (device->state == DASD_STATE_READY &&
341 device->target <= DASD_STATE_BASIC) 341 device->target <= DASD_STATE_BASIC)
342 dasd_state_ready_to_basic(device); 342 dasd_state_ready_to_basic(device);
@@ -348,7 +348,7 @@ dasd_decrease_state(struct dasd_device *device)
348 if (device->state == DASD_STATE_BASIC && 348 if (device->state == DASD_STATE_BASIC &&
349 device->target <= DASD_STATE_KNOWN) 349 device->target <= DASD_STATE_KNOWN)
350 dasd_state_basic_to_known(device); 350 dasd_state_basic_to_known(device);
351 351
352 if (device->state == DASD_STATE_KNOWN && 352 if (device->state == DASD_STATE_KNOWN &&
353 device->target <= DASD_STATE_NEW) 353 device->target <= DASD_STATE_NEW)
354 dasd_state_known_to_new(device); 354 dasd_state_known_to_new(device);
@@ -994,7 +994,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
994 ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); 994 ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr);
995 995
996 /* Find out the appropriate era_action. */ 996 /* Find out the appropriate era_action. */
997 if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) 997 if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC)
998 era = dasd_era_fatal; 998 era = dasd_era_fatal;
999 else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && 999 else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
1000 irb->scsw.cstat == 0 && 1000 irb->scsw.cstat == 0 &&
@@ -1004,7 +1004,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1004 era = dasd_era_fatal; /* don't recover this request */ 1004 era = dasd_era_fatal; /* don't recover this request */
1005 else if (irb->esw.esw0.erw.cons) 1005 else if (irb->esw.esw0.erw.cons)
1006 era = device->discipline->examine_error(cqr, irb); 1006 era = device->discipline->examine_error(cqr, irb);
1007 else 1007 else
1008 era = dasd_era_recover; 1008 era = dasd_era_recover;
1009 1009
1010 DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); 1010 DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era);
@@ -1287,7 +1287,7 @@ __dasd_start_head(struct dasd_device * device)
1287} 1287}
1288 1288
1289/* 1289/*
1290 * Remove requests from the ccw queue. 1290 * Remove requests from the ccw queue.
1291 */ 1291 */
1292static void 1292static void
1293dasd_flush_ccw_queue(struct dasd_device * device, int all) 1293dasd_flush_ccw_queue(struct dasd_device * device, int all)
@@ -1450,23 +1450,23 @@ dasd_sleep_on(struct dasd_ccw_req * cqr)
1450 wait_queue_head_t wait_q; 1450 wait_queue_head_t wait_q;
1451 struct dasd_device *device; 1451 struct dasd_device *device;
1452 int rc; 1452 int rc;
1453 1453
1454 device = cqr->device; 1454 device = cqr->device;
1455 spin_lock_irq(get_ccwdev_lock(device->cdev)); 1455 spin_lock_irq(get_ccwdev_lock(device->cdev));
1456 1456
1457 init_waitqueue_head (&wait_q); 1457 init_waitqueue_head (&wait_q);
1458 cqr->callback = dasd_wakeup_cb; 1458 cqr->callback = dasd_wakeup_cb;
1459 cqr->callback_data = (void *) &wait_q; 1459 cqr->callback_data = (void *) &wait_q;
1460 cqr->status = DASD_CQR_QUEUED; 1460 cqr->status = DASD_CQR_QUEUED;
1461 list_add_tail(&cqr->list, &device->ccw_queue); 1461 list_add_tail(&cqr->list, &device->ccw_queue);
1462 1462
1463 /* let the bh start the request to keep them in order */ 1463 /* let the bh start the request to keep them in order */
1464 dasd_schedule_bh(device); 1464 dasd_schedule_bh(device);
1465 1465
1466 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1466 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1467 1467
1468 wait_event(wait_q, _wait_for_wakeup(cqr)); 1468 wait_event(wait_q, _wait_for_wakeup(cqr));
1469 1469
1470 /* Request status is either done or failed. */ 1470 /* Request status is either done or failed. */
1471 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; 1471 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
1472 return rc; 1472 return rc;
@@ -1568,7 +1568,7 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr)
1568 wait_queue_head_t wait_q; 1568 wait_queue_head_t wait_q;
1569 struct dasd_device *device; 1569 struct dasd_device *device;
1570 int rc; 1570 int rc;
1571 1571
1572 device = cqr->device; 1572 device = cqr->device;
1573 spin_lock_irq(get_ccwdev_lock(device->cdev)); 1573 spin_lock_irq(get_ccwdev_lock(device->cdev));
1574 rc = _dasd_term_running_cqr(device); 1574 rc = _dasd_term_running_cqr(device);
@@ -1576,20 +1576,20 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr)
1576 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1576 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1577 return rc; 1577 return rc;
1578 } 1578 }
1579 1579
1580 init_waitqueue_head (&wait_q); 1580 init_waitqueue_head (&wait_q);
1581 cqr->callback = dasd_wakeup_cb; 1581 cqr->callback = dasd_wakeup_cb;
1582 cqr->callback_data = (void *) &wait_q; 1582 cqr->callback_data = (void *) &wait_q;
1583 cqr->status = DASD_CQR_QUEUED; 1583 cqr->status = DASD_CQR_QUEUED;
1584 list_add(&cqr->list, &device->ccw_queue); 1584 list_add(&cqr->list, &device->ccw_queue);
1585 1585
1586 /* let the bh start the request to keep them in order */ 1586 /* let the bh start the request to keep them in order */
1587 dasd_schedule_bh(device); 1587 dasd_schedule_bh(device);
1588 1588
1589 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1589 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1590 1590
1591 wait_event(wait_q, _wait_for_wakeup(cqr)); 1591 wait_event(wait_q, _wait_for_wakeup(cqr));
1592 1592
1593 /* Request status is either done or failed. */ 1593 /* Request status is either done or failed. */
1594 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; 1594 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
1595 return rc; 1595 return rc;
@@ -1725,7 +1725,7 @@ dasd_flush_request_queue(struct dasd_device * device)
1725 1725
1726 if (!device->request_queue) 1726 if (!device->request_queue)
1727 return; 1727 return;
1728 1728
1729 spin_lock_irq(&device->request_queue_lock); 1729 spin_lock_irq(&device->request_queue_lock);
1730 while (!list_empty(&device->request_queue->queue_head)) { 1730 while (!list_empty(&device->request_queue->queue_head)) {
1731 req = elv_next_request(device->request_queue); 1731 req = elv_next_request(device->request_queue);
@@ -1855,15 +1855,34 @@ dasd_generic_probe (struct ccw_device *cdev,
1855{ 1855{
1856 int ret; 1856 int ret;
1857 1857
1858 ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
1859 if (ret) {
1860 printk(KERN_WARNING
1861 "dasd_generic_probe: could not set ccw-device options "
1862 "for %s\n", cdev->dev.bus_id);
1863 return ret;
1864 }
1858 ret = dasd_add_sysfs_files(cdev); 1865 ret = dasd_add_sysfs_files(cdev);
1859 if (ret) { 1866 if (ret) {
1860 printk(KERN_WARNING 1867 printk(KERN_WARNING
1861 "dasd_generic_probe: could not add sysfs entries " 1868 "dasd_generic_probe: could not add sysfs entries "
1862 "for %s\n", cdev->dev.bus_id); 1869 "for %s\n", cdev->dev.bus_id);
1863 } else { 1870 return ret;
1864 cdev->handler = &dasd_int_handler;
1865 } 1871 }
1872 cdev->handler = &dasd_int_handler;
1866 1873
1874 /*
1875 * Automatically online either all dasd devices (dasd_autodetect)
1876 * or all devices specified with dasd= parameters during
1877 * initial probe.
1878 */
1879 if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) ||
1880 (dasd_autodetect && dasd_busid_known(cdev->dev.bus_id) != 0))
1881 ret = ccw_device_set_online(cdev);
1882 if (ret)
1883 printk(KERN_WARNING
1884 "dasd_generic_probe: could not initially online "
1885 "ccw-device %s\n", cdev->dev.bus_id);
1867 return ret; 1886 return ret;
1868} 1887}
1869 1888
@@ -1911,6 +1930,8 @@ dasd_generic_set_online (struct ccw_device *cdev,
1911 struct dasd_device *device; 1930 struct dasd_device *device;
1912 int rc; 1931 int rc;
1913 1932
1933 /* first online clears initial online feature flag */
1934 dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0);
1914 device = dasd_create_device(cdev); 1935 device = dasd_create_device(cdev);
1915 if (IS_ERR(device)) 1936 if (IS_ERR(device))
1916 return PTR_ERR(device); 1937 return PTR_ERR(device);
@@ -2065,31 +2086,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
2065 return ret; 2086 return ret;
2066} 2087}
2067 2088
2068/*
2069 * Automatically online either all dasd devices (dasd_autodetect) or
2070 * all devices specified with dasd= parameters.
2071 */
2072static int
2073__dasd_auto_online(struct device *dev, void *data)
2074{
2075 struct ccw_device *cdev;
2076
2077 cdev = to_ccwdev(dev);
2078 if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
2079 ccw_device_set_online(cdev);
2080 return 0;
2081}
2082
2083void
2084dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
2085{
2086 struct device_driver *drv;
2087
2088 drv = get_driver(&dasd_discipline_driver->driver);
2089 driver_for_each_device(drv, NULL, NULL, __dasd_auto_online);
2090 put_driver(drv);
2091}
2092
2093 2089
2094static int __init 2090static int __init
2095dasd_init(void) 2091dasd_init(void)
@@ -2170,23 +2166,4 @@ EXPORT_SYMBOL_GPL(dasd_generic_remove);
2170EXPORT_SYMBOL_GPL(dasd_generic_notify); 2166EXPORT_SYMBOL_GPL(dasd_generic_notify);
2171EXPORT_SYMBOL_GPL(dasd_generic_set_online); 2167EXPORT_SYMBOL_GPL(dasd_generic_set_online);
2172EXPORT_SYMBOL_GPL(dasd_generic_set_offline); 2168EXPORT_SYMBOL_GPL(dasd_generic_set_offline);
2173EXPORT_SYMBOL_GPL(dasd_generic_auto_online);
2174 2169
2175/*
2176 * Overrides for Emacs so that we follow Linus's tabbing style.
2177 * Emacs will notice this stuff at the end of the file and automatically
2178 * adjust the settings for this buffer only. This must remain at the end
2179 * of the file.
2180 * ---------------------------------------------------------------------------
2181 * Local variables:
2182 * c-indent-level: 4
2183 * c-brace-imaginary-offset: 0
2184 * c-brace-offset: -4
2185 * c-argdecl-indent: 4
2186 * c-label-offset: -4
2187 * c-continued-statement-offset: 4
2188 * c-continued-brace-offset: 0
2189 * indent-tabs-mode: 1
2190 * tab-width: 8
2191 * End:
2192 */
diff --git a/drivers/s390/block/dasd_3370_erp.c b/drivers/s390/block/dasd_3370_erp.c
index 1d11c2a9525d..1ddab8991d92 100644
--- a/drivers/s390/block/dasd_3370_erp.c
+++ b/drivers/s390/block/dasd_3370_erp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_3370_erp.c 2 * File...........: linux/drivers/s390/block/dasd_3370_erp.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -12,10 +12,10 @@
12 12
13 13
14/* 14/*
15 * DASD_3370_ERP_EXAMINE 15 * DASD_3370_ERP_EXAMINE
16 * 16 *
17 * DESCRIPTION 17 * DESCRIPTION
18 * Checks only for fatal/no/recover error. 18 * Checks only for fatal/no/recover error.
19 * A detailed examination of the sense data is done later outside 19 * A detailed examination of the sense data is done later outside
20 * the interrupt handler. 20 * the interrupt handler.
21 * 21 *
@@ -23,7 +23,7 @@
23 * 'Chapter 7. 3370 Sense Data'. 23 * 'Chapter 7. 3370 Sense Data'.
24 * 24 *
25 * RETURN VALUES 25 * RETURN VALUES
26 * dasd_era_none no error 26 * dasd_era_none no error
27 * dasd_era_fatal for all fatal (unrecoverable errors) 27 * dasd_era_fatal for all fatal (unrecoverable errors)
28 * dasd_era_recover for all others. 28 * dasd_era_recover for all others.
29 */ 29 */
@@ -82,22 +82,3 @@ dasd_3370_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
82 return dasd_era_recover; 82 return dasd_era_recover;
83 83
84} /* END dasd_3370_erp_examine */ 84} /* END dasd_3370_erp_examine */
85
86/*
87 * Overrides for Emacs so that we follow Linus's tabbing style.
88 * Emacs will notice this stuff at the end of the file and automatically
89 * adjust the settings for this buffer only. This must remain at the end
90 * of the file.
91 * ---------------------------------------------------------------------------
92 * Local variables:
93 * c-indent-level: 4
94 * c-brace-imaginary-offset: 0
95 * c-brace-offset: -4
96 * c-argdecl-indent: 4
97 * c-label-offset: -4
98 * c-continued-statement-offset: 4
99 * c-continued-brace-offset: 0
100 * indent-tabs-mode: 1
101 * tab-width: 8
102 * End:
103 */
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 2ed51562319e..669805d4402d 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_3990_erp.c 2 * File...........: linux/drivers/s390/block/dasd_3990_erp.c
3 * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com> 3 * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com>
4 * Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Holger Smolinski <Holger.Smolinski@de.ibm.com>
5 * Bugreports.to..: <Linux390@de.ibm.com> 5 * Bugreports.to..: <Linux390@de.ibm.com>
6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
@@ -25,23 +25,23 @@ struct DCTL_data {
25} __attribute__ ((packed)); 25} __attribute__ ((packed));
26 26
27/* 27/*
28 ***************************************************************************** 28 *****************************************************************************
29 * SECTION ERP EXAMINATION 29 * SECTION ERP EXAMINATION
30 ***************************************************************************** 30 *****************************************************************************
31 */ 31 */
32 32
33/* 33/*
34 * DASD_3990_ERP_EXAMINE_24 34 * DASD_3990_ERP_EXAMINE_24
35 * 35 *
36 * DESCRIPTION 36 * DESCRIPTION
37 * Checks only for fatal (unrecoverable) error. 37 * Checks only for fatal (unrecoverable) error.
38 * A detailed examination of the sense data is done later outside 38 * A detailed examination of the sense data is done later outside
39 * the interrupt handler. 39 * the interrupt handler.
40 * 40 *
41 * Each bit configuration leading to an action code 2 (Exit with 41 * Each bit configuration leading to an action code 2 (Exit with
42 * programming error or unusual condition indication) 42 * programming error or unusual condition indication)
43 * are handled as fatal error´s. 43 * are handled as fatal error´s.
44 * 44 *
45 * All other configurations are handled as recoverable errors. 45 * All other configurations are handled as recoverable errors.
46 * 46 *
47 * RETURN VALUES 47 * RETURN VALUES
@@ -93,15 +93,15 @@ dasd_3990_erp_examine_24(struct dasd_ccw_req * cqr, char *sense)
93} /* END dasd_3990_erp_examine_24 */ 93} /* END dasd_3990_erp_examine_24 */
94 94
95/* 95/*
96 * DASD_3990_ERP_EXAMINE_32 96 * DASD_3990_ERP_EXAMINE_32
97 * 97 *
98 * DESCRIPTION 98 * DESCRIPTION
99 * Checks only for fatal/no/recoverable error. 99 * Checks only for fatal/no/recoverable error.
100 * A detailed examination of the sense data is done later outside 100 * A detailed examination of the sense data is done later outside
101 * the interrupt handler. 101 * the interrupt handler.
102 * 102 *
103 * RETURN VALUES 103 * RETURN VALUES
104 * dasd_era_none no error 104 * dasd_era_none no error
105 * dasd_era_fatal for all fatal (unrecoverable errors) 105 * dasd_era_fatal for all fatal (unrecoverable errors)
106 * dasd_era_recover for recoverable others. 106 * dasd_era_recover for recoverable others.
107 */ 107 */
@@ -128,10 +128,10 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense)
128} /* end dasd_3990_erp_examine_32 */ 128} /* end dasd_3990_erp_examine_32 */
129 129
130/* 130/*
131 * DASD_3990_ERP_EXAMINE 131 * DASD_3990_ERP_EXAMINE
132 * 132 *
133 * DESCRIPTION 133 * DESCRIPTION
134 * Checks only for fatal/no/recover error. 134 * Checks only for fatal/no/recover error.
135 * A detailed examination of the sense data is done later outside 135 * A detailed examination of the sense data is done later outside
136 * the interrupt handler. 136 * the interrupt handler.
137 * 137 *
@@ -139,7 +139,7 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense)
139 * 'Chapter 7. Error Recovery Procedures'. 139 * 'Chapter 7. Error Recovery Procedures'.
140 * 140 *
141 * RETURN VALUES 141 * RETURN VALUES
142 * dasd_era_none no error 142 * dasd_era_none no error
143 * dasd_era_fatal for all fatal (unrecoverable errors) 143 * dasd_era_fatal for all fatal (unrecoverable errors)
144 * dasd_era_recover for all others. 144 * dasd_era_recover for all others.
145 */ 145 */
@@ -178,18 +178,18 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
178} /* END dasd_3990_erp_examine */ 178} /* END dasd_3990_erp_examine */
179 179
180/* 180/*
181 ***************************************************************************** 181 *****************************************************************************
182 * SECTION ERP HANDLING 182 * SECTION ERP HANDLING
183 ***************************************************************************** 183 *****************************************************************************
184 */ 184 */
185/* 185/*
186 ***************************************************************************** 186 *****************************************************************************
187 * 24 and 32 byte sense ERP functions 187 * 24 and 32 byte sense ERP functions
188 ***************************************************************************** 188 *****************************************************************************
189 */ 189 */
190 190
191/* 191/*
192 * DASD_3990_ERP_CLEANUP 192 * DASD_3990_ERP_CLEANUP
193 * 193 *
194 * DESCRIPTION 194 * DESCRIPTION
195 * Removes the already build but not necessary ERP request and sets 195 * Removes the already build but not necessary ERP request and sets
@@ -197,10 +197,10 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
197 * 197 *
198 * PARAMETER 198 * PARAMETER
199 * erp request to be blocked 199 * erp request to be blocked
200 * final_status either DASD_CQR_DONE or DASD_CQR_FAILED 200 * final_status either DASD_CQR_DONE or DASD_CQR_FAILED
201 * 201 *
202 * RETURN VALUES 202 * RETURN VALUES
203 * cqr original cqr 203 * cqr original cqr
204 */ 204 */
205static struct dasd_ccw_req * 205static struct dasd_ccw_req *
206dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) 206dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status)
@@ -214,7 +214,7 @@ dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status)
214} /* end dasd_3990_erp_cleanup */ 214} /* end dasd_3990_erp_cleanup */
215 215
216/* 216/*
217 * DASD_3990_ERP_BLOCK_QUEUE 217 * DASD_3990_ERP_BLOCK_QUEUE
218 * 218 *
219 * DESCRIPTION 219 * DESCRIPTION
220 * Block the given device request queue to prevent from further 220 * Block the given device request queue to prevent from further
@@ -237,7 +237,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
237} 237}
238 238
239/* 239/*
240 * DASD_3990_ERP_INT_REQ 240 * DASD_3990_ERP_INT_REQ
241 * 241 *
242 * DESCRIPTION 242 * DESCRIPTION
243 * Handles 'Intervention Required' error. 243 * Handles 'Intervention Required' error.
@@ -277,7 +277,7 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
277} /* end dasd_3990_erp_int_req */ 277} /* end dasd_3990_erp_int_req */
278 278
279/* 279/*
280 * DASD_3990_ERP_ALTERNATE_PATH 280 * DASD_3990_ERP_ALTERNATE_PATH
281 * 281 *
282 * DESCRIPTION 282 * DESCRIPTION
283 * Repeat the operation on a different channel path. 283 * Repeat the operation on a different channel path.
@@ -330,15 +330,15 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
330 * DASD_3990_ERP_DCTL 330 * DASD_3990_ERP_DCTL
331 * 331 *
332 * DESCRIPTION 332 * DESCRIPTION
333 * Setup cqr to do the Diagnostic Control (DCTL) command with an 333 * Setup cqr to do the Diagnostic Control (DCTL) command with an
334 * Inhibit Write subcommand (0x20) and the given modifier. 334 * Inhibit Write subcommand (0x20) and the given modifier.
335 * 335 *
336 * PARAMETER 336 * PARAMETER
337 * erp pointer to the current (failed) ERP 337 * erp pointer to the current (failed) ERP
338 * modifier subcommand modifier 338 * modifier subcommand modifier
339 * 339 *
340 * RETURN VALUES 340 * RETURN VALUES
341 * dctl_cqr pointer to NEW dctl_cqr 341 * dctl_cqr pointer to NEW dctl_cqr
342 * 342 *
343 */ 343 */
344static struct dasd_ccw_req * 344static struct dasd_ccw_req *
@@ -386,7 +386,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
386} /* end dasd_3990_erp_DCTL */ 386} /* end dasd_3990_erp_DCTL */
387 387
388/* 388/*
389 * DASD_3990_ERP_ACTION_1 389 * DASD_3990_ERP_ACTION_1
390 * 390 *
391 * DESCRIPTION 391 * DESCRIPTION
392 * Setup ERP to do the ERP action 1 (see Reference manual). 392 * Setup ERP to do the ERP action 1 (see Reference manual).
@@ -415,7 +415,7 @@ dasd_3990_erp_action_1(struct dasd_ccw_req * erp)
415} /* end dasd_3990_erp_action_1 */ 415} /* end dasd_3990_erp_action_1 */
416 416
417/* 417/*
418 * DASD_3990_ERP_ACTION_4 418 * DASD_3990_ERP_ACTION_4
419 * 419 *
420 * DESCRIPTION 420 * DESCRIPTION
421 * Setup ERP to do the ERP action 4 (see Reference manual). 421 * Setup ERP to do the ERP action 4 (see Reference manual).
@@ -453,11 +453,11 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
453 453
454 if (sense[25] == 0x1D) { /* state change pending */ 454 if (sense[25] == 0x1D) { /* state change pending */
455 455
456 DEV_MESSAGE(KERN_INFO, device, 456 DEV_MESSAGE(KERN_INFO, device,
457 "waiting for state change pending " 457 "waiting for state change pending "
458 "interrupt, %d retries left", 458 "interrupt, %d retries left",
459 erp->retries); 459 erp->retries);
460 460
461 dasd_3990_erp_block_queue(erp, 30*HZ); 461 dasd_3990_erp_block_queue(erp, 30*HZ);
462 462
463 } else if (sense[25] == 0x1E) { /* busy */ 463 } else if (sense[25] == 0x1E) { /* busy */
@@ -469,9 +469,9 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
469 } else { 469 } else {
470 470
471 /* no state change pending - retry */ 471 /* no state change pending - retry */
472 DEV_MESSAGE (KERN_INFO, device, 472 DEV_MESSAGE (KERN_INFO, device,
473 "redriving request immediately, " 473 "redriving request immediately, "
474 "%d retries left", 474 "%d retries left",
475 erp->retries); 475 erp->retries);
476 erp->status = DASD_CQR_QUEUED; 476 erp->status = DASD_CQR_QUEUED;
477 } 477 }
@@ -482,13 +482,13 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
482} /* end dasd_3990_erp_action_4 */ 482} /* end dasd_3990_erp_action_4 */
483 483
484/* 484/*
485 ***************************************************************************** 485 *****************************************************************************
486 * 24 byte sense ERP functions (only) 486 * 24 byte sense ERP functions (only)
487 ***************************************************************************** 487 *****************************************************************************
488 */ 488 */
489 489
490/* 490/*
491 * DASD_3990_ERP_ACTION_5 491 * DASD_3990_ERP_ACTION_5
492 * 492 *
493 * DESCRIPTION 493 * DESCRIPTION
494 * Setup ERP to do the ERP action 5 (see Reference manual). 494 * Setup ERP to do the ERP action 5 (see Reference manual).
@@ -523,7 +523,7 @@ dasd_3990_erp_action_5(struct dasd_ccw_req * erp)
523 * 523 *
524 * PARAMETER 524 * PARAMETER
525 * sense current sense data 525 * sense current sense data
526 * 526 *
527 * RETURN VALUES 527 * RETURN VALUES
528 * void 528 * void
529 */ 529 */
@@ -1150,9 +1150,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
1150 * PARAMETER 1150 * PARAMETER
1151 * erp current erp_head 1151 * erp current erp_head
1152 * sense current sense data 1152 * sense current sense data
1153 * 1153 *
1154 * RETURN VALUES 1154 * RETURN VALUES
1155 * erp 'new' erp_head - pointer to new ERP 1155 * erp 'new' erp_head - pointer to new ERP
1156 */ 1156 */
1157static struct dasd_ccw_req * 1157static struct dasd_ccw_req *
1158dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) 1158dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
@@ -1185,7 +1185,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
1185} /* end dasd_3990_erp_com_rej */ 1185} /* end dasd_3990_erp_com_rej */
1186 1186
1187/* 1187/*
1188 * DASD_3990_ERP_BUS_OUT 1188 * DASD_3990_ERP_BUS_OUT
1189 * 1189 *
1190 * DESCRIPTION 1190 * DESCRIPTION
1191 * Handles 24 byte 'Bus Out Parity Check' error. 1191 * Handles 24 byte 'Bus Out Parity Check' error.
@@ -1483,7 +1483,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense)
1483 * 1483 *
1484 * PARAMETER 1484 * PARAMETER
1485 * erp already added default ERP 1485 * erp already added default ERP
1486 * 1486 *
1487 * RETURN VALUES 1487 * RETURN VALUES
1488 * erp new erp_head - pointer to new ERP 1488 * erp new erp_head - pointer to new ERP
1489 */ 1489 */
@@ -1527,11 +1527,11 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
1527} /* end dasd_3990_erp_file_prot */ 1527} /* end dasd_3990_erp_file_prot */
1528 1528
1529/* 1529/*
1530 * DASD_3990_ERP_INSPECT_24 1530 * DASD_3990_ERP_INSPECT_24
1531 * 1531 *
1532 * DESCRIPTION 1532 * DESCRIPTION
1533 * Does a detailed inspection of the 24 byte sense data 1533 * Does a detailed inspection of the 24 byte sense data
1534 * and sets up a related error recovery action. 1534 * and sets up a related error recovery action.
1535 * 1535 *
1536 * PARAMETER 1536 * PARAMETER
1537 * sense sense data of the actual error 1537 * sense sense data of the actual error
@@ -1602,13 +1602,13 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense)
1602} /* END dasd_3990_erp_inspect_24 */ 1602} /* END dasd_3990_erp_inspect_24 */
1603 1603
1604/* 1604/*
1605 ***************************************************************************** 1605 *****************************************************************************
1606 * 32 byte sense ERP functions (only) 1606 * 32 byte sense ERP functions (only)
1607 ***************************************************************************** 1607 *****************************************************************************
1608 */ 1608 */
1609 1609
1610/* 1610/*
1611 * DASD_3990_ERPACTION_10_32 1611 * DASD_3990_ERPACTION_10_32
1612 * 1612 *
1613 * DESCRIPTION 1613 * DESCRIPTION
1614 * Handles 32 byte 'Action 10' of Single Program Action Codes. 1614 * Handles 32 byte 'Action 10' of Single Program Action Codes.
@@ -1616,7 +1616,7 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense)
1616 * 1616 *
1617 * PARAMETER 1617 * PARAMETER
1618 * erp current erp_head 1618 * erp current erp_head
1619 * sense current sense data 1619 * sense current sense data
1620 * RETURN VALUES 1620 * RETURN VALUES
1621 * erp modified erp_head 1621 * erp modified erp_head
1622 */ 1622 */
@@ -1640,18 +1640,18 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense)
1640 * 1640 *
1641 * DESCRIPTION 1641 * DESCRIPTION
1642 * Handles 32 byte 'Action 1B' of Single Program Action Codes. 1642 * Handles 32 byte 'Action 1B' of Single Program Action Codes.
1643 * A write operation could not be finished because of an unexpected 1643 * A write operation could not be finished because of an unexpected
1644 * condition. 1644 * condition.
1645 * The already created 'default erp' is used to get the link to 1645 * The already created 'default erp' is used to get the link to
1646 * the erp chain, but it can not be used for this recovery 1646 * the erp chain, but it can not be used for this recovery
1647 * action because it contains no DE/LO data space. 1647 * action because it contains no DE/LO data space.
1648 * 1648 *
1649 * PARAMETER 1649 * PARAMETER
1650 * default_erp already added default erp. 1650 * default_erp already added default erp.
1651 * sense current sense data 1651 * sense current sense data
1652 * 1652 *
1653 * RETURN VALUES 1653 * RETURN VALUES
1654 * erp new erp or 1654 * erp new erp or
1655 * default_erp in case of imprecise ending or error 1655 * default_erp in case of imprecise ending or error
1656 */ 1656 */
1657static struct dasd_ccw_req * 1657static struct dasd_ccw_req *
@@ -1789,16 +1789,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
1789 * DASD_3990_UPDATE_1B 1789 * DASD_3990_UPDATE_1B
1790 * 1790 *
1791 * DESCRIPTION 1791 * DESCRIPTION
1792 * Handles the update to the 32 byte 'Action 1B' of Single Program 1792 * Handles the update to the 32 byte 'Action 1B' of Single Program
1793 * Action Codes in case the first action was not successful. 1793 * Action Codes in case the first action was not successful.
1794 * The already created 'previous_erp' is the currently not successful 1794 * The already created 'previous_erp' is the currently not successful
1795 * ERP. 1795 * ERP.
1796 * 1796 *
1797 * PARAMETER 1797 * PARAMETER
1798 * previous_erp already created previous erp. 1798 * previous_erp already created previous erp.
1799 * sense current sense data 1799 * sense current sense data
1800 * RETURN VALUES 1800 * RETURN VALUES
1801 * erp modified erp 1801 * erp modified erp
1802 */ 1802 */
1803static struct dasd_ccw_req * 1803static struct dasd_ccw_req *
1804dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) 1804dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
@@ -1897,7 +1897,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
1897} /* end dasd_3990_update_1B */ 1897} /* end dasd_3990_update_1B */
1898 1898
1899/* 1899/*
1900 * DASD_3990_ERP_COMPOUND_RETRY 1900 * DASD_3990_ERP_COMPOUND_RETRY
1901 * 1901 *
1902 * DESCRIPTION 1902 * DESCRIPTION
1903 * Handles the compound ERP action retry code. 1903 * Handles the compound ERP action retry code.
@@ -1943,7 +1943,7 @@ dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense)
1943} /* end dasd_3990_erp_compound_retry */ 1943} /* end dasd_3990_erp_compound_retry */
1944 1944
1945/* 1945/*
1946 * DASD_3990_ERP_COMPOUND_PATH 1946 * DASD_3990_ERP_COMPOUND_PATH
1947 * 1947 *
1948 * DESCRIPTION 1948 * DESCRIPTION
1949 * Handles the compound ERP action for retry on alternate 1949 * Handles the compound ERP action for retry on alternate
@@ -1965,7 +1965,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
1965 dasd_3990_erp_alternate_path(erp); 1965 dasd_3990_erp_alternate_path(erp);
1966 1966
1967 if (erp->status == DASD_CQR_FAILED) { 1967 if (erp->status == DASD_CQR_FAILED) {
1968 /* reset the lpm and the status to be able to 1968 /* reset the lpm and the status to be able to
1969 * try further actions. */ 1969 * try further actions. */
1970 1970
1971 erp->lpm = 0; 1971 erp->lpm = 0;
@@ -1980,7 +1980,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
1980} /* end dasd_3990_erp_compound_path */ 1980} /* end dasd_3990_erp_compound_path */
1981 1981
1982/* 1982/*
1983 * DASD_3990_ERP_COMPOUND_CODE 1983 * DASD_3990_ERP_COMPOUND_CODE
1984 * 1984 *
1985 * DESCRIPTION 1985 * DESCRIPTION
1986 * Handles the compound ERP action for retry code. 1986 * Handles the compound ERP action for retry code.
@@ -2001,18 +2001,18 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense)
2001 2001
2002 switch (sense[28]) { 2002 switch (sense[28]) {
2003 case 0x17: 2003 case 0x17:
2004 /* issue a Diagnostic Control command with an 2004 /* issue a Diagnostic Control command with an
2005 * Inhibit Write subcommand and controler modifier */ 2005 * Inhibit Write subcommand and controler modifier */
2006 erp = dasd_3990_erp_DCTL(erp, 0x20); 2006 erp = dasd_3990_erp_DCTL(erp, 0x20);
2007 break; 2007 break;
2008 2008
2009 case 0x25: 2009 case 0x25:
2010 /* wait for 5 seconds and retry again */ 2010 /* wait for 5 seconds and retry again */
2011 erp->retries = 1; 2011 erp->retries = 1;
2012 2012
2013 dasd_3990_erp_block_queue (erp, 5*HZ); 2013 dasd_3990_erp_block_queue (erp, 5*HZ);
2014 break; 2014 break;
2015 2015
2016 default: 2016 default:
2017 /* should not happen - continue */ 2017 /* should not happen - continue */
2018 break; 2018 break;
@@ -2026,7 +2026,7 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense)
2026} /* end dasd_3990_erp_compound_code */ 2026} /* end dasd_3990_erp_compound_code */
2027 2027
2028/* 2028/*
2029 * DASD_3990_ERP_COMPOUND_CONFIG 2029 * DASD_3990_ERP_COMPOUND_CONFIG
2030 * 2030 *
2031 * DESCRIPTION 2031 * DESCRIPTION
2032 * Handles the compound ERP action for configruation 2032 * Handles the compound ERP action for configruation
@@ -2063,10 +2063,10 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense)
2063} /* end dasd_3990_erp_compound_config */ 2063} /* end dasd_3990_erp_compound_config */
2064 2064
2065/* 2065/*
2066 * DASD_3990_ERP_COMPOUND 2066 * DASD_3990_ERP_COMPOUND
2067 * 2067 *
2068 * DESCRIPTION 2068 * DESCRIPTION
2069 * Does the further compound program action if 2069 * Does the further compound program action if
2070 * compound retry was not successful. 2070 * compound retry was not successful.
2071 * 2071 *
2072 * PARAMETER 2072 * PARAMETER
@@ -2110,11 +2110,11 @@ dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense)
2110} /* end dasd_3990_erp_compound */ 2110} /* end dasd_3990_erp_compound */
2111 2111
2112/* 2112/*
2113 * DASD_3990_ERP_INSPECT_32 2113 * DASD_3990_ERP_INSPECT_32
2114 * 2114 *
2115 * DESCRIPTION 2115 * DESCRIPTION
2116 * Does a detailed inspection of the 32 byte sense data 2116 * Does a detailed inspection of the 32 byte sense data
2117 * and sets up a related error recovery action. 2117 * and sets up a related error recovery action.
2118 * 2118 *
2119 * PARAMETER 2119 * PARAMETER
2120 * sense sense data of the actual error 2120 * sense sense data of the actual error
@@ -2228,9 +2228,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2228} /* end dasd_3990_erp_inspect_32 */ 2228} /* end dasd_3990_erp_inspect_32 */
2229 2229
2230/* 2230/*
2231 ***************************************************************************** 2231 *****************************************************************************
2232 * main ERP control fuctions (24 and 32 byte sense) 2232 * main ERP control fuctions (24 and 32 byte sense)
2233 ***************************************************************************** 2233 *****************************************************************************
2234 */ 2234 */
2235 2235
2236/* 2236/*
@@ -2243,7 +2243,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2243 * PARAMETER 2243 * PARAMETER
2244 * erp pointer to the currently created default ERP 2244 * erp pointer to the currently created default ERP
2245 * RETURN VALUES 2245 * RETURN VALUES
2246 * erp_new contens was possibly modified 2246 * erp_new contens was possibly modified
2247 */ 2247 */
2248static struct dasd_ccw_req * 2248static struct dasd_ccw_req *
2249dasd_3990_erp_inspect(struct dasd_ccw_req * erp) 2249dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
@@ -2272,14 +2272,14 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
2272 2272
2273/* 2273/*
2274 * DASD_3990_ERP_ADD_ERP 2274 * DASD_3990_ERP_ADD_ERP
2275 * 2275 *
2276 * DESCRIPTION 2276 * DESCRIPTION
2277 * This funtion adds an additional request block (ERP) to the head of 2277 * This funtion adds an additional request block (ERP) to the head of
2278 * the given cqr (or erp). 2278 * the given cqr (or erp).
2279 * This erp is initialized as an default erp (retry TIC) 2279 * This erp is initialized as an default erp (retry TIC)
2280 * 2280 *
2281 * PARAMETER 2281 * PARAMETER
2282 * cqr head of the current ERP-chain (or single cqr if 2282 * cqr head of the current ERP-chain (or single cqr if
2283 * first error) 2283 * first error)
2284 * RETURN VALUES 2284 * RETURN VALUES
2285 * erp pointer to new ERP-chain head 2285 * erp pointer to new ERP-chain head
@@ -2332,15 +2332,15 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
2332} 2332}
2333 2333
2334/* 2334/*
2335 * DASD_3990_ERP_ADDITIONAL_ERP 2335 * DASD_3990_ERP_ADDITIONAL_ERP
2336 * 2336 *
2337 * DESCRIPTION 2337 * DESCRIPTION
2338 * An additional ERP is needed to handle the current error. 2338 * An additional ERP is needed to handle the current error.
2339 * Add ERP to the head of the ERP-chain containing the ERP processing 2339 * Add ERP to the head of the ERP-chain containing the ERP processing
2340 * determined based on the sense data. 2340 * determined based on the sense data.
2341 * 2341 *
2342 * PARAMETER 2342 * PARAMETER
2343 * cqr head of the current ERP-chain (or single cqr if 2343 * cqr head of the current ERP-chain (or single cqr if
2344 * first error) 2344 * first error)
2345 * 2345 *
2346 * RETURN VALUES 2346 * RETURN VALUES
@@ -2376,7 +2376,7 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
2376 * 24 byte sense byte 25 and 27 is set as well. 2376 * 24 byte sense byte 25 and 27 is set as well.
2377 * 2377 *
2378 * PARAMETER 2378 * PARAMETER
2379 * cqr1 first cqr, which will be compared with the 2379 * cqr1 first cqr, which will be compared with the
2380 * cqr2 second cqr. 2380 * cqr2 second cqr.
2381 * 2381 *
2382 * RETURN VALUES 2382 * RETURN VALUES
@@ -2415,7 +2415,7 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
2415 * cqr failed cqr (either original cqr or already an erp) 2415 * cqr failed cqr (either original cqr or already an erp)
2416 * 2416 *
2417 * RETURN VALUES 2417 * RETURN VALUES
2418 * erp erp-pointer to the already defined error 2418 * erp erp-pointer to the already defined error
2419 * recovery procedure OR 2419 * recovery procedure OR
2420 * NULL if a 'new' error occurred. 2420 * NULL if a 'new' error occurred.
2421 */ 2421 */
@@ -2451,10 +2451,10 @@ dasd_3990_erp_in_erp(struct dasd_ccw_req *cqr)
2451 * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) 2451 * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense)
2452 * 2452 *
2453 * DESCRIPTION 2453 * DESCRIPTION
2454 * No retry is left for the current ERP. Check what has to be done 2454 * No retry is left for the current ERP. Check what has to be done
2455 * with the ERP. 2455 * with the ERP.
2456 * - do further defined ERP action or 2456 * - do further defined ERP action or
2457 * - wait for interrupt or 2457 * - wait for interrupt or
2458 * - exit with permanent error 2458 * - exit with permanent error
2459 * 2459 *
2460 * PARAMETER 2460 * PARAMETER
@@ -2485,7 +2485,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2485 2485
2486 if (!(sense[2] & DASD_SENSE_BIT_0)) { 2486 if (!(sense[2] & DASD_SENSE_BIT_0)) {
2487 2487
2488 /* issue a Diagnostic Control command with an 2488 /* issue a Diagnostic Control command with an
2489 * Inhibit Write subcommand */ 2489 * Inhibit Write subcommand */
2490 2490
2491 switch (sense[25]) { 2491 switch (sense[25]) {
@@ -2535,14 +2535,14 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2535} /* end dasd_3990_erp_further_erp */ 2535} /* end dasd_3990_erp_further_erp */
2536 2536
2537/* 2537/*
2538 * DASD_3990_ERP_HANDLE_MATCH_ERP 2538 * DASD_3990_ERP_HANDLE_MATCH_ERP
2539 * 2539 *
2540 * DESCRIPTION 2540 * DESCRIPTION
2541 * An error occurred again and an ERP has been detected which is already 2541 * An error occurred again and an ERP has been detected which is already
2542 * used to handle this error (e.g. retries). 2542 * used to handle this error (e.g. retries).
2543 * All prior ERP's are asumed to be successful and therefore removed 2543 * All prior ERP's are asumed to be successful and therefore removed
2544 * from queue. 2544 * from queue.
2545 * If retry counter of matching erp is already 0, it is checked if further 2545 * If retry counter of matching erp is already 0, it is checked if further
2546 * action is needed (besides retry) or if the ERP has failed. 2546 * action is needed (besides retry) or if the ERP has failed.
2547 * 2547 *
2548 * PARAMETER 2548 * PARAMETER
@@ -2631,7 +2631,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,
2631 * erp erp-pointer to the head of the ERP action chain. 2631 * erp erp-pointer to the head of the ERP action chain.
2632 * This means: 2632 * This means:
2633 * - either a ptr to an additional ERP cqr or 2633 * - either a ptr to an additional ERP cqr or
2634 * - the original given cqr (which's status might 2634 * - the original given cqr (which's status might
2635 * be modified) 2635 * be modified)
2636 */ 2636 */
2637struct dasd_ccw_req * 2637struct dasd_ccw_req *
@@ -2723,22 +2723,3 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
2723 return erp; 2723 return erp;
2724 2724
2725} /* end dasd_3990_erp_action */ 2725} /* end dasd_3990_erp_action */
2726
2727/*
2728 * Overrides for Emacs so that we follow Linus's tabbing style.
2729 * Emacs will notice this stuff at the end of the file and automatically
2730 * adjust the settings for this buffer only. This must remain at the end
2731 * of the file.
2732 * ---------------------------------------------------------------------------
2733 * Local variables:
2734 * c-indent-level: 4
2735 * c-brace-imaginary-offset: 0
2736 * c-brace-offset: -4
2737 * c-argdecl-indent: 4
2738 * c-label-offset: -4
2739 * c-continued-statement-offset: 4
2740 * c-continued-brace-offset: 0
2741 * indent-tabs-mode: 1
2742 * tab-width: 8
2743 * End:
2744 */
diff --git a/drivers/s390/block/dasd_9336_erp.c b/drivers/s390/block/dasd_9336_erp.c
index dc861446d056..6e082688475a 100644
--- a/drivers/s390/block/dasd_9336_erp.c
+++ b/drivers/s390/block/dasd_9336_erp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_9336_erp.c 2 * File...........: linux/drivers/s390/block/dasd_9336_erp.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -12,10 +12,10 @@
12 12
13 13
14/* 14/*
15 * DASD_9336_ERP_EXAMINE 15 * DASD_9336_ERP_EXAMINE
16 * 16 *
17 * DESCRIPTION 17 * DESCRIPTION
18 * Checks only for fatal/no/recover error. 18 * Checks only for fatal/no/recover error.
19 * A detailed examination of the sense data is done later outside 19 * A detailed examination of the sense data is done later outside
20 * the interrupt handler. 20 * the interrupt handler.
21 * 21 *
@@ -23,7 +23,7 @@
23 * 'Chapter 7. 9336 Sense Data'. 23 * 'Chapter 7. 9336 Sense Data'.
24 * 24 *
25 * RETURN VALUES 25 * RETURN VALUES
26 * dasd_era_none no error 26 * dasd_era_none no error
27 * dasd_era_fatal for all fatal (unrecoverable errors) 27 * dasd_era_fatal for all fatal (unrecoverable errors)
28 * dasd_era_recover for all others. 28 * dasd_era_recover for all others.
29 */ 29 */
@@ -39,22 +39,3 @@ dasd_9336_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
39 return dasd_era_recover; 39 return dasd_era_recover;
40 40
41} /* END dasd_9336_erp_examine */ 41} /* END dasd_9336_erp_examine */
42
43/*
44 * Overrides for Emacs so that we follow Linus's tabbing style.
45 * Emacs will notice this stuff at the end of the file and automatically
46 * adjust the settings for this buffer only. This must remain at the end
47 * of the file.
48 * ---------------------------------------------------------------------------
49 * Local variables:
50 * c-indent-level: 4
51 * c-brace-imaginary-offset: 0
52 * c-brace-offset: -4
53 * c-argdecl-indent: 4
54 * c-label-offset: -4
55 * c-continued-statement-offset: 4
56 * c-continued-brace-offset: 0
57 * indent-tabs-mode: 1
58 * tab-width: 8
59 * End:
60 */
diff --git a/drivers/s390/block/dasd_9343_erp.c b/drivers/s390/block/dasd_9343_erp.c
index 4a5b79569aaa..ddecb9808ed4 100644
--- a/drivers/s390/block/dasd_9343_erp.c
+++ b/drivers/s390/block/dasd_9343_erp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_9345_erp.c 2 * File...........: linux/drivers/s390/block/dasd_9345_erp.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 216bc4fba199..9e9ae7179602 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -27,7 +27,7 @@
27#include "dasd_int.h" 27#include "dasd_int.h"
28 28
29kmem_cache_t *dasd_page_cache; 29kmem_cache_t *dasd_page_cache;
30EXPORT_SYMBOL(dasd_page_cache); 30EXPORT_SYMBOL_GPL(dasd_page_cache);
31 31
32/* 32/*
33 * dasd_devmap_t is used to store the features and the relation 33 * dasd_devmap_t is used to store the features and the relation
@@ -49,6 +49,20 @@ struct dasd_devmap {
49}; 49};
50 50
51/* 51/*
52 * dasd_servermap is used to store the server_id of all storage servers
53 * accessed by DASD device driver.
54 */
55struct dasd_servermap {
56 struct list_head list;
57 struct server_id {
58 char vendor[4];
59 char serial[15];
60 } sid;
61};
62
63static struct list_head dasd_serverlist;
64
65/*
52 * Parameter parsing functions for dasd= parameter. The syntax is: 66 * Parameter parsing functions for dasd= parameter. The syntax is:
53 * <devno> : (0x)?[0-9a-fA-F]+ 67 * <devno> : (0x)?[0-9a-fA-F]+
54 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ 68 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
@@ -64,6 +78,8 @@ struct dasd_devmap {
64 78
65int dasd_probeonly = 0; /* is true, when probeonly mode is active */ 79int dasd_probeonly = 0; /* is true, when probeonly mode is active */
66int dasd_autodetect = 0; /* is true, when autodetection is active */ 80int dasd_autodetect = 0; /* is true, when autodetection is active */
81int dasd_nopav = 0; /* is true, when PAV is disabled */
82EXPORT_SYMBOL_GPL(dasd_nopav);
67 83
68/* 84/*
69 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement 85 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -123,7 +139,7 @@ static inline int
123dasd_busid(char **str, int *id0, int *id1, int *devno) 139dasd_busid(char **str, int *id0, int *id1, int *devno)
124{ 140{
125 int val, old_style; 141 int val, old_style;
126 142
127 /* check for leading '0x' */ 143 /* check for leading '0x' */
128 old_style = 0; 144 old_style = 0;
129 if ((*str)[0] == '0' && (*str)[1] == 'x') { 145 if ((*str)[0] == '0' && (*str)[1] == 'x') {
@@ -179,7 +195,7 @@ dasd_feature_list(char *str, char **endp)
179 features = 0; 195 features = 0;
180 196
181 while (1) { 197 while (1) {
182 for (len = 0; 198 for (len = 0;
183 str[len] && str[len] != ':' && str[len] != ')'; len++); 199 str[len] && str[len] != ':' && str[len] != ')'; len++);
184 if (len == 2 && !strncmp(str, "ro", 2)) 200 if (len == 2 && !strncmp(str, "ro", 2))
185 features |= DASD_FEATURE_READONLY; 201 features |= DASD_FEATURE_READONLY;
@@ -228,19 +244,24 @@ dasd_parse_keyword( char *parsestring ) {
228 length = strlen(parsestring); 244 length = strlen(parsestring);
229 residual_str = parsestring + length; 245 residual_str = parsestring + length;
230 } 246 }
231 if (strncmp ("autodetect", parsestring, length) == 0) { 247 if (strncmp("autodetect", parsestring, length) == 0) {
232 dasd_autodetect = 1; 248 dasd_autodetect = 1;
233 MESSAGE (KERN_INFO, "%s", 249 MESSAGE (KERN_INFO, "%s",
234 "turning to autodetection mode"); 250 "turning to autodetection mode");
235 return residual_str; 251 return residual_str;
236 } 252 }
237 if (strncmp ("probeonly", parsestring, length) == 0) { 253 if (strncmp("probeonly", parsestring, length) == 0) {
238 dasd_probeonly = 1; 254 dasd_probeonly = 1;
239 MESSAGE(KERN_INFO, "%s", 255 MESSAGE(KERN_INFO, "%s",
240 "turning to probeonly mode"); 256 "turning to probeonly mode");
241 return residual_str; 257 return residual_str;
242 } 258 }
243 if (strncmp ("fixedbuffers", parsestring, length) == 0) { 259 if (strncmp("nopav", parsestring, length) == 0) {
260 dasd_nopav = 1;
261 MESSAGE(KERN_INFO, "%s", "disable PAV mode");
262 return residual_str;
263 }
264 if (strncmp("fixedbuffers", parsestring, length) == 0) {
244 if (dasd_page_cache) 265 if (dasd_page_cache)
245 return residual_str; 266 return residual_str;
246 dasd_page_cache = 267 dasd_page_cache =
@@ -294,6 +315,8 @@ dasd_parse_range( char *parsestring ) {
294 features = dasd_feature_list(str, &str); 315 features = dasd_feature_list(str, &str);
295 if (features < 0) 316 if (features < 0)
296 return ERR_PTR(-EINVAL); 317 return ERR_PTR(-EINVAL);
318 /* each device in dasd= parameter should be set initially online */
319 features |= DASD_FEATURE_INITIAL_ONLINE;
297 while (from <= to) { 320 while (from <= to) {
298 sprintf(bus_id, "%01x.%01x.%04x", 321 sprintf(bus_id, "%01x.%01x.%04x",
299 from_id0, from_id1, from++); 322 from_id0, from_id1, from++);
@@ -359,7 +382,7 @@ dasd_parse(void)
359 * Add a devmap for the device specified by busid. It is possible that 382 * Add a devmap for the device specified by busid. It is possible that
360 * the devmap already exists (dasd= parameter). The order of the devices 383 * the devmap already exists (dasd= parameter). The order of the devices
361 * added through this function will define the kdevs for the individual 384 * added through this function will define the kdevs for the individual
362 * devices. 385 * devices.
363 */ 386 */
364static struct dasd_devmap * 387static struct dasd_devmap *
365dasd_add_busid(char *bus_id, int features) 388dasd_add_busid(char *bus_id, int features)
@@ -368,7 +391,7 @@ dasd_add_busid(char *bus_id, int features)
368 int hash; 391 int hash;
369 392
370 new = (struct dasd_devmap *) 393 new = (struct dasd_devmap *)
371 kmalloc(sizeof(struct dasd_devmap), GFP_KERNEL); 394 kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
372 if (!new) 395 if (!new)
373 return ERR_PTR(-ENOMEM); 396 return ERR_PTR(-ENOMEM);
374 spin_lock(&dasd_devmap_lock); 397 spin_lock(&dasd_devmap_lock);
@@ -630,7 +653,8 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
630} 653}
631 654
632static ssize_t 655static ssize_t
633dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 656dasd_ro_store(struct device *dev, struct device_attribute *attr,
657 const char *buf, size_t count)
634{ 658{
635 struct dasd_devmap *devmap; 659 struct dasd_devmap *devmap;
636 int ro_flag; 660 int ro_flag;
@@ -658,7 +682,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
658 * use_diag controls whether the driver should use diag rather than ssch 682 * use_diag controls whether the driver should use diag rather than ssch
659 * to talk to the device 683 * to talk to the device
660 */ 684 */
661static ssize_t 685static ssize_t
662dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) 686dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
663{ 687{
664 struct dasd_devmap *devmap; 688 struct dasd_devmap *devmap;
@@ -673,7 +697,8 @@ dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
673} 697}
674 698
675static ssize_t 699static ssize_t
676dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 700dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
701 const char *buf, size_t count)
677{ 702{
678 struct dasd_devmap *devmap; 703 struct dasd_devmap *devmap;
679 ssize_t rc; 704 ssize_t rc;
@@ -697,11 +722,11 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const cha
697 return rc; 722 return rc;
698} 723}
699 724
700static 725static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
701DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
702 726
703static ssize_t 727static ssize_t
704dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf) 728dasd_discipline_show(struct device *dev, struct device_attribute *attr,
729 char *buf)
705{ 730{
706 struct dasd_devmap *devmap; 731 struct dasd_devmap *devmap;
707 char *dname; 732 char *dname;
@@ -834,6 +859,38 @@ static struct attribute_group dasd_attr_group = {
834 .attrs = dasd_attrs, 859 .attrs = dasd_attrs,
835}; 860};
836 861
862/*
863 * Check if the related storage server is already contained in the
864 * dasd_serverlist. If server is not contained, create new entry.
865 * Return 0 if server was already in serverlist,
866 * 1 if the server was added successfully
867 * <0 in case of error.
868 */
869static int
870dasd_add_server(struct dasd_uid *uid)
871{
872 struct dasd_servermap *new, *tmp;
873
874 /* check if server is already contained */
875 list_for_each_entry(tmp, &dasd_serverlist, list)
876 // normale cmp?
877 if (strncmp(tmp->sid.vendor, uid->vendor,
878 sizeof(tmp->sid.vendor)) == 0
879 && strncmp(tmp->sid.serial, uid->serial,
880 sizeof(tmp->sid.serial)) == 0)
881 return 0;
882
883 new = (struct dasd_servermap *)
884 kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL);
885 if (!new)
886 return -ENOMEM;
887
888 strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor));
889 strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial));
890 list_add(&new->list, &dasd_serverlist);
891 return 1;
892}
893
837 894
838/* 895/*
839 * Return copy of the device unique identifier. 896 * Return copy of the device unique identifier.
@@ -854,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
854 911
855/* 912/*
856 * Register the given device unique identifier into devmap struct. 913 * Register the given device unique identifier into devmap struct.
914 * Return 0 if server was already in serverlist,
915 * 1 if the server was added successful
916 * <0 in case of error.
857 */ 917 */
858int 918int
859dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) 919dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
860{ 920{
861 struct dasd_devmap *devmap; 921 struct dasd_devmap *devmap;
922 int rc;
862 923
863 devmap = dasd_find_busid(cdev->dev.bus_id); 924 devmap = dasd_find_busid(cdev->dev.bus_id);
864 if (IS_ERR(devmap)) 925 if (IS_ERR(devmap))
865 return PTR_ERR(devmap); 926 return PTR_ERR(devmap);
866 spin_lock(&dasd_devmap_lock); 927 spin_lock(&dasd_devmap_lock);
867 devmap->uid = *uid; 928 devmap->uid = *uid;
929 rc = dasd_add_server(uid);
868 spin_unlock(&dasd_devmap_lock); 930 spin_unlock(&dasd_devmap_lock);
869 return 0; 931 return rc;
870} 932}
871EXPORT_SYMBOL(dasd_set_uid); 933EXPORT_SYMBOL_GPL(dasd_set_uid);
872 934
873/* 935/*
874 * Return value of the specified feature. 936 * Return value of the specified feature.
@@ -880,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature)
880 942
881 devmap = dasd_find_busid(cdev->dev.bus_id); 943 devmap = dasd_find_busid(cdev->dev.bus_id);
882 if (IS_ERR(devmap)) 944 if (IS_ERR(devmap))
883 return (int) PTR_ERR(devmap); 945 return PTR_ERR(devmap);
884 946
885 return ((devmap->features & feature) != 0); 947 return ((devmap->features & feature) != 0);
886} 948}
@@ -896,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
896 958
897 devmap = dasd_find_busid(cdev->dev.bus_id); 959 devmap = dasd_find_busid(cdev->dev.bus_id);
898 if (IS_ERR(devmap)) 960 if (IS_ERR(devmap))
899 return (int) PTR_ERR(devmap); 961 return PTR_ERR(devmap);
900 962
901 spin_lock(&dasd_devmap_lock); 963 spin_lock(&dasd_devmap_lock);
902 if (flag) 964 if (flag)
@@ -932,8 +994,10 @@ dasd_devmap_init(void)
932 dasd_max_devindex = 0; 994 dasd_max_devindex = 0;
933 for (i = 0; i < 256; i++) 995 for (i = 0; i < 256; i++)
934 INIT_LIST_HEAD(&dasd_hashlists[i]); 996 INIT_LIST_HEAD(&dasd_hashlists[i]);
935 return 0;
936 997
998 /* Initialize servermap structure. */
999 INIT_LIST_HEAD(&dasd_serverlist);
1000 return 0;
937} 1001}
938 1002
939void 1003void
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 3f9d704d2657..4002f6c1c1b3 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_diag.c 2 * File...........: linux/drivers/s390/block/dasd_diag.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Based on.......: linux/drivers/s390/block/mdisk.c 4 * Based on.......: linux/drivers/s390/block/mdisk.c
@@ -336,7 +336,7 @@ dasd_diag_check_device(struct dasd_device *device)
336 336
337 private = (struct dasd_diag_private *) device->private; 337 private = (struct dasd_diag_private *) device->private;
338 if (private == NULL) { 338 if (private == NULL) {
339 private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); 339 private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
340 if (private == NULL) { 340 if (private == NULL) {
341 DEV_MESSAGE(KERN_WARNING, device, "%s", 341 DEV_MESSAGE(KERN_WARNING, device, "%s",
342 "memory allocation failed for private data"); 342 "memory allocation failed for private data");
@@ -527,7 +527,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
527 datasize, device); 527 datasize, device);
528 if (IS_ERR(cqr)) 528 if (IS_ERR(cqr))
529 return cqr; 529 return cqr;
530 530
531 dreq = (struct dasd_diag_req *) cqr->data; 531 dreq = (struct dasd_diag_req *) cqr->data;
532 dreq->block_count = count; 532 dreq->block_count = count;
533 dbio = dreq->bio; 533 dbio = dreq->bio;
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index 38a4e55f8953..b8c78267ff3e 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_diag.h 2 * File...........: linux/drivers/s390/block/dasd_diag.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Based on.......: linux/drivers/s390/block/mdisk.h 4 * Based on.......: linux/drivers/s390/block/mdisk.h
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 7d5a6cee4bd8..0dfab30e8089 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_eckd.c 2 * File...........: linux/drivers/s390/block/dasd_eckd.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Carsten Otte <Cotte@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -24,6 +24,7 @@
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/todclk.h> 25#include <asm/todclk.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/cio.h>
27#include <asm/ccwdev.h> 28#include <asm/ccwdev.h>
28 29
29#include "dasd_int.h" 30#include "dasd_int.h"
@@ -89,17 +90,22 @@ dasd_eckd_probe (struct ccw_device *cdev)
89{ 90{
90 int ret; 91 int ret;
91 92
92 ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); 93 /* set ECKD specific ccw-device options */
93 if (ret) 94 ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
95 if (ret) {
96 printk(KERN_WARNING
97 "dasd_eckd_probe: could not set ccw-device options "
98 "for %s\n", cdev->dev.bus_id);
94 return ret; 99 return ret;
95 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); 100 }
96 return 0; 101 ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
102 return ret;
97} 103}
98 104
99static int 105static int
100dasd_eckd_set_online(struct ccw_device *cdev) 106dasd_eckd_set_online(struct ccw_device *cdev)
101{ 107{
102 return dasd_generic_set_online (cdev, &dasd_eckd_discipline); 108 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
103} 109}
104 110
105static struct ccw_driver dasd_eckd_driver = { 111static struct ccw_driver dasd_eckd_driver = {
@@ -210,14 +216,14 @@ check_XRC (struct ccw1 *de_ccw,
210 216
211 /* switch on System Time Stamp - needed for XRC Support */ 217 /* switch on System Time Stamp - needed for XRC Support */
212 if (private->rdc_data.facilities.XRC_supported) { 218 if (private->rdc_data.facilities.XRC_supported) {
213 219
214 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ 220 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
215 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ 221 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
216 222
217 data->ep_sys_time = get_clock (); 223 data->ep_sys_time = get_clock ();
218 224
219 de_ccw->count = sizeof (struct DE_eckd_data); 225 de_ccw->count = sizeof (struct DE_eckd_data);
220 de_ccw->flags |= CCW_FLAG_SLI; 226 de_ccw->flags |= CCW_FLAG_SLI;
221 } 227 }
222 228
223 return; 229 return;
@@ -296,8 +302,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
296 /* check for sequential prestage - enhance cylinder range */ 302 /* check for sequential prestage - enhance cylinder range */
297 if (data->attributes.operation == DASD_SEQ_PRESTAGE || 303 if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
298 data->attributes.operation == DASD_SEQ_ACCESS) { 304 data->attributes.operation == DASD_SEQ_ACCESS) {
299 305
300 if (end.cyl + private->attrib.nr_cyl < geo.cyl) 306 if (end.cyl + private->attrib.nr_cyl < geo.cyl)
301 end.cyl += private->attrib.nr_cyl; 307 end.cyl += private->attrib.nr_cyl;
302 else 308 else
303 end.cyl = (geo.cyl - 1); 309 end.cyl = (geo.cyl - 1);
@@ -317,7 +323,7 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
317 struct dasd_eckd_private *private; 323 struct dasd_eckd_private *private;
318 int sector; 324 int sector;
319 int dn, d; 325 int dn, d;
320 326
321 private = (struct dasd_eckd_private *) device->private; 327 private = (struct dasd_eckd_private *) device->private;
322 328
323 DBF_DEV_EVENT(DBF_INFO, device, 329 DBF_DEV_EVENT(DBF_INFO, device,
@@ -541,6 +547,86 @@ dasd_eckd_read_conf(struct dasd_device *device)
541} 547}
542 548
543/* 549/*
550 * Build CP for Perform Subsystem Function - SSC.
551 */
552struct dasd_ccw_req *
553dasd_eckd_build_psf_ssc(struct dasd_device *device)
554{
555 struct dasd_ccw_req *cqr;
556 struct dasd_psf_ssc_data *psf_ssc_data;
557 struct ccw1 *ccw;
558
559 cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ ,
560 sizeof(struct dasd_psf_ssc_data),
561 device);
562
563 if (IS_ERR(cqr)) {
564 DEV_MESSAGE(KERN_WARNING, device, "%s",
565 "Could not allocate PSF-SSC request");
566 return cqr;
567 }
568 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
569 psf_ssc_data->order = PSF_ORDER_SSC;
570 psf_ssc_data->suborder = 0x08;
571
572 ccw = cqr->cpaddr;
573 ccw->cmd_code = DASD_ECKD_CCW_PSF;
574 ccw->cda = (__u32)(addr_t)psf_ssc_data;
575 ccw->count = 66;
576
577 cqr->device = device;
578 cqr->expires = 10*HZ;
579 cqr->buildclk = get_clock();
580 cqr->status = DASD_CQR_FILLED;
581 return cqr;
582}
583
584/*
585 * Perform Subsystem Function.
586 * It is necessary to trigger CIO for channel revalidation since this
587 * call might change behaviour of DASD devices.
588 */
589static int
590dasd_eckd_psf_ssc(struct dasd_device *device)
591{
592 struct dasd_ccw_req *cqr;
593 int rc;
594
595 cqr = dasd_eckd_build_psf_ssc(device);
596 if (IS_ERR(cqr))
597 return PTR_ERR(cqr);
598
599 rc = dasd_sleep_on(cqr);
600 if (!rc)
601 /* trigger CIO to reprobe devices */
602 css_schedule_reprobe();
603 dasd_sfree_request(cqr, cqr->device);
604 return rc;
605}
606
607/*
608 * Valide storage server of current device.
609 */
610static int
611dasd_eckd_validate_server(struct dasd_device *device)
612{
613 int rc;
614
615 /* Currently PAV is the only reason to 'validate' server on LPAR */
616 if (dasd_nopav || MACHINE_IS_VM)
617 return 0;
618
619 rc = dasd_eckd_psf_ssc(device);
620 if (rc)
621 /* may be requested feature is not available on server,
622 * therefore just report error and go ahead */
623 DEV_MESSAGE(KERN_INFO, device,
624 "Perform Subsystem Function returned rc=%d", rc);
625 /* RE-Read Configuration Data */
626 return dasd_eckd_read_conf(device);
627}
628
629/*
544 * Check device characteristics. 630 * Check device characteristics.
545 * If the device is accessible using ECKD discipline, the device is enabled. 631 * If the device is accessible using ECKD discipline, the device is enabled.
546 */ 632 */
@@ -554,7 +640,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
554 640
555 private = (struct dasd_eckd_private *) device->private; 641 private = (struct dasd_eckd_private *) device->private;
556 if (private == NULL) { 642 if (private == NULL) {
557 private = kmalloc(sizeof(struct dasd_eckd_private), 643 private = kzalloc(sizeof(struct dasd_eckd_private),
558 GFP_KERNEL | GFP_DMA); 644 GFP_KERNEL | GFP_DMA);
559 if (private == NULL) { 645 if (private == NULL) {
560 DEV_MESSAGE(KERN_WARNING, device, "%s", 646 DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -562,7 +648,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
562 "data"); 648 "data");
563 return -ENOMEM; 649 return -ENOMEM;
564 } 650 }
565 memset(private, 0, sizeof(struct dasd_eckd_private));
566 device->private = (void *) private; 651 device->private = (void *) private;
567 } 652 }
568 /* Invalidate status of initial analysis. */ 653 /* Invalidate status of initial analysis. */
@@ -571,16 +656,29 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
571 private->attrib.operation = DASD_NORMAL_CACHE; 656 private->attrib.operation = DASD_NORMAL_CACHE;
572 private->attrib.nr_cyl = 0; 657 private->attrib.nr_cyl = 0;
573 658
659 /* Read Configuration Data */
660 rc = dasd_eckd_read_conf(device);
661 if (rc)
662 return rc;
663
664 /* Generate device unique id and register in devmap */
665 rc = dasd_eckd_generate_uid(device, &uid);
666 if (rc)
667 return rc;
668 rc = dasd_set_uid(device->cdev, &uid);
669 if (rc == 1) /* new server found */
670 rc = dasd_eckd_validate_server(device);
671 if (rc)
672 return rc;
673
574 /* Read Device Characteristics */ 674 /* Read Device Characteristics */
575 rdc_data = (void *) &(private->rdc_data); 675 rdc_data = (void *) &(private->rdc_data);
576 memset(rdc_data, 0, sizeof(rdc_data)); 676 memset(rdc_data, 0, sizeof(rdc_data));
577 rc = read_dev_chars(device->cdev, &rdc_data, 64); 677 rc = read_dev_chars(device->cdev, &rdc_data, 64);
578 if (rc) { 678 if (rc)
579 DEV_MESSAGE(KERN_WARNING, device, 679 DEV_MESSAGE(KERN_WARNING, device,
580 "Read device characteristics returned error %d", 680 "Read device characteristics returned "
581 rc); 681 "rc=%d", rc);
582 return rc;
583 }
584 682
585 DEV_MESSAGE(KERN_INFO, device, 683 DEV_MESSAGE(KERN_INFO, device,
586 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", 684 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
@@ -591,19 +689,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
591 private->rdc_data.no_cyl, 689 private->rdc_data.no_cyl,
592 private->rdc_data.trk_per_cyl, 690 private->rdc_data.trk_per_cyl,
593 private->rdc_data.sec_per_trk); 691 private->rdc_data.sec_per_trk);
594
595 /* Read Configuration Data */
596 rc = dasd_eckd_read_conf (device);
597 if (rc)
598 return rc;
599
600 /* Generate device unique id and register in devmap */
601 rc = dasd_eckd_generate_uid(device, &uid);
602 if (rc)
603 return rc;
604
605 rc = dasd_set_uid(device->cdev, &uid);
606
607 return rc; 692 return rc;
608} 693}
609 694
@@ -773,7 +858,7 @@ dasd_eckd_end_analysis(struct dasd_device *device)
773 ((private->rdc_data.no_cyl * 858 ((private->rdc_data.no_cyl *
774 private->rdc_data.trk_per_cyl * 859 private->rdc_data.trk_per_cyl *
775 blk_per_trk * (device->bp_block >> 9)) >> 1), 860 blk_per_trk * (device->bp_block >> 9)) >> 1),
776 ((blk_per_trk * device->bp_block) >> 10), 861 ((blk_per_trk * device->bp_block) >> 10),
777 private->uses_cdl ? 862 private->uses_cdl ?
778 "compatible disk layout" : "linux disk layout"); 863 "compatible disk layout" : "linux disk layout");
779 864
@@ -970,7 +1055,7 @@ dasd_eckd_format_device(struct dasd_device * device,
970 if (i < 3) { 1055 if (i < 3) {
971 ect->kl = 4; 1056 ect->kl = 4;
972 ect->dl = sizes_trk0[i] - 4; 1057 ect->dl = sizes_trk0[i] - 4;
973 } 1058 }
974 } 1059 }
975 if ((fdata->intensity & 0x08) && 1060 if ((fdata->intensity & 0x08) &&
976 fdata->start_unit == 1) { 1061 fdata->start_unit == 1) {
@@ -1270,7 +1355,7 @@ dasd_eckd_fill_info(struct dasd_device * device,
1270 1355
1271/* 1356/*
1272 * Release device ioctl. 1357 * Release device ioctl.
1273 * Buils a channel programm to releases a prior reserved 1358 * Buils a channel programm to releases a prior reserved
1274 * (see dasd_eckd_reserve) device. 1359 * (see dasd_eckd_reserve) device.
1275 */ 1360 */
1276static int 1361static int
@@ -1310,8 +1395,8 @@ dasd_eckd_release(struct dasd_device *device)
1310/* 1395/*
1311 * Reserve device ioctl. 1396 * Reserve device ioctl.
1312 * Options are set to 'synchronous wait for interrupt' and 1397 * Options are set to 'synchronous wait for interrupt' and
1313 * 'timeout the request'. This leads to a terminate IO if 1398 * 'timeout the request'. This leads to a terminate IO if
1314 * the interrupt is outstanding for a certain time. 1399 * the interrupt is outstanding for a certain time.
1315 */ 1400 */
1316static int 1401static int
1317dasd_eckd_reserve(struct dasd_device *device) 1402dasd_eckd_reserve(struct dasd_device *device)
@@ -1349,7 +1434,7 @@ dasd_eckd_reserve(struct dasd_device *device)
1349 1434
1350/* 1435/*
1351 * Steal lock ioctl - unconditional reserve device. 1436 * Steal lock ioctl - unconditional reserve device.
1352 * Buils a channel programm to break a device's reservation. 1437 * Buils a channel programm to break a device's reservation.
1353 * (unconditional reserve) 1438 * (unconditional reserve)
1354 */ 1439 */
1355static int 1440static int
@@ -1522,6 +1607,40 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
1522} 1607}
1523 1608
1524/* 1609/*
1610 * Dump the range of CCWs into 'page' buffer
1611 * and return number of printed chars.
1612 */
1613static inline int
1614dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
1615{
1616 int len, count;
1617 char *datap;
1618
1619 len = 0;
1620 while (from <= to) {
1621 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1622 " CCW %p: %08X %08X DAT:",
1623 from, ((int *) from)[0], ((int *) from)[1]);
1624
1625 /* get pointer to data (consider IDALs) */
1626 if (from->flags & CCW_FLAG_IDA)
1627 datap = (char *) *((addr_t *) (addr_t) from->cda);
1628 else
1629 datap = (char *) ((addr_t) from->cda);
1630
1631 /* dump data (max 32 bytes) */
1632 for (count = 0; count < from->count && count < 32; count++) {
1633 if (count % 8 == 0) len += sprintf(page + len, " ");
1634 if (count % 4 == 0) len += sprintf(page + len, " ");
1635 len += sprintf(page + len, "%02x", datap[count]);
1636 }
1637 len += sprintf(page + len, "\n");
1638 from++;
1639 }
1640 return len;
1641}
1642
1643/*
1525 * Print sense data and related channel program. 1644 * Print sense data and related channel program.
1526 * Parts are printed because printk buffer is only 1024 bytes. 1645 * Parts are printed because printk buffer is only 1024 bytes.
1527 */ 1646 */
@@ -1530,8 +1649,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1530 struct irb *irb) 1649 struct irb *irb)
1531{ 1650{
1532 char *page; 1651 char *page;
1533 struct ccw1 *act, *end, *last; 1652 struct ccw1 *first, *last, *fail, *from, *to;
1534 int len, sl, sct, count; 1653 int len, sl, sct;
1535 1654
1536 page = (char *) get_zeroed_page(GFP_ATOMIC); 1655 page = (char *) get_zeroed_page(GFP_ATOMIC);
1537 if (page == NULL) { 1656 if (page == NULL) {
@@ -1539,7 +1658,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1539 "No memory to dump sense data"); 1658 "No memory to dump sense data");
1540 return; 1659 return;
1541 } 1660 }
1542 len = sprintf(page, KERN_ERR PRINTK_HEADER 1661 /* dump the sense data */
1662 len = sprintf(page, KERN_ERR PRINTK_HEADER
1543 " I/O status report for device %s:\n", 1663 " I/O status report for device %s:\n",
1544 device->cdev->dev.bus_id); 1664 device->cdev->dev.bus_id);
1545 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1665 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
@@ -1564,87 +1684,55 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1564 1684
1565 if (irb->ecw[27] & DASD_SENSE_BIT_0) { 1685 if (irb->ecw[27] & DASD_SENSE_BIT_0) {
1566 /* 24 Byte Sense Data */ 1686 /* 24 Byte Sense Data */
1567 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1687 sprintf(page + len, KERN_ERR PRINTK_HEADER
1568 " 24 Byte: %x MSG %x, " 1688 " 24 Byte: %x MSG %x, "
1569 "%s MSGb to SYSOP\n", 1689 "%s MSGb to SYSOP\n",
1570 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, 1690 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
1571 irb->ecw[1] & 0x10 ? "" : "no"); 1691 irb->ecw[1] & 0x10 ? "" : "no");
1572 } else { 1692 } else {
1573 /* 32 Byte Sense Data */ 1693 /* 32 Byte Sense Data */
1574 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1694 sprintf(page + len, KERN_ERR PRINTK_HEADER
1575 " 32 Byte: Format: %x " 1695 " 32 Byte: Format: %x "
1576 "Exception class %x\n", 1696 "Exception class %x\n",
1577 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); 1697 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
1578 } 1698 }
1579 } else { 1699 } else {
1580 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1700 sprintf(page + len, KERN_ERR PRINTK_HEADER
1581 " SORRY - NO VALID SENSE AVAILABLE\n"); 1701 " SORRY - NO VALID SENSE AVAILABLE\n");
1582 } 1702 }
1583 MESSAGE_LOG(KERN_ERR, "%s", 1703 printk("%s", page);
1584 page + sizeof(KERN_ERR PRINTK_HEADER)); 1704
1585 1705 /* dump the Channel Program (max 140 Bytes per line) */
1586 /* dump the Channel Program */ 1706 /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */
1587 /* print first CCWs (maximum 8) */ 1707 first = req->cpaddr;
1588 act = req->cpaddr; 1708 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
1589 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 1709 to = min(first + 6, last);
1590 end = min(act + 8, last); 1710 len = sprintf(page, KERN_ERR PRINTK_HEADER
1591 len = sprintf(page, KERN_ERR PRINTK_HEADER
1592 " Related CP in req: %p\n", req); 1711 " Related CP in req: %p\n", req);
1593 while (act <= end) { 1712 dasd_eckd_dump_ccw_range(first, to, page + len);
1594 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1713 printk("%s", page);
1595 " CCW %p: %08X %08X DAT:",
1596 act, ((int *) act)[0], ((int *) act)[1]);
1597 for (count = 0; count < 32 && count < act->count;
1598 count += sizeof(int))
1599 len += sprintf(page + len, " %08X",
1600 ((int *) (addr_t) act->cda)
1601 [(count>>2)]);
1602 len += sprintf(page + len, "\n");
1603 act++;
1604 }
1605 MESSAGE_LOG(KERN_ERR, "%s",
1606 page + sizeof(KERN_ERR PRINTK_HEADER));
1607 1714
1608 /* print failing CCW area */ 1715 /* print failing CCW area (maximum 4) */
1716 /* scsw->cda is either valid or zero */
1609 len = 0; 1717 len = 0;
1610 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { 1718 from = ++to;
1611 act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; 1719 fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */
1612 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1720 if (from < fail - 2) {
1613 } 1721 from = fail - 2; /* there is a gap - print header */
1614 end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); 1722 len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n");
1615 while (act <= end) {
1616 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1617 " CCW %p: %08X %08X DAT:",
1618 act, ((int *) act)[0], ((int *) act)[1]);
1619 for (count = 0; count < 32 && count < act->count;
1620 count += sizeof(int))
1621 len += sprintf(page + len, " %08X",
1622 ((int *) (addr_t) act->cda)
1623 [(count>>2)]);
1624 len += sprintf(page + len, "\n");
1625 act++;
1626 } 1723 }
1724 to = min(fail + 1, last);
1725 len += dasd_eckd_dump_ccw_range(from, to, page + len);
1627 1726
1628 /* print last CCWs */ 1727 /* print last CCWs (maximum 2) */
1629 if (act < last - 2) { 1728 from = max(from, ++to);
1630 act = last - 2; 1729 if (from < last - 1) {
1730 from = last - 1; /* there is a gap - print header */
1631 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1731 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
1632 } 1732 }
1633 while (act <= last) { 1733 len += dasd_eckd_dump_ccw_range(from, last, page + len);
1634 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1635 " CCW %p: %08X %08X DAT:",
1636 act, ((int *) act)[0], ((int *) act)[1]);
1637 for (count = 0; count < 32 && count < act->count;
1638 count += sizeof(int))
1639 len += sprintf(page + len, " %08X",
1640 ((int *) (addr_t) act->cda)
1641 [(count>>2)]);
1642 len += sprintf(page + len, "\n");
1643 act++;
1644 }
1645 if (len > 0) 1734 if (len > 0)
1646 MESSAGE_LOG(KERN_ERR, "%s", 1735 printk("%s", page);
1647 page + sizeof(KERN_ERR PRINTK_HEADER));
1648 free_page((unsigned long) page); 1736 free_page((unsigned long) page);
1649} 1737}
1650 1738
@@ -1685,14 +1773,8 @@ static struct dasd_discipline dasd_eckd_discipline = {
1685static int __init 1773static int __init
1686dasd_eckd_init(void) 1774dasd_eckd_init(void)
1687{ 1775{
1688 int ret;
1689
1690 ASCEBC(dasd_eckd_discipline.ebcname, 4); 1776 ASCEBC(dasd_eckd_discipline.ebcname, 4);
1691 1777 return ccw_driver_register(&dasd_eckd_driver);
1692 ret = ccw_driver_register(&dasd_eckd_driver);
1693 if (!ret)
1694 dasd_generic_auto_online(&dasd_eckd_driver);
1695 return ret;
1696} 1778}
1697 1779
1698static void __exit 1780static void __exit
@@ -1703,22 +1785,3 @@ dasd_eckd_cleanup(void)
1703 1785
1704module_init(dasd_eckd_init); 1786module_init(dasd_eckd_init);
1705module_exit(dasd_eckd_cleanup); 1787module_exit(dasd_eckd_cleanup);
1706
1707/*
1708 * Overrides for Emacs so that we follow Linus's tabbing style.
1709 * Emacs will notice this stuff at the end of the file and automatically
1710 * adjust the settings for this buffer only. This must remain at the end
1711 * of the file.
1712 * ---------------------------------------------------------------------------
1713 * Local variables:
1714 * c-indent-level: 4
1715 * c-brace-imaginary-offset: 0
1716 * c-brace-offset: -4
1717 * c-argdecl-indent: 4
1718 * c-label-offset: -4
1719 * c-continued-statement-offset: 4
1720 * c-continued-brace-offset: 0
1721 * indent-tabs-mode: 1
1722 * tab-width: 8
1723 * End:
1724 */
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index d5734e976e1c..712ff1650134 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_eckd.h 2 * File...........: linux/drivers/s390/block/dasd_eckd.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Bugreports.to..: <Linux390@de.ibm.com> 5 * Bugreports.to..: <Linux390@de.ibm.com>
6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
7 * 7 *
@@ -41,9 +41,10 @@
41#define DASD_ECKD_CCW_RESERVE 0xB4 41#define DASD_ECKD_CCW_RESERVE 0xB4
42 42
43/* 43/*
44 *Perform Subsystem Function / Sub-Orders 44 * Perform Subsystem Function / Sub-Orders
45 */ 45 */
46#define PSF_ORDER_PRSSD 0x18 46#define PSF_ORDER_PRSSD 0x18
47#define PSF_ORDER_SSC 0x1D
47 48
48/***************************************************************************** 49/*****************************************************************************
49 * SECTION: Type Definitions 50 * SECTION: Type Definitions
@@ -155,7 +156,7 @@ struct dasd_eckd_characteristics {
155 unsigned char reserved2:4; 156 unsigned char reserved2:4;
156 unsigned char reserved3:8; 157 unsigned char reserved3:8;
157 unsigned char defect_wr:1; 158 unsigned char defect_wr:1;
158 unsigned char XRC_supported:1; 159 unsigned char XRC_supported:1;
159 unsigned char reserved4:1; 160 unsigned char reserved4:1;
160 unsigned char striping:1; 161 unsigned char striping:1;
161 unsigned char reserved5:4; 162 unsigned char reserved5:4;
@@ -343,7 +344,7 @@ struct dasd_eckd_path {
343}; 344};
344 345
345/* 346/*
346 * Perform Subsystem Function - Prepare for Read Subsystem Data 347 * Perform Subsystem Function - Prepare for Read Subsystem Data
347 */ 348 */
348struct dasd_psf_prssd_data { 349struct dasd_psf_prssd_data {
349 unsigned char order; 350 unsigned char order;
@@ -353,4 +354,15 @@ struct dasd_psf_prssd_data {
353 unsigned char varies[9]; 354 unsigned char varies[9];
354} __attribute__ ((packed)); 355} __attribute__ ((packed));
355 356
357/*
358 * Perform Subsystem Function - Set Subsystem Characteristics
359 */
360struct dasd_psf_ssc_data {
361 unsigned char order;
362 unsigned char flags;
363 unsigned char cu_type[4];
364 unsigned char suborder;
365 unsigned char reserved[59];
366} __attribute__((packed));
367
356#endif /* DASD_ECKD_H */ 368#endif /* DASD_ECKD_H */
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 2d8af709947f..da65f1b032f5 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -276,7 +276,7 @@ struct dasd_eer_header {
276 __u64 tv_sec; 276 __u64 tv_sec;
277 __u64 tv_usec; 277 __u64 tv_usec;
278 char busid[DASD_EER_BUSID_SIZE]; 278 char busid[DASD_EER_BUSID_SIZE];
279}; 279} __attribute__ ((packed));
280 280
281/* 281/*
282 * The following function can be used for those triggers that have 282 * The following function can be used for those triggers that have
@@ -521,6 +521,8 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
521 unsigned long flags; 521 unsigned long flags;
522 522
523 eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); 523 eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL);
524 if (!eerb)
525 return -ENOMEM;
524 eerb->buffer_page_count = eer_pages; 526 eerb->buffer_page_count = eer_pages;
525 if (eerb->buffer_page_count < 1 || 527 if (eerb->buffer_page_count < 1 ||
526 eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { 528 eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index b842377cb0c6..4108d96f6a5a 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -90,7 +90,7 @@ dasd_default_erp_action(struct dasd_ccw_req * cqr)
90 90
91 /* just retry - there is nothing to save ... I got no sense data.... */ 91 /* just retry - there is nothing to save ... I got no sense data.... */
92 if (cqr->retries > 0) { 92 if (cqr->retries > 0) {
93 DEV_MESSAGE (KERN_DEBUG, device, 93 DEV_MESSAGE (KERN_DEBUG, device,
94 "default ERP called (%i retries left)", 94 "default ERP called (%i retries left)",
95 cqr->retries); 95 cqr->retries);
96 cqr->lpm = LPM_ANYPATH; 96 cqr->lpm = LPM_ANYPATH;
@@ -155,7 +155,7 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr)
155 155
156/* 156/*
157 * Print the hex dump of the memory used by a request. This includes 157 * Print the hex dump of the memory used by a request. This includes
158 * all error recovery ccws that have been chained in from of the 158 * all error recovery ccws that have been chained in from of the
159 * real request. 159 * real request.
160 */ 160 */
161static inline void 161static inline void
@@ -227,12 +227,12 @@ dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa)
227 /* 227 /*
228 * Log bytes arround failed CCW but only if we did 228 * Log bytes arround failed CCW but only if we did
229 * not log the whole CP of the CCW is outside the 229 * not log the whole CP of the CCW is outside the
230 * logged CP. 230 * logged CP.
231 */ 231 */
232 if (cplength > 40 || 232 if (cplength > 40 ||
233 ((addr_t) cpa < (addr_t) lcqr->cpaddr && 233 ((addr_t) cpa < (addr_t) lcqr->cpaddr &&
234 (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) { 234 (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) {
235 235
236 DEV_MESSAGE(KERN_ERR, device, 236 DEV_MESSAGE(KERN_ERR, device,
237 "Failed CCW (%p) (area):", 237 "Failed CCW (%p) (area):",
238 (void *) (long) cpa); 238 (void *) (long) cpa);
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 91145698f8e9..bb7755b9b19d 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_fba.c 2 * File...........: linux/drivers/s390/block/dasd_fba.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -56,19 +56,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */
56static int 56static int
57dasd_fba_probe(struct ccw_device *cdev) 57dasd_fba_probe(struct ccw_device *cdev)
58{ 58{
59 int ret; 59 return dasd_generic_probe(cdev, &dasd_fba_discipline);
60
61 ret = dasd_generic_probe (cdev, &dasd_fba_discipline);
62 if (ret)
63 return ret;
64 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
65 return 0;
66} 60}
67 61
68static int 62static int
69dasd_fba_set_online(struct ccw_device *cdev) 63dasd_fba_set_online(struct ccw_device *cdev)
70{ 64{
71 return dasd_generic_set_online (cdev, &dasd_fba_discipline); 65 return dasd_generic_set_online(cdev, &dasd_fba_discipline);
72} 66}
73 67
74static struct ccw_driver dasd_fba_driver = { 68static struct ccw_driver dasd_fba_driver = {
@@ -125,13 +119,13 @@ static int
125dasd_fba_check_characteristics(struct dasd_device *device) 119dasd_fba_check_characteristics(struct dasd_device *device)
126{ 120{
127 struct dasd_fba_private *private; 121 struct dasd_fba_private *private;
128 struct ccw_device *cdev = device->cdev; 122 struct ccw_device *cdev = device->cdev;
129 void *rdc_data; 123 void *rdc_data;
130 int rc; 124 int rc;
131 125
132 private = (struct dasd_fba_private *) device->private; 126 private = (struct dasd_fba_private *) device->private;
133 if (private == NULL) { 127 if (private == NULL) {
134 private = kmalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); 128 private = kzalloc(sizeof(struct dasd_fba_private), GFP_KERNEL);
135 if (private == NULL) { 129 if (private == NULL) {
136 DEV_MESSAGE(KERN_WARNING, device, "%s", 130 DEV_MESSAGE(KERN_WARNING, device, "%s",
137 "memory allocation failed for private " 131 "memory allocation failed for private "
@@ -204,7 +198,7 @@ dasd_fba_examine_error(struct dasd_ccw_req * cqr, struct irb * irb)
204 if (irb->scsw.cstat == 0x00 && 198 if (irb->scsw.cstat == 0x00 &&
205 irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) 199 irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
206 return dasd_era_none; 200 return dasd_era_none;
207 201
208 cdev = device->cdev; 202 cdev = device->cdev;
209 switch (cdev->id.dev_type) { 203 switch (cdev->id.dev_type) {
210 case 0x3370: 204 case 0x3370:
@@ -539,7 +533,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
539 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has 533 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has
540 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use 534 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use
541 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In 535 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In
542 * addition we have one define extent ccw + 16 bytes of data and a 536 * addition we have one define extent ccw + 16 bytes of data and a
543 * locate record ccw for each block (stupid devices!) + 16 bytes of data. 537 * locate record ccw for each block (stupid devices!) + 16 bytes of data.
544 * That makes: 538 * That makes:
545 * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum. 539 * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum.
@@ -569,16 +563,8 @@ static struct dasd_discipline dasd_fba_discipline = {
569static int __init 563static int __init
570dasd_fba_init(void) 564dasd_fba_init(void)
571{ 565{
572 int ret;
573
574 ASCEBC(dasd_fba_discipline.ebcname, 4); 566 ASCEBC(dasd_fba_discipline.ebcname, 4);
575 567 return ccw_driver_register(&dasd_fba_driver);
576 ret = ccw_driver_register(&dasd_fba_driver);
577 if (ret)
578 return ret;
579
580 dasd_generic_auto_online(&dasd_fba_driver);
581 return 0;
582} 568}
583 569
584static void __exit 570static void __exit
@@ -589,22 +575,3 @@ dasd_fba_cleanup(void)
589 575
590module_init(dasd_fba_init); 576module_init(dasd_fba_init);
591module_exit(dasd_fba_cleanup); 577module_exit(dasd_fba_cleanup);
592
593/*
594 * Overrides for Emacs so that we follow Linus's tabbing style.
595 * Emacs will notice this stuff at the end of the file and automatically
596 * adjust the settings for this buffer only. This must remain at the end
597 * of the file.
598 * ---------------------------------------------------------------------------
599 * Local variables:
600 * c-indent-level: 4
601 * c-brace-imaginary-offset: 0
602 * c-brace-offset: -4
603 * c-argdecl-indent: 4
604 * c-label-offset: -4
605 * c-continued-statement-offset: 4
606 * c-continued-brace-offset: 0
607 * indent-tabs-mode: 1
608 * tab-width: 8
609 * End:
610 */
diff --git a/drivers/s390/block/dasd_fba.h b/drivers/s390/block/dasd_fba.h
index da1fa91fc01d..14c910baa5fe 100644
--- a/drivers/s390/block/dasd_fba.h
+++ b/drivers/s390/block/dasd_fba.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_fba.h 2 * File...........: linux/drivers/s390/block/dasd_fba.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index d4b13e300a76..03a83efc34c4 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_int.h 2 * File...........: linux/drivers/s390/block/dasd_int.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com> 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
@@ -186,7 +186,7 @@ struct dasd_ccw_req {
186 void *callback_data; 186 void *callback_data;
187}; 187};
188 188
189/* 189/*
190 * dasd_ccw_req -> status can be: 190 * dasd_ccw_req -> status can be:
191 */ 191 */
192#define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ 192#define DASD_CQR_FILLED 0x00 /* request is ready to be processed */
@@ -248,7 +248,7 @@ struct dasd_discipline {
248 /* 248 /*
249 * Error recovery functions. examine_error() returns a value that 249 * Error recovery functions. examine_error() returns a value that
250 * indicates what to do for an error condition. If examine_error() 250 * indicates what to do for an error condition. If examine_error()
251 * returns 'dasd_era_recover' erp_action() is called to create a 251 * returns 'dasd_era_recover' erp_action() is called to create a
252 * special error recovery ccw. erp_postaction() is called after 252 * special error recovery ccw. erp_postaction() is called after
253 * an error recovery ccw has finished its execution. dump_sense 253 * an error recovery ccw has finished its execution. dump_sense
254 * is called for every error condition to print the sense data 254 * is called for every error condition to print the sense data
@@ -302,11 +302,11 @@ struct dasd_device {
302 spinlock_t request_queue_lock; 302 spinlock_t request_queue_lock;
303 struct block_device *bdev; 303 struct block_device *bdev;
304 unsigned int devindex; 304 unsigned int devindex;
305 unsigned long blocks; /* size of volume in blocks */ 305 unsigned long blocks; /* size of volume in blocks */
306 unsigned int bp_block; /* bytes per block */ 306 unsigned int bp_block; /* bytes per block */
307 unsigned int s2b_shift; /* log2 (bp_block/512) */ 307 unsigned int s2b_shift; /* log2 (bp_block/512) */
308 unsigned long flags; /* per device flags */ 308 unsigned long flags; /* per device flags */
309 unsigned short features; /* copy of devmap-features (read-only!) */ 309 unsigned short features; /* copy of devmap-features (read-only!) */
310 310
311 /* extended error reporting stuff (eer) */ 311 /* extended error reporting stuff (eer) */
312 struct dasd_ccw_req *eer_cqr; 312 struct dasd_ccw_req *eer_cqr;
@@ -513,12 +513,12 @@ void dasd_generic_remove (struct ccw_device *cdev);
513int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); 513int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
514int dasd_generic_set_offline (struct ccw_device *cdev); 514int dasd_generic_set_offline (struct ccw_device *cdev);
515int dasd_generic_notify(struct ccw_device *, int); 515int dasd_generic_notify(struct ccw_device *, int);
516void dasd_generic_auto_online (struct ccw_driver *);
517 516
518/* externals in dasd_devmap.c */ 517/* externals in dasd_devmap.c */
519extern int dasd_max_devindex; 518extern int dasd_max_devindex;
520extern int dasd_probeonly; 519extern int dasd_probeonly;
521extern int dasd_autodetect; 520extern int dasd_autodetect;
521extern int dasd_nopav;
522 522
523int dasd_devmap_init(void); 523int dasd_devmap_init(void);
524void dasd_devmap_exit(void); 524void dasd_devmap_exit(void);
@@ -606,22 +606,3 @@ static inline int dasd_eer_enabled(struct dasd_device *device)
606#endif /* __KERNEL__ */ 606#endif /* __KERNEL__ */
607 607
608#endif /* DASD_H */ 608#endif /* DASD_H */
609
610/*
611 * Overrides for Emacs so that we follow Linus's tabbing style.
612 * Emacs will notice this stuff at the end of the file and automatically
613 * adjust the settings for this buffer only. This must remain at the end
614 * of the file.
615 * ---------------------------------------------------------------------------
616 * Local variables:
617 * c-indent-level: 4
618 * c-brace-imaginary-offset: 0
619 * c-brace-offset: -4
620 * c-argdecl-indent: 4
621 * c-label-offset: -4
622 * c-continued-statement-offset: 4
623 * c-continued-brace-offset: 0
624 * indent-tabs-mode: 1
625 * tab-width: 8
626 * End:
627 */
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index b8c80d28df41..302bcd0f28be 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -90,10 +90,10 @@ static int
90dasd_ioctl_quiesce(struct dasd_device *device) 90dasd_ioctl_quiesce(struct dasd_device *device)
91{ 91{
92 unsigned long flags; 92 unsigned long flags;
93 93
94 if (!capable (CAP_SYS_ADMIN)) 94 if (!capable (CAP_SYS_ADMIN))
95 return -EACCES; 95 return -EACCES;
96 96
97 DEV_MESSAGE (KERN_DEBUG, device, "%s", 97 DEV_MESSAGE (KERN_DEBUG, device, "%s",
98 "Quiesce IO on device"); 98 "Quiesce IO on device");
99 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 99 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
@@ -110,13 +110,13 @@ static int
110dasd_ioctl_resume(struct dasd_device *device) 110dasd_ioctl_resume(struct dasd_device *device)
111{ 111{
112 unsigned long flags; 112 unsigned long flags;
113 113
114 if (!capable (CAP_SYS_ADMIN)) 114 if (!capable (CAP_SYS_ADMIN))
115 return -EACCES; 115 return -EACCES;
116 116
117 DEV_MESSAGE (KERN_DEBUG, device, "%s", 117 DEV_MESSAGE (KERN_DEBUG, device, "%s",
118 "resume IO on device"); 118 "resume IO on device");
119 119
120 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 120 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
121 device->stopped &= ~DASD_STOPPED_QUIESCE; 121 device->stopped &= ~DASD_STOPPED_QUIESCE;
122 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 122 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
@@ -287,7 +287,7 @@ dasd_ioctl_information(struct dasd_device *device,
287 dasd_info->open_count = atomic_read(&device->open_count); 287 dasd_info->open_count = atomic_read(&device->open_count);
288 if (!device->bdev) 288 if (!device->bdev)
289 dasd_info->open_count++; 289 dasd_info->open_count++;
290 290
291 /* 291 /*
292 * check if device is really formatted 292 * check if device is really formatted
293 * LDL / CDL was returned by 'fill_info' 293 * LDL / CDL was returned by 'fill_info'
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index eecb2afad5c2..3c1314b7391b 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -50,6 +50,9 @@ struct raw3270 {
50 unsigned char *ascebc; /* ascii -> ebcdic table */ 50 unsigned char *ascebc; /* ascii -> ebcdic table */
51 struct class_device *clttydev; /* 3270-class tty device ptr */ 51 struct class_device *clttydev; /* 3270-class tty device ptr */
52 struct class_device *cltubdev; /* 3270-class tub device ptr */ 52 struct class_device *cltubdev; /* 3270-class tub device ptr */
53
54 struct raw3270_request init_request;
55 unsigned char init_data[256];
53}; 56};
54 57
55/* raw3270->flags */ 58/* raw3270->flags */
@@ -484,8 +487,6 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */
484 } __attribute__ ((packed)) aua; 487 } __attribute__ ((packed)) aua;
485} __attribute__ ((packed)); 488} __attribute__ ((packed));
486 489
487static unsigned char raw3270_init_data[256];
488static struct raw3270_request raw3270_init_request;
489static struct diag210 raw3270_init_diag210; 490static struct diag210 raw3270_init_diag210;
490static DECLARE_MUTEX(raw3270_init_sem); 491static DECLARE_MUTEX(raw3270_init_sem);
491 492
@@ -644,17 +645,17 @@ __raw3270_size_device(struct raw3270 *rp)
644 * required (3270 device switched to 'stand-by') and command 645 * required (3270 device switched to 'stand-by') and command
645 * rejects (old devices that can't do 'read partition'). 646 * rejects (old devices that can't do 'read partition').
646 */ 647 */
647 memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); 648 memset(&rp->init_request, 0, sizeof(rp->init_request));
648 memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); 649 memset(&rp->init_data, 0, 256);
649 /* Store 'read partition' data stream to raw3270_init_data */ 650 /* Store 'read partition' data stream to init_data */
650 memcpy(raw3270_init_data, wbuf, sizeof(wbuf)); 651 memcpy(&rp->init_data, wbuf, sizeof(wbuf));
651 INIT_LIST_HEAD(&raw3270_init_request.list); 652 INIT_LIST_HEAD(&rp->init_request.list);
652 raw3270_init_request.ccw.cmd_code = TC_WRITESF; 653 rp->init_request.ccw.cmd_code = TC_WRITESF;
653 raw3270_init_request.ccw.flags = CCW_FLAG_SLI; 654 rp->init_request.ccw.flags = CCW_FLAG_SLI;
654 raw3270_init_request.ccw.count = sizeof(wbuf); 655 rp->init_request.ccw.count = sizeof(wbuf);
655 raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); 656 rp->init_request.ccw.cda = (__u32) __pa(&rp->init_data);
656 657
657 rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); 658 rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
658 if (rc) 659 if (rc)
659 /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */ 660 /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */
660 return rc; 661 return rc;
@@ -679,18 +680,18 @@ __raw3270_size_device(struct raw3270 *rp)
679 * The device accepted the 'read partition' command. Now 680 * The device accepted the 'read partition' command. Now
680 * set up a read ccw and issue it. 681 * set up a read ccw and issue it.
681 */ 682 */
682 raw3270_init_request.ccw.cmd_code = TC_READMOD; 683 rp->init_request.ccw.cmd_code = TC_READMOD;
683 raw3270_init_request.ccw.flags = CCW_FLAG_SLI; 684 rp->init_request.ccw.flags = CCW_FLAG_SLI;
684 raw3270_init_request.ccw.count = sizeof(raw3270_init_data); 685 rp->init_request.ccw.count = sizeof(rp->init_data);
685 raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); 686 rp->init_request.ccw.cda = (__u32) __pa(rp->init_data);
686 rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); 687 rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
687 if (rc) 688 if (rc)
688 return rc; 689 return rc;
689 /* Got a Query Reply */ 690 /* Got a Query Reply */
690 count = sizeof(raw3270_init_data) - raw3270_init_request.rescnt; 691 count = sizeof(rp->init_data) - rp->init_request.rescnt;
691 uap = (struct raw3270_ua *) (raw3270_init_data + 1); 692 uap = (struct raw3270_ua *) (rp->init_data + 1);
692 /* Paranoia check. */ 693 /* Paranoia check. */
693 if (raw3270_init_data[0] != 0x88 || uap->uab.qcode != 0x81) 694 if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81)
694 return -EOPNOTSUPP; 695 return -EOPNOTSUPP;
695 /* Copy rows/columns of default Usable Area */ 696 /* Copy rows/columns of default Usable Area */
696 rp->rows = uap->uab.h; 697 rp->rows = uap->uab.h;
@@ -749,18 +750,18 @@ raw3270_reset_device(struct raw3270 *rp)
749 int rc; 750 int rc;
750 751
751 down(&raw3270_init_sem); 752 down(&raw3270_init_sem);
752 memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); 753 memset(&rp->init_request, 0, sizeof(rp->init_request));
753 memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); 754 memset(&rp->init_data, 0, sizeof(rp->init_data));
754 /* Store reset data stream to raw3270_init_data/raw3270_init_request */ 755 /* Store reset data stream to init_data/init_request */
755 raw3270_init_data[0] = TW_KR; 756 rp->init_data[0] = TW_KR;
756 INIT_LIST_HEAD(&raw3270_init_request.list); 757 INIT_LIST_HEAD(&rp->init_request.list);
757 raw3270_init_request.ccw.cmd_code = TC_EWRITEA; 758 rp->init_request.ccw.cmd_code = TC_EWRITEA;
758 raw3270_init_request.ccw.flags = CCW_FLAG_SLI; 759 rp->init_request.ccw.flags = CCW_FLAG_SLI;
759 raw3270_init_request.ccw.count = 1; 760 rp->init_request.ccw.count = 1;
760 raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); 761 rp->init_request.ccw.cda = (__u32) __pa(rp->init_data);
761 rp->view = &raw3270_init_view; 762 rp->view = &raw3270_init_view;
762 raw3270_init_view.dev = rp; 763 raw3270_init_view.dev = rp;
763 rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); 764 rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
764 raw3270_init_view.dev = 0; 765 raw3270_init_view.dev = 0;
765 rp->view = 0; 766 rp->view = 0;
766 up(&raw3270_init_sem); 767 up(&raw3270_init_sem);
@@ -854,7 +855,7 @@ raw3270_setup_console(struct ccw_device *cdev)
854 char *ascebc; 855 char *ascebc;
855 int rc; 856 int rc;
856 857
857 rp = (struct raw3270 *) alloc_bootmem(sizeof(struct raw3270)); 858 rp = (struct raw3270 *) alloc_bootmem_low(sizeof(struct raw3270));
858 ascebc = (char *) alloc_bootmem(256); 859 ascebc = (char *) alloc_bootmem(256);
859 rc = raw3270_setup_device(cdev, rp, ascebc); 860 rc = raw3270_setup_device(cdev, rp, ascebc);
860 if (rc) 861 if (rc)
@@ -895,7 +896,7 @@ raw3270_create_device(struct ccw_device *cdev)
895 char *ascebc; 896 char *ascebc;
896 int rc; 897 int rc;
897 898
898 rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL); 899 rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
899 if (!rp) 900 if (!rp)
900 return ERR_PTR(-ENOMEM); 901 return ERR_PTR(-ENOMEM);
901 ascebc = kmalloc(256, GFP_KERNEL); 902 ascebc = kmalloc(256, GFP_KERNEL);
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 0960bef7b199..15b895496a45 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -224,39 +224,6 @@ is_blacklisted (int ssid, int devno)
224} 224}
225 225
226#ifdef CONFIG_PROC_FS 226#ifdef CONFIG_PROC_FS
227static int
228__s390_redo_validation(struct subchannel_id schid, void *data)
229{
230 int ret;
231 struct subchannel *sch;
232
233 sch = get_subchannel_by_schid(schid);
234 if (sch) {
235 /* Already known. */
236 put_device(&sch->dev);
237 return 0;
238 }
239 ret = css_probe_device(schid);
240 if (ret == -ENXIO)
241 return ret; /* We're through. */
242 if (ret == -ENOMEM)
243 /* Stop validation for now. Bad, but no need for a panic. */
244 return ret;
245 return 0;
246}
247
248/*
249 * Function: s390_redo_validation
250 * Look for no longer blacklisted devices
251 * FIXME: there must be a better way to do this */
252static inline void
253s390_redo_validation (void)
254{
255 CIO_TRACE_EVENT (0, "redoval");
256
257 for_each_subchannel(__s390_redo_validation, NULL);
258}
259
260/* 227/*
261 * Function: blacklist_parse_proc_parameters 228 * Function: blacklist_parse_proc_parameters
262 * parse the stuff which is piped to /proc/cio_ignore 229 * parse the stuff which is piped to /proc/cio_ignore
@@ -281,7 +248,7 @@ blacklist_parse_proc_parameters (char *buf)
281 return; 248 return;
282 } 249 }
283 250
284 s390_redo_validation (); 251 css_schedule_reprobe();
285} 252}
286 253
287/* Iterator struct for all devices. */ 254/* Iterator struct for all devices. */
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index bdfee7fbaa2e..c7319a07ba35 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -404,21 +404,24 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
404} 404}
405 405
406static int 406static int
407__ccwgroup_driver_unregister_device(struct device *dev, void *data) 407__ccwgroup_match_all(struct device *dev, void *data)
408{ 408{
409 __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); 409 return 1;
410 device_unregister(dev);
411 put_device(dev);
412 return 0;
413} 410}
414 411
415void 412void
416ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) 413ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
417{ 414{
415 struct device *dev;
416
418 /* We don't want ccwgroup devices to live longer than their driver. */ 417 /* We don't want ccwgroup devices to live longer than their driver. */
419 get_driver(&cdriver->driver); 418 get_driver(&cdriver->driver);
420 driver_for_each_device(&cdriver->driver, NULL, NULL, 419 while ((dev = driver_find_device(&cdriver->driver, NULL, NULL,
421 __ccwgroup_driver_unregister_device); 420 __ccwgroup_match_all))) {
421 __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
422 device_unregister(dev);
423 put_device(dev);
424 }
422 put_driver(&cdriver->driver); 425 put_driver(&cdriver->driver);
423 driver_unregister(&cdriver->driver); 426 driver_unregister(&cdriver->driver);
424} 427}
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 72187e54dcac..b00f3ed051a0 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -244,8 +244,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
244 244
245 if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && 245 if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) &&
246 (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && 246 (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) &&
247 (sch->schib.pmcw.lpum == mask) && 247 (sch->schib.pmcw.lpum == mask)) {
248 (sch->vpm == 0)) {
249 int cc; 248 int cc;
250 249
251 cc = cio_clear(sch); 250 cc = cio_clear(sch);
@@ -918,12 +917,13 @@ chp_measurement_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
918 chp = to_channelpath(container_of(kobj, struct device, kobj)); 917 chp = to_channelpath(container_of(kobj, struct device, kobj));
919 css = to_css(chp->dev.parent); 918 css = to_css(chp->dev.parent);
920 919
921 size = sizeof(struct cmg_chars); 920 size = sizeof(struct cmg_entry);
922 921
923 /* Only allow single reads. */ 922 /* Only allow single reads. */
924 if (off || count < size) 923 if (off || count < size)
925 return 0; 924 return 0;
926 chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); 925 chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id);
926 count = size;
927 return count; 927 return count;
928} 928}
929 929
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 07ef3f640f4a..1c3e8e9012b0 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -3,9 +3,10 @@
3 * 3 *
4 * Linux on zSeries Channel Measurement Facility support 4 * Linux on zSeries Channel Measurement Facility support
5 * 5 *
6 * Copyright 2000,2003 IBM Corporation 6 * Copyright 2000,2006 IBM Corporation
7 * 7 *
8 * Author: Arnd Bergmann <arndb@de.ibm.com> 8 * Authors: Arnd Bergmann <arndb@de.ibm.com>
9 * Cornelia Huck <cornelia.huck@de.ibm.com>
9 * 10 *
10 * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com> 11 * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com>
11 * 12 *
@@ -96,9 +97,9 @@ module_param(format, bool, 0444);
96/** 97/**
97 * struct cmb_operations - functions to use depending on cmb_format 98 * struct cmb_operations - functions to use depending on cmb_format
98 * 99 *
99 * all these functions operate on a struct cmf_device. There is only 100 * Most of these functions operate on a struct ccw_device. There is only
100 * one instance of struct cmb_operations because all cmf_device 101 * one instance of struct cmb_operations because the format of the measurement
101 * objects are guaranteed to be of the same type. 102 * data is guaranteed to be the same for every ccw_device.
102 * 103 *
103 * @alloc: allocate memory for a channel measurement block, 104 * @alloc: allocate memory for a channel measurement block,
104 * either with the help of a special pool or with kmalloc 105 * either with the help of a special pool or with kmalloc
@@ -107,6 +108,7 @@ module_param(format, bool, 0444);
107 * @readall: read a measurement block in a common format 108 * @readall: read a measurement block in a common format
108 * @reset: clear the data in the associated measurement block and 109 * @reset: clear the data in the associated measurement block and
109 * reset its time stamp 110 * reset its time stamp
111 * @align: align an allocated block so that the hardware can use it
110 */ 112 */
111struct cmb_operations { 113struct cmb_operations {
112 int (*alloc) (struct ccw_device*); 114 int (*alloc) (struct ccw_device*);
@@ -115,11 +117,19 @@ struct cmb_operations {
115 u64 (*read) (struct ccw_device*, int); 117 u64 (*read) (struct ccw_device*, int);
116 int (*readall)(struct ccw_device*, struct cmbdata *); 118 int (*readall)(struct ccw_device*, struct cmbdata *);
117 void (*reset) (struct ccw_device*); 119 void (*reset) (struct ccw_device*);
120 void * (*align) (void *);
118 121
119 struct attribute_group *attr_group; 122 struct attribute_group *attr_group;
120}; 123};
121static struct cmb_operations *cmbops; 124static struct cmb_operations *cmbops;
122 125
126struct cmb_data {
127 void *hw_block; /* Pointer to block updated by hardware */
128 void *last_block; /* Last changed block copied from hardware block */
129 int size; /* Size of hw_block and last_block */
130 unsigned long long last_update; /* when last_block was updated */
131};
132
123/* our user interface is designed in terms of nanoseconds, 133/* our user interface is designed in terms of nanoseconds,
124 * while the hardware measures total times in its own 134 * while the hardware measures total times in its own
125 * unit.*/ 135 * unit.*/
@@ -226,63 +236,229 @@ struct set_schib_struct {
226 unsigned long address; 236 unsigned long address;
227 wait_queue_head_t wait; 237 wait_queue_head_t wait;
228 int ret; 238 int ret;
239 struct kref kref;
229}; 240};
230 241
242static void cmf_set_schib_release(struct kref *kref)
243{
244 struct set_schib_struct *set_data;
245
246 set_data = container_of(kref, struct set_schib_struct, kref);
247 kfree(set_data);
248}
249
250#define CMF_PENDING 1
251
231static int set_schib_wait(struct ccw_device *cdev, u32 mme, 252static int set_schib_wait(struct ccw_device *cdev, u32 mme,
232 int mbfc, unsigned long address) 253 int mbfc, unsigned long address)
233{ 254{
234 struct set_schib_struct s = { 255 struct set_schib_struct *set_data;
235 .mme = mme, 256 int ret;
236 .mbfc = mbfc,
237 .address = address,
238 .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s.wait),
239 };
240 257
241 spin_lock_irq(cdev->ccwlock); 258 spin_lock_irq(cdev->ccwlock);
242 s.ret = set_schib(cdev, mme, mbfc, address); 259 if (!cdev->private->cmb) {
243 if (s.ret != -EBUSY) { 260 ret = -ENODEV;
244 goto out_nowait; 261 goto out;
245 } 262 }
263 set_data = kzalloc(sizeof(struct set_schib_struct), GFP_ATOMIC);
264 if (!set_data) {
265 ret = -ENOMEM;
266 goto out;
267 }
268 init_waitqueue_head(&set_data->wait);
269 kref_init(&set_data->kref);
270 set_data->mme = mme;
271 set_data->mbfc = mbfc;
272 set_data->address = address;
273
274 ret = set_schib(cdev, mme, mbfc, address);
275 if (ret != -EBUSY)
276 goto out_put;
246 277
247 if (cdev->private->state != DEV_STATE_ONLINE) { 278 if (cdev->private->state != DEV_STATE_ONLINE) {
248 s.ret = -EBUSY;
249 /* if the device is not online, don't even try again */ 279 /* if the device is not online, don't even try again */
250 goto out_nowait; 280 ret = -EBUSY;
281 goto out_put;
251 } 282 }
283
252 cdev->private->state = DEV_STATE_CMFCHANGE; 284 cdev->private->state = DEV_STATE_CMFCHANGE;
253 cdev->private->cmb_wait = &s; 285 set_data->ret = CMF_PENDING;
254 s.ret = 1; 286 cdev->private->cmb_wait = set_data;
255 287
256 spin_unlock_irq(cdev->ccwlock); 288 spin_unlock_irq(cdev->ccwlock);
257 if (wait_event_interruptible(s.wait, s.ret != 1)) { 289 if (wait_event_interruptible(set_data->wait,
290 set_data->ret != CMF_PENDING)) {
258 spin_lock_irq(cdev->ccwlock); 291 spin_lock_irq(cdev->ccwlock);
259 if (s.ret == 1) { 292 if (set_data->ret == CMF_PENDING) {
260 s.ret = -ERESTARTSYS; 293 set_data->ret = -ERESTARTSYS;
261 cdev->private->cmb_wait = 0;
262 if (cdev->private->state == DEV_STATE_CMFCHANGE) 294 if (cdev->private->state == DEV_STATE_CMFCHANGE)
263 cdev->private->state = DEV_STATE_ONLINE; 295 cdev->private->state = DEV_STATE_ONLINE;
264 } 296 }
265 spin_unlock_irq(cdev->ccwlock); 297 spin_unlock_irq(cdev->ccwlock);
266 } 298 }
267 return s.ret; 299 spin_lock_irq(cdev->ccwlock);
268 300 cdev->private->cmb_wait = NULL;
269out_nowait: 301 ret = set_data->ret;
302out_put:
303 kref_put(&set_data->kref, cmf_set_schib_release);
304out:
270 spin_unlock_irq(cdev->ccwlock); 305 spin_unlock_irq(cdev->ccwlock);
271 return s.ret; 306 return ret;
272} 307}
273 308
274void retry_set_schib(struct ccw_device *cdev) 309void retry_set_schib(struct ccw_device *cdev)
275{ 310{
276 struct set_schib_struct *s; 311 struct set_schib_struct *set_data;
312
313 set_data = cdev->private->cmb_wait;
314 if (!set_data) {
315 WARN_ON(1);
316 return;
317 }
318 kref_get(&set_data->kref);
319 set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc,
320 set_data->address);
321 wake_up(&set_data->wait);
322 kref_put(&set_data->kref, cmf_set_schib_release);
323}
324
325static int cmf_copy_block(struct ccw_device *cdev)
326{
327 struct subchannel *sch;
328 void *reference_buf;
329 void *hw_block;
330 struct cmb_data *cmb_data;
331
332 sch = to_subchannel(cdev->dev.parent);
333
334 if (stsch(sch->schid, &sch->schib))
335 return -ENODEV;
336
337 if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) {
338 /* Don't copy if a start function is in progress. */
339 if ((!sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED) &&
340 (sch->schib.scsw.actl &
341 (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) &&
342 (!sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS))
343 return -EBUSY;
344 }
345 cmb_data = cdev->private->cmb;
346 hw_block = cmbops->align(cmb_data->hw_block);
347 if (!memcmp(cmb_data->last_block, hw_block, cmb_data->size))
348 /* No need to copy. */
349 return 0;
350 reference_buf = kzalloc(cmb_data->size, GFP_ATOMIC);
351 if (!reference_buf)
352 return -ENOMEM;
353 /* Ensure consistency of block copied from hardware. */
354 do {
355 memcpy(cmb_data->last_block, hw_block, cmb_data->size);
356 memcpy(reference_buf, hw_block, cmb_data->size);
357 } while (memcmp(cmb_data->last_block, reference_buf, cmb_data->size));
358 cmb_data->last_update = get_clock();
359 kfree(reference_buf);
360 return 0;
361}
362
363struct copy_block_struct {
364 wait_queue_head_t wait;
365 int ret;
366 struct kref kref;
367};
368
369static void cmf_copy_block_release(struct kref *kref)
370{
371 struct copy_block_struct *copy_block;
372
373 copy_block = container_of(kref, struct copy_block_struct, kref);
374 kfree(copy_block);
375}
376
377static int cmf_cmb_copy_wait(struct ccw_device *cdev)
378{
379 struct copy_block_struct *copy_block;
380 int ret;
381 unsigned long flags;
382
383 spin_lock_irqsave(cdev->ccwlock, flags);
384 if (!cdev->private->cmb) {
385 ret = -ENODEV;
386 goto out;
387 }
388 copy_block = kzalloc(sizeof(struct copy_block_struct), GFP_ATOMIC);
389 if (!copy_block) {
390 ret = -ENOMEM;
391 goto out;
392 }
393 init_waitqueue_head(&copy_block->wait);
394 kref_init(&copy_block->kref);
395
396 ret = cmf_copy_block(cdev);
397 if (ret != -EBUSY)
398 goto out_put;
399
400 if (cdev->private->state != DEV_STATE_ONLINE) {
401 ret = -EBUSY;
402 goto out_put;
403 }
404
405 cdev->private->state = DEV_STATE_CMFUPDATE;
406 copy_block->ret = CMF_PENDING;
407 cdev->private->cmb_wait = copy_block;
408
409 spin_unlock_irqrestore(cdev->ccwlock, flags);
410 if (wait_event_interruptible(copy_block->wait,
411 copy_block->ret != CMF_PENDING)) {
412 spin_lock_irqsave(cdev->ccwlock, flags);
413 if (copy_block->ret == CMF_PENDING) {
414 copy_block->ret = -ERESTARTSYS;
415 if (cdev->private->state == DEV_STATE_CMFUPDATE)
416 cdev->private->state = DEV_STATE_ONLINE;
417 }
418 spin_unlock_irqrestore(cdev->ccwlock, flags);
419 }
420 spin_lock_irqsave(cdev->ccwlock, flags);
421 cdev->private->cmb_wait = NULL;
422 ret = copy_block->ret;
423out_put:
424 kref_put(&copy_block->kref, cmf_copy_block_release);
425out:
426 spin_unlock_irqrestore(cdev->ccwlock, flags);
427 return ret;
428}
429
430void cmf_retry_copy_block(struct ccw_device *cdev)
431{
432 struct copy_block_struct *copy_block;
277 433
278 s = cdev->private->cmb_wait; 434 copy_block = cdev->private->cmb_wait;
279 cdev->private->cmb_wait = 0; 435 if (!copy_block) {
280 if (!s) {
281 WARN_ON(1); 436 WARN_ON(1);
282 return; 437 return;
283 } 438 }
284 s->ret = set_schib(cdev, s->mme, s->mbfc, s->address); 439 kref_get(&copy_block->kref);
285 wake_up(&s->wait); 440 copy_block->ret = cmf_copy_block(cdev);
441 wake_up(&copy_block->wait);
442 kref_put(&copy_block->kref, cmf_copy_block_release);
443}
444
445static void cmf_generic_reset(struct ccw_device *cdev)
446{
447 struct cmb_data *cmb_data;
448
449 spin_lock_irq(cdev->ccwlock);
450 cmb_data = cdev->private->cmb;
451 if (cmb_data) {
452 memset(cmb_data->last_block, 0, cmb_data->size);
453 /*
454 * Need to reset hw block as well to make the hardware start
455 * from 0 again.
456 */
457 memset(cmbops->align(cmb_data->hw_block), 0, cmb_data->size);
458 cmb_data->last_update = 0;
459 }
460 cdev->private->cmb_start_time = get_clock();
461 spin_unlock_irq(cdev->ccwlock);
286} 462}
287 463
288/** 464/**
@@ -343,8 +519,8 @@ struct cmb {
343/* insert a single device into the cmb_area list 519/* insert a single device into the cmb_area list
344 * called with cmb_area.lock held from alloc_cmb 520 * called with cmb_area.lock held from alloc_cmb
345 */ 521 */
346static inline int 522static inline int alloc_cmb_single (struct ccw_device *cdev,
347alloc_cmb_single (struct ccw_device *cdev) 523 struct cmb_data *cmb_data)
348{ 524{
349 struct cmb *cmb; 525 struct cmb *cmb;
350 struct ccw_device_private *node; 526 struct ccw_device_private *node;
@@ -358,10 +534,12 @@ alloc_cmb_single (struct ccw_device *cdev)
358 534
359 /* find first unused cmb in cmb_area.mem. 535 /* find first unused cmb in cmb_area.mem.
360 * this is a little tricky: cmb_area.list 536 * this is a little tricky: cmb_area.list
361 * remains sorted by ->cmb pointers */ 537 * remains sorted by ->cmb->hw_data pointers */
362 cmb = cmb_area.mem; 538 cmb = cmb_area.mem;
363 list_for_each_entry(node, &cmb_area.list, cmb_list) { 539 list_for_each_entry(node, &cmb_area.list, cmb_list) {
364 if ((struct cmb*)node->cmb > cmb) 540 struct cmb_data *data;
541 data = node->cmb;
542 if ((struct cmb*)data->hw_block > cmb)
365 break; 543 break;
366 cmb++; 544 cmb++;
367 } 545 }
@@ -372,7 +550,8 @@ alloc_cmb_single (struct ccw_device *cdev)
372 550
373 /* insert new cmb */ 551 /* insert new cmb */
374 list_add_tail(&cdev->private->cmb_list, &node->cmb_list); 552 list_add_tail(&cdev->private->cmb_list, &node->cmb_list);
375 cdev->private->cmb = cmb; 553 cmb_data->hw_block = cmb;
554 cdev->private->cmb = cmb_data;
376 ret = 0; 555 ret = 0;
377out: 556out:
378 spin_unlock_irq(cdev->ccwlock); 557 spin_unlock_irq(cdev->ccwlock);
@@ -385,7 +564,19 @@ alloc_cmb (struct ccw_device *cdev)
385 int ret; 564 int ret;
386 struct cmb *mem; 565 struct cmb *mem;
387 ssize_t size; 566 ssize_t size;
567 struct cmb_data *cmb_data;
568
569 /* Allocate private cmb_data. */
570 cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL);
571 if (!cmb_data)
572 return -ENOMEM;
388 573
574 cmb_data->last_block = kzalloc(sizeof(struct cmb), GFP_KERNEL);
575 if (!cmb_data->last_block) {
576 kfree(cmb_data);
577 return -ENOMEM;
578 }
579 cmb_data->size = sizeof(struct cmb);
389 spin_lock(&cmb_area.lock); 580 spin_lock(&cmb_area.lock);
390 581
391 if (!cmb_area.mem) { 582 if (!cmb_area.mem) {
@@ -414,29 +605,36 @@ alloc_cmb (struct ccw_device *cdev)
414 } 605 }
415 606
416 /* do the actual allocation */ 607 /* do the actual allocation */
417 ret = alloc_cmb_single(cdev); 608 ret = alloc_cmb_single(cdev, cmb_data);
418out: 609out:
419 spin_unlock(&cmb_area.lock); 610 spin_unlock(&cmb_area.lock);
420 611 if (ret) {
612 kfree(cmb_data->last_block);
613 kfree(cmb_data);
614 }
421 return ret; 615 return ret;
422} 616}
423 617
424static void 618static void free_cmb(struct ccw_device *cdev)
425free_cmb(struct ccw_device *cdev)
426{ 619{
427 struct ccw_device_private *priv; 620 struct ccw_device_private *priv;
428 621 struct cmb_data *cmb_data;
429 priv = cdev->private;
430 622
431 spin_lock(&cmb_area.lock); 623 spin_lock(&cmb_area.lock);
432 spin_lock_irq(cdev->ccwlock); 624 spin_lock_irq(cdev->ccwlock);
433 625
626 priv = cdev->private;
627
434 if (list_empty(&priv->cmb_list)) { 628 if (list_empty(&priv->cmb_list)) {
435 /* already freed */ 629 /* already freed */
436 goto out; 630 goto out;
437 } 631 }
438 632
633 cmb_data = priv->cmb;
439 priv->cmb = NULL; 634 priv->cmb = NULL;
635 if (cmb_data)
636 kfree(cmb_data->last_block);
637 kfree(cmb_data);
440 list_del_init(&priv->cmb_list); 638 list_del_init(&priv->cmb_list);
441 639
442 if (list_empty(&cmb_area.list)) { 640 if (list_empty(&cmb_area.list)) {
@@ -451,83 +649,97 @@ out:
451 spin_unlock(&cmb_area.lock); 649 spin_unlock(&cmb_area.lock);
452} 650}
453 651
454static int 652static int set_cmb(struct ccw_device *cdev, u32 mme)
455set_cmb(struct ccw_device *cdev, u32 mme)
456{ 653{
457 u16 offset; 654 u16 offset;
655 struct cmb_data *cmb_data;
656 unsigned long flags;
458 657
459 if (!cdev->private->cmb) 658 spin_lock_irqsave(cdev->ccwlock, flags);
659 if (!cdev->private->cmb) {
660 spin_unlock_irqrestore(cdev->ccwlock, flags);
460 return -EINVAL; 661 return -EINVAL;
461 662 }
462 offset = mme ? (struct cmb *)cdev->private->cmb - cmb_area.mem : 0; 663 cmb_data = cdev->private->cmb;
664 offset = mme ? (struct cmb *)cmb_data->hw_block - cmb_area.mem : 0;
665 spin_unlock_irqrestore(cdev->ccwlock, flags);
463 666
464 return set_schib_wait(cdev, mme, 0, offset); 667 return set_schib_wait(cdev, mme, 0, offset);
465} 668}
466 669
467static u64 670static u64 read_cmb (struct ccw_device *cdev, int index)
468read_cmb (struct ccw_device *cdev, int index)
469{ 671{
470 /* yes, we have to put it on the stack 672 struct cmb *cmb;
471 * because the cmb must only be accessed
472 * atomically, e.g. with mvc */
473 struct cmb cmb;
474 unsigned long flags;
475 u32 val; 673 u32 val;
674 int ret;
675 unsigned long flags;
676
677 ret = cmf_cmb_copy_wait(cdev);
678 if (ret < 0)
679 return 0;
476 680
477 spin_lock_irqsave(cdev->ccwlock, flags); 681 spin_lock_irqsave(cdev->ccwlock, flags);
478 if (!cdev->private->cmb) { 682 if (!cdev->private->cmb) {
479 spin_unlock_irqrestore(cdev->ccwlock, flags); 683 ret = 0;
480 return 0; 684 goto out;
481 } 685 }
482 686 cmb = ((struct cmb_data *)cdev->private->cmb)->last_block;
483 cmb = *(struct cmb*)cdev->private->cmb;
484 spin_unlock_irqrestore(cdev->ccwlock, flags);
485 687
486 switch (index) { 688 switch (index) {
487 case cmb_ssch_rsch_count: 689 case cmb_ssch_rsch_count:
488 return cmb.ssch_rsch_count; 690 ret = cmb->ssch_rsch_count;
691 goto out;
489 case cmb_sample_count: 692 case cmb_sample_count:
490 return cmb.sample_count; 693 ret = cmb->sample_count;
694 goto out;
491 case cmb_device_connect_time: 695 case cmb_device_connect_time:
492 val = cmb.device_connect_time; 696 val = cmb->device_connect_time;
493 break; 697 break;
494 case cmb_function_pending_time: 698 case cmb_function_pending_time:
495 val = cmb.function_pending_time; 699 val = cmb->function_pending_time;
496 break; 700 break;
497 case cmb_device_disconnect_time: 701 case cmb_device_disconnect_time:
498 val = cmb.device_disconnect_time; 702 val = cmb->device_disconnect_time;
499 break; 703 break;
500 case cmb_control_unit_queuing_time: 704 case cmb_control_unit_queuing_time:
501 val = cmb.control_unit_queuing_time; 705 val = cmb->control_unit_queuing_time;
502 break; 706 break;
503 case cmb_device_active_only_time: 707 case cmb_device_active_only_time:
504 val = cmb.device_active_only_time; 708 val = cmb->device_active_only_time;
505 break; 709 break;
506 default: 710 default:
507 return 0; 711 ret = 0;
712 goto out;
508 } 713 }
509 return time_to_avg_nsec(val, cmb.sample_count); 714 ret = time_to_avg_nsec(val, cmb->sample_count);
715out:
716 spin_unlock_irqrestore(cdev->ccwlock, flags);
717 return ret;
510} 718}
511 719
512static int 720static int readall_cmb (struct ccw_device *cdev, struct cmbdata *data)
513readall_cmb (struct ccw_device *cdev, struct cmbdata *data)
514{ 721{
515 /* yes, we have to put it on the stack 722 struct cmb *cmb;
516 * because the cmb must only be accessed 723 struct cmb_data *cmb_data;
517 * atomically, e.g. with mvc */
518 struct cmb cmb;
519 unsigned long flags;
520 u64 time; 724 u64 time;
725 unsigned long flags;
726 int ret;
521 727
728 ret = cmf_cmb_copy_wait(cdev);
729 if (ret < 0)
730 return ret;
522 spin_lock_irqsave(cdev->ccwlock, flags); 731 spin_lock_irqsave(cdev->ccwlock, flags);
523 if (!cdev->private->cmb) { 732 cmb_data = cdev->private->cmb;
524 spin_unlock_irqrestore(cdev->ccwlock, flags); 733 if (!cmb_data) {
525 return -ENODEV; 734 ret = -ENODEV;
735 goto out;
526 } 736 }
527 737 if (cmb_data->last_update == 0) {
528 cmb = *(struct cmb*)cdev->private->cmb; 738 ret = -EAGAIN;
529 time = get_clock() - cdev->private->cmb_start_time; 739 goto out;
530 spin_unlock_irqrestore(cdev->ccwlock, flags); 740 }
741 cmb = cmb_data->last_block;
742 time = cmb_data->last_update - cdev->private->cmb_start_time;
531 743
532 memset(data, 0, sizeof(struct cmbdata)); 744 memset(data, 0, sizeof(struct cmbdata));
533 745
@@ -538,31 +750,32 @@ readall_cmb (struct ccw_device *cdev, struct cmbdata *data)
538 data->elapsed_time = (time * 1000) >> 12; 750 data->elapsed_time = (time * 1000) >> 12;
539 751
540 /* copy data to new structure */ 752 /* copy data to new structure */
541 data->ssch_rsch_count = cmb.ssch_rsch_count; 753 data->ssch_rsch_count = cmb->ssch_rsch_count;
542 data->sample_count = cmb.sample_count; 754 data->sample_count = cmb->sample_count;
543 755
544 /* time fields are converted to nanoseconds while copying */ 756 /* time fields are converted to nanoseconds while copying */
545 data->device_connect_time = time_to_nsec(cmb.device_connect_time); 757 data->device_connect_time = time_to_nsec(cmb->device_connect_time);
546 data->function_pending_time = time_to_nsec(cmb.function_pending_time); 758 data->function_pending_time = time_to_nsec(cmb->function_pending_time);
547 data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); 759 data->device_disconnect_time =
760 time_to_nsec(cmb->device_disconnect_time);
548 data->control_unit_queuing_time 761 data->control_unit_queuing_time
549 = time_to_nsec(cmb.control_unit_queuing_time); 762 = time_to_nsec(cmb->control_unit_queuing_time);
550 data->device_active_only_time 763 data->device_active_only_time
551 = time_to_nsec(cmb.device_active_only_time); 764 = time_to_nsec(cmb->device_active_only_time);
765 ret = 0;
766out:
767 spin_unlock_irqrestore(cdev->ccwlock, flags);
768 return ret;
769}
552 770
553 return 0; 771static void reset_cmb(struct ccw_device *cdev)
772{
773 cmf_generic_reset(cdev);
554} 774}
555 775
556static void 776static void * align_cmb(void *area)
557reset_cmb(struct ccw_device *cdev)
558{ 777{
559 struct cmb *cmb; 778 return area;
560 spin_lock_irq(cdev->ccwlock);
561 cmb = cdev->private->cmb;
562 if (cmb)
563 memset (cmb, 0, sizeof (*cmb));
564 cdev->private->cmb_start_time = get_clock();
565 spin_unlock_irq(cdev->ccwlock);
566} 779}
567 780
568static struct attribute_group cmf_attr_group; 781static struct attribute_group cmf_attr_group;
@@ -574,6 +787,7 @@ static struct cmb_operations cmbops_basic = {
574 .read = read_cmb, 787 .read = read_cmb,
575 .readall = readall_cmb, 788 .readall = readall_cmb,
576 .reset = reset_cmb, 789 .reset = reset_cmb,
790 .align = align_cmb,
577 .attr_group = &cmf_attr_group, 791 .attr_group = &cmf_attr_group,
578}; 792};
579 793
@@ -610,22 +824,34 @@ static inline struct cmbe* cmbe_align(struct cmbe *c)
610 return (struct cmbe*)addr; 824 return (struct cmbe*)addr;
611} 825}
612 826
613static int 827static int alloc_cmbe (struct ccw_device *cdev)
614alloc_cmbe (struct ccw_device *cdev)
615{ 828{
616 struct cmbe *cmbe; 829 struct cmbe *cmbe;
617 cmbe = kmalloc (sizeof (*cmbe) * 2, GFP_KERNEL); 830 struct cmb_data *cmb_data;
831 int ret;
832
833 cmbe = kzalloc (sizeof (*cmbe) * 2, GFP_KERNEL);
618 if (!cmbe) 834 if (!cmbe)
619 return -ENOMEM; 835 return -ENOMEM;
620 836 cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL);
837 if (!cmb_data) {
838 ret = -ENOMEM;
839 goto out_free;
840 }
841 cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL);
842 if (!cmb_data->last_block) {
843 ret = -ENOMEM;
844 goto out_free;
845 }
846 cmb_data->size = sizeof(struct cmbe);
621 spin_lock_irq(cdev->ccwlock); 847 spin_lock_irq(cdev->ccwlock);
622 if (cdev->private->cmb) { 848 if (cdev->private->cmb) {
623 kfree(cmbe);
624 spin_unlock_irq(cdev->ccwlock); 849 spin_unlock_irq(cdev->ccwlock);
625 return -EBUSY; 850 ret = -EBUSY;
851 goto out_free;
626 } 852 }
627 853 cmb_data->hw_block = cmbe;
628 cdev->private->cmb = cmbe; 854 cdev->private->cmb = cmb_data;
629 spin_unlock_irq(cdev->ccwlock); 855 spin_unlock_irq(cdev->ccwlock);
630 856
631 /* activate global measurement if this is the first channel */ 857 /* activate global measurement if this is the first channel */
@@ -636,14 +862,24 @@ alloc_cmbe (struct ccw_device *cdev)
636 spin_unlock(&cmb_area.lock); 862 spin_unlock(&cmb_area.lock);
637 863
638 return 0; 864 return 0;
865out_free:
866 if (cmb_data)
867 kfree(cmb_data->last_block);
868 kfree(cmb_data);
869 kfree(cmbe);
870 return ret;
639} 871}
640 872
641static void 873static void free_cmbe (struct ccw_device *cdev)
642free_cmbe (struct ccw_device *cdev)
643{ 874{
875 struct cmb_data *cmb_data;
876
644 spin_lock_irq(cdev->ccwlock); 877 spin_lock_irq(cdev->ccwlock);
645 kfree(cdev->private->cmb); 878 cmb_data = cdev->private->cmb;
646 cdev->private->cmb = NULL; 879 cdev->private->cmb = NULL;
880 if (cmb_data)
881 kfree(cmb_data->last_block);
882 kfree(cmb_data);
647 spin_unlock_irq(cdev->ccwlock); 883 spin_unlock_irq(cdev->ccwlock);
648 884
649 /* deactivate global measurement if this is the last channel */ 885 /* deactivate global measurement if this is the last channel */
@@ -654,89 +890,105 @@ free_cmbe (struct ccw_device *cdev)
654 spin_unlock(&cmb_area.lock); 890 spin_unlock(&cmb_area.lock);
655} 891}
656 892
657static int 893static int set_cmbe(struct ccw_device *cdev, u32 mme)
658set_cmbe(struct ccw_device *cdev, u32 mme)
659{ 894{
660 unsigned long mba; 895 unsigned long mba;
896 struct cmb_data *cmb_data;
897 unsigned long flags;
661 898
662 if (!cdev->private->cmb) 899 spin_lock_irqsave(cdev->ccwlock, flags);
900 if (!cdev->private->cmb) {
901 spin_unlock_irqrestore(cdev->ccwlock, flags);
663 return -EINVAL; 902 return -EINVAL;
664 mba = mme ? (unsigned long) cmbe_align(cdev->private->cmb) : 0; 903 }
904 cmb_data = cdev->private->cmb;
905 mba = mme ? (unsigned long) cmbe_align(cmb_data->hw_block) : 0;
906 spin_unlock_irqrestore(cdev->ccwlock, flags);
665 907
666 return set_schib_wait(cdev, mme, 1, mba); 908 return set_schib_wait(cdev, mme, 1, mba);
667} 909}
668 910
669 911
670u64 912static u64 read_cmbe (struct ccw_device *cdev, int index)
671read_cmbe (struct ccw_device *cdev, int index)
672{ 913{
673 /* yes, we have to put it on the stack 914 struct cmbe *cmb;
674 * because the cmb must only be accessed 915 struct cmb_data *cmb_data;
675 * atomically, e.g. with mvc */
676 struct cmbe cmb;
677 unsigned long flags;
678 u32 val; 916 u32 val;
917 int ret;
918 unsigned long flags;
679 919
680 spin_lock_irqsave(cdev->ccwlock, flags); 920 ret = cmf_cmb_copy_wait(cdev);
681 if (!cdev->private->cmb) { 921 if (ret < 0)
682 spin_unlock_irqrestore(cdev->ccwlock, flags);
683 return 0; 922 return 0;
684 }
685 923
686 cmb = *cmbe_align(cdev->private->cmb); 924 spin_lock_irqsave(cdev->ccwlock, flags);
687 spin_unlock_irqrestore(cdev->ccwlock, flags); 925 cmb_data = cdev->private->cmb;
926 if (!cmb_data) {
927 ret = 0;
928 goto out;
929 }
930 cmb = cmb_data->last_block;
688 931
689 switch (index) { 932 switch (index) {
690 case cmb_ssch_rsch_count: 933 case cmb_ssch_rsch_count:
691 return cmb.ssch_rsch_count; 934 ret = cmb->ssch_rsch_count;
935 goto out;
692 case cmb_sample_count: 936 case cmb_sample_count:
693 return cmb.sample_count; 937 ret = cmb->sample_count;
938 goto out;
694 case cmb_device_connect_time: 939 case cmb_device_connect_time:
695 val = cmb.device_connect_time; 940 val = cmb->device_connect_time;
696 break; 941 break;
697 case cmb_function_pending_time: 942 case cmb_function_pending_time:
698 val = cmb.function_pending_time; 943 val = cmb->function_pending_time;
699 break; 944 break;
700 case cmb_device_disconnect_time: 945 case cmb_device_disconnect_time:
701 val = cmb.device_disconnect_time; 946 val = cmb->device_disconnect_time;
702 break; 947 break;
703 case cmb_control_unit_queuing_time: 948 case cmb_control_unit_queuing_time:
704 val = cmb.control_unit_queuing_time; 949 val = cmb->control_unit_queuing_time;
705 break; 950 break;
706 case cmb_device_active_only_time: 951 case cmb_device_active_only_time:
707 val = cmb.device_active_only_time; 952 val = cmb->device_active_only_time;
708 break; 953 break;
709 case cmb_device_busy_time: 954 case cmb_device_busy_time:
710 val = cmb.device_busy_time; 955 val = cmb->device_busy_time;
711 break; 956 break;
712 case cmb_initial_command_response_time: 957 case cmb_initial_command_response_time:
713 val = cmb.initial_command_response_time; 958 val = cmb->initial_command_response_time;
714 break; 959 break;
715 default: 960 default:
716 return 0; 961 ret = 0;
962 goto out;
717 } 963 }
718 return time_to_avg_nsec(val, cmb.sample_count); 964 ret = time_to_avg_nsec(val, cmb->sample_count);
965out:
966 spin_unlock_irqrestore(cdev->ccwlock, flags);
967 return ret;
719} 968}
720 969
721static int 970static int readall_cmbe (struct ccw_device *cdev, struct cmbdata *data)
722readall_cmbe (struct ccw_device *cdev, struct cmbdata *data)
723{ 971{
724 /* yes, we have to put it on the stack 972 struct cmbe *cmb;
725 * because the cmb must only be accessed 973 struct cmb_data *cmb_data;
726 * atomically, e.g. with mvc */
727 struct cmbe cmb;
728 unsigned long flags;
729 u64 time; 974 u64 time;
975 unsigned long flags;
976 int ret;
730 977
978 ret = cmf_cmb_copy_wait(cdev);
979 if (ret < 0)
980 return ret;
731 spin_lock_irqsave(cdev->ccwlock, flags); 981 spin_lock_irqsave(cdev->ccwlock, flags);
732 if (!cdev->private->cmb) { 982 cmb_data = cdev->private->cmb;
733 spin_unlock_irqrestore(cdev->ccwlock, flags); 983 if (!cmb_data) {
734 return -ENODEV; 984 ret = -ENODEV;
985 goto out;
735 } 986 }
736 987 if (cmb_data->last_update == 0) {
737 cmb = *cmbe_align(cdev->private->cmb); 988 ret = -EAGAIN;
738 time = get_clock() - cdev->private->cmb_start_time; 989 goto out;
739 spin_unlock_irqrestore(cdev->ccwlock, flags); 990 }
991 time = cmb_data->last_update - cdev->private->cmb_start_time;
740 992
741 memset (data, 0, sizeof(struct cmbdata)); 993 memset (data, 0, sizeof(struct cmbdata));
742 994
@@ -746,35 +998,38 @@ readall_cmbe (struct ccw_device *cdev, struct cmbdata *data)
746 /* conver to nanoseconds */ 998 /* conver to nanoseconds */
747 data->elapsed_time = (time * 1000) >> 12; 999 data->elapsed_time = (time * 1000) >> 12;
748 1000
1001 cmb = cmb_data->last_block;
749 /* copy data to new structure */ 1002 /* copy data to new structure */
750 data->ssch_rsch_count = cmb.ssch_rsch_count; 1003 data->ssch_rsch_count = cmb->ssch_rsch_count;
751 data->sample_count = cmb.sample_count; 1004 data->sample_count = cmb->sample_count;
752 1005
753 /* time fields are converted to nanoseconds while copying */ 1006 /* time fields are converted to nanoseconds while copying */
754 data->device_connect_time = time_to_nsec(cmb.device_connect_time); 1007 data->device_connect_time = time_to_nsec(cmb->device_connect_time);
755 data->function_pending_time = time_to_nsec(cmb.function_pending_time); 1008 data->function_pending_time = time_to_nsec(cmb->function_pending_time);
756 data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); 1009 data->device_disconnect_time =
1010 time_to_nsec(cmb->device_disconnect_time);
757 data->control_unit_queuing_time 1011 data->control_unit_queuing_time
758 = time_to_nsec(cmb.control_unit_queuing_time); 1012 = time_to_nsec(cmb->control_unit_queuing_time);
759 data->device_active_only_time 1013 data->device_active_only_time
760 = time_to_nsec(cmb.device_active_only_time); 1014 = time_to_nsec(cmb->device_active_only_time);
761 data->device_busy_time = time_to_nsec(cmb.device_busy_time); 1015 data->device_busy_time = time_to_nsec(cmb->device_busy_time);
762 data->initial_command_response_time 1016 data->initial_command_response_time
763 = time_to_nsec(cmb.initial_command_response_time); 1017 = time_to_nsec(cmb->initial_command_response_time);
764 1018
765 return 0; 1019 ret = 0;
1020out:
1021 spin_unlock_irqrestore(cdev->ccwlock, flags);
1022 return ret;
766} 1023}
767 1024
768static void 1025static void reset_cmbe(struct ccw_device *cdev)
769reset_cmbe(struct ccw_device *cdev)
770{ 1026{
771 struct cmbe *cmb; 1027 cmf_generic_reset(cdev);
772 spin_lock_irq(cdev->ccwlock); 1028}
773 cmb = cmbe_align(cdev->private->cmb); 1029
774 if (cmb) 1030static void * align_cmbe(void *area)
775 memset (cmb, 0, sizeof (*cmb)); 1031{
776 cdev->private->cmb_start_time = get_clock(); 1032 return cmbe_align(area);
777 spin_unlock_irq(cdev->ccwlock);
778} 1033}
779 1034
780static struct attribute_group cmf_attr_group_ext; 1035static struct attribute_group cmf_attr_group_ext;
@@ -786,6 +1041,7 @@ static struct cmb_operations cmbops_extended = {
786 .read = read_cmbe, 1041 .read = read_cmbe,
787 .readall = readall_cmbe, 1042 .readall = readall_cmbe,
788 .reset = reset_cmbe, 1043 .reset = reset_cmbe,
1044 .align = align_cmbe,
789 .attr_group = &cmf_attr_group_ext, 1045 .attr_group = &cmf_attr_group_ext,
790}; 1046};
791 1047
@@ -803,14 +1059,19 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr,
803 struct ccw_device *cdev; 1059 struct ccw_device *cdev;
804 long interval; 1060 long interval;
805 unsigned long count; 1061 unsigned long count;
1062 struct cmb_data *cmb_data;
806 1063
807 cdev = to_ccwdev(dev); 1064 cdev = to_ccwdev(dev);
808 interval = get_clock() - cdev->private->cmb_start_time;
809 count = cmf_read(cdev, cmb_sample_count); 1065 count = cmf_read(cdev, cmb_sample_count);
810 if (count) 1066 spin_lock_irq(cdev->ccwlock);
1067 cmb_data = cdev->private->cmb;
1068 if (count) {
1069 interval = cmb_data->last_update -
1070 cdev->private->cmb_start_time;
811 interval /= count; 1071 interval /= count;
812 else 1072 } else
813 interval = -1; 1073 interval = -1;
1074 spin_unlock_irq(cdev->ccwlock);
814 return sprintf(buf, "%ld\n", interval); 1075 return sprintf(buf, "%ld\n", interval);
815} 1076}
816 1077
@@ -823,7 +1084,10 @@ cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char
823 int ret; 1084 int ret;
824 1085
825 ret = cmf_readall(to_ccwdev(dev), &data); 1086 ret = cmf_readall(to_ccwdev(dev), &data);
826 if (ret) 1087 if (ret == -EAGAIN || ret == -ENODEV)
1088 /* No data (yet/currently) available to use for calculation. */
1089 return sprintf(buf, "n/a\n");
1090 else if (ret)
827 return ret; 1091 return ret;
828 1092
829 utilization = data.device_connect_time + 1093 utilization = data.device_connect_time +
@@ -982,6 +1246,13 @@ cmf_readall(struct ccw_device *cdev, struct cmbdata *data)
982 return cmbops->readall(cdev, data); 1246 return cmbops->readall(cdev, data);
983} 1247}
984 1248
1249/* Reenable cmf when a disconnected device becomes available again. */
1250int cmf_reenable(struct ccw_device *cdev)
1251{
1252 cmbops->reset(cdev);
1253 return cmbops->set(cdev, 2);
1254}
1255
985static int __init 1256static int __init
986init_cmf(void) 1257init_cmf(void)
987{ 1258{
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 74ea8aac4b7d..1d3be80797f8 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -19,9 +19,11 @@
19#include "cio_debug.h" 19#include "cio_debug.h"
20#include "ioasm.h" 20#include "ioasm.h"
21#include "chsc.h" 21#include "chsc.h"
22#include "device.h"
22 23
23int need_rescan = 0; 24int need_rescan = 0;
24int css_init_done = 0; 25int css_init_done = 0;
26static int need_reprobe = 0;
25static int max_ssid = 0; 27static int max_ssid = 0;
26 28
27struct channel_subsystem *css[__MAX_CSSID + 1]; 29struct channel_subsystem *css[__MAX_CSSID + 1];
@@ -339,6 +341,67 @@ typedef void (*workfunc)(void *);
339DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); 341DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL);
340struct workqueue_struct *slow_path_wq; 342struct workqueue_struct *slow_path_wq;
341 343
344/* Reprobe subchannel if unregistered. */
345static int reprobe_subchannel(struct subchannel_id schid, void *data)
346{
347 struct subchannel *sch;
348 int ret;
349
350 CIO_DEBUG(KERN_INFO, 6, "cio: reprobe 0.%x.%04x\n",
351 schid.ssid, schid.sch_no);
352 if (need_reprobe)
353 return -EAGAIN;
354
355 sch = get_subchannel_by_schid(schid);
356 if (sch) {
357 /* Already known. */
358 put_device(&sch->dev);
359 return 0;
360 }
361
362 ret = css_probe_device(schid);
363 switch (ret) {
364 case 0:
365 break;
366 case -ENXIO:
367 case -ENOMEM:
368 /* These should abort looping */
369 break;
370 default:
371 ret = 0;
372 }
373
374 return ret;
375}
376
377/* Work function used to reprobe all unregistered subchannels. */
378static void reprobe_all(void *data)
379{
380 int ret;
381
382 CIO_MSG_EVENT(2, "reprobe start\n");
383
384 need_reprobe = 0;
385 /* Make sure initial subchannel scan is done. */
386 wait_event(ccw_device_init_wq,
387 atomic_read(&ccw_device_init_count) == 0);
388 ret = for_each_subchannel(reprobe_subchannel, NULL);
389
390 CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
391 need_reprobe);
392}
393
394DECLARE_WORK(css_reprobe_work, reprobe_all, NULL);
395
396/* Schedule reprobing of all unregistered subchannels. */
397void css_schedule_reprobe(void)
398{
399 need_reprobe = 1;
400 queue_work(ccw_device_work, &css_reprobe_work);
401}
402
403EXPORT_SYMBOL_GPL(css_schedule_reprobe);
404
342/* 405/*
343 * Rescan for new devices. FIXME: This is slow. 406 * Rescan for new devices. FIXME: This is slow.
344 * This function is called when we have lost CRWs due to overflows and we have 407 * This function is called when we have lost CRWs due to overflows and we have
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 8e3053c2a451..eafde43e8410 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -133,8 +133,8 @@ struct css_driver io_subchannel_driver = {
133 133
134struct workqueue_struct *ccw_device_work; 134struct workqueue_struct *ccw_device_work;
135struct workqueue_struct *ccw_device_notify_work; 135struct workqueue_struct *ccw_device_notify_work;
136static wait_queue_head_t ccw_device_init_wq; 136wait_queue_head_t ccw_device_init_wq;
137static atomic_t ccw_device_init_count; 137atomic_t ccw_device_init_count;
138 138
139static int __init 139static int __init
140init_ccw_bus_type (void) 140init_ccw_bus_type (void)
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 11587ebb7289..00be9a5b4acd 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -1,6 +1,10 @@
1#ifndef S390_DEVICE_H 1#ifndef S390_DEVICE_H
2#define S390_DEVICE_H 2#define S390_DEVICE_H
3 3
4#include <asm/ccwdev.h>
5#include <asm/atomic.h>
6#include <linux/wait.h>
7
4/* 8/*
5 * states of the device statemachine 9 * states of the device statemachine
6 */ 10 */
@@ -23,6 +27,7 @@ enum dev_state {
23 DEV_STATE_DISCONNECTED, 27 DEV_STATE_DISCONNECTED,
24 DEV_STATE_DISCONNECTED_SENSE_ID, 28 DEV_STATE_DISCONNECTED_SENSE_ID,
25 DEV_STATE_CMFCHANGE, 29 DEV_STATE_CMFCHANGE,
30 DEV_STATE_CMFUPDATE,
26 /* last element! */ 31 /* last element! */
27 NR_DEV_STATES 32 NR_DEV_STATES
28}; 33};
@@ -67,6 +72,8 @@ dev_fsm_final_state(struct ccw_device *cdev)
67 72
68extern struct workqueue_struct *ccw_device_work; 73extern struct workqueue_struct *ccw_device_work;
69extern struct workqueue_struct *ccw_device_notify_work; 74extern struct workqueue_struct *ccw_device_notify_work;
75extern wait_queue_head_t ccw_device_init_wq;
76extern atomic_t ccw_device_init_count;
70 77
71void io_subchannel_recog_done(struct ccw_device *cdev); 78void io_subchannel_recog_done(struct ccw_device *cdev);
72 79
@@ -112,5 +119,8 @@ int ccw_device_stlck(struct ccw_device *);
112void ccw_device_set_timeout(struct ccw_device *, int); 119void ccw_device_set_timeout(struct ccw_device *, int);
113extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); 120extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *);
114 121
122/* Channel measurement facility related */
115void retry_set_schib(struct ccw_device *cdev); 123void retry_set_schib(struct ccw_device *cdev);
124void cmf_retry_copy_block(struct ccw_device *);
125int cmf_reenable(struct ccw_device *);
116#endif 126#endif
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 49ec562d7f60..7d0dd72635eb 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -336,8 +336,11 @@ ccw_device_oper_notify(void *data)
336 if (!ret) 336 if (!ret)
337 /* Driver doesn't want device back. */ 337 /* Driver doesn't want device back. */
338 ccw_device_do_unreg_rereg((void *)cdev); 338 ccw_device_do_unreg_rereg((void *)cdev);
339 else 339 else {
340 /* Reenable channel measurements, if needed. */
341 cmf_reenable(cdev);
340 wake_up(&cdev->private->wait_q); 342 wake_up(&cdev->private->wait_q);
343 }
341} 344}
342 345
343/* 346/*
@@ -861,6 +864,8 @@ ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event)
861 irb = (struct irb *) __LC_IRB; 864 irb = (struct irb *) __LC_IRB;
862 /* Accumulate status. We don't do basic sense. */ 865 /* Accumulate status. We don't do basic sense. */
863 ccw_device_accumulate_irb(cdev, irb); 866 ccw_device_accumulate_irb(cdev, irb);
867 /* Remember to clear irb to avoid residuals. */
868 memset(&cdev->private->irb, 0, sizeof(struct irb));
864 /* Try to start delayed device verification. */ 869 /* Try to start delayed device verification. */
865 ccw_device_online_verify(cdev, 0); 870 ccw_device_online_verify(cdev, 0);
866 /* Note: Don't call handler for cio initiated clear! */ 871 /* Note: Don't call handler for cio initiated clear! */
@@ -1093,6 +1098,13 @@ ccw_device_change_cmfstate(struct ccw_device *cdev, enum dev_event dev_event)
1093 dev_fsm_event(cdev, dev_event); 1098 dev_fsm_event(cdev, dev_event);
1094} 1099}
1095 1100
1101static void ccw_device_update_cmfblock(struct ccw_device *cdev,
1102 enum dev_event dev_event)
1103{
1104 cmf_retry_copy_block(cdev);
1105 cdev->private->state = DEV_STATE_ONLINE;
1106 dev_fsm_event(cdev, dev_event);
1107}
1096 1108
1097static void 1109static void
1098ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) 1110ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event)
@@ -1247,6 +1259,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
1247 [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, 1259 [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate,
1248 [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, 1260 [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate,
1249 }, 1261 },
1262 [DEV_STATE_CMFUPDATE] = {
1263 [DEV_EVENT_NOTOPER] = ccw_device_update_cmfblock,
1264 [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock,
1265 [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock,
1266 [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock,
1267 },
1250}; 1268};
1251 1269
1252/* 1270/*
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 795abb5a65ba..b266ad8e14ff 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -78,7 +78,8 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
78 return -ENODEV; 78 return -ENODEV;
79 if (cdev->private->state == DEV_STATE_NOT_OPER) 79 if (cdev->private->state == DEV_STATE_NOT_OPER)
80 return -ENODEV; 80 return -ENODEV;
81 if (cdev->private->state == DEV_STATE_VERIFY) { 81 if (cdev->private->state == DEV_STATE_VERIFY ||
82 cdev->private->state == DEV_STATE_CLEAR_VERIFY) {
82 /* Remember to fake irb when finished. */ 83 /* Remember to fake irb when finished. */
83 if (!cdev->private->flags.fake_irb) { 84 if (!cdev->private->flags.fake_irb) {
84 cdev->private->flags.fake_irb = 1; 85 cdev->private->flags.fake_irb = 1;
@@ -270,7 +271,8 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
270 * We didn't get channel end / device end. Check if path 271 * We didn't get channel end / device end. Check if path
271 * verification has been started; we can retry after it has 272 * verification has been started; we can retry after it has
272 * finished. We also retry unit checks except for command reject 273 * finished. We also retry unit checks except for command reject
273 * or intervention required. 274 * or intervention required. Also check for long busy
275 * conditions.
274 */ 276 */
275 if (cdev->private->flags.doverify || 277 if (cdev->private->flags.doverify ||
276 cdev->private->state == DEV_STATE_VERIFY) 278 cdev->private->state == DEV_STATE_VERIFY)
@@ -279,6 +281,10 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
279 !(irb->ecw[0] & 281 !(irb->ecw[0] &
280 (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) 282 (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)))
281 cdev->private->intparm = -EAGAIN; 283 cdev->private->intparm = -EAGAIN;
284 else if ((irb->scsw.dstat & DEV_STAT_ATTENTION) &&
285 (irb->scsw.dstat & DEV_STAT_DEV_END) &&
286 (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP))
287 cdev->private->intparm = -EAGAIN;
282 else 288 else
283 cdev->private->intparm = -EIO; 289 cdev->private->intparm = -EIO;
284 290
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index f99e55308b32..8dc75002acbe 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -14,6 +14,7 @@
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/workqueue.h> 15#include <linux/workqueue.h>
16#include <linux/time.h> 16#include <linux/time.h>
17#include <linux/kthread.h>
17 18
18#include <asm/lowcore.h> 19#include <asm/lowcore.h>
19 20
@@ -56,8 +57,6 @@ s390_collect_crw_info(void *param)
56 unsigned int chain; 57 unsigned int chain;
57 58
58 sem = (struct semaphore *)param; 59 sem = (struct semaphore *)param;
59 /* Set a nice name. */
60 daemonize("kmcheck");
61repeat: 60repeat:
62 down_interruptible(sem); 61 down_interruptible(sem);
63 slow = 0; 62 slow = 0;
@@ -516,7 +515,7 @@ arch_initcall(machine_check_init);
516static int __init 515static int __init
517machine_check_crw_init (void) 516machine_check_crw_init (void)
518{ 517{
519 kernel_thread(s390_collect_crw_info, &m_sem, CLONE_FS|CLONE_FILES); 518 kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
520 ctl_set_bit(14, 28); /* enable channel report MCH */ 519 ctl_set_bit(14, 28); /* enable channel report MCH */
521 return 0; 520 return 0;
522} 521}
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index 4d2b126ba159..0ddcdba79e4a 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -12,6 +12,9 @@
12 * Copyright (C) 1992, Linus Torvalds 12 * Copyright (C) 1992, Linus Torvalds
13 * 13 *
14 */ 14 */
15
16#ifdef __KERNEL__
17
15#include <linux/compiler.h> 18#include <linux/compiler.h>
16 19
17/* 20/*
@@ -50,19 +53,6 @@
50 * with operation of the form "set_bit(bitnr, flags)". 53 * with operation of the form "set_bit(bitnr, flags)".
51 */ 54 */
52 55
53/* set ALIGN_CS to 1 if the SMP safe bit operations should
54 * align the address to 4 byte boundary. It seems to work
55 * without the alignment.
56 */
57#ifdef __KERNEL__
58#define ALIGN_CS 0
59#else
60#define ALIGN_CS 1
61#ifndef CONFIG_SMP
62#error "bitops won't work without CONFIG_SMP"
63#endif
64#endif
65
66/* bitmap tables from arch/S390/kernel/bitmap.S */ 56/* bitmap tables from arch/S390/kernel/bitmap.S */
67extern const char _oi_bitmap[]; 57extern const char _oi_bitmap[];
68extern const char _ni_bitmap[]; 58extern const char _ni_bitmap[];
@@ -121,10 +111,6 @@ static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
121 unsigned long addr, old, new, mask; 111 unsigned long addr, old, new, mask;
122 112
123 addr = (unsigned long) ptr; 113 addr = (unsigned long) ptr;
124#if ALIGN_CS == 1
125 nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
126 addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
127#endif
128 /* calculate address for CS */ 114 /* calculate address for CS */
129 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; 115 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
130 /* make OR mask */ 116 /* make OR mask */
@@ -141,10 +127,6 @@ static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
141 unsigned long addr, old, new, mask; 127 unsigned long addr, old, new, mask;
142 128
143 addr = (unsigned long) ptr; 129 addr = (unsigned long) ptr;
144#if ALIGN_CS == 1
145 nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
146 addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
147#endif
148 /* calculate address for CS */ 130 /* calculate address for CS */
149 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; 131 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
150 /* make AND mask */ 132 /* make AND mask */
@@ -161,10 +143,6 @@ static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
161 unsigned long addr, old, new, mask; 143 unsigned long addr, old, new, mask;
162 144
163 addr = (unsigned long) ptr; 145 addr = (unsigned long) ptr;
164#if ALIGN_CS == 1
165 nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
166 addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
167#endif
168 /* calculate address for CS */ 146 /* calculate address for CS */
169 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; 147 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
170 /* make XOR mask */ 148 /* make XOR mask */
@@ -182,10 +160,6 @@ test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
182 unsigned long addr, old, new, mask; 160 unsigned long addr, old, new, mask;
183 161
184 addr = (unsigned long) ptr; 162 addr = (unsigned long) ptr;
185#if ALIGN_CS == 1
186 nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
187 addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
188#endif
189 /* calculate address for CS */ 163 /* calculate address for CS */
190 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; 164 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
191 /* make OR/test mask */ 165 /* make OR/test mask */
@@ -205,10 +179,6 @@ test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
205 unsigned long addr, old, new, mask; 179 unsigned long addr, old, new, mask;
206 180
207 addr = (unsigned long) ptr; 181 addr = (unsigned long) ptr;
208#if ALIGN_CS == 1
209 nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
210 addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
211#endif
212 /* calculate address for CS */ 182 /* calculate address for CS */
213 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; 183 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
214 /* make AND/test mask */ 184 /* make AND/test mask */
@@ -228,10 +198,6 @@ test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
228 unsigned long addr, old, new, mask; 198 unsigned long addr, old, new, mask;
229 199
230 addr = (unsigned long) ptr; 200 addr = (unsigned long) ptr;
231#if ALIGN_CS == 1
232 nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
233 addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
234#endif
235 /* calculate address for CS */ 201 /* calculate address for CS */
236 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; 202 addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
237 /* make XOR/test mask */ 203 /* make XOR/test mask */
@@ -834,8 +800,6 @@ static inline int sched_find_first_bit(unsigned long *b)
834 800
835#include <asm-generic/bitops/hweight.h> 801#include <asm-generic/bitops/hweight.h>
836 802
837#ifdef __KERNEL__
838
839/* 803/*
840 * ATTENTION: intel byte ordering convention for ext2 and minix !! 804 * ATTENTION: intel byte ordering convention for ext2 and minix !!
841 * bit 0 is the LSB of addr; bit 31 is the MSB of addr; 805 * bit 0 is the LSB of addr; bit 31 is the MSB of addr;
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h
index 089cf567c317..2b1619306351 100644
--- a/include/asm-s390/cio.h
+++ b/include/asm-s390/cio.h
@@ -276,6 +276,8 @@ extern void wait_cons_dev(void);
276 276
277extern void clear_all_subchannels(void); 277extern void clear_all_subchannels(void);
278 278
279extern void css_schedule_reprobe(void);
280
279#endif 281#endif
280 282
281#endif 283#endif
diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h
index 2d09950a9c11..241756f80df3 100644
--- a/include/asm-s390/cmb.h
+++ b/include/asm-s390/cmb.h
@@ -44,10 +44,6 @@ struct cmbdata {
44#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER,32) 44#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER,32)
45/* enable channel measurement */ 45/* enable channel measurement */
46#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER,33) 46#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER,33)
47/* reset channel measurement block */
48#define BIODASDRESETCMB _IO(DASD_IOCTL_LETTER,34)
49/* read channel measurement data */
50#define BIODASDREADCMB _IOWR(DASD_IOCTL_LETTER,32,__u64)
51/* read channel measurement data */ 47/* read channel measurement data */
52#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) 48#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata)
53 49
diff --git a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h
index 1630c26e8f45..c042f9578081 100644
--- a/include/asm-s390/dasd.h
+++ b/include/asm-s390/dasd.h
@@ -68,10 +68,12 @@ typedef struct dasd_information2_t {
68 * 0x00: default features 68 * 0x00: default features
69 * 0x01: readonly (ro) 69 * 0x01: readonly (ro)
70 * 0x02: use diag discipline (diag) 70 * 0x02: use diag discipline (diag)
71 * 0x04: set the device initially online (internal use only)
71 */ 72 */
72#define DASD_FEATURE_DEFAULT 0 73#define DASD_FEATURE_DEFAULT 0x00
73#define DASD_FEATURE_READONLY 1 74#define DASD_FEATURE_READONLY 0x01
74#define DASD_FEATURE_USEDIAG 2 75#define DASD_FEATURE_USEDIAG 0x02
76#define DASD_FEATURE_INITIAL_ONLINE 0x04
75 77
76#define DASD_PARTN_BITS 2 78#define DASD_PARTN_BITS 2
77 79
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h
index 8e0c7ed73d03..0a518915bf90 100644
--- a/include/asm-s390/thread_info.h
+++ b/include/asm-s390/thread_info.h
@@ -63,6 +63,7 @@ struct thread_info {
63 .exec_domain = &default_exec_domain, \ 63 .exec_domain = &default_exec_domain, \
64 .flags = 0, \ 64 .flags = 0, \
65 .cpu = 0, \ 65 .cpu = 0, \
66 .preempt_count = 1, \
66 .restart_block = { \ 67 .restart_block = { \
67 .fn = do_no_restart_syscall, \ 68 .fn = do_no_restart_syscall, \
68 }, \ 69 }, \
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index e21443d3ea1d..aa7a243862e1 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -394,11 +394,9 @@
394 394
395#ifdef __KERNEL__ 395#ifdef __KERNEL__
396 396
397/* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
398
399#define __syscall_return(type, res) \ 397#define __syscall_return(type, res) \
400do { \ 398do { \
401 if ((unsigned long)(res) >= (unsigned long)(-125)) { \ 399 if ((unsigned long)(res) >= (unsigned long)(-4095)) {\
402 errno = -(res); \ 400 errno = -(res); \
403 res = -1; \ 401 res = -1; \
404 } \ 402 } \