diff -urpN linux-2.6/drivers/s390/char/con3270.c linux-2.6-patched/drivers/s390/char/con3270.c
--- linux-2.6/drivers/s390/char/con3270.c	2005-08-10 15:43:44.000000000 +0200
+++ linux-2.6-patched/drivers/s390/char/con3270.c	2005-08-10 15:43:57.000000000 +0200
@@ -512,7 +512,8 @@ extern struct tty_driver *tty3270_driver
 static struct tty_driver *
 con3270_device(struct console *c, int *index)
 {
-	*index = c->index;
+	/* Check for minor 0 special case, see fs3270.c:fs3270_open(). */
+	*index = c->index + 1;
 	return tty3270_driver;
 }
 
@@ -620,7 +621,7 @@ con3270_init(void)
 		     (void (*)(unsigned long)) con3270_read_tasklet,
 		     (unsigned long) condev->read);
 
-	raw3270_add_view(&condev->view, &con3270_fn, 0);
+	raw3270_add_view(&condev->view, &con3270_fn, 1);
 
 	INIT_LIST_HEAD(&condev->freemem);
 	for (i = 0; i < CON3270_STRING_PAGES; i++) {
diff -urpN linux-2.6/drivers/s390/char/fs3270.c linux-2.6-patched/drivers/s390/char/fs3270.c
--- linux-2.6/drivers/s390/char/fs3270.c	2005-08-10 15:43:44.000000000 +0200
+++ linux-2.6-patched/drivers/s390/char/fs3270.c	2005-08-10 15:43:57.000000000 +0200
@@ -77,7 +77,7 @@ fs3270_activate(struct raw3270_view *vie
 	fp = (struct fs3270 *) view;
 	raw3270_request_set_cmd(fp->clear, TC_EWRITEA);
 	fp->clear->callback = fs3270_reset_callback;
-	return raw3270_start(view, fp->clear);
+	return raw3270_start_locked(view, fp->clear);
 }
 
 /*
@@ -95,6 +95,7 @@ fs3270_deactivate(struct raw3270_view *v
 	if (fp->fs_pid != 0)
 		kill_proc(fp->fs_pid, SIGHUP, 1);
 	fp->fs_pid = 0;
+	raw3270_reset(view);
 }
 
 static int
@@ -125,7 +126,7 @@ fs3270_read(struct file *filp, char *dat
 	struct fs3270 *fp;
 	struct raw3270_request *rq;
 	struct idal_buffer *ib;
-	int rc;
+	ssize_t rc;
 	
 	if (count == 0 || count > 65535)
 		return -EINVAL;
@@ -141,10 +142,18 @@ fs3270_read(struct file *filp, char *dat
 			fp->read_command = 6;
 		raw3270_request_set_cmd(rq, fp->read_command ? : 2);
 		raw3270_request_set_idal(rq, ib);
-		wait_event(fp->attn_wait, fp->attention);
-		rc = fs3270_do_io(&fp->view, rq);
-		if (rc == 0 && idal_buffer_to_user(ib, data, count))
-			rc = -EFAULT;
+		rc = wait_event_interruptible(fp->attn_wait, fp->attention);
+		if (rc == 0) {
+			rc = fs3270_do_io(&fp->view, rq);
+			if (rc == 0) {
+				count -= rq->rescnt;
+				if (idal_buffer_to_user(ib, data, count) != 0)
+					rc = -EFAULT;
+				else
+					rc = count;
+
+			}
+		}
 		raw3270_request_free(rq);
 	} else
 		rc = PTR_ERR(rq);
@@ -162,7 +171,7 @@ fs3270_write(struct file *filp, const ch
 	struct raw3270_request *rq;
 	struct idal_buffer *ib;
 	int write_command;
-	int rc;
+	ssize_t rc;
 
 	fp = filp->private_data;
 	if (!fp)
@@ -179,6 +188,8 @@ fs3270_write(struct file *filp, const ch
 			raw3270_request_set_cmd(rq, write_command);
 			raw3270_request_set_idal(rq, ib);
 			rc = fs3270_do_io(&fp->view, rq);
+			if (rc == 0)
+				rc = count - rq->rescnt;
 		} else
 			rc = -EFAULT;
 		raw3270_request_free(rq);
@@ -244,7 +255,7 @@ fs3270_alloc_view(void)
 		return ERR_PTR(-ENOMEM);
 	memset(fp, 0, sizeof(struct fs3270));
 	fp->clear = raw3270_request_alloc(0);
-	if (!IS_ERR(fp->clear)) {
+	if (IS_ERR(fp->clear)) {
 		kfree(fp);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -290,6 +301,14 @@ fs3270_open(struct inode *inode, struct 
 	if (imajor(filp->f_dentry->d_inode) != IBM_FS3270_MAJOR)
 		return -ENODEV;
 	minor = iminor(filp->f_dentry->d_inode);
+	/* Check for minor 0 multiplexer. */
+	if (minor == 0) {
+		if (!current->signal->tty)
+			return -ENODEV;
+		if (current->signal->tty->driver->major != IBM_TTY3270_MAJOR)
+			return -ENODEV;
+		minor = current->signal->tty->index;
+	}
 	/* Check if some other program is already using fullscreen mode. */
 	fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
 	if (!IS_ERR(fp)) {
@@ -311,6 +330,7 @@ fs3270_open(struct inode *inode, struct 
 
 	rc = raw3270_activate_view(&fp->view);
 	if (rc) {
+		raw3270_put_view(&fp->view);
 		raw3270_del_view(&fp->view);
 		return rc;
 	}
@@ -329,8 +349,12 @@ fs3270_close(struct inode *inode, struct
 
 	fp = filp->private_data;
 	filp->private_data = 0;
-	if (fp)
+	if (fp) {
+		fp->fs_pid = 0;
+		raw3270_reset(&fp->view);
+		raw3270_put_view(&fp->view);
 		raw3270_del_view(&fp->view);
+	}
 	return 0;
 }
 
diff -urpN linux-2.6/drivers/s390/char/raw3270.c linux-2.6-patched/drivers/s390/char/raw3270.c
--- linux-2.6/drivers/s390/char/raw3270.c	2005-08-10 15:43:45.000000000 +0200
+++ linux-2.6-patched/drivers/s390/char/raw3270.c	2005-08-10 15:43:57.000000000 +0200
@@ -317,6 +317,22 @@ raw3270_start(struct raw3270_view *view,
 }
 
 int
+raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
+{
+	struct raw3270 *rp;
+	int rc;
+
+	rp = view->dev;
+	if (!rp || rp->view != view)
+		rc = -EACCES;
+	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+		rc = -ENODEV;
+	else
+		rc =  __raw3270_start(rp, view, rq);
+	return rc;
+}
+
+int
 raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
 {
 	struct raw3270 *rp;
@@ -632,12 +648,9 @@ __raw3270_size_device(struct raw3270 *rp
 	raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data);
 
 	rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request);
-	if (rc) {
+	if (rc)
 		/* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */
-		if (rc == -EOPNOTSUPP && MACHINE_IS_VM)
-			return __raw3270_size_device_vm(rp);
 		return rc;
-	}
 
 	/* Wait for attention interrupt. */
 #ifdef CONFIG_TN3270_CONSOLE
@@ -695,7 +708,10 @@ raw3270_size_device(struct raw3270 *rp)
 	down(&raw3270_init_sem);
 	rp->view = &raw3270_init_view;
 	raw3270_init_view.dev = rp;
-	rc = __raw3270_size_device(rp);
+	if (MACHINE_IS_VM)
+		rc = __raw3270_size_device_vm(rp);
+	else
+		rc = __raw3270_size_device(rp);
 	raw3270_init_view.dev = 0;
 	rp->view = 0;
 	up(&raw3270_init_sem);
@@ -710,6 +726,12 @@ raw3270_size_device(struct raw3270 *rp)
 			rp->model = 4;
 		if (rp->rows == 27 && rp->cols == 132)
 			rp->model = 5;
+	} else {
+		/* Couldn't detect size. Use default model 2. */
+		rp->model = 2;
+		rp->rows = 24;
+		rp->cols = 80;
+		return 0;
 	}
 	return rc;
 }
@@ -738,6 +760,22 @@ raw3270_reset_device(struct raw3270 *rp)
 	return rc;
 }
 
