Merge branch 'for-jeff' of git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux...
[cascardo/linux.git] / drivers / char / synclink.c
index 9d247d8..500f517 100644 (file)
@@ -180,19 +180,14 @@ struct tx_holding_buffer {
  
 struct mgsl_struct {
        int                     magic;
-       int                     flags;
-       int                     count;          /* count of opens */
+       struct tty_port         port;
        int                     line;
        int                     hw_version;
-       unsigned short          close_delay;
-       unsigned short          closing_wait;   /* time to wait before closing */
        
        struct mgsl_icount      icount;
        
-       struct tty_struct       *tty;
        int                     timeout;
        int                     x_char;         /* xon/xoff character */
-       int                     blocked_open;   /* # of blocked opens */
        u16                     read_status_mask;
        u16                     ignore_status_mask;     
        unsigned char           *xmit_buf;
@@ -200,9 +195,6 @@ struct mgsl_struct {
        int                     xmit_tail;
        int                     xmit_cnt;
        
-       wait_queue_head_t       open_wait;
-       wait_queue_head_t       close_wait;
-       
        wait_queue_head_t       status_event_wait_q;
        wait_queue_head_t       event_wait_q;
        struct timer_list       tx_timer;       /* HDLC transmit timeout timer */
@@ -312,7 +304,6 @@ struct mgsl_struct {
 
        /* generic HDLC device parts */
        int netcount;
-       int dosyncppp;
        spinlock_t netlock;
 
 #if SYNCLINK_GENERIC_HDLC
@@ -876,7 +867,6 @@ static int irq[MAX_ISA_DEVICES];
 static int dma[MAX_ISA_DEVICES];
 static int debug_level;
 static int maxframe[MAX_TOTAL_DEVICES];
-static int dosyncppp[MAX_TOTAL_DEVICES];
 static int txdmabufs[MAX_TOTAL_DEVICES];
 static int txholdbufs[MAX_TOTAL_DEVICES];
        
@@ -887,7 +877,6 @@ module_param_array(irq, int, NULL, 0);
 module_param_array(dma, int, NULL, 0);
 module_param(debug_level, int, 0);
 module_param_array(maxframe, int, NULL, 0);
-module_param_array(dosyncppp, int, NULL, 0);
 module_param_array(txdmabufs, int, NULL, 0);
 module_param_array(txholdbufs, int, NULL, 0);
 
@@ -975,8 +964,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
                return;
        ld = tty_ldisc_ref(tty);
        if (ld) {
-               if (ld->receive_buf)
-                       ld->receive_buf(tty, data, flags, count);
+               if (ld->ops->receive_buf)
+                       ld->ops->receive_buf(tty, data, flags, count);
                tty_ldisc_deref(ld);
        }
 }
@@ -1134,7 +1123,7 @@ static void mgsl_bh_receive(struct mgsl_struct *info)
 
 static void mgsl_bh_transmit(struct mgsl_struct *info)
 {
-       struct tty_struct *tty = info->tty;
+       struct tty_struct *tty = info->port.tty;
        unsigned long flags;
        
        if ( debug_level >= DEBUG_LEVEL_BH )
@@ -1276,7 +1265,7 @@ static void mgsl_isr_transmit_status( struct mgsl_struct *info )
        else 
 #endif
        {
-               if (info->tty->stopped || info->tty->hw_stopped) {
+               if (info->port.tty->stopped || info->port.tty->hw_stopped) {
                        usc_stop_transmitter(info);
                        return;
                }
@@ -1357,29 +1346,29 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
                wake_up_interruptible(&info->status_event_wait_q);
                wake_up_interruptible(&info->event_wait_q);
 
-               if ( (info->flags & ASYNC_CHECK_CD) && 
+               if ( (info->port.flags & ASYNC_CHECK_CD) && 
                     (status & MISCSTATUS_DCD_LATCHED) ) {
                        if ( debug_level >= DEBUG_LEVEL_ISR )
                                printk("%s CD now %s...", info->device_name,
                                       (status & MISCSTATUS_DCD) ? "on" : "off");
                        if (status & MISCSTATUS_DCD)
-                               wake_up_interruptible(&info->open_wait);
+                               wake_up_interruptible(&info->port.open_wait);
                        else {
                                if ( debug_level >= DEBUG_LEVEL_ISR )
                                        printk("doing serial hangup...");
-                               if (info->tty)
-                                       tty_hangup(info->tty);
+                               if (info->port.tty)
+                                       tty_hangup(info->port.tty);
                        }
                }
        
-               if ( (info->flags & ASYNC_CTS_FLOW) && 
+               if ( (info->port.flags & ASYNC_CTS_FLOW) && 
                     (status & MISCSTATUS_CTS_LATCHED) ) {
-                       if (info->tty->hw_stopped) {
+                       if (info->port.tty->hw_stopped) {
                                if (status & MISCSTATUS_CTS) {
                                        if ( debug_level >= DEBUG_LEVEL_ISR )
                                                printk("CTS tx start...");
-                                       if (info->tty)
-                                               info->tty->hw_stopped = 0;
+                                       if (info->port.tty)
+                                               info->port.tty->hw_stopped = 0;
                                        usc_start_transmitter(info);
                                        info->pending_bh |= BH_TRANSMIT;
                                        return;
@@ -1388,8 +1377,8 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
                                if (!(status & MISCSTATUS_CTS)) {
                                        if ( debug_level >= DEBUG_LEVEL_ISR )
                                                printk("CTS tx stop...");
-                                       if (info->tty)
-                                               info->tty->hw_stopped = 1;
+                                       if (info->port.tty)
+                                               info->port.tty->hw_stopped = 1;
                                        usc_stop_transmitter(info);
                                }
                        }
@@ -1423,7 +1412,7 @@ static void mgsl_isr_transmit_data( struct mgsl_struct *info )
                        
        usc_ClearIrqPendingBits( info, TRANSMIT_DATA );
        
-       if (info->tty->stopped || info->tty->hw_stopped) {
+       if (info->port.tty->stopped || info->port.tty->hw_stopped) {
                usc_stop_transmitter(info);
                return;
        }
@@ -1453,7 +1442,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
        u16 status;
        int work = 0;
        unsigned char DataByte;
-       struct tty_struct *tty = info->tty;
+       struct tty_struct *tty = info->port.tty;
        struct  mgsl_icount *icount = &info->icount;
        
        if ( debug_level >= DEBUG_LEVEL_ISR )   
@@ -1514,7 +1503,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
                
                        if (status & RXSTATUS_BREAK_RECEIVED) {
                                flag = TTY_BREAK;
-                               if (info->flags & ASYNC_SAK)
+                               if (info->port.flags & ASYNC_SAK)
                                        do_SAK(tty);
                        } else if (status & RXSTATUS_PARITY_ERROR)
                                flag = TTY_PARITY;
@@ -1771,7 +1760,7 @@ static int startup(struct mgsl_struct * info)
        if ( debug_level >= DEBUG_LEVEL_INFO )
                printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name);
                
-       if (info->flags & ASYNC_INITIALIZED)
+       if (info->port.flags & ASYNC_INITIALIZED)
                return 0;
        
        if (!info->xmit_buf) {
@@ -1798,8 +1787,8 @@ static int startup(struct mgsl_struct * info)
                retval = mgsl_adapter_test(info);
                
        if ( retval ) {
-               if (capable(CAP_SYS_ADMIN) && info->tty)
-                       set_bit(TTY_IO_ERROR, &info->tty->flags);
+               if (capable(CAP_SYS_ADMIN) && info->port.tty)
+                       set_bit(TTY_IO_ERROR, &info->port.tty->flags);
                mgsl_release_resources(info);
                return retval;
        }
@@ -1807,10 +1796,10 @@ static int startup(struct mgsl_struct * info)
        /* program hardware for current parameters */
        mgsl_change_params(info);
        
-       if (info->tty)
-               clear_bit(TTY_IO_ERROR, &info->tty->flags);
+       if (info->port.tty)
+               clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
 
-       info->flags |= ASYNC_INITIALIZED;
+       info->port.flags |= ASYNC_INITIALIZED;
        
        return 0;
        
@@ -1827,7 +1816,7 @@ static void shutdown(struct mgsl_struct * info)
 {
        unsigned long flags;
        
-       if (!(info->flags & ASYNC_INITIALIZED))
+       if (!(info->port.flags & ASYNC_INITIALIZED))
                return;
 
        if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1864,7 +1853,7 @@ static void shutdown(struct mgsl_struct * info)
        /* on the ISA adapter. This has no effect for the PCI adapter */
        usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12));
        
-       if (!info->tty || info->tty->termios->c_cflag & HUPCL) {
+       if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
                info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
                usc_set_serial_signals(info);
        }
@@ -1873,10 +1862,10 @@ static void shutdown(struct mgsl_struct * info)
 
        mgsl_release_resources(info);   
        
-       if (info->tty)
-               set_bit(TTY_IO_ERROR, &info->tty->flags);
+       if (info->port.tty)
+               set_bit(TTY_IO_ERROR, &info->port.tty->flags);
 
-       info->flags &= ~ASYNC_INITIALIZED;
+       info->port.flags &= ~ASYNC_INITIALIZED;
        
 }      /* end of shutdown() */
 
@@ -1908,7 +1897,7 @@ static void mgsl_program_hw(struct mgsl_struct *info)
        usc_EnableInterrupts(info, IO_PIN);
        usc_get_serial_signals(info);
                
-       if (info->netcount || info->tty->termios->c_cflag & CREAD)
+       if (info->netcount || info->port.tty->termios->c_cflag & CREAD)
                usc_start_receiver(info);
                
        spin_unlock_irqrestore(&info->irq_spinlock,flags);
@@ -1921,14 +1910,14 @@ static void mgsl_change_params(struct mgsl_struct *info)
        unsigned cflag;
        int bits_per_char;
 
-       if (!info->tty || !info->tty->termios)
+       if (!info->port.tty || !info->port.tty->termios)
                return;
                
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):mgsl_change_params(%s)\n",
                         __FILE__,__LINE__, info->device_name );
                         
-       cflag = info->tty->termios->c_cflag;
+       cflag = info->port.tty->termios->c_cflag;
 
        /* if B0 rate (hangup) specified then negate DTR and RTS */
        /* otherwise assert DTR and RTS */
@@ -1976,7 +1965,7 @@ static void mgsl_change_params(struct mgsl_struct *info)
         * current data rate.
         */
        if (info->params.data_rate <= 460800)
-               info->params.data_rate = tty_get_baud_rate(info->tty);
+               info->params.data_rate = tty_get_baud_rate(info->port.tty);
        
        if ( info->params.data_rate ) {
                info->timeout = (32*HZ*bits_per_char) / 
@@ -1985,31 +1974,31 @@ static void mgsl_change_params(struct mgsl_struct *info)
        info->timeout += HZ/50;         /* Add .02 seconds of slop */
 
        if (cflag & CRTSCTS)
-               info->flags |= ASYNC_CTS_FLOW;
+               info->port.flags |= ASYNC_CTS_FLOW;
        else
-               info->flags &= ~ASYNC_CTS_FLOW;
+               info->port.flags &= ~ASYNC_CTS_FLOW;
                
        if (cflag & CLOCAL)
-               info->flags &= ~ASYNC_CHECK_CD;
+               info->port.flags &= ~ASYNC_CHECK_CD;
        else
-               info->flags |= ASYNC_CHECK_CD;
+               info->port.flags |= ASYNC_CHECK_CD;
 
        /* process tty input control flags */
        
        info->read_status_mask = RXSTATUS_OVERRUN;
-       if (I_INPCK(info->tty))
+       if (I_INPCK(info->port.tty))
                info->read_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR;
-       if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+       if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
                info->read_status_mask |= RXSTATUS_BREAK_RECEIVED;
        
-       if (I_IGNPAR(info->tty))
+       if (I_IGNPAR(info->port.tty))
                info->ignore_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR;
-       if (I_IGNBRK(info->tty)) {
+       if (I_IGNBRK(info->port.tty)) {
                info->ignore_status_mask |= RXSTATUS_BREAK_RECEIVED;
                /* If ignoring parity and break indicators, ignore 
                 * overruns too.  (For real raw support).
                 */
-               if (I_IGNPAR(info->tty))
+               if (I_IGNPAR(info->port.tty))
                        info->ignore_status_mask |= RXSTATUS_OVERRUN;
        }
 
@@ -2905,9 +2894,9 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
  *
  * Arguments:          tty             pointer to tty instance data
  *                     break_state     -1=set break condition, 0=clear
- * Return Value:       None
+ * Return Value:       error code
  */
-static void mgsl_break(struct tty_struct *tty, int break_state)
+static int mgsl_break(struct tty_struct *tty, int break_state)
 {
        struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data;
        unsigned long flags;
@@ -2917,7 +2906,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state)
                         __FILE__,__LINE__, info->device_name, break_state);
                         
        if (mgsl_paranoia_check(info, tty->name, "mgsl_break"))
-               return;
+               return -EINVAL;
 
        spin_lock_irqsave(&info->irq_spinlock,flags);
        if (break_state == -1)
@@ -2925,6 +2914,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state)
        else 
                usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7));
        spin_unlock_irqrestore(&info->irq_spinlock,flags);
+       return 0;
        
 }      /* end of mgsl_break() */
 
@@ -3113,32 +3103,32 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
        
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):mgsl_close(%s) entry, count=%d\n",
-                        __FILE__,__LINE__, info->device_name, info->count);
+                        __FILE__,__LINE__, info->device_name, info->port.count);
                         
-       if (!info->count)
+       if (!info->port.count)
                return;
 
        if (tty_hung_up_p(filp))
                goto cleanup;
                        
-       if ((tty->count == 1) && (info->count != 1)) {
+       if ((tty->count == 1) && (info->port.count != 1)) {
                /*
                 * tty->count is 1 and the tty structure will be freed.
-                * info->count should be one in this case.
+                * info->port.count should be one in this case.
                 * if it's not, correct it so that the port is shutdown.
                 */
                printk("mgsl_close: bad refcount; tty->count is 1, "
-                      "info->count is %d\n", info->count);
-               info->count = 1;
+                      "info->port.count is %d\n", info->port.count);
+               info->port.count = 1;
        }
        
-       info->count--;
+       info->port.count--;
        
        /* if at least one open remaining, leave hardware active */
-       if (info->count)
+       if (info->port.count)
                goto cleanup;
        
-       info->flags |= ASYNC_CLOSING;
+       info->port.flags |= ASYNC_CLOSING;
        
        /* set tty->closing to notify line discipline to 
         * only process XON/XOFF characters. Only the N_TTY
@@ -3148,14 +3138,14 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
        
        /* wait for transmit data to clear all layers */
        
-       if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+       if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
                if (debug_level >= DEBUG_LEVEL_INFO)
                        printk("%s(%d):mgsl_close(%s) calling tty_wait_until_sent\n",
                                 __FILE__,__LINE__, info->device_name );
-               tty_wait_until_sent(tty, info->closing_wait);
+               tty_wait_until_sent(tty, info->port.closing_wait);
        }
                
-       if (info->flags & ASYNC_INITIALIZED)
+       if (info->port.flags & ASYNC_INITIALIZED)
                mgsl_wait_until_sent(tty, info->timeout);
 
        mgsl_flush_buffer(tty);
@@ -3165,23 +3155,23 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
        shutdown(info);
        
        tty->closing = 0;
-       info->tty = NULL;
+       info->port.tty = NULL;
        
-       if (info->blocked_open) {
-               if (info->close_delay) {
-                       msleep_interruptible(jiffies_to_msecs(info->close_delay));
+       if (info->port.blocked_open) {
+               if (info->port.close_delay) {
+                       msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
                }
-               wake_up_interruptible(&info->open_wait);
+               wake_up_interruptible(&info->port.open_wait);
        }
        
-       info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+       info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
                         
-       wake_up_interruptible(&info->close_wait);
+       wake_up_interruptible(&info->port.close_wait);
        
 cleanup:                       
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__,
-                       tty->driver->name, info->count);
+                       tty->driver->name, info->port.count);
                        
 }      /* end of mgsl_close() */
 
