fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / s390 / char / con3215.c
index 0e724c8..25b5d7a 100644 (file)
  *            Dan Morrison, IBM Corporation (dmorriso@cse.buffalo.edu)
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kdev_t.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/vt_kern.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
 
 #include <linux/slab.h>
 #include <linux/bootmem.h>
@@ -102,7 +103,7 @@ struct raw3215_info {
 /* array of 3215 devices structures */
 static struct raw3215_info *raw3215[NR_3215];
 /* spinlock to protect the raw3215 array */
-static spinlock_t raw3215_device_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(raw3215_device_lock);
 /* list of free request structures */
 static struct raw3215_req *raw3215_freelist;
 /* spinlock to protect free list */
@@ -298,14 +299,14 @@ raw3215_timeout(unsigned long __data)
        struct raw3215_info *raw = (struct raw3215_info *) __data;
        unsigned long flags;
 
-       spin_lock_irqsave(raw->lock, flags);
+       spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
        if (raw->flags & RAW3215_TIMER_RUNS) {
                del_timer(&raw->timer);
                raw->flags &= ~RAW3215_TIMER_RUNS;
                raw3215_mk_write_req(raw);
                raw3215_start_io(raw);
        }
-       spin_unlock_irqrestore(raw->lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 }
 
 /*
@@ -354,10 +355,10 @@ raw3215_tasklet(void *data)
        unsigned long flags;
 
        raw = (struct raw3215_info *) data;
-       spin_lock_irqsave(raw->lock, flags);
+       spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
        raw3215_mk_write_req(raw);
        raw3215_try_io(raw);
-       spin_unlock_irqrestore(raw->lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
        /* Check for pending message from raw3215_irq */
        if (raw->message != NULL) {
                printk(raw->message, raw->msg_dstat, raw->msg_cstat);
@@ -366,10 +367,7 @@ raw3215_tasklet(void *data)
        tty = raw->tty;
        if (tty != NULL &&
            RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
-               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                   tty->ldisc.write_wakeup)
-                       (tty->ldisc.write_wakeup)(tty);
-               wake_up_interruptible(&tty->write_wait);
+               tty_wakeup(tty);
        }
 }
 
@@ -435,8 +433,6 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                                if (count > slen)
                                        count = slen;
                        } else
-                       if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
-                               count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
                        EBCASC(raw->inbuf, count);
                        cchar = ctrlchar_handle(raw->inbuf, count, tty);
                        switch (cchar & CTRLCHAR_MASK) {
@@ -444,28 +440,20 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                                break;
 
                        case CTRLCHAR_CTRL:
-                               tty->flip.count++;
-                               *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                               *tty->flip.char_buf_ptr++ = cchar;
+                               tty_insert_flip_char(tty, cchar, TTY_NORMAL);
                                tty_flip_buffer_push(raw->tty);
                                break;
 
                        case CTRLCHAR_NONE:
-                               memcpy(tty->flip.char_buf_ptr,
-                                      raw->inbuf, count);
                                if (count < 2 ||
-                                   (strncmp(raw->inbuf+count-2, "^n", 2) &&
-                                   strncmp(raw->inbuf+count-2, "\252n", 2)) ) {
-                                       /* don't add the auto \n */
-                                       tty->flip.char_buf_ptr[count] = '\n';
-                                       memset(tty->flip.flag_buf_ptr,
-                                              TTY_NORMAL, count + 1);
+                                   (strncmp(raw->inbuf+count-2, "\252n", 2) &&
+                                    strncmp(raw->inbuf+count-2, "^n", 2)) ) {
+                                       /* add the auto \n */
+                                       raw->inbuf[count] = '\n';
                                        count++;
                                } else
-                                       count-=2;
-                               tty->flip.char_buf_ptr += count;
-                               tty->flip.flag_buf_ptr += count;
-                               tty->flip.count += count;
+                                       count -= 2;
+                               tty_insert_flip_string(tty, raw->inbuf, count);
                                tty_flip_buffer_push(raw->tty);
                                break;
                        }
@@ -524,9 +512,9 @@ raw3215_make_room(struct raw3215_info *raw, unsigned int length)
                if (RAW3215_BUFFER_SIZE - raw->count >= length)
                        break;
                /* there might be another cpu waiting for the lock */
-               spin_unlock(raw->lock);
+               spin_unlock(get_ccwdev_lock(raw->cdev));
                udelay(100);
-               spin_lock(raw->lock);
+               spin_lock(get_ccwdev_lock(raw->cdev));
        }
 }
 
@@ -540,7 +528,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
        int c, count;
 
        while (length > 0) {
-               spin_lock_irqsave(raw->lock, flags);
+               spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
                count = (length > RAW3215_BUFFER_SIZE) ?
                                             RAW3215_BUFFER_SIZE : length;
                length -= count;
@@ -567,7 +555,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
                        /* start or queue request */
                        raw3215_try_io(raw);
                }
-               spin_unlock_irqrestore(raw->lock, flags);
+               spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
        }
 }
 
@@ -580,7 +568,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
        unsigned long flags;
        unsigned int length, i;
 
-       spin_lock_irqsave(raw->lock, flags);
+       spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
        if (ch == '\t') {
                length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE);
                raw->line_pos += length;
@@ -604,7 +592,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
                /* start or queue request */
                raw3215_try_io(raw);
        }
