aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/con3215.c142
-rw-r--r--drivers/s390/char/keyboard.c30
-rw-r--r--drivers/s390/char/keyboard.h14
-rw-r--r--drivers/s390/char/sclp_cmd.c24
-rw-r--r--drivers/s390/char/sclp_sdias.c2
-rw-r--r--drivers/s390/char/sclp_tty.c33
-rw-r--r--drivers/s390/char/sclp_vt220.c33
-rw-r--r--drivers/s390/char/tape.h43
-rw-r--r--drivers/s390/char/tape_34xx.c136
-rw-r--r--drivers/s390/char/tape_3590.c105
-rw-r--r--drivers/s390/char/tape_char.c13
-rw-r--r--drivers/s390/char/tape_core.c16
-rw-r--r--drivers/s390/char/tty3270.c121
13 files changed, 219 insertions, 493 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 4f9f1dcc1551..6c0116d48c74 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/reboot.h>
+#include <linux/serial.h> /* ASYNC_* flags */
#include <linux/slab.h>
#include <asm/ccwdev.h>
#include <asm/cio.h>
@@ -44,14 +45,11 @@
#define RAW3215_TIMEOUT HZ/10 /* time for delayed output */
#define RAW3215_FIXED 1 /* 3215 console device is not be freed */
-#define RAW3215_ACTIVE 2 /* set if the device is in use */
#define RAW3215_WORKING 4 /* set if a request is being worked on */
#define RAW3215_THROTTLED 8 /* set if reading is disabled */
#define RAW3215_STOPPED 16 /* set if writing is disabled */
-#define RAW3215_CLOSING 32 /* set while in close process */
#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */
#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */
-#define RAW3215_FROZEN 256 /* set if 3215 is frozen for suspend */
#define TAB_STOP_SIZE 8 /* tab stop size */
@@ -76,6 +74,7 @@ struct raw3215_req {
} __attribute__ ((aligned(8)));
struct raw3215_info {
+ struct tty_port port;
struct ccw_device *cdev; /* device for tty driver */
spinlock_t *lock; /* pointer to irq lock */
int flags; /* state flags */
@@ -84,7 +83,6 @@ struct raw3215_info {
int head; /* first free byte in output buffer */
int count; /* number of bytes in output buffer */
int written; /* number of bytes in write requests */
- struct tty_struct *tty; /* pointer to tty structure if present */
struct raw3215_req *queued_read; /* pointer to queued read requests */
struct raw3215_req *queued_write;/* pointer to queued write requests */
struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */
@@ -293,7 +291,7 @@ static void raw3215_timeout(unsigned long __data)
if (raw->flags & RAW3215_TIMER_RUNS) {
del_timer(&raw->timer);
raw->flags &= ~RAW3215_TIMER_RUNS;
- if (!(raw->flags & RAW3215_FROZEN)) {
+ if (!(raw->port.flags & ASYNC_SUSPENDED)) {
raw3215_mk_write_req(raw);
raw3215_start_io(raw);
}
@@ -309,7 +307,8 @@ static void raw3215_timeout(unsigned long __data)
*/
static inline void raw3215_try_io(struct raw3215_info *raw)
{
- if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FROZEN))
+ if (!(raw->port.flags & ASYNC_INITIALIZED) ||
+ (raw->port.flags & ASYNC_SUSPENDED))
return;
if (raw->queued_read != NULL)
raw3215_start_io(raw);
@@ -324,10 +323,7 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
}
} else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
/* delay small writes */
- init_timer(&raw->timer);
raw->timer.expires = RAW3215_TIMEOUT + jiffies;
- raw->timer.data = (unsigned long) raw;
- raw->timer.function = raw3215_timeout;
add_timer(&raw->timer);
raw->flags |= RAW3215_TIMER_RUNS;
}
@@ -340,17 +336,21 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
static void raw3215_wakeup(unsigned long data)
{
struct raw3215_info *raw = (struct raw3215_info *) data;
- tty_wakeup(raw->tty);
+ struct tty_struct *tty;
+
+ tty = tty_port_tty_get(&raw->port);
+ tty_wakeup(tty);
+ tty_kref_put(tty);
}
/*
* Try to start the next IO and wake up processes waiting on the tty.
*/
-static void raw3215_next_io(struct raw3215_info *raw)
+static void raw3215_next_io(struct raw3215_info *raw, struct tty_struct *tty)
{
raw3215_mk_write_req(raw);
raw3215_try_io(raw);
- if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
+ if (tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
tasklet_schedule(&raw->tlet);
}
@@ -368,10 +368,11 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
raw = dev_get_drvdata(&cdev->dev);
req = (struct raw3215_req *) intparm;
+ tty = tty_port_tty_get(&raw->port);
cstat = irb->scsw.cmd.cstat;
dstat = irb->scsw.cmd.dstat;
if (cstat != 0)
- raw3215_next_io(raw);
+ raw3215_next_io(raw, tty);
if (dstat & 0x01) { /* we got a unit exception */
dstat &= ~0x01; /* we can ignore it */
}
@@ -381,13 +382,13 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
break;
/* Attention interrupt, someone hit the enter key */
raw3215_mk_read_req(raw);
- raw3215_next_io(raw);
+ raw3215_next_io(raw, tty);
break;
case 0x08:
case 0x0C:
/* Channel end interrupt. */
if ((raw = req->info) == NULL)
- return; /* That shouldn't happen ... */
+ goto put_tty; /* That shouldn't happen ... */
if (req->type == RAW3215_READ) {
/* store residual count, then wait for device end */
req->residual = irb->scsw.cmd.count;
@@ -397,11 +398,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
case 0x04:
/* Device end interrupt. */
if ((raw = req->info) == NULL)
- return; /* That shouldn't happen ... */
- if (req->type == RAW3215_READ && raw->tty != NULL) {
+ goto put_tty; /* That shouldn't happen ... */
+ if (req->type == RAW3215_READ && tty != NULL) {
unsigned int cchar;
- tty = raw->tty;
count = 160 - req->residual;
EBCASC(raw->inbuf, count);
cchar = ctrlchar_handle(raw->inbuf, count, tty);
@@ -411,7 +411,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
case CTRLCHAR_CTRL:
tty_insert_flip_char(tty, cchar, TTY_NORMAL);
- tty_flip_buffer_push(raw->tty);
+ tty_flip_buffer_push(tty);
break;
case CTRLCHAR_NONE:
@@ -424,7 +424,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
} else
count -= 2;
tty_insert_flip_string(tty, raw->inbuf, count);
- tty_flip_buffer_push(raw->tty);
+ tty_flip_buffer_push(tty);
break;
}
} else if (req->type == RAW3215_WRITE) {
@@ -439,7 +439,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
raw->queued_read == NULL) {
wake_up_interruptible(&raw->empty_wait);
}
- raw3215_next_io(raw);
+ raw3215_next_io(raw, tty);
break;
default:
/* Strange interrupt, I'll do my best to clean up */
@@ -451,9 +451,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
raw->flags &= ~RAW3215_WORKING;
raw3215_free_req(req);
}
- raw3215_next_io(raw);
+ raw3215_next_io(raw, tty);
}
- return;
+put_tty:
+ tty_kref_put(tty);
}
/*
@@ -487,7 +488,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
/* While console is frozen for suspend we have no other
* choice but to drop message from the buffer to make
* room for even more messages. */
- if (raw->flags & RAW3215_FROZEN) {
+ if (raw->port.flags & ASYNC_SUSPENDED) {
raw3215_drop_line(raw);
continue;
}
@@ -609,10 +610,10 @@ static int raw3215_startup(struct raw3215_info *raw)
{
unsigned long flags;
- if (raw->flags & RAW3215_ACTIVE)
+ if (raw->port.flags & ASYNC_INITIALIZED)
return 0;
raw->line_pos = 0;
- raw->flags |= RAW3215_ACTIVE;
+ raw->port.flags |= ASYNC_INITIALIZED;
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_try_io(raw);
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -628,14 +629,15 @@ static void raw3215_shutdown(struct raw3215_info *raw)
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
- if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
+ if (!(raw->port.flags & ASYNC_INITIALIZED) ||
+ (raw->flags & RAW3215_FIXED))
return;
/* Wait for outstanding requests, then free irq */
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
if ((raw->flags & RAW3215_WORKING) ||
raw->queued_write != NULL ||
raw->queued_read != NULL) {
- raw->flags |= RAW3215_CLOSING;
+ raw->port.flags |= ASYNC_CLOSING;
add_wait_queue(&raw->empty_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -643,11 +645,41 @@ static void raw3215_shutdown(struct raw3215_info *raw)
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
remove_wait_queue(&raw->empty_wait, &wait);
set_current_state(TASK_RUNNING);
- raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING);
+ raw->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING);
}
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
+static struct raw3215_info *raw3215_alloc_info(void)
+{
+ struct raw3215_info *info;
+
+ info = kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA);
+ if (!info)
+ return NULL;
+
+ info->buffer = kzalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
+ info->inbuf = kzalloc(RAW3215_INBUF_SIZE, GFP_KERNEL | GFP_DMA);
+ if (!info->buffer || !info->inbuf) {
+ kfree(info);
+ return NULL;
+ }
+
+ setup_timer(&info->timer, raw3215_timeout, (unsigned long)info);
+ init_waitqueue_head(&info->empty_wait);
+ tasklet_init(&info->tlet, raw3215_wakeup, (unsigned long)info);
+ tty_port_init(&info->port);
+
+ return info;
+}
+
+static void raw3215_free_info(struct raw3215_info *raw)
+{
+ kfree(raw->inbuf);
+ kfree(raw->buffer);
+ kfree(raw);
+}
+
static int raw3215_probe (struct ccw_device *cdev)
{
struct raw3215_info *raw;
@@ -656,11 +688,15 @@ static int raw3215_probe (struct ccw_device *cdev)
/* Console is special. */
if (raw3215[0] && (raw3215[0] == dev_get_drvdata(&cdev->dev)))
return 0;
- raw = kmalloc(sizeof(struct raw3215_info) +
- RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA);
+
+ raw = raw3215_alloc_info();
if (raw == NULL)
return -ENOMEM;
+ raw->cdev = cdev;
+ dev_set_drvdata(&cdev->dev, raw);
+ cdev->handler = raw3215_irq;
+
spin_lock(&raw3215_device_lock);
for (line = 0; line < NR_3215; line++) {
if (!raw3215[line]) {
@@ -670,28 +706,10 @@ static int raw3215_probe (struct ccw_device *cdev)
}
spin_unlock(&raw3215_device_lock);
if (line == NR_3215) {
- kfree(raw);
+ raw3215_free_info(raw);
return -ENODEV;
}
- raw->cdev = cdev;
- raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
- memset(raw, 0, sizeof(struct raw3215_info));
- raw->buffer = kmalloc(RAW3215_BUFFER_SIZE,
- GFP_KERNEL|GFP_DMA);
- if (raw->buffer == NULL) {
- spin_lock(&raw3215_device_lock);
- raw3215[line] = NULL;
- spin_unlock(&raw3215_device_lock);
- kfree(raw);
- return -ENOMEM;
- }
- init_waitqueue_head(&raw->empty_wait);
- tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
-
- dev_set_drvdata(&cdev->dev, raw);
- cdev->handler = raw3215_irq;
-
return 0;
}
@@ -703,8 +721,7 @@ static void raw3215_remove (struct ccw_device *cdev)
raw = dev_get_drvdata(&cdev->dev);
if (raw) {
dev_set_drvdata(&cdev->dev, NULL);
- kfree(raw->buffer);
- kfree(raw);
+ raw3215_free_info(raw);
}
}
@@ -741,7 +758,7 @@ static int raw3215_pm_stop(struct ccw_device *cdev)
raw = dev_get_drvdata(&cdev->dev);
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
- raw->flags |= RAW3215_FROZEN;
+ raw->port.flags |= ASYNC_SUSPENDED;
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
return 0;
}
@@ -754,7 +771,7 @@ static int raw3215_pm_start(struct ccw_device *cdev)
/* Allow I/O again and flush output buffer. */
raw = dev_get_drvdata(&cdev->dev);
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
- raw->flags &= ~RAW3215_FROZEN;
+ raw->port.flags &= ~ASYNC_SUSPENDED;
raw->flags |= RAW3215_FLUSHING;
raw3215_try_io(raw);
raw->flags &= ~RAW3215_FLUSHING;
@@ -827,7 +844,7 @@ static void con3215_flush(void)
unsigned long flags;
raw = raw3215[0]; /* console 3215 is the first one */
- if (raw->flags & RAW3215_FROZEN)
+ if (raw->port.flags & ASYNC_SUSPENDED)
/* The console is still frozen for suspend. */
if (ccw_device_force_console())
/* Forcing didn't work, no panic message .. */
@@ -897,23 +914,16 @@ static int __init con3215_init(void)
if (IS_ERR(cdev))
return -ENODEV;
- raw3215[0] = raw = (struct raw3215_info *)
- kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA);
- raw->buffer = kzalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
- raw->inbuf = kzalloc(RAW3215_INBUF_SIZE, GFP_KERNEL | GFP_DMA);
+ raw3215[0] = raw = raw3215_alloc_info();
raw->cdev = cdev;
dev_set_drvdata(&cdev->dev, raw);
cdev->handler = raw3215_irq;
raw->flags |= RAW3215_FIXED;
- init_waitqueue_head(&raw->empty_wait);
- tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
/* Request the console irq */
if (raw3215_startup(raw) != 0) {
- kfree(raw->inbuf);
- kfree(raw->buffer);
- kfree(raw);
+ raw3215_free_info(raw);
raw3215[0] = NULL;
return -ENODEV;
}
@@ -940,7 +950,7 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp)
return -ENODEV;
tty->driver_data = raw;
- raw->tty = tty;
+ tty_port_tty_set(&raw->port, tty);
tty->low_latency = 0; /* don't use bottom half for pushing chars */
/*
@@ -971,7 +981,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
raw3215_shutdown(raw);
tasklet_kill(&raw->tlet);
tty->closing = 0;
- raw->tty = NULL;
+ tty_port_tty_set(&raw->port, NULL);
}
/*
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index 806588192483..7ef9cfdc17d8 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -199,7 +199,7 @@ handle_diacr(struct kbd_data *kbd, unsigned int ch)
if (ch == ' ' || ch == d)
return d;
- kbd_put_queue(kbd->tty, d);
+ kbd_put_queue(kbd->port, d);
return ch;
}
@@ -221,7 +221,7 @@ k_self(struct kbd_data *kbd, unsigned char value)
{
if (kbd->diacr)
value = handle_diacr(kbd, value);
- kbd_put_queue(kbd->tty, value);
+ kbd_put_queue(kbd->port, value);
}
/*
@@ -239,7 +239,7 @@ static void
k_fn(struct kbd_data *kbd, unsigned char value)
{
if (kbd->func_table[value])
- kbd_puts_queue(kbd->tty, kbd->func_table[value]);
+ kbd_puts_queue(kbd->port, kbd->func_table[value]);
}
static void
@@ -257,20 +257,20 @@ k_spec(struct kbd_data *kbd, unsigned char value)
* but we need only 16 bits here
*/
static void
-to_utf8(struct tty_struct *tty, ushort c)
+to_utf8(struct tty_port *port, ushort c)
{
if (c < 0x80)
/* 0******* */
- kbd_put_queue(tty, c);
+ kbd_put_queue(port, c);
else if (c < 0x800) {
/* 110***** 10****** */
- kbd_put_queue(tty, 0xc0 | (c >> 6));
- kbd_put_queue(tty, 0x80 | (c & 0x3f));
+ kbd_put_queue(port, 0xc0 | (c >> 6));
+ kbd_put_queue(port, 0x80 | (c & 0x3f));
} else {
/* 1110**** 10****** 10****** */
- kbd_put_queue(tty, 0xe0 | (c >> 12));
- kbd_put_queue(tty, 0x80 | ((c >> 6) & 0x3f));
- kbd_put_queue(tty, 0x80 | (c & 0x3f));
+ kbd_put_queue(port, 0xe0 | (c >> 12));
+ kbd_put_queue(port, 0x80 | ((c >> 6) & 0x3f));
+ kbd_put_queue(port, 0x80 | (c & 0x3f));
}
}
@@ -283,7 +283,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
unsigned short keysym;
unsigned char type, value;
- if (!kbd || !kbd->tty)
+ if (!kbd)
return;
if (keycode >= 384)
@@ -323,7 +323,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
#endif
(*k_handler[type])(kbd, value);
} else
- to_utf8(kbd->tty, keysym);
+ to_utf8(kbd->port, keysym);
}
/*
@@ -457,6 +457,7 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
{
+ struct tty_struct *tty;
void __user *argp;
unsigned int ct;
int perm;
@@ -467,7 +468,10 @@ int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
* To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
*/
- perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG);
+ tty = tty_port_tty_get(kbd->port);
+ /* FIXME this test is pretty racy */
+ perm = current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG);
+ tty_kref_put(tty);
switch (cmd) {
case KDGKBTYPE:
return put_user(KB_101, (char __user *)argp);
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 7e736aaeae6e..f682f4e49680 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -21,7 +21,7 @@ typedef void (fn_handler_fn)(struct kbd_data *);
*/
struct kbd_data {
- struct tty_struct *tty;
+ struct tty_port *port;
unsigned short **key_maps;
char **func_table;
fn_handler_fn **fn_handler;
@@ -42,16 +42,24 @@ int kbd_ioctl(struct kbd_data *, unsigned int, unsigned long);
* Helper Functions.
*/
static inline void
-kbd_put_queue(struct tty_struct *tty, int ch)
+kbd_put_queue(struct tty_port *port, int ch)
{
+ struct tty_struct *tty = tty_port_tty_get(port);
+ if (!tty)
+ return;
tty_insert_flip_char(tty, ch, 0);
tty_schedule_flip(tty);
+ tty_kref_put(tty);
}
static inline void
-kbd_puts_queue(struct tty_struct *tty, char *cp)
+kbd_puts_queue(struct tty_port *port, char *cp)
{
+ struct tty_struct *tty = tty_port_tty_get(port);
+ if (!tty)
+ return;
while (*cp)
tty_insert_flip_char(tty, *cp++, 0);
tty_schedule_flip(tty);
+ tty_kref_put(tty);
}
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 231a1d85127b..766cb7b19b40 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -17,6 +17,7 @@
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/memory.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
@@ -38,7 +39,8 @@ struct read_info_sccb {
u64 facilities; /* 48-55 */
u8 _reserved2[84 - 56]; /* 56-83 */
u8 fac84; /* 84 */
- u8 _reserved3[91 - 85]; /* 85-90 */
+ u8 fac85; /* 85 */
+ u8 _reserved3[91 - 86]; /* 86-90 */
u8 flags; /* 91 */
u8 _reserved4[100 - 92]; /* 92-99 */
u32 rnsize2; /* 100-103 */
@@ -51,6 +53,7 @@ static int __initdata early_read_info_sccb_valid;
u64 sclp_facilities;
static u8 sclp_fac84;
+static u8 sclp_fac85;
static unsigned long long rzm;
static unsigned long long rnmax;
@@ -112,6 +115,7 @@ void __init sclp_facilities_detect(void)
sccb = &early_read_info_sccb;
sclp_facilities = sccb->facilities;
sclp_fac84 = sccb->fac84;
+ sclp_fac85 = sccb->fac85;
rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
rzm <<= 20;
@@ -127,6 +131,12 @@ unsigned long long sclp_get_rzm(void)
return rzm;
}
+u8 sclp_get_fac85(void)
+{
+ return sclp_fac85;
+}
+EXPORT_SYMBOL_GPL(sclp_get_fac85);
+
/*
* This function will be called after sclp_facilities_detect(), which gets
* called from early.c code. Therefore the sccb should have valid contents.
@@ -352,7 +362,17 @@ out:
static int sclp_assign_storage(u16 rn)
{
- return do_assign_storage(0x000d0001, rn);
+ unsigned long long start, address;
+ int rc;
+
+ rc = do_assign_storage(0x000d0001, rn);
+ if (rc)
+ goto out;
+ start = address = rn2addr(rn);
+ for (; address < start + rzm; address += PAGE_SIZE)
+ page_set_storage_key(address, PAGE_DEFAULT_KEY, 0);
+out:
+ return rc;
}
static int sclp_unassign_storage(u16 rn)
diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c
index 69e6c50d4cfb..50f7115990ff 100644
--- a/drivers/s390/char/sclp_sdias.c
+++ b/drivers/s390/char/sclp_sdias.c
@@ -211,7 +211,7 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
sccb.evbuf.event_qual = EQ_STORE_DATA;
sccb.evbuf.data_id = DI_FCP_DUMP;
sccb.evbuf.event_id = 4712;
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
sccb.evbuf.asa_size = ASA_SIZE_64;
#else
sccb.evbuf.asa_size = ASA_SIZE_32;
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 40a9d69c898e..e66a75b3822c 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -48,7 +48,7 @@ static struct sclp_buffer *sclp_ttybuf;
/* Timer for delayed output of console messages. */
static struct timer_list sclp_tty_timer;
-static struct tty_struct *sclp_tty;
+static struct tty_port sclp_port;
static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE];
static unsigned short int sclp_tty_chars_count;
@@ -64,7 +64,7 @@ static int sclp_tty_columns = 80;
static int
sclp_tty_open(struct tty_struct *tty, struct file *filp)
{
- sclp_tty = tty;
+ tty_port_tty_set(&sclp_port, tty);
tty->driver_data = NULL;
tty->low_latency = 0;
return 0;
@@ -76,7 +76,7 @@ sclp_tty_close(struct tty_struct *tty, struct file *filp)
{
if (tty->count > 1)
return;
- sclp_tty = NULL;
+ tty_port_tty_set(&sclp_port, NULL);
}
/*
@@ -108,6 +108,7 @@ sclp_tty_write_room (struct tty_struct *tty)
static void
sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
{
+ struct tty_struct *tty;
unsigned long flags;
void *page;
@@ -126,8 +127,10 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
spin_unlock_irqrestore(&sclp_tty_lock, flags);
} while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback));
/* check if the tty needs a wake up call */
- if (sclp_tty != NULL) {
- tty_wakeup(sclp_tty);
+ tty = tty_port_tty_get(&sclp_port);
+ if (tty != NULL) {
+ tty_wakeup(tty);
+ tty_kref_put(tty);
}
}
@@ -326,21 +329,22 @@ sclp_tty_flush_buffer(struct tty_struct *tty)
static void
sclp_tty_input(unsigned char* buf, unsigned int count)
{
+ struct tty_struct *tty = tty_port_tty_get(&sclp_port);
unsigned int cchar;
/*
* If this tty driver is currently closed
* then throw the received input away.
*/
- if (sclp_tty == NULL)
+ if (tty == NULL)
return;
- cchar = ctrlchar_handle(buf, count, sclp_tty);
+ cchar = ctrlchar_handle(buf, count, tty);
switch (cchar & CTRLCHAR_MASK) {
case CTRLCHAR_SYSRQ:
break;
case CTRLCHAR_CTRL:
- tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL);
- tty_flip_buffer_push(sclp_tty);
+ tty_insert_flip_char(tty, cchar, TTY_NORMAL);
+ tty_flip_buffer_push(tty);
break;
case CTRLCHAR_NONE:
/* send (normal) input to line discipline */
@@ -348,13 +352,14 @@ sclp_tty_input(unsigned char* buf, unsigned int count)
(strncmp((const char *) buf + count - 2, "^n", 2) &&
strncmp((const char *) buf + count - 2, "\252n", 2))) {
/* add the auto \n */
- tty_insert_flip_string(sclp_tty, buf, count);
- tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL);
+ tty_insert_flip_string(tty, buf, count);
+ tty_insert_flip_char(tty, '\n', TTY_NORMAL);
} else
- tty_insert_flip_string(sclp_tty, buf, count - 2);
- tty_flip_buffer_push(sclp_tty);
+ tty_insert_flip_string(tty, buf, count - 2);
+ tty_flip_buffer_push(tty);
break;
}
+ tty_kref_put(tty);
}
/*
@@ -543,7 +548,7 @@ sclp_tty_init(void)
sclp_tty_tolower = 1;
}
sclp_tty_chars_count = 0;
- sclp_tty = NULL;
+ tty_port_init(&sclp_port);
rc = sclp_register(&sclp_input_event);
if (rc) {
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index b635472ae660..edfc0fd73dc6 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -34,7 +34,6 @@
#define SCLP_VT220_DEVICE_NAME "ttysclp"
#define SCLP_VT220_CONSOLE_NAME "ttyS"
#define SCLP_VT220_CONSOLE_INDEX 1 /* console=ttyS1 */
-#define SCLP_VT220_BUF_SIZE 80
/* Representation of a single write request */
struct sclp_vt220_request {
@@ -56,8 +55,7 @@ struct sclp_vt220_sccb {
/* Structures and data needed to register tty driver */
static struct tty_driver *sclp_vt220_driver;
-/* The tty_struct that the kernel associated with us */
-static struct tty_struct *sclp_vt220_tty;
+static struct tty_port sclp_vt220_port;
/* Lock to protect internal data from concurrent access */
static spinlock_t sclp_vt220_lock;
@@ -116,6 +114,7 @@ static struct sclp_register sclp_vt220_register = {
static void
sclp_vt220_process_queue(struct sclp_vt220_request *request)
{
+ struct tty_struct *tty;
unsigned long flags;
void *page;
@@ -141,8 +140,10 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request)
if (request == NULL && sclp_vt220_flush_later)
sclp_vt220_emit_current();
/* Check if the tty needs a wake up call */
- if (sclp_vt220_tty != NULL) {
- tty_wakeup(sclp_vt220_tty);
+ tty = tty_port_tty_get(&sclp_vt220_port);
+ if (tty) {
+ tty_wakeup(tty);
+ tty_kref_put(tty);
}
}
@@ -460,11 +461,12 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count)
static void
sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
{
+ struct tty_struct *tty = tty_port_tty_get(&sclp_vt220_port);
char *buffer;
unsigned int count;
/* Ignore input if device is not open */
- if (sclp_vt220_tty == NULL)
+ if (tty == NULL)
return;
buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header));
@@ -478,10 +480,11 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
/* Send input to line discipline */
buffer++;
count--;
- tty_insert_flip_string(sclp_vt220_tty, buffer, count);
- tty_flip_buffer_push(sclp_vt220_tty);
+ tty_insert_flip_string(tty, buffer, count);
+ tty_flip_buffer_push(tty);
break;
}
+ tty_kref_put(tty);
}
/*
@@ -491,10 +494,7 @@ static int
sclp_vt220_open(struct tty_struct *tty, struct file *filp)
{
if (tty->count == 1) {
- sclp_vt220_tty = tty;
- tty->driver_data = kmalloc(SCLP_VT220_BUF_SIZE, GFP_KERNEL);
- if (tty->driver_data == NULL)
- return -ENOMEM;
+ tty_port_tty_set(&sclp_vt220_port, tty);
tty->low_latency = 0;
if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
tty->winsize.ws_row = 24;
@@ -510,11 +510,8 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp)
static void
sclp_vt220_close(struct tty_struct *tty, struct file *filp)
{
- if (tty->count == 1) {
- sclp_vt220_tty = NULL;
- kfree(tty->driver_data);
- tty->driver_data = NULL;
- }
+ if (tty->count == 1)
+ tty_port_tty_set(&sclp_vt220_port, NULL);
}
/*
@@ -635,9 +632,9 @@ static int __init __sclp_vt220_init(int num_pages)
INIT_LIST_HEAD(&sclp_vt220_empty);
INIT_LIST_HEAD(&sclp_vt220_outqueue);
init_timer(&sclp_vt220_timer);
+ tty_port_init(&sclp_vt220_port);
sclp_vt220_current_request = NULL;
sclp_vt220_buffered_chars = 0;
- sclp_vt220_tty = NULL;
sclp_vt220_flush_later = 0;
/* Allocate pages for output buffering */
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index 267b54e8ff5a..bc6c7cfd36b6 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -154,12 +154,6 @@ struct tape_discipline {
struct tape_request *(*read_block)(struct tape_device *, size_t);
struct tape_request *(*write_block)(struct tape_device *, size_t);
void (*process_eov)(struct tape_device*);
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Block device stuff. */
- struct tape_request *(*bread)(struct tape_device *, struct request *);
- void (*check_locate)(struct tape_device *, struct tape_request *);
- void (*free_bread)(struct tape_request *);
-#endif
/* ioctl function for additional ioctls. */
int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long);
/* Array of tape commands with TAPE_NR_MTOPS entries */
@@ -182,26 +176,6 @@ struct tape_char_data {
int block_size; /* of size block_size. */
};
-#ifdef CONFIG_S390_TAPE_BLOCK
-/* Block Frontend Data */
-struct tape_blk_data
-{
- struct tape_device * device;
- /* Block device request queue. */
- struct request_queue * request_queue;
- spinlock_t request_queue_lock;
-
- /* Task to move entries from block request to CCS request queue. */
- struct work_struct requeue_task;
- atomic_t requeue_scheduled;
-
- /* Current position on the tape. */
- long block_position;
- int medium_changed;
- struct gendisk * disk;
-};
-#endif
-
/* Tape Info */
struct tape_device {
/* entry in tape_device_list */
@@ -248,10 +222,6 @@ struct tape_device {
/* Character device frontend data */
struct tape_char_data char_data;
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Block dev frontend data */
- struct tape_blk_data blk_data;
-#endif
/* Function to start or stop the next request later. */
struct delayed_work tape_dnr;
@@ -313,19 +283,6 @@ extern void tapechar_exit(void);
extern int tapechar_setup_device(struct tape_device *);
extern void tapechar_cleanup_device(struct tape_device *);
-/* Externals from tape_block.c */
-#ifdef CONFIG_S390_TAPE_BLOCK
-extern int tapeblock_init (void);
-extern void tapeblock_exit(void);
-extern int tapeblock_setup_device(struct tape_device *);
-extern void tapeblock_cleanup_device(struct tape_device *);
-#else
-static inline int tapeblock_init (void) {return 0;}
-static inline void tapeblock_exit (void) {;}
-static inline int tapeblock_setup_device(struct tape_device *t) {return 0;}
-static inline void tapeblock_cleanup_device (struct tape_device *t) {;}
-#endif
-
/* tape initialisation functions */
#ifdef CONFIG_PROC_FS
extern void tape_proc_init (void);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 934ef33eb9a4..b28de80b7ca4 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -323,20 +323,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0;
sense = irb->ecw;
-#ifdef CONFIG_S390_TAPE_BLOCK
- if (request->op == TO_BLOCK) {
- /*
- * Recovery for block device requests. Set the block_position
- * to something invalid and retry.
- */
- device->blk_data.block_position = -1;
- if (request->retries-- <= 0)
- return tape_34xx_erp_failed(request, -EIO);
- else
- return tape_34xx_erp_retry(request);
- }
-#endif
-
if (
sense[0] & SENSE_COMMAND_REJECT &&
sense[1] & SENSE_WRITE_PROTECT
@@ -1129,123 +1115,6 @@ tape_34xx_mtseek(struct tape_device *device, int mt_count)
return tape_do_io_free(device, request);
}
-#ifdef CONFIG_S390_TAPE_BLOCK
-/*
- * Tape block read for 34xx.
- */
-static struct tape_request *
-tape_34xx_bread(struct tape_device *device, struct request *req)
-{
- struct tape_request *request;
- struct ccw1 *ccw;
- int count = 0;
- unsigned off;
- char *dst;
- struct bio_vec *bv;
- struct req_iterator iter;
- struct tape_34xx_block_id * start_block;
-
- DBF_EVENT(6, "xBREDid:");
-
- /* Count the number of blocks for the request. */
- rq_for_each_segment(bv, req, iter)
- count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9);
-
- /* Allocate the ccw request. */
- request = tape_alloc_request(3+count+1, 8);
- if (IS_ERR(request))
- return request;
-
- /* Setup ccws. */
- request->op = TO_BLOCK;
- start_block = (struct tape_34xx_block_id *) request->cpdata;
- start_block->block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B;
- DBF_EVENT(6, "start_block = %i\n", start_block->block);
-
- ccw = request->cpaddr;
- ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte);
-
- /*
- * We always setup a nop after the mode set ccw. This slot is
- * used in tape_std_check_locate to insert a locate ccw if the
- * current tape position doesn't match the start block to be read.
- * The second nop will be filled with a read block id which is in
- * turn used by tape_34xx_free_bread to populate the segment bid
- * table.
- */
- ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
- ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
-
- rq_for_each_segment(bv, req, iter) {
- dst = kmap(bv->bv_page) + bv->bv_offset;
- for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) {
- ccw->flags = CCW_FLAG_CC;
- ccw->cmd_code = READ_FORWARD;
- ccw->count = TAPEBLOCK_HSEC_SIZE;
- set_normalized_cda(ccw, (void*) __pa(dst));
- ccw++;
- dst += TAPEBLOCK_HSEC_SIZE;
- }
- }
-
- ccw = tape_ccw_end(ccw, NOP, 0, NULL);
- DBF_EVENT(6, "xBREDccwg\n");
- return request;
-}
-
-static void
-tape_34xx_free_bread (struct tape_request *request)
-{
- struct ccw1* ccw;
-
- ccw = request->cpaddr;
- if ((ccw + 2)->cmd_code == READ_BLOCK_ID) {
- struct {
- struct tape_34xx_block_id cbid;
- struct tape_34xx_block_id dbid;
- } __attribute__ ((packed)) *rbi_data;
-
- rbi_data = request->cpdata;
-
- if (request->device)
- tape_34xx_add_sbid(request->device, rbi_data->cbid);
- }
-
- /* Last ccw is a nop and doesn't need clear_normalized_cda */
- for (; ccw->flags & CCW_FLAG_CC; ccw++)
- if (ccw->cmd_code == READ_FORWARD)
- clear_normalized_cda(ccw);
- tape_free_request(request);
-}
-
-/*
- * check_locate is called just before the tape request is passed to
- * the common io layer for execution. It has to check the current
- * tape position and insert a locate ccw if it doesn't match the
- * start block for the request.
- */
-static void
-tape_34xx_check_locate(struct tape_device *device, struct tape_request *request)
-{
- struct tape_34xx_block_id * start_block;
-
- start_block = (struct tape_34xx_block_id *) request->cpdata;
- if (start_block->block == device->blk_data.block_position)
- return;
-
- DBF_LH(4, "Block seek(%06d+%06d)\n", start_block->block, device->bof);
- start_block->wrap = 0;
- start_block->segment = 1;
- start_block->format = (*device->modeset_byte & 0x08) ?
- TAPE34XX_FMT_3480_XF :
- TAPE34XX_FMT_3480;
- start_block->block = start_block->block + device->bof;
- tape_34xx_merge_sbid(device, start_block);
- tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);
- tape_ccw_cc(request->cpaddr + 2, READ_BLOCK_ID, 8, request->cpdata);
-}
-#endif
-
/*
* List of 3480/3490 magnetic tape commands.
*/
@@ -1295,11 +1164,6 @@ static struct tape_discipline tape_discipline_34xx = {
.irq = tape_34xx_irq,
.read_block = tape_std_read_block,
.write_block = tape_std_write_block,
-#ifdef CONFIG_S390_TAPE_BLOCK
- .bread = tape_34xx_bread,
- .free_bread = tape_34xx_free_bread,
- .check_locate = tape_34xx_check_locate,
-#endif
.ioctl_fn = tape_34xx_ioctl,
.mtop_array = tape_34xx_mtop
};
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 49c6aab7ad78..a5c6614b0db2 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -670,92 +670,6 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
return 0;
}
-#ifdef CONFIG_S390_TAPE_BLOCK
-/*
- * Tape Block READ
- */
-static struct tape_request *
-tape_3590_bread(struct tape_device *device, struct request *req)
-{
- struct tape_request *request;
- struct ccw1 *ccw;
- int count = 0, start_block;
- unsigned off;
- char *dst;
- struct bio_vec *bv;
- struct req_iterator iter;
-
- DBF_EVENT(6, "xBREDid:");
- start_block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B;
- DBF_EVENT(6, "start_block = %i\n", start_block);
-
- rq_for_each_segment(bv, req, iter)
- count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9);
-
- request = tape_alloc_request(2 + count + 1, 4);
- if (IS_ERR(request))
- return request;
- request->op = TO_BLOCK;
- *(__u32 *) request->cpdata = start_block;
- ccw = request->cpaddr;
- ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte);
-
- /*
- * We always setup a nop after the mode set ccw. This slot is
- * used in tape_std_check_locate to insert a locate ccw if the
- * current tape position doesn't match the start block to be read.
- */
- ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
-
- rq_for_each_segment(bv, req, iter) {
- dst = page_address(bv->bv_page) + bv->bv_offset;
- for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) {
- ccw->flags = CCW_FLAG_CC;
- ccw->cmd_code = READ_FORWARD;
- ccw->count = TAPEBLOCK_HSEC_SIZE;
- set_normalized_cda(ccw, (void *) __pa(dst));
- ccw++;
- dst += TAPEBLOCK_HSEC_SIZE;
- }
- BUG_ON(off > bv->bv_len);
- }
- ccw = tape_ccw_end(ccw, NOP, 0, NULL);
- DBF_EVENT(6, "xBREDccwg\n");
- return request;
-}
-
-static void
-tape_3590_free_bread(struct tape_request *request)
-{
- struct ccw1 *ccw;
-
- /* Last ccw is a nop and doesn't need clear_normalized_cda */
- for (ccw = request->cpaddr; ccw->flags & CCW_FLAG_CC; ccw++)
- if (ccw->cmd_code == READ_FORWARD)
- clear_normalized_cda(ccw);
- tape_free_request(request);
-}
-
-/*
- * check_locate is called just before the tape request is passed to
- * the common io layer for execution. It has to check the current
- * tape position and insert a locate ccw if it doesn't match the
- * start block for the request.
- */
-static void
-tape_3590_check_locate(struct tape_device *device, struct tape_request *request)
-{
- __u32 *start_block;
-
- start_block = (__u32 *) request->cpdata;
- if (*start_block != device->blk_data.block_position) {
- /* Add the start offset of the file to get the real block. */
- *start_block += device->bof;
- tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);
- }
-}
-#endif
-
static void tape_3590_med_state_set(struct tape_device *device,
struct tape_3590_med_sense *sense)
{
@@ -1423,20 +1337,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
{
struct tape_3590_sense *sense;
-#ifdef CONFIG_S390_TAPE_BLOCK
- if (request->op == TO_BLOCK) {
- /*
- * Recovery for block device requests. Set the block_position
- * to something invalid and retry.
- */
- device->blk_data.block_position = -1;
- if (request->retries-- <= 0)
- return tape_3590_erp_failed(device, request, irb, -EIO);
- else
- return tape_3590_erp_retry(device, request, irb);
- }
-#endif
-
sense = (struct tape_3590_sense *) irb->ecw;
DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc);
@@ -1729,11 +1629,6 @@ static struct tape_discipline tape_discipline_3590 = {
.irq = tape_3590_irq,
.read_block = tape_std_read_block,
.write_block = tape_std_write_block,
-#ifdef CONFIG_S390_TAPE_BLOCK
- .bread = tape_3590_bread,
- .free_bread = tape_3590_free_bread,
- .check_locate = tape_3590_check_locate,
-#endif
.ioctl_fn = tape_3590_ioctl,
.mtop_array = tape_3590_mtop
};
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 87cd0ab242de..46886a7578c6 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -161,11 +161,6 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
if (rc)
return rc;
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Changes position. */
- device->blk_data.medium_changed = 1;
-#endif
-
DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size);
/* Let the discipline build the ccw chain. */
request = device->discipline->read_block(device, block_size);
@@ -218,11 +213,6 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t
if (rc)
return rc;
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Changes position. */
- device->blk_data.medium_changed = 1;
-#endif
-
DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size);
DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks);
/* Let the discipline build the ccw chain. */
@@ -379,9 +369,6 @@ __tapechar_ioctl(struct tape_device *device,
case MTBSFM:
case MTFSFM:
case MTSEEK:
-#ifdef CONFIG_S390_TAPE_BLOCK
- device->blk_data.medium_changed = 1;
-#endif
if (device->required_tapemarks)
tape_std_terminate_write(device);
default:
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index b3a3e8e8656e..585618663ba4 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -401,9 +401,6 @@ tape_generic_online(struct tape_device *device,
rc = tapechar_setup_device(device);
if (rc)
goto out_minor;
- rc = tapeblock_setup_device(device);
- if (rc)
- goto out_char;
tape_state_set(device, TS_UNUSED);
@@ -411,8 +408,6 @@ tape_generic_online(struct tape_device *device,
return 0;
-out_char:
- tapechar_cleanup_device(device);
out_minor:
tape_remove_minor(device);
out_discipline:
@@ -426,7 +421,6 @@ out:
static void
tape_cleanup_device(struct tape_device *device)
{
- tapeblock_cleanup_device(device);
tapechar_cleanup_device(device);
device->discipline->cleanup_device(device);
module_put(device->discipline->owner);
@@ -785,10 +779,6 @@ __tape_start_io(struct tape_device *device, struct tape_request *request)
{
int rc;
-#ifdef CONFIG_S390_TAPE_BLOCK
- if (request->op == TO_BLOCK)
- device->discipline->check_locate(device, request);
-#endif
rc = ccw_device_start(
device->cdev,
request->cpaddr,
@@ -1253,7 +1243,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
}
/*
- * Tape device open function used by tape_char & tape_block frontends.
+ * Tape device open function used by tape_char frontend.
*/
int
tape_open(struct tape_device *device)
@@ -1283,7 +1273,7 @@ tape_open(struct tape_device *device)
}
/*
- * Tape device release function used by tape_char & tape_block frontends.
+ * Tape device release function used by tape_char frontend.
*/
int
tape_release(struct tape_device *device)
@@ -1344,7 +1334,6 @@ tape_init (void)
DBF_EVENT(3, "tape init\n");
tape_proc_init();
tapechar_init ();
- tapeblock_init ();
return 0;
}
@@ -1358,7 +1347,6 @@ tape_exit(void)
/* Get rid of the frontends */
tapechar_exit();
- tapeblock_exit();
tape_proc_cleanup();
debug_unregister (TAPE_DBF_AREA);
}
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index b43445a55cb6..10ec690197cb 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -61,7 +61,7 @@ struct tty3270_line {
*/
struct tty3270 {
struct raw3270_view view;
- struct tty_struct *tty; /* Pointer to tty structure */
+ struct tty_port port;
void **freemem_pages; /* Array of pages used for freemem. */
struct list_head freemem; /* List of free memory for strings. */
@@ -324,9 +324,8 @@ tty3270_blank_line(struct tty3270 *tp)
static void
tty3270_write_callback(struct raw3270_request *rq, void *data)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(rq->view, struct tty3270, view);
- tp = (struct tty3270 *) rq->view;
if (rq->rc != 0) {
/* Write wasn't successful. Refresh all. */
tp->update_flags = TTY_UPDATE_ALL;
@@ -450,10 +449,9 @@ tty3270_rcl_add(struct tty3270 *tp, char *input, int len)
static void
tty3270_rcl_backward(struct kbd_data *kbd)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
struct string *s;
- tp = kbd->tty->driver_data;
spin_lock_bh(&tp->view.lock);
if (tp->inattr == TF_INPUT) {
if (tp->rcl_walk && tp->rcl_walk->prev != &tp->rcl_lines)
@@ -478,9 +476,8 @@ tty3270_rcl_backward(struct kbd_data *kbd)
static void
tty3270_exit_tty(struct kbd_data *kbd)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
- tp = kbd->tty->driver_data;
raw3270_deactivate_view(&tp->view);
}
@@ -490,10 +487,9 @@ tty3270_exit_tty(struct kbd_data *kbd)
static void
tty3270_scroll_forward(struct kbd_data *kbd)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
int nr_up;
- tp = kbd->tty->driver_data;
spin_lock_bh(&tp->view.lock);
nr_up = tp->nr_up - tp->view.rows + 2;
if (nr_up < 0)
@@ -513,10 +509,9 @@ tty3270_scroll_forward(struct kbd_data *kbd)
static void
tty3270_scroll_backward(struct kbd_data *kbd)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
int nr_up;
- tp = kbd->tty->driver_data;
spin_lock_bh(&tp->view.lock);
nr_up = tp->nr_up + tp->view.rows - 2;
if (nr_up + tp->view.rows - 2 > tp->nr_lines)
@@ -537,11 +532,10 @@ static void
tty3270_read_tasklet(struct raw3270_request *rrq)
{
static char kreset_data = TW_KR;
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(rrq->view, struct tty3270, view);
char *input;
int len;
- tp = (struct tty3270 *) rrq->view;
spin_lock_bh(&tp->view.lock);
/*
* Two AID keys are special: For 0x7d (enter) the input line
@@ -577,13 +571,10 @@ tty3270_read_tasklet(struct raw3270_request *rrq)
raw3270_request_add_data(tp->kreset, &kreset_data, 1);
raw3270_start(&tp->view, tp->kreset);
- /* Emit input string. */
- if (tp->tty) {
- while (len-- > 0)
- kbd_keycode(tp->kbd, *input++);
- /* Emit keycode for AID byte. */
- kbd_keycode(tp->kbd, 256 + tp->input->string[0]);
- }
+ while (len-- > 0)
+ kbd_keycode(tp->kbd, *input++);
+ /* Emit keycode for AID byte. */
+ kbd_keycode(tp->kbd, 256 + tp->input->string[0]);
raw3270_request_reset(rrq);
xchg(&tp->read, rrq);
@@ -596,9 +587,10 @@ tty3270_read_tasklet(struct raw3270_request *rrq)
static void
tty3270_read_callback(struct raw3270_request *rq, void *data)
{
+ struct tty3270 *tp = container_of(rq->view, struct tty3270, view);
raw3270_get_view(rq->view);
/* Schedule tasklet to pass input to tty. */
- tasklet_schedule(&((struct tty3270 *) rq->view)->readlet);
+ tasklet_schedule(&tp->readlet);
}
/*
@@ -635,9 +627,8 @@ tty3270_issue_read(struct tty3270 *tp, int lock)
static int
tty3270_activate(struct raw3270_view *view)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(view, struct tty3270, view);
- tp = (struct tty3270 *) view;
tp->update_flags = TTY_UPDATE_ALL;
tty3270_set_timer(tp, 1);
return 0;
@@ -646,9 +637,8 @@ tty3270_activate(struct raw3270_view *view)
static void
tty3270_deactivate(struct raw3270_view *view)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = container_of(view, struct tty3270, view);
- tp = (struct tty3270 *) view;
del_timer(&tp->timer);
}
@@ -690,6 +680,17 @@ tty3270_alloc_view(void)
if (!tp->freemem_pages)
goto out_tp;
INIT_LIST_HEAD(&tp->freemem);
+ INIT_LIST_HEAD(&tp->lines);
+ INIT_LIST_HEAD(&tp->update);
+ INIT_LIST_HEAD(&tp->rcl_lines);
+ tp->rcl_max = 20;
+ tty_port_init(&tp->port);
+ setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
+ (unsigned long) tp);
+ tasklet_init(&tp->readlet,
+ (void (*)(unsigned long)) tty3270_read_tasklet,
+ (unsigned long) tp->read);
+
for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) {
tp->freemem_pages[pages] = (void *)
__get_free_pages(GFP_KERNEL|GFP_DMA, 0);
@@ -794,16 +795,15 @@ tty3270_free_screen(struct tty3270 *tp)
static void
tty3270_release(struct raw3270_view *view)
{
- struct tty3270 *tp;
- struct tty_struct *tty;
+ struct tty3270 *tp = container_of(view, struct tty3270, view);
+ struct tty_struct *tty = tty_port_tty_get(&tp->port);
- tp = (struct tty3270 *) view;
- tty = tp->tty;
if (tty) {
tty->driver_data = NULL;
- tp->tty = tp->kbd->tty = NULL;
+ tty_port_tty_set(&tp->port, NULL);
tty_hangup(tty);
raw3270_put_view(&tp->view);
+ tty_kref_put(tty);
}
}
@@ -813,8 +813,9 @@ tty3270_release(struct raw3270_view *view)
static void
tty3270_free(struct raw3270_view *view)
{
- tty3270_free_screen((struct tty3270 *) view);
- tty3270_free_view((struct tty3270 *) view);
+ struct tty3270 *tp = container_of(view, struct tty3270, view);
+ tty3270_free_screen(tp);
+ tty3270_free_view(tp);
}
/*
@@ -823,14 +824,13 @@ tty3270_free(struct raw3270_view *view)
static void
tty3270_del_views(void)
{
- struct tty3270 *tp;
int i;
for (i = 0; i < tty3270_max_index; i++) {
- tp = (struct tty3270 *)
+ struct raw3270_view *view =
raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
- if (!IS_ERR(tp))
- raw3270_del_view(&tp->view);
+ if (!IS_ERR(view))
+ raw3270_del_view(view);
}
}
@@ -848,22 +848,23 @@ static struct raw3270_fn tty3270_fn = {
static int
tty3270_open(struct tty_struct *tty, struct file * filp)
{
+ struct raw3270_view *view;
struct tty3270 *tp;
int i, rc;
if (tty->count > 1)
return 0;
/* Check if the tty3270 is already there. */
- tp = (struct tty3270 *)
- raw3270_find_view(&tty3270_fn,
+ view = raw3270_find_view(&tty3270_fn,
tty->index + RAW3270_FIRSTMINOR);
- if (!IS_ERR(tp)) {
+ if (!IS_ERR(view)) {
+ tp = container_of(view, struct tty3270, view);
tty->driver_data = tp;
tty->winsize.ws_row = tp->view.rows - 2;
tty->winsize.ws_col = tp->view.cols;
tty->low_latency = 0;
- tp->tty = tty;
- tp->kbd->tty = tty;
+ /* why to reassign? */
+ tty_port_tty_set(&tp->port, tty);
tp->inattr = TF_INPUT;
return 0;
}
@@ -871,7 +872,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
tty3270_max_index = tty->index + 1;
/* Quick exit if there is no device for tty->index. */
- if (PTR_ERR(tp) == -ENODEV)
+ if (PTR_ERR(view) == -ENODEV)
return -ENODEV;
/* Allocate tty3270 structure on first open. */
@@ -879,16 +880,6 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
if (IS_ERR(tp))
return PTR_ERR(tp);
- INIT_LIST_HEAD(&tp->lines);
- INIT_LIST_HEAD(&tp->update);
- INIT_LIST_HEAD(&tp->rcl_lines);
- tp->rcl_max = 20;
- setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
- (unsigned long) tp);
- tasklet_init(&tp->readlet,
- (void (*)(unsigned long)) tty3270_read_tasklet,
- (unsigned long) tp->read);
-
rc = raw3270_add_view(&tp->view, &tty3270_fn,
tty->index + RAW3270_FIRSTMINOR);
if (rc) {
@@ -903,7 +894,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
return rc;
}
- tp->tty = tty;
+ tty_port_tty_set(&tp->port, tty);
tty->low_latency = 0;
tty->driver_data = tp;
tty->winsize.ws_row = tp->view.rows - 2;
@@ -917,7 +908,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
for (i = 0; i < tp->view.rows - 2; i++)
tty3270_blank_line(tp);
- tp->kbd->tty = tty;
+ tp->kbd->port = &tp->port;
tp->kbd->fn_handler[KVAL(K_INCRCONSOLE)] = tty3270_exit_tty;
tp->kbd->fn_handler[KVAL(K_SCROLLBACK)] = tty3270_scroll_backward;
tp->kbd->fn_handler[KVAL(K_SCROLLFORW)] = tty3270_scroll_forward;
@@ -935,14 +926,13 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
static void
tty3270_close(struct tty_struct *tty, struct file * filp)
{
- struct tty3270 *tp;
+ struct tty3270 *tp = tty->driver_data;
if (tty->count > 1)
return;
- tp = (struct tty3270 *) tty->driver_data;
if (tp) {
tty->driver_data = NULL;
- tp->tty = tp->kbd->tty = NULL;
+ tty_port_tty_set(&tp->port, NULL);
raw3270_put_view(&tp->view);
}
}
@@ -1391,7 +1381,7 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
tty3270_lf(tp);
break;
case 'Z': /* Respond ID. */
- kbd_puts_queue(tp->tty, "\033[?6c");
+ kbd_puts_queue(&tp->port, "\033[?6c");
break;
case '7': /* Save cursor position. */
tp->saved_cx = tp->cx;
@@ -1437,11 +1427,11 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
tp->esc_state = ESnormal;
if (ch == 'n' && !tp->esc_ques) {
if (tp->esc_par[0] == 5) /* Status report. */
- kbd_puts_queue(tp->tty, "\033[0n");
+ kbd_puts_queue(&tp->port, "\033[0n");
else if (tp->esc_par[0] == 6) { /* Cursor report. */
char buf[40];
sprintf(buf, "\033[%d;%dR", tp->cy + 1, tp->cx + 1);
- kbd_puts_queue(tp->tty, buf);
+ kbd_puts_queue(&tp->port, buf);
}
return;
}
@@ -1513,12 +1503,13 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
* String write routine for 3270 ttys
*/
static void
-tty3270_do_write(struct tty3270 *tp, const unsigned char *buf, int count)
+tty3270_do_write(struct tty3270 *tp, struct tty_struct *tty,
+ const unsigned char *buf, int count)
{
int i_msg, i;
spin_lock_bh(&tp->view.lock);
- for (i_msg = 0; !tp->tty->stopped && i_msg < count; i_msg++) {
+ for (i_msg = 0; !tty->stopped && i_msg < count; i_msg++) {
if (tp->esc_state != 0) {
/* Continue escape sequence. */
tty3270_escape_sequence(tp, buf[i_msg]);
@@ -1595,10 +1586,10 @@ tty3270_write(struct tty_struct * tty,
if (!tp)
return 0;
if (tp->char_count > 0) {
- tty3270_do_write(tp, tp->char_buf, tp->char_count);
+ tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
tp->char_count = 0;
}
- tty3270_do_write(tp, buf, count);
+ tty3270_do_write(tp, tty, buf, count);
return count;
}
@@ -1629,7 +1620,7 @@ tty3270_flush_chars(struct tty_struct *tty)
if (!tp)
return;
if (tp->char_count > 0) {
- tty3270_do_write(tp, tp->char_buf, tp->char_count);
+ tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
tp->char_count = 0;
}
}