linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / char / synclinkmp.c
index 5648ed3..960adb2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: synclinkmp.c,v 4.29 2004/08/27 20:06:41 paulkf Exp $
+ * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $
  *
  * Device driver for Microgate SyncLink Multiport
  * high speed multiprotocol serial adapter.
@@ -55,7 +55,6 @@
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <asm/serial.h>
 #include <linux/delay.h>
 #include <linux/ioctl.h>
 
@@ -63,7 +62,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/types.h>
 #include <linux/termios.h>
 #include <linux/workqueue.h>
@@ -480,14 +479,14 @@ static int debug_level = 0;
 static int maxframe[MAX_DEVICES] = {0,};
 static int dosyncppp[MAX_DEVICES] = {0,};
 
-MODULE_PARM(break_on_load,"i");
-MODULE_PARM(ttymajor,"i");
-MODULE_PARM(debug_level,"i");
-MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICES) "i");
-MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");
+module_param(break_on_load, bool, 0);
+module_param(ttymajor, int, 0);
+module_param(debug_level, int, 0);
+module_param_array(maxframe, int, NULL, 0);
+module_param_array(dosyncppp, int, NULL, 0);
 
 static char *driver_name = "SyncLink MultiPort driver";
-static char *driver_version = "$Revision: 4.29 $";
+static char *driver_version = "$Revision: 4.38 $";
 
 static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
 static void synclinkmp_remove_one(struct pci_dev *dev);
@@ -521,7 +520,7 @@ static void close(struct tty_struct *tty, struct file * filp);
 static void hangup(struct tty_struct *tty);
 static void set_termios(struct tty_struct *tty, struct termios *old_termios);
 
-static int  write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
+static int  write(struct tty_struct *tty, const unsigned char *buf, int count);
 static void put_char(struct tty_struct *tty, unsigned char ch);
 static void send_xchar(struct tty_struct *tty, char ch);
 static void wait_until_sent(struct tty_struct *tty, int timeout);
@@ -556,7 +555,6 @@ static int  set_txidle(SLMP_INFO *info, int idle_mode);
 static int  tx_enable(SLMP_INFO *info, int enable);
 static int  tx_abort(SLMP_INFO *info);
 static int  rx_enable(SLMP_INFO *info, int enable);
-static int  map_status(int signals);
 static int  modem_input_wait(SLMP_INFO *info,int arg);
 static int  wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
 static int  tiocmget(struct tty_struct *tty, struct file *file);
@@ -645,7 +643,7 @@ static unsigned char tx_active_fifo_level = 16;     // tx request FIFO activation le
 static unsigned char tx_negate_fifo_level = 32;        // tx request FIFO negation level in bytes
 
 static u32 misc_ctrl_value = 0x007e4040;
-static u32 lcr1_brdr_value = 0x00800029;
+static u32 lcr1_brdr_value = 0x00800028;
 
 static u32 read_ahead_count = 8;
 
@@ -878,8 +876,7 @@ static void close(struct tty_struct *tty, struct file *filp)
 
        if (info->blocked_open) {
                if (info->close_delay) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(info->close_delay);
+                       msleep_interruptible(jiffies_to_msecs(info->close_delay));
                }
                wake_up_interruptible(&info->open_wait);
        }
@@ -972,16 +969,15 @@ static void set_termios(struct tty_struct *tty, struct termios *old_termios)
  * Arguments:
  *
  *     tty             pointer to tty information structure
- *     from_user       flag: 1 = from user process
  *     buf             pointer to buffer containing send data
  *     count           size of send data in bytes
  *
  * Return Value:       number of characters written
  */
