fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / irda / ircomm / ircomm_tty.c
index 6b9ae8c..262bda8 100644 (file)
@@ -30,7 +30,6 @@
  *     
  ********************************************************************/
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/fs.h>
@@ -52,7 +51,7 @@
 
 static int  ircomm_tty_open(struct tty_struct *tty, struct file *filp);
 static void ircomm_tty_close(struct tty_struct * tty, struct file *filp);
-static int  ircomm_tty_write(struct tty_struct * tty, int from_user,
+static int  ircomm_tty_write(struct tty_struct * tty,
                             const unsigned char *buf, int count);
 static int  ircomm_tty_write_room(struct tty_struct *tty);
 static void ircomm_tty_throttle(struct tty_struct *tty);
@@ -62,8 +61,9 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty);
 static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch);
 static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout);
 static void ircomm_tty_hangup(struct tty_struct *tty);
-static void ircomm_tty_do_softint(void *private_);
+static void ircomm_tty_do_softint(struct work_struct *work);
 static void ircomm_tty_shutdown(struct ircomm_tty_cb *self);
+static void ircomm_tty_stop(struct tty_struct *tty);
 
 static int ircomm_tty_data_indication(void *instance, void *sap,
                                      struct sk_buff *skb);
@@ -79,7 +79,7 @@ static struct tty_driver *driver;
 
 hashbin_t *ircomm_tty = NULL;
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
        .open            = ircomm_tty_open,
        .close           = ircomm_tty_close,
        .write           = ircomm_tty_write,
@@ -108,14 +108,14 @@ static struct tty_operations ops = {
  *    Init IrCOMM TTY layer/driver
  *
  */
-int __init ircomm_tty_init(void)
+static int __init ircomm_tty_init(void)
 {
        driver = alloc_tty_driver(IRCOMM_TTY_PORTS);
        if (!driver)
                return -ENOMEM;
        ircomm_tty = hashbin_new(HB_LOCK); 
        if (ircomm_tty == NULL) {
-               ERROR("%s(), can't allocate hashbin!\n", __FUNCTION__);
+               IRDA_ERROR("%s(), can't allocate hashbin!\n", __FUNCTION__);
                put_tty_driver(driver);
                return -ENOMEM;
        }
@@ -123,7 +123,6 @@ int __init ircomm_tty_init(void)
        driver->owner           = THIS_MODULE;
        driver->driver_name     = "ircomm";
        driver->name            = "ircomm";
-       driver->devfs_name      = "ircomm";
        driver->major           = IRCOMM_TTY_MAJOR;
        driver->minor_start     = IRCOMM_TTY_MINOR;
        driver->type            = TTY_DRIVER_TYPE_SERIAL;
@@ -133,7 +132,8 @@ int __init ircomm_tty_init(void)
        driver->flags           = TTY_DRIVER_REAL_RAW;
        tty_set_operations(driver, &ops);
        if (tty_register_driver(driver)) {
-               ERROR("%s(): Couldn't register serial driver\n", __FUNCTION__);
+               IRDA_ERROR("%s(): Couldn't register serial driver\n",
+                          __FUNCTION__);
                put_tty_driver(driver);
                return -1;
        }
@@ -144,8 +144,8 @@ static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self)
 {
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        ircomm_tty_shutdown(self);
 
@@ -159,7 +159,7 @@ static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self)
  *    Remove IrCOMM TTY layer/driver
  *
  */
-void __exit ircomm_tty_cleanup(void)
+static void __exit ircomm_tty_cleanup(void)
 {
        int ret;
 
@@ -167,7 +167,8 @@ void __exit ircomm_tty_cleanup(void)
 
        ret = tty_unregister_driver(driver);
         if (ret) {
-                ERROR("%s(), failed to unregister driver\n", __FUNCTION__);
+                IRDA_ERROR("%s(), failed to unregister driver\n",
+                          __FUNCTION__);
                return;
        }
 
@@ -188,8 +189,8 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
-       ASSERT(self != NULL, return -1;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+       IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
        /* Check if already open */
        if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) {
@@ -223,7 +224,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
        /* Connect IrCOMM link with remote device */
        ret = ircomm_tty_attach_cable(self);
        if (ret < 0) {
-               ERROR("%s(), error attaching cable!\n", __FUNCTION__);
+               IRDA_ERROR("%s(), error attaching cable!\n", __FUNCTION__);
                goto err;
        }
 
@@ -378,18 +379,17 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
        self = hashbin_lock_find(ircomm_tty, line, NULL);
        if (!self) {
                /* No, so make new instance */
-               self = kmalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
+               self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
                if (self == NULL) {
-                       ERROR("%s(), kmalloc failed!\n", __FUNCTION__);
+                       IRDA_ERROR("%s(), kmalloc failed!\n", __FUNCTION__);
                        return -ENOMEM;
                }
-               memset(self, 0, sizeof(struct ircomm_tty_cb));
                
                self->magic = IRCOMM_TTY_MAGIC;
                self->flow = FLOW_STOP;
 
                self->line = line;
-               INIT_WORK(&self->tqueue, ircomm_tty_do_softint, self);
+               INIT_WORK(&self->tqueue, ircomm_tty_do_softint);
                self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
                self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;
                self->close_delay = 5*HZ/10;
@@ -441,8 +441,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
                 */
 
                if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) {
-                       WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
-                               __FUNCTION__);
+                       IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
+                                    __FUNCTION__);
                        return -ERESTARTSYS;
                }
 
@@ -498,8 +498,8 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
        if (!tty)
                return;
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        spin_lock_irqsave(&self->spinlock, flags);
 
@@ -525,8 +525,8 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
        }
 
        if (--self->open_count < 0) {
-               ERROR("%s(), bad serial port count for ttys%d: %d\n",
-                     __FUNCTION__, self->line, self->open_count);
+               IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
+                          __FUNCTION__, self->line, self->open_count);
                self->open_count = 0;
        }
        if (self->open_count) {
@@ -561,13 +561,11 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
                tty->ldisc.flush_buffer(tty);
 
        tty->closing = 0;
-       self->tty = 0;
+       self->tty = NULL;
 
        if (self->blocked_open) {
-               if (self->close_delay) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(self->close_delay);
-               }
+               if (self->close_delay)
+                       schedule_timeout_interruptible(self->close_delay);
                wake_up_interruptible(&self->open_wait);
        }
 
