aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/con3215.c18
-rw-r--r--drivers/s390/char/con3270.c2
-rw-r--r--drivers/s390/char/fs3270.c32
-rw-r--r--drivers/s390/char/keyboard.c1
-rw-r--r--drivers/s390/char/monreader.c11
-rw-r--r--drivers/s390/char/monwriter.c10
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp.c4
-rw-r--r--drivers/s390/char/sclp_async.c7
-rw-r--r--drivers/s390/char/sclp_cmd.c10
-rw-r--r--drivers/s390/char/sclp_con.c1
-rw-r--r--drivers/s390/char/sclp_tty.c2
-rw-r--r--drivers/s390/char/sclp_vt220.c5
-rw-r--r--drivers/s390/char/tape.h9
-rw-r--r--drivers/s390/char/tape_34xx.c10
-rw-r--r--drivers/s390/char/tape_3590.c6
-rw-r--r--drivers/s390/char/tape_block.c60
-rw-r--r--drivers/s390/char/tape_char.c75
-rw-r--r--drivers/s390/char/tape_class.c6
-rw-r--r--drivers/s390/char/tape_core.c68
-rw-r--r--drivers/s390/char/tape_proc.c5
-rw-r--r--drivers/s390/char/tape_std.c3
-rw-r--r--drivers/s390/char/tty3270.c20
-rw-r--r--drivers/s390/char/vmcp.c13
-rw-r--r--drivers/s390/char/vmlogrdr.c11
-rw-r--r--drivers/s390/char/vmur.c4
-rw-r--r--drivers/s390/char/vmwatchdog.c30
-rw-r--r--drivers/s390/char/zcore.c201
28 files changed, 304 insertions, 322 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 21639d6c996f..59ec073724bf 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -857,7 +857,6 @@ static struct console con3215 = {
857 857
858/* 858/*
859 * 3215 console initialization code called from console_init(). 859 * 3215 console initialization code called from console_init().
860 * NOTE: This is called before kmalloc is available.
861 */ 860 */
862static int __init con3215_init(void) 861static int __init con3215_init(void)
863{ 862{
@@ -1038,22 +1037,6 @@ static void tty3215_flush_buffer(struct tty_struct *tty)
1038} 1037}
1039 1038
1040/* 1039/*
1041 * Currently we don't have any io controls for 3215 ttys
1042 */
1043static int tty3215_ioctl(struct tty_struct *tty, struct file * file,
1044 unsigned int cmd, unsigned long arg)
1045{
1046 if (tty->flags & (1 << TTY_IO_ERROR))
1047 return -EIO;
1048
1049 switch (cmd) {
1050 default:
1051 return -ENOIOCTLCMD;
1052 }
1053 return 0;
1054}
1055
1056/*
1057 * Disable reading from a 3215 tty 1040 * Disable reading from a 3215 tty
1058 */ 1041 */
1059static void tty3215_throttle(struct tty_struct * tty) 1042static void tty3215_throttle(struct tty_struct * tty)
@@ -1118,7 +1101,6 @@ static const struct tty_operations tty3215_ops = {
1118 .write_room = tty3215_write_room, 1101 .write_room = tty3215_write_room,
1119 .chars_in_buffer = tty3215_chars_in_buffer, 1102 .chars_in_buffer = tty3215_chars_in_buffer,
1120 .flush_buffer = tty3215_flush_buffer, 1103 .flush_buffer = tty3215_flush_buffer,
1121 .ioctl = tty3215_ioctl,
1122 .throttle = tty3215_throttle, 1104 .throttle = tty3215_throttle,
1123 .unthrottle = tty3215_unthrottle, 1105 .unthrottle = tty3215_unthrottle,
1124 .stop = tty3215_stop, 1106 .stop = tty3215_stop,
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index bb838bdf829d..bb07577e8fd4 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -12,6 +12,7 @@
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/slab.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/reboot.h> 17#include <linux/reboot.h>
17 18
@@ -572,7 +573,6 @@ static struct console con3270 = {
572 573
573/* 574/*
574 * 3270 console initialization code called from console_init(). 575 * 3270 console initialization code called from console_init().
575 * NOTE: This is called before kmalloc is available.
576 */ 576 */
577static int __init 577static int __init
578con3270_init(void) 578con3270_init(void)
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 097d3846a828..0eabcca3c92d 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -12,9 +12,11 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/slab.h>
15#include <linux/types.h> 16#include <linux/types.h>
16#include <linux/smp_lock.h> 17#include <linux/smp_lock.h>
17 18
19#include <asm/compat.h>
18#include <asm/ccwdev.h> 20#include <asm/ccwdev.h>
19#include <asm/cio.h> 21#include <asm/cio.h>
20#include <asm/ebcdic.h> 22#include <asm/ebcdic.h>
@@ -38,6 +40,8 @@ struct fs3270 {
38 size_t rdbuf_size; /* size of data returned by RDBUF */ 40 size_t rdbuf_size; /* size of data returned by RDBUF */
39}; 41};
40 42
43static DEFINE_MUTEX(fs3270_mutex);
44
41static void 45static void
42fs3270_wake_up(struct raw3270_request *rq, void *data) 46fs3270_wake_up(struct raw3270_request *rq, void *data)
43{ 47{
@@ -74,7 +78,7 @@ fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq)
74 } 78 }
75 rc = raw3270_start(view, rq); 79 rc = raw3270_start(view, rq);
76 if (rc == 0) { 80 if (rc == 0) {
77 /* Started sucessfully. Now wait for completion. */ 81 /* Started successfully. Now wait for completion. */
78 wait_event(fp->wait, raw3270_request_final(rq)); 82 wait_event(fp->wait, raw3270_request_final(rq));
79 } 83 }
80 } while (rc == -EACCES); 84 } while (rc == -EACCES);
@@ -320,6 +324,7 @@ fs3270_write(struct file *filp, const char __user *data, size_t count, loff_t *o
320static long 324static long
321fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 325fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
322{ 326{
327 char __user *argp;
323 struct fs3270 *fp; 328 struct fs3270 *fp;
324 struct raw3270_iocb iocb; 329 struct raw3270_iocb iocb;
325 int rc; 330 int rc;
@@ -327,8 +332,12 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
327 fp = filp->private_data; 332 fp = filp->private_data;
328 if (!fp) 333 if (!fp)
329 return -ENODEV; 334 return -ENODEV;
335 if (is_compat_task())
336 argp = compat_ptr(arg);
337 else
338 argp = (char __user *)arg;
330 rc = 0; 339 rc = 0;
331 lock_kernel(); 340 mutex_lock(&fs3270_mutex);
332 switch (cmd) { 341 switch (cmd) {
333 case TUBICMD: 342 case TUBICMD:
334 fp->read_command = arg; 343 fp->read_command = arg;
@@ -337,10 +346,10 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
337 fp->write_command = arg; 346 fp->write_command = arg;
338 break; 347 break;
339 case TUBGETI: 348 case TUBGETI:
340 rc = put_user(fp->read_command, (char __user *) arg); 349 rc = put_user(fp->read_command, argp);
341 break; 350 break;
342 case TUBGETO: 351 case TUBGETO:
343 rc = put_user(fp->write_command,(char __user *) arg); 352 rc = put_user(fp->write_command, argp);
344 break; 353 break;
345 case TUBGETMOD: 354 case TUBGETMOD:
346 iocb.model = fp->view.model; 355 iocb.model = fp->view.model;
@@ -349,12 +358,11 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
349 iocb.pf_cnt = 24; 358 iocb.pf_cnt = 24;
350 iocb.re_cnt = 20; 359 iocb.re_cnt = 20;
351 iocb.map = 0; 360 iocb.map = 0;
352 if (copy_to_user((char __user *) arg, &iocb, 361 if (copy_to_user(argp, &iocb, sizeof(struct raw3270_iocb)))
353 sizeof(struct raw3270_iocb)))
354 rc = -EFAULT; 362 rc = -EFAULT;
355 break; 363 break;
356 } 364 }
357 unlock_kernel(); 365 mutex_unlock(&fs3270_mutex);
358 return rc; 366 return rc;
359} 367}
360 368
@@ -437,7 +445,7 @@ fs3270_open(struct inode *inode, struct file *filp)
437 minor = tty->index + RAW3270_FIRSTMINOR; 445 minor = tty->index + RAW3270_FIRSTMINOR;
438 tty_kref_put(tty); 446 tty_kref_put(tty);
439 } 447 }
440 lock_kernel(); 448 mutex_lock(&fs3270_mutex);
441 /* Check if some other program is already using fullscreen mode. */ 449 /* Check if some other program is already using fullscreen mode. */
442 fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); 450 fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
443 if (!IS_ERR(fp)) { 451 if (!IS_ERR(fp)) {
@@ -465,7 +473,7 @@ fs3270_open(struct inode *inode, struct file *filp)
465 if (IS_ERR(ib)) { 473 if (IS_ERR(ib)) {
466 raw3270_put_view(&fp->view); 474 raw3270_put_view(&fp->view);
467 raw3270_del_view(&fp->view); 475 raw3270_del_view(&fp->view);
468 rc = PTR_ERR(fp); 476 rc = PTR_ERR(ib);
469 goto out; 477 goto out;
470 } 478 }
471 fp->rdbuf = ib; 479 fp->rdbuf = ib;
@@ -478,7 +486,7 @@ fs3270_open(struct inode *inode, struct file *filp)
478 } 486 }
479 filp->private_data = fp; 487 filp->private_data = fp;
480out: 488out:
481 unlock_kernel(); 489 mutex_unlock(&fs3270_mutex);
482 return rc; 490 return rc;
483} 491}
484 492
@@ -509,8 +517,8 @@ static const struct file_operations fs3270_fops = {
509 .write = fs3270_write, /* write */ 517 .write = fs3270_write, /* write */
510 .unlocked_ioctl = fs3270_ioctl, /* ioctl */ 518 .unlocked_ioctl = fs3270_ioctl, /* ioctl */
511 .compat_ioctl = fs3270_ioctl, /* ioctl */ 519 .compat_ioctl = fs3270_ioctl, /* ioctl */
512 .open = fs3270_open, /* open */ 520 .open = fs3270_open, /* open */
513 .release = fs3270_close, /* release */ 521 .release = fs3270_close, /* release */
514}; 522};
515 523
516/* 524/*
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index cee4d4e42429..cb6bffe7141a 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <linux/slab.h>
12#include <linux/sysrq.h> 13#include <linux/sysrq.h>
13 14
14#include <linux/consolemap.h> 15#include <linux/consolemap.h>
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 66e21dd23154..2ed3f82e5c30 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -12,7 +12,6 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/moduleparam.h> 13#include <linux/moduleparam.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/smp_lock.h>
16#include <linux/errno.h> 15#include <linux/errno.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
@@ -22,6 +21,7 @@
22#include <linux/interrupt.h> 21#include <linux/interrupt.h>
23#include <linux/poll.h> 22#include <linux/poll.h>
24#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/slab.h>
25#include <net/iucv/iucv.h> 25#include <net/iucv/iucv.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/ebcdic.h> 27#include <asm/ebcdic.h>
@@ -283,7 +283,6 @@ static int mon_open(struct inode *inode, struct file *filp)
283 /* 283 /*
284 * only one user allowed 284 * only one user allowed
285 */ 285 */
286 lock_kernel();
287 rc = -EBUSY; 286 rc = -EBUSY;
288 if (test_and_set_bit(MON_IN_USE, &mon_in_use)) 287 if (test_and_set_bit(MON_IN_USE, &mon_in_use))
289 goto out; 288 goto out;
@@ -321,7 +320,6 @@ static int mon_open(struct inode *inode, struct file *filp)
321 } 320 }
322 filp->private_data = monpriv; 321 filp->private_data = monpriv;
323 dev_set_drvdata(monreader_device, monpriv); 322 dev_set_drvdata(monreader_device, monpriv);
324 unlock_kernel();
325 return nonseekable_open(inode, filp); 323 return nonseekable_open(inode, filp);
326 324
327out_path: 325out_path:
@@ -331,7 +329,6 @@ out_priv:
331out_use: 329out_use:
332 clear_bit(MON_IN_USE, &mon_in_use); 330 clear_bit(MON_IN_USE, &mon_in_use);
333out: 331out:
334 unlock_kernel();
335 return rc; 332 return rc;
336} 333}
337 334
@@ -533,7 +530,7 @@ static int monreader_restore(struct device *dev)
533 return monreader_thaw(dev); 530 return monreader_thaw(dev);
534} 531}
535 532
536static struct dev_pm_ops monreader_pm_ops = { 533static const struct dev_pm_ops monreader_pm_ops = {
537 .freeze = monreader_freeze, 534 .freeze = monreader_freeze,
538 .thaw = monreader_thaw, 535 .thaw = monreader_thaw,
539 .restore = monreader_restore, 536 .restore = monreader_restore,
@@ -607,6 +604,10 @@ static int __init mon_init(void)
607 } 604 }
608 dcss_mkname(mon_dcss_name, &user_data_connect[8]); 605 dcss_mkname(mon_dcss_name, &user_data_connect[8]);
609 606
607 /*
608 * misc_register() has to be the last action in module_init(), because
609 * file operations will be available right after this.
610 */
610 rc = misc_register(&mon_dev); 611 rc = misc_register(&mon_dev);
611 if (rc < 0 ) 612 if (rc < 0 )
612 goto out; 613 goto out;
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 66fb8eba93f4..98a49dfda1de 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -13,7 +13,6 @@
13#include <linux/moduleparam.h> 13#include <linux/moduleparam.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/smp_lock.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <linux/miscdevice.h> 18#include <linux/miscdevice.h>
@@ -21,6 +20,7 @@
21#include <linux/poll.h> 20#include <linux/poll.h>
22#include <linux/mutex.h> 21#include <linux/mutex.h>
23#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/slab.h>
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25#include <asm/ebcdic.h> 25#include <asm/ebcdic.h>
26#include <asm/io.h> 26#include <asm/io.h>
@@ -185,13 +185,11 @@ static int monwrite_open(struct inode *inode, struct file *filp)
185 monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); 185 monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
186 if (!monpriv) 186 if (!monpriv)
187 return -ENOMEM; 187 return -ENOMEM;
188 lock_kernel();
189 INIT_LIST_HEAD(&monpriv->list); 188 INIT_LIST_HEAD(&monpriv->list);
190 monpriv->hdr_to_read = sizeof(monpriv->hdr); 189 monpriv->hdr_to_read = sizeof(monpriv->hdr);
191 mutex_init(&monpriv->thread_mutex); 190 mutex_init(&monpriv->thread_mutex);
192 filp->private_data = monpriv; 191 filp->private_data = monpriv;
193 list_add_tail(&monpriv->priv_list, &mon_priv_list); 192 list_add_tail(&monpriv->priv_list, &mon_priv_list);
194 unlock_kernel();
195 return nonseekable_open(inode, filp); 193 return nonseekable_open(inode, filp);
196} 194}
197 195
@@ -326,7 +324,7 @@ static int monwriter_thaw(struct device *dev)
326 return monwriter_restore(dev); 324 return monwriter_restore(dev);
327} 325}
328 326
329static struct dev_pm_ops monwriter_pm_ops = { 327static const struct dev_pm_ops monwriter_pm_ops = {
330 .freeze = monwriter_freeze, 328 .freeze = monwriter_freeze,
331 .thaw = monwriter_thaw, 329 .thaw = monwriter_thaw,
332 .restore = monwriter_restore, 330 .restore = monwriter_restore,
@@ -364,6 +362,10 @@ static int __init mon_init(void)
364 goto out_driver; 362 goto out_driver;
365 } 363 }
366 364
365 /*
366 * misc_register() has to be the last action in module_init(), because
367 * file operations will be available right after this.
368 */
367 rc = misc_register(&mon_dev); 369 rc = misc_register(&mon_dev);
368 if (rc) 370 if (rc)
369 goto out_device; 371 goto out_device;
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 62ddf5202b79..2a4c566456e7 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -373,7 +373,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
373 rq->rc = ccw_device_start(rp->cdev, &rq->ccw, 373 rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
374 (unsigned long) rq, 0, 0); 374 (unsigned long) rq, 0, 0);
375 if (rq->rc == 0) 375 if (rq->rc == 0)
376 return; /* Sucessfully restarted. */ 376 return; /* Successfully restarted. */
377 break; 377 break;
378 case RAW3270_IO_STOP: 378 case RAW3270_IO_STOP:
379 if (!rq) 379 if (!rq)
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index a983f5086788..f6d72e1f2a38 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -196,7 +196,7 @@ __sclp_start_request(struct sclp_req *req)
196 req->start_count++; 196 req->start_count++;
197 197
198 if (rc == 0) { 198 if (rc == 0) {
199 /* Sucessfully started request */ 199 /* Successfully started request */
200 req->status = SCLP_REQ_RUNNING; 200 req->status = SCLP_REQ_RUNNING;
201 sclp_running_state = sclp_running_state_running; 201 sclp_running_state = sclp_running_state_running;
202 __sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ, 202 __sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ,
@@ -1019,7 +1019,7 @@ static int sclp_restore(struct device *dev)
1019 return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE); 1019 return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE);
1020} 1020}
1021 1021
1022static struct dev_pm_ops sclp_pm_ops = { 1022static const struct dev_pm_ops sclp_pm_ops = {
1023 .freeze = sclp_freeze, 1023 .freeze = sclp_freeze,
1024 .thaw = sclp_thaw, 1024 .thaw = sclp_thaw,
1025 .restore = sclp_restore, 1025 .restore = sclp_restore,
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c
index b44462a6c6d3..7ad30e72f868 100644
--- a/drivers/s390/char/sclp_async.c
+++ b/drivers/s390/char/sclp_async.c
@@ -11,6 +11,7 @@
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/stat.h> 12#include <linux/stat.h>
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/slab.h>
14#include <linux/ctype.h> 15#include <linux/ctype.h>
15#include <linux/kmod.h> 16#include <linux/kmod.h>
16#include <linux/err.h> 17#include <linux/err.h>
@@ -84,6 +85,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write,
84 rc = copy_from_user(buf, buffer, sizeof(buf)); 85 rc = copy_from_user(buf, buffer, sizeof(buf));
85 if (rc != 0) 86 if (rc != 0)
86 return -EFAULT; 87 return -EFAULT;
88 buf[sizeof(buf) - 1] = '\0';
87 if (strict_strtoul(buf, 0, &val) != 0) 89 if (strict_strtoul(buf, 0, &val) != 0)
88 return -EINVAL; 90 return -EINVAL;
89 if (val != 0 && val != 1) 91 if (val != 0 && val != 1)
@@ -101,18 +103,17 @@ static struct ctl_table callhome_table[] = {
101 .mode = 0644, 103 .mode = 0644,
102 .proc_handler = proc_handler_callhome, 104 .proc_handler = proc_handler_callhome,
103 }, 105 },
104 { .ctl_name = 0 } 106 {}
105}; 107};
106 108
107static struct ctl_table kern_dir_table[] = { 109static struct ctl_table kern_dir_table[] = {
108 { 110 {
109 .ctl_name = CTL_KERN,
110 .procname = "kernel", 111 .procname = "kernel",
111 .maxlen = 0, 112 .maxlen = 0,
112 .mode = 0555, 113 .mode = 0555,
113 .child = callhome_table, 114 .child = callhome_table,
114 }, 115 },
115 { .ctl_name = 0 } 116 {}
116}; 117};
117 118
118/* 119/*
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 5cc11c636d38..4b60ede07f0e 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -84,6 +84,7 @@ static void __init sclp_read_info_early(void)
84 do { 84 do {
85 memset(sccb, 0, sizeof(*sccb)); 85 memset(sccb, 0, sizeof(*sccb));
86 sccb->header.length = sizeof(*sccb); 86 sccb->header.length = sizeof(*sccb);
87 sccb->header.function_code = 0x80;
87 sccb->header.control_mask[2] = 0x80; 88 sccb->header.control_mask[2] = 0x80;
88 rc = sclp_cmd_sync_early(commands[i], sccb); 89 rc = sclp_cmd_sync_early(commands[i], sccb);
89 } while (rc == -EBUSY); 90 } while (rc == -EBUSY);
@@ -307,6 +308,13 @@ struct assign_storage_sccb {
307 u16 rn; 308 u16 rn;
308} __packed; 309} __packed;
309 310
311int arch_get_memory_phys_device(unsigned long start_pfn)
312{
313 if (!rzm)
314 return 0;
315 return PFN_PHYS(start_pfn) >> ilog2(rzm);
316}
317
310static unsigned long long rn2addr(u16 rn) 318static unsigned long long rn2addr(u16 rn)
311{ 319{
312 return (unsigned long long) (rn - 1) * rzm; 320 return (unsigned long long) (rn - 1) * rzm;
@@ -546,7 +554,7 @@ struct read_storage_sccb {
546 u32 entries[0]; 554 u32 entries[0];
547} __packed; 555} __packed;
548 556
549static struct dev_pm_ops sclp_mem_pm_ops = { 557static const struct dev_pm_ops sclp_mem_pm_ops = {
550 .freeze = sclp_mem_freeze, 558 .freeze = sclp_mem_freeze,
551}; 559};
552 560
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index ad698d30cb3b..ecf45c54f8c4 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -14,6 +14,7 @@
14#include <linux/termios.h> 14#include <linux/termios.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/reboot.h> 16#include <linux/reboot.h>
17#include <linux/gfp.h>
17 18
18#include "sclp.h" 19#include "sclp.h"
19#include "sclp_rw.h" 20#include "sclp_rw.h"
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 434ba04b1309..8258d590505f 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -13,10 +13,10 @@
13#include <linux/tty.h> 13#include <linux/tty.h>
14#include <linux/tty_driver.h> 14#include <linux/tty_driver.h>
15#include <linux/tty_flip.h> 15#include <linux/tty_flip.h>
16#include <linux/slab.h>
17#include <linux/err.h> 16#include <linux/err.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/gfp.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21 21
22#include "ctrlchar.h" 22#include "ctrlchar.h"
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index b9d2a007e93b..5d706e6c946f 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -23,6 +23,7 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/reboot.h> 25#include <linux/reboot.h>
26#include <linux/slab.h>
26 27
27#include <asm/uaccess.h> 28#include <asm/uaccess.h>
28#include "sclp.h" 29#include "sclp.h"
@@ -495,6 +496,10 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp)
495 if (tty->driver_data == NULL) 496 if (tty->driver_data == NULL)
496 return -ENOMEM; 497 return -ENOMEM;
497 tty->low_latency = 0; 498 tty->low_latency = 0;
499 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
500 tty->winsize.ws_row = 24;
501 tty->winsize.ws_col = 80;
502 }
498 } 503 }
499 return 0; 504 return 0;
500} 505}
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index a26333774701..7a242f073632 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -212,6 +212,9 @@ struct tape_device {
212 struct tape_class_device * nt; 212 struct tape_class_device * nt;
213 struct tape_class_device * rt; 213 struct tape_class_device * rt;
214 214
215 /* Device mutex to serialize tape commands. */
216 struct mutex mutex;
217
215 /* Device discipline information. */ 218 /* Device discipline information. */
216 struct tape_discipline * discipline; 219 struct tape_discipline * discipline;
217 void * discdata; 220 void * discdata;
@@ -292,9 +295,9 @@ extern int tape_generic_pm_suspend(struct ccw_device *);
292extern int tape_generic_probe(struct ccw_device *); 295extern int tape_generic_probe(struct ccw_device *);
293extern void tape_generic_remove(struct ccw_device *); 296extern void tape_generic_remove(struct ccw_device *);
294 297
295extern struct tape_device *tape_get_device(int devindex); 298extern struct tape_device *tape_find_device(int devindex);
296extern struct tape_device *tape_get_device_reference(struct tape_device *); 299extern struct tape_device *tape_get_device(struct tape_device *);
297extern struct tape_device *tape_put_device(struct tape_device *); 300extern void tape_put_device(struct tape_device *);
298 301
299/* Externals from tape_char.c */ 302/* Externals from tape_char.c */
300extern int tapechar_init(void); 303extern int tapechar_init(void);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 2fe45ff77b75..c17f35b6136a 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -9,11 +9,13 @@
9 */ 9 */
10 10
11#define KMSG_COMPONENT "tape_34xx" 11#define KMSG_COMPONENT "tape_34xx"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
12 13
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/bio.h> 16#include <linux/bio.h>
16#include <linux/workqueue.h> 17#include <linux/workqueue.h>
18#include <linux/slab.h>
17 19
18#define TAPE_DBF_AREA tape_34xx_dbf 20#define TAPE_DBF_AREA tape_34xx_dbf
19 21
@@ -113,16 +115,16 @@ tape_34xx_work_handler(struct work_struct *work)
113{ 115{
114 struct tape_34xx_work *p = 116 struct tape_34xx_work *p =
115 container_of(work, struct tape_34xx_work, work); 117 container_of(work, struct tape_34xx_work, work);
118 struct tape_device *device = p->device;
116 119
117 switch(p->op) { 120 switch(p->op) {
118 case TO_MSEN: 121 case TO_MSEN:
119 tape_34xx_medium_sense(p->device); 122 tape_34xx_medium_sense(device);
120 break; 123 break;
121 default: 124 default:
122 DBF_EVENT(3, "T34XX: internal error: unknown work\n"); 125 DBF_EVENT(3, "T34XX: internal error: unknown work\n");
123 } 126 }
124 127 tape_put_device(device);
125 p->device = tape_put_device(p->device);
126 kfree(p); 128 kfree(p);
127} 129}
128 130
@@ -136,7 +138,7 @@ tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)
136 138
137 INIT_WORK(&p->work, tape_34xx_work_handler); 139 INIT_WORK(&p->work, tape_34xx_work_handler);
138 140
139 p->device = tape_get_device_reference(device); 141 p->device = tape_get_device(device);
140 p->op = op; 142 p->op = op;
141 143
142 schedule_work(&p->work); 144 schedule_work(&p->work);
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index e4cc3aae9162..fc993acf99b6 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -9,8 +9,10 @@
9 */ 9 */
10 10
11#define KMSG_COMPONENT "tape_3590" 11#define KMSG_COMPONENT "tape_3590"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
12 13
13#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/slab.h>
14#include <linux/init.h> 16#include <linux/init.h>
15#include <linux/bio.h> 17#include <linux/bio.h>
16#include <asm/ebcdic.h> 18#include <asm/ebcdic.h>
@@ -136,7 +138,7 @@ static void int_to_ext_kekl(struct tape3592_kekl *in,
136 out->type_on_tape = TAPE390_KEKL_TYPE_LABEL; 138 out->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
137 memcpy(out->label, in->label, sizeof(in->label)); 139 memcpy(out->label, in->label, sizeof(in->label));
138 EBCASC(out->label, sizeof(in->label)); 140 EBCASC(out->label, sizeof(in->label));
139 strstrip(out->label); 141 strim(out->label);
140} 142}
141 143
142static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in, 144static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in,
@@ -608,7 +610,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
608 610
609 INIT_WORK(&p->work, tape_3590_work_handler); 611 INIT_WORK(&p->work, tape_3590_work_handler);
610 612
611 p->device = tape_get_device_reference(device); 613 p->device = tape_get_device(device);
612 p->op = op; 614 p->op = op;
613 615
614 schedule_work(&p->work); 616 schedule_work(&p->work);
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 0c0705b91c28..097da8ce6be6 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#define KMSG_COMPONENT "tape" 13#define KMSG_COMPONENT "tape"
14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14 15
15#include <linux/fs.h> 16#include <linux/fs.h>
16#include <linux/module.h> 17#include <linux/module.h>
@@ -45,8 +46,6 @@
45 */ 46 */
46static int tapeblock_open(struct block_device *, fmode_t); 47static int tapeblock_open(struct block_device *, fmode_t);
47static int tapeblock_release(struct gendisk *, fmode_t); 48static int tapeblock_release(struct gendisk *, fmode_t);
48static int tapeblock_ioctl(struct block_device *, fmode_t, unsigned int,
49 unsigned long);
50static int tapeblock_medium_changed(struct gendisk *); 49static int tapeblock_medium_changed(struct gendisk *);
51static int tapeblock_revalidate_disk(struct gendisk *); 50static int tapeblock_revalidate_disk(struct gendisk *);
52 51
@@ -54,7 +53,6 @@ static const struct block_device_operations tapeblock_fops = {
54 .owner = THIS_MODULE, 53 .owner = THIS_MODULE,
55 .open = tapeblock_open, 54 .open = tapeblock_open,
56 .release = tapeblock_release, 55 .release = tapeblock_release,
57 .locked_ioctl = tapeblock_ioctl,
58 .media_changed = tapeblock_medium_changed, 56 .media_changed = tapeblock_medium_changed,
59 .revalidate_disk = tapeblock_revalidate_disk, 57 .revalidate_disk = tapeblock_revalidate_disk,
60}; 58};
@@ -224,9 +222,8 @@ tapeblock_setup_device(struct tape_device * device)
224 goto cleanup_queue; 222 goto cleanup_queue;
225 223
226 blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE); 224 blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE);
227 blk_queue_max_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC); 225 blk_queue_max_hw_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC);
228 blk_queue_max_phys_segments(blkdat->request_queue, -1L); 226 blk_queue_max_segments(blkdat->request_queue, -1L);
229 blk_queue_max_hw_segments(blkdat->request_queue, -1L);
230 blk_queue_max_segment_size(blkdat->request_queue, -1L); 227 blk_queue_max_segment_size(blkdat->request_queue, -1L);
231 blk_queue_segment_boundary(blkdat->request_queue, -1L); 228 blk_queue_segment_boundary(blkdat->request_queue, -1L);
232 229
@@ -239,7 +236,7 @@ tapeblock_setup_device(struct tape_device * device)
239 disk->major = tapeblock_major; 236 disk->major = tapeblock_major;
240 disk->first_minor = device->first_minor; 237 disk->first_minor = device->first_minor;
241 disk->fops = &tapeblock_fops; 238 disk->fops = &tapeblock_fops;
242 disk->private_data = tape_get_device_reference(device); 239 disk->private_data = tape_get_device(device);
243 disk->queue = blkdat->request_queue; 240 disk->queue = blkdat->request_queue;
244 set_capacity(disk, 0); 241 set_capacity(disk, 0);
245 sprintf(disk->disk_name, "btibm%d", 242 sprintf(disk->disk_name, "btibm%d",
@@ -247,11 +244,11 @@ tapeblock_setup_device(struct tape_device * device)
247 244
248 blkdat->disk = disk; 245 blkdat->disk = disk;
249 blkdat->medium_changed = 1; 246 blkdat->medium_changed = 1;
250 blkdat->request_queue->queuedata = tape_get_device_reference(device); 247 blkdat->request_queue->queuedata = tape_get_device(device);
251 248
252 add_disk(disk); 249 add_disk(disk);
253 250
254 tape_get_device_reference(device); 251 tape_get_device(device);
255 INIT_WORK(&blkdat->requeue_task, tapeblock_requeue); 252 INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
256 253
257 return 0; 254 return 0;
@@ -274,13 +271,14 @@ tapeblock_cleanup_device(struct tape_device *device)
274 } 271 }
275 272
276 del_gendisk(device->blk_data.disk); 273 del_gendisk(device->blk_data.disk);
277 device->blk_data.disk->private_data = 274 device->blk_data.disk->private_data = NULL;
278 tape_put_device(device->blk_data.disk->private_data); 275 tape_put_device(device);
279 put_disk(device->blk_data.disk); 276 put_disk(device->blk_data.disk);
280 277
281 device->blk_data.disk = NULL; 278 device->blk_data.disk = NULL;
282cleanup_queue: 279cleanup_queue:
283 device->blk_data.request_queue->queuedata = tape_put_device(device); 280 device->blk_data.request_queue->queuedata = NULL;
281 tape_put_device(device);
284 282
285 blk_cleanup_queue(device->blk_data.request_queue); 283 blk_cleanup_queue(device->blk_data.request_queue);
286 device->blk_data.request_queue = NULL; 284 device->blk_data.request_queue = NULL;
@@ -363,7 +361,7 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)
363 struct tape_device * device; 361 struct tape_device * device;
364 int rc; 362 int rc;
365 363
366 device = tape_get_device_reference(disk->private_data); 364 device = tape_get_device(disk->private_data);
367 365
368 if (device->required_tapemarks) { 366 if (device->required_tapemarks) {
369 DBF_EVENT(2, "TBLOCK: missing tapemarks\n"); 367 DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
@@ -414,42 +412,6 @@ tapeblock_release(struct gendisk *disk, fmode_t mode)
414} 412}
415 413
416/* 414/*
417 * Support of some generic block device IOCTLs.
418 */
419static int
420tapeblock_ioctl(
421 struct block_device * bdev,
422 fmode_t mode,
423 unsigned int command,
424 unsigned long arg
425) {
426 int rc;
427 int minor;
428 struct gendisk *disk = bdev->bd_disk;
429 struct tape_device *device;
430
431 rc = 0;
432 BUG_ON(!disk);
433 device = disk->private_data;
434 BUG_ON(!device);
435 minor = MINOR(bdev->bd_dev);
436
437 DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command);
438 DBF_LH(6, "device = %d:%d\n", tapeblock_major, minor);
439
440 switch (command) {
441 /* Refuse some IOCTL calls without complaining (mount). */
442 case 0x5310: /* CDROMMULTISESSION */
443 rc = -EINVAL;
444 break;
445 default:
446 rc = -EINVAL;
447 }
448
449 return rc;
450}
451
452/*
453 * Initialize block device frontend. 415 * Initialize block device frontend.
454 */ 416 */
455int 417int
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 31566c55adfe..539045acaad4 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -10,11 +10,15 @@
10 * Martin Schwidefsky <schwidefsky@de.ibm.com> 10 * Martin Schwidefsky <schwidefsky@de.ibm.com>
11 */ 11 */
12 12
13#define KMSG_COMPONENT "tape"
14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
15
13#include <linux/module.h> 16#include <linux/module.h>
14#include <linux/types.h> 17#include <linux/types.h>
15#include <linux/proc_fs.h> 18#include <linux/proc_fs.h>
16#include <linux/mtio.h> 19#include <linux/mtio.h>
17#include <linux/smp_lock.h> 20#include <linux/smp_lock.h>
21#include <linux/compat.h>
18 22
19#include <asm/uaccess.h> 23#include <asm/uaccess.h>
20 24
@@ -33,18 +37,20 @@ static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *);
33static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); 37static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *);
34static int tapechar_open(struct inode *,struct file *); 38static int tapechar_open(struct inode *,struct file *);
35static int tapechar_release(struct inode *,struct file *); 39static int tapechar_release(struct inode *,struct file *);
36static int tapechar_ioctl(struct inode *, struct file *, unsigned int, 40static long tapechar_ioctl(struct file *, unsigned int, unsigned long);
37 unsigned long); 41#ifdef CONFIG_COMPAT
38static long tapechar_compat_ioctl(struct file *, unsigned int, 42static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long);
39 unsigned long); 43#endif
40 44
41static const struct file_operations tape_fops = 45static const struct file_operations tape_fops =
42{ 46{
43 .owner = THIS_MODULE, 47 .owner = THIS_MODULE,
44 .read = tapechar_read, 48 .read = tapechar_read,
45 .write = tapechar_write, 49 .write = tapechar_write,
46 .ioctl = tapechar_ioctl, 50 .unlocked_ioctl = tapechar_ioctl,
51#ifdef CONFIG_COMPAT
47 .compat_ioctl = tapechar_compat_ioctl, 52 .compat_ioctl = tapechar_compat_ioctl,
53#endif
48 .open = tapechar_open, 54 .open = tapechar_open,
49 .release = tapechar_release, 55 .release = tapechar_release,
50}; 56};
@@ -170,7 +176,6 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
170 if (rc == 0) { 176 if (rc == 0) {
171 rc = block_size - request->rescnt; 177 rc = block_size - request->rescnt;
172 DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); 178 DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc);
173 filp->f_pos += rc;
174 /* Copy data from idal buffer to user space. */ 179 /* Copy data from idal buffer to user space. */
175 if (idal_buffer_to_user(device->char_data.idal_buf, 180 if (idal_buffer_to_user(device->char_data.idal_buf,
176 data, rc) != 0) 181 data, rc) != 0)
@@ -238,7 +243,6 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t
238 break; 243 break;
239 DBF_EVENT(6, "TCHAR:wbytes: %lx\n", 244 DBF_EVENT(6, "TCHAR:wbytes: %lx\n",
240 block_size - request->rescnt); 245 block_size - request->rescnt);
241 filp->f_pos += block_size - request->rescnt;
242 written += block_size - request->rescnt; 246 written += block_size - request->rescnt;
243 if (request->rescnt != 0) 247 if (request->rescnt != 0)
244 break; 248 break;
@@ -286,26 +290,20 @@ tapechar_open (struct inode *inode, struct file *filp)
286 if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) 290 if (imajor(filp->f_path.dentry->d_inode) != tapechar_major)
287 return -ENODEV; 291 return -ENODEV;
288 292
289 lock_kernel();
290 minor = iminor(filp->f_path.dentry->d_inode); 293 minor = iminor(filp->f_path.dentry->d_inode);
291 device = tape_get_device(minor / TAPE_MINORS_PER_DEV); 294 device = tape_find_device(minor / TAPE_MINORS_PER_DEV);
292 if (IS_ERR(device)) { 295 if (IS_ERR(device)) {
293 DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n"); 296 DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n");
294 rc = PTR_ERR(device); 297 return PTR_ERR(device);
295 goto out;
296 } 298 }
297 299
298
299 rc = tape_open(device); 300 rc = tape_open(device);
300 if (rc == 0) { 301 if (rc == 0) {
301 filp->private_data = device; 302 filp->private_data = device;
302 rc = nonseekable_open(inode, filp); 303 nonseekable_open(inode, filp);
303 } 304 } else
304 else
305 tape_put_device(device); 305 tape_put_device(device);
306 306
307out:
308 unlock_kernel();
309 return rc; 307 return rc;
310} 308}
311 309
@@ -342,7 +340,8 @@ tapechar_release(struct inode *inode, struct file *filp)
342 device->char_data.idal_buf = NULL; 340 device->char_data.idal_buf = NULL;
343 } 341 }
344 tape_release(device); 342 tape_release(device);
345 filp->private_data = tape_put_device(device); 343 filp->private_data = NULL;
344 tape_put_device(device);
346 345
347 return 0; 346 return 0;
348} 347}
@@ -351,16 +350,11 @@ tapechar_release(struct inode *inode, struct file *filp)
351 * Tape device io controls. 350 * Tape device io controls.
352 */ 351 */
353static int 352static int
354tapechar_ioctl(struct inode *inp, struct file *filp, 353__tapechar_ioctl(struct tape_device *device,
355 unsigned int no, unsigned long data) 354 unsigned int no, unsigned long data)
356{ 355{
357 struct tape_device *device;
358 int rc; 356 int rc;
359 357
360 DBF_EVENT(6, "TCHAR:ioct\n");
361
362 device = (struct tape_device *) filp->private_data;
363
364 if (no == MTIOCTOP) { 358 if (no == MTIOCTOP) {
365 struct mtop op; 359 struct mtop op;
366 360
@@ -453,21 +447,44 @@ tapechar_ioctl(struct inode *inp, struct file *filp,
453} 447}
454 448
455static long 449static long
450tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data)
451{
452 struct tape_device *device;
453 long rc;
454
455 DBF_EVENT(6, "TCHAR:ioct\n");
456
457 device = (struct tape_device *) filp->private_data;
458 mutex_lock(&device->mutex);
459 rc = __tapechar_ioctl(device, no, data);
460 mutex_unlock(&device->mutex);
461 return rc;
462}
463
464#ifdef CONFIG_COMPAT
465static long
456tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) 466tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data)
457{ 467{
458 struct tape_device *device = filp->private_data; 468 struct tape_device *device = filp->private_data;
459 int rval = -ENOIOCTLCMD; 469 int rval = -ENOIOCTLCMD;
470 unsigned long argp;
460 471
472 /* The 'arg' argument of any ioctl function may only be used for
473 * pointers because of the compat pointer conversion.
474 * Consider this when adding new ioctls.
475 */
476 argp = (unsigned long) compat_ptr(data);
461 if (device->discipline->ioctl_fn) { 477 if (device->discipline->ioctl_fn) {
462 lock_kernel(); 478 mutex_lock(&device->mutex);
463 rval = device->discipline->ioctl_fn(device, no, data); 479 rval = device->discipline->ioctl_fn(device, no, argp);
464 unlock_kernel(); 480 mutex_unlock(&device->mutex);
465 if (rval == -EINVAL) 481 if (rval == -EINVAL)
466 rval = -ENOIOCTLCMD; 482 rval = -ENOIOCTLCMD;
467 } 483 }
468 484
469 return rval; 485 return rval;
470} 486}
487#endif /* CONFIG_COMPAT */
471 488
472/* 489/*
473 * Initialize character device frontend. 490 * Initialize character device frontend.
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index ddc914ccea8f..55343df61edd 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -7,6 +7,12 @@
7 * Author: Stefan Bader <shbader@de.ibm.com> 7 * Author: Stefan Bader <shbader@de.ibm.com>
8 * Based on simple class device code by Greg K-H 8 * Based on simple class device code by Greg K-H
9 */ 9 */
10
11#define KMSG_COMPONENT "tape"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13
14#include <linux/slab.h>
15
10#include "tape_class.h" 16#include "tape_class.h"
11 17
12MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>"); 18MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 5cd31e071647..29c2d73d719d 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -12,12 +12,15 @@
12 */ 12 */
13 13
14#define KMSG_COMPONENT "tape" 14#define KMSG_COMPONENT "tape"
15#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
16
15#include <linux/module.h> 17#include <linux/module.h>
16#include <linux/init.h> // for kernel parameters 18#include <linux/init.h> // for kernel parameters
17#include <linux/kmod.h> // for requesting modules 19#include <linux/kmod.h> // for requesting modules
18#include <linux/spinlock.h> // for locks 20#include <linux/spinlock.h> // for locks
19#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
20#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/slab.h>
21 24
22#include <asm/types.h> // for variable types 25#include <asm/types.h> // for variable types
23 26
@@ -492,6 +495,7 @@ tape_alloc_device(void)
492 kfree(device); 495 kfree(device);
493 return ERR_PTR(-ENOMEM); 496 return ERR_PTR(-ENOMEM);
494 } 497 }
498 mutex_init(&device->mutex);
495 INIT_LIST_HEAD(&device->req_queue); 499 INIT_LIST_HEAD(&device->req_queue);
496 INIT_LIST_HEAD(&device->node); 500 INIT_LIST_HEAD(&device->node);
497 init_waitqueue_head(&device->state_change_wq); 501 init_waitqueue_head(&device->state_change_wq);
@@ -511,11 +515,12 @@ tape_alloc_device(void)
511 * increment the reference count. 515 * increment the reference count.
512 */ 516 */
513struct tape_device * 517struct tape_device *
514tape_get_device_reference(struct tape_device *device) 518tape_get_device(struct tape_device *device)
515{ 519{
516 DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device, 520 int count;
517 atomic_inc_return(&device->ref_count));
518 521
522 count = atomic_inc_return(&device->ref_count);
523 DBF_EVENT(4, "tape_get_device(%p) = %i\n", device, count);
519 return device; 524 return device;
520} 525}
521 526
@@ -525,32 +530,25 @@ tape_get_device_reference(struct tape_device *device)
525 * The function returns a NULL pointer to be used by the caller 530 * The function returns a NULL pointer to be used by the caller
526 * for clearing reference pointers. 531 * for clearing reference pointers.
527 */ 532 */
528struct tape_device * 533void
529tape_put_device(struct tape_device *device) 534tape_put_device(struct tape_device *device)
530{ 535{
531 int remain; 536 int count;
532 537
533 remain = atomic_dec_return(&device->ref_count); 538 count = atomic_dec_return(&device->ref_count);
534 if (remain > 0) { 539 DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, count);
535 DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain); 540 BUG_ON(count < 0);
536 } else { 541 if (count == 0) {
537 if (remain < 0) { 542 kfree(device->modeset_byte);
538 DBF_EVENT(4, "put device without reference\n"); 543 kfree(device);
539 } else {
540 DBF_EVENT(4, "tape_free_device(%p)\n", device);
541 kfree(device->modeset_byte);
542 kfree(device);
543 }
544 } 544 }
545
546 return NULL;
547} 545}
548 546
549/* 547/*
550 * Find tape device by a device index. 548 * Find tape device by a device index.
551 */ 549 */
552struct tape_device * 550struct tape_device *
553tape_get_device(int devindex) 551tape_find_device(int devindex)
554{ 552{
555 struct tape_device *device, *tmp; 553 struct tape_device *device, *tmp;
556 554
@@ -558,7 +556,7 @@ tape_get_device(int devindex)
558 read_lock(&tape_device_lock); 556 read_lock(&tape_device_lock);
559 list_for_each_entry(tmp, &tape_device_list, node) { 557 list_for_each_entry(tmp, &tape_device_list, node) {
560 if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) { 558 if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) {
561 device = tape_get_device_reference(tmp); 559 device = tape_get_device(tmp);
562 break; 560 break;
563 } 561 }
564 } 562 }
@@ -579,7 +577,8 @@ tape_generic_probe(struct ccw_device *cdev)
579 device = tape_alloc_device(); 577 device = tape_alloc_device();
580 if (IS_ERR(device)) 578 if (IS_ERR(device))
581 return -ENODEV; 579 return -ENODEV;
582 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); 580 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP |
581 CCWDEV_DO_MULTIPATH);
583 ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); 582 ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
584 if (ret) { 583 if (ret) {
585 tape_put_device(device); 584 tape_put_device(device);
@@ -606,7 +605,8 @@ __tape_discard_requests(struct tape_device *device)
606 list_del(&request->list); 605 list_del(&request->list);
607 606
608 /* Decrease ref_count for removed request. */ 607 /* Decrease ref_count for removed request. */
609 request->device = tape_put_device(device); 608 request->device = NULL;
609 tape_put_device(device);
610 request->rc = -EIO; 610 request->rc = -EIO;
611 if (request->callback != NULL) 611 if (request->callback != NULL)
612 request->callback(request, request->callback_data); 612 request->callback(request, request->callback_data);
@@ -664,9 +664,11 @@ tape_generic_remove(struct ccw_device *cdev)
664 tape_cleanup_device(device); 664 tape_cleanup_device(device);
665 } 665 }
666 666
667 if (!dev_get_drvdata(&cdev->dev)) { 667 device = dev_get_drvdata(&cdev->dev);
668 if (device) {
668 sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group); 669 sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group);
669 dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev))); 670 dev_set_drvdata(&cdev->dev, NULL);
671 tape_put_device(device);
670 } 672 }
671} 673}
672 674
@@ -721,9 +723,8 @@ tape_free_request (struct tape_request * request)
721{ 723{
722 DBF_LH(6, "Free request %p\n", request); 724 DBF_LH(6, "Free request %p\n", request);
723 725
724 if (request->device != NULL) { 726 if (request->device)
725 request->device = tape_put_device(request->device); 727 tape_put_device(request->device);
726 }
727 kfree(request->cpdata); 728 kfree(request->cpdata);
728 kfree(request->cpaddr); 729 kfree(request->cpaddr);
729 kfree(request); 730 kfree(request);
@@ -838,7 +839,8 @@ static void tape_long_busy_timeout(unsigned long data)
838 BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY); 839 BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY);
839 DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id); 840 DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
840 __tape_start_next_request(device); 841 __tape_start_next_request(device);
841 device->lb_timeout.data = (unsigned long) tape_put_device(device); 842 device->lb_timeout.data = 0UL;
843 tape_put_device(device);
842 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 844 spin_unlock_irq(get_ccwdev_lock(device->cdev));
843} 845}
844 846
@@ -918,7 +920,7 @@ __tape_start_request(struct tape_device *device, struct tape_request *request)
918 } 920 }
919 921
920 /* Increase use count of device for the added request. */ 922 /* Increase use count of device for the added request. */
921 request->device = tape_get_device_reference(device); 923 request->device = tape_get_device(device);
922 924
923 if (list_empty(&device->req_queue)) { 925 if (list_empty(&device->req_queue)) {
924 /* No other requests are on the queue. Start this one. */ 926 /* No other requests are on the queue. Start this one. */
@@ -1117,8 +1119,8 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1117 if (req->status == TAPE_REQUEST_LONG_BUSY) { 1119 if (req->status == TAPE_REQUEST_LONG_BUSY) {
1118 DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id); 1120 DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
1119 if (del_timer(&device->lb_timeout)) { 1121 if (del_timer(&device->lb_timeout)) {
1120 device->lb_timeout.data = (unsigned long) 1122 device->lb_timeout.data = 0UL;
1121 tape_put_device(device); 1123 tape_put_device(device);
1122 __tape_start_next_request(device); 1124 __tape_start_next_request(device);
1123 } 1125 }
1124 return; 1126 return;
@@ -1173,7 +1175,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1173 break; 1175 break;
1174 case TAPE_IO_LONG_BUSY: 1176 case TAPE_IO_LONG_BUSY:
1175 device->lb_timeout.data = 1177 device->lb_timeout.data =
1176 (unsigned long)tape_get_device_reference(device); 1178 (unsigned long) tape_get_device(device);
1177 device->lb_timeout.expires = jiffies + 1179 device->lb_timeout.expires = jiffies +
1178 LONG_BUSY_TIMEOUT * HZ; 1180 LONG_BUSY_TIMEOUT * HZ;
1179 DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id); 1181 DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id);
@@ -1326,7 +1328,7 @@ EXPORT_SYMBOL(tape_generic_online);
1326EXPORT_SYMBOL(tape_generic_offline); 1328EXPORT_SYMBOL(tape_generic_offline);
1327EXPORT_SYMBOL(tape_generic_pm_suspend); 1329EXPORT_SYMBOL(tape_generic_pm_suspend);
1328EXPORT_SYMBOL(tape_put_device); 1330EXPORT_SYMBOL(tape_put_device);
1329EXPORT_SYMBOL(tape_get_device_reference); 1331EXPORT_SYMBOL(tape_get_device);
1330EXPORT_SYMBOL(tape_state_verbose); 1332EXPORT_SYMBOL(tape_state_verbose);
1331EXPORT_SYMBOL(tape_op_verbose); 1333EXPORT_SYMBOL(tape_op_verbose);
1332EXPORT_SYMBOL(tape_state_set); 1334EXPORT_SYMBOL(tape_state_set);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index 202f42132939..0ceb37984f77 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -11,6 +11,9 @@
11 * PROCFS Functions 11 * PROCFS Functions
12 */ 12 */
13 13
14#define KMSG_COMPONENT "tape"
15#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
16
14#include <linux/module.h> 17#include <linux/module.h>
15#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
16#include <linux/seq_file.h> 19#include <linux/seq_file.h>
@@ -45,7 +48,7 @@ static int tape_proc_show(struct seq_file *m, void *v)
45 seq_printf(m, "TapeNo\tBusID CuType/Model\t" 48 seq_printf(m, "TapeNo\tBusID CuType/Model\t"
46 "DevType/Model\tBlkSize\tState\tOp\tMedState\n"); 49 "DevType/Model\tBlkSize\tState\tOp\tMedState\n");
47 } 50 }
48 device = tape_get_device(n); 51 device = tape_find_device(n);
49 if (IS_ERR(device)) 52 if (IS_ERR(device))
50 return 0; 53 return 0;
51 spin_lock_irq(get_ccwdev_lock(device->cdev)); 54 spin_lock_irq(get_ccwdev_lock(device->cdev));
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index 750354ad16e5..03f07e5dd6e9 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -11,6 +11,9 @@
11 * Stefan Bader <shbader@de.ibm.com> 11 * Stefan Bader <shbader@de.ibm.com>
12 */ 12 */
13 13
14#define KMSG_COMPONENT "tape"
15#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
16
14#include <linux/stddef.h> 17#include <linux/stddef.h>
15#include <linux/kernel.h> 18#include <linux/kernel.h>
16#include <linux/bio.h> 19#include <linux/bio.h>
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 38385677c653..911822db614d 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/bootmem.h> 21#include <linux/bootmem.h>
22#include <linux/compat.h>
22 23
23#include <asm/ccwdev.h> 24#include <asm/ccwdev.h>
24#include <asm/cio.h> 25#include <asm/cio.h>
@@ -1731,6 +1732,22 @@ tty3270_ioctl(struct tty_struct *tty, struct file *file,
1731 return kbd_ioctl(tp->kbd, file, cmd, arg); 1732 return kbd_ioctl(tp->kbd, file, cmd, arg);
1732} 1733}
1733 1734
1735#ifdef CONFIG_COMPAT
1736static long
1737tty3270_compat_ioctl(struct tty_struct *tty, struct file *file,
1738 unsigned int cmd, unsigned long arg)
1739{
1740 struct tty3270 *tp;
1741
1742 tp = tty->driver_data;
1743 if (!tp)
1744 return -ENODEV;
1745 if (tty->flags & (1 << TTY_IO_ERROR))
1746 return -EIO;
1747 return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg));
1748}
1749#endif
1750
1734static const struct tty_operations tty3270_ops = { 1751static const struct tty_operations tty3270_ops = {
1735 .open = tty3270_open, 1752 .open = tty3270_open,
1736 .close = tty3270_close, 1753 .close = tty3270_close,
@@ -1745,6 +1762,9 @@ static const struct tty_operations tty3270_ops = {
1745 .hangup = tty3270_hangup, 1762 .hangup = tty3270_hangup,
1746 .wait_until_sent = tty3270_wait_until_sent, 1763 .wait_until_sent = tty3270_wait_until_sent,
1747 .ioctl = tty3270_ioctl, 1764 .ioctl = tty3270_ioctl,
1765#ifdef CONFIG_COMPAT
1766 .compat_ioctl = tty3270_compat_ioctl,
1767#endif
1748 .set_termios = tty3270_set_termios 1768 .set_termios = tty3270_set_termios
1749}; 1769};
1750 1770
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index a6087cec55b4..5bb59d36a6d4 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -19,6 +19,8 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/miscdevice.h> 20#include <linux/miscdevice.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h>
23#include <asm/compat.h>
22#include <asm/cpcmd.h> 24#include <asm/cpcmd.h>
23#include <asm/debug.h> 25#include <asm/debug.h>
24#include <asm/uaccess.h> 26#include <asm/uaccess.h>
@@ -139,21 +141,26 @@ vmcp_write(struct file *file, const char __user *buff, size_t count,
139static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 141static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
140{ 142{
141 struct vmcp_session *session; 143 struct vmcp_session *session;
144 int __user *argp;
142 int temp; 145 int temp;
143 146
144 session = (struct vmcp_session *)file->private_data; 147 session = (struct vmcp_session *)file->private_data;
148 if (is_compat_task())
149 argp = compat_ptr(arg);
150 else
151 argp = (int __user *)arg;
145 if (mutex_lock_interruptible(&session->mutex)) 152 if (mutex_lock_interruptible(&session->mutex))
146 return -ERESTARTSYS; 153 return -ERESTARTSYS;
147 switch (cmd) { 154 switch (cmd) {
148 case VMCP_GETCODE: 155 case VMCP_GETCODE:
149 temp = session->resp_code; 156 temp = session->resp_code;
150 mutex_unlock(&session->mutex); 157 mutex_unlock(&session->mutex);
151 return put_user(temp, (int __user *)arg); 158 return put_user(temp, argp);
152 case VMCP_SETBUF: 159 case VMCP_SETBUF:
153 free_pages((unsigned long)session->response, 160 free_pages((unsigned long)session->response,
154 get_order(session->bufsize)); 161 get_order(session->bufsize));
155 session->response=NULL; 162 session->response=NULL;
156 temp = get_user(session->bufsize, (int __user *)arg); 163 temp = get_user(session->bufsize, argp);
157 if (get_order(session->bufsize) > 8) { 164 if (get_order(session->bufsize) > 8) {
158 session->bufsize = PAGE_SIZE; 165 session->bufsize = PAGE_SIZE;
159 temp = -EINVAL; 166 temp = -EINVAL;
@@ -163,7 +170,7 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
163 case VMCP_GETSIZE: 170 case VMCP_GETSIZE:
164 temp = session->resp_size; 171 temp = session->resp_size;
165 mutex_unlock(&session->mutex); 172 mutex_unlock(&session->mutex);
166 return put_user(temp, (int __user *)arg); 173 return put_user(temp, argp);
167 default: 174 default:
168 mutex_unlock(&session->mutex); 175 mutex_unlock(&session->mutex);
169 return -ENOIOCTLCMD; 176 return -ENOIOCTLCMD;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index d1a142fa3eb4..e40a1b892866 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/slab.h>
19#include <linux/errno.h> 20#include <linux/errno.h>
20#include <linux/types.h> 21#include <linux/types.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
@@ -312,11 +313,9 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp)
312 return -ENOSYS; 313 return -ENOSYS;
313 314
314 /* Besure this device hasn't already been opened */ 315 /* Besure this device hasn't already been opened */
315 lock_kernel();
316 spin_lock_bh(&logptr->priv_lock); 316 spin_lock_bh(&logptr->priv_lock);
317 if (logptr->dev_in_use) { 317 if (logptr->dev_in_use) {
318 spin_unlock_bh(&logptr->priv_lock); 318 spin_unlock_bh(&logptr->priv_lock);
319 unlock_kernel();
320 return -EBUSY; 319 return -EBUSY;
321 } 320 }
322 logptr->dev_in_use = 1; 321 logptr->dev_in_use = 1;
@@ -360,9 +359,8 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp)
360 || (logptr->iucv_path_severed)); 359 || (logptr->iucv_path_severed));
361 if (logptr->iucv_path_severed) 360 if (logptr->iucv_path_severed)
362 goto out_record; 361 goto out_record;
363 ret = nonseekable_open(inode, filp); 362 nonseekable_open(inode, filp);
364 unlock_kernel(); 363 return 0;
365 return ret;
366 364
367out_record: 365out_record:
368 if (logptr->autorecording) 366 if (logptr->autorecording)
@@ -372,7 +370,6 @@ out_path:
372 logptr->path = NULL; 370 logptr->path = NULL;
373out_dev: 371out_dev:
374 logptr->dev_in_use = 0; 372 logptr->dev_in_use = 0;
375 unlock_kernel();
376 return -EIO; 373 return -EIO;
377} 374}
378 375
@@ -679,7 +676,7 @@ static int vmlogrdr_pm_prepare(struct device *dev)
679} 676}
680 677
681 678
682static struct dev_pm_ops vmlogrdr_pm_ops = { 679static const struct dev_pm_ops vmlogrdr_pm_ops = {
683 .prepare = vmlogrdr_pm_prepare, 680 .prepare = vmlogrdr_pm_prepare,
684}; 681};
685 682
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 77571b68539a..1de672f21037 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -12,6 +12,7 @@
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13 13
14#include <linux/cdev.h> 14#include <linux/cdev.h>
15#include <linux/slab.h>
15#include <linux/smp_lock.h> 16#include <linux/smp_lock.h>
16 17
17#include <asm/uaccess.h> 18#include <asm/uaccess.h>
@@ -695,7 +696,6 @@ static int ur_open(struct inode *inode, struct file *file)
695 696
696 if (accmode == O_RDWR) 697 if (accmode == O_RDWR)
697 return -EACCES; 698 return -EACCES;
698 lock_kernel();
699 /* 699 /*
700 * We treat the minor number as the devno of the ur device 700 * We treat the minor number as the devno of the ur device
701 * to find in the driver tree. 701 * to find in the driver tree.
@@ -749,7 +749,6 @@ static int ur_open(struct inode *inode, struct file *file)
749 goto fail_urfile_free; 749 goto fail_urfile_free;
750 urf->file_reclen = rc; 750 urf->file_reclen = rc;
751 file->private_data = urf; 751 file->private_data = urf;
752 unlock_kernel();
753 return 0; 752 return 0;
754 753
755fail_urfile_free: 754fail_urfile_free:
@@ -761,7 +760,6 @@ fail_unlock:
761fail_put: 760fail_put:
762 urdev_put(urd); 761 urdev_put(urd);
763out: 762out:
764 unlock_kernel();
765 return rc; 763 return rc;
766} 764}
767 765
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index f2bc287b69e4..e13508c98b1a 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -17,9 +17,9 @@
17#include <linux/miscdevice.h> 17#include <linux/miscdevice.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/slab.h>
20#include <linux/suspend.h> 21#include <linux/suspend.h>
21#include <linux/watchdog.h> 22#include <linux/watchdog.h>
22#include <linux/smp_lock.h>
23 23
24#include <asm/ebcdic.h> 24#include <asm/ebcdic.h>
25#include <asm/io.h> 25#include <asm/io.h>
@@ -49,6 +49,8 @@ static unsigned int vmwdt_interval = 60;
49static unsigned long vmwdt_is_open; 49static unsigned long vmwdt_is_open;
50static int vmwdt_expect_close; 50static int vmwdt_expect_close;
51 51
52static DEFINE_MUTEX(vmwdt_mutex);
53
52#define VMWDT_OPEN 0 /* devnode is open or suspend in progress */ 54#define VMWDT_OPEN 0 /* devnode is open or suspend in progress */
53#define VMWDT_RUNNING 1 /* The watchdog is armed */ 55#define VMWDT_RUNNING 1 /* The watchdog is armed */
54 56
@@ -133,15 +135,11 @@ static int __init vmwdt_probe(void)
133static int vmwdt_open(struct inode *i, struct file *f) 135static int vmwdt_open(struct inode *i, struct file *f)
134{ 136{
135 int ret; 137 int ret;
136 lock_kernel(); 138 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open))
137 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
138 unlock_kernel();
139 return -EBUSY; 139 return -EBUSY;
140 }
141 ret = vmwdt_keepalive(); 140 ret = vmwdt_keepalive();
142 if (ret) 141 if (ret)
143 clear_bit(VMWDT_OPEN, &vmwdt_is_open); 142 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
144 unlock_kernel();
145 return ret ? ret : nonseekable_open(i, f); 143 return ret ? ret : nonseekable_open(i, f);
146} 144}
147 145
@@ -160,8 +158,7 @@ static struct watchdog_info vmwdt_info = {
160 .identity = "z/VM Watchdog Timer", 158 .identity = "z/VM Watchdog Timer",
161}; 159};
162 160
163static int vmwdt_ioctl(struct inode *i, struct file *f, 161static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg)
164 unsigned int cmd, unsigned long arg)
165{ 162{
166 switch (cmd) { 163 switch (cmd) {
167 case WDIOC_GETSUPPORT: 164 case WDIOC_GETSUPPORT:
@@ -205,10 +202,19 @@ static int vmwdt_ioctl(struct inode *i, struct file *f,
205 case WDIOC_KEEPALIVE: 202 case WDIOC_KEEPALIVE:
206 return vmwdt_keepalive(); 203 return vmwdt_keepalive();
207 } 204 }
208
209 return -EINVAL; 205 return -EINVAL;
210} 206}
211 207
208static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
209{
210 int rc;
211
212 mutex_lock(&vmwdt_mutex);
213 rc = __vmwdt_ioctl(cmd, arg);
214 mutex_unlock(&vmwdt_mutex);
215 return (long) rc;
216}
217
212static ssize_t vmwdt_write(struct file *f, const char __user *buf, 218static ssize_t vmwdt_write(struct file *f, const char __user *buf,
213 size_t count, loff_t *ppos) 219 size_t count, loff_t *ppos)
214{ 220{
@@ -288,7 +294,7 @@ static struct notifier_block vmwdt_power_notifier = {
288static const struct file_operations vmwdt_fops = { 294static const struct file_operations vmwdt_fops = {
289 .open = &vmwdt_open, 295 .open = &vmwdt_open,
290 .release = &vmwdt_close, 296 .release = &vmwdt_close,
291 .ioctl = &vmwdt_ioctl, 297 .unlocked_ioctl = &vmwdt_ioctl,
292 .write = &vmwdt_write, 298 .write = &vmwdt_write,
293 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
294}; 300};
@@ -309,6 +315,10 @@ static int __init vmwdt_init(void)
309 ret = register_pm_notifier(&vmwdt_power_notifier); 315 ret = register_pm_notifier(&vmwdt_power_notifier);
310 if (ret) 316 if (ret)
311 return ret; 317 return ret;
318 /*
319 * misc_register() has to be the last action in module_init(), because
320 * file operations will be available right after this.
321 */
312 ret = misc_register(&vmwdt_dev); 322 ret = misc_register(&vmwdt_dev);
313 if (ret) { 323 if (ret) {
314 unregister_pm_notifier(&vmwdt_power_notifier); 324 unregister_pm_notifier(&vmwdt_power_notifier);
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 82daa3c1dc9c..7217966f7d31 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -13,8 +13,10 @@
13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h>
16#include <linux/miscdevice.h> 17#include <linux/miscdevice.h>
17#include <linux/debugfs.h> 18#include <linux/debugfs.h>
19#include <asm/asm-offsets.h>
18#include <asm/ipl.h> 20#include <asm/ipl.h>
19#include <asm/sclp.h> 21#include <asm/sclp.h>
20#include <asm/setup.h> 22#include <asm/setup.h>
@@ -40,12 +42,12 @@ enum arch_id {
40/* dump system info */ 42/* dump system info */
41 43
42struct sys_info { 44struct sys_info {
43 enum arch_id arch; 45 enum arch_id arch;
44 unsigned long sa_base; 46 unsigned long sa_base;
45 u32 sa_size; 47 u32 sa_size;
46 int cpu_map[NR_CPUS]; 48 int cpu_map[NR_CPUS];
47 unsigned long mem_size; 49 unsigned long mem_size;
48 union save_area lc_mask; 50 struct save_area lc_mask;
49}; 51};
50 52
51struct ipib_info { 53struct ipib_info {
@@ -140,33 +142,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
140 return memcpy_hsa(dest, src, count, TO_KERNEL); 142 return memcpy_hsa(dest, src, count, TO_KERNEL);
141} 143}
142 144
143static int memcpy_real(void *dest, unsigned long src, size_t count)
144{
145 unsigned long flags;
146 int rc = -EFAULT;
147 register unsigned long _dest asm("2") = (unsigned long) dest;
148 register unsigned long _len1 asm("3") = (unsigned long) count;
149 register unsigned long _src asm("4") = src;
150 register unsigned long _len2 asm("5") = (unsigned long) count;
151
152 if (count == 0)
153 return 0;
154 flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */
155 asm volatile (
156 "0: mvcle %1,%2,0x0\n"
157 "1: jo 0b\n"
158 " lhi %0,0x0\n"
159 "2:\n"
160 EX_TABLE(1b,2b)
161 : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
162 "+d" (_len2), "=m" (*((long*)dest))
163 : "m" (*((long*)src))
164 : "cc", "memory");
165 __raw_local_irq_ssm(flags);
166
167 return rc;
168}
169
170static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) 145static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
171{ 146{
172 static char buf[4096]; 147 static char buf[4096];
@@ -174,7 +149,7 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
174 149
175 while (offs < count) { 150 while (offs < count) {
176 size = min(sizeof(buf), count - offs); 151 size = min(sizeof(buf), count - offs);
177 if (memcpy_real(buf, src + offs, size)) 152 if (memcpy_real(buf, (void *) src + offs, size))
178 return -EFAULT; 153 return -EFAULT;
179 if (copy_to_user(dest + offs, buf, size)) 154 if (copy_to_user(dest + offs, buf, size))
180 return -EFAULT; 155 return -EFAULT;
@@ -183,52 +158,9 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
183 return 0; 158 return 0;
184} 159}
185 160
186#ifdef __s390x__
187/*
188 * Convert s390x (64 bit) cpu info to s390 (32 bit) cpu info
189 */
190static void __init s390x_to_s390_regs(union save_area *out, union save_area *in,
191 int cpu)
192{
193 int i;
194
195 for (i = 0; i < 16; i++) {
196 out->s390.gp_regs[i] = in->s390x.gp_regs[i] & 0x00000000ffffffff;
197 out->s390.acc_regs[i] = in->s390x.acc_regs[i];
198 out->s390.ctrl_regs[i] =
199 in->s390x.ctrl_regs[i] & 0x00000000ffffffff;
200 }
201 /* locore for 31 bit has only space for fpregs 0,2,4,6 */
202 out->s390.fp_regs[0] = in->s390x.fp_regs[0];
203 out->s390.fp_regs[1] = in->s390x.fp_regs[2];
204 out->s390.fp_regs[2] = in->s390x.fp_regs[4];
205 out->s390.fp_regs[3] = in->s390x.fp_regs[6];
206 memcpy(&(out->s390.psw[0]), &(in->s390x.psw[0]), 4);
207 out->s390.psw[1] |= 0x8; /* set bit 12 */
208 memcpy(&(out->s390.psw[4]),&(in->s390x.psw[12]), 4);
209 out->s390.psw[4] |= 0x80; /* set (31bit) addressing bit */
210 out->s390.pref_reg = in->s390x.pref_reg;
211 out->s390.timer = in->s390x.timer;
212 out->s390.clk_cmp = in->s390x.clk_cmp;
213}
214
215static void __init s390x_to_s390_save_areas(void)
216{
217 int i = 1;
218 static union save_area tmp;
219
220 while (zfcpdump_save_areas[i]) {
221 s390x_to_s390_regs(&tmp, zfcpdump_save_areas[i], i);
222 memcpy(zfcpdump_save_areas[i], &tmp, sizeof(tmp));
223 i++;
224 }
225}
226
227#endif /* __s390x__ */
228
229static int __init init_cpu_info(enum arch_id arch) 161static int __init init_cpu_info(enum arch_id arch)
230{ 162{
231 union save_area *sa; 163 struct save_area *sa;
232 164
233 /* get info for boot cpu from lowcore, stored in the HSA */ 165 /* get info for boot cpu from lowcore, stored in the HSA */
234 166
@@ -241,20 +173,12 @@ static int __init init_cpu_info(enum arch_id arch)
241 return -EIO; 173 return -EIO;
242 } 174 }
243 zfcpdump_save_areas[0] = sa; 175 zfcpdump_save_areas[0] = sa;
244
245#ifdef __s390x__
246 /* convert s390x regs to s390, if we are dumping an s390 Linux */
247
248 if (arch == ARCH_S390)
249 s390x_to_s390_save_areas();
250#endif
251
252 return 0; 176 return 0;
253} 177}
254 178
255static DEFINE_MUTEX(zcore_mutex); 179static DEFINE_MUTEX(zcore_mutex);
256 180
257#define DUMP_VERSION 0x3 181#define DUMP_VERSION 0x5
258#define DUMP_MAGIC 0xa8190173618f23fdULL 182#define DUMP_MAGIC 0xa8190173618f23fdULL
259#define DUMP_ARCH_S390X 2 183#define DUMP_ARCH_S390X 2
260#define DUMP_ARCH_S390 1 184#define DUMP_ARCH_S390 1
@@ -279,7 +203,14 @@ struct zcore_header {
279 u32 volnr; 203 u32 volnr;
280 u32 build_arch; 204 u32 build_arch;
281 u64 rmem_size; 205 u64 rmem_size;
282 char pad2[4016]; 206 u8 mvdump;
207 u16 cpu_cnt;
208 u16 real_cpu_cnt;
209 u8 end_pad1[0x200-0x061];
210 u64 mvdump_sign;
211 u64 mvdump_zipl_time;
212 u8 end_pad2[0x800-0x210];
213 u32 lc_vec[512];
283} __attribute__((packed,__aligned__(16))); 214} __attribute__((packed,__aligned__(16)));
284 215
285static struct zcore_header zcore_header = { 216static struct zcore_header zcore_header = {
@@ -289,7 +220,7 @@ static struct zcore_header zcore_header = {
289 .dump_level = 0, 220 .dump_level = 0,
290 .page_size = PAGE_SIZE, 221 .page_size = PAGE_SIZE,
291 .mem_start = 0, 222 .mem_start = 0,
292#ifdef __s390x__ 223#ifdef CONFIG_64BIT
293 .build_arch = DUMP_ARCH_S390X, 224 .build_arch = DUMP_ARCH_S390X,
294#else 225#else
295 .build_arch = DUMP_ARCH_S390, 226 .build_arch = DUMP_ARCH_S390,
@@ -340,11 +271,7 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
340 unsigned long prefix; 271 unsigned long prefix;
341 unsigned long sa_off, len, buf_off; 272 unsigned long sa_off, len, buf_off;
342 273
343 if (sys_info.arch == ARCH_S390) 274 prefix = zfcpdump_save_areas[i]->pref_reg;
344 prefix = zfcpdump_save_areas[i]->s390.pref_reg;
345 else
346 prefix = zfcpdump_save_areas[i]->s390x.pref_reg;
347
348 sa_start = prefix + sys_info.sa_base; 275 sa_start = prefix + sys_info.sa_base;
349 sa_end = prefix + sys_info.sa_base + sys_info.sa_size; 276 sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
350 277
@@ -561,34 +488,39 @@ static const struct file_operations zcore_reipl_fops = {
561 .release = zcore_reipl_release, 488 .release = zcore_reipl_release,
562}; 489};
563 490
491#ifdef CONFIG_32BIT
564 492
565static void __init set_s390_lc_mask(union save_area *map) 493static void __init set_lc_mask(struct save_area *map)
566{ 494{
567 memset(&map->s390.ext_save, 0xff, sizeof(map->s390.ext_save)); 495 memset(&map->ext_save, 0xff, sizeof(map->ext_save));
568 memset(&map->s390.timer, 0xff, sizeof(map->s390.timer)); 496 memset(&map->timer, 0xff, sizeof(map->timer));
569 memset(&map->s390.clk_cmp, 0xff, sizeof(map->s390.clk_cmp)); 497 memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
570 memset(&map->s390.psw, 0xff, sizeof(map->s390.psw)); 498 memset(&map->psw, 0xff, sizeof(map->psw));
571 memset(&map->s390.pref_reg, 0xff, sizeof(map->s390.pref_reg)); 499 memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
572 memset(&map->s390.acc_regs, 0xff, sizeof(map->s390.acc_regs)); 500 memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
573 memset(&map->s390.fp_regs, 0xff, sizeof(map->s390.fp_regs)); 501 memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
574 memset(&map->s390.gp_regs, 0xff, sizeof(map->s390.gp_regs)); 502 memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
575 memset(&map->s390.ctrl_regs, 0xff, sizeof(map->s390.ctrl_regs)); 503 memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
576} 504}
577 505
578static void __init set_s390x_lc_mask(union save_area *map) 506#else /* CONFIG_32BIT */
507
508static void __init set_lc_mask(struct save_area *map)
579{ 509{
580 memset(&map->s390x.fp_regs, 0xff, sizeof(map->s390x.fp_regs)); 510 memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
581 memset(&map->s390x.gp_regs, 0xff, sizeof(map->s390x.gp_regs)); 511 memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
582 memset(&map->s390x.psw, 0xff, sizeof(map->s390x.psw)); 512 memset(&map->psw, 0xff, sizeof(map->psw));
583 memset(&map->s390x.pref_reg, 0xff, sizeof(map->s390x.pref_reg)); 513 memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
584 memset(&map->s390x.fp_ctrl_reg, 0xff, sizeof(map->s390x.fp_ctrl_reg)); 514 memset(&map->fp_ctrl_reg, 0xff, sizeof(map->fp_ctrl_reg));
585 memset(&map->s390x.tod_reg, 0xff, sizeof(map->s390x.tod_reg)); 515 memset(&map->tod_reg, 0xff, sizeof(map->tod_reg));
586 memset(&map->s390x.timer, 0xff, sizeof(map->s390x.timer)); 516 memset(&map->timer, 0xff, sizeof(map->timer));
587 memset(&map->s390x.clk_cmp, 0xff, sizeof(map->s390x.clk_cmp)); 517 memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
588 memset(&map->s390x.acc_regs, 0xff, sizeof(map->s390x.acc_regs)); 518 memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
589 memset(&map->s390x.ctrl_regs, 0xff, sizeof(map->s390x.ctrl_regs)); 519 memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
590} 520}
591 521
522#endif /* CONFIG_32BIT */
523
592/* 524/*
593 * Initialize dump globals for a given architecture 525 * Initialize dump globals for a given architecture
594 */ 526 */
@@ -599,21 +531,18 @@ static int __init sys_info_init(enum arch_id arch)
599 switch (arch) { 531 switch (arch) {
600 case ARCH_S390X: 532 case ARCH_S390X:
601 pr_alert("DETECTED 'S390X (64 bit) OS'\n"); 533 pr_alert("DETECTED 'S390X (64 bit) OS'\n");
602 sys_info.sa_base = SAVE_AREA_BASE_S390X;
603 sys_info.sa_size = sizeof(struct save_area_s390x);
604 set_s390x_lc_mask(&sys_info.lc_mask);
605 break; 534 break;
606 case ARCH_S390: 535 case ARCH_S390:
607 pr_alert("DETECTED 'S390 (32 bit) OS'\n"); 536 pr_alert("DETECTED 'S390 (32 bit) OS'\n");
608 sys_info.sa_base = SAVE_AREA_BASE_S390;
609 sys_info.sa_size = sizeof(struct save_area_s390);
610 set_s390_lc_mask(&sys_info.lc_mask);
611 break; 537 break;
612 default: 538 default:
613 pr_alert("0x%x is an unknown architecture.\n",arch); 539 pr_alert("0x%x is an unknown architecture.\n",arch);
614 return -EINVAL; 540 return -EINVAL;
615 } 541 }
542 sys_info.sa_base = SAVE_AREA_BASE;
543 sys_info.sa_size = sizeof(struct save_area);
616 sys_info.arch = arch; 544 sys_info.arch = arch;
545 set_lc_mask(&sys_info.lc_mask);
617 rc = init_cpu_info(arch); 546 rc = init_cpu_info(arch);
618 if (rc) 547 if (rc)
619 return rc; 548 return rc;
@@ -660,8 +589,9 @@ static int __init get_mem_size(unsigned long *mem)
660 589
661static int __init zcore_header_init(int arch, struct zcore_header *hdr) 590static int __init zcore_header_init(int arch, struct zcore_header *hdr)
662{ 591{
663 int rc; 592 int rc, i;
664 unsigned long memory = 0; 593 unsigned long memory = 0;
594 u32 prefix;
665 595
666 if (arch == ARCH_S390X) 596 if (arch == ARCH_S390X)
667 hdr->arch_id = DUMP_ARCH_S390X; 597 hdr->arch_id = DUMP_ARCH_S390X;
@@ -676,6 +606,14 @@ static int __init zcore_header_init(int arch, struct zcore_header *hdr)
676 hdr->num_pages = memory / PAGE_SIZE; 606 hdr->num_pages = memory / PAGE_SIZE;
677 hdr->tod = get_clock(); 607 hdr->tod = get_clock();
678 get_cpu_id(&hdr->cpu_id); 608 get_cpu_id(&hdr->cpu_id);
609 for (i = 0; zfcpdump_save_areas[i]; i++) {
610 prefix = zfcpdump_save_areas[i]->pref_reg;
611 hdr->real_cpu_cnt++;
612 if (!prefix)
613 continue;
614 hdr->lc_vec[hdr->cpu_cnt] = prefix;
615 hdr->cpu_cnt++;
616 }
679 return 0; 617 return 0;
680} 618}
681 619
@@ -699,12 +637,8 @@ static int __init zcore_reipl_init(void)
699 if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE) 637 if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
700 rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); 638 rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
701 else 639 else
702 rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE); 640 rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
703 if (rc) { 641 if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
704 free_page((unsigned long) ipl_block);
705 return rc;
706 }
707 if (csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
708 ipib_info.checksum) { 642 ipib_info.checksum) {
709 TRACE("Checksum does not match\n"); 643 TRACE("Checksum does not match\n");
710 free_page((unsigned long) ipl_block); 644 free_page((unsigned long) ipl_block);
@@ -741,14 +675,21 @@ static int __init zcore_init(void)
741 if (rc) 675 if (rc)
742 goto fail; 676 goto fail;
743 677
744#ifndef __s390x__ 678#ifdef CONFIG_64BIT
679 if (arch == ARCH_S390) {
680 pr_alert("The 64-bit dump tool cannot be used for a "
681 "32-bit system\n");
682 rc = -EINVAL;
683 goto fail;
684 }
685#else /* CONFIG_64BIT */
745 if (arch == ARCH_S390X) { 686 if (arch == ARCH_S390X) {
746 pr_alert("The 32-bit dump tool cannot be used for a " 687 pr_alert("The 32-bit dump tool cannot be used for a "
747 "64-bit system\n"); 688 "64-bit system\n");
748 rc = -EINVAL; 689 rc = -EINVAL;
749 goto fail; 690 goto fail;
750 } 691 }
751#endif 692#endif /* CONFIG_64BIT */
752 693
753 rc = sys_info_init(arch); 694 rc = sys_info_init(arch);
754 if (rc) 695 if (rc)