@@ -3211,7 +3201,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
        if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent"))
                return;
 
-       if (!(info->flags & ASYNC_INITIALIZED))
+       if (!(info->port.flags & ASYNC_INITIALIZED))
                goto exit;
         
        orig_jiffies = jiffies;
@@ -3283,11 +3273,11 @@ static void mgsl_hangup(struct tty_struct *tty)
        mgsl_flush_buffer(tty);
        shutdown(info);
        
-       info->count = 0;        
-       info->flags &= ~ASYNC_NORMAL_ACTIVE;
-       info->tty = NULL;
+       info->port.count = 0;   
+       info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+       info->port.tty = NULL;
 
-       wake_up_interruptible(&info->open_wait);
+       wake_up_interruptible(&info->port.open_wait);
        
 }      /* end of mgsl_hangup() */
 
@@ -3319,7 +3309,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 
        if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
                /* nonblock mode is set or port is not enabled */
-               info->flags |= ASYNC_NORMAL_ACTIVE;
+               info->port.flags |= ASYNC_NORMAL_ACTIVE;
                return 0;
        }
 
@@ -3328,25 +3318,25 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 
        /* Wait for carrier detect and the line to become
         * free (i.e., not in use by the callout).  While we are in
-        * this loop, info->count is dropped by one, so that
+        * this loop, info->port.count is dropped by one, so that
         * mgsl_close() knows when to free things.  We restore it upon
         * exit, either normal or abnormal.
         */
         
        retval = 0;
