Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[pandora-kernel.git] / drivers / char / epca.c
index 86d290e..88fc24f 100644 (file)
@@ -199,8 +199,8 @@ static int pc_ioctl(struct tty_struct *, struct file *,
                     unsigned int, unsigned long);
 static int info_ioctl(struct tty_struct *, struct file *,
                     unsigned int, unsigned long);
-static void pc_set_termios(struct tty_struct *, struct termios *);
-static void do_softint(void *);
+static void pc_set_termios(struct tty_struct *, struct ktermios *);
+static void do_softint(struct work_struct *work);
 static void pc_stop(struct tty_struct *);
 static void pc_start(struct tty_struct *);
 static void pc_throttle(struct tty_struct * tty);
@@ -844,7 +844,6 @@ static void pc_flush_buffer(struct tty_struct *tty)
        fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0);
        memoff(ch);
        spin_unlock_irqrestore(&epca_lock, flags);
-       wake_up_interruptible(&tty->write_wait);
        tty_wakeup(tty);
 } /* End pc_flush_buffer */
 
@@ -1113,11 +1112,8 @@ static void __exit epca_module_exit(void)
                ch = card_ptr[crd];
                for (count = 0; count < bd->numports; count++, ch++) 
                { /* Begin for each port */
-                       if (ch) {
-                               if (ch->tty)
-                                       tty_hangup(ch->tty);
-                               kfree(ch->tmp_buf);
-                       }
+                       if (ch && ch->tty)
+                               tty_hangup(ch->tty);
                } /* End for each port */
        } /* End for each card */
        pci_unregister_driver (&epca_driver);
@@ -1125,7 +1121,7 @@ static void __exit epca_module_exit(void)
 
 module_exit(epca_module_exit);
 
-static struct tty_operations pc_ops = {
+static const struct tty_operations pc_ops = {
        .open = pc_open,
        .close = pc_close,
        .write = pc_write,
@@ -1160,6 +1156,7 @@ static int __init pc_init(void)
        int crd;
        struct board_info *bd;
        unsigned char board_id = 0;
+       int err = -ENOMEM;
 
        int pci_boards_found, pci_count;
 
@@ -1167,13 +1164,11 @@ static int __init pc_init(void)
 
        pc_driver = alloc_tty_driver(MAX_ALLOC);
        if (!pc_driver)
-               return -ENOMEM;
+               goto out1;
 
        pc_info = alloc_tty_driver(MAX_ALLOC);
-       if (!pc_info) {
-               put_tty_driver(pc_driver);
-               return -ENOMEM;
-       }
+       if (!pc_info)
+               goto out2;
 
        /* -----------------------------------------------------------------------
                If epca_setup has not been ran by LILO set num_cards to defaults; copy
@@ -1240,6 +1235,8 @@ static int __init pc_init(void)
        pc_driver->init_termios.c_oflag = 0;
        pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
        pc_driver->init_termios.c_lflag = 0;
+       pc_driver->init_termios.c_ispeed = 9600;
+       pc_driver->init_termios.c_ospeed = 9600;
        pc_driver->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(pc_driver, &pc_ops);
 
@@ -1254,6 +1251,8 @@ static int __init pc_init(void)
        pc_info->init_termios.c_oflag = 0;
        pc_info->init_termios.c_lflag = 0;
        pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
+       pc_info->init_termios.c_ispeed = 9600;
+       pc_info->init_termios.c_ospeed = 9600;
        pc_info->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(pc_info, &info_ops);
 
@@ -1373,11 +1372,17 @@ static int __init pc_init(void)
 
        } /* End for each card */
 
-       if (tty_register_driver(pc_driver))
-               panic("Couldn't register Digi PC/ driver");
+       err = tty_register_driver(pc_driver);
+       if (err) {
+               printk(KERN_ERR "Couldn't register Digi PC/ driver");
+               goto out3;
+       }
 
-       if (tty_register_driver(pc_info))
-               panic("Couldn't register Digi PC/ info ");
+       err = tty_register_driver(pc_info);
+       if (err) {
+               printk(KERN_ERR "Couldn't register Digi PC/ info ");
+               goto out4;
+       }
 
        /* -------------------------------------------------------------------
           Start up the poller to check for events on all enabled boards
@@ -1388,6 +1393,15 @@ static int __init pc_init(void)
        mod_timer(&epca_timer, jiffies + HZ/25);
        return 0;
 
+out4:
+       tty_unregister_driver(pc_driver);
+out3:
+       put_tty_driver(pc_info);
+out2:
+       put_tty_driver(pc_driver);
+out1:
+       return err;
+
 } /* End pc_init */
 
 /* ------------------ Begin post_fep_init  ---------------------- */
@@ -1494,7 +1508,7 @@ static void post_fep_init(unsigned int crd)
 
                ch->brdchan        = bc;
                ch->mailbox        = gd; 
-               INIT_WORK(&ch->tqueue, do_softint, ch);
+               INIT_WORK(&ch->tqueue, do_softint);
                ch->board          = &boards[crd];
 
                spin_lock_irqsave(&epca_lock, flags);
@@ -1635,16 +1649,6 @@ static void post_fep_init(unsigned int crd)
                init_waitqueue_head(&ch->close_wait);
 
                spin_unlock_irqrestore(&epca_lock, flags);
-
-               ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
-               if (!ch->tmp_buf) {
-                       printk(KERN_ERR "POST FEP INIT : kmalloc failed for port 0x%x\n",i);
-                       release_region((int)bd->port, 4);
-                       while(i-- > 0)
-                               kfree((ch--)->tmp_buf);
-                       return;
-               } else
-                       memset((void *)ch->tmp_buf,0,ch->txbufsize);
        } /* End for each port */
 
        printk(KERN_INFO 
@@ -1790,7 +1794,6 @@ static void doevent(int crd)
                                { /* Begin if LOWWAIT */
                                        ch->statusflags &= ~LOWWAIT;
                                        tty_wakeup(tty);
-                                       wake_up_interruptible(&tty->write_wait);
                                } /* End if LOWWAIT */
                        } else if (event & EMPTYTX_IND)  { /* Begin EMPTYTX_IND */
                                /* This event is generated by setup_empty_event */
@@ -1798,7 +1801,6 @@ static void doevent(int crd)
                                if (ch->statusflags & EMPTYWAIT)  { /* Begin if EMPTYWAIT */
                                        ch->statusflags &= ~EMPTYWAIT;
                                        tty_wakeup(tty);
-                                       wake_up_interruptible(&tty->write_wait);
                                } /* End if EMPTYWAIT */
                        } /* End EMPTYTX_IND */
                } /* End if valid tty */
