aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-13 16:16:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-13 16:16:16 -0500
commitcbd88cd4c07f9361914ab7fd7e21c9227986fe68 (patch)
tree8bc448d73f93f10ebd34ef38c911b06359000ed0 /drivers/s390
parent928b3f12e5fea9d201bbc029d8d537ba7cc14fe7 (diff)
parentc2ab7282f0fcd11eea4d0ba45d1c65d89428c314 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "Among the traditional bug fixes and cleanups are some improvements: - A tool to generated the facility lists, generating the bit fields by hand has been a source of bugs in the past - The spinlock loop is reordered to avoid bursts of hypervisor calls - Add support for the open-for-business interface to the service element - The get_cpu call is added to the vdso - A set of tracepoints is defined for the common I/O layer - The deprecated sclp_cpi module is removed - Update default configuration" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (56 commits) s390/sclp: fix possible control register corruption s390: fix normalization bug in exception table sorting s390/configs: update default configurations s390/vdso: optimize getcpu system call s390: drop smp_mb in vdso_init s390: rename struct _lowcore to struct lowcore s390/mem_detect: use unsigned longs s390/ptrace: get rid of long longs in psw_bits s390/sysinfo: add missing SYSIB 1.2.2 multithreading fields s390: get rid of CONFIG_SCHED_MC and CONFIG_SCHED_BOOK s390/Kconfig: remove pointless 64 bit dependencies s390/dasd: fix failfast for disconnected devices s390/con3270: testing return kzalloc retval s390/hmcdrv: constify hmcdrv_ftp_ops structs s390/cio: add NULL test s390/cio: Change I/O instructions from inline to normal functions s390/cio: Introduce common I/O layer tracepoints s390/cio: Consolidate inline assemblies and related data definitions s390/cio: Fix incorrect xsch opcode specification s390/cio: Remove unused inline assemblies ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c8
-rw-r--r--drivers/s390/char/Kconfig21
-rw-r--r--drivers/s390/char/Makefile5
-rw-r--r--drivers/s390/char/con3215.c2
-rw-r--r--drivers/s390/char/con3270.c2
-rw-r--r--drivers/s390/char/hmcdrv_ftp.c6
-rw-r--r--drivers/s390/char/sclp.c5
-rw-r--r--drivers/s390/char/sclp_config.c102
-rw-r--r--drivers/s390/char/sclp_cpi.c40
-rw-r--r--drivers/s390/char/zcore.c450
-rw-r--r--drivers/s390/cio/Makefile5
-rw-r--r--drivers/s390/cio/airq.c1
-rw-r--r--drivers/s390/cio/chsc_sch.c5
-rw-r--r--drivers/s390/cio/cio.c37
-rw-r--r--drivers/s390/cio/cio.h12
-rw-r--r--drivers/s390/cio/crw.c1
-rw-r--r--drivers/s390/cio/css.c2
-rw-r--r--drivers/s390/cio/device_fsm.c2
-rw-r--r--drivers/s390/cio/io_sch.h45
-rw-r--r--drivers/s390/cio/ioasm.c224
-rw-r--r--drivers/s390/cio/ioasm.h169
-rw-r--r--drivers/s390/cio/qdio_debug.c6
-rw-r--r--drivers/s390/cio/trace.c24
-rw-r--r--drivers/s390/cio/trace.h363
-rw-r--r--drivers/s390/crypto/zcrypt_api.c6
25 files changed, 843 insertions, 700 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index a263c10359e1..41605dac8309 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2556,8 +2556,12 @@ static void __dasd_process_request_queue(struct dasd_block *block)
2556 return; 2556 return;
2557 } 2557 }
2558 2558
2559 /* if device ist stopped do not fetch new requests */ 2559 /*
2560 if (basedev->stopped) 2560 * if device is stopped do not fetch new requests
2561 * except failfast is active which will let requests fail
2562 * immediately in __dasd_block_start_head()
2563 */
2564 if (basedev->stopped && !(basedev->features & DASD_FEATURE_FAILFAST))
2561 return; 2565 return;
2562 2566
2563 /* Now we try to fetch requests from the request queue */ 2567 /* Now we try to fetch requests from the request queue */
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig
index eaca3e006301..b3f1c458905f 100644
--- a/drivers/s390/char/Kconfig
+++ b/drivers/s390/char/Kconfig
@@ -78,19 +78,6 @@ config SCLP_VT220_CONSOLE
78 Include support for using an IBM SCLP VT220-compatible terminal as a 78 Include support for using an IBM SCLP VT220-compatible terminal as a
79 Linux system console. 79 Linux system console.
80 80
81config SCLP_CPI
82 def_tristate m
83 prompt "Control-Program Identification"
84 depends on S390
85 help
86 This option enables the hardware console interface for system
87 identification. This is commonly used for workload management and
88 gives you a nice name for the system on the service element.
89 Please select this option as a module since built-in operation is
90 completely untested.
91 You should only select this option if you know what you are doing,
92 need this feature and intend to run your kernel in LPAR.
93
94config SCLP_ASYNC 81config SCLP_ASYNC
95 def_tristate m 82 def_tristate m
96 prompt "Support for Call Home via Asynchronous SCLP Records" 83 prompt "Support for Call Home via Asynchronous SCLP Records"
@@ -125,6 +112,14 @@ config HMC_DRV
125 transfer cache size from it's default value 0.5MB to N bytes. If N 112 transfer cache size from it's default value 0.5MB to N bytes. If N
126 is zero, then no caching is performed. 113 is zero, then no caching is performed.
127 114
115config SCLP_OFB
116 def_bool n
117 prompt "Support for Open-for-Business SCLP Event"
118 depends on S390
119 help
120 This option enables the Open-for-Business interface to the s390
121 Service Element.
122
128config S390_TAPE 123config S390_TAPE
129 def_tristate m 124 def_tristate m
130 prompt "S/390 tape device support" 125 prompt "S/390 tape device support"
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index 6fa9364d1c07..dd2f7c832e5e 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_TN3215) += con3215.o
16obj-$(CONFIG_SCLP_TTY) += sclp_tty.o 16obj-$(CONFIG_SCLP_TTY) += sclp_tty.o
17obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o 17obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o
18obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o 18obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
19obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
20obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o 19obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o
21 20
22obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o 21obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
@@ -30,9 +29,7 @@ obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o
30obj-$(CONFIG_MONREADER) += monreader.o 29obj-$(CONFIG_MONREADER) += monreader.o
31obj-$(CONFIG_MONWRITER) += monwriter.o 30obj-$(CONFIG_MONWRITER) += monwriter.o
32obj-$(CONFIG_S390_VMUR) += vmur.o 31obj-$(CONFIG_S390_VMUR) += vmur.o
33 32obj-$(CONFIG_CRASH_DUMP) += sclp_sdias.o zcore.o
34zcore_mod-objs := sclp_sdias.o zcore.o
35obj-$(CONFIG_CRASH_DUMP) += zcore_mod.o
36 33
37hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o 34hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o
38obj-$(CONFIG_HMC_DRV) += hmcdrv.o 35obj-$(CONFIG_HMC_DRV) += hmcdrv.o
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 0fc3fe5fd5b8..7d82bbcb12df 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -922,6 +922,8 @@ static int __init con3215_init(void)
922 spin_lock_init(&raw3215_freelist_lock); 922 spin_lock_init(&raw3215_freelist_lock);
923 for (i = 0; i < NR_3215_REQ; i++) { 923 for (i = 0; i < NR_3215_REQ; i++) {
924 req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); 924 req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA);
925 if (!req)
926 return -ENOMEM;
925 req->next = raw3215_freelist; 927 req->next = raw3215_freelist;
926 raw3215_freelist = req; 928 raw3215_freelist = req;
927 } 929 }
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 7c511add5aa7..4d7a9badfede 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -606,6 +606,8 @@ con3270_init(void)
606 return PTR_ERR(rp); 606 return PTR_ERR(rp);
607 607
608 condev = kzalloc(sizeof(struct con3270), GFP_KERNEL | GFP_DMA); 608 condev = kzalloc(sizeof(struct con3270), GFP_KERNEL | GFP_DMA);
609 if (!condev)
610 return -ENOMEM;
609 condev->view.dev = rp; 611 condev->view.dev = rp;
610 612
611 condev->read = raw3270_request_alloc(0); 613 condev->read = raw3270_request_alloc(0);
diff --git a/drivers/s390/char/hmcdrv_ftp.c b/drivers/s390/char/hmcdrv_ftp.c
index d4b61d9088fb..8cb7d8fbadd6 100644
--- a/drivers/s390/char/hmcdrv_ftp.c
+++ b/drivers/s390/char/hmcdrv_ftp.c
@@ -37,7 +37,7 @@ struct hmcdrv_ftp_ops {
37static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len); 37static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len);
38static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp); 38static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp);
39 39
40static struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ 40static const struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */
41static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */ 41static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */
42static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */ 42static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */
43 43
@@ -290,13 +290,13 @@ ssize_t hmcdrv_ftp_cmd(char __kernel *cmd, loff_t offset,
290 */ 290 */
291int hmcdrv_ftp_startup(void) 291int hmcdrv_ftp_startup(void)
292{ 292{
293 static struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = { 293 static const struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = {
294 .startup = diag_ftp_startup, 294 .startup = diag_ftp_startup,
295 .shutdown = diag_ftp_shutdown, 295 .shutdown = diag_ftp_shutdown,
296 .transfer = diag_ftp_cmd 296 .transfer = diag_ftp_cmd
297 }; 297 };
298 298
299 static struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = { 299 static const struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = {
300 .startup = sclp_ftp_startup, 300 .startup = sclp_ftp_startup,
301 .shutdown = sclp_ftp_shutdown, 301 .shutdown = sclp_ftp_shutdown,
302 .transfer = sclp_ftp_cmd 302 .transfer = sclp_ftp_cmd
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index f58bf4c6c3ee..272898225dbb 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -579,9 +579,8 @@ sclp_sync_wait(void)
579 old_tick = local_tick_disable(); 579 old_tick = local_tick_disable();
580 trace_hardirqs_on(); 580 trace_hardirqs_on();
581 __ctl_store(cr0, 0, 0); 581 __ctl_store(cr0, 0, 0);
582 cr0_sync = cr0; 582 cr0_sync = cr0 & ~CR0_IRQ_SUBCLASS_MASK;
583 cr0_sync &= 0xffff00a0; 583 cr0_sync |= 1UL << (63 - 54);
584 cr0_sync |= 0x00000200;
585 __ctl_load(cr0_sync, 0, 0); 584 __ctl_load(cr0_sync, 0, 0);
586 __arch_local_irq_stosm(0x01); 585 __arch_local_irq_stosm(0x01);
587 /* Loop until driver state indicates finished request */ 586 /* Loop until driver state indicates finished request */
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
index 944156207477..2ced50ccca63 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -11,6 +11,8 @@
11#include <linux/cpu.h> 11#include <linux/cpu.h>
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/workqueue.h> 13#include <linux/workqueue.h>
14#include <linux/slab.h>
15#include <linux/sysfs.h>
14#include <asm/smp.h> 16#include <asm/smp.h>
15 17
16#include "sclp.h" 18#include "sclp.h"
@@ -20,8 +22,22 @@ struct conf_mgm_data {
20 u8 ev_qualifier; 22 u8 ev_qualifier;
21} __attribute__((packed)); 23} __attribute__((packed));
22 24
25#define OFB_DATA_MAX 64
26
27struct sclp_ofb_evbuf {
28 struct evbuf_header header;
29 struct conf_mgm_data cm_data;
30 char ev_data[OFB_DATA_MAX];
31} __packed;
32
33struct sclp_ofb_sccb {
34 struct sccb_header header;
35 struct sclp_ofb_evbuf ofb_evbuf;
36} __packed;
37
23#define EV_QUAL_CPU_CHANGE 1 38#define EV_QUAL_CPU_CHANGE 1
24#define EV_QUAL_CAP_CHANGE 3 39#define EV_QUAL_CAP_CHANGE 3
40#define EV_QUAL_OPEN4BUSINESS 5
25 41
26static struct work_struct sclp_cpu_capability_work; 42static struct work_struct sclp_cpu_capability_work;
27static struct work_struct sclp_cpu_change_work; 43static struct work_struct sclp_cpu_change_work;
@@ -63,15 +79,99 @@ static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
63 79
64static struct sclp_register sclp_conf_register = 80static struct sclp_register sclp_conf_register =
65{ 81{
82#ifdef CONFIG_SCLP_OFB
83 .send_mask = EVTYP_CONFMGMDATA_MASK,
84#endif
66 .receive_mask = EVTYP_CONFMGMDATA_MASK, 85 .receive_mask = EVTYP_CONFMGMDATA_MASK,
67 .receiver_fn = sclp_conf_receiver_fn, 86 .receiver_fn = sclp_conf_receiver_fn,
68}; 87};
69 88
89#ifdef CONFIG_SCLP_OFB
90static int sclp_ofb_send_req(char *ev_data, size_t len)
91{
92 static DEFINE_MUTEX(send_mutex);
93 struct sclp_ofb_sccb *sccb;
94 int rc, response;
95
96 if (len > OFB_DATA_MAX)
97 return -EINVAL;
98 sccb = (struct sclp_ofb_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
99 if (!sccb)
100 return -ENOMEM;
101 /* Setup SCCB for Control-Program Identification */
102 sccb->header.length = sizeof(struct sclp_ofb_sccb);
103 sccb->ofb_evbuf.header.length = sizeof(struct sclp_ofb_evbuf);
104 sccb->ofb_evbuf.header.type = EVTYP_CONFMGMDATA;
105 sccb->ofb_evbuf.cm_data.ev_qualifier = EV_QUAL_OPEN4BUSINESS;
106 memcpy(sccb->ofb_evbuf.ev_data, ev_data, len);
107
108 if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK))
109 pr_warn("SCLP receiver did not register to receive "
110 "Configuration Management Data Events.\n");
111
112 mutex_lock(&send_mutex);
113 rc = sclp_sync_request(SCLP_CMDW_WRITE_EVENT_DATA, sccb);
114 mutex_unlock(&send_mutex);
115 if (rc)
116 goto out;
117 response = sccb->header.response_code;
118 if (response != 0x0020) {
119 pr_err("Open for Business request failed with response code "
120 "0x%04x\n", response);
121 rc = -EIO;
122 }
123out:
124 free_page((unsigned long)sccb);
125 return rc;
126}
127
128static ssize_t sysfs_ofb_data_write(struct file *filp, struct kobject *kobj,
129 struct bin_attribute *bin_attr,
130 char *buf, loff_t off, size_t count)
131{
132 int rc;
133
134 rc = sclp_ofb_send_req(buf, count);
135 return rc ?: count;
136}
137
138static struct bin_attribute ofb_bin_attr = {
139 .attr = {
140 .name = "event_data",
141 .mode = S_IWUSR,
142 },
143 .write = sysfs_ofb_data_write,
144};
145#endif
146
147static int __init sclp_ofb_setup(void)
148{
149#ifdef CONFIG_SCLP_OFB
150 struct kset *ofb_kset;
151 int rc;
152
153 ofb_kset = kset_create_and_add("ofb", NULL, firmware_kobj);
154 if (!ofb_kset)
155 return -ENOMEM;
156 rc = sysfs_create_bin_file(&ofb_kset->kobj, &ofb_bin_attr);
157 if (rc) {
158 kset_unregister(ofb_kset);
159 return rc;
160 }
161#endif
162 return 0;
163}
164
70static int __init sclp_conf_init(void) 165static int __init sclp_conf_init(void)
71{ 166{
167 int rc;
168
72 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); 169 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
73 INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); 170 INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
74 return sclp_register(&sclp_conf_register); 171 rc = sclp_register(&sclp_conf_register);
172 if (rc)
173 return rc;
174 return sclp_ofb_setup();
75} 175}
76 176
77__initcall(sclp_conf_init); 177__initcall(sclp_conf_init);
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
deleted file mode 100644
index d70d8c20229c..000000000000
--- a/drivers/s390/char/sclp_cpi.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * SCLP control programm identification
3 *
4 * Copyright IBM Corp. 2001, 2007
5 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
6 * Michael Ernst <mernst@de.ibm.com>
7 */
8
9#include <linux/kmod.h>
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/version.h>
13#include "sclp_cpi_sys.h"
14
15MODULE_LICENSE("GPL");
16MODULE_DESCRIPTION("Identify this operating system instance "
17 "to the System z hardware");
18MODULE_AUTHOR("Martin Peschke <mpeschke@de.ibm.com>, "
19 "Michael Ernst <mernst@de.ibm.com>");
20
21static char *system_name = "";
22static char *sysplex_name = "";
23
24module_param(system_name, charp, 0);
25MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters");
26module_param(sysplex_name, charp, 0);
27MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters");
28
29static int __init cpi_module_init(void)
30{
31 return sclp_cpi_set_data(system_name, sysplex_name, "LINUX",
32 LINUX_VERSION_CODE);
33}
34
35static void __exit cpi_module_exit(void)
36{
37}
38
39module_init(cpi_module_init);
40module_exit(cpi_module_exit);
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 3339b862ec17..5043ecfa1fbc 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -28,13 +28,12 @@
28#include <asm/processor.h> 28#include <asm/processor.h>
29#include <asm/irqflags.h> 29#include <asm/irqflags.h>
30#include <asm/checksum.h> 30#include <asm/checksum.h>
31#include <asm/os_info.h>
31#include <asm/switch_to.h> 32#include <asm/switch_to.h>
32#include "sclp.h" 33#include "sclp.h"
33 34
34#define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x) 35#define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
35 36
36#define TO_USER 1
37#define TO_KERNEL 0
38#define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */ 37#define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */
39 38
40enum arch_id { 39enum arch_id {
@@ -42,241 +41,93 @@ enum arch_id {
42 ARCH_S390X = 1, 41 ARCH_S390X = 1,
43}; 42};
44 43
45/* dump system info */
46
47struct sys_info {
48 enum arch_id arch;
49 unsigned long sa_base;
50 u32 sa_size;
51 int cpu_map[NR_CPUS];
52 unsigned long mem_size;
53 struct save_area lc_mask;
54};
55
56struct ipib_info { 44struct ipib_info {
57 unsigned long ipib; 45 unsigned long ipib;
58 u32 checksum; 46 u32 checksum;
59} __attribute__((packed)); 47} __attribute__((packed));
60 48
61static struct sys_info sys_info;
62static struct debug_info *zcore_dbf; 49static struct debug_info *zcore_dbf;
63static int hsa_available; 50static int hsa_available;
64static struct dentry *zcore_dir; 51static struct dentry *zcore_dir;
65static struct dentry *zcore_file;
66static struct dentry *zcore_memmap_file; 52static struct dentry *zcore_memmap_file;
67static struct dentry *zcore_reipl_file; 53static struct dentry *zcore_reipl_file;
68static struct dentry *zcore_hsa_file; 54static struct dentry *zcore_hsa_file;
69static struct ipl_parameter_block *ipl_block; 55static struct ipl_parameter_block *ipl_block;
70 56
57static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE);
58
71/* 59/*
72 * Copy memory from HSA to kernel or user memory (not reentrant): 60 * Copy memory from HSA to user memory (not reentrant):
73 * 61 *
74 * @dest: Kernel or user buffer where memory should be copied to 62 * @dest: User buffer where memory should be copied to
75 * @src: Start address within HSA where data should be copied 63 * @src: Start address within HSA where data should be copied
76 * @count: Size of buffer, which should be copied 64 * @count: Size of buffer, which should be copied
77 * @mode: Either TO_KERNEL or TO_USER
78 */ 65 */
79int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) 66int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
80{ 67{
81 int offs, blk_num; 68 unsigned long offset, bytes;
82 static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
83 69
84 if (!hsa_available) 70 if (!hsa_available)
85 return -ENODATA; 71 return -ENODATA;
86 if (count == 0)
87 return 0;
88 72
89 /* copy first block */ 73 while (count) {
90 offs = 0; 74 if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
91 if ((src % PAGE_SIZE) != 0) {
92 blk_num = src / PAGE_SIZE + 2;
93 if (sclp_sdias_copy(buf, blk_num, 1)) {
94 TRACE("sclp_sdias_copy() failed\n"); 75 TRACE("sclp_sdias_copy() failed\n");
95 return -EIO; 76 return -EIO;
96 } 77 }
97 offs = min((PAGE_SIZE - (src % PAGE_SIZE)), count); 78 offset = src % PAGE_SIZE;
98 if (mode == TO_USER) { 79 bytes = min(PAGE_SIZE - offset, count);
99 if (copy_to_user((__force __user void*) dest, 80 if (copy_to_user(dest, hsa_buf + offset, bytes))
100 buf + (src % PAGE_SIZE), offs))
101 return -EFAULT;
102 } else
103 memcpy(dest, buf + (src % PAGE_SIZE), offs);
104 }
105 if (offs == count)
106 goto out;
107
108 /* copy middle */
109 for (; (offs + PAGE_SIZE) <= count; offs += PAGE_SIZE) {
110 blk_num = (src + offs) / PAGE_SIZE + 2;
111 if (sclp_sdias_copy(buf, blk_num, 1)) {
112 TRACE("sclp_sdias_copy() failed\n");
113 return -EIO;
114 }
115 if (mode == TO_USER) {
116 if (copy_to_user((__force __user void*) dest + offs,
117 buf, PAGE_SIZE))
118 return -EFAULT;
119 } else
120 memcpy(dest + offs, buf, PAGE_SIZE);
121 }
122 if (offs == count)
123 goto out;
124
125 /* copy last block */
126 blk_num = (src + offs) / PAGE_SIZE + 2;
127 if (sclp_sdias_copy(buf, blk_num, 1)) {
128 TRACE("sclp_sdias_copy() failed\n");
129 return -EIO;
130 }
131 if (mode == TO_USER) {
132 if (copy_to_user((__force __user void*) dest + offs, buf,
133 count - offs))
134 return -EFAULT; 81 return -EFAULT;
135 } else 82 src += bytes;
136 memcpy(dest + offs, buf, count - offs); 83 dest += bytes;
137out: 84 count -= bytes;
138 return 0;
139}
140
141static int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
142{
143 return memcpy_hsa((void __force *) dest, src, count, TO_USER);
144}
145
146static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
147{
148 return memcpy_hsa(dest, src, count, TO_KERNEL);
149}
150
151static int __init init_cpu_info(enum arch_id arch)
152{
153 struct save_area_ext *sa_ext;
154
155 /* get info for boot cpu from lowcore, stored in the HSA */
156
157 sa_ext = dump_save_areas.areas[0];
158 if (!sa_ext)
159 return -ENOMEM;
160 if (memcpy_hsa_kernel(&sa_ext->sa, sys_info.sa_base,
161 sys_info.sa_size) < 0) {
162 TRACE("could not copy from HSA\n");
163 kfree(sa_ext);
164 return -EIO;
165 } 85 }
166 if (MACHINE_HAS_VX)
167 save_vx_regs_safe(sa_ext->vx_regs);
168 return 0; 86 return 0;
169} 87}
170 88
171static DEFINE_MUTEX(zcore_mutex);
172
173#define DUMP_VERSION 0x5
174#define DUMP_MAGIC 0xa8190173618f23fdULL
175#define DUMP_ARCH_S390X 2
176#define DUMP_ARCH_S390 1
177#define HEADER_SIZE 4096
178
179/* dump header dumped according to s390 crash dump format */
180
181struct zcore_header {
182 u64 magic;
183 u32 version;
184 u32 header_size;
185 u32 dump_level;
186 u32 page_size;
187 u64 mem_size;
188 u64 mem_start;
189 u64 mem_end;
190 u32 num_pages;
191 u32 pad1;
192 u64 tod;
193 struct cpuid cpu_id;
194 u32 arch_id;
195 u32 volnr;
196 u32 build_arch;
197 u64 rmem_size;
198 u8 mvdump;
199 u16 cpu_cnt;
200 u16 real_cpu_cnt;
201 u8 end_pad1[0x200-0x061];
202 u64 mvdump_sign;
203 u64 mvdump_zipl_time;
204 u8 end_pad2[0x800-0x210];
205 u32 lc_vec[512];
206} __attribute__((packed,__aligned__(16)));
207
208static struct zcore_header zcore_header = {
209 .magic = DUMP_MAGIC,
210 .version = DUMP_VERSION,
211 .header_size = 4096,
212 .dump_level = 0,
213 .page_size = PAGE_SIZE,
214 .mem_start = 0,
215 .build_arch = DUMP_ARCH_S390X,
216};
217
218/* 89/*
219 * Copy lowcore info to buffer. Use map in order to copy only register parts. 90 * Copy memory from HSA to kernel memory (not reentrant):
220 * 91 *
221 * @buf: User buffer 92 * @dest: Kernel or user buffer where memory should be copied to
222 * @sa: Pointer to save area 93 * @src: Start address within HSA where data should be copied
223 * @sa_off: Offset in save area to copy 94 * @count: Size of buffer, which should be copied
224 * @len: Number of bytes to copy
225 */ 95 */
226static int copy_lc(void __user *buf, void *sa, int sa_off, int len) 96int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
227{ 97{
228 int i; 98 unsigned long offset, bytes;
229 char *lc_mask = (char*)&sys_info.lc_mask;
230 99
231 for (i = 0; i < len; i++) { 100 if (!hsa_available)
232 if (!lc_mask[i + sa_off]) 101 return -ENODATA;
233 continue; 102
234 if (copy_to_user(buf + i, sa + sa_off + i, 1)) 103 while (count) {
235 return -EFAULT; 104 if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
105 TRACE("sclp_sdias_copy() failed\n");
106 return -EIO;
107 }
108 offset = src % PAGE_SIZE;
109 bytes = min(PAGE_SIZE - offset, count);
110 memcpy(dest, hsa_buf + offset, bytes);
111 src += bytes;
112 dest += bytes;
113 count -= bytes;
236 } 114 }
237 return 0; 115 return 0;
238} 116}
239 117
240/* 118static int __init init_cpu_info(void)
241 * Copy lowcores info to memory, if necessary
242 *
243 * @buf: User buffer
244 * @addr: Start address of buffer in dump memory
245 * @count: Size of buffer
246 */
247static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
248{ 119{
249 unsigned long end; 120 struct save_area *sa;
250 int i;
251
252 if (count == 0)
253 return 0;
254 121
255 end = start + count; 122 /* get info for boot cpu from lowcore, stored in the HSA */
256 for (i = 0; i < dump_save_areas.count; i++) { 123 sa = save_area_boot_cpu();
257 unsigned long cp_start, cp_end; /* copy range */ 124 if (!sa)
258 unsigned long sa_start, sa_end; /* save area range */ 125 return -ENOMEM;
259 unsigned long prefix; 126 if (memcpy_hsa_kernel(hsa_buf, __LC_FPREGS_SAVE_AREA, 512) < 0) {
260 unsigned long sa_off, len, buf_off; 127 TRACE("could not copy from HSA\n");
261 struct save_area *save_area = &dump_save_areas.areas[i]->sa; 128 return -EIO;
262
263 prefix = save_area->pref_reg;
264 sa_start = prefix + sys_info.sa_base;
265 sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
266
267 if ((end < sa_start) || (start > sa_end))
268 continue;
269 cp_start = max(start, sa_start);
270 cp_end = min(end, sa_end);
271
272 buf_off = cp_start - start;
273 sa_off = cp_start - sa_start;
274 len = cp_end - cp_start;
275
276 TRACE("copy_lc for: %lx\n", start);
277 if (copy_lc(buf + buf_off, save_area, sa_off, len))
278 return -EFAULT;
279 } 129 }
130 save_area_add_regs(sa, hsa_buf); /* vx registers are saved in smp.c */
280 return 0; 131 return 0;
281} 132}
282 133
@@ -289,115 +140,6 @@ static void release_hsa(void)
289 hsa_available = 0; 140 hsa_available = 0;
290} 141}
291 142
292/*
293 * Read routine for zcore character device
294 * First 4K are dump header
295 * Next 32MB are HSA Memory
296 * Rest is read from absolute Memory
297 */
298static ssize_t zcore_read(struct file *file, char __user *buf, size_t count,
299 loff_t *ppos)
300{
301 unsigned long mem_start; /* Start address in memory */
302 size_t mem_offs; /* Offset in dump memory */
303 size_t hdr_count; /* Size of header part of output buffer */
304 size_t size;
305 int rc;
306
307 mutex_lock(&zcore_mutex);
308
309 if (*ppos > (sys_info.mem_size + HEADER_SIZE)) {
310 rc = -EINVAL;
311 goto fail;
312 }
313
314 count = min(count, (size_t) (sys_info.mem_size + HEADER_SIZE - *ppos));
315
316 /* Copy dump header */
317 if (*ppos < HEADER_SIZE) {
318 size = min(count, (size_t) (HEADER_SIZE - *ppos));
319 if (copy_to_user(buf, &zcore_header + *ppos, size)) {
320 rc = -EFAULT;
321 goto fail;
322 }
323 hdr_count = size;
324 mem_start = 0;
325 } else {
326 hdr_count = 0;
327 mem_start = *ppos - HEADER_SIZE;
328 }
329
330 mem_offs = 0;
331
332 /* Copy from HSA data */
333 if (*ppos < sclp.hsa_size + HEADER_SIZE) {
334 size = min((count - hdr_count),
335 (size_t) (sclp.hsa_size - mem_start));
336 rc = memcpy_hsa_user(buf + hdr_count, mem_start, size);
337 if (rc)
338 goto fail;
339
340 mem_offs += size;
341 }
342
343 /* Copy from real mem */
344 size = count - mem_offs - hdr_count;
345 rc = copy_to_user_real(buf + hdr_count + mem_offs,
346 (void *) mem_start + mem_offs, size);
347 if (rc)
348 goto fail;
349
350 /*
351 * Since s390 dump analysis tools like lcrash or crash
352 * expect register sets in the prefix pages of the cpus,
353 * we copy them into the read buffer, if necessary.
354 * buf + hdr_count: Start of memory part of output buffer
355 * mem_start: Start memory address to copy from
356 * count - hdr_count: Size of memory area to copy
357 */
358 if (zcore_add_lc(buf + hdr_count, mem_start, count - hdr_count)) {
359 rc = -EFAULT;
360 goto fail;
361 }
362 *ppos += count;
363fail:
364 mutex_unlock(&zcore_mutex);
365 return (rc < 0) ? rc : count;
366}
367
368static int zcore_open(struct inode *inode, struct file *filp)
369{
370 if (!hsa_available)
371 return -ENODATA;
372 else
373 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
374}
375
376static int zcore_release(struct inode *inode, struct file *filep)
377{
378 if (hsa_available)
379 release_hsa();
380 return 0;
381}
382
383static loff_t zcore_lseek(struct file *file, loff_t offset, int orig)
384{
385 loff_t rc;
386
387 mutex_lock(&zcore_mutex);
388 rc = no_seek_end_llseek(file, offset, orig);
389 mutex_unlock(&zcore_mutex);
390 return rc;
391}
392
393static const struct file_operations zcore_fops = {
394 .owner = THIS_MODULE,
395 .llseek = zcore_lseek,
396 .read = zcore_read,
397 .open = zcore_open,
398 .release = zcore_release,
399};
400
401static ssize_t zcore_memmap_read(struct file *filp, char __user *buf, 143static ssize_t zcore_memmap_read(struct file *filp, char __user *buf,
402 size_t count, loff_t *ppos) 144 size_t count, loff_t *ppos)
403{ 145{
@@ -501,50 +243,6 @@ static const struct file_operations zcore_hsa_fops = {
501 .llseek = no_llseek, 243 .llseek = no_llseek,
502}; 244};
503 245
504static void __init set_lc_mask(struct save_area *map)
505{
506 memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
507 memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
508 memset(&map->psw, 0xff, sizeof(map->psw));
509 memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
510 memset(&map->fp_ctrl_reg, 0xff, sizeof(map->fp_ctrl_reg));
511 memset(&map->tod_reg, 0xff, sizeof(map->tod_reg));
512 memset(&map->timer, 0xff, sizeof(map->timer));
513 memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
514 memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
515 memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
516}
517
518/*
519 * Initialize dump globals for a given architecture
520 */
521static int __init sys_info_init(enum arch_id arch, unsigned long mem_end)
522{
523 int rc;
524
525 switch (arch) {
526 case ARCH_S390X:
527 pr_alert("DETECTED 'S390X (64 bit) OS'\n");
528 break;
529 case ARCH_S390:
530 pr_alert("DETECTED 'S390 (32 bit) OS'\n");
531 break;
532 default:
533 pr_alert("0x%x is an unknown architecture.\n",arch);
534 return -EINVAL;
535 }
536 sys_info.sa_base = SAVE_AREA_BASE;
537 sys_info.sa_size = sizeof(struct save_area);
538 sys_info.arch = arch;
539 set_lc_mask(&sys_info.lc_mask);
540 rc = init_cpu_info(arch);
541 if (rc)
542 return rc;
543 sys_info.mem_size = mem_end;
544
545 return 0;
546}
547
548static int __init check_sdias(void) 246static int __init check_sdias(void)
549{ 247{
550 if (!sclp.hsa_size) { 248 if (!sclp.hsa_size) {
@@ -554,43 +252,6 @@ static int __init check_sdias(void)
554 return 0; 252 return 0;
555} 253}
556 254
557static int __init get_mem_info(unsigned long *mem, unsigned long *end)
558{
559 struct memblock_region *reg;
560
561 for_each_memblock(memory, reg) {
562 *mem += reg->size;
563 *end = max_t(unsigned long, *end, reg->base + reg->size);
564 }
565 return 0;
566}
567
568static void __init zcore_header_init(int arch, struct zcore_header *hdr,
569 unsigned long mem_size)
570{
571 u32 prefix;
572 int i;
573
574 if (arch == ARCH_S390X)
575 hdr->arch_id = DUMP_ARCH_S390X;
576 else
577 hdr->arch_id = DUMP_ARCH_S390;
578 hdr->mem_size = mem_size;
579 hdr->rmem_size = mem_size;
580 hdr->mem_end = sys_info.mem_size;
581 hdr->num_pages = mem_size / PAGE_SIZE;
582 hdr->tod = get_tod_clock();
583 get_cpu_id(&hdr->cpu_id);
584 for (i = 0; i < dump_save_areas.count; i++) {
585 prefix = dump_save_areas.areas[i]->sa.pref_reg;
586 hdr->real_cpu_cnt++;
587 if (!prefix)
588 continue;
589 hdr->lc_vec[hdr->cpu_cnt] = prefix;
590 hdr->cpu_cnt++;
591 }
592}
593
594/* 255/*
595 * Provide IPL parameter information block from either HSA or memory 256 * Provide IPL parameter information block from either HSA or memory
596 * for future reipl 257 * for future reipl
@@ -623,11 +284,9 @@ static int __init zcore_reipl_init(void)
623 284
624static int __init zcore_init(void) 285static int __init zcore_init(void)
625{ 286{
626 unsigned long mem_size, mem_end;
627 unsigned char arch; 287 unsigned char arch;
628 int rc; 288 int rc;
629 289
630 mem_size = mem_end = 0;
631 if (ipl_info.type != IPL_TYPE_FCP_DUMP) 290 if (ipl_info.type != IPL_TYPE_FCP_DUMP)
632 return -ENODATA; 291 return -ENODATA;
633 if (OLDMEM_BASE) 292 if (OLDMEM_BASE)
@@ -661,14 +320,10 @@ static int __init zcore_init(void)
661 goto fail; 320 goto fail;
662 } 321 }
663 322
664 rc = get_mem_info(&mem_size, &mem_end); 323 pr_alert("DETECTED 'S390X (64 bit) OS'\n");
665 if (rc) 324 rc = init_cpu_info();
666 goto fail;
667
668 rc = sys_info_init(arch, mem_end);
669 if (rc) 325 if (rc)
670 goto fail; 326 goto fail;
671 zcore_header_init(arch, &zcore_header, mem_size);
672 327
673 rc = zcore_reipl_init(); 328 rc = zcore_reipl_init();
674 if (rc) 329 if (rc)
@@ -679,17 +334,11 @@ static int __init zcore_init(void)
679 rc = -ENOMEM; 334 rc = -ENOMEM;
680 goto fail; 335 goto fail;
681 } 336 }
682 zcore_file = debugfs_create_file("mem", S_IRUSR, zcore_dir, NULL,
683 &zcore_fops);
684 if (!zcore_file) {
685 rc = -ENOMEM;
686 goto fail_dir;
687 }
688 zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir, 337 zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir,
689 NULL, &zcore_memmap_fops); 338 NULL, &zcore_memmap_fops);
690 if (!zcore_memmap_file) { 339 if (!zcore_memmap_file) {
691 rc = -ENOMEM; 340 rc = -ENOMEM;
692 goto fail_file; 341 goto fail_dir;
693 } 342 }
694 zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir, 343 zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
695 NULL, &zcore_reipl_fops); 344 NULL, &zcore_reipl_fops);
@@ -709,8 +358,6 @@ fail_reipl_file:
709 debugfs_remove(zcore_reipl_file); 358 debugfs_remove(zcore_reipl_file);
710fail_memmap_file: 359fail_memmap_file:
711 debugfs_remove(zcore_memmap_file); 360 debugfs_remove(zcore_memmap_file);
712fail_file:
713 debugfs_remove(zcore_file);
714fail_dir: 361fail_dir:
715 debugfs_remove(zcore_dir); 362 debugfs_remove(zcore_dir);
716fail: 363fail:
@@ -726,7 +373,6 @@ static void __exit zcore_exit(void)
726 debugfs_remove(zcore_hsa_file); 373 debugfs_remove(zcore_hsa_file);
727 debugfs_remove(zcore_reipl_file); 374 debugfs_remove(zcore_reipl_file);
728 debugfs_remove(zcore_memmap_file); 375 debugfs_remove(zcore_memmap_file);
729 debugfs_remove(zcore_file);
730 debugfs_remove(zcore_dir); 376 debugfs_remove(zcore_dir);
731 diag308(DIAG308_REL_HSA, NULL); 377 diag308(DIAG308_REL_HSA, NULL);
732} 378}
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
index 8c4a386e97f6..3ab9aedeb84a 100644
--- a/drivers/s390/cio/Makefile
+++ b/drivers/s390/cio/Makefile
@@ -2,8 +2,11 @@
2# Makefile for the S/390 common i/o drivers 2# Makefile for the S/390 common i/o drivers
3# 3#
4 4
5# The following is required for define_trace.h to find ./trace.h
6CFLAGS_trace.o := -I$(src)
7
5obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ 8obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \
6 fcx.o itcw.o crw.o ccwreq.o 9 fcx.o itcw.o crw.o ccwreq.o trace.o ioasm.o
7ccw_device-objs += device.o device_fsm.o device_ops.o 10ccw_device-objs += device.o device_fsm.o device_ops.o
8ccw_device-objs += device_id.o device_pgid.o device_status.o 11ccw_device-objs += device_id.o device_pgid.o device_status.o
9obj-y += ccw_device.o cmf.o 12obj-y += ccw_device.o cmf.o
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index 56eb4ee4deba..99b5db469097 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -89,6 +89,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy)
89 89
90 set_cpu_flag(CIF_NOHZ_DELAY); 90 set_cpu_flag(CIF_NOHZ_DELAY);
91 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; 91 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
92 trace_s390_cio_adapter_int(tpi_info);
92 head = &airq_lists[tpi_info->isc]; 93 head = &airq_lists[tpi_info->isc];
93 rcu_read_lock(); 94 rcu_read_lock();
94 hlist_for_each_entry_rcu(airq, head, list) 95 hlist_for_each_entry_rcu(airq, head, list)
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 213159dec89e..b6f12c2bb114 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -133,7 +133,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch)
133 * since we don't have a way to clear the subchannel and 133 * since we don't have a way to clear the subchannel and
134 * cannot disable it with a request running. 134 * cannot disable it with a request running.
135 */ 135 */
136 cc = stsch_err(sch->schid, &schib); 136 cc = stsch(sch->schid, &schib);
137 if (!cc && scsw_stctl(&schib.scsw)) 137 if (!cc && scsw_stctl(&schib.scsw))
138 return -EAGAIN; 138 return -EAGAIN;
139 return 0; 139 return 0;
@@ -185,8 +185,7 @@ static int __init chsc_init_dbfs(void)
185 debug_set_level(chsc_debug_log_id, 2); 185 debug_set_level(chsc_debug_log_id, 2);
186 return 0; 186 return 0;
187out: 187out:
188 if (chsc_debug_msg_id) 188 debug_unregister(chsc_debug_msg_id);
189 debug_unregister(chsc_debug_msg_id);
190 return -ENOMEM; 189 return -ENOMEM;
191} 190}
192 191
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 690b8547e828..39a8ae54e9c1 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -41,6 +41,7 @@
41#include "blacklist.h" 41#include "blacklist.h"
42#include "cio_debug.h" 42#include "cio_debug.h"
43#include "chp.h" 43#include "chp.h"
44#include "trace.h"
44 45
45debug_info_t *cio_debug_msg_id; 46debug_info_t *cio_debug_msg_id;
46debug_info_t *cio_debug_trace_id; 47debug_info_t *cio_debug_trace_id;
@@ -76,12 +77,9 @@ static int __init cio_debug_init(void)
76 return 0; 77 return 0;
77 78
78out_unregister: 79out_unregister:
79 if (cio_debug_msg_id) 80 debug_unregister(cio_debug_msg_id);
80 debug_unregister(cio_debug_msg_id); 81 debug_unregister(cio_debug_trace_id);
81 if (cio_debug_trace_id) 82 debug_unregister(cio_debug_crw_id);
82 debug_unregister(cio_debug_trace_id);
83 if (cio_debug_crw_id)
84 debug_unregister(cio_debug_crw_id);
85 return -1; 83 return -1;
86} 84}
87 85
@@ -348,18 +346,18 @@ int cio_commit_config(struct subchannel *sch)
348 struct schib schib; 346 struct schib schib;
349 struct irb irb; 347 struct irb irb;
350 348
351 if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) 349 if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
352 return -ENODEV; 350 return -ENODEV;
353 351
354 for (retry = 0; retry < 5; retry++) { 352 for (retry = 0; retry < 5; retry++) {
355 /* copy desired changes to local schib */ 353 /* copy desired changes to local schib */
356 cio_apply_config(sch, &schib); 354 cio_apply_config(sch, &schib);
357 ccode = msch_err(sch->schid, &schib); 355 ccode = msch(sch->schid, &schib);
358 if (ccode < 0) /* -EIO if msch gets a program check. */ 356 if (ccode < 0) /* -EIO if msch gets a program check. */
359 return ccode; 357 return ccode;
360 switch (ccode) { 358 switch (ccode) {
361 case 0: /* successful */ 359 case 0: /* successful */
362 if (stsch_err(sch->schid, &schib) || 360 if (stsch(sch->schid, &schib) ||
363 !css_sch_is_valid(&schib)) 361 !css_sch_is_valid(&schib))
364 return -ENODEV; 362 return -ENODEV;
365 if (cio_check_config(sch, &schib)) { 363 if (cio_check_config(sch, &schib)) {
@@ -394,7 +392,7 @@ int cio_update_schib(struct subchannel *sch)
394{ 392{
395 struct schib schib; 393 struct schib schib;
396 394
397 if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) 395 if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
398 return -ENODEV; 396 return -ENODEV;
399 397
400 memcpy(&sch->schib, &schib, sizeof(schib)); 398 memcpy(&sch->schib, &schib, sizeof(schib));
@@ -503,7 +501,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
503 * If stsch gets an exception, it means the current subchannel set 501 * If stsch gets an exception, it means the current subchannel set
504 * is not valid. 502 * is not valid.
505 */ 503 */
506 ccode = stsch_err(schid, &sch->schib); 504 ccode = stsch(schid, &sch->schib);
507 if (ccode) { 505 if (ccode) {
508 err = (ccode == 3) ? -ENXIO : ccode; 506 err = (ccode == 3) ? -ENXIO : ccode;
509 goto out; 507 goto out;
@@ -542,6 +540,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
542 540
543 set_cpu_flag(CIF_NOHZ_DELAY); 541 set_cpu_flag(CIF_NOHZ_DELAY);
544 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; 542 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
543 trace_s390_cio_interrupt(tpi_info);
545 irb = this_cpu_ptr(&cio_irb); 544 irb = this_cpu_ptr(&cio_irb);
546 sch = (struct subchannel *)(unsigned long) tpi_info->intparm; 545 sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
547 if (!sch) { 546 if (!sch) {
@@ -619,7 +618,7 @@ static int cio_test_for_console(struct subchannel_id schid, void *data)
619{ 618{
620 struct schib schib; 619 struct schib schib;
621 620
622 if (stsch_err(schid, &schib) != 0) 621 if (stsch(schid, &schib) != 0)
623 return -ENXIO; 622 return -ENXIO;
624 if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && 623 if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv &&
625 (schib.pmcw.dev == console_devno)) { 624 (schib.pmcw.dev == console_devno)) {
@@ -638,7 +637,7 @@ static int cio_get_console_sch_no(void)
638 if (console_irq != -1) { 637 if (console_irq != -1) {
639 /* VM provided us with the irq number of the console. */ 638 /* VM provided us with the irq number of the console. */
640 schid.sch_no = console_irq; 639 schid.sch_no = console_irq;
641 if (stsch_err(schid, &schib) != 0 || 640 if (stsch(schid, &schib) != 0 ||
642 (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv) 641 (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv)
643 return -1; 642 return -1;
644 console_devno = schib.pmcw.dev; 643 console_devno = schib.pmcw.dev;
@@ -708,10 +707,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
708 cc = 0; 707 cc = 0;
709 for (retry=0;retry<3;retry++) { 708 for (retry=0;retry<3;retry++) {
710 schib->pmcw.ena = 0; 709 schib->pmcw.ena = 0;
711 cc = msch_err(schid, schib); 710 cc = msch(schid, schib);
712 if (cc) 711 if (cc)
713 return (cc==3?-ENODEV:-EBUSY); 712 return (cc==3?-ENODEV:-EBUSY);
714 if (stsch_err(schid, schib) || !css_sch_is_valid(schib)) 713 if (stsch(schid, schib) || !css_sch_is_valid(schib))
715 return -ENODEV; 714 return -ENODEV;
716 if (!schib->pmcw.ena) 715 if (!schib->pmcw.ena)
717 return 0; 716 return 0;
@@ -758,7 +757,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr)
758 757
759 pgm_check_occured = 0; 758 pgm_check_occured = 0;
760 s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; 759 s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
761 rc = stsch_err(schid, addr); 760 rc = stsch(schid, addr);
762 s390_base_pgm_handler_fn = NULL; 761 s390_base_pgm_handler_fn = NULL;
763 762
764 /* The program check handler could have changed pgm_check_occured. */ 763 /* The program check handler could have changed pgm_check_occured. */
@@ -795,7 +794,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
795 /* No default clear strategy */ 794 /* No default clear strategy */
796 break; 795 break;
797 } 796 }
798 stsch_err(schid, &schib); 797 stsch(schid, &schib);
799 __disable_subchannel_easy(schid, &schib); 798 __disable_subchannel_easy(schid, &schib);
800 } 799 }
801out: 800out:
@@ -917,7 +916,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
917{ 916{
918 struct subchannel_id uninitialized_var(schid); 917 struct subchannel_id uninitialized_var(schid);
919 918
920 s390_reset_system(NULL, NULL, NULL); 919 s390_reset_system();
921 if (reipl_find_schid(devid, &schid) != 0) 920 if (reipl_find_schid(devid, &schid) != 0)
922 panic("IPL Device not found\n"); 921 panic("IPL Device not found\n");
923 do_reipl_asm(*((__u32*)&schid)); 922 do_reipl_asm(*((__u32*)&schid));
@@ -943,7 +942,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
943 if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS)) 942 if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS))
944 return -ENODEV; 943 return -ENODEV;
945 } 944 }
946 if (stsch_err(schid, &schib)) 945 if (stsch(schid, &schib))
947 return -ENODEV; 946 return -ENODEV;
948 if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) 947 if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
949 return -ENODEV; 948 return -ENODEV;
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index a01376ae1749..93de0b46b489 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -45,6 +45,18 @@ struct pmcw {
45 /* ... in an operand exception. */ 45 /* ... in an operand exception. */
46} __attribute__ ((packed)); 46} __attribute__ ((packed));
47 47
48/* I/O-Interruption Code as stored by TEST PENDING INTERRUPTION (TPI). */
49struct tpi_info {
50 struct subchannel_id schid;
51 u32 intparm;
52 u32 adapter_IO:1;
53 u32 :1;
54 u32 isc:3;
55 u32 :27;
56 u32 type:3;
57 u32 :12;
58} __packed __aligned(4);
59
48/* Target SCHIB configuration. */ 60/* Target SCHIB configuration. */
49struct schib_config { 61struct schib_config {
50 u64 mba; 62 u64 mba;
diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c
index 0f8a25f98b10..3d3cd402b376 100644
--- a/drivers/s390/cio/crw.c
+++ b/drivers/s390/cio/crw.c
@@ -14,6 +14,7 @@
14#include <linux/wait.h> 14#include <linux/wait.h>
15#include <asm/crw.h> 15#include <asm/crw.h>
16#include <asm/ctl_reg.h> 16#include <asm/ctl_reg.h>
17#include "ioasm.h"
17 18
18static DEFINE_MUTEX(crw_handler_mutex); 19static DEFINE_MUTEX(crw_handler_mutex);
19static crw_handler_t crw_handlers[NR_RSCS]; 20static crw_handler_t crw_handlers[NR_RSCS];
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 489e703dc82d..3d2b20ee613f 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -390,7 +390,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow)
390 /* Will be done on the slow path. */ 390 /* Will be done on the slow path. */
391 return -EAGAIN; 391 return -EAGAIN;
392 } 392 }
393 if (stsch_err(schid, &schib)) { 393 if (stsch(schid, &schib)) {
394 /* Subchannel is not provided. */ 394 /* Subchannel is not provided. */
395 return -ENXIO; 395 return -ENXIO;
396 } 396 }
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 92e03b42e661..8327d47e08b6 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -44,7 +44,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
44 sch = to_subchannel(cdev->dev.parent); 44 sch = to_subchannel(cdev->dev.parent);
45 private = to_io_private(sch); 45 private = to_io_private(sch);
46 orb = &private->orb; 46 orb = &private->orb;
47 cc = stsch_err(sch->schid, &schib); 47 cc = stsch(sch->schid, &schib);
48 48
49 printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " 49 printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
50 "device information:\n", get_tod_clock()); 50 "device information:\n", get_tod_clock());
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index b108f4a5c7dd..8975060af96c 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -169,49 +169,4 @@ struct ccw_device_private {
169 enum interruption_class int_class; 169 enum interruption_class int_class;
170}; 170};
171 171
172static inline int rsch(struct subchannel_id schid)
173{
174 register struct subchannel_id reg1 asm("1") = schid;
175 int ccode;
176
177 asm volatile(
178 " rsch\n"
179 " ipm %0\n"
180 " srl %0,28"
181 : "=d" (ccode)
182 : "d" (reg1)
183 : "cc", "memory");
184 return ccode;
185}
186
187static inline int hsch(struct subchannel_id schid)
188{
189 register struct subchannel_id reg1 asm("1") = schid;
190 int ccode;
191
192 asm volatile(
193 " hsch\n"
194 " ipm %0\n"
195 " srl %0,28"
196 : "=d" (ccode)
197 : "d" (reg1)
198 : "cc");
199 return ccode;
200}
201
202static inline int xsch(struct subchannel_id schid)
203{
204 register struct subchannel_id reg1 asm("1") = schid;
205 int ccode;
206
207 asm volatile(
208 " .insn rre,0xb2760000,%1,0\n"
209 " ipm %0\n"
210 " srl %0,28"
211 : "=d" (ccode)
212 : "d" (reg1)
213 : "cc");
214 return ccode;
215}
216
217#endif 172#endif
diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c
new file mode 100644
index 000000000000..98984818618f
--- /dev/null
+++ b/drivers/s390/cio/ioasm.c
@@ -0,0 +1,224 @@
1/*
2 * Channel subsystem I/O instructions.
3 */
4
5#include <linux/export.h>
6
7#include <asm/chpid.h>
8#include <asm/schid.h>
9#include <asm/crw.h>
10
11#include "ioasm.h"
12#include "orb.h"
13#include "cio.h"
14
15int stsch(struct subchannel_id schid, struct schib *addr)
16{
17 register struct subchannel_id reg1 asm ("1") = schid;
18 int ccode = -EIO;
19
20 asm volatile(
21 " stsch 0(%3)\n"
22 "0: ipm %0\n"
23 " srl %0,28\n"
24 "1:\n"
25 EX_TABLE(0b, 1b)
26 : "+d" (ccode), "=m" (*addr)
27 : "d" (reg1), "a" (addr)
28 : "cc");
29 trace_s390_cio_stsch(schid, addr, ccode);
30
31 return ccode;
32}
33EXPORT_SYMBOL(stsch);
34
35int msch(struct subchannel_id schid, struct schib *addr)
36{
37 register struct subchannel_id reg1 asm ("1") = schid;
38 int ccode = -EIO;
39
40 asm volatile(
41 " msch 0(%2)\n"
42 "0: ipm %0\n"
43 " srl %0,28\n"
44 "1:\n"
45 EX_TABLE(0b, 1b)
46 : "+d" (ccode)
47 : "d" (reg1), "a" (addr), "m" (*addr)
48 : "cc");
49 trace_s390_cio_msch(schid, addr, ccode);
50
51 return ccode;
52}
53
54int tsch(struct subchannel_id schid, struct irb *addr)
55{
56 register struct subchannel_id reg1 asm ("1") = schid;
57 int ccode;
58
59 asm volatile(
60 " tsch 0(%3)\n"
61 " ipm %0\n"
62 " srl %0,28"
63 : "=d" (ccode), "=m" (*addr)
64 : "d" (reg1), "a" (addr)
65 : "cc");
66 trace_s390_cio_tsch(schid, addr, ccode);
67
68 return ccode;
69}
70
71int ssch(struct subchannel_id schid, union orb *addr)
72{
73 register struct subchannel_id reg1 asm("1") = schid;
74 int ccode = -EIO;
75
76 asm volatile(
77 " ssch 0(%2)\n"
78 "0: ipm %0\n"
79 " srl %0,28\n"
80 "1:\n"
81 EX_TABLE(0b, 1b)
82 : "+d" (ccode)
83 : "d" (reg1), "a" (addr), "m" (*addr)
84 : "cc", "memory");
85 trace_s390_cio_ssch(schid, addr, ccode);
86
87 return ccode;
88}
89EXPORT_SYMBOL(ssch);
90
91int csch(struct subchannel_id schid)
92{
93 register struct subchannel_id reg1 asm("1") = schid;
94 int ccode;
95
96 asm volatile(
97 " csch\n"
98 " ipm %0\n"
99 " srl %0,28"
100 : "=d" (ccode)
101 : "d" (reg1)
102 : "cc");
103 trace_s390_cio_csch(schid, ccode);
104
105 return ccode;
106}
107EXPORT_SYMBOL(csch);
108
109int tpi(struct tpi_info *addr)
110{
111 int ccode;
112
113 asm volatile(
114 " tpi 0(%2)\n"
115 " ipm %0\n"
116 " srl %0,28"
117 : "=d" (ccode), "=m" (*addr)
118 : "a" (addr)
119 : "cc");
120 trace_s390_cio_tpi(addr, ccode);
121
122 return ccode;
123}
124
125int chsc(void *chsc_area)
126{
127 typedef struct { char _[4096]; } addr_type;
128 int cc;
129
130 asm volatile(
131 " .insn rre,0xb25f0000,%2,0\n"
132 " ipm %0\n"
133 " srl %0,28\n"
134 : "=d" (cc), "=m" (*(addr_type *) chsc_area)
135 : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
136 : "cc");
137 trace_s390_cio_chsc(chsc_area, cc);
138
139 return cc;
140}
141EXPORT_SYMBOL(chsc);
142
143int rchp(struct chp_id chpid)
144{
145 register struct chp_id reg1 asm ("1") = chpid;
146 int ccode;
147
148 asm volatile(
149 " lr 1,%1\n"
150 " rchp\n"
151 " ipm %0\n"
152 " srl %0,28"
153 : "=d" (ccode) : "d" (reg1) : "cc");
154 trace_s390_cio_rchp(chpid, ccode);
155
156 return ccode;
157}
158
159int rsch(struct subchannel_id schid)
160{
161 register struct subchannel_id reg1 asm("1") = schid;
162 int ccode;
163
164 asm volatile(
165 " rsch\n"
166 " ipm %0\n"
167 " srl %0,28"
168 : "=d" (ccode)
169 : "d" (reg1)
170 : "cc", "memory");
171 trace_s390_cio_rsch(schid, ccode);
172
173 return ccode;
174}
175
176int hsch(struct subchannel_id schid)
177{
178 register struct subchannel_id reg1 asm("1") = schid;
179 int ccode;
180
181 asm volatile(
182 " hsch\n"
183 " ipm %0\n"
184 " srl %0,28"
185 : "=d" (ccode)
186 : "d" (reg1)
187 : "cc");
188 trace_s390_cio_hsch(schid, ccode);
189
190 return ccode;
191}
192
193int xsch(struct subchannel_id schid)
194{
195 register struct subchannel_id reg1 asm("1") = schid;
196 int ccode;
197
198 asm volatile(
199 " xsch\n"
200 " ipm %0\n"
201 " srl %0,28"
202 : "=d" (ccode)
203 : "d" (reg1)
204 : "cc");
205 trace_s390_cio_xsch(schid, ccode);
206
207 return ccode;
208}
209
210int stcrw(struct crw *crw)
211{
212 int ccode;
213
214 asm volatile(
215 " stcrw 0(%2)\n"
216 " ipm %0\n"
217 " srl %0,28\n"
218 : "=d" (ccode), "=m" (*crw)
219 : "a" (crw)
220 : "cc");
221 trace_s390_cio_stcrw(crw, ccode);
222
223 return ccode;
224}
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
index 4d80fc67a06b..b31ee6bff1e4 100644
--- a/drivers/s390/cio/ioasm.h
+++ b/drivers/s390/cio/ioasm.h
@@ -3,165 +3,26 @@
3 3
4#include <asm/chpid.h> 4#include <asm/chpid.h>
5#include <asm/schid.h> 5#include <asm/schid.h>
6#include <asm/crw.h>
6#include "orb.h" 7#include "orb.h"
7#include "cio.h" 8#include "cio.h"
9#include "trace.h"
8 10
9/* 11/*
10 * TPI info structure 12 * Some S390 specific IO instructions
11 */ 13 */
12struct tpi_info {
13 struct subchannel_id schid;
14 __u32 intparm; /* interruption parameter */
15 __u32 adapter_IO : 1;
16 __u32 reserved2 : 1;
17 __u32 isc : 3;
18 __u32 reserved3 : 12;
19 __u32 int_type : 3;
20 __u32 reserved4 : 12;
21} __attribute__ ((packed));
22 14
23 15int stsch(struct subchannel_id schid, struct schib *addr);
24/* 16int msch(struct subchannel_id schid, struct schib *addr);
25 * Some S390 specific IO instructions as inline 17int tsch(struct subchannel_id schid, struct irb *addr);
26 */ 18int ssch(struct subchannel_id schid, union orb *addr);
27 19int csch(struct subchannel_id schid);
28static inline int stsch_err(struct subchannel_id schid, struct schib *addr) 20int tpi(struct tpi_info *addr);
29{ 21int chsc(void *chsc_area);
30 register struct subchannel_id reg1 asm ("1") = schid; 22int rchp(struct chp_id chpid);
31 int ccode = -EIO; 23int rsch(struct subchannel_id schid);
32 24int hsch(struct subchannel_id schid);
33 asm volatile( 25int xsch(struct subchannel_id schid);
34 " stsch 0(%3)\n" 26int stcrw(struct crw *crw);
35 "0: ipm %0\n"
36 " srl %0,28\n"
37 "1:\n"
38 EX_TABLE(0b,1b)
39 : "+d" (ccode), "=m" (*addr)
40 : "d" (reg1), "a" (addr)
41 : "cc");
42 return ccode;
43}
44
45static inline int msch(struct subchannel_id schid, struct schib *addr)
46{
47 register struct subchannel_id reg1 asm ("1") = schid;
48 int ccode;
49
50 asm volatile(
51 " msch 0(%2)\n"
52 " ipm %0\n"
53 " srl %0,28"
54 : "=d" (ccode)
55 : "d" (reg1), "a" (addr), "m" (*addr)
56 : "cc");
57 return ccode;
58}
59
60static inline int msch_err(struct subchannel_id schid, struct schib *addr)
61{
62 register struct subchannel_id reg1 asm ("1") = schid;
63 int ccode = -EIO;
64
65 asm volatile(
66 " msch 0(%2)\n"
67 "0: ipm %0\n"
68 " srl %0,28\n"
69 "1:\n"
70 EX_TABLE(0b,1b)
71 : "+d" (ccode)
72 : "d" (reg1), "a" (addr), "m" (*addr)
73 : "cc");
74 return ccode;
75}
76
77static inline int tsch(struct subchannel_id schid, struct irb *addr)
78{
79 register struct subchannel_id reg1 asm ("1") = schid;
80 int ccode;
81
82 asm volatile(
83 " tsch 0(%3)\n"
84 " ipm %0\n"
85 " srl %0,28"
86 : "=d" (ccode), "=m" (*addr)
87 : "d" (reg1), "a" (addr)
88 : "cc");
89 return ccode;
90}
91
92static inline int ssch(struct subchannel_id schid, union orb *addr)
93{
94 register struct subchannel_id reg1 asm("1") = schid;
95 int ccode = -EIO;
96
97 asm volatile(
98 " ssch 0(%2)\n"
99 "0: ipm %0\n"
100 " srl %0,28\n"
101 "1:\n"
102 EX_TABLE(0b, 1b)
103 : "+d" (ccode)
104 : "d" (reg1), "a" (addr), "m" (*addr)
105 : "cc", "memory");
106 return ccode;
107}
108
109static inline int csch(struct subchannel_id schid)
110{
111 register struct subchannel_id reg1 asm("1") = schid;
112 int ccode;
113
114 asm volatile(
115 " csch\n"
116 " ipm %0\n"
117 " srl %0,28"
118 : "=d" (ccode)
119 : "d" (reg1)
120 : "cc");
121 return ccode;
122}
123
124static inline int tpi(struct tpi_info *addr)
125{
126 int ccode;
127
128 asm volatile(
129 " tpi 0(%2)\n"
130 " ipm %0\n"
131 " srl %0,28"
132 : "=d" (ccode), "=m" (*addr)
133 : "a" (addr)
134 : "cc");
135 return ccode;
136}
137
138static inline int chsc(void *chsc_area)
139{
140 typedef struct { char _[4096]; } addr_type;
141 int cc;
142
143 asm volatile(
144 " .insn rre,0xb25f0000,%2,0\n"
145 " ipm %0\n"
146 " srl %0,28\n"
147 : "=d" (cc), "=m" (*(addr_type *) chsc_area)
148 : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
149 : "cc");
150 return cc;
151}
152
153static inline int rchp(struct chp_id chpid)
154{
155 register struct chp_id reg1 asm ("1") = chpid;
156 int ccode;
157
158 asm volatile(
159 " lr 1,%1\n"
160 " rchp\n"
161 " ipm %0\n"
162 " srl %0,28"
163 : "=d" (ccode) : "d" (reg1) : "cc");
164 return ccode;
165}
166 27
167#endif 28#endif
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index f1f3baa8e6e4..b6fc147f83d8 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -366,8 +366,6 @@ void qdio_debug_exit(void)
366{ 366{
367 qdio_clear_dbf_list(); 367 qdio_clear_dbf_list();
368 debugfs_remove(debugfs_root); 368 debugfs_remove(debugfs_root);
369 if (qdio_dbf_setup) 369 debug_unregister(qdio_dbf_setup);
370 debug_unregister(qdio_dbf_setup); 370 debug_unregister(qdio_dbf_error);
371 if (qdio_dbf_error)
372 debug_unregister(qdio_dbf_error);
373} 371}
diff --git a/drivers/s390/cio/trace.c b/drivers/s390/cio/trace.c
new file mode 100644
index 000000000000..8e706669ac8b
--- /dev/null
+++ b/drivers/s390/cio/trace.c
@@ -0,0 +1,24 @@
1/*
2 * Tracepoint definitions for s390_cio
3 *
4 * Copyright IBM Corp. 2015
5 * Author(s): Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
6 */
7
8#include <asm/crw.h>
9#include "cio.h"
10
11#define CREATE_TRACE_POINTS
12#include "trace.h"
13
14EXPORT_TRACEPOINT_SYMBOL(s390_cio_stsch);
15EXPORT_TRACEPOINT_SYMBOL(s390_cio_msch);
16EXPORT_TRACEPOINT_SYMBOL(s390_cio_tsch);
17EXPORT_TRACEPOINT_SYMBOL(s390_cio_tpi);
18EXPORT_TRACEPOINT_SYMBOL(s390_cio_ssch);
19EXPORT_TRACEPOINT_SYMBOL(s390_cio_csch);
20EXPORT_TRACEPOINT_SYMBOL(s390_cio_hsch);
21EXPORT_TRACEPOINT_SYMBOL(s390_cio_xsch);
22EXPORT_TRACEPOINT_SYMBOL(s390_cio_rsch);
23EXPORT_TRACEPOINT_SYMBOL(s390_cio_rchp);
24EXPORT_TRACEPOINT_SYMBOL(s390_cio_chsc);
diff --git a/drivers/s390/cio/trace.h b/drivers/s390/cio/trace.h
new file mode 100644
index 000000000000..5b807a09f21b
--- /dev/null
+++ b/drivers/s390/cio/trace.h
@@ -0,0 +1,363 @@
1/*
2 * Tracepoint header for the s390 Common I/O layer (CIO)
3 *
4 * Copyright IBM Corp. 2015
5 * Author(s): Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
6 */
7
8#include <linux/kernel.h>
9#include <asm/crw.h>
10#include <uapi/asm/chpid.h>
11#include <uapi/asm/schid.h>
12#include "cio.h"
13#include "orb.h"
14
15#undef TRACE_SYSTEM
16#define TRACE_SYSTEM s390
17
18#if !defined(_TRACE_S390_CIO_H) || defined(TRACE_HEADER_MULTI_READ)
19#define _TRACE_S390_CIO_H
20
21#include <linux/tracepoint.h>
22
23DECLARE_EVENT_CLASS(s390_class_schib,
24 TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc),
25 TP_ARGS(schid, schib, cc),
26 TP_STRUCT__entry(
27 __field(u8, cssid)
28 __field(u8, ssid)
29 __field(u16, schno)
30 __field(u16, devno)
31 __field_struct(struct schib, schib)
32 __field(int, cc)
33 ),
34 TP_fast_assign(
35 __entry->cssid = schid.cssid;
36 __entry->ssid = schid.ssid;
37 __entry->schno = schid.sch_no;
38 __entry->devno = schib->pmcw.dev;
39 __entry->schib = *schib;
40 __entry->cc = cc;
41 ),
42 TP_printk("schid=%x.%x.%04x cc=%d ena=%d st=%d dnv=%d dev=%04x "
43 "lpm=0x%02x pnom=0x%02x lpum=0x%02x pim=0x%02x pam=0x%02x "
44 "pom=0x%02x chpids=%016llx",
45 __entry->cssid, __entry->ssid, __entry->schno, __entry->cc,
46 __entry->schib.pmcw.ena, __entry->schib.pmcw.st,
47 __entry->schib.pmcw.dnv, __entry->schib.pmcw.dev,
48 __entry->schib.pmcw.lpm, __entry->schib.pmcw.pnom,
49 __entry->schib.pmcw.lpum, __entry->schib.pmcw.pim,
50 __entry->schib.pmcw.pam, __entry->schib.pmcw.pom,
51 *((u64 *) __entry->schib.pmcw.chpid)
52 )
53);
54
55/**
56 * s390_cio_stsch - Store Subchannel instruction (STSCH) was performed
57 * @schid: Subchannel ID
58 * @schib: Subchannel-Information block
59 * @cc: Condition code
60 */
61DEFINE_EVENT(s390_class_schib, s390_cio_stsch,
62 TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc),
63 TP_ARGS(schid, schib, cc)
64);
65
66/**
67 * s390_cio_msch - Modify Subchannel instruction (MSCH) was performed
68 * @schid: Subchannel ID
69 * @schib: Subchannel-Information block
70 * @cc: Condition code
71 */
72DEFINE_EVENT(s390_class_schib, s390_cio_msch,
73 TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc),
74 TP_ARGS(schid, schib, cc)
75);
76
77/**
78 * s390_cio_tsch - Test Subchannel instruction (TSCH) was performed
79 * @schid: Subchannel ID
80 * @irb: Interruption-Response Block
81 * @cc: Condition code
82 */
83TRACE_EVENT(s390_cio_tsch,
84 TP_PROTO(struct subchannel_id schid, struct irb *irb, int cc),
85 TP_ARGS(schid, irb, cc),
86 TP_STRUCT__entry(
87 __field(u8, cssid)
88 __field(u8, ssid)
89 __field(u16, schno)
90 __field_struct(struct irb, irb)
91 __field(int, cc)
92 ),
93 TP_fast_assign(
94 __entry->cssid = schid.cssid;
95 __entry->ssid = schid.ssid;
96 __entry->schno = schid.sch_no;
97 __entry->irb = *irb;
98 __entry->cc = cc;
99 ),
100 TP_printk("schid=%x.%x.%04x cc=%d dcc=%d pno=%d fctl=0x%x actl=0x%x "
101 "stctl=0x%x dstat=0x%x cstat=0x%x",
102 __entry->cssid, __entry->ssid, __entry->schno, __entry->cc,
103 scsw_cc(&__entry->irb.scsw), scsw_pno(&__entry->irb.scsw),
104 scsw_fctl(&__entry->irb.scsw), scsw_actl(&__entry->irb.scsw),
105 scsw_stctl(&__entry->irb.scsw),
106 scsw_dstat(&__entry->irb.scsw), scsw_cstat(&__entry->irb.scsw)
107 )
108);
109
110/**
111 * s390_cio_tpi - Test Pending Interruption instruction (TPI) was performed
112 * @addr: Address of the I/O interruption code or %NULL
113 * @cc: Condition code
114 */
115TRACE_EVENT(s390_cio_tpi,
116 TP_PROTO(struct tpi_info *addr, int cc),
117 TP_ARGS(addr, cc),
118 TP_STRUCT__entry(
119 __field(int, cc)
120 __field_struct(struct tpi_info, tpi_info)
121 __field(u8, cssid)
122 __field(u8, ssid)
123 __field(u16, schno)
124 ),
125 TP_fast_assign(
126 __entry->cc = cc;
127 if (cc != 0)
128 memset(&__entry->tpi_info, 0, sizeof(struct tpi_info));
129 else if (addr)
130 __entry->tpi_info = *addr;
131 else {
132 memcpy(&__entry->tpi_info, &S390_lowcore.subchannel_id,
133 sizeof(struct tpi_info));
134 }
135 __entry->cssid = __entry->tpi_info.schid.cssid;
136 __entry->ssid = __entry->tpi_info.schid.ssid;
137 __entry->schno = __entry->tpi_info.schid.sch_no;
138 ),
139 TP_printk("schid=%x.%x.%04x cc=%d a=%d isc=%d type=%d",
140 __entry->cssid, __entry->ssid, __entry->schno, __entry->cc,
141 __entry->tpi_info.adapter_IO, __entry->tpi_info.isc,
142 __entry->tpi_info.type
143 )
144);
145
146/**
147 * s390_cio_ssch - Start Subchannel instruction (SSCH) was performed
148 * @schid: Subchannel ID
149 * @orb: Operation-Request Block
150 * @cc: Condition code
151 */
152TRACE_EVENT(s390_cio_ssch,
153 TP_PROTO(struct subchannel_id schid, union orb *orb, int cc),
154 TP_ARGS(schid, orb, cc),
155 TP_STRUCT__entry(
156 __field(u8, cssid)
157 __field(u8, ssid)
158 __field(u16, schno)
159 __field_struct(union orb, orb)
160 __field(int, cc)
161 ),
162 TP_fast_assign(
163 __entry->cssid = schid.cssid;
164 __entry->ssid = schid.ssid;
165 __entry->schno = schid.sch_no;
166 __entry->orb = *orb;
167 __entry->cc = cc;
168 ),
169 TP_printk("schid=%x.%x.%04x cc=%d", __entry->cssid, __entry->ssid,
170 __entry->schno, __entry->cc
171 )
172);
173
174DECLARE_EVENT_CLASS(s390_class_schid,
175 TP_PROTO(struct subchannel_id schid, int cc),
176 TP_ARGS(schid, cc),
177 TP_STRUCT__entry(
178 __field(u8, cssid)
179 __field(u8, ssid)
180 __field(u16, schno)
181 __field(int, cc)
182 ),
183 TP_fast_assign(
184 __entry->cssid = schid.cssid;
185 __entry->ssid = schid.ssid;
186 __entry->schno = schid.sch_no;
187 __entry->cc = cc;
188 ),
189 TP_printk("schid=%x.%x.%04x cc=%d", __entry->cssid, __entry->ssid,
190 __entry->schno, __entry->cc
191 )
192);
193
194/**
195 * s390_cio_csch - Clear Subchannel instruction (CSCH) was performed
196 * @schid: Subchannel ID
197 * @cc: Condition code
198 */
199DEFINE_EVENT(s390_class_schid, s390_cio_csch,
200 TP_PROTO(struct subchannel_id schid, int cc),
201 TP_ARGS(schid, cc)
202);
203
204/**
205 * s390_cio_hsch - Halt Subchannel instruction (HSCH) was performed
206 * @schid: Subchannel ID
207 * @cc: Condition code
208 */
209DEFINE_EVENT(s390_class_schid, s390_cio_hsch,
210 TP_PROTO(struct subchannel_id schid, int cc),
211 TP_ARGS(schid, cc)
212);
213
214/**
215 * s390_cio_xsch - Cancel Subchannel instruction (XSCH) was performed
216 * @schid: Subchannel ID
217 * @cc: Condition code
218 */
219DEFINE_EVENT(s390_class_schid, s390_cio_xsch,
220 TP_PROTO(struct subchannel_id schid, int cc),
221 TP_ARGS(schid, cc)
222);
223
224/**
225 * s390_cio_rsch - Resume Subchannel instruction (RSCH) was performed
226 * @schid: Subchannel ID
227 * @cc: Condition code
228 */
229DEFINE_EVENT(s390_class_schid, s390_cio_rsch,
230 TP_PROTO(struct subchannel_id schid, int cc),
231 TP_ARGS(schid, cc)
232);
233
234/**
235 * s390_cio_rchp - Reset Channel Path (RCHP) instruction was performed
236 * @chpid: Channel-Path Identifier
237 * @cc: Condition code
238 */
239TRACE_EVENT(s390_cio_rchp,
240 TP_PROTO(struct chp_id chpid, int cc),
241 TP_ARGS(chpid, cc),
242 TP_STRUCT__entry(
243 __field(u8, cssid)
244 __field(u8, id)
245 __field(int, cc)
246 ),
247 TP_fast_assign(
248 __entry->cssid = chpid.cssid;
249 __entry->id = chpid.id;
250 __entry->cc = cc;
251 ),
252 TP_printk("chpid=%x.%02x cc=%d", __entry->cssid, __entry->id,
253 __entry->cc
254 )
255);
256
257#define CHSC_MAX_REQUEST_LEN 64
258#define CHSC_MAX_RESPONSE_LEN 64
259
260/**
261 * s390_cio_chsc - Channel Subsystem Call (CHSC) instruction was performed
262 * @chsc: CHSC block
263 * @cc: Condition code
264 */
265TRACE_EVENT(s390_cio_chsc,
266 TP_PROTO(struct chsc_header *chsc, int cc),
267 TP_ARGS(chsc, cc),
268 TP_STRUCT__entry(
269 __field(int, cc)
270 __field(u16, code)
271 __field(u16, rcode)
272 __array(u8, request, CHSC_MAX_REQUEST_LEN)
273 __array(u8, response, CHSC_MAX_RESPONSE_LEN)
274 ),
275 TP_fast_assign(
276 __entry->cc = cc;
277 __entry->code = chsc->code;
278 memcpy(&entry->request, chsc,
279 min_t(u16, chsc->length, CHSC_MAX_REQUEST_LEN));
280 chsc = (struct chsc_header *) ((char *) chsc + chsc->length);
281 __entry->rcode = chsc->code;
282 memcpy(&entry->response, chsc,
283 min_t(u16, chsc->length, CHSC_MAX_RESPONSE_LEN));
284 ),
285 TP_printk("code=0x%04x cc=%d rcode=0x%04x", __entry->code,
286 __entry->cc, __entry->rcode)
287);
288
289/**
290 * s390_cio_interrupt - An I/O interrupt occurred
291 * @tpi_info: Address of the I/O interruption code
292 */
293TRACE_EVENT(s390_cio_interrupt,
294 TP_PROTO(struct tpi_info *tpi_info),
295 TP_ARGS(tpi_info),
296 TP_STRUCT__entry(
297 __field_struct(struct tpi_info, tpi_info)
298 __field(u8, cssid)
299 __field(u8, ssid)
300 __field(u16, schno)
301 ),
302 TP_fast_assign(
303 __entry->tpi_info = *tpi_info;
304 __entry->cssid = __entry->tpi_info.schid.cssid;
305 __entry->ssid = __entry->tpi_info.schid.ssid;
306 __entry->schno = __entry->tpi_info.schid.sch_no;
307 ),
308 TP_printk("schid=%x.%x.%04x isc=%d type=%d",
309 __entry->cssid, __entry->ssid, __entry->schno,
310 __entry->tpi_info.isc, __entry->tpi_info.type
311 )
312);
313
314/**
315 * s390_cio_adapter_int - An adapter interrupt occurred
316 * @tpi_info: Address of the I/O interruption code
317 */
318TRACE_EVENT(s390_cio_adapter_int,
319 TP_PROTO(struct tpi_info *tpi_info),
320 TP_ARGS(tpi_info),
321 TP_STRUCT__entry(
322 __field_struct(struct tpi_info, tpi_info)
323 ),
324 TP_fast_assign(
325 __entry->tpi_info = *tpi_info;
326 ),
327 TP_printk("isc=%d", __entry->tpi_info.isc)
328);
329
330/**
331 * s390_cio_stcrw - Store Channel Report Word (STCRW) was performed
332 * @crw: Channel Report Word
333 * @cc: Condition code
334 */
335TRACE_EVENT(s390_cio_stcrw,
336 TP_PROTO(struct crw *crw, int cc),
337 TP_ARGS(crw, cc),
338 TP_STRUCT__entry(
339 __field_struct(struct crw, crw)
340 __field(int, cc)
341 ),
342 TP_fast_assign(
343 __entry->crw = *crw;
344 __entry->cc = cc;
345 ),
346 TP_printk("cc=%d slct=%d oflw=%d chn=%d rsc=%d anc=%d erc=0x%x "
347 "rsid=0x%x",
348 __entry->cc, __entry->crw.slct, __entry->crw.oflw,
349 __entry->crw.chn, __entry->crw.rsc, __entry->crw.anc,
350 __entry->crw.erc, __entry->crw.rsid
351 )
352);
353
354#endif /* _TRACE_S390_CIO_H */
355
356/* This part must be outside protection */
357#undef TRACE_INCLUDE_PATH
358#define TRACE_INCLUDE_PATH .
359
360#undef TRACE_INCLUDE_FILE
361#define TRACE_INCLUDE_FILE trace
362
363#include <trace/define_trace.h>
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 9f8fa42c062c..5d3d04c040c2 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -1428,10 +1428,8 @@ int __init zcrypt_debug_init(void)
1428void zcrypt_debug_exit(void) 1428void zcrypt_debug_exit(void)
1429{ 1429{
1430 debugfs_remove(debugfs_root); 1430 debugfs_remove(debugfs_root);
1431 if (zcrypt_dbf_common) 1431 debug_unregister(zcrypt_dbf_common);
1432 debug_unregister(zcrypt_dbf_common); 1432 debug_unregister(zcrypt_dbf_devices);
1433 if (zcrypt_dbf_devices)
1434 debug_unregister(zcrypt_dbf_devices);
1435} 1433}
1436 1434
1437/** 1435/**