-       add_wait_queue(&info->open_wait, &wait);
+       add_wait_queue(&info->port.open_wait, &wait);
        
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):block_til_ready before block on %s count=%d\n",
-                        __FILE__,__LINE__, tty->driver->name, info->count );
+                        __FILE__,__LINE__, tty->driver->name, info->port.count );
 
        spin_lock_irqsave(&info->irq_spinlock, flags);
        if (!tty_hung_up_p(filp)) {
                extra_count = true;
-               info->count--;
+               info->port.count--;
        }
        spin_unlock_irqrestore(&info->irq_spinlock, flags);
-       info->blocked_open++;
+       info->port.blocked_open++;
        
        while (1) {
                if (tty->termios->c_cflag & CBAUD) {
@@ -3358,8 +3348,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
                
                set_current_state(TASK_INTERRUPTIBLE);
                
-               if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){
-                       retval = (info->flags & ASYNC_HUP_NOTIFY) ?
+               if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
+                       retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
                                        -EAGAIN : -ERESTARTSYS;
                        break;
                }
@@ -3368,7 +3358,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
                usc_get_serial_signals(info);
                spin_unlock_irqrestore(&info->irq_spinlock,flags);
                
-               if (!(info->flags & ASYNC_CLOSING) &&
+               if (!(info->port.flags & ASYNC_CLOSING) &&
                    (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
                        break;
                }
@@ -3380,24 +3370,24 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
                
                if (debug_level >= DEBUG_LEVEL_INFO)
                        printk("%s(%d):block_til_ready blocking on %s count=%d\n",
-                                __FILE__,__LINE__, tty->driver->name, info->count );
+                                __FILE__,__LINE__, tty->driver->name, info->port.count );
                                 
                schedule();
        }
        
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&info->open_wait, &wait);
+       remove_wait_queue(&info->port.open_wait, &wait);
        
        if (extra_count)
