aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/s390/char
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/Kconfig77
-rw-r--r--drivers/s390/char/Makefile3
-rw-r--r--drivers/s390/char/con3215.c8
-rw-r--r--drivers/s390/char/fs3270.c2
-rw-r--r--drivers/s390/char/keyboard.c7
-rw-r--r--drivers/s390/char/keyboard.h2
-rw-r--r--drivers/s390/char/monreader.c1
-rw-r--r--drivers/s390/char/monwriter.c5
-rw-r--r--drivers/s390/char/raw3270.c12
-rw-r--r--drivers/s390/char/sclp.c39
-rw-r--r--drivers/s390/char/sclp.h24
-rw-r--r--drivers/s390/char/sclp_cmd.c2
-rw-r--r--drivers/s390/char/sclp_config.c15
-rw-r--r--drivers/s390/char/sclp_ocf.c145
-rw-r--r--drivers/s390/char/sclp_sdias.c3
-rw-r--r--drivers/s390/char/sclp_tty.c122
-rw-r--r--drivers/s390/char/tape.h8
-rw-r--r--drivers/s390/char/tape_34xx.c65
-rw-r--r--drivers/s390/char/tape_3590.c124
-rw-r--r--drivers/s390/char/tape_block.c444
-rw-r--r--drivers/s390/char/tape_char.c4
-rw-r--r--drivers/s390/char/tape_class.h1
-rw-r--r--drivers/s390/char/tape_core.c79
-rw-r--r--drivers/s390/char/tape_std.c7
-rw-r--r--drivers/s390/char/tty3270.c16
-rw-r--r--drivers/s390/char/vmcp.c7
-rw-r--r--drivers/s390/char/vmlogrdr.c42
-rw-r--r--drivers/s390/char/vmur.c9
-rw-r--r--drivers/s390/char/vmwatchdog.c1
-rw-r--r--drivers/s390/char/zcore.c2
30 files changed, 551 insertions, 725 deletions
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig
index 40834f18754c..a4f117d9fdc6 100644
--- a/drivers/s390/char/Kconfig
+++ b/drivers/s390/char/Kconfig
@@ -2,76 +2,85 @@ comment "S/390 character device drivers"
2 depends on S390 2 depends on S390
3 3
4config TN3270 4config TN3270
5 tristate "Support for locally attached 3270 terminals" 5 def_tristate y
6 prompt "Support for locally attached 3270 terminals"
6 depends on CCW 7 depends on CCW
7 help 8 help
8 Include support for IBM 3270 terminals. 9 Include support for IBM 3270 terminals.
9 10
10config TN3270_TTY 11config TN3270_TTY
11 tristate "Support for tty input/output on 3270 terminals" 12 def_tristate y
13 prompt "Support for tty input/output on 3270 terminals"
12 depends on TN3270 14 depends on TN3270
13 help 15 help
14 Include support for using an IBM 3270 terminal as a Linux tty. 16 Include support for using an IBM 3270 terminal as a Linux tty.
15 17
16config TN3270_FS 18config TN3270_FS
17 tristate "Support for fullscreen applications on 3270 terminals" 19 def_tristate m
20 prompt "Support for fullscreen applications on 3270 terminals"
18 depends on TN3270 21 depends on TN3270
19 help 22 help
20 Include support for fullscreen applications on an IBM 3270 terminal. 23 Include support for fullscreen applications on an IBM 3270 terminal.
21 24
22config TN3270_CONSOLE 25config TN3270_CONSOLE
23 bool "Support for console on 3270 terminal" 26 def_bool y
27 prompt "Support for console on 3270 terminal"
24 depends on TN3270=y && TN3270_TTY=y 28 depends on TN3270=y && TN3270_TTY=y
25 help 29 help
26 Include support for using an IBM 3270 terminal as a Linux system 30 Include support for using an IBM 3270 terminal as a Linux system
27 console. Available only if 3270 support is compiled in statically. 31 console. Available only if 3270 support is compiled in statically.
28 32
29config TN3215 33config TN3215
30 bool "Support for 3215 line mode terminal" 34 def_bool y
35 prompt "Support for 3215 line mode terminal"
31 depends on CCW 36 depends on CCW
32 help 37 help
33 Include support for IBM 3215 line-mode terminals. 38 Include support for IBM 3215 line-mode terminals.
34 39
35config TN3215_CONSOLE 40config TN3215_CONSOLE
36 bool "Support for console on 3215 line mode terminal" 41 def_bool y
42 prompt "Support for console on 3215 line mode terminal"
37 depends on TN3215 43 depends on TN3215
38 help 44 help
39 Include support for using an IBM 3215 line-mode terminal as a 45 Include support for using an IBM 3215 line-mode terminal as a
40 Linux system console. 46 Linux system console.
41 47
42config CCW_CONSOLE 48config CCW_CONSOLE
43 bool 49 def_bool y if TN3215_CONSOLE || TN3270_CONSOLE
44 depends on TN3215_CONSOLE || TN3270_CONSOLE
45 default y
46 50
47config SCLP_TTY 51config SCLP_TTY
48 bool "Support for SCLP line mode terminal" 52 def_bool y
53 prompt "Support for SCLP line mode terminal"
49 depends on S390 54 depends on S390
50 help 55 help
51 Include support for IBM SCLP line-mode terminals. 56 Include support for IBM SCLP line-mode terminals.
52 57
53config SCLP_CONSOLE 58config SCLP_CONSOLE
54 bool "Support for console on SCLP line mode terminal" 59 def_bool y
60 prompt "Support for console on SCLP line mode terminal"
55 depends on SCLP_TTY 61 depends on SCLP_TTY
56 help 62 help
57 Include support for using an IBM HWC line-mode terminal as the Linux 63 Include support for using an IBM HWC line-mode terminal as the Linux
58 system console. 64 system console.
59 65
60config SCLP_VT220_TTY 66config SCLP_VT220_TTY
61 bool "Support for SCLP VT220-compatible terminal" 67 def_bool y
68 prompt "Support for SCLP VT220-compatible terminal"
62 depends on S390 69 depends on S390
63 help 70 help
64 Include support for an IBM SCLP VT220-compatible terminal. 71 Include support for an IBM SCLP VT220-compatible terminal.
65 72
66config SCLP_VT220_CONSOLE 73config SCLP_VT220_CONSOLE
67 bool "Support for console on SCLP VT220-compatible terminal" 74 def_bool y
75 prompt "Support for console on SCLP VT220-compatible terminal"
68 depends on SCLP_VT220_TTY 76 depends on SCLP_VT220_TTY
69 help 77 help
70 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
71 Linux system console. 79 Linux system console.
72 80
73config SCLP_CPI 81config SCLP_CPI
74 tristate "Control-Program Identification" 82 def_tristate m
83 prompt "Control-Program Identification"
75 depends on S390 84 depends on S390
76 help 85 help
77 This option enables the hardware console interface for system 86 This option enables the hardware console interface for system
@@ -83,7 +92,8 @@ config SCLP_CPI
83 need this feature and intend to run your kernel in LPAR. 92 need this feature and intend to run your kernel in LPAR.
84 93
85config SCLP_ASYNC 94config SCLP_ASYNC
86 tristate "Support for Call Home via Asynchronous SCLP Records" 95 def_tristate m
96 prompt "Support for Call Home via Asynchronous SCLP Records"
87 depends on S390 97 depends on S390
88 help 98 help
89 This option enables the call home function, which is able to inform 99 This option enables the call home function, which is able to inform
@@ -93,7 +103,8 @@ config SCLP_ASYNC
93 need this feature and intend to run your kernel in LPAR. 103 need this feature and intend to run your kernel in LPAR.
94 104
95config S390_TAPE 105config S390_TAPE
96 tristate "S/390 tape device support" 106 def_tristate m
107 prompt "S/390 tape device support"
97 depends on CCW 108 depends on CCW
98 help 109 help
99 Select this option if you want to access channel-attached tape 110 Select this option if you want to access channel-attached tape
@@ -108,22 +119,12 @@ config S390_TAPE
108comment "S/390 tape interface support" 119comment "S/390 tape interface support"
109 depends on S390_TAPE 120 depends on S390_TAPE
110 121
111config S390_TAPE_BLOCK
112 bool "Support for tape block devices"
113 depends on S390_TAPE && BLOCK
114 help
115 Select this option if you want to access your channel-attached tape
116 devices using the block device interface. This interface is similar
117 to CD-ROM devices on other platforms. The tapes can only be
118 accessed read-only when using this interface. Have a look at
119 <file:Documentation/s390/TAPE> for further information about creating
120 volumes for and using this interface. It is safe to say "Y" here.
121
122comment "S/390 tape hardware support" 122comment "S/390 tape hardware support"
123 depends on S390_TAPE 123 depends on S390_TAPE
124 124
125config S390_TAPE_34XX 125config S390_TAPE_34XX
126 tristate "Support for 3480/3490 tape hardware" 126 def_tristate m
127 prompt "Support for 3480/3490 tape hardware"
127 depends on S390_TAPE 128 depends on S390_TAPE
128 help 129 help
129 Select this option if you want to access IBM 3480/3490 magnetic 130 Select this option if you want to access IBM 3480/3490 magnetic
@@ -131,7 +132,8 @@ config S390_TAPE_34XX
131 It is safe to say "Y" here. 132 It is safe to say "Y" here.
132 133
133config S390_TAPE_3590 134config S390_TAPE_3590
134 tristate "Support for 3590 tape hardware" 135 def_tristate m
136 prompt "Support for 3590 tape hardware"
135 depends on S390_TAPE 137 depends on S390_TAPE
136 help 138 help
137 Select this option if you want to access IBM 3590 magnetic 139 Select this option if you want to access IBM 3590 magnetic
@@ -139,7 +141,8 @@ config S390_TAPE_3590
139 It is safe to say "Y" here. 141 It is safe to say "Y" here.
140 142
141config VMLOGRDR 143config VMLOGRDR
142 tristate "Support for the z/VM recording system services (VM only)" 144 def_tristate m
145 prompt "Support for the z/VM recording system services (VM only)"
143 depends on IUCV 146 depends on IUCV
144 help 147 help
145 Select this option if you want to be able to receive records collected 148 Select this option if you want to be able to receive records collected
@@ -148,29 +151,31 @@ config VMLOGRDR
148 This driver depends on the IUCV support driver. 151 This driver depends on the IUCV support driver.
149 152
150config VMCP 153config VMCP
151 bool "Support for the z/VM CP interface" 154 def_bool y
155 prompt "Support for the z/VM CP interface"
152 depends on S390 156 depends on S390
153 help 157 help
154 Select this option if you want to be able to interact with the control 158 Select this option if you want to be able to interact with the control
155 program on z/VM 159 program on z/VM
156 160
157config MONREADER 161config MONREADER
158 tristate "API for reading z/VM monitor service records" 162 def_tristate m
163 prompt "API for reading z/VM monitor service records"
159 depends on IUCV 164 depends on IUCV
160 help 165 help
161 Character device driver for reading z/VM monitor service records 166 Character device driver for reading z/VM monitor service records
162 167
163config MONWRITER 168config MONWRITER
164 tristate "API for writing z/VM monitor service records" 169 def_tristate m
170 prompt "API for writing z/VM monitor service records"
165 depends on S390 171 depends on S390
166 default "m"
167 help 172 help
168 Character device driver for writing z/VM monitor service records 173 Character device driver for writing z/VM monitor service records
169 174
170config S390_VMUR 175config S390_VMUR
171 tristate "z/VM unit record device driver" 176 def_tristate m
177 prompt "z/VM unit record device driver"
172 depends on S390 178 depends on S390
173 default "m"
174 help 179 help
175 Character device driver for z/VM reader, puncher and printer. 180 Character device driver for z/VM reader, puncher and printer.
176 181
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index efb500ab66c0..f3c325207445 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ 5obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
6 sclp_cmd.o sclp_config.o sclp_cpi_sys.o 6 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o
7 7
8obj-$(CONFIG_TN3270) += raw3270.o 8obj-$(CONFIG_TN3270) += raw3270.o
9obj-$(CONFIG_TN3270_CONSOLE) += con3270.o 9obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
@@ -22,7 +22,6 @@ obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o
22obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o 22obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
23obj-$(CONFIG_VMCP) += vmcp.o 23obj-$(CONFIG_VMCP) += vmcp.o
24 24
25tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o
26tape-$(CONFIG_PROC_FS) += tape_proc.o 25tape-$(CONFIG_PROC_FS) += tape_proc.o
27tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y) 26tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y)
28obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o 27obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 59ec073724bf..694464c65fcd 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -9,6 +9,7 @@
9 * Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu> 9 * Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu>
10 */ 10 */
11 11
12#include <linux/kernel_stat.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kdev_t.h> 15#include <linux/kdev_t.h>
@@ -361,6 +362,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
361 int cstat, dstat; 362 int cstat, dstat;
362 int count; 363 int count;
363 364
365 kstat_cpu(smp_processor_id()).irqs[IOINT_C15]++;
364 raw = dev_get_drvdata(&cdev->dev); 366 raw = dev_get_drvdata(&cdev->dev);
365 req = (struct raw3215_req *) intparm; 367 req = (struct raw3215_req *) intparm;
366 cstat = irb->scsw.cmd.cstat; 368 cstat = irb->scsw.cmd.cstat;
@@ -762,8 +764,10 @@ static struct ccw_device_id raw3215_id[] = {
762}; 764};
763 765
764static struct ccw_driver raw3215_ccw_driver = { 766static struct ccw_driver raw3215_ccw_driver = {
765 .name = "3215", 767 .driver = {
766 .owner = THIS_MODULE, 768 .name = "3215",
769 .owner = THIS_MODULE,
770 },
767 .ids = raw3215_id, 771 .ids = raw3215_id,
768 .probe = &raw3215_probe, 772 .probe = &raw3215_probe,
769 .remove = &raw3215_remove, 773 .remove = &raw3215_remove,
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 857dfcb7b359..f6489eb7e976 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -14,7 +14,6 @@
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/smp_lock.h>
18 17
19#include <asm/compat.h> 18#include <asm/compat.h>
20#include <asm/ccwdev.h> 19#include <asm/ccwdev.h>
@@ -520,6 +519,7 @@ static const struct file_operations fs3270_fops = {
520 .compat_ioctl = fs3270_ioctl, /* ioctl */ 519 .compat_ioctl = fs3270_ioctl, /* ioctl */
521 .open = fs3270_open, /* open */ 520 .open = fs3270_open, /* open */
522 .release = fs3270_close, /* release */ 521 .release = fs3270_close, /* release */
522 .llseek = no_llseek,
523}; 523};
524 524
525/* 525/*
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index 8cd58e412b5e..806588192483 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -455,12 +455,11 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
455 return 0; 455 return 0;
456} 456}
457 457
458int 458int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
459kbd_ioctl(struct kbd_data *kbd, struct file *file,
460 unsigned int cmd, unsigned long arg)
461{ 459{
462 void __user *argp; 460 void __user *argp;
463 int ct, perm; 461 unsigned int ct;
462 int perm;
464 463
465 argp = (void __user *)arg; 464 argp = (void __user *)arg;
466 465
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 5ccfe9cf126d..7e736aaeae6e 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -36,7 +36,7 @@ void kbd_free(struct kbd_data *);
36void kbd_ascebc(struct kbd_data *, unsigned char *); 36void kbd_ascebc(struct kbd_data *, unsigned char *);
37 37
38void kbd_keycode(struct kbd_data *, unsigned int); 38void kbd_keycode(struct kbd_data *, unsigned int);
39int kbd_ioctl(struct kbd_data *, struct file *, unsigned int, unsigned long); 39int kbd_ioctl(struct kbd_data *, unsigned int, unsigned long);
40 40
41/* 41/*
42 * Helper Functions. 42 * Helper Functions.
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index e021ec663ef9..5b8b8592d311 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -447,6 +447,7 @@ static const struct file_operations mon_fops = {
447 .release = &mon_close, 447 .release = &mon_close,
448 .read = &mon_read, 448 .read = &mon_read,
449 .poll = &mon_poll, 449 .poll = &mon_poll,
450 .llseek = noop_llseek,
450}; 451};
451 452
452static struct miscdevice mon_dev = { 453static struct miscdevice mon_dev = {
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 572a1e7fd099..4600aa10a1c6 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -97,7 +97,7 @@ static int monwrite_new_hdr(struct mon_private *monpriv)
97{ 97{
98 struct monwrite_hdr *monhdr = &monpriv->hdr; 98 struct monwrite_hdr *monhdr = &monpriv->hdr;
99 struct mon_buf *monbuf; 99 struct mon_buf *monbuf;
100 int rc; 100 int rc = 0;
101 101
102 if (monhdr->datalen > MONWRITE_MAX_DATALEN || 102 if (monhdr->datalen > MONWRITE_MAX_DATALEN ||
103 monhdr->mon_function > MONWRITE_START_CONFIG || 103 monhdr->mon_function > MONWRITE_START_CONFIG ||
@@ -135,7 +135,7 @@ static int monwrite_new_hdr(struct mon_private *monpriv)
135 mon_buf_count++; 135 mon_buf_count++;
136 } 136 }
137 monpriv->current_buf = monbuf; 137 monpriv->current_buf = monbuf;
138 return 0; 138 return rc;
139} 139}
140 140
141static int monwrite_new_data(struct mon_private *monpriv) 141static int monwrite_new_data(struct mon_private *monpriv)
@@ -274,6 +274,7 @@ static const struct file_operations monwrite_fops = {
274 .open = &monwrite_open, 274 .open = &monwrite_open,
275 .release = &monwrite_close, 275 .release = &monwrite_close,
276 .write = &monwrite_write, 276 .write = &monwrite_write,
277 .llseek = noop_llseek,
277}; 278};
278 279
279static struct miscdevice mon_dev = { 280static struct miscdevice mon_dev = {
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 2a4c566456e7..810ac38631c3 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -7,6 +7,7 @@
7 * Copyright IBM Corp. 2003, 2009 7 * Copyright IBM Corp. 2003, 2009
8 */ 8 */
9 9
10#include <linux/kernel_stat.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/err.h> 12#include <linux/err.h>
12#include <linux/init.h> 13#include <linux/init.h>
@@ -329,6 +330,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
329 struct raw3270_request *rq; 330 struct raw3270_request *rq;
330 int rc; 331 int rc;
331 332
333 kstat_cpu(smp_processor_id()).irqs[IOINT_C70]++;
332 rp = dev_get_drvdata(&cdev->dev); 334 rp = dev_get_drvdata(&cdev->dev);
333 if (!rp) 335 if (!rp)
334 return; 336 return;
@@ -596,13 +598,12 @@ __raw3270_size_device(struct raw3270 *rp)
596 static const unsigned char wbuf[] = 598 static const unsigned char wbuf[] =
597 { 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 }; 599 { 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 };
598 struct raw3270_ua *uap; 600 struct raw3270_ua *uap;
599 unsigned short count;
600 int rc; 601 int rc;
601 602
602 /* 603 /*
603 * To determine the size of the 3270 device we need to do: 604 * To determine the size of the 3270 device we need to do:
604 * 1) send a 'read partition' data stream to the device 605 * 1) send a 'read partition' data stream to the device
605 * 2) wait for the attn interrupt that preceeds the query reply 606 * 2) wait for the attn interrupt that precedes the query reply
606 * 3) do a read modified to get the query reply 607 * 3) do a read modified to get the query reply
607 * To make things worse we have to cope with intervention 608 * To make things worse we have to cope with intervention
608 * required (3270 device switched to 'stand-by') and command 609 * required (3270 device switched to 'stand-by') and command
@@ -651,7 +652,6 @@ __raw3270_size_device(struct raw3270 *rp)
651 if (rc) 652 if (rc)
652 return rc; 653 return rc;
653 /* Got a Query Reply */ 654 /* Got a Query Reply */
654 count = sizeof(rp->init_data) - rp->init_request.rescnt;
655 uap = (struct raw3270_ua *) (rp->init_data + 1); 655 uap = (struct raw3270_ua *) (rp->init_data + 1);
656 /* Paranoia check. */ 656 /* Paranoia check. */
657 if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81) 657 if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81)
@@ -1386,8 +1386,10 @@ static struct ccw_device_id raw3270_id[] = {
1386}; 1386};
1387 1387
1388static struct ccw_driver raw3270_ccw_driver = { 1388static struct ccw_driver raw3270_ccw_driver = {
1389 .name = "3270", 1389 .driver = {
1390 .owner = THIS_MODULE, 1390 .name = "3270",
1391 .owner = THIS_MODULE,
1392 },
1391 .ids = raw3270_id, 1393 .ids = raw3270_id,
1392 .probe = &raw3270_probe, 1394 .probe = &raw3270_probe,
1393 .remove = &raw3270_remove, 1395 .remove = &raw3270_remove,
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index f6d72e1f2a38..eaa7e78186f9 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -7,6 +7,7 @@
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 */ 8 */
9 9
10#include <linux/kernel_stat.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/err.h> 12#include <linux/err.h>
12#include <linux/spinlock.h> 13#include <linux/spinlock.h>
@@ -19,15 +20,12 @@
19#include <linux/completion.h> 20#include <linux/completion.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <asm/types.h> 22#include <asm/types.h>
22#include <asm/s390_ext.h> 23#include <asm/irq.h>
23 24
24#include "sclp.h" 25#include "sclp.h"
25 26
26#define SCLP_HEADER "sclp: " 27#define SCLP_HEADER "sclp: "
27 28
28/* Structure for register_early_external_interrupt. */
29static ext_int_info_t ext_int_info_hwc;
30
31/* Lock to protect internal data consistency. */ 29/* Lock to protect internal data consistency. */
32static DEFINE_SPINLOCK(sclp_lock); 30static DEFINE_SPINLOCK(sclp_lock);
33 31
@@ -395,16 +393,17 @@ __sclp_find_req(u32 sccb)
395/* Handler for external interruption. Perform request post-processing. 393/* Handler for external interruption. Perform request post-processing.
396 * Prepare read event data request if necessary. Start processing of next 394 * Prepare read event data request if necessary. Start processing of next
397 * request on queue. */ 395 * request on queue. */
398static void 396static void sclp_interrupt_handler(unsigned int ext_int_code,
399sclp_interrupt_handler(__u16 code) 397 unsigned int param32, unsigned long param64)
400{ 398{
401 struct sclp_req *req; 399 struct sclp_req *req;
402 u32 finished_sccb; 400 u32 finished_sccb;
403 u32 evbuf_pending; 401 u32 evbuf_pending;
404 402
403 kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++;
405 spin_lock(&sclp_lock); 404 spin_lock(&sclp_lock);
406 finished_sccb = S390_lowcore.ext_params & 0xfffffff8; 405 finished_sccb = param32 & 0xfffffff8;
407 evbuf_pending = S390_lowcore.ext_params & 0x3; 406 evbuf_pending = param32 & 0x3;
408 if (finished_sccb) { 407 if (finished_sccb) {
409 del_timer(&sclp_request_timer); 408 del_timer(&sclp_request_timer);
410 sclp_running_state = sclp_running_state_reset_pending; 409 sclp_running_state = sclp_running_state_reset_pending;
@@ -468,7 +467,7 @@ sclp_sync_wait(void)
468 cr0_sync &= 0xffff00a0; 467 cr0_sync &= 0xffff00a0;
469 cr0_sync |= 0x00000200; 468 cr0_sync |= 0x00000200;
470 __ctl_load(cr0_sync, 0, 0); 469 __ctl_load(cr0_sync, 0, 0);
471 __raw_local_irq_stosm(0x01); 470 __arch_local_irq_stosm(0x01);
472 /* Loop until driver state indicates finished request */ 471 /* Loop until driver state indicates finished request */
473 while (sclp_running_state != sclp_running_state_idle) { 472 while (sclp_running_state != sclp_running_state_idle) {
474 /* Check for expired request timer */ 473 /* Check for expired request timer */
@@ -819,12 +818,13 @@ EXPORT_SYMBOL(sclp_reactivate);
819 818
820/* Handler for external interruption used during initialization. Modify 819/* Handler for external interruption used during initialization. Modify
821 * request state to done. */ 820 * request state to done. */
822static void 821static void sclp_check_handler(unsigned int ext_int_code,
823sclp_check_handler(__u16 code) 822 unsigned int param32, unsigned long param64)
824{ 823{
825 u32 finished_sccb; 824 u32 finished_sccb;
826 825
827 finished_sccb = S390_lowcore.ext_params & 0xfffffff8; 826 kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++;
827 finished_sccb = param32 & 0xfffffff8;
828 /* Is this the interrupt we are waiting for? */ 828 /* Is this the interrupt we are waiting for? */
829 if (finished_sccb == 0) 829 if (finished_sccb == 0)
830 return; 830 return;
@@ -866,8 +866,7 @@ sclp_check_interface(void)
866 866
867 spin_lock_irqsave(&sclp_lock, flags); 867 spin_lock_irqsave(&sclp_lock, flags);
868 /* Prepare init mask command */ 868 /* Prepare init mask command */
869 rc = register_early_external_interrupt(0x2401, sclp_check_handler, 869 rc = register_external_interrupt(0x2401, sclp_check_handler);
870 &ext_int_info_hwc);
871 if (rc) { 870 if (rc) {
872 spin_unlock_irqrestore(&sclp_lock, flags); 871 spin_unlock_irqrestore(&sclp_lock, flags);
873 return rc; 872 return rc;
@@ -885,12 +884,12 @@ sclp_check_interface(void)
885 spin_unlock_irqrestore(&sclp_lock, flags); 884 spin_unlock_irqrestore(&sclp_lock, flags);
886 /* Enable service-signal interruption - needs to happen 885 /* Enable service-signal interruption - needs to happen
887 * with IRQs enabled. */ 886 * with IRQs enabled. */
888 ctl_set_bit(0, 9); 887 service_subclass_irq_register();
889 /* Wait for signal from interrupt or timeout */ 888 /* Wait for signal from interrupt or timeout */
890 sclp_sync_wait(); 889 sclp_sync_wait();
891 /* Disable service-signal interruption - needs to happen 890 /* Disable service-signal interruption - needs to happen
892 * with IRQs enabled. */ 891 * with IRQs enabled. */
893 ctl_clear_bit(0,9); 892 service_subclass_irq_unregister();
894 spin_lock_irqsave(&sclp_lock, flags); 893 spin_lock_irqsave(&sclp_lock, flags);
895 del_timer(&sclp_request_timer); 894 del_timer(&sclp_request_timer);
896 if (sclp_init_req.status == SCLP_REQ_DONE && 895 if (sclp_init_req.status == SCLP_REQ_DONE &&
@@ -900,8 +899,7 @@ sclp_check_interface(void)
900 } else 899 } else
901 rc = -EBUSY; 900 rc = -EBUSY;
902 } 901 }
903 unregister_early_external_interrupt(0x2401, sclp_check_handler, 902 unregister_external_interrupt(0x2401, sclp_check_handler);
904 &ext_int_info_hwc);
905 spin_unlock_irqrestore(&sclp_lock, flags); 903 spin_unlock_irqrestore(&sclp_lock, flags);
906 return rc; 904 return rc;
907} 905}
@@ -1064,15 +1062,14 @@ sclp_init(void)
1064 if (rc) 1062 if (rc)
1065 goto fail_init_state_uninitialized; 1063 goto fail_init_state_uninitialized;
1066 /* Register interrupt handler */ 1064 /* Register interrupt handler */
1067 rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler, 1065 rc = register_external_interrupt(0x2401, sclp_interrupt_handler);
1068 &ext_int_info_hwc);
1069 if (rc) 1066 if (rc)
1070 goto fail_unregister_reboot_notifier; 1067 goto fail_unregister_reboot_notifier;
1071 sclp_init_state = sclp_init_state_initialized; 1068 sclp_init_state = sclp_init_state_initialized;
1072 spin_unlock_irqrestore(&sclp_lock, flags); 1069 spin_unlock_irqrestore(&sclp_lock, flags);
1073 /* Enable service-signal external interruption - needs to happen with 1070 /* Enable service-signal external interruption - needs to happen with
1074 * IRQs enabled. */ 1071 * IRQs enabled. */
1075 ctl_set_bit(0, 9); 1072 service_subclass_irq_register();
1076 sclp_init_mask(1); 1073 sclp_init_mask(1);
1077 return 0; 1074 return 0;
1078 1075
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 6bb5a6bdfab5..49a1bb52bc87 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -28,6 +28,7 @@
28#define EVTYP_CONFMGMDATA 0x04 28#define EVTYP_CONFMGMDATA 0x04
29#define EVTYP_SDIAS 0x1C 29#define EVTYP_SDIAS 0x1C
30#define EVTYP_ASYNC 0x0A 30#define EVTYP_ASYNC 0x0A
31#define EVTYP_OCF 0x1E
31 32
32#define EVTYP_OPCMD_MASK 0x80000000 33#define EVTYP_OPCMD_MASK 0x80000000
33#define EVTYP_MSG_MASK 0x40000000 34#define EVTYP_MSG_MASK 0x40000000
@@ -40,6 +41,7 @@
40#define EVTYP_CONFMGMDATA_MASK 0x10000000 41#define EVTYP_CONFMGMDATA_MASK 0x10000000
41#define EVTYP_SDIAS_MASK 0x00000010 42#define EVTYP_SDIAS_MASK 0x00000010
42#define EVTYP_ASYNC_MASK 0x00400000 43#define EVTYP_ASYNC_MASK 0x00400000
44#define EVTYP_OCF_MASK 0x00000004
43 45
44#define GNRLMSGFLGS_DOM 0x8000 46#define GNRLMSGFLGS_DOM 0x8000
45#define GNRLMSGFLGS_SNDALRM 0x4000 47#define GNRLMSGFLGS_SNDALRM 0x4000
@@ -186,4 +188,26 @@ sclp_ascebc_str(unsigned char *str, int nr)
186 (MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr); 188 (MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr);
187} 189}
188 190
191static inline struct gds_vector *
192sclp_find_gds_vector(void *start, void *end, u16 id)
193{
194 struct gds_vector *v;
195
196 for (v = start; (void *) v < end; v = (void *) v + v->length)
197 if (v->gds_id == id)
198 return v;
199 return NULL;
200}
201
202static inline struct gds_subvector *
203sclp_find_gds_subvector(void *start, void *end, u8 key)
204{
205 struct gds_subvector *sv;
206
207 for (sv = start; (void *) sv < end; sv = (void *) sv + sv->length)
208 if (sv->key == key)
209 return sv;
210 return NULL;
211}
212
189#endif /* __SCLP_H__ */ 213#endif /* __SCLP_H__ */
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 4b60ede07f0e..be55fb2b1b1c 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -518,6 +518,8 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
518 return; 518 return;
519 new_incr->rn = rn; 519 new_incr->rn = rn;
520 new_incr->standby = standby; 520 new_incr->standby = standby;
521 if (!standby)
522 new_incr->usecount = 1;
521 last_rn = 0; 523 last_rn = 0;
522 prev = &sclp_mem_list; 524 prev = &sclp_mem_list;
523 list_for_each_entry(incr, &sclp_mem_list, list) { 525 list_for_each_entry(incr, &sclp_mem_list, list) {
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
index b497afe061cc..95b909ac2b73 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -33,6 +33,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
33 int cpu; 33 int cpu;
34 struct sys_device *sysdev; 34 struct sys_device *sysdev;
35 35
36 s390_adjust_jiffies();
36 pr_warning("cpu capability changed.\n"); 37 pr_warning("cpu capability changed.\n");
37 get_online_cpus(); 38 get_online_cpus();
38 for_each_online_cpu(cpu) { 39 for_each_online_cpu(cpu) {
@@ -70,21 +71,9 @@ static struct sclp_register sclp_conf_register =
70 71
71static int __init sclp_conf_init(void) 72static int __init sclp_conf_init(void)
72{ 73{
73 int rc;
74
75 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); 74 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
76 INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); 75 INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
77 76 return sclp_register(&sclp_conf_register);
78 rc = sclp_register(&sclp_conf_register);
79 if (rc)
80 return rc;
81
82 if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) {
83 pr_warning("no configuration management.\n");
84 sclp_unregister(&sclp_conf_register);
85 rc = -ENOSYS;
86 }
87 return rc;
88} 77}
89 78
90__initcall(sclp_conf_init); 79__initcall(sclp_conf_init);
diff --git a/drivers/s390/char/sclp_ocf.c b/drivers/s390/char/sclp_ocf.c
new file mode 100644
index 000000000000..ab294d5a534e
--- /dev/null
+++ b/drivers/s390/char/sclp_ocf.c
@@ -0,0 +1,145 @@
1/*
2 * drivers/s390/char/sclp_ocf.c
3 * SCLP OCF communication parameters sysfs interface
4 *
5 * Copyright IBM Corp. 2011
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8
9#define KMSG_COMPONENT "sclp_ocf"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/stat.h>
15#include <linux/device.h>
16#include <linux/string.h>
17#include <linux/ctype.h>
18#include <linux/kmod.h>
19#include <linux/timer.h>
20#include <linux/err.h>
21#include <asm/ebcdic.h>
22#include <asm/sclp.h>
23
24#include "sclp.h"
25
26#define OCF_LENGTH_HMC_NETWORK 8UL
27#define OCF_LENGTH_CPC_NAME 8UL
28
29static char hmc_network[OCF_LENGTH_HMC_NETWORK + 1];
30static char cpc_name[OCF_LENGTH_CPC_NAME + 1];
31
32static DEFINE_SPINLOCK(sclp_ocf_lock);
33static struct work_struct sclp_ocf_change_work;
34
35static struct kset *ocf_kset;
36
37static void sclp_ocf_change_notify(struct work_struct *work)
38{
39 kobject_uevent(&ocf_kset->kobj, KOBJ_CHANGE);
40}
41
42/* Handler for OCF event. Look for the CPC image name. */
43static void sclp_ocf_handler(struct evbuf_header *evbuf)
44{
45 struct gds_vector *v;
46 struct gds_subvector *sv, *netid, *cpc;
47 size_t size;
48
49 /* Find the 0x9f00 block. */
50 v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length,
51 0x9f00);
52 if (!v)
53 return;
54 /* Find the 0x9f22 block inside the 0x9f00 block. */
55 v = sclp_find_gds_vector(v + 1, (void *) v + v->length, 0x9f22);
56 if (!v)
57 return;
58 /* Find the 0x81 block inside the 0x9f22 block. */
59 sv = sclp_find_gds_subvector(v + 1, (void *) v + v->length, 0x81);
60 if (!sv)
61 return;
62 /* Find the 0x01 block inside the 0x81 block. */
63 netid = sclp_find_gds_subvector(sv + 1, (void *) sv + sv->length, 1);
64 /* Find the 0x02 block inside the 0x81 block. */
65 cpc = sclp_find_gds_subvector(sv + 1, (void *) sv + sv->length, 2);
66 /* Copy network name and cpc name. */
67 spin_lock(&sclp_ocf_lock);
68 if (netid) {
69 size = min(OCF_LENGTH_HMC_NETWORK, (size_t) netid->length);
70 memcpy(hmc_network, netid + 1, size);
71 EBCASC(hmc_network, size);
72 hmc_network[size] = 0;
73 }
74 if (cpc) {
75 size = min(OCF_LENGTH_CPC_NAME, (size_t) cpc->length);
76 memcpy(cpc_name, cpc + 1, size);
77 EBCASC(cpc_name, size);
78 cpc_name[size] = 0;
79 }
80 spin_unlock(&sclp_ocf_lock);
81 schedule_work(&sclp_ocf_change_work);
82}
83
84static struct sclp_register sclp_ocf_event = {
85 .receive_mask = EVTYP_OCF_MASK,
86 .receiver_fn = sclp_ocf_handler,
87};
88
89static ssize_t cpc_name_show(struct kobject *kobj,
90 struct kobj_attribute *attr, char *page)
91{
92 int rc;
93
94 spin_lock_irq(&sclp_ocf_lock);
95 rc = snprintf(page, PAGE_SIZE, "%s\n", cpc_name);
96 spin_unlock_irq(&sclp_ocf_lock);
97 return rc;
98}
99
100static struct kobj_attribute cpc_name_attr =
101 __ATTR(cpc_name, 0444, cpc_name_show, NULL);
102
103static ssize_t hmc_network_show(struct kobject *kobj,
104 struct kobj_attribute *attr, char *page)
105{
106 int rc;
107
108 spin_lock_irq(&sclp_ocf_lock);
109 rc = snprintf(page, PAGE_SIZE, "%s\n", hmc_network);
110 spin_unlock_irq(&sclp_ocf_lock);
111 return rc;
112}
113
114static struct kobj_attribute hmc_network_attr =
115 __ATTR(hmc_network, 0444, hmc_network_show, NULL);
116
117static struct attribute *ocf_attrs[] = {
118 &cpc_name_attr.attr,
119 &hmc_network_attr.attr,
120 NULL,
121};
122
123static struct attribute_group ocf_attr_group = {
124 .attrs = ocf_attrs,
125};
126
127static int __init ocf_init(void)
128{
129 int rc;
130
131 INIT_WORK(&sclp_ocf_change_work, sclp_ocf_change_notify);
132 ocf_kset = kset_create_and_add("ocf", NULL, firmware_kobj);
133 if (!ocf_kset)
134 return -ENOMEM;
135
136 rc = sysfs_create_group(&ocf_kset->kobj, &ocf_attr_group);
137 if (rc) {
138 kset_unregister(ocf_kset);
139 return rc;
140 }
141
142 return sclp_register(&sclp_ocf_event);
143}
144
145device_initcall(ocf_init);
diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c
index 6a1c58dc61a7..fa733ecd3d70 100644
--- a/drivers/s390/char/sclp_sdias.c
+++ b/drivers/s390/char/sclp_sdias.c
@@ -69,9 +69,6 @@ static DEFINE_MUTEX(sdias_mutex);
69 69
70static void sdias_callback(struct sclp_req *request, void *data) 70static void sdias_callback(struct sclp_req *request, void *data)
71{ 71{
72 struct sdias_sccb *cbsccb;
73
74 cbsccb = (struct sdias_sccb *) request->sccb;
75 sclp_req_done = 1; 72 sclp_req_done = 1;
76 wake_up(&sdias_wq); /* Inform caller, that request is complete */ 73 wake_up(&sdias_wq); /* Inform caller, that request is complete */
77 TRACE("callback done\n"); 74 TRACE("callback done\n");
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 8258d590505f..a879c139926a 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -408,118 +408,72 @@ static int sclp_switch_cases(unsigned char *buf, int count)
408 return op - buf; 408 return op - buf;
409} 409}
410 410
411static void 411static void sclp_get_input(struct gds_subvector *sv)
412sclp_get_input(unsigned char *start, unsigned char *end)
413{ 412{
413 unsigned char *str;
414 int count; 414 int count;
415 415
416 count = end - start; 416 str = (unsigned char *) (sv + 1);
417 count = sv->length - sizeof(*sv);
417 if (sclp_tty_tolower) 418 if (sclp_tty_tolower)
418 EBC_TOLOWER(start, count); 419 EBC_TOLOWER(str, count);
419 count = sclp_switch_cases(start, count); 420 count = sclp_switch_cases(str, count);
420 /* convert EBCDIC to ASCII (modify original input in SCCB) */ 421 /* convert EBCDIC to ASCII (modify original input in SCCB) */
421 sclp_ebcasc_str(start, count); 422 sclp_ebcasc_str(str, count);
422 423
423 /* transfer input to high level driver */ 424 /* transfer input to high level driver */
424 sclp_tty_input(start, count); 425 sclp_tty_input(str, count);
425}
426
427static inline struct gds_vector *
428find_gds_vector(struct gds_vector *start, struct gds_vector *end, u16 id)
429{
430 struct gds_vector *vec;
431
432 for (vec = start; vec < end; vec = (void *) vec + vec->length)
433 if (vec->gds_id == id)
434 return vec;
435 return NULL;
436} 426}
437 427
438static inline struct gds_subvector * 428static inline void sclp_eval_selfdeftextmsg(struct gds_subvector *sv)
439find_gds_subvector(struct gds_subvector *start,
440 struct gds_subvector *end, u8 key)
441{ 429{
442 struct gds_subvector *subvec; 430 void *end;
443 431
444 for (subvec = start; subvec < end; 432 end = (void *) sv + sv->length;
445 subvec = (void *) subvec + subvec->length) 433 for (sv = sv + 1; (void *) sv < end; sv = (void *) sv + sv->length)
446 if (subvec->key == key) 434 if (sv->key == 0x30)
447 return subvec; 435 sclp_get_input(sv);
448 return NULL;
449} 436}
450 437
451static inline void 438static inline void sclp_eval_textcmd(struct gds_vector *v)
452sclp_eval_selfdeftextmsg(struct gds_subvector *start,
453 struct gds_subvector *end)
454{ 439{
455 struct gds_subvector *subvec; 440 struct gds_subvector *sv;
456 441 void *end;
457 subvec = start;
458 while (subvec < end) {
459 subvec = find_gds_subvector(subvec, end, 0x30);
460 if (!subvec)
461 break;
462 sclp_get_input((unsigned char *)(subvec + 1),
463 (unsigned char *) subvec + subvec->length);
464 subvec = (void *) subvec + subvec->length;
465 }
466}
467 442
468static inline void 443 end = (void *) v + v->length;
469sclp_eval_textcmd(struct gds_subvector *start, 444 for (sv = (struct gds_subvector *) (v + 1);
470 struct gds_subvector *end) 445 (void *) sv < end; sv = (void *) sv + sv->length)
471{ 446 if (sv->key == GDS_KEY_SELFDEFTEXTMSG)
472 struct gds_subvector *subvec; 447 sclp_eval_selfdeftextmsg(sv);
473 448
474 subvec = start;
475 while (subvec < end) {
476 subvec = find_gds_subvector(subvec, end,
477 GDS_KEY_SELFDEFTEXTMSG);
478 if (!subvec)
479 break;
480 sclp_eval_selfdeftextmsg((struct gds_subvector *)(subvec + 1),
481 (void *)subvec + subvec->length);
482 subvec = (void *) subvec + subvec->length;
483 }
484} 449}
485 450
486static inline void 451static inline void sclp_eval_cpmsu(struct gds_vector *v)
487sclp_eval_cpmsu(struct gds_vector *start, struct gds_vector *end)
488{ 452{
489 struct gds_vector *vec; 453 void *end;
490 454
491 vec = start; 455 end = (void *) v + v->length;
492 while (vec < end) { 456 for (v = v + 1; (void *) v < end; v = (void *) v + v->length)
493 vec = find_gds_vector(vec, end, GDS_ID_TEXTCMD); 457 if (v->gds_id == GDS_ID_TEXTCMD)
494 if (!vec) 458 sclp_eval_textcmd(v);
495 break;
496 sclp_eval_textcmd((struct gds_subvector *)(vec + 1),
497 (void *) vec + vec->length);
498 vec = (void *) vec + vec->length;
499 }
500} 459}
501 460
502 461
503static inline void 462static inline void sclp_eval_mdsmu(struct gds_vector *v)
504sclp_eval_mdsmu(struct gds_vector *start, void *end)
505{ 463{
506 struct gds_vector *vec; 464 v = sclp_find_gds_vector(v + 1, (void *) v + v->length, GDS_ID_CPMSU);
507 465 if (v)
508 vec = find_gds_vector(start, end, GDS_ID_CPMSU); 466 sclp_eval_cpmsu(v);
509 if (vec)
510 sclp_eval_cpmsu(vec + 1, (void *) vec + vec->length);
511} 467}
512 468
513static void 469static void sclp_tty_receiver(struct evbuf_header *evbuf)
514sclp_tty_receiver(struct evbuf_header *evbuf)
515{ 470{
516 struct gds_vector *start, *end, *vec; 471 struct gds_vector *v;
517 472
518 start = (struct gds_vector *)(evbuf + 1); 473 v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length,
519 end = (void *) evbuf + evbuf->length; 474 GDS_ID_MDSMU);
520 vec = find_gds_vector(start, end, GDS_ID_MDSMU); 475 if (v)
521 if (vec) 476 sclp_eval_mdsmu(v);
522 sclp_eval_mdsmu(vec + 1, (void *) vec + vec->length);
523} 477}
524 478
525static void 479static void
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index 7a242f073632..267b54e8ff5a 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -280,6 +280,14 @@ tape_do_io_free(struct tape_device *device, struct tape_request *request)
280 return rc; 280 return rc;
281} 281}
282 282
283static inline void
284tape_do_io_async_free(struct tape_device *device, struct tape_request *request)
285{
286 request->callback = (void *) tape_free_request;
287 request->callback_data = NULL;
288 tape_do_io_async(device, request);
289}
290
283extern int tape_oper_handler(int irq, int status); 291extern int tape_oper_handler(int irq, int status);
284extern void tape_noper_handler(int irq, int status); 292extern void tape_noper_handler(int irq, int status);
285extern int tape_open(struct tape_device *); 293extern int tape_open(struct tape_device *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index c17f35b6136a..9eff2df70ddb 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -53,23 +53,11 @@ static void tape_34xx_delete_sbid_from(struct tape_device *, int);
53 * Medium sense for 34xx tapes. There is no 'real' medium sense call. 53 * Medium sense for 34xx tapes. There is no 'real' medium sense call.
54 * So we just do a normal sense. 54 * So we just do a normal sense.
55 */ 55 */
56static int 56static void __tape_34xx_medium_sense(struct tape_request *request)
57tape_34xx_medium_sense(struct tape_device *device)
58{ 57{
59 struct tape_request *request; 58 struct tape_device *device = request->device;
60 unsigned char *sense; 59 unsigned char *sense;
61 int rc;
62
63 request = tape_alloc_request(1, 32);
64 if (IS_ERR(request)) {
65 DBF_EXCEPTION(6, "MSEN fail\n");
66 return PTR_ERR(request);
67 }
68
69 request->op = TO_MSEN;
70 tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);
71 60
72 rc = tape_do_io_interruptible(device, request);
73 if (request->rc == 0) { 61 if (request->rc == 0) {
74 sense = request->cpdata; 62 sense = request->cpdata;
75 63
@@ -88,15 +76,47 @@ tape_34xx_medium_sense(struct tape_device *device)
88 device->tape_generic_status |= GMT_WR_PROT(~0); 76 device->tape_generic_status |= GMT_WR_PROT(~0);
89 else 77 else
90 device->tape_generic_status &= ~GMT_WR_PROT(~0); 78 device->tape_generic_status &= ~GMT_WR_PROT(~0);
91 } else { 79 } else
92 DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n", 80 DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n",
93 request->rc); 81 request->rc);
94 }
95 tape_free_request(request); 82 tape_free_request(request);
83}
96 84
85static int tape_34xx_medium_sense(struct tape_device *device)
86{
87 struct tape_request *request;
88 int rc;
89
90 request = tape_alloc_request(1, 32);
91 if (IS_ERR(request)) {
92 DBF_EXCEPTION(6, "MSEN fail\n");
93 return PTR_ERR(request);
94 }
95
96 request->op = TO_MSEN;
97 tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);
98 rc = tape_do_io_interruptible(device, request);
99 __tape_34xx_medium_sense(request);
97 return rc; 100 return rc;
98} 101}
99 102
103static void tape_34xx_medium_sense_async(struct tape_device *device)
104{
105 struct tape_request *request;
106
107 request = tape_alloc_request(1, 32);
108 if (IS_ERR(request)) {
109 DBF_EXCEPTION(6, "MSEN fail\n");
110 return;
111 }
112
113 request->op = TO_MSEN;
114 tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);
115 request->callback = (void *) __tape_34xx_medium_sense;
116 request->callback_data = NULL;
117 tape_do_io_async(device, request);
118}
119
100struct tape_34xx_work { 120struct tape_34xx_work {
101 struct tape_device *device; 121 struct tape_device *device;
102 enum tape_op op; 122 enum tape_op op;
@@ -109,6 +129,9 @@ struct tape_34xx_work {
109 * is inserted but cannot call tape_do_io* from an interrupt context. 129 * is inserted but cannot call tape_do_io* from an interrupt context.
110 * Maybe that's useful for other actions we want to start from the 130 * Maybe that's useful for other actions we want to start from the
111 * interrupt handler. 131 * interrupt handler.
132 * Note: the work handler is called by the system work queue. The tape
133 * commands started by the handler need to be asynchrounous, otherwise
134 * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).
112 */ 135 */
113static void 136static void
114tape_34xx_work_handler(struct work_struct *work) 137tape_34xx_work_handler(struct work_struct *work)
@@ -119,7 +142,7 @@ tape_34xx_work_handler(struct work_struct *work)
119 142
120 switch(p->op) { 143 switch(p->op) {
121 case TO_MSEN: 144 case TO_MSEN:
122 tape_34xx_medium_sense(device); 145 tape_34xx_medium_sense_async(device);
123 break; 146 break;
124 default: 147 default:
125 DBF_EVENT(3, "T34XX: internal error: unknown work\n"); 148 DBF_EVENT(3, "T34XX: internal error: unknown work\n");
@@ -1297,8 +1320,10 @@ tape_34xx_online(struct ccw_device *cdev)
1297} 1320}
1298 1321
1299static struct ccw_driver tape_34xx_driver = { 1322static struct ccw_driver tape_34xx_driver = {
1300 .name = "tape_34xx", 1323 .driver = {
1301 .owner = THIS_MODULE, 1324 .name = "tape_34xx",
1325 .owner = THIS_MODULE,
1326 },
1302 .ids = tape_34xx_ids, 1327 .ids = tape_34xx_ids,
1303 .probe = tape_generic_probe, 1328 .probe = tape_generic_probe,
1304 .remove = tape_generic_remove, 1329 .remove = tape_generic_remove,
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index fc993acf99b6..a7d570728882 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -24,6 +24,8 @@
24#include "tape_std.h" 24#include "tape_std.h"
25#include "tape_3590.h" 25#include "tape_3590.h"
26 26
27static struct workqueue_struct *tape_3590_wq;
28
27/* 29/*
28 * Pointer to debug area. 30 * Pointer to debug area.
29 */ 31 */
@@ -31,7 +33,7 @@ debug_info_t *TAPE_DBF_AREA = NULL;
31EXPORT_SYMBOL(TAPE_DBF_AREA); 33EXPORT_SYMBOL(TAPE_DBF_AREA);
32 34
33/******************************************************************* 35/*******************************************************************
34 * Error Recovery fuctions: 36 * Error Recovery functions:
35 * - Read Opposite: implemented 37 * - Read Opposite: implemented
36 * - Read Device (buffered) log: BRA 38 * - Read Device (buffered) log: BRA
37 * - Read Library log: BRA 39 * - Read Library log: BRA
@@ -327,17 +329,17 @@ out:
327/* 329/*
328 * Enable encryption 330 * Enable encryption
329 */ 331 */
330static int tape_3592_enable_crypt(struct tape_device *device) 332static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device)
331{ 333{
332 struct tape_request *request; 334 struct tape_request *request;
333 char *data; 335 char *data;
334 336
335 DBF_EVENT(6, "tape_3592_enable_crypt\n"); 337 DBF_EVENT(6, "tape_3592_enable_crypt\n");
336 if (!crypt_supported(device)) 338 if (!crypt_supported(device))
337 return -ENOSYS; 339 return ERR_PTR(-ENOSYS);
338 request = tape_alloc_request(2, 72); 340 request = tape_alloc_request(2, 72);
339 if (IS_ERR(request)) 341 if (IS_ERR(request))
340 return PTR_ERR(request); 342 return request;
341 data = request->cpdata; 343 data = request->cpdata;
342 memset(data,0,72); 344 memset(data,0,72);
343 345
@@ -352,23 +354,42 @@ static int tape_3592_enable_crypt(struct tape_device *device)
352 request->op = TO_CRYPT_ON; 354 request->op = TO_CRYPT_ON;
353 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); 355 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
354 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); 356 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
357 return request;
358}
359
360static int tape_3592_enable_crypt(struct tape_device *device)
361{
362 struct tape_request *request;
363
364 request = __tape_3592_enable_crypt(device);
365 if (IS_ERR(request))
366 return PTR_ERR(request);
355 return tape_do_io_free(device, request); 367 return tape_do_io_free(device, request);
356} 368}
357 369
370static void tape_3592_enable_crypt_async(struct tape_device *device)
371{
372 struct tape_request *request;
373
374 request = __tape_3592_enable_crypt(device);
375 if (!IS_ERR(request))
376 tape_do_io_async_free(device, request);
377}
378
358/* 379/*
359 * Disable encryption 380 * Disable encryption
360 */ 381 */
361static int tape_3592_disable_crypt(struct tape_device *device) 382static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device)
362{ 383{
363 struct tape_request *request; 384 struct tape_request *request;
364 char *data; 385 char *data;
365 386
366 DBF_EVENT(6, "tape_3592_disable_crypt\n"); 387 DBF_EVENT(6, "tape_3592_disable_crypt\n");
367 if (!crypt_supported(device)) 388 if (!crypt_supported(device))
368 return -ENOSYS; 389 return ERR_PTR(-ENOSYS);
369 request = tape_alloc_request(2, 72); 390 request = tape_alloc_request(2, 72);
370 if (IS_ERR(request)) 391 if (IS_ERR(request))
371 return PTR_ERR(request); 392 return request;
372 data = request->cpdata; 393 data = request->cpdata;
373 memset(data,0,72); 394 memset(data,0,72);
374 395
@@ -381,9 +402,28 @@ static int tape_3592_disable_crypt(struct tape_device *device)
381 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); 402 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
382 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); 403 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
383 404
405 return request;
406}
407
408static int tape_3592_disable_crypt(struct tape_device *device)
409{
410 struct tape_request *request;
411
412 request = __tape_3592_disable_crypt(device);
413 if (IS_ERR(request))
414 return PTR_ERR(request);
384 return tape_do_io_free(device, request); 415 return tape_do_io_free(device, request);
385} 416}
386 417
418static void tape_3592_disable_crypt_async(struct tape_device *device)
419{
420 struct tape_request *request;
421
422 request = __tape_3592_disable_crypt(device);
423 if (!IS_ERR(request))
424 tape_do_io_async_free(device, request);
425}
426
387/* 427/*
388 * IOCTL: Set encryption status 428 * IOCTL: Set encryption status
389 */ 429 */
@@ -455,8 +495,7 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)
455/* 495/*
456 * SENSE Medium: Get Sense data about medium state 496 * SENSE Medium: Get Sense data about medium state
457 */ 497 */
458static int 498static int tape_3590_sense_medium(struct tape_device *device)
459tape_3590_sense_medium(struct tape_device *device)
460{ 499{
461 struct tape_request *request; 500 struct tape_request *request;
462 501
@@ -468,6 +507,18 @@ tape_3590_sense_medium(struct tape_device *device)
468 return tape_do_io_free(device, request); 507 return tape_do_io_free(device, request);
469} 508}
470 509
510static void tape_3590_sense_medium_async(struct tape_device *device)
511{
512 struct tape_request *request;
513
514 request = tape_alloc_request(1, 128);
515 if (IS_ERR(request))
516 return;
517 request->op = TO_MSEN;
518 tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata);
519 tape_do_io_async_free(device, request);
520}
521
471/* 522/*
472 * MTTELL: Tell block. Return the number of block relative to current file. 523 * MTTELL: Tell block. Return the number of block relative to current file.
473 */ 524 */
@@ -544,15 +595,14 @@ tape_3590_read_opposite(struct tape_device *device,
544 * 2. The attention msg is written to the "read subsystem data" buffer. 595 * 2. The attention msg is written to the "read subsystem data" buffer.
545 * In this case we probably should print it to the console. 596 * In this case we probably should print it to the console.
546 */ 597 */
547static int 598static void tape_3590_read_attmsg_async(struct tape_device *device)
548tape_3590_read_attmsg(struct tape_device *device)
549{ 599{
550 struct tape_request *request; 600 struct tape_request *request;
551 char *buf; 601 char *buf;
552 602
553 request = tape_alloc_request(3, 4096); 603 request = tape_alloc_request(3, 4096);
554 if (IS_ERR(request)) 604 if (IS_ERR(request))
555 return PTR_ERR(request); 605 return;
556 request->op = TO_READ_ATTMSG; 606 request->op = TO_READ_ATTMSG;
557 buf = request->cpdata; 607 buf = request->cpdata;
558 buf[0] = PREP_RD_SS_DATA; 608 buf[0] = PREP_RD_SS_DATA;
@@ -560,12 +610,15 @@ tape_3590_read_attmsg(struct tape_device *device)
560 tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf); 610 tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf);
561 tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12); 611 tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12);
562 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); 612 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
563 return tape_do_io_free(device, request); 613 tape_do_io_async_free(device, request);
564} 614}
565 615
566/* 616/*
567 * These functions are used to schedule follow-up actions from within an 617 * These functions are used to schedule follow-up actions from within an
568 * interrupt context (like unsolicited interrupts). 618 * interrupt context (like unsolicited interrupts).
619 * Note: the work handler is called by the system work queue. The tape
620 * commands started by the handler need to be asynchrounous, otherwise
621 * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).
569 */ 622 */
570struct work_handler_data { 623struct work_handler_data {
571 struct tape_device *device; 624 struct tape_device *device;
@@ -581,16 +634,16 @@ tape_3590_work_handler(struct work_struct *work)
581 634
582 switch (p->op) { 635 switch (p->op) {
583 case TO_MSEN: 636 case TO_MSEN:
584 tape_3590_sense_medium(p->device); 637 tape_3590_sense_medium_async(p->device);
585 break; 638 break;
586 case TO_READ_ATTMSG: 639 case TO_READ_ATTMSG:
587 tape_3590_read_attmsg(p->device); 640 tape_3590_read_attmsg_async(p->device);
588 break; 641 break;
589 case TO_CRYPT_ON: 642 case TO_CRYPT_ON:
590 tape_3592_enable_crypt(p->device); 643 tape_3592_enable_crypt_async(p->device);
591 break; 644 break;
592 case TO_CRYPT_OFF: 645 case TO_CRYPT_OFF:
593 tape_3592_disable_crypt(p->device); 646 tape_3592_disable_crypt_async(p->device);
594 break; 647 break;
595 default: 648 default:
596 DBF_EVENT(3, "T3590: work handler undefined for " 649 DBF_EVENT(3, "T3590: work handler undefined for "
@@ -613,7 +666,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
613 p->device = tape_get_device(device); 666 p->device = tape_get_device(device);
614 p->op = op; 667 p->op = op;
615 668
616 schedule_work(&p->work); 669 queue_work(tape_3590_wq, &p->work);
617 return 0; 670 return 0;
618} 671}
619 672
@@ -743,10 +796,8 @@ static void tape_3590_med_state_set(struct tape_device *device,
743static int 796static int
744tape_3590_done(struct tape_device *device, struct tape_request *request) 797tape_3590_done(struct tape_device *device, struct tape_request *request)
745{ 798{
746 struct tape_3590_disc_data *disc_data;
747 799
748 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]); 800 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
749 disc_data = device->discdata;
750 801
751 switch (request->op) { 802 switch (request->op) {
752 case TO_BSB: 803 case TO_BSB:
@@ -798,7 +849,7 @@ tape_3590_done(struct tape_device *device, struct tape_request *request)
798} 849}
799 850
800/* 851/*
801 * This fuction is called, when error recovery was successfull 852 * This function is called, when error recovery was successful
802 */ 853 */
803static inline int 854static inline int
804tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request) 855tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request)
@@ -809,7 +860,7 @@ tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request)
809} 860}
810 861
811/* 862/*
812 * This fuction is called, when error recovery was not successfull 863 * This function is called, when error recovery was not successful
813 */ 864 */
814static inline int 865static inline int
815tape_3590_erp_failed(struct tape_device *device, struct tape_request *request, 866tape_3590_erp_failed(struct tape_device *device, struct tape_request *request,
@@ -1341,17 +1392,12 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
1341static int tape_3590_crypt_error(struct tape_device *device, 1392static int tape_3590_crypt_error(struct tape_device *device,
1342 struct tape_request *request, struct irb *irb) 1393 struct tape_request *request, struct irb *irb)
1343{ 1394{
1344 u8 cu_rc, ekm_rc1; 1395 u8 cu_rc;
1345 u16 ekm_rc2; 1396 u16 ekm_rc2;
1346 u32 drv_rc;
1347 const char *bus_id;
1348 char *sense; 1397 char *sense;
1349 1398
1350 sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data; 1399 sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
1351 bus_id = dev_name(&device->cdev->dev);
1352 cu_rc = sense[0]; 1400 cu_rc = sense[0];
1353 drv_rc = *((u32*) &sense[5]) & 0xffffff;
1354 ekm_rc1 = sense[9];
1355 ekm_rc2 = *((u16*) &sense[10]); 1401 ekm_rc2 = *((u16*) &sense[10]);
1356 if ((cu_rc == 0) && (ekm_rc2 == 0xee31)) 1402 if ((cu_rc == 0) && (ekm_rc2 == 0xee31))
1357 /* key not defined on EKM */ 1403 /* key not defined on EKM */
@@ -1376,7 +1422,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1376 struct irb *irb) 1422 struct irb *irb)
1377{ 1423{
1378 struct tape_3590_sense *sense; 1424 struct tape_3590_sense *sense;
1379 int rc;
1380 1425
1381#ifdef CONFIG_S390_TAPE_BLOCK 1426#ifdef CONFIG_S390_TAPE_BLOCK
1382 if (request->op == TO_BLOCK) { 1427 if (request->op == TO_BLOCK) {
@@ -1401,7 +1446,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1401 * - "break": basic error recovery is done 1446 * - "break": basic error recovery is done
1402 * - "goto out:": just print error message if available 1447 * - "goto out:": just print error message if available
1403 */ 1448 */
1404 rc = -EIO;
1405 switch (sense->rc_rqc) { 1449 switch (sense->rc_rqc) {
1406 1450
1407 case 0x1110: 1451 case 0x1110:
@@ -1629,7 +1673,7 @@ fail_kmalloc:
1629static void 1673static void
1630tape_3590_cleanup_device(struct tape_device *device) 1674tape_3590_cleanup_device(struct tape_device *device)
1631{ 1675{
1632 flush_scheduled_work(); 1676 flush_workqueue(tape_3590_wq);
1633 tape_std_unassign(device); 1677 tape_std_unassign(device);
1634 1678
1635 kfree(device->discdata); 1679 kfree(device->discdata);
@@ -1708,8 +1752,10 @@ tape_3590_online(struct ccw_device *cdev)
1708} 1752}
1709 1753
1710static struct ccw_driver tape_3590_driver = { 1754static struct ccw_driver tape_3590_driver = {
1711 .name = "tape_3590", 1755 .driver = {
1712 .owner = THIS_MODULE, 1756 .name = "tape_3590",
1757 .owner = THIS_MODULE,
1758 },
1713 .ids = tape_3590_ids, 1759 .ids = tape_3590_ids,
1714 .probe = tape_generic_probe, 1760 .probe = tape_generic_probe,
1715 .remove = tape_generic_remove, 1761 .remove = tape_generic_remove,
@@ -1733,11 +1779,17 @@ tape_3590_init(void)
1733#endif 1779#endif
1734 1780
1735 DBF_EVENT(3, "3590 init\n"); 1781 DBF_EVENT(3, "3590 init\n");
1782
1783 tape_3590_wq = alloc_workqueue("tape_3590", 0, 0);
1784 if (!tape_3590_wq)
1785 return -ENOMEM;
1786
1736 /* Register driver for 3590 tapes. */ 1787 /* Register driver for 3590 tapes. */
1737 rc = ccw_driver_register(&tape_3590_driver); 1788 rc = ccw_driver_register(&tape_3590_driver);
1738 if (rc) 1789 if (rc) {
1790 destroy_workqueue(tape_3590_wq);
1739 DBF_EVENT(3, "3590 init failed\n"); 1791 DBF_EVENT(3, "3590 init failed\n");
1740 else 1792 } else
1741 DBF_EVENT(3, "3590 registered\n"); 1793 DBF_EVENT(3, "3590 registered\n");
1742 return rc; 1794 return rc;
1743} 1795}
@@ -1746,7 +1798,7 @@ static void
1746tape_3590_exit(void) 1798tape_3590_exit(void)
1747{ 1799{
1748 ccw_driver_unregister(&tape_3590_driver); 1800 ccw_driver_unregister(&tape_3590_driver);
1749 1801 destroy_workqueue(tape_3590_wq);
1750 debug_unregister(TAPE_DBF_AREA); 1802 debug_unregister(TAPE_DBF_AREA);
1751} 1803}
1752 1804
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
deleted file mode 100644
index 85cf607fc78f..000000000000
--- a/drivers/s390/char/tape_block.c
+++ /dev/null
@@ -1,444 +0,0 @@
1/*
2 * drivers/s390/char/tape_block.c
3 * block device frontend for tape device driver
4 *
5 * S390 and zSeries version
6 * Copyright (C) 2001,2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
9 * Martin Schwidefsky <schwidefsky@de.ibm.com>
10 * Stefan Bader <shbader@de.ibm.com>
11 */
12
13#define KMSG_COMPONENT "tape"
14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
15
16#include <linux/fs.h>
17#include <linux/module.h>
18#include <linux/blkdev.h>
19#include <linux/smp_lock.h>
20#include <linux/interrupt.h>
21#include <linux/buffer_head.h>
22#include <linux/kernel.h>
23
24#include <asm/debug.h>
25
26#define TAPE_DBF_AREA tape_core_dbf
27
28#include "tape.h"
29
30#define TAPEBLOCK_MAX_SEC 100
31#define TAPEBLOCK_MIN_REQUEUE 3
32
33/*
34 * 2003/11/25 Stefan Bader <shbader@de.ibm.com>
35 *
36 * In 2.5/2.6 the block device request function is very likely to be called
37 * with disabled interrupts (e.g. generic_unplug_device). So the driver can't
38 * just call any function that tries to allocate CCW requests from that con-
39 * text since it might sleep. There are two choices to work around this:
40 * a) do not allocate with kmalloc but use its own memory pool
41 * b) take requests from the queue outside that context, knowing that
42 * allocation might sleep
43 */
44
45/*
46 * file operation structure for tape block frontend
47 */
48static int tapeblock_open(struct block_device *, fmode_t);
49static int tapeblock_release(struct gendisk *, fmode_t);
50static int tapeblock_medium_changed(struct gendisk *);
51static int tapeblock_revalidate_disk(struct gendisk *);
52
53static const struct block_device_operations tapeblock_fops = {
54 .owner = THIS_MODULE,
55 .open = tapeblock_open,
56 .release = tapeblock_release,
57 .media_changed = tapeblock_medium_changed,
58 .revalidate_disk = tapeblock_revalidate_disk,
59};
60
61static int tapeblock_major = 0;
62
63static void
64tapeblock_trigger_requeue(struct tape_device *device)
65{
66 /* Protect against rescheduling. */
67 if (atomic_cmpxchg(&device->blk_data.requeue_scheduled, 0, 1) != 0)
68 return;
69 schedule_work(&device->blk_data.requeue_task);
70}
71
72/*
73 * Post finished request.
74 */
75static void
76__tapeblock_end_request(struct tape_request *ccw_req, void *data)
77{
78 struct tape_device *device;
79 struct request *req;
80
81 DBF_LH(6, "__tapeblock_end_request()\n");
82
83 device = ccw_req->device;
84 req = (struct request *) data;
85 blk_end_request_all(req, (ccw_req->rc == 0) ? 0 : -EIO);
86 if (ccw_req->rc == 0)
87 /* Update position. */
88 device->blk_data.block_position =
89 (blk_rq_pos(req) + blk_rq_sectors(req)) >> TAPEBLOCK_HSEC_S2B;
90 else
91 /* We lost the position information due to an error. */
92 device->blk_data.block_position = -1;
93 device->discipline->free_bread(ccw_req);
94 if (!list_empty(&device->req_queue) ||
95 blk_peek_request(device->blk_data.request_queue))
96 tapeblock_trigger_requeue(device);
97}
98
99/*
100 * Feed the tape device CCW queue with requests supplied in a list.
101 */
102static int
103tapeblock_start_request(struct tape_device *device, struct request *req)
104{
105 struct tape_request * ccw_req;
106 int rc;
107
108 DBF_LH(6, "tapeblock_start_request(%p, %p)\n", device, req);
109
110 ccw_req = device->discipline->bread(device, req);
111 if (IS_ERR(ccw_req)) {
112 DBF_EVENT(1, "TBLOCK: bread failed\n");
113 blk_end_request_all(req, -EIO);
114 return PTR_ERR(ccw_req);
115 }
116 ccw_req->callback = __tapeblock_end_request;
117 ccw_req->callback_data = (void *) req;
118 ccw_req->retries = TAPEBLOCK_RETRIES;
119
120 rc = tape_do_io_async(device, ccw_req);
121 if (rc) {
122 /*
123 * Start/enqueueing failed. No retries in
124 * this case.
125 */
126 blk_end_request_all(req, -EIO);
127 device->discipline->free_bread(ccw_req);
128 }
129
130 return rc;
131}
132
133/*
134 * Move requests from the block device request queue to the tape device ccw
135 * queue.
136 */
137static void
138tapeblock_requeue(struct work_struct *work) {
139 struct tape_blk_data * blkdat;
140 struct tape_device * device;
141 struct request_queue * queue;
142 int nr_queued;
143 struct request * req;
144 struct list_head * l;
145 int rc;
146
147 blkdat = container_of(work, struct tape_blk_data, requeue_task);
148 device = blkdat->device;
149 if (!device)
150 return;
151
152 spin_lock_irq(get_ccwdev_lock(device->cdev));
153 queue = device->blk_data.request_queue;
154
155 /* Count number of requests on ccw queue. */
156 nr_queued = 0;
157 list_for_each(l, &device->req_queue)
158 nr_queued++;
159 spin_unlock(get_ccwdev_lock(device->cdev));
160
161 spin_lock_irq(&device->blk_data.request_queue_lock);
162 while (
163 !blk_queue_plugged(queue) &&
164 blk_peek_request(queue) &&
165 nr_queued < TAPEBLOCK_MIN_REQUEUE
166 ) {
167 req = blk_fetch_request(queue);
168 if (rq_data_dir(req) == WRITE) {
169 DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
170 spin_unlock_irq(&device->blk_data.request_queue_lock);
171 blk_end_request_all(req, -EIO);
172 spin_lock_irq(&device->blk_data.request_queue_lock);
173 continue;
174 }
175 nr_queued++;
176 spin_unlock_irq(&device->blk_data.request_queue_lock);
177 rc = tapeblock_start_request(device, req);
178 spin_lock_irq(&device->blk_data.request_queue_lock);
179 }
180 spin_unlock_irq(&device->blk_data.request_queue_lock);
181 atomic_set(&device->blk_data.requeue_scheduled, 0);
182}
183
184/*
185 * Tape request queue function. Called from ll_rw_blk.c
186 */
187static void
188tapeblock_request_fn(struct request_queue *queue)
189{
190 struct tape_device *device;
191
192 device = (struct tape_device *) queue->queuedata;
193 DBF_LH(6, "tapeblock_request_fn(device=%p)\n", device);
194 BUG_ON(device == NULL);
195 tapeblock_trigger_requeue(device);
196}
197
198/*
199 * This function is called for every new tapedevice
200 */
201int
202tapeblock_setup_device(struct tape_device * device)
203{
204 struct tape_blk_data * blkdat;
205 struct gendisk * disk;
206 int rc;
207
208 blkdat = &device->blk_data;
209 blkdat->device = device;
210 spin_lock_init(&blkdat->request_queue_lock);
211 atomic_set(&blkdat->requeue_scheduled, 0);
212
213 blkdat->request_queue = blk_init_queue(
214 tapeblock_request_fn,
215 &blkdat->request_queue_lock
216 );
217 if (!blkdat->request_queue)
218 return -ENOMEM;
219
220 rc = elevator_change(blkdat->request_queue, "noop");
221 if (rc)
222 goto cleanup_queue;
223
224 blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE);
225 blk_queue_max_hw_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC);
226 blk_queue_max_segments(blkdat->request_queue, -1L);
227 blk_queue_max_segment_size(blkdat->request_queue, -1L);
228 blk_queue_segment_boundary(blkdat->request_queue, -1L);
229
230 disk = alloc_disk(1);
231 if (!disk) {
232 rc = -ENOMEM;
233 goto cleanup_queue;
234 }
235
236 disk->major = tapeblock_major;
237 disk->first_minor = device->first_minor;
238 disk->fops = &tapeblock_fops;
239 disk->private_data = tape_get_device(device);
240 disk->queue = blkdat->request_queue;
241 set_capacity(disk, 0);
242 sprintf(disk->disk_name, "btibm%d",
243 device->first_minor / TAPE_MINORS_PER_DEV);
244
245 blkdat->disk = disk;
246 blkdat->medium_changed = 1;
247 blkdat->request_queue->queuedata = tape_get_device(device);
248
249 add_disk(disk);
250
251 tape_get_device(device);
252 INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
253
254 return 0;
255
256cleanup_queue:
257 blk_cleanup_queue(blkdat->request_queue);
258 blkdat->request_queue = NULL;
259
260 return rc;
261}
262
263void
264tapeblock_cleanup_device(struct tape_device *device)
265{
266 flush_scheduled_work();
267 tape_put_device(device);
268
269 if (!device->blk_data.disk) {
270 goto cleanup_queue;
271 }
272
273 del_gendisk(device->blk_data.disk);
274 device->blk_data.disk->private_data = NULL;
275 tape_put_device(device);
276 put_disk(device->blk_data.disk);
277
278 device->blk_data.disk = NULL;
279cleanup_queue:
280 device->blk_data.request_queue->queuedata = NULL;
281 tape_put_device(device);
282
283 blk_cleanup_queue(device->blk_data.request_queue);
284 device->blk_data.request_queue = NULL;
285}
286
287/*
288 * Detect number of blocks of the tape.
289 * FIXME: can we extent this to detect the blocks size as well ?
290 */
291static int
292tapeblock_revalidate_disk(struct gendisk *disk)
293{
294 struct tape_device * device;
295 unsigned int nr_of_blks;
296 int rc;
297
298 device = (struct tape_device *) disk->private_data;
299 BUG_ON(!device);
300
301 if (!device->blk_data.medium_changed)
302 return 0;
303
304 rc = tape_mtop(device, MTFSFM, 1);
305 if (rc)
306 return rc;
307
308 rc = tape_mtop(device, MTTELL, 1);
309 if (rc < 0)
310 return rc;
311
312 pr_info("%s: Determining the size of the recorded area...\n",
313 dev_name(&device->cdev->dev));
314 DBF_LH(3, "Image file ends at %d\n", rc);
315 nr_of_blks = rc;
316
317 /* This will fail for the first file. Catch the error by checking the
318 * position. */
319 tape_mtop(device, MTBSF, 1);
320
321 rc = tape_mtop(device, MTTELL, 1);
322 if (rc < 0)
323 return rc;
324
325 if (rc > nr_of_blks)
326 return -EINVAL;
327
328 DBF_LH(3, "Image file starts at %d\n", rc);
329 device->bof = rc;
330 nr_of_blks -= rc;
331
332 pr_info("%s: The size of the recorded area is %i blocks\n",
333 dev_name(&device->cdev->dev), nr_of_blks);
334 set_capacity(device->blk_data.disk,
335 nr_of_blks*(TAPEBLOCK_HSEC_SIZE/512));
336
337 device->blk_data.block_position = 0;
338 device->blk_data.medium_changed = 0;
339 return 0;
340}
341
342static int
343tapeblock_medium_changed(struct gendisk *disk)
344{
345 struct tape_device *device;
346
347 device = (struct tape_device *) disk->private_data;
348 DBF_LH(6, "tapeblock_medium_changed(%p) = %d\n",
349 device, device->blk_data.medium_changed);
350
351 return device->blk_data.medium_changed;
352}
353
354/*
355 * Block frontend tape device open function.
356 */
357static int
358tapeblock_open(struct block_device *bdev, fmode_t mode)
359{
360 struct gendisk * disk = bdev->bd_disk;
361 struct tape_device * device;
362 int rc;
363
364 lock_kernel();
365 device = tape_get_device(disk->private_data);
366
367 if (device->required_tapemarks) {
368 DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
369 pr_warning("%s: Opening the tape failed because of missing "
370 "end-of-file marks\n", dev_name(&device->cdev->dev));
371 rc = -EPERM;
372 goto put_device;
373 }
374
375 rc = tape_open(device);
376 if (rc)
377 goto put_device;
378
379 rc = tapeblock_revalidate_disk(disk);
380 if (rc)
381 goto release;
382
383 /*
384 * Note: The reference to <device> is hold until the release function
385 * is called.
386 */
387 tape_state_set(device, TS_BLKUSE);
388 unlock_kernel();
389 return 0;
390
391release:
392 tape_release(device);
393 put_device:
394 tape_put_device(device);
395 unlock_kernel();
396 return rc;
397}
398
399/*
400 * Block frontend tape device release function.
401 *
402 * Note: One reference to the tape device was made by the open function. So
403 * we just get the pointer here and release the reference.
404 */
405static int
406tapeblock_release(struct gendisk *disk, fmode_t mode)
407{
408 struct tape_device *device = disk->private_data;
409
410 lock_kernel();
411 tape_state_set(device, TS_IN_USE);
412 tape_release(device);
413 tape_put_device(device);
414 unlock_kernel();
415
416 return 0;
417}
418
419/*
420 * Initialize block device frontend.
421 */
422int
423tapeblock_init(void)
424{
425 int rc;
426
427 /* Register the tape major number to the kernel */
428 rc = register_blkdev(tapeblock_major, "tBLK");
429 if (rc < 0)
430 return rc;
431
432 if (tapeblock_major == 0)
433 tapeblock_major = rc;
434 return 0;
435}
436
437/*
438 * Deregister major for block device frontend
439 */
440void
441tapeblock_exit(void)
442{
443 unregister_blkdev(tapeblock_major, "tBLK");
444}
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 539045acaad4..87cd0ab242de 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -17,7 +17,6 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/proc_fs.h> 18#include <linux/proc_fs.h>
19#include <linux/mtio.h> 19#include <linux/mtio.h>
20#include <linux/smp_lock.h>
21#include <linux/compat.h> 20#include <linux/compat.h>
22 21
23#include <asm/uaccess.h> 22#include <asm/uaccess.h>
@@ -53,6 +52,7 @@ static const struct file_operations tape_fops =
53#endif 52#endif
54 .open = tapechar_open, 53 .open = tapechar_open,
55 .release = tapechar_release, 54 .release = tapechar_release,
55 .llseek = no_llseek,
56}; 56};
57 57
58static int tapechar_major = TAPECHAR_MAJOR; 58static int tapechar_major = TAPECHAR_MAJOR;
@@ -139,7 +139,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
139 /* 139 /*
140 * If the tape isn't terminated yet, do it now. And since we then 140 * If the tape isn't terminated yet, do it now. And since we then
141 * are at the end of the tape there wouldn't be anything to read 141 * are at the end of the tape there wouldn't be anything to read
142 * anyways. So we return immediatly. 142 * anyways. So we return immediately.
143 */ 143 */
144 if(device->required_tapemarks) { 144 if(device->required_tapemarks) {
145 return tape_std_terminate_write(device); 145 return tape_std_terminate_write(device);
diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h
index 707b7f48c232..9e32780c317f 100644
--- a/drivers/s390/char/tape_class.h
+++ b/drivers/s390/char/tape_class.h
@@ -14,7 +14,6 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/fs.h> 15#include <linux/fs.h>
16#include <linux/major.h> 16#include <linux/major.h>
17#include <linux/kobject.h>
18#include <linux/kobj_map.h> 17#include <linux/kobj_map.h>
19#include <linux/cdev.h> 18#include <linux/cdev.h>
20 19
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 29c2d73d719d..7978a0adeaf3 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -14,6 +14,7 @@
14#define KMSG_COMPONENT "tape" 14#define KMSG_COMPONENT "tape"
15#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 15#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
16 16
17#include <linux/kernel_stat.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/init.h> // for kernel parameters 19#include <linux/init.h> // for kernel parameters
19#include <linux/kmod.h> // for requesting modules 20#include <linux/kmod.h> // for requesting modules
@@ -209,29 +210,79 @@ tape_state_set(struct tape_device *device, enum tape_state newstate)
209 wake_up(&device->state_change_wq); 210 wake_up(&device->state_change_wq);
210} 211}
211 212
213struct tape_med_state_work_data {
214 struct tape_device *device;
215 enum tape_medium_state state;
216 struct work_struct work;
217};
218
219static void
220tape_med_state_work_handler(struct work_struct *work)
221{
222 static char env_state_loaded[] = "MEDIUM_STATE=LOADED";
223 static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED";
224 struct tape_med_state_work_data *p =
225 container_of(work, struct tape_med_state_work_data, work);
226 struct tape_device *device = p->device;
227 char *envp[] = { NULL, NULL };
228
229 switch (p->state) {
230 case MS_UNLOADED:
231 pr_info("%s: The tape cartridge has been successfully "
232 "unloaded\n", dev_name(&device->cdev->dev));
233 envp[0] = env_state_unloaded;
234 kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
235 break;
236 case MS_LOADED:
237 pr_info("%s: A tape cartridge has been mounted\n",
238 dev_name(&device->cdev->dev));
239 envp[0] = env_state_loaded;
240 kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
241 break;
242 default:
243 break;
244 }
245 tape_put_device(device);
246 kfree(p);
247}
248
249static void
250tape_med_state_work(struct tape_device *device, enum tape_medium_state state)
251{
252 struct tape_med_state_work_data *p;
253
254 p = kzalloc(sizeof(*p), GFP_ATOMIC);
255 if (p) {
256 INIT_WORK(&p->work, tape_med_state_work_handler);
257 p->device = tape_get_device(device);
258 p->state = state;
259 schedule_work(&p->work);
260 }
261}
262
212void 263void
213tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate) 264tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
214{ 265{
215 if (device->medium_state == newstate) 266 enum tape_medium_state oldstate;
267
268 oldstate = device->medium_state;
269 if (oldstate == newstate)
216 return; 270 return;
271 device->medium_state = newstate;
217 switch(newstate){ 272 switch(newstate){
218 case MS_UNLOADED: 273 case MS_UNLOADED:
219 device->tape_generic_status |= GMT_DR_OPEN(~0); 274 device->tape_generic_status |= GMT_DR_OPEN(~0);
220 if (device->medium_state == MS_LOADED) 275 if (oldstate == MS_LOADED)
221 pr_info("%s: The tape cartridge has been successfully " 276 tape_med_state_work(device, MS_UNLOADED);
222 "unloaded\n", dev_name(&device->cdev->dev));
223 break; 277 break;
224 case MS_LOADED: 278 case MS_LOADED:
225 device->tape_generic_status &= ~GMT_DR_OPEN(~0); 279 device->tape_generic_status &= ~GMT_DR_OPEN(~0);
226 if (device->medium_state == MS_UNLOADED) 280 if (oldstate == MS_UNLOADED)
227 pr_info("%s: A tape cartridge has been mounted\n", 281 tape_med_state_work(device, MS_LOADED);
228 dev_name(&device->cdev->dev));
229 break; 282 break;
230 default: 283 default:
231 // print nothing
232 break; 284 break;
233 } 285 }
234 device->medium_state = newstate;
235 wake_up(&device->state_change_wq); 286 wake_up(&device->state_change_wq);
236} 287}
237 288
@@ -1064,6 +1115,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1064 struct tape_request *request; 1115 struct tape_request *request;
1065 int rc; 1116 int rc;
1066 1117
1118 kstat_cpu(smp_processor_id()).irqs[IOINT_TAP]++;
1067 device = dev_get_drvdata(&cdev->dev); 1119 device = dev_get_drvdata(&cdev->dev);
1068 if (device == NULL) { 1120 if (device == NULL) {
1069 return; 1121 return;
@@ -1077,15 +1129,14 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1077 /* FIXME: What to do with the request? */ 1129 /* FIXME: What to do with the request? */
1078 switch (PTR_ERR(irb)) { 1130 switch (PTR_ERR(irb)) {
1079 case -ETIMEDOUT: 1131 case -ETIMEDOUT:
1080 DBF_LH(1, "(%s): Request timed out\n", 1132 DBF_LH(1, "(%08x): Request timed out\n",
1081 dev_name(&cdev->dev)); 1133 device->cdev_id);
1082 case -EIO: 1134 case -EIO:
1083 __tape_end_request(device, request, -EIO); 1135 __tape_end_request(device, request, -EIO);
1084 break; 1136 break;
1085 default: 1137 default:
1086 DBF_LH(1, "(%s): Unexpected i/o error %li\n", 1138 DBF_LH(1, "(%08x): Unexpected i/o error %li\n",
1087 dev_name(&cdev->dev), 1139 device->cdev_id, PTR_ERR(irb));
1088 PTR_ERR(irb));
1089 } 1140 }
1090 return; 1141 return;
1091 } 1142 }
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index 03f07e5dd6e9..e7650170274a 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -47,8 +47,8 @@ tape_std_assign_timeout(unsigned long data)
47 device->cdev_id); 47 device->cdev_id);
48 rc = tape_cancel_io(device, request); 48 rc = tape_cancel_io(device, request);
49 if(rc) 49 if(rc)
50 DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n", 50 DBF_EVENT(3, "(%08x): Assign timeout: Cancel failed with rc = "
51 dev_name(&device->cdev->dev), rc); 51 "%i\n", device->cdev_id, rc);
52} 52}
53 53
54int 54int
@@ -564,7 +564,6 @@ int
564tape_std_mtreten(struct tape_device *device, int mt_count) 564tape_std_mtreten(struct tape_device *device, int mt_count)
565{ 565{
566 struct tape_request *request; 566 struct tape_request *request;
567 int rc;
568 567
569 request = tape_alloc_request(4, 0); 568 request = tape_alloc_request(4, 0);
570 if (IS_ERR(request)) 569 if (IS_ERR(request))
@@ -576,7 +575,7 @@ tape_std_mtreten(struct tape_device *device, int mt_count)
576 tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL); 575 tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
577 tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr); 576 tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
578 /* execute it, MTRETEN rc gets ignored */ 577 /* execute it, MTRETEN rc gets ignored */
579 rc = tape_do_io_interruptible(device, request); 578 tape_do_io_interruptible(device, request);
580 tape_free_request(request); 579 tape_free_request(request);
581 return tape_mtop(device, MTREW, 1); 580 return tape_mtop(device, MTREW, 1);
582} 581}
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 911822db614d..2db1482b406e 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -328,7 +328,7 @@ tty3270_write_callback(struct raw3270_request *rq, void *data)
328 328
329 tp = (struct tty3270 *) rq->view; 329 tp = (struct tty3270 *) rq->view;
330 if (rq->rc != 0) { 330 if (rq->rc != 0) {
331 /* Write wasn't successfull. Refresh all. */ 331 /* Write wasn't successful. Refresh all. */
332 tp->update_flags = TTY_UPDATE_ALL; 332 tp->update_flags = TTY_UPDATE_ALL;
333 tty3270_set_timer(tp, 1); 333 tty3270_set_timer(tp, 1);
334 } 334 }
@@ -1718,9 +1718,8 @@ tty3270_wait_until_sent(struct tty_struct *tty, int timeout)
1718{ 1718{
1719} 1719}
1720 1720
1721static int 1721static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd,
1722tty3270_ioctl(struct tty_struct *tty, struct file *file, 1722 unsigned long arg)
1723 unsigned int cmd, unsigned long arg)
1724{ 1723{
1725 struct tty3270 *tp; 1724 struct tty3270 *tp;
1726 1725
@@ -1729,13 +1728,12 @@ tty3270_ioctl(struct tty_struct *tty, struct file *file,
1729 return -ENODEV; 1728 return -ENODEV;
1730 if (tty->flags & (1 << TTY_IO_ERROR)) 1729 if (tty->flags & (1 << TTY_IO_ERROR))
1731 return -EIO; 1730 return -EIO;
1732 return kbd_ioctl(tp->kbd, file, cmd, arg); 1731 return kbd_ioctl(tp->kbd, cmd, arg);
1733} 1732}
1734 1733
1735#ifdef CONFIG_COMPAT 1734#ifdef CONFIG_COMPAT
1736static long 1735static long tty3270_compat_ioctl(struct tty_struct *tty,
1737tty3270_compat_ioctl(struct tty_struct *tty, struct file *file, 1736 unsigned int cmd, unsigned long arg)
1738 unsigned int cmd, unsigned long arg)
1739{ 1737{
1740 struct tty3270 *tp; 1738 struct tty3270 *tp;
1741 1739
@@ -1744,7 +1742,7 @@ tty3270_compat_ioctl(struct tty_struct *tty, struct file *file,
1744 return -ENODEV; 1742 return -ENODEV;
1745 if (tty->flags & (1 << TTY_IO_ERROR)) 1743 if (tty->flags & (1 << TTY_IO_ERROR))
1746 return -EIO; 1744 return -EIO;
1747 return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg)); 1745 return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg));
1748} 1746}
1749#endif 1747#endif
1750 1748
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 04e532eec032..31a3ccbb6495 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -47,7 +47,7 @@ static int vmcp_release(struct inode *inode, struct file *file)
47{ 47{
48 struct vmcp_session *session; 48 struct vmcp_session *session;
49 49
50 session = (struct vmcp_session *)file->private_data; 50 session = file->private_data;
51 file->private_data = NULL; 51 file->private_data = NULL;
52 free_pages((unsigned long)session->response, get_order(session->bufsize)); 52 free_pages((unsigned long)session->response, get_order(session->bufsize));
53 kfree(session); 53 kfree(session);
@@ -94,7 +94,7 @@ vmcp_write(struct file *file, const char __user *buff, size_t count,
94 return -EFAULT; 94 return -EFAULT;
95 } 95 }
96 cmd[count] = '\0'; 96 cmd[count] = '\0';
97 session = (struct vmcp_session *)file->private_data; 97 session = file->private_data;
98 if (mutex_lock_interruptible(&session->mutex)) { 98 if (mutex_lock_interruptible(&session->mutex)) {
99 kfree(cmd); 99 kfree(cmd);
100 return -ERESTARTSYS; 100 return -ERESTARTSYS;
@@ -136,7 +136,7 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
136 int __user *argp; 136 int __user *argp;
137 int temp; 137 int temp;
138 138
139 session = (struct vmcp_session *)file->private_data; 139 session = file->private_data;
140 if (is_compat_task()) 140 if (is_compat_task())
141 argp = compat_ptr(arg); 141 argp = compat_ptr(arg);
142 else 142 else
@@ -177,6 +177,7 @@ static const struct file_operations vmcp_fops = {
177 .write = vmcp_write, 177 .write = vmcp_write,
178 .unlocked_ioctl = vmcp_ioctl, 178 .unlocked_ioctl = vmcp_ioctl,
179 .compat_ioctl = vmcp_ioctl, 179 .compat_ioctl = vmcp_ioctl,
180 .llseek = no_llseek,
180}; 181};
181 182
182static struct miscdevice vmcp_dev = { 183static struct miscdevice vmcp_dev = {
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index e40a1b892866..c837d7419a6a 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -30,7 +30,6 @@
30#include <linux/kmod.h> 30#include <linux/kmod.h>
31#include <linux/cdev.h> 31#include <linux/cdev.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include <linux/smp_lock.h>
34#include <linux/string.h> 33#include <linux/string.h>
35 34
36MODULE_AUTHOR 35MODULE_AUTHOR
@@ -97,6 +96,7 @@ static const struct file_operations vmlogrdr_fops = {
97 .open = vmlogrdr_open, 96 .open = vmlogrdr_open,
98 .release = vmlogrdr_release, 97 .release = vmlogrdr_release,
99 .read = vmlogrdr_read, 98 .read = vmlogrdr_read,
99 .llseek = no_llseek,
100}; 100};
101 101
102 102
@@ -214,7 +214,7 @@ static void vmlogrdr_iucv_message_pending(struct iucv_path *path,
214 214
215static int vmlogrdr_get_recording_class_AB(void) 215static int vmlogrdr_get_recording_class_AB(void)
216{ 216{
217 char cp_command[]="QUERY COMMAND RECORDING "; 217 static const char cp_command[] = "QUERY COMMAND RECORDING ";
218 char cp_response[80]; 218 char cp_response[80];
219 char *tail; 219 char *tail;
220 int len,i; 220 int len,i;
@@ -248,27 +248,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
248 char cp_command[80]; 248 char cp_command[80];
249 char cp_response[160]; 249 char cp_response[160];
250 char *onoff, *qid_string; 250 char *onoff, *qid_string;
251 int rc;
251 252
252 memset(cp_command, 0x00, sizeof(cp_command)); 253 onoff = ((action == 1) ? "ON" : "OFF");
253 memset(cp_response, 0x00, sizeof(cp_response));
254
255 onoff = ((action == 1) ? "ON" : "OFF");
256 qid_string = ((recording_class_AB == 1) ? " QID * " : ""); 254 qid_string = ((recording_class_AB == 1) ? " QID * " : "");
257 255
258 /* 256 /*
259 * The recording commands needs to be called with option QID 257 * The recording commands needs to be called with option QID
260 * for guests that have previlege classes A or B. 258 * for guests that have previlege classes A or B.
261 * Purging has to be done as separate step, because recording 259 * Purging has to be done as separate step, because recording
262 * can't be switched on as long as records are on the queue. 260 * can't be switched on as long as records are on the queue.
263 * Doing both at the same time doesn't work. 261 * Doing both at the same time doesn't work.
264 */ 262 */
265 263 if (purge && (action == 1)) {
266 if (purge) { 264 memset(cp_command, 0x00, sizeof(cp_command));
265 memset(cp_response, 0x00, sizeof(cp_response));
267 snprintf(cp_command, sizeof(cp_command), 266 snprintf(cp_command, sizeof(cp_command),
268 "RECORDING %s PURGE %s", 267 "RECORDING %s PURGE %s",
269 logptr->recording_name, 268 logptr->recording_name,
270 qid_string); 269 qid_string);
271
272 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); 270 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
273 } 271 }
274 272
@@ -278,19 +276,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
278 logptr->recording_name, 276 logptr->recording_name,
279 onoff, 277 onoff,
280 qid_string); 278 qid_string);
281
282 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); 279 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
283 /* The recording command will usually answer with 'Command complete' 280 /* The recording command will usually answer with 'Command complete'
284 * on success, but when the specific service was never connected 281 * on success, but when the specific service was never connected
285 * before then there might be an additional informational message 282 * before then there might be an additional informational message
286 * 'HCPCRC8072I Recording entry not found' before the 283 * 'HCPCRC8072I Recording entry not found' before the
287 * 'Command complete'. So I use strstr rather then the strncmp. 284 * 'Command complete'. So I use strstr rather then the strncmp.
288 */ 285 */
289 if (strstr(cp_response,"Command complete")) 286 if (strstr(cp_response,"Command complete"))
290 return 0; 287 rc = 0;
291 else 288 else
292 return -EIO; 289 rc = -EIO;
290 /*
291 * If we turn recording off, we have to purge any remaining records
292 * afterwards, as a large number of queued records may impact z/VM
293 * performance.
294 */
295 if (purge && (action == 0)) {
296 memset(cp_command, 0x00, sizeof(cp_command));
297 memset(cp_response, 0x00, sizeof(cp_response));
298 snprintf(cp_command, sizeof(cp_command),
299 "RECORDING %s PURGE %s",
300 logptr->recording_name,
301 qid_string);
302 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
303 }
293 304
305 return rc;
294} 306}
295 307
296 308
@@ -637,7 +649,7 @@ static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver,
637 char *buf) 649 char *buf)
638{ 650{
639 651
640 char cp_command[] = "QUERY RECORDING "; 652 static const char cp_command[] = "QUERY RECORDING ";
641 int len; 653 int len;
642 654
643 cpcmd(cp_command, buf, 4096, NULL); 655 cpcmd(cp_command, buf, 4096, NULL);
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 1de672f21037..f6b00c3df425 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -11,9 +11,9 @@
11#define KMSG_COMPONENT "vmur" 11#define KMSG_COMPONENT "vmur"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13 13
14#include <linux/kernel_stat.h>
14#include <linux/cdev.h> 15#include <linux/cdev.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/smp_lock.h>
17 17
18#include <asm/uaccess.h> 18#include <asm/uaccess.h>
19#include <asm/cio.h> 19#include <asm/cio.h>
@@ -64,8 +64,10 @@ static int ur_set_offline(struct ccw_device *cdev);
64static int ur_pm_suspend(struct ccw_device *cdev); 64static int ur_pm_suspend(struct ccw_device *cdev);
65 65
66static struct ccw_driver ur_driver = { 66static struct ccw_driver ur_driver = {
67 .name = "vmur", 67 .driver = {
68 .owner = THIS_MODULE, 68 .name = "vmur",
69 .owner = THIS_MODULE,
70 },
69 .ids = ur_ids, 71 .ids = ur_ids,
70 .probe = ur_probe, 72 .probe = ur_probe,
71 .remove = ur_remove, 73 .remove = ur_remove,
@@ -303,6 +305,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
303{ 305{
304 struct urdev *urd; 306 struct urdev *urd;
305 307
308 kstat_cpu(smp_processor_id()).irqs[IOINT_VMR]++;
306 TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n", 309 TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",
307 intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, 310 intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
308 irb->scsw.cmd.count); 311 irb->scsw.cmd.count);
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index e13508c98b1a..12ef9121d4f0 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -297,6 +297,7 @@ static const struct file_operations vmwdt_fops = {
297 .unlocked_ioctl = &vmwdt_ioctl, 297 .unlocked_ioctl = &vmwdt_ioctl,
298 .write = &vmwdt_write, 298 .write = &vmwdt_write,
299 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
300 .llseek = noop_llseek,
300}; 301};
301 302
302static struct miscdevice vmwdt_dev = { 303static struct miscdevice vmwdt_dev = {
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index f5ea3384a4b9..3b94044027c2 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -459,6 +459,7 @@ static const struct file_operations zcore_memmap_fops = {
459 .read = zcore_memmap_read, 459 .read = zcore_memmap_read,
460 .open = zcore_memmap_open, 460 .open = zcore_memmap_open,
461 .release = zcore_memmap_release, 461 .release = zcore_memmap_release,
462 .llseek = no_llseek,
462}; 463};
463 464
464static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf, 465static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
@@ -486,6 +487,7 @@ static const struct file_operations zcore_reipl_fops = {
486 .write = zcore_reipl_write, 487 .write = zcore_reipl_write,
487 .open = zcore_reipl_open, 488 .open = zcore_reipl_open,
488 .release = zcore_reipl_release, 489 .release = zcore_reipl_release,
490 .llseek = no_llseek,
489}; 491};
490 492
491#ifdef CONFIG_32BIT 493#ifdef CONFIG_32BIT