include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / char / hvc_console.c
index f2685b7..d3890e8 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -125,7 +126,7 @@ static struct hvc_struct *hvc_get_by_index(int index)
  * console interfaces but can still be used as a tty device.  This has to be
  * static because kmalloc will not work during early console init.
  */
-static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
+static const struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
 static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
        {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
 
@@ -146,7 +147,7 @@ static void hvc_console_print(struct console *co, const char *b,
                return;
 
        /* This console adapter was removed so it is not usable. */
-       if (vtermnos[index] < 0)
+       if (vtermnos[index] == -1)
                return;
 
        while (count > 0 || i > 0) {
@@ -247,7 +248,7 @@ static void destroy_hvc_struct(struct kref *kref)
  * vty adapters do NOT get an hvc_instantiate() callback since they
  * appear after early console init.
  */
-int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
+int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
 {
        struct hvc_struct *hp;
 
@@ -312,15 +313,15 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
        spin_lock_irqsave(&hp->lock, flags);
        /* Check and then increment for fast path open. */
        if (hp->count++ > 0) {
+               tty_kref_get(tty);
                spin_unlock_irqrestore(&hp->lock, flags);
                hvc_kick();
                return 0;
        } /* else count == 0 */
 
        tty->driver_data = hp;
-       tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */
 
-       hp->tty = tty;
+       hp->tty = tty_kref_get(tty);
 
        spin_unlock_irqrestore(&hp->lock, flags);
 
@@ -337,6 +338,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
                spin_lock_irqsave(&hp->lock, flags);
                hp->tty = NULL;
                spin_unlock_irqrestore(&hp->lock, flags);
+               tty_kref_put(tty);
                tty->driver_data = NULL;
                kref_put(&hp->kref, destroy_hvc_struct);
                printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -364,13 +366,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
                return;
 
        hp = tty->driver_data;
+
        spin_lock_irqsave(&hp->lock, flags);
+       tty_kref_get(tty);
 
        if (--hp->count == 0) {
                /* We are done with the tty pointer now. */
                hp->tty = NULL;
                spin_unlock_irqrestore(&hp->lock, flags);
 
+               /* Put the ref obtained in hvc_open() */
+               tty_kref_put(tty);
+
                if (hp->ops->notifier_del)
                        hp->ops->notifier_del(hp, hp->data);
 
@@ -390,6 +397,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
                spin_unlock_irqrestore(&hp->lock, flags);
        }
 
+       tty_kref_put(tty);
        kref_put(&hp->kref, destroy_hvc_struct);
 }
 
@@ -425,10 +433,11 @@ static void hvc_hangup(struct tty_struct *tty)
        spin_unlock_irqrestore(&hp->lock, flags);
 
        if (hp->ops->notifier_hangup)
-                       hp->ops->notifier_hangup(hp, hp->data);
+               hp->ops->notifier_hangup(hp, hp->data);
 
        while(temp_open_count) {
                --temp_open_count;
+               tty_kref_put(tty);
                kref_put(&hp->kref, destroy_hvc_struct);
        }
 }
@@ -517,8 +526,6 @@ static void hvc_set_winsz(struct work_struct *work)
        struct winsize ws;
 
        hp = container_of(work, struct hvc_struct, tty_resize);
-       if (!hp)
-               return;
 
        spin_lock_irqsave(&hp->lock, hvc_flags);
        if (!hp->tty) {
@@ -553,7 +560,7 @@ static int hvc_chars_in_buffer(struct tty_struct *tty)
        struct hvc_struct *hp = tty->driver_data;
 
        if (!hp)
-               return -1;
+               return 0;
        return hp->n_outbuf;
 }
 
@@ -595,7 +602,7 @@ int hvc_poll(struct hvc_struct *hp)
        }
 
        /* No tty attached, just skip */
-       tty = hp->tty;
+       tty = tty_kref_get(hp->tty);
        if (tty == NULL)
                goto bail;
 
@@ -675,13 +682,15 @@ int hvc_poll(struct hvc_struct *hp)
 
                tty_flip_buffer_push(tty);
        }
+       if (tty)
+               tty_kref_put(tty);
 
        return poll_mask;
 }
 EXPORT_SYMBOL_GPL(hvc_poll);
 
 /**
- * hvc_resize() - Update terminal window size information.
+ * __hvc_resize() - Update terminal window size information.
  * @hp:                HVC console pointer
  * @ws:                Terminal window size structure
  *
@@ -690,12 +699,12 @@ EXPORT_SYMBOL_GPL(hvc_poll);
  *
  * Locking:    Locking free; the function MUST be called holding hp->lock
  */
-void hvc_resize(struct hvc_struct *hp, struct winsize ws)
+void __hvc_resize(struct hvc_struct *hp, struct winsize ws)
 {
        hp->ws = ws;
        schedule_work(&hp->tty_resize);
 }
-EXPORT_SYMBOL_GPL(hvc_resize);
+EXPORT_SYMBOL_GPL(__hvc_resize);
 
 /*
  * This kthread is either polling or interrupt driven.  This is determined by
@@ -751,8 +760,9 @@ static const struct tty_operations hvc_ops = {
        .chars_in_buffer = hvc_chars_in_buffer,
 };
 
-struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
-                                       struct hv_ops *ops, int outbuf_size)
+struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
+                            const struct hv_ops *ops,
+                            int outbuf_size)
 {
        struct hvc_struct *hp;
        int i;
@@ -764,13 +774,11 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
                        return ERR_PTR(err);
        }
 
-       hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
+       hp = kzalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
                        GFP_KERNEL);
        if (!hp)
                return ERR_PTR(-ENOMEM);
 
-       memset(hp, 0x00, sizeof(*hp));
-
        hp->vtermno = vtermno;
        hp->data = data;
        hp->ops = ops;
@@ -811,7 +819,7 @@ int hvc_remove(struct hvc_struct *hp)
        struct tty_struct *tty;
 
        spin_lock_irqsave(&hp->lock, flags);
-       tty = hp->tty;
+       tty = tty_kref_get(hp->tty);
 
        if (hp->index < MAX_NR_HVC_CONSOLES)
                vtermnos[hp->index] = -1;
@@ -823,20 +831,21 @@ int hvc_remove(struct hvc_struct *hp)
        /*
         * We 'put' the instance that was grabbed when the kref instance
         * was initialized using kref_init().  Let the last holder of this
-        * kref cause it to be removed, which will probably be the tty_hangup
+        * kref cause it to be removed, which will probably be the tty_vhangup
         * below.
         */
        kref_put(&hp->kref, destroy_hvc_struct);
 
        /*
-        * This function call will auto chain call hvc_hangup.  The tty should
-        * always be valid at this time unless a simultaneous tty close already
-        * cleaned up the hvc_struct.
+        * This function call will auto chain call hvc_hangup.
         */
-       if (tty)
-               tty_hangup(tty);
+       if (tty) {
+               tty_vhangup(tty);
+               tty_kref_put(tty);
+       }
        return 0;
 }
+EXPORT_SYMBOL_GPL(hvc_remove);
 
 /* Driver initialization: called as soon as someone uses hvc_alloc(). */
 static int hvc_init(void)