-               info->count++;
-       info->blocked_open--;
+               info->port.count++;
+       info->port.blocked_open--;
        
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):block_til_ready after blocking on %s count=%d\n",
-                        __FILE__,__LINE__, tty->driver->name, info->count );
+                        __FILE__,__LINE__, tty->driver->name, info->port.count );
                         
        if (!retval)
-               info->flags |= ASYNC_NORMAL_ACTIVE;
+               info->port.flags |= ASYNC_NORMAL_ACTIVE;
                
        return retval;
        
@@ -3435,22 +3425,22 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
                return -ENODEV;
        
        tty->driver_data = info;
-       info->tty = tty;
+       info->port.tty = tty;
                
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):mgsl_open(%s), old ref count = %d\n",
-                        __FILE__,__LINE__,tty->driver->name, info->count);
+                        __FILE__,__LINE__,tty->driver->name, info->port.count);
 
        /* If port is closing, signal caller to try again */
-       if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){
-               if (info->flags & ASYNC_CLOSING)
-                       interruptible_sleep_on(&info->close_wait);
-               retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+       if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){
+               if (info->port.flags & ASYNC_CLOSING)
+                       interruptible_sleep_on(&info->port.close_wait);
+               retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
                        -EAGAIN : -ERESTARTSYS);
                goto cleanup;
        }
        