@@ -585,8 +583,8 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        /* 
         * Let do_softint() do this to avoid race condition with 
@@ -596,15 +594,16 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty)
 }
 
 /*
- * Function ircomm_tty_do_softint (private_)
+ * Function ircomm_tty_do_softint (work)
  *
  *    We use this routine to give the write wakeup to the user at at a
  *    safe time (as fast as possible after write have completed). This 
  *    can be compared to the Tx interrupt.
  */
-static void ircomm_tty_do_softint(void *private_)
+static void ircomm_tty_do_softint(struct work_struct *work)
 {
-       struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_;
+       struct ircomm_tty_cb *self =
+               container_of(work, struct ircomm_tty_cb, tqueue);
        struct tty_struct *tty;
        unsigned long flags;
        struct sk_buff *skb, *ctrl_skb;
@@ -662,18 +661,17 @@ static void ircomm_tty_do_softint(void *private_)
 }
 
 /*
- * Function ircomm_tty_write (tty, from_user, buf, count)
+ * Function ircomm_tty_write (tty, buf, count)
  *
  *    This routine is called by the kernel to write a series of characters
  *    to the tty device. The characters may come from user space or kernel
  *    space. This routine will return the number of characters actually
  *    accepted for writing. This routine is mandatory.
  */
-static int ircomm_tty_write(struct tty_struct *tty, int from_user,
-                           const unsigned char *ubuf, int count)
+static int ircomm_tty_write(struct tty_struct *tty,
+                           const unsigned char *buf, int count)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
-       unsigned char *kbuf;            /* Buffer in kernel space */
        unsigned long flags;
        struct sk_buff *skb;
        int tailroom = 0;
@@ -683,8 +681,8 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
        IRDA_DEBUG(2, "%s(), count=%d, hw_stopped=%d\n", __FUNCTION__ , count,
                   tty->hw_stopped);
 
