]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/isicom.c
autofs4: cleanup autofs mount type usage
[linux-2.6-omap-h63xx.git] / drivers / char / isicom.c
index d4281df10c22dbd54a28f790774c7636126cd709..7d30ee1d3fca9de33cb5e23790fd6df96c791e05 100644 (file)
@@ -421,17 +421,16 @@ static void isicom_tx(unsigned long _data)
        if (retries >= 100)
                goto unlock;
 
+       tty = tty_port_tty_get(&port->port);
+       if (tty == NULL)
+               goto put_unlock;
+
        for (; count > 0; count--, port++) {
                /* port not active or tx disabled to force flow control */
                if (!(port->port.flags & ASYNC_INITIALIZED) ||
                                !(port->status & ISI_TXOK))
                        continue;
 
-               tty = port->port.tty;
-
-               if (tty == NULL)
-                       continue;
-
                txcount = min_t(short, TX_SIZE, port->xmit_cnt);
                if (txcount <= 0 || tty->stopped || tty->hw_stopped)
                        continue;
@@ -489,6 +488,8 @@ static void isicom_tx(unsigned long _data)
                        tty_wakeup(tty);
        }
 
+put_unlock:
+       tty_kref_put(tty);
 unlock:
        spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
        /*      schedule another tx for hopefully in about 10ms */
@@ -547,7 +548,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
                return IRQ_HANDLED;
        }
 
