aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/fs3270.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char/fs3270.c')
-rw-r--r--drivers/s390/char/fs3270.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index ef36f2132aa4..d18e6d2e0b49 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -14,6 +14,7 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/smp_lock.h>
17 18
18#include <asm/ccwdev.h> 19#include <asm/ccwdev.h>
19#include <asm/cio.h> 20#include <asm/cio.h>
@@ -216,17 +217,17 @@ static int
216fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb) 217fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
217{ 218{
218 /* Handle ATTN. Set indication and wake waiters for attention. */ 219 /* Handle ATTN. Set indication and wake waiters for attention. */
219 if (irb->scsw.dstat & DEV_STAT_ATTENTION) { 220 if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
220 fp->attention = 1; 221 fp->attention = 1;
221 wake_up(&fp->wait); 222 wake_up(&fp->wait);
222 } 223 }
223 224
224 if (rq) { 225 if (rq) {
225 if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) 226 if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
226 rq->rc = -EIO; 227 rq->rc = -EIO;
227 else 228 else
228 /* Normal end. Copy residual count. */ 229 /* Normal end. Copy residual count. */
229 rq->rescnt = irb->scsw.count; 230 rq->rescnt = irb->scsw.cmd.count;
230 } 231 }
231 return RAW3270_IO_DONE; 232 return RAW3270_IO_DONE;
232} 233}
@@ -421,6 +422,7 @@ fs3270_open(struct inode *inode, struct file *filp)
421 422
422 if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR) 423 if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR)
423 return -ENODEV; 424 return -ENODEV;
425 lock_kernel();
424 minor = iminor(filp->f_path.dentry->d_inode); 426 minor = iminor(filp->f_path.dentry->d_inode);
425 /* Check for minor 0 multiplexer. */ 427 /* Check for minor 0 multiplexer. */
426 if (minor == 0) { 428 if (minor == 0) {
@@ -429,7 +431,8 @@ fs3270_open(struct inode *inode, struct file *filp)
429 tty = get_current_tty(); 431 tty = get_current_tty();
430 if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { 432 if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
431 mutex_unlock(&tty_mutex); 433 mutex_unlock(&tty_mutex);
432 return -ENODEV; 434 rc = -ENODEV;
435 goto out;
433 } 436 }
434 minor = tty->index + RAW3270_FIRSTMINOR; 437 minor = tty->index + RAW3270_FIRSTMINOR;
435 mutex_unlock(&tty_mutex); 438 mutex_unlock(&tty_mutex);
@@ -438,19 +441,22 @@ fs3270_open(struct inode *inode, struct file *filp)
438 fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); 441 fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
439 if (!IS_ERR(fp)) { 442 if (!IS_ERR(fp)) {
440 raw3270_put_view(&fp->view); 443 raw3270_put_view(&fp->view);
441 return -EBUSY; 444 rc = -EBUSY;
445 goto out;
442 } 446 }
443 /* Allocate fullscreen view structure. */ 447 /* Allocate fullscreen view structure. */
444 fp = fs3270_alloc_view(); 448 fp = fs3270_alloc_view();
445 if (IS_ERR(fp)) 449 if (IS_ERR(fp)) {
446 return PTR_ERR(fp); 450 rc = PTR_ERR(fp);
451 goto out;
452 }
447 453
448 init_waitqueue_head(&fp->wait); 454 init_waitqueue_head(&fp->wait);
449 fp->fs_pid = get_pid(task_pid(current)); 455 fp->fs_pid = get_pid(task_pid(current));
450 rc = raw3270_add_view(&fp->view, &fs3270_fn, minor); 456 rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
451 if (rc) { 457 if (rc) {
452 fs3270_free_view(&fp->view); 458 fs3270_free_view(&fp->view);
453 return rc; 459 goto out;
454 } 460 }
455 461
456 /* Allocate idal-buffer. */ 462 /* Allocate idal-buffer. */
@@ -458,7 +464,8 @@ fs3270_open(struct inode *inode, struct file *filp)
458 if (IS_ERR(ib)) { 464 if (IS_ERR(ib)) {
459 raw3270_put_view(&fp->view); 465 raw3270_put_view(&fp->view);
460 raw3270_del_view(&fp->view); 466 raw3270_del_view(&fp->view);
461 return PTR_ERR(fp); 467 rc = PTR_ERR(fp);
468 goto out;
462 } 469 }
463 fp->rdbuf = ib; 470 fp->rdbuf = ib;
464 471
@@ -466,9 +473,11 @@ fs3270_open(struct inode *inode, struct file *filp)
466 if (rc) { 473 if (rc) {
467 raw3270_put_view(&fp->view); 474 raw3270_put_view(&fp->view);
468 raw3270_del_view(&fp->view); 475 raw3270_del_view(&fp->view);
469 return rc; 476 goto out;
470 } 477 }
471 filp->private_data = fp; 478 filp->private_data = fp;
479out:
480 unlock_kernel();
472 return 0; 481 return 0;
473} 482}
474 483
@@ -512,11 +521,8 @@ fs3270_init(void)
512 int rc; 521 int rc;
513 522
514 rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops); 523 rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops);
515 if (rc) { 524 if (rc)
516 printk(KERN_ERR "fs3270 can't get major number %d: errno %d\n",
517 IBM_FS3270_MAJOR, rc);
518 return rc; 525 return rc;
519 }
520 return 0; 526 return 0;
521} 527}
522 528