-       ASSERT(self != NULL, return -1;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+       IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
        /* We may receive packets from the TTY even before we have finished
         * our setup. Not cool.
@@ -713,20 +711,6 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
        if (count < 1)
                return 0;
 
-       /* Additional copy to avoid copy_from_user() under spinlock.
-        * We tradeoff this extra copy to allow to pack more the
-        * IrCOMM frames. This is advantageous because the IrDA link
-        * is the bottleneck. */
-       if (from_user) {
-               kbuf = kmalloc(count, GFP_KERNEL);
-               if (kbuf == NULL)
-                       return -ENOMEM;
-               if (copy_from_user(kbuf, ubuf, count))
-                       return -EFAULT;
-       } else
-               /* The buffer is already in kernel space */
-               kbuf = (unsigned char *) ubuf;
-
        /* Protect our manipulation of self->tx_skb and related */
        spin_lock_irqsave(&self->spinlock, flags);
 
@@ -775,8 +759,9 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
                        }
                } else {
                        /* Prepare a full sized frame */
-                       skb = dev_alloc_skb(self->max_data_size+
-                                           self->max_header_size);
+                       skb = alloc_skb(self->max_data_size+
+                                       self->max_header_size,
+                                       GFP_ATOMIC);
                        if (!skb) {
                                spin_unlock_irqrestore(&self->spinlock, flags);
                                return -ENOBUFS;
@@ -789,7 +774,7 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
                }
 
                /* Copy data */
-               memcpy(skb_put(skb,size), kbuf + len, size);
+               memcpy(skb_put(skb,size), buf + len, size);
 
                count -= size;
                len += size;
@@ -797,9 +782,6 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
 
        spin_unlock_irqrestore(&self->spinlock, flags);
 
-       if (from_user)
-               kfree(kbuf);
-
        /*     
         * Schedule a new thread which will transmit the frame as soon
         * as possible, but at a safe point in time. We do this so the
@@ -825,8 +807,8 @@ static int ircomm_tty_write_room(struct tty_struct *tty)
        unsigned long flags;
        int ret;
 
-       ASSERT(self != NULL, return -1;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+       IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
 #ifdef IRCOMM_NO_TX_BEFORE_INIT
        /* max_header_size tells us if the channel is initialised or not. */
@@ -867,19 +849,18 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
        
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        orig_jiffies = jiffies;
 
        /* Set poll time to 200 ms */
-       poll_time = IRDA_MIN(timeout, MSECS_TO_JIFFIES(200));
+       poll_time = IRDA_MIN(timeout, msecs_to_jiffies(200));
 
        spin_lock_irqsave(&self->spinlock, flags);
        while (self->tx_skb && self->tx_skb->len) {
                spin_unlock_irqrestore(&self->spinlock, flags);
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(poll_time);
+               schedule_timeout_interruptible(poll_time);
                spin_lock_irqsave(&self->spinlock, flags);
                if (signal_pending(current))
                        break;
@@ -903,8 +884,8 @@ static void ircomm_tty_throttle(struct tty_struct *tty)
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        /* Software flow control? */
        if (I_IXOFF(tty))
@@ -934,8 +915,8 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty)
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        /* Using software flow control? */
        if (I_IXOFF(tty)) {
@@ -964,8 +945,8 @@ static int ircomm_tty_chars_in_buffer(struct tty_struct *tty)
        unsigned long flags;
        int len = 0;
 
-       ASSERT(self != NULL, return -1;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+       IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
        spin_lock_irqsave(&self->spinlock, flags);
 
@@ -981,8 +962,8 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
 {
        unsigned long flags;
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
@@ -1029,8 +1010,8 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        if (!tty)
                return;
@@ -1041,7 +1022,7 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
        /* I guess we need to lock here - Jean II */
        spin_lock_irqsave(&self->spinlock, flags);
        self->flags &= ~ASYNC_NORMAL_ACTIVE;
-       self->tty = 0;
+       self->tty = NULL;
        self->open_count = 0;
        spin_unlock_irqrestore(&self->spinlock, flags);
 
@@ -1078,12 +1059,12 @@ void ircomm_tty_start(struct tty_struct *tty)
  *     This routine notifies the tty driver that it should stop outputting
  *     characters to the tty device. 
  */
-void ircomm_tty_stop(struct tty_struct *tty) 
+static void ircomm_tty_stop(struct tty_struct *tty) 
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        ircomm_flow_request(self->ircomm, FLOW_STOP);
 }
@@ -1102,8 +1083,8 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        tty = self->tty;
 
@@ -1165,9 +1146,9 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
        
-       ASSERT(self != NULL, return -1;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
-       ASSERT(skb != NULL, return -1;);
+       IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+       IRDA_ASSERT(skb != NULL, return -1;);
 
        if (!self->tty) {
                IRDA_DEBUG(0, "%s(), no tty!\n", __FUNCTION__ );
@@ -1215,9 +1196,9 @@ static int ircomm_tty_control_indication(void *instance, void *sap,
 
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
        
-       ASSERT(self != NULL, return -1;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
-       ASSERT(skb != NULL, return -1;);
+       IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+       IRDA_ASSERT(skb != NULL, return -1;);
 
        clen = skb->data[0];
 
@@ -1242,8 +1223,8 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
        struct tty_struct *tty;
 
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       IRDA_ASSERT(self != NULL, return;);
+       IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        tty = self->tty;