-       tty = port->port.tty;
+       tty = tty_port_tty_get(&port->port);
        if (tty == NULL) {
                word_count = byte_count >> 1;
                while (byte_count > 1) {
@@ -588,7 +589,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
                        }
 
                        if (port->port.flags & ASYNC_CTS_FLOW) {
-                               if (port->port.tty->hw_stopped) {
+                               if (tty->hw_stopped) {
                                        if (header & ISI_CTS) {
                                                port->port.tty->hw_stopped = 0;
                                                /* start tx ing */
@@ -597,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
                                                tty_wakeup(tty);
                                        }
                                } else if (!(header & ISI_CTS)) {
-                                       port->port.tty->hw_stopped = 1;
+                                       tty->hw_stopped = 1;
                                        /* stop tx ing */
                                        port->status &= ~(ISI_TXOK | ISI_CTS);
                                }
@@ -660,24 +661,21 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
        }
        outw(0x0000, base+0x04); /* enable interrupts */
        spin_unlock(&card->card_lock);
+       tty_kref_put(tty);
 
        return IRQ_HANDLED;
 }
 
-static void isicom_config_port(struct isi_port *port)
+static void isicom_config_port(struct tty_struct *tty)
 {
+       struct isi_port *port = tty->driver_data;
        struct isi_board *card = port->card;
-       struct tty_struct *tty;
        unsigned long baud;
        unsigned long base = card->base;
        u16 channel_setup, channel = port->channel,
                shift_count = card->shift_count;
        unsigned char flow_ctrl;
 
-       tty = port->port.tty;
-
-       if (tty == NULL)
-               return;
        /* FIXME: Switch to new tty baud API */
        baud = C_BAUD(tty);
        if (baud & CBAUDEX) {
@@ -690,7 +688,7 @@ static void isicom_config_port(struct isi_port *port)
 
                /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
                if (baud < 1 || baud > 4)
-                       port->port.tty->termios->c_cflag &= ~CBAUDEX;
+                       tty->termios->c_cflag &= ~CBAUDEX;
                else
                        baud += 15;
        }
@@ -797,8 +795,9 @@ static inline void isicom_setup_board(struct isi_board *bp)
        spin_unlock_irqrestore(&bp->card_lock, flags);
 }
 
-static int isicom_setup_port(struct isi_port *port)
+static int isicom_setup_port(struct tty_struct *tty)
 {
+       struct isi_port *port = tty->driver_data;
        struct isi_board *card = port->card;
        unsigned long flags;
 
@@ -808,8 +807,7 @@ static int isicom_setup_port(struct isi_port *port)
                return -ENOMEM;
 
        spin_lock_irqsave(&card->card_lock, flags);
-       if (port->port.tty)
-               clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
+       clear_bit(TTY_IO_ERROR, &tty->flags);
        if (port->port.count == 1)
                card->count++;
 
@@ -823,7 +821,7 @@ static int isicom_setup_port(struct isi_port *port)
                InterruptTheCard(card->base);
        }
 
-       isicom_config_port(port);
+       isicom_config_port(tty);
        port->port.flags |= ASYNC_INITIALIZED;
        spin_unlock_irqrestore(&card->card_lock, flags);
 
@@ -934,8 +932,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
 
        port->port.count++;
        tty->driver_data = port;
-       port->port.tty = tty;
-       error = isicom_setup_port(port);
+       tty_port_tty_set(&port->port, tty);
+       error = isicom_setup_port(tty);
        if (error == 0)
                error = block_til_ready(tty, filp, port);
        return error;
@@ -955,15 +953,17 @@ static void isicom_shutdown_port(struct isi_port *port)
        struct isi_board *card = port->card;
        struct tty_struct *tty;
 
-       tty = port->port.tty;
+       tty = tty_port_tty_get(&port->port);
 
-       if (!(port->port.flags & ASYNC_INITIALIZED))
+       if (!(port->port.flags & ASYNC_INITIALIZED)) {
+               tty_kref_put(tty);
                return;
+       }
 
        tty_port_free_xmit_buf(&port->port);
        port->port.flags &= ~ASYNC_INITIALIZED;
        /* 3rd October 2000 : Vinayak P Risbud */
-       port->port.tty = NULL;
+       tty_port_tty_set(&port->port, NULL);
 
        /*Fix done by Anil .S on 30-04-2001
        remote login through isi port has dtr toggle problem
@@ -1181,14 +1181,17 @@ static int isicom_chars_in_buffer(struct tty_struct *tty)
 }
 
 /* ioctl et all */
-static inline void isicom_send_break(struct isi_port *port,
-       unsigned long length)
+static int isicom_send_break(struct tty_struct *tty, int length)
 {
+       struct isi_port *port = tty->driver_data;
        struct isi_board *card = port->card;
        unsigned long base = card->base;
 
+       if (length == -1)
+               return -EOPNOTSUPP;
+
        if (!lock_card(card))
-               return;
+               return -EINVAL;
 
        outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
        outw((length & 0xff) << 8 | 0x00, base);
@@ -1196,6 +1199,7 @@ static inline void isicom_send_break(struct isi_port *port,
        InterruptTheCard(base);
 
        unlock_card(card);
+       return 0;
 }
 
 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
@@ -1239,9 +1243,10 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
        return 0;
 }
 
-static int isicom_set_serial_info(struct isi_port *port,
-       struct serial_struct __user *info)
+static int isicom_set_serial_info(struct tty_struct *tty,
+                                       struct serial_struct __user *info)
 {
+       struct isi_port *port = tty->driver_data;
        struct serial_struct newinfo;
        int reconfig_port;
 
@@ -1272,7 +1277,7 @@ static int isicom_set_serial_info(struct isi_port *port,
        if (reconfig_port) {
                unsigned long flags;
                spin_lock_irqsave(&port->card->card_lock, flags);
-               isicom_config_port(port);
+               isicom_config_port(tty);
                spin_unlock_irqrestore(&port->card->card_lock, flags);
        }
        unlock_kernel();
@@ -1305,33 +1310,16 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
 {
        struct isi_port *port = tty->driver_data;
        void __user *argp = (void __user *)arg;
-       int retval;
 
        if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
                return -ENODEV;
 
        switch (cmd) {
-       case TCSBRK:
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               if (!arg)
-                       isicom_send_break(port, HZ/4);
-               return 0;
-
-       case TCSBRKP:
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
-               return 0;
        case TIOCGSERIAL:
                return isicom_get_serial_info(port, argp);
 
        case TIOCSSERIAL:
-               return isicom_set_serial_info(port, argp);
+               return isicom_set_serial_info(tty, argp);
 
        default:
                return -ENOIOCTLCMD;
@@ -1354,7 +1342,7 @@ static void isicom_set_termios(struct tty_struct *tty,
                return;
 
        spin_lock_irqsave(&port->card->card_lock, flags);
-       isicom_config_port(port);
+       isicom_config_port(tty);
        spin_unlock_irqrestore(&port->card->card_lock, flags);
 
        if ((old_termios->c_cflag & CRTSCTS) &&
@@ -1432,7 +1420,7 @@ static void isicom_hangup(struct tty_struct *tty)
 
        port->port.count = 0;
        port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-       port->port.tty = NULL;
+       tty_port_tty_set(&port->port, NULL);
        wake_up_interruptible(&port->port.open_wait);
 }
 
@@ -1459,6 +1447,7 @@ static const struct tty_operations isicom_ops = {
        .flush_buffer           = isicom_flush_buffer,
        .tiocmget               = isicom_tiocmget,
        .tiocmset               = isicom_tiocmset,
+       .break_ctl              = isicom_send_break,
 };
 
 static int __devinit reset_card(struct pci_dev *pdev,
@@ -1832,7 +1821,7 @@ static int __init isicom_init(void)
        isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
                CLOCAL;
        isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
-               TTY_DRIVER_DYNAMIC_DEV;
+               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
        tty_set_operations(isicom_normal, &isicom_ops);
 
        retval = tty_register_driver(isicom_normal);