+int
+raw3270_reset(struct raw3270_view *view)
+{
+	struct raw3270 *rp;
+	int rc;
+
+	rp = view->dev;
+	if (!rp || rp->view != view)
+		rc = -EACCES;
+	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+		rc = -ENODEV;
+	else
+		rc = raw3270_reset_device(view->dev);
+	return rc;
+}
+
 /*
  * Setup new 3270 device.
  */
@@ -768,11 +806,12 @@ raw3270_setup_device(struct ccw_device *
 
 	/*
 	 * Add device to list and find the smallest unused minor
-	 * number for it.
+	 * number for it. Note: there is no device with minor 0,
+	 * see special case for fs3270.c:fs3270_open().
 	 */
 	down(&raw3270_sem);
 	/* Keep the list sorted. */
-	minor = 0;
+	minor = 1;
 	rp->minor = -1;
 	list_for_each(l, &raw3270_devices) {
 		tmp = list_entry(l, struct raw3270, list);
@@ -955,6 +994,8 @@ raw3270_add_view(struct raw3270_view *vi
 	struct raw3270 *rp;
 	int rc;
 
+	if (minor <= 0)
+		return -ENODEV;
 	down(&raw3270_sem);
 	rc = -ENODEV;
 	list_for_each_entry(rp, &raw3270_devices, list) {
@@ -970,7 +1011,7 @@ raw3270_add_view(struct raw3270_view *vi
 			view->cols = rp->cols;
 			view->ascebc = rp->ascebc;
 			spin_lock_init(&view->lock);
-			list_add_tail(&view->list, &rp->view_list);
+			list_add(&view->list, &rp->view_list);
 			rc = 0;
 		}
 		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
@@ -1033,7 +1074,7 @@ raw3270_del_view(struct raw3270_view *vi
 	if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
 		/* Try to activate another view. */
 		list_for_each_entry(nv, &rp->view_list, list) {
-			if (nv->fn->activate(view) == 0) {
+			if (nv->fn->activate(nv) == 0) {
 				rp->view = nv;
 				break;
 			}
@@ -1329,7 +1370,9 @@ EXPORT_SYMBOL(raw3270_find_view);
 EXPORT_SYMBOL(raw3270_activate_view);
 EXPORT_SYMBOL(raw3270_deactivate_view);
 EXPORT_SYMBOL(raw3270_start);
+EXPORT_SYMBOL(raw3270_start_locked);
 EXPORT_SYMBOL(raw3270_start_irq);
+EXPORT_SYMBOL(raw3270_reset);
 EXPORT_SYMBOL(raw3270_register_notifier);
 EXPORT_SYMBOL(raw3270_unregister_notifier);
 EXPORT_SYMBOL(raw3270_wait_queue);
diff -urpN linux-2.6/drivers/s390/char/raw3270.h linux-2.6-patched/drivers/s390/char/raw3270.h
--- linux-2.6/drivers/s390/char/raw3270.h	2005-08-10 15:43:44.000000000 +0200
+++ linux-2.6-patched/drivers/s390/char/raw3270.h	2005-08-10 15:43:57.000000000 +0200
@@ -166,7 +166,9 @@ void raw3270_del_view(struct raw3270_vie
 void raw3270_deactivate_view(struct raw3270_view *);
 struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
 int raw3270_start(struct raw3270_view *, struct raw3270_request *);
+int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
 int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
+int raw3270_reset(struct raw3270_view *);
 
 /* Reference count inliner for view structures. */
 static inline void
diff -urpN linux-2.6/drivers/s390/char/tty3270.c linux-2.6-patched/drivers/s390/char/tty3270.c
--- linux-2.6/drivers/s390/char/tty3270.c	2005-08-10 15:43:44.000000000 +0200
+++ linux-2.6-patched/drivers/s390/char/tty3270.c	2005-08-10 15:43:57.000000000 +0200
@@ -653,18 +653,12 @@ tty3270_activate(struct raw3270_view *vi
 	tp->update_flags = TTY_UPDATE_ALL;
 	tty3270_set_timer(tp, 1);
 	spin_unlock_irqrestore(&tp->view.lock, flags);
-	start_tty(tp->tty);
 	return 0;
 }
 
 static void
 tty3270_deactivate(struct raw3270_view *view)
 {
-	struct tty3270 *tp;
-
-	tp = (struct tty3270 *) view;
-	if (tp && tp->tty)
-		stop_tty(tp->tty);
 }
 
 static int
@@ -870,6 +864,9 @@ tty3270_open(struct tty_struct *tty, str
 
 	if (tty->count > 1)
 		return 0;
+	/* Check for minor 0 special case, see fs3270.c:fs3270_open(). */
+	if (tty->index == 0)
+		return -ENODEV;
 	/* Check if the tty3270 is already there. */
 	tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, tty->index);
 	if (!IS_ERR(tp)) {
@@ -911,8 +908,8 @@ tty3270_open(struct tty_struct *tty, str
 
 	rc = tty3270_alloc_screen(tp);
 	if (rc) {
-		raw3270_del_view(&tp->view);
 		raw3270_put_view(&tp->view);
+		raw3270_del_view(&tp->view);
 		return rc;
 	}
 