-       spin_unlock_irqrestore(raw->lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 }
 
 /*
@@ -616,13 +604,13 @@ raw3215_flush_buffer(struct raw3215_info *raw)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(raw->lock, flags);
+       spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
        if (raw->count > 0) {
                raw->flags |= RAW3215_FLUSHING;
                raw3215_try_io(raw);
                raw->flags &= ~RAW3215_FLUSHING;
        }
-       spin_unlock_irqrestore(raw->lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 }
 
 /*
@@ -637,9 +625,9 @@ raw3215_startup(struct raw3215_info *raw)
                return 0;
        raw->line_pos = 0;
        raw->flags |= RAW3215_ACTIVE;
-       spin_lock_irqsave(raw->lock, flags);
+       spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
        raw3215_try_io(raw);
-       spin_unlock_irqrestore(raw->lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 
        return 0;
 }
@@ -656,21 +644,21 @@ raw3215_shutdown(struct raw3215_info *raw)
        if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
                return;
        /* Wait for outstanding requests, then free irq */
-       spin_lock_irqsave(raw->lock, flags);
+       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;
                add_wait_queue(&raw->empty_wait, &wait);
                set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(raw->lock, flags);
+               spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
                schedule();
-               spin_lock_irqsave(raw->lock, flags);
+               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);
        }
-       spin_unlock_irqrestore(raw->lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 }
 
 static int
@@ -698,14 +686,13 @@ raw3215_probe (struct ccw_device *cdev)
        }
 
        raw->cdev = cdev;
-       raw->lock = get_ccwdev_lock(cdev);
        raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
        memset(raw, 0, sizeof(struct raw3215_info));
-       raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
+       raw->buffer = kmalloc(RAW3215_BUFFER_SIZE,
                                       GFP_KERNEL|GFP_DMA);
        if (raw->buffer == NULL) {
                spin_lock(&raw3215_device_lock);
-               raw3215[line] = 0;
+               raw3215[line] = NULL;
                spin_unlock(&raw3215_device_lock);
                kfree(raw);
                return -ENOMEM;
@@ -730,8 +717,7 @@ raw3215_remove (struct ccw_device *cdev)
        raw = cdev->dev.driver_data;
        if (raw) {
                cdev->dev.driver_data = NULL;
-               if (raw->buffer)
-                       kfree(raw->buffer);
+               kfree(raw->buffer);
                kfree(raw);
        }
 }
@@ -822,9 +808,9 @@ con3215_unblank(void)
        unsigned long flags;
 
        raw = raw3215[0];  /* console 3215 is the first one */
-       spin_lock_irqsave(raw->lock, flags);
+       spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
        raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
-       spin_unlock_irqrestore(raw->lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 }
 
 static int __init 
@@ -863,8 +849,8 @@ con3215_init(void)
 
        /* Set the console mode for VM */
        if (MACHINE_IS_VM) {
-               cpcmd("TERM CONMODE 3215", NULL, 0);
-               cpcmd("TERM AUTOCR OFF", NULL, 0);
+               cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
+               cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
        }
 
        /* allocate 3215 request structures */
@@ -877,7 +863,7 @@ con3215_init(void)
        }
 
        cdev = ccw_device_probe_console();
-       if (!cdev)
+       if (IS_ERR(cdev))
                return -ENODEV;
 
        raw3215[0] = raw = (struct raw3215_info *)
@@ -886,7 +872,6 @@ con3215_init(void)
        raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE);
        raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
        raw->cdev = cdev;
-       raw->lock = get_ccwdev_lock(cdev);
        cdev->dev.driver_data = raw;
        cdev->handler = raw3215_irq;
 
@@ -986,34 +971,16 @@ tty3215_write_room(struct tty_struct *tty)
  * String write routine for 3215 ttys
  */
 static int
-tty3215_write(struct tty_struct * tty, int from_user,
+tty3215_write(struct tty_struct * tty,
              const unsigned char *buf, int count)
 {
        struct raw3215_info *raw;
-       int length, ret;
 
        if (!tty)
                return 0;
        raw = (struct raw3215_info *) tty->driver_data;
-       if (!from_user) {
-               raw3215_write(raw, buf, count);
-               return count;
-       }
-       ret = 0;
-       while (count > 0) {
-               length = count < 80 ? count : 80;
-               length -= copy_from_user(raw->ubuffer, buf, length);
-               if (length == 0) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               raw3215_write(raw, raw->ubuffer, count);
-               buf += length;
-               count -= length;
-               ret += length;
-       }
-       return ret;
+       raw3215_write(raw, buf, count);
+       return count;
 }
 
 /*
@@ -1054,10 +1021,7 @@ tty3215_flush_buffer(struct tty_struct *tty)
 
        raw = (struct raw3215_info *) tty->driver_data;
        raw3215_flush_buffer(raw);
-       wake_up_interruptible(&tty->write_wait);
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-           tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup)(tty);
+       tty_wakeup(tty);
 }
 
 /*
@@ -1100,10 +1064,10 @@ tty3215_unthrottle(struct tty_struct * tty)
 
        raw = (struct raw3215_info *) tty->driver_data;
        if (raw->flags & RAW3215_THROTTLED) {
-               spin_lock_irqsave(raw->lock, flags);
+               spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
                raw->flags &= ~RAW3215_THROTTLED;
                raw3215_try_io(raw);
-               spin_unlock_irqrestore(raw->lock, flags);
+               spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
        }
 }
 
@@ -1130,14 +1094,14 @@ tty3215_start(struct tty_struct *tty)
 
        raw = (struct raw3215_info *) tty->driver_data;
        if (raw->flags & RAW3215_STOPPED) {
-               spin_lock_irqsave(raw->lock, flags);
+               spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
                raw->flags &= ~RAW3215_STOPPED;
                raw3215_try_io(raw);
-               spin_unlock_irqrestore(raw->lock, flags);
+               spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
        }
 }
 
-static struct tty_operations tty3215_ops = {
+static const struct tty_operations tty3215_ops = {
        .open = tty3215_open,
        .close = tty3215_close,
        .write = tty3215_write,