-static int write(struct tty_struct *tty, int from_user,
+static int write(struct tty_struct *tty,
                 const unsigned char *buf, int count)
 {
-       int     c, ret = 0, err;
+       int     c, ret = 0;
        SLMP_INFO *info = (SLMP_INFO *)tty->driver_data;
        unsigned long flags;
 
@@ -1008,11 +1004,9 @@ static int write(struct tty_struct *tty, int from_user,
                        tx_load_dma_buffer(info, info->tx_buf, info->tx_count);
                        goto start;
                }
-               if (!from_user) {
-                       ret = info->tx_count = count;
-                       tx_load_dma_buffer(info, buf, count);
-                       goto start;
-               }
+               ret = info->tx_count = count;
+               tx_load_dma_buffer(info, buf, count);
+               goto start;
        }
 
        for (;;) {
@@ -1022,15 +1016,7 @@ static int write(struct tty_struct *tty, int from_user,
                if (c <= 0)
                        break;
                        
-               if (from_user) {
-                       COPY_FROM_USER(err, info->tx_buf + info->tx_put, buf, c);
-                       if (err) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               break;
-                       }
-               } else
-                       memcpy(info->tx_buf + info->tx_put, buf, c);
+               memcpy(info->tx_buf + info->tx_put, buf, c);
 
                spin_lock_irqsave(&info->lock,flags);
                info->tx_put += c;
@@ -1164,8 +1150,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
 
        if ( info->params.mode == MGSL_MODE_HDLC ) {
                while (info->tx_active) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(char_time);
+                       msleep_interruptible(jiffies_to_msecs(char_time));
                        if (signal_pending(current))
                                break;
                        if (timeout && time_after(jiffies, orig_jiffies + timeout))
@@ -1175,8 +1160,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
                //TODO: determine if there is something similar to USC16C32
                //      TXSTATUS_ALL_SENT status
                while ( info->tx_active && info->tx_enabled) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(char_time);
+                       msleep_interruptible(jiffies_to_msecs(char_time));
                        if (signal_pending(current))
                                break;
                        if (timeout && time_after(jiffies, orig_jiffies + timeout))
@@ -1968,9 +1952,7 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
 
        memcpy(skb_put(skb, size),buf,size);
 
-       skb->dev      = info->netdev;
-       skb->mac.raw  = skb->data;
-       skb->protocol = hdlc_type_trans(skb, skb->dev);
+       skb->protocol = hdlc_type_trans(skb, info->netdev);
 
        stats->rx_packets++;
        stats->rx_bytes += size;
@@ -2214,7 +2196,7 @@ void isr_rxint(SLMP_INFO * info)
                        if ( tty ) {
                                if (!(status & info->ignore_status_mask1)) {
                                        if (info->read_status_mask1 & BRKD) {
-                                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                                               tty_insert_flip_char(tty, 0, TTY_BREAK);
                                                if (info->flags & ASYNC_SAK)
                                                        do_SAK(tty);
                                        }
@@ -2258,16 +2240,10 @@ void isr_rxrdy(SLMP_INFO * info)
 
        while((status = read_reg(info,CST0)) & BIT0)
        {
+               int flag = 0;
+               int over = 0;
                DataByte = read_reg(info,TRB);
 
-               if ( tty ) {
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               continue;
-
-                       *tty->flip.char_buf_ptr = DataByte;
-                       *tty->flip.flag_buf_ptr = 0;
-               }
-
                icount->rx++;
 
                if ( status & (PE + FRME + OVRN) ) {
@@ -2290,46 +2266,38 @@ void isr_rxrdy(SLMP_INFO * info)
 
                        if ( tty ) {
                                if (status & PE)
-                                       *tty->flip.flag_buf_ptr = TTY_PARITY;
+                                       flag = TTY_PARITY;
                                else if (status & FRME)
-                                       *tty->flip.flag_buf_ptr = TTY_FRAME;
+                                       flag = TTY_FRAME;
                                if (status & OVRN) {
                                        /* Overrun is special, since it's
                                         * reported immediately, and doesn't
                                         * affect the current character
                                         */
-                                       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                               tty->flip.count++;
-                                               tty->flip.flag_buf_ptr++;
-                                               tty->flip.char_buf_ptr++;
-                                               *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                                       }
+                                       over = 1;
                                }
                        }
                }       /* end of if (error) */
 
                if ( tty ) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, DataByte, flag);
+                       if (over)
+                               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                }
        }
 
        if ( debug_level >= DEBUG_LEVEL_ISR ) {
-               printk("%s(%d):%s isr_rxrdy() flip count=%d\n",
-                       __FILE__,__LINE__,info->device_name,
-                       tty ? tty->flip.count : 0);
                printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n",
                        __FILE__,__LINE__,info->device_name,
                        icount->rx,icount->brk,icount->parity,
                        icount->frame,icount->overrun);
        }
 
-       if ( tty && tty->flip.count )
+       if ( tty )
                tty_flip_buffer_push(tty);
 }
 
-void isr_txeom(SLMP_INFO * info, unsigned char status)
+static void isr_txeom(SLMP_INFO * info, unsigned char status)
 {
        if ( debug_level >= DEBUG_LEVEL_ISR )
                printk("%s(%d):%s isr_txeom status=%02x\n",
@@ -2766,6 +2734,8 @@ static int startup(SLMP_INFO * info)
 
        info->pending_bh = 0;
 
+       memset(&info->icount, 0, sizeof(info->icount));
+
        /* program hardware for current parameters */
        reset_port(info);
 
@@ -2803,10 +2773,8 @@ static void shutdown(SLMP_INFO * info)
        del_timer(&info->tx_timer);
        del_timer(&info->status_timer);
 
-       if (info->tx_buf) {
-               kfree(info->tx_buf);
-               info->tx_buf = NULL;
-       }
+       kfree(info->tx_buf);
+       info->tx_buf = NULL;
 
        spin_lock_irqsave(&info->lock,flags);
 
@@ -2969,12 +2937,12 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
                printk("%s(%d):%s get_params()\n",
                         __FILE__,__LINE__, info->device_name);
 
-       COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount));
-       if (err) {
-               if ( debug_level >= DEBUG_LEVEL_INFO )
-                       printk( "%s(%d):%s get_stats() user buffer copy failed\n",
-                               __FILE__,__LINE__,info->device_name);
-               return -EFAULT;
+       if (!user_icount) {
+               memset(&info->icount, 0, sizeof(info->icount));
+       } else {
+               COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
+               if (err)
+                       return -EFAULT;
        }
 
        return 0;
@@ -3125,16 +3093,6 @@ static int rx_enable(SLMP_INFO * info, int enable)
        return 0;
 }
 
