]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/isicom.c
Merge commit 'v2.6.27-rc3' into core/urgent
[linux-2.6-omap-h63xx.git] / drivers / char / isicom.c
index 5a53c15b0dc2f5d69f6c3ffff4f5a02bad81c67c..8f7cc190b62d420116b5c0d30e70899c3332c94d 100644 (file)
@@ -199,10 +199,8 @@ struct     isi_board {
 struct isi_port {
        unsigned short          magic;
        struct tty_port         port;
-       int                     close_delay;
        u16                     channel;
        u16                     status;
-       u16                     closing_wait;
        struct isi_board        *card;
        unsigned char           *xmit_buf;
        int                     xmit_head;
@@ -1051,8 +1049,8 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
        tty->closing = 1;
        spin_unlock_irqrestore(&card->card_lock, flags);
 
-       if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-               tty_wait_until_sent(tty, port->closing_wait);
+       if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
+               tty_wait_until_sent(tty, port->port.closing_wait);
        /* indicate to the card that no more data can be received
           on this port */
        spin_lock_irqsave(&card->card_lock, flags);
@@ -1071,10 +1069,10 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
 
        if (port->port.blocked_open) {
                spin_unlock_irqrestore(&card->card_lock, flags);
-               if (port->close_delay) {
+               if (port->port.close_delay) {
                        pr_dbg("scheduling until time out.\n");
                        msleep_interruptible(
-                               jiffies_to_msecs(port->close_delay));
+                               jiffies_to_msecs(port->port.close_delay));
                }
                spin_lock_irqsave(&card->card_lock, flags);
                wake_up_interruptible(&port->port.open_wait);
@@ -1183,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);
@@ -1198,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)
@@ -1256,8 +1258,8 @@ static int isicom_set_serial_info(struct isi_port *port,
                (newinfo.flags & ASYNC_SPD_MASK));
 
        if (!capable(CAP_SYS_ADMIN)) {
-               if ((newinfo.close_delay != port->close_delay) ||
-                               (newinfo.closing_wait != port->closing_wait) ||
+               if ((newinfo.close_delay != port->port.close_delay) ||
+                               (newinfo.closing_wait != port->port.closing_wait) ||
                                ((newinfo.flags & ~ASYNC_USR_MASK) !=
                                (port->port.flags & ~ASYNC_USR_MASK))) {
                        unlock_kernel();
@@ -1266,8 +1268,8 @@ static int isicom_set_serial_info(struct isi_port *port,
                port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
                                (newinfo.flags & ASYNC_USR_MASK));
        } else {
-               port->close_delay = newinfo.close_delay;
-               port->closing_wait = newinfo.closing_wait;
+               port->port.close_delay = newinfo.close_delay;
+               port->port.closing_wait = newinfo.closing_wait;
                port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
                                (newinfo.flags & ASYNC_FLAGS));
        }
@@ -1294,8 +1296,8 @@ static int isicom_get_serial_info(struct isi_port *port,
        out_info.irq = port->card->irq;
        out_info.flags = port->port.flags;
 /*     out_info.baud_base = ? */
-       out_info.close_delay = port->close_delay;
-       out_info.closing_wait = port->closing_wait;
+       out_info.close_delay = port->port.close_delay;
+       out_info.closing_wait = port->port.closing_wait;
        unlock_kernel();
        if (copy_to_user(info, &out_info, sizeof(out_info)))
                return -EFAULT;
@@ -1307,28 +1309,11 @@ 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);
 
@@ -1461,6 +1446,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,
@@ -1804,13 +1790,13 @@ static int __init isicom_init(void)
                isi_card[idx].ports = port;
                spin_lock_init(&isi_card[idx].card_lock);
                for (channel = 0; channel < 16; channel++, port++) {
+                       tty_port_init(&port->port);
                        port->magic = ISICOM_MAGIC;
                        port->card = &isi_card[idx];
                        port->channel = channel;
-                       port->close_delay = 50 * HZ/100;
-                       port->closing_wait = 3000 * HZ/100;
+                       port->port.close_delay = 50 * HZ/100;
+                       port->port.closing_wait = 3000 * HZ/100;
                        port->status = 0;
-                       tty_port_init(&port->port);
                        /*  . . .  */
                }
                isi_card[idx].base = 0;
@@ -1834,7 +1820,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);