@@ -1998,7 +2000,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
 { /* Begin epcaparam */
 
        unsigned int cmdHead;
-       struct termios *ts;
+       struct ktermios *ts;
        struct board_chan __iomem *bc;
        unsigned mval, hflow, cflag, iflag;
 
@@ -2113,7 +2115,7 @@ static void receive_data(struct channel *ch)
 { /* Begin receive_data */
 
        unchar *rptr;
-       struct termios *ts = NULL;
+       struct ktermios *ts = NULL;
        struct tty_struct *tty;
        struct board_chan __iomem *bc;
        int dataToRead, wrapgap, bytesAvailable;
@@ -2361,12 +2363,14 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
        switch (cmd) 
        { /* Begin switch cmd */
 
+#if 0  /* Handled by calling layer properly */
                case TCGETS:
-                       if (copy_to_user(argp, tty->termios, sizeof(struct termios)))
+                       if (copy_to_user(argp, tty->termios, sizeof(struct ktermios)))
                                return -EFAULT;
                        return 0;
                case TCGETA:
                        return get_termio(tty, argp);
+#endif
                case TCSBRK:    /* SVID version: non-zero arg --> no break */
                        retval = tty_check_change(tty);
                        if (retval)
@@ -2535,7 +2539,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
 
 /* --------------------- Begin pc_set_termios  ----------------------- */
 
-static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 { /* Begin pc_set_termios */
 
        struct channel *ch;
@@ -2565,9 +2569,9 @@ static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios)
 
 /* --------------------- Begin do_softint  ----------------------- */
 
-static void do_softint(void *private_)
+static void do_softint(struct work_struct *work)
 { /* Begin do_softint */
-       struct channel *ch = (struct channel *) private_;
+       struct channel *ch = container_of(work, struct channel, tqueue);
        /* Called in response to a modem change event */
        if (ch && ch->magic == EPCA_MAGIC)  { /* Begin EPCA_MAGIC */
                struct tty_struct *tty = ch->tty;