aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd_alias.c4
-rw-r--r--drivers/s390/block/dasd_eckd.c11
-rw-r--r--drivers/s390/char/Kconfig12
-rw-r--r--drivers/s390/char/Makefile3
-rw-r--r--drivers/s390/char/monwriter.c4
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp.h24
-rw-r--r--drivers/s390/char/sclp_config.c14
-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_3590.c11
-rw-r--r--drivers/s390/char/tape_block.c444
-rw-r--r--drivers/s390/char/tape_std.c3
-rw-r--r--drivers/s390/cio/chsc.c35
-rw-r--r--drivers/s390/cio/device_fsm.c8
-rw-r--r--drivers/s390/cio/device_ops.c3
-rw-r--r--drivers/s390/cio/qdio_main.c2
-rw-r--r--drivers/s390/crypto/ap_bus.c8
19 files changed, 258 insertions, 600 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 2b771f18d1ad..c388eda1e2b1 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -253,13 +253,11 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
253 */ 253 */
254void dasd_alias_lcu_setup_complete(struct dasd_device *device) 254void dasd_alias_lcu_setup_complete(struct dasd_device *device)
255{ 255{
256 struct dasd_eckd_private *private;
257 unsigned long flags; 256 unsigned long flags;
258 struct alias_server *server; 257 struct alias_server *server;
259 struct alias_lcu *lcu; 258 struct alias_lcu *lcu;
260 struct dasd_uid uid; 259 struct dasd_uid uid;
261 260
262 private = (struct dasd_eckd_private *) device->private;
263 device->discipline->get_uid(device, &uid); 261 device->discipline->get_uid(device, &uid);
264 lcu = NULL; 262 lcu = NULL;
265 spin_lock_irqsave(&aliastree.lock, flags); 263 spin_lock_irqsave(&aliastree.lock, flags);
@@ -279,13 +277,11 @@ void dasd_alias_lcu_setup_complete(struct dasd_device *device)
279 277
280void dasd_alias_wait_for_lcu_setup(struct dasd_device *device) 278void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
281{ 279{
282 struct dasd_eckd_private *private;
283 unsigned long flags; 280 unsigned long flags;
284 struct alias_server *server; 281 struct alias_server *server;
285 struct alias_lcu *lcu; 282 struct alias_lcu *lcu;
286 struct dasd_uid uid; 283 struct dasd_uid uid;
287 284
288 private = (struct dasd_eckd_private *) device->private;
289 device->discipline->get_uid(device, &uid); 285 device->discipline->get_uid(device, &uid);
290 lcu = NULL; 286 lcu = NULL;
291 spin_lock_irqsave(&aliastree.lock, flags); 287 spin_lock_irqsave(&aliastree.lock, flags);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 3ebdf5f92f8f..30fb979d684d 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1611,10 +1611,8 @@ static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr,
1611 1611
1612static int dasd_eckd_start_analysis(struct dasd_block *block) 1612static int dasd_eckd_start_analysis(struct dasd_block *block)
1613{ 1613{
1614 struct dasd_eckd_private *private;
1615 struct dasd_ccw_req *init_cqr; 1614 struct dasd_ccw_req *init_cqr;
1616 1615
1617 private = (struct dasd_eckd_private *) block->base->private;
1618 init_cqr = dasd_eckd_analysis_ccw(block->base); 1616 init_cqr = dasd_eckd_analysis_ccw(block->base);
1619 if (IS_ERR(init_cqr)) 1617 if (IS_ERR(init_cqr))
1620 return PTR_ERR(init_cqr); 1618 return PTR_ERR(init_cqr);
@@ -2264,7 +2262,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2264 unsigned int blk_per_trk, 2262 unsigned int blk_per_trk,
2265 unsigned int blksize) 2263 unsigned int blksize)
2266{ 2264{
2267 struct dasd_eckd_private *private;
2268 unsigned long *idaws; 2265 unsigned long *idaws;
2269 struct dasd_ccw_req *cqr; 2266 struct dasd_ccw_req *cqr;
2270 struct ccw1 *ccw; 2267 struct ccw1 *ccw;
@@ -2283,7 +2280,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2283 unsigned int recoffs; 2280 unsigned int recoffs;
2284 2281
2285 basedev = block->base; 2282 basedev = block->base;
2286 private = (struct dasd_eckd_private *) basedev->private;
2287 if (rq_data_dir(req) == READ) 2283 if (rq_data_dir(req) == READ)
2288 cmd = DASD_ECKD_CCW_READ_TRACK_DATA; 2284 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
2289 else if (rq_data_dir(req) == WRITE) 2285 else if (rq_data_dir(req) == WRITE)
@@ -2556,8 +2552,7 @@ static int prepare_itcw(struct itcw *itcw,
2556 2552
2557 dcw = itcw_add_dcw(itcw, pfx_cmd, 0, 2553 dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
2558 &pfxdata, sizeof(pfxdata), total_data_size); 2554 &pfxdata, sizeof(pfxdata), total_data_size);
2559 2555 return IS_ERR(dcw) ? PTR_ERR(dcw) : 0;
2560 return rc;
2561} 2556}
2562 2557
2563static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( 2558static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
@@ -2573,7 +2568,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2573 unsigned int blk_per_trk, 2568 unsigned int blk_per_trk,
2574 unsigned int blksize) 2569 unsigned int blksize)
2575{ 2570{
2576 struct dasd_eckd_private *private;
2577 struct dasd_ccw_req *cqr; 2571 struct dasd_ccw_req *cqr;
2578 struct req_iterator iter; 2572 struct req_iterator iter;
2579 struct bio_vec *bv; 2573 struct bio_vec *bv;
@@ -2594,7 +2588,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2594 unsigned int count, count_to_trk_end; 2588 unsigned int count, count_to_trk_end;
2595 2589
2596 basedev = block->base; 2590 basedev = block->base;
2597 private = (struct dasd_eckd_private *) basedev->private;
2598 if (rq_data_dir(req) == READ) { 2591 if (rq_data_dir(req) == READ) {
2599 cmd = DASD_ECKD_CCW_READ_TRACK_DATA; 2592 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
2600 itcw_op = ITCW_OP_READ; 2593 itcw_op = ITCW_OP_READ;
@@ -2801,7 +2794,6 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
2801 struct dasd_block *block, 2794 struct dasd_block *block,
2802 struct request *req) 2795 struct request *req)
2803{ 2796{
2804 struct dasd_eckd_private *private;
2805 unsigned long *idaws; 2797 unsigned long *idaws;
2806 struct dasd_device *basedev; 2798 struct dasd_device *basedev;
2807 struct dasd_ccw_req *cqr; 2799 struct dasd_ccw_req *cqr;
@@ -2836,7 +2828,6 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
2836 trkcount = last_trk - first_trk + 1; 2828 trkcount = last_trk - first_trk + 1;
2837 first_offs = 0; 2829 first_offs = 0;
2838 basedev = block->base; 2830 basedev = block->base;
2839 private = (struct dasd_eckd_private *) basedev->private;
2840 2831
2841 if (rq_data_dir(req) == READ) 2832 if (rq_data_dir(req) == READ)
2842 cmd = DASD_ECKD_CCW_READ_TRACK; 2833 cmd = DASD_ECKD_CCW_READ_TRACK;
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig
index dcee3c5c8954..a4f117d9fdc6 100644
--- a/drivers/s390/char/Kconfig
+++ b/drivers/s390/char/Kconfig
@@ -119,18 +119,6 @@ config S390_TAPE
119comment "S/390 tape interface support" 119comment "S/390 tape interface support"
120 depends on S390_TAPE 120 depends on S390_TAPE
121 121
122config S390_TAPE_BLOCK
123 def_bool y
124 prompt "Support for tape block devices"
125 depends on S390_TAPE && BLOCK
126 help
127 Select this option if you want to access your channel-attached tape
128 devices using the block device interface. This interface is similar
129 to CD-ROM devices on other platforms. The tapes can only be
130 accessed read-only when using this interface. Have a look at
131 <file:Documentation/s390/TAPE> for further information about creating
132 volumes for and using this interface. It is safe to say "Y" here.
133
134comment "S/390 tape hardware support" 122comment "S/390 tape hardware support"
135 depends on S390_TAPE 123 depends on S390_TAPE
136 124
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/monwriter.c b/drivers/s390/char/monwriter.c
index e0702d3ea33b..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)
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index e21a5c39ef20..810ac38631c3 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -598,7 +598,6 @@ __raw3270_size_device(struct raw3270 *rp)
598 static const unsigned char wbuf[] = 598 static const unsigned char wbuf[] =
599 { 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 }; 599 { 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 };
600 struct raw3270_ua *uap; 600 struct raw3270_ua *uap;
601 unsigned short count;
602 int rc; 601 int rc;
603 602
604 /* 603 /*
@@ -653,7 +652,6 @@ __raw3270_size_device(struct raw3270 *rp)
653 if (rc) 652 if (rc)
654 return rc; 653 return rc;
655 /* Got a Query Reply */ 654 /* Got a Query Reply */
656 count = sizeof(rp->init_data) - rp->init_request.rescnt;
657 uap = (struct raw3270_ua *) (rp->init_data + 1); 655 uap = (struct raw3270_ua *) (rp->init_data + 1);
658 /* Paranoia check. */ 656 /* Paranoia check. */
659 if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81) 657 if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81)
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_config.c b/drivers/s390/char/sclp_config.c
index 16e232a99fb7..95b909ac2b73 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -71,21 +71,9 @@ static struct sclp_register sclp_conf_register =
71 71
72static int __init sclp_conf_init(void) 72static int __init sclp_conf_init(void)
73{ 73{
74 int rc;
75
76 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); 74 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
77 INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); 75 INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
78 76 return sclp_register(&sclp_conf_register);
79 rc = sclp_register(&sclp_conf_register);
80 if (rc)
81 return rc;
82
83 if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) {
84 pr_warning("no configuration management.\n");
85 sclp_unregister(&sclp_conf_register);
86 rc = -ENOSYS;
87 }
88 return rc;
89} 77}
90 78
91__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_3590.c b/drivers/s390/char/tape_3590.c
index b98dcbd16711..a7d570728882 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -796,10 +796,8 @@ static void tape_3590_med_state_set(struct tape_device *device,
796static int 796static int
797tape_3590_done(struct tape_device *device, struct tape_request *request) 797tape_3590_done(struct tape_device *device, struct tape_request *request)
798{ 798{
799 struct tape_3590_disc_data *disc_data;
800 799
801 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]); 800 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
802 disc_data = device->discdata;
803 801
804 switch (request->op) { 802 switch (request->op) {
805 case TO_BSB: 803 case TO_BSB:
@@ -1394,17 +1392,12 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
1394static int tape_3590_crypt_error(struct tape_device *device, 1392static int tape_3590_crypt_error(struct tape_device *device,
1395 struct tape_request *request, struct irb *irb) 1393 struct tape_request *request, struct irb *irb)
1396{ 1394{
1397 u8 cu_rc, ekm_rc1; 1395 u8 cu_rc;
1398 u16 ekm_rc2; 1396 u16 ekm_rc2;
1399 u32 drv_rc;
1400 const char *bus_id;
1401 char *sense; 1397 char *sense;
1402 1398
1403 sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data; 1399 sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
1404 bus_id = dev_name(&device->cdev->dev);
1405 cu_rc = sense[0]; 1400 cu_rc = sense[0];
1406 drv_rc = *((u32*) &sense[5]) & 0xffffff;
1407 ekm_rc1 = sense[9];
1408 ekm_rc2 = *((u16*) &sense[10]); 1401 ekm_rc2 = *((u16*) &sense[10]);
1409 if ((cu_rc == 0) && (ekm_rc2 == 0xee31)) 1402 if ((cu_rc == 0) && (ekm_rc2 == 0xee31))
1410 /* key not defined on EKM */ 1403 /* key not defined on EKM */
@@ -1429,7 +1422,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1429 struct irb *irb) 1422 struct irb *irb)
1430{ 1423{
1431 struct tape_3590_sense *sense; 1424 struct tape_3590_sense *sense;
1432 int rc;
1433 1425
1434#ifdef CONFIG_S390_TAPE_BLOCK 1426#ifdef CONFIG_S390_TAPE_BLOCK
1435 if (request->op == TO_BLOCK) { 1427 if (request->op == TO_BLOCK) {
@@ -1454,7 +1446,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1454 * - "break": basic error recovery is done 1446 * - "break": basic error recovery is done
1455 * - "goto out:": just print error message if available 1447 * - "goto out:": just print error message if available
1456 */ 1448 */
1457 rc = -EIO;
1458 switch (sense->rc_rqc) { 1449 switch (sense->rc_rqc) {
1459 1450
1460 case 0x1110: 1451 case 0x1110:
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
deleted file mode 100644
index 1b3924c2fffd..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/mutex.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 DEFINE_MUTEX(tape_block_mutex);
49static int tapeblock_open(struct block_device *, fmode_t);
50static int tapeblock_release(struct gendisk *, fmode_t);
51static unsigned int tapeblock_check_events(struct gendisk *, unsigned int);
52static int tapeblock_revalidate_disk(struct gendisk *);
53
54static const struct block_device_operations tapeblock_fops = {
55 .owner = THIS_MODULE,
56 .open = tapeblock_open,
57 .release = tapeblock_release,
58 .check_events = tapeblock_check_events,
59 .revalidate_disk = tapeblock_revalidate_disk,
60};
61
62static int tapeblock_major = 0;
63
64static void
65tapeblock_trigger_requeue(struct tape_device *device)
66{
67 /* Protect against rescheduling. */
68 if (atomic_cmpxchg(&device->blk_data.requeue_scheduled, 0, 1) != 0)
69 return;
70 schedule_work(&device->blk_data.requeue_task);
71}
72
73/*
74 * Post finished request.
75 */
76static void
77__tapeblock_end_request(struct tape_request *ccw_req, void *data)
78{
79 struct tape_device *device;
80 struct request *req;
81
82 DBF_LH(6, "__tapeblock_end_request()\n");
83
84 device = ccw_req->device;
85 req = (struct request *) data;
86 blk_end_request_all(req, (ccw_req->rc == 0) ? 0 : -EIO);
87 if (ccw_req->rc == 0)
88 /* Update position. */
89 device->blk_data.block_position =
90 (blk_rq_pos(req) + blk_rq_sectors(req)) >> TAPEBLOCK_HSEC_S2B;
91 else
92 /* We lost the position information due to an error. */
93 device->blk_data.block_position = -1;
94 device->discipline->free_bread(ccw_req);
95 if (!list_empty(&device->req_queue) ||
96 blk_peek_request(device->blk_data.request_queue))
97 tapeblock_trigger_requeue(device);
98}
99
100/*
101 * Feed the tape device CCW queue with requests supplied in a list.
102 */
103static int
104tapeblock_start_request(struct tape_device *device, struct request *req)
105{
106 struct tape_request * ccw_req;
107 int rc;
108
109 DBF_LH(6, "tapeblock_start_request(%p, %p)\n", device, req);
110
111 ccw_req = device->discipline->bread(device, req);
112 if (IS_ERR(ccw_req)) {
113 DBF_EVENT(1, "TBLOCK: bread failed\n");
114 blk_end_request_all(req, -EIO);
115 return PTR_ERR(ccw_req);
116 }
117 ccw_req->callback = __tapeblock_end_request;
118 ccw_req->callback_data = (void *) req;
119 ccw_req->retries = TAPEBLOCK_RETRIES;
120
121 rc = tape_do_io_async(device, ccw_req);
122 if (rc) {
123 /*
124 * Start/enqueueing failed. No retries in
125 * this case.
126 */
127 blk_end_request_all(req, -EIO);
128 device->discipline->free_bread(ccw_req);
129 }
130
131 return rc;
132}
133
134/*
135 * Move requests from the block device request queue to the tape device ccw
136 * queue.
137 */
138static void
139tapeblock_requeue(struct work_struct *work) {
140 struct tape_blk_data * blkdat;
141 struct tape_device * device;
142 struct request_queue * queue;
143 int nr_queued;
144 struct request * req;
145 struct list_head * l;
146 int rc;
147
148 blkdat = container_of(work, struct tape_blk_data, requeue_task);
149 device = blkdat->device;
150 if (!device)
151 return;
152
153 spin_lock_irq(get_ccwdev_lock(device->cdev));
154 queue = device->blk_data.request_queue;
155
156 /* Count number of requests on ccw queue. */
157 nr_queued = 0;
158 list_for_each(l, &device->req_queue)
159 nr_queued++;
160 spin_unlock(get_ccwdev_lock(device->cdev));
161
162 spin_lock_irq(&device->blk_data.request_queue_lock);
163 while (
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_work_sync(&device->blk_data.requeue_task);
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 unsigned int
343tapeblock_check_events(struct gendisk *disk, unsigned int clearing)
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 ? DISK_EVENT_MEDIA_CHANGE : 0;
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 mutex_lock(&tape_block_mutex);
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 mutex_unlock(&tape_block_mutex);
389 return 0;
390
391release:
392 tape_release(device);
393 put_device:
394 tape_put_device(device);
395 mutex_unlock(&tape_block_mutex);
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 mutex_lock(&tape_block_mutex);
411 tape_state_set(device, TS_IN_USE);
412 tape_release(device);
413 tape_put_device(device);
414 mutex_unlock(&tape_block_mutex);
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_std.c b/drivers/s390/char/tape_std.c
index 3c3f342149ec..e7650170274a 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -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/cio/chsc.c b/drivers/s390/cio/chsc.c
index 0689fcf23a11..75c3f1f8fd43 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -326,6 +326,36 @@ static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
326 s390_process_res_acc(&link); 326 s390_process_res_acc(&link);
327} 327}
328 328
329static void chsc_process_sei_chp_avail(struct chsc_sei_area *sei_area)
330{
331 struct channel_path *chp;
332 struct chp_id chpid;
333 u8 *data;
334 int num;
335
336 CIO_CRW_EVENT(4, "chsc: channel path availability information\n");
337 if (sei_area->rs != 0)
338 return;
339 data = sei_area->ccdf;
340 chp_id_init(&chpid);
341 for (num = 0; num <= __MAX_CHPID; num++) {
342 if (!chp_test_bit(data, num))
343 continue;
344 chpid.id = num;
345
346 CIO_CRW_EVENT(4, "Update information for channel path "
347 "%x.%02x\n", chpid.cssid, chpid.id);
348 chp = chpid_to_chp(chpid);
349 if (!chp) {
350 chp_new(chpid);
351 continue;
352 }
353 mutex_lock(&chp->lock);
354 chsc_determine_base_channel_path_desc(chpid, &chp->desc);
355 mutex_unlock(&chp->lock);
356 }
357}
358
329struct chp_config_data { 359struct chp_config_data {
330 u8 map[32]; 360 u8 map[32];
331 u8 op; 361 u8 op;
@@ -376,9 +406,12 @@ static void chsc_process_sei(struct chsc_sei_area *sei_area)
376 case 1: /* link incident*/ 406 case 1: /* link incident*/
377 chsc_process_sei_link_incident(sei_area); 407 chsc_process_sei_link_incident(sei_area);
378 break; 408 break;
379 case 2: /* i/o resource accessibiliy */ 409 case 2: /* i/o resource accessibility */
380 chsc_process_sei_res_acc(sei_area); 410 chsc_process_sei_res_acc(sei_area);
381 break; 411 break;
412 case 7: /* channel-path-availability information */
413 chsc_process_sei_chp_avail(sei_area);
414 break;
382 case 8: /* channel-path-configuration notification */ 415 case 8: /* channel-path-configuration notification */
383 chsc_process_sei_chp_config(sei_area); 416 chsc_process_sei_chp_config(sei_area);
384 break; 417 break;
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 6084103672b5..52c233fa2b12 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -408,9 +408,10 @@ ccw_device_done(struct ccw_device *cdev, int state)
408 CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel " 408 CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel "
409 "%04x\n", cdev->private->dev_id.devno, 409 "%04x\n", cdev->private->dev_id.devno,
410 sch->schid.sch_no); 410 sch->schid.sch_no);
411 if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK) 411 if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK) {
412 cdev->private->state = DEV_STATE_NOT_OPER;
412 ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 413 ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
413 else 414 } else
414 ccw_device_set_disconnected(cdev); 415 ccw_device_set_disconnected(cdev);
415 cdev->private->flags.donotify = 0; 416 cdev->private->flags.donotify = 0;
416 break; 417 break;
@@ -840,9 +841,6 @@ call_handler:
840static void 841static void
841ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event) 842ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
842{ 843{
843 struct subchannel *sch;
844
845 sch = to_subchannel(cdev->dev.parent);
846 ccw_device_set_timeout(cdev, 0); 844 ccw_device_set_timeout(cdev, 0);
847 /* Start delayed path verification. */ 845 /* Start delayed path verification. */
848 ccw_device_online_verify(cdev, 0); 846 ccw_device_online_verify(cdev, 0);
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 651976b54af8..f98698d5735e 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -418,12 +418,9 @@ int ccw_device_resume(struct ccw_device *cdev)
418int 418int
419ccw_device_call_handler(struct ccw_device *cdev) 419ccw_device_call_handler(struct ccw_device *cdev)
420{ 420{
421 struct subchannel *sch;
422 unsigned int stctl; 421 unsigned int stctl;
423 int ending_status; 422 int ending_status;
424 423
425 sch = to_subchannel(cdev->dev.parent);
426
427 /* 424 /*
428 * we allow for the device action handler if . 425 * we allow for the device action handler if .
429 * - we received ending status 426 * - we received ending status
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index e8f267eb8887..55e8f721e38a 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -1446,7 +1446,7 @@ set:
1446static int handle_outbound(struct qdio_q *q, unsigned int callflags, 1446static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1447 int bufnr, int count) 1447 int bufnr, int count)
1448{ 1448{
1449 unsigned char state; 1449 unsigned char state = 0;
1450 int used, rc = 0; 1450 int used, rc = 0;
1451 1451
1452 qperf_inc(q, outbound_call); 1452 qperf_inc(q, outbound_call);
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 67302b944ab3..16e4a25596e7 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -1183,8 +1183,12 @@ static void ap_scan_bus(struct work_struct *unused)
1183 INIT_LIST_HEAD(&ap_dev->list); 1183 INIT_LIST_HEAD(&ap_dev->list);
1184 setup_timer(&ap_dev->timeout, ap_request_timeout, 1184 setup_timer(&ap_dev->timeout, ap_request_timeout,
1185 (unsigned long) ap_dev); 1185 (unsigned long) ap_dev);
1186 if (device_type == 0) 1186 if (device_type == 0) {
1187 ap_probe_device_type(ap_dev); 1187 if (ap_probe_device_type(ap_dev)) {
1188 kfree(ap_dev);
1189 continue;
1190 }
1191 }
1188 else 1192 else
1189 ap_dev->device_type = device_type; 1193 ap_dev->device_type = device_type;
1190 1194