-static int map_status(int signals)
-{
-       /* Map status bits to API event bits */
-
-       return ((signals & SerialSignal_DSR) ? MgslEvent_DsrActive : MgslEvent_DsrInactive) +
-              ((signals & SerialSignal_CTS) ? MgslEvent_CtsActive : MgslEvent_CtsInactive) +
-              ((signals & SerialSignal_DCD) ? MgslEvent_DcdActive : MgslEvent_DcdInactive) +
-              ((signals & SerialSignal_RI)  ? MgslEvent_RiActive : MgslEvent_RiInactive);
-}
-
 /* wait for specified event to occur
  */
 static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
@@ -3161,7 +3119,7 @@ static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
 
        /* return immediately if state matches requested events */
        get_signals(info);
-       s = map_status(info->serial_signals);
+       s = info->serial_signals;
 
        events = mask &
                ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
@@ -3636,8 +3594,7 @@ int alloc_tmp_rx_buf(SLMP_INFO *info)
 
 void free_tmp_rx_buf(SLMP_INFO *info)
 {
-       if (info->tmp_rx_buf)
-               kfree(info->tmp_rx_buf);
+       kfree(info->tmp_rx_buf);
        info->tmp_rx_buf = NULL;
 }
 
@@ -3831,7 +3788,7 @@ void add_device(SLMP_INFO *info)
  *
  * Return Value:       pointer to SLMP_INFO if success, otherwise NULL
  */
-SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
+static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
 {
        SLMP_INFO *info;
 
@@ -4505,11 +4462,13 @@ void async_mode(SLMP_INFO *info)
        /* MD2, Mode Register 2
         *
         * 07..02  Reserved, must be 0
-        * 01..00  CNCT<1..0> Channel connection, 0=normal
+        * 01..00  CNCT<1..0> Channel connection, 00=normal 11=local loopback
         *
         * 0000 0000
         */
        RegValue = 0x00;
+       if (info->params.loopback)
+               RegValue |= (BIT1 + BIT0);
        write_reg(info, MD2, RegValue);
 
        /* RXS, Receive clock source
@@ -4544,7 +4503,7 @@ void async_mode(SLMP_INFO *info)
         * 07..05  Reserved, must be 0
         * 04..00  RRC<4..0> Rx FIFO trigger active 0x00 = 1 byte
         */
-       write_reg(info, TRC0, 0x00);
+       write_reg(info, RRC, 0x00);
 
        /* TRC0 Transmit Ready Control 0
         *
@@ -4590,9 +4549,6 @@ void async_mode(SLMP_INFO *info)
        write_reg(info, IE2, info->ie2_value);
 
        set_rate( info, info->params.data_rate * 16 );
-
-       if (info->params.loopback)
-               enable_loopback(info,1);
 }
 
 /* Program the SCA for HDLC communications.
@@ -5134,7 +5090,7 @@ void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count)
 int register_test(SLMP_INFO *info)
 {
        static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96};
-       static unsigned int count = sizeof(testval)/sizeof(unsigned char);
+       static unsigned int count = ARRAY_SIZE(testval);
        unsigned int i;
        int rc = TRUE;
        unsigned long flags;
@@ -5209,8 +5165,7 @@ int irq_test(SLMP_INFO *info)
 
        timeout=100;
        while( timeout-- && !info->irq_occurred ) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(msecs_to_jiffies(10));
+               msleep_interruptible(10);
        }
 
        spin_lock_irqsave(&info->lock,flags);
@@ -5222,7 +5177,7 @@ int irq_test(SLMP_INFO *info)
 
 /* initialize individual SCA device (2 ports)
  */
-int sca_init(SLMP_INFO *info)
+static int sca_init(SLMP_INFO *info)
 {
        /* set wait controller to single mem partition (low), no wait states */
        write_reg(info, PABR0, 0);      /* wait controller addr boundary 0 */
@@ -5360,8 +5315,7 @@ int loopback_test(SLMP_INFO *info)
        /* wait for receive complete */
        /* Set a timeout for waiting for interrupt. */
        for ( timeout = 100; timeout; --timeout ) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(msecs_to_jiffies(10));
+               msleep_interruptible(10);
 
                if (rx_get_frame(info)) {
                        rc = TRUE;
@@ -5454,7 +5408,7 @@ int memory_test(SLMP_INFO *info)
 {
        static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa,
                0x66666666, 0x99999999, 0xffffffff, 0x12345678 };
-       unsigned long count = sizeof(testval)/sizeof(unsigned long);
+       unsigned long count = ARRAY_SIZE(testval);
        unsigned long i;
        unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long);
        unsigned long * addr = (unsigned long *)info->memory_base;