-       info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+       info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
        spin_lock_irqsave(&info->netlock, flags);
        if (info->netcount) {
@@ -3458,10 +3448,10 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
                spin_unlock_irqrestore(&info->netlock, flags);
                goto cleanup;
        }
-       info->count++;
+       info->port.count++;
        spin_unlock_irqrestore(&info->netlock, flags);
 
-       if (info->count == 1) {
+       if (info->port.count == 1) {
                /* 1st open on this device, init hardware */
                retval = startup(info);
                if (retval < 0)
@@ -3484,9 +3474,9 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
 cleanup:                       
        if (retval) {
                if (tty->count == 1)
-                       info->tty = NULL; /* tty layer will release tty struct */
-               if(info->count)
-                       info->count--;
+                       info->port.tty = NULL; /* tty layer will release tty struct */
+               if(info->port.count)
+                       info->port.count--;
        }
        
        return retval;
@@ -4265,7 +4255,6 @@ static void mgsl_add_device( struct mgsl_struct *info )
        if (info->line < MAX_TOTAL_DEVICES) {
                if (maxframe[info->line])
                        info->max_frame_size = maxframe[info->line];
-               info->dosyncppp = dosyncppp[info->line];
 
                if (txdmabufs[info->line]) {
                        info->num_tx_dma_buffers = txdmabufs[info->line];
@@ -4332,13 +4321,12 @@ static struct mgsl_struct* mgsl_allocate_device(void)
        if (!info) {
                printk("Error can't allocate device instance data\n");
        } else {
+               tty_port_init(&info->port);
                info->magic = MGSL_MAGIC;
                INIT_WORK(&info->task, mgsl_bh_handler);
                info->max_frame_size = 4096;
-               info->close_delay = 5*HZ/10;
-               info->closing_wait = 30*HZ;
-               init_waitqueue_head(&info->open_wait);
-               init_waitqueue_head(&info->close_wait);
+               info->port.close_delay = 5*HZ/10;
+               info->port.closing_wait = 30*HZ;
                init_waitqueue_head(&info->status_event_wait_q);
                init_waitqueue_head(&info->event_wait_q);
                spin_lock_init(&info->irq_spinlock);
@@ -6575,7 +6563,7 @@ static bool mgsl_get_rx_frame(struct mgsl_struct *info)
        unsigned int framesize = 0;
        bool ReturnCode = false;
        unsigned long flags;
-       struct tty_struct *tty = info->tty;
+       struct tty_struct *tty = info->port.tty;
        bool return_frame = false;
        
        /*
@@ -6773,7 +6761,7 @@ static bool mgsl_get_raw_rx_frame(struct mgsl_struct *info)
        unsigned int framesize = 0;
        bool ReturnCode = false;
        unsigned long flags;
-       struct tty_struct *tty = info->tty;
+       struct tty_struct *tty = info->port.tty;
 
        /*
         * current_rx_buffer points to the 1st buffer of the next available
@@ -7710,7 +7698,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
        unsigned short new_crctype;
 
        /* return error if TTY interface open */
-       if (info->count)
+       if (info->port.count)
                return -EBUSY;
 
        switch (encoding)
@@ -7806,7 +7794,7 @@ static int hdlcdev_open(struct net_device *dev)
 
        /* arbitrate between network and tty opens */
        spin_lock_irqsave(&info->netlock, flags);
-       if (info->count != 0 || info->netcount != 0) {
+       if (info->port.count != 0 || info->netcount != 0) {
                printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
                spin_unlock_irqrestore(&info->netlock, flags);
                return -EBUSY;
@@ -7892,7 +7880,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name);
 
        /* return error if TTY interface open */
-       if (info->count)
+       if (info->port.count)
                return -EBUSY;
 
        if (cmd != SIOCWANDEV)