diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 16:16:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 16:16:16 -0500 |
commit | cbd88cd4c07f9361914ab7fd7e21c9227986fe68 (patch) | |
tree | 8bc448d73f93f10ebd34ef38c911b06359000ed0 /drivers/s390 | |
parent | 928b3f12e5fea9d201bbc029d8d537ba7cc14fe7 (diff) | |
parent | c2ab7282f0fcd11eea4d0ba45d1c65d89428c314 (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.c | 8 | ||||
-rw-r--r-- | drivers/s390/char/Kconfig | 21 | ||||
-rw-r--r-- | drivers/s390/char/Makefile | 5 | ||||
-rw-r--r-- | drivers/s390/char/con3215.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/con3270.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/hmcdrv_ftp.c | 6 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 5 | ||||
-rw-r--r-- | drivers/s390/char/sclp_config.c | 102 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cpi.c | 40 | ||||
-rw-r--r-- | drivers/s390/char/zcore.c | 450 | ||||
-rw-r--r-- | drivers/s390/cio/Makefile | 5 | ||||
-rw-r--r-- | drivers/s390/cio/airq.c | 1 | ||||
-rw-r--r-- | drivers/s390/cio/chsc_sch.c | 5 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 37 | ||||
-rw-r--r-- | drivers/s390/cio/cio.h | 12 | ||||
-rw-r--r-- | drivers/s390/cio/crw.c | 1 | ||||
-rw-r--r-- | drivers/s390/cio/css.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/io_sch.h | 45 | ||||
-rw-r--r-- | drivers/s390/cio/ioasm.c | 224 | ||||
-rw-r--r-- | drivers/s390/cio/ioasm.h | 169 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.c | 6 | ||||
-rw-r--r-- | drivers/s390/cio/trace.c | 24 | ||||
-rw-r--r-- | drivers/s390/cio/trace.h | 363 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 6 |
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 | ||
81 | config 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 | |||
94 | config SCLP_ASYNC | 81 | config 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 | ||
115 | config 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 | |||
128 | config S390_TAPE | 123 | config 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 | |||
16 | obj-$(CONFIG_SCLP_TTY) += sclp_tty.o | 16 | obj-$(CONFIG_SCLP_TTY) += sclp_tty.o |
17 | obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o | 17 | obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o |
18 | obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o | 18 | obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o |
19 | obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o | ||
20 | obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o | 19 | obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o |
21 | 20 | ||
22 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o | 21 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o |
@@ -30,9 +29,7 @@ obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o | |||
30 | obj-$(CONFIG_MONREADER) += monreader.o | 29 | obj-$(CONFIG_MONREADER) += monreader.o |
31 | obj-$(CONFIG_MONWRITER) += monwriter.o | 30 | obj-$(CONFIG_MONWRITER) += monwriter.o |
32 | obj-$(CONFIG_S390_VMUR) += vmur.o | 31 | obj-$(CONFIG_S390_VMUR) += vmur.o |
33 | 32 | obj-$(CONFIG_CRASH_DUMP) += sclp_sdias.o zcore.o | |
34 | zcore_mod-objs := sclp_sdias.o zcore.o | ||
35 | obj-$(CONFIG_CRASH_DUMP) += zcore_mod.o | ||
36 | 33 | ||
37 | hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o | 34 | hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o |
38 | obj-$(CONFIG_HMC_DRV) += hmcdrv.o | 35 | obj-$(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 { | |||
37 | static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len); | 37 | static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len); |
38 | static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp); | 38 | static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp); |
39 | 39 | ||
40 | static struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ | 40 | static const struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ |
41 | static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */ | 41 | static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */ |
42 | static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */ | 42 | static 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 | */ |
291 | int hmcdrv_ftp_startup(void) | 291 | int 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 | |||
27 | struct 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 | |||
33 | struct 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 | ||
26 | static struct work_struct sclp_cpu_capability_work; | 42 | static struct work_struct sclp_cpu_capability_work; |
27 | static struct work_struct sclp_cpu_change_work; | 43 | static struct work_struct sclp_cpu_change_work; |
@@ -63,15 +79,99 @@ static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) | |||
63 | 79 | ||
64 | static struct sclp_register sclp_conf_register = | 80 | static 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 | ||
90 | static 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 | } | ||
123 | out: | ||
124 | free_page((unsigned long)sccb); | ||
125 | return rc; | ||
126 | } | ||
127 | |||
128 | static 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 | |||
138 | static 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 | |||
147 | static 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 | |||
70 | static int __init sclp_conf_init(void) | 165 | static 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 | |||
15 | MODULE_LICENSE("GPL"); | ||
16 | MODULE_DESCRIPTION("Identify this operating system instance " | ||
17 | "to the System z hardware"); | ||
18 | MODULE_AUTHOR("Martin Peschke <mpeschke@de.ibm.com>, " | ||
19 | "Michael Ernst <mernst@de.ibm.com>"); | ||
20 | |||
21 | static char *system_name = ""; | ||
22 | static char *sysplex_name = ""; | ||
23 | |||
24 | module_param(system_name, charp, 0); | ||
25 | MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters"); | ||
26 | module_param(sysplex_name, charp, 0); | ||
27 | MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters"); | ||
28 | |||
29 | static int __init cpi_module_init(void) | ||
30 | { | ||
31 | return sclp_cpi_set_data(system_name, sysplex_name, "LINUX", | ||
32 | LINUX_VERSION_CODE); | ||
33 | } | ||
34 | |||
35 | static void __exit cpi_module_exit(void) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | module_init(cpi_module_init); | ||
40 | module_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 | ||
40 | enum arch_id { | 39 | enum 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 | |||
47 | struct 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 | |||
56 | struct ipib_info { | 44 | struct ipib_info { |
57 | unsigned long ipib; | 45 | unsigned long ipib; |
58 | u32 checksum; | 46 | u32 checksum; |
59 | } __attribute__((packed)); | 47 | } __attribute__((packed)); |
60 | 48 | ||
61 | static struct sys_info sys_info; | ||
62 | static struct debug_info *zcore_dbf; | 49 | static struct debug_info *zcore_dbf; |
63 | static int hsa_available; | 50 | static int hsa_available; |
64 | static struct dentry *zcore_dir; | 51 | static struct dentry *zcore_dir; |
65 | static struct dentry *zcore_file; | ||
66 | static struct dentry *zcore_memmap_file; | 52 | static struct dentry *zcore_memmap_file; |
67 | static struct dentry *zcore_reipl_file; | 53 | static struct dentry *zcore_reipl_file; |
68 | static struct dentry *zcore_hsa_file; | 54 | static struct dentry *zcore_hsa_file; |
69 | static struct ipl_parameter_block *ipl_block; | 55 | static struct ipl_parameter_block *ipl_block; |
70 | 56 | ||
57 | static 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 | */ |
79 | int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) | 66 | int 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; |
137 | out: | 84 | count -= bytes; |
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static 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 | |||
146 | static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) | ||
147 | { | ||
148 | return memcpy_hsa(dest, src, count, TO_KERNEL); | ||
149 | } | ||
150 | |||
151 | static 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 | ||
171 | static 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 | |||
181 | struct 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 | |||
208 | static 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 | */ |
226 | static int copy_lc(void __user *buf, void *sa, int sa_off, int len) | 96 | int 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 | /* | 118 | static 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 | */ | ||
247 | static 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 | */ | ||
298 | static 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; | ||
363 | fail: | ||
364 | mutex_unlock(&zcore_mutex); | ||
365 | return (rc < 0) ? rc : count; | ||
366 | } | ||
367 | |||
368 | static 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 | |||
376 | static int zcore_release(struct inode *inode, struct file *filep) | ||
377 | { | ||
378 | if (hsa_available) | ||
379 | release_hsa(); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static 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 | |||
393 | static 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 | |||
401 | static ssize_t zcore_memmap_read(struct file *filp, char __user *buf, | 143 | static 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 | ||
504 | static 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 | */ | ||
521 | static 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 | |||
548 | static int __init check_sdias(void) | 246 | static 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 | ||
557 | static 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 | |||
568 | static 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 | ||
624 | static int __init zcore_init(void) | 285 | static 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); |
710 | fail_memmap_file: | 359 | fail_memmap_file: |
711 | debugfs_remove(zcore_memmap_file); | 360 | debugfs_remove(zcore_memmap_file); |
712 | fail_file: | ||
713 | debugfs_remove(zcore_file); | ||
714 | fail_dir: | 361 | fail_dir: |
715 | debugfs_remove(zcore_dir); | 362 | debugfs_remove(zcore_dir); |
716 | fail: | 363 | fail: |
@@ -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 | ||
6 | CFLAGS_trace.o := -I$(src) | ||
7 | |||
5 | obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ | 8 | obj-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 |
7 | ccw_device-objs += device.o device_fsm.o device_ops.o | 10 | ccw_device-objs += device.o device_fsm.o device_ops.o |
8 | ccw_device-objs += device_id.o device_pgid.o device_status.o | 11 | ccw_device-objs += device_id.o device_pgid.o device_status.o |
9 | obj-y += ccw_device.o cmf.o | 12 | obj-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; |
187 | out: | 187 | out: |
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 | ||
45 | debug_info_t *cio_debug_msg_id; | 46 | debug_info_t *cio_debug_msg_id; |
46 | debug_info_t *cio_debug_trace_id; | 47 | debug_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 | ||
78 | out_unregister: | 79 | out_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 | } |
801 | out: | 800 | out: |
@@ -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). */ | ||
49 | struct 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. */ |
49 | struct schib_config { | 61 | struct 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 | ||
18 | static DEFINE_MUTEX(crw_handler_mutex); | 19 | static DEFINE_MUTEX(crw_handler_mutex); |
19 | static crw_handler_t crw_handlers[NR_RSCS]; | 20 | static 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 | ||
172 | static 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 | |||
187 | static 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 | |||
202 | static 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 | |||
15 | int 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 | } | ||
33 | EXPORT_SYMBOL(stsch); | ||
34 | |||
35 | int 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 | |||
54 | int 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 | |||
71 | int 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 | } | ||
89 | EXPORT_SYMBOL(ssch); | ||
90 | |||
91 | int 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 | } | ||
107 | EXPORT_SYMBOL(csch); | ||
108 | |||
109 | int 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 | |||
125 | int 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 | } | ||
141 | EXPORT_SYMBOL(chsc); | ||
142 | |||
143 | int 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 | |||
159 | int 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 | |||
176 | int 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 | |||
193 | int 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 | |||
210 | int 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 | */ |
12 | struct 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 | 15 | int stsch(struct subchannel_id schid, struct schib *addr); | |
24 | /* | 16 | int msch(struct subchannel_id schid, struct schib *addr); |
25 | * Some S390 specific IO instructions as inline | 17 | int tsch(struct subchannel_id schid, struct irb *addr); |
26 | */ | 18 | int ssch(struct subchannel_id schid, union orb *addr); |
27 | 19 | int csch(struct subchannel_id schid); | |
28 | static inline int stsch_err(struct subchannel_id schid, struct schib *addr) | 20 | int tpi(struct tpi_info *addr); |
29 | { | 21 | int chsc(void *chsc_area); |
30 | register struct subchannel_id reg1 asm ("1") = schid; | 22 | int rchp(struct chp_id chpid); |
31 | int ccode = -EIO; | 23 | int rsch(struct subchannel_id schid); |
32 | 24 | int hsch(struct subchannel_id schid); | |
33 | asm volatile( | 25 | int xsch(struct subchannel_id schid); |
34 | " stsch 0(%3)\n" | 26 | int 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 | |||
45 | static 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 | |||
60 | static 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 | |||
77 | static 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 | |||
92 | static 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 | |||
109 | static 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 | |||
124 | static 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 | |||
138 | static 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 | |||
153 | static 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 | |||
14 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_stsch); | ||
15 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_msch); | ||
16 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_tsch); | ||
17 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_tpi); | ||
18 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_ssch); | ||
19 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_csch); | ||
20 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_hsch); | ||
21 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_xsch); | ||
22 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_rsch); | ||
23 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_rchp); | ||
24 | EXPORT_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 | |||
23 | DECLARE_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 | */ | ||
61 | DEFINE_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 | */ | ||
72 | DEFINE_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 | */ | ||
83 | TRACE_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 | */ | ||
115 | TRACE_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 | */ | ||
152 | TRACE_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 | |||
174 | DECLARE_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 | */ | ||
199 | DEFINE_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 | */ | ||
209 | DEFINE_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 | */ | ||
219 | DEFINE_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 | */ | ||
229 | DEFINE_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 | */ | ||
239 | TRACE_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 | */ | ||
265 | TRACE_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 | */ | ||
293 | TRACE_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 | */ | ||
318 | TRACE_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 | */ | ||
335 | TRACE_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) | |||
1428 | void zcrypt_debug_exit(void) | 1428 | void 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 | /** |