Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / char / synclink_gt.c
index 2f07b08..b4d1f4e 100644 (file)
@@ -46,6 +46,7 @@
 //#define DBGRBUF(info) dump_rbufs(info)
 
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/errno.h>
@@ -100,7 +101,6 @@ MODULE_LICENSE("GPL");
 
 static struct pci_device_id pci_table[] = {
        {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-       {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {0,}, /* terminate list */
@@ -391,8 +391,8 @@ static MGSL_PARAMS default_params = {
 #define DESC_LIST_SIZE 4096
 
 #define MASK_PARITY  BIT1
-#define MASK_FRAMING BIT0
-#define MASK_BREAK   BIT14
+#define MASK_FRAMING BIT2
+#define MASK_BREAK   BIT3
 #define MASK_OVERRUN BIT4
 
 #define GSR   0x00 /* global status */
@@ -870,7 +870,7 @@ static int write(struct tty_struct *tty,
                goto cleanup;
        DBGINFO(("%s write count=%d\n", info->device_name, count));
 
-       if (!info->tx_buf)
+       if (!tty || !info->tx_buf)
                goto cleanup;
 
        if (count > info->max_frame_size) {
@@ -924,7 +924,7 @@ static void put_char(struct tty_struct *tty, unsigned char ch)
        if (sanity_check(info, tty->name, "put_char"))
                return;
        DBGINFO(("%s put_char(%d)\n", info->device_name, ch));
-       if (!info->tx_buf)
+       if (!tty || !info->tx_buf)
                return;
        spin_lock_irqsave(&info->lock,flags);
        if (!info->tx_active && (info->tx_count < info->max_frame_size))
@@ -1497,10 +1497,8 @@ static int hdlcdev_open(struct net_device *dev)
        spin_lock_irqsave(&info->lock, flags);
        get_signals(info);
        spin_unlock_irqrestore(&info->lock, flags);
-       if (info->signals & SerialSignal_DCD)
-               netif_carrier_on(dev);
-       else
-               netif_carrier_off(dev);
+       hdlc_set_carrier(info->signals & SerialSignal_DCD, dev);
+
        return 0;
 }
 
@@ -1800,17 +1798,17 @@ static void rx_async(struct slgt_info *info)
 
                        stat = 0;
 
-                       if ((status = *(p+1) & (BIT1 + BIT0))) {
-                               if (status & BIT1)
+                       if ((status = *(p+1) & (BIT9 + BIT8))) {
+                               if (status & BIT9)
                                        icount->parity++;
-                               else if (status & BIT0)
+                               else if (status & BIT8)
                                        icount->frame++;
                                /* discard char if tty control flags say so */
                                if (status & info->ignore_status_mask)
                                        continue;
-                               if (status & BIT1)
+                               if (status & BIT9)
                                        stat = TTY_PARITY;
-                               else if (status & BIT0)
+                               else if (status & BIT8)
                                        stat = TTY_FRAME;
                        }
                        if (tty) {
@@ -1999,12 +1997,8 @@ static void dcd_change(struct slgt_info *info)
                info->input_signal_events.dcd_down++;
        }
 #ifdef CONFIG_HDLC
-       if (info->netcount) {
-               if (info->signals & SerialSignal_DCD)
-                       netif_carrier_on(info->netdev);
-               else
-                       netif_carrier_off(info->netdev);
-       }
+       if (info->netcount)
+               hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev);
 #endif
        wake_up_interruptible(&info->status_event_wait_q);
        wake_up_interruptible(&info->event_wait_q);
@@ -2521,8 +2515,7 @@ static int set_txidle(struct slgt_info *info, int idle_mode)
        DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode));
        spin_lock_irqsave(&info->lock,flags);
        info->idle_mode = idle_mode;
-       if (info->params.mode != MGSL_MODE_ASYNC)
-               tx_set_idle(info);
+       tx_set_idle(info);
        spin_unlock_irqrestore(&info->lock,flags);
        return 0;
 }
@@ -3083,7 +3076,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
 
 static int alloc_tmp_rbuf(struct slgt_info *info)
 {
-       info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL);
+       info->tmp_rbuf = kmalloc(info->max_frame_size, GFP_KERNEL);
        if (info->tmp_rbuf == NULL)
                return -ENOMEM;
        return 0;
@@ -3283,9 +3276,6 @@ static void add_device(struct slgt_info *info)
        case SYNCLINK_GT_DEVICE_ID:
                devstr = "GT";
                break;
-       case SYNCLINK_GT2_DEVICE_ID:
-               devstr = "GT2";
-               break;
        case SYNCLINK_GT4_DEVICE_ID:
                devstr = "GT4";
                break;
@@ -3349,7 +3339,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
                info->phys_reg_addr = pci_resource_start(pdev,0);
 
                info->bus_type = MGSL_BUS_TYPE_PCI;
-               info->irq_flags = IRQF_SHARED;
+               info->irq_flags = SA_SHIRQ;
 
                info->init_error = -1; /* assume error, set to 0 on successful init */
        }
@@ -3363,9 +3353,7 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
        int i;
        int port_count = 1;
 
-       if (pdev->device == SYNCLINK_GT2_DEVICE_ID)
-               port_count = 2;
-       else if (pdev->device == SYNCLINK_GT4_DEVICE_ID)
+       if (pdev->device == SYNCLINK_GT4_DEVICE_ID)
                port_count = 4;
 
        /* allocate device instances for all ports */
@@ -3952,6 +3940,8 @@ static void async_mode(struct slgt_info *info)
 
        msc_set_vcr(info);
 
+       tx_set_idle(info);
+
        /* SCR (serial control)
         *
         * 15  1=tx req on FIFO half empty
@@ -4022,7 +4012,7 @@ static void hdlc_mode(struct slgt_info *info)
        case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
        }
 
-       switch (info->params.crc_type & HDLC_CRC_MASK)
+       switch (info->params.crc_type)
        {
        case HDLC_CRC_16_CCITT: val |= BIT9; break;
        case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
@@ -4083,7 +4073,7 @@ static void hdlc_mode(struct slgt_info *info)
        case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
        }
 
-       switch (info->params.crc_type & HDLC_CRC_MASK)
+       switch (info->params.crc_type)
        {
        case HDLC_CRC_16_CCITT: val |= BIT9; break;
        case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
@@ -4185,38 +4175,17 @@ static void hdlc_mode(struct slgt_info *info)
  */
 static void tx_set_idle(struct slgt_info *info)
 {
-       unsigned char val;
-       unsigned short tcr;
+       unsigned char val = 0xff;
 
-       /* if preamble enabled (tcr[6] == 1) then tx idle size = 8 bits
-        * else tcr[5:4] = tx idle size: 00 = 8 bits, 01 = 16 bits
-        */
-       tcr = rd_reg16(info, TCR);
-       if (info->idle_mode & HDLC_TXIDLE_CUSTOM_16) {
-               /* disable preamble, set idle size to 16 bits */
-               tcr = (tcr & ~(BIT6 + BIT5)) | BIT4;
-               /* MSB of 16 bit idle specified in tx preamble register (TPR) */
-               wr_reg8(info, TPR, (unsigned char)((info->idle_mode >> 8) & 0xff));
-       } else if (!(tcr & BIT6)) {
-               /* preamble is disabled, set idle size to 8 bits */
-               tcr &= ~(BIT5 + BIT4);
-       }
-       wr_reg16(info, TCR, tcr);
-
-       if (info->idle_mode & (HDLC_TXIDLE_CUSTOM_8 | HDLC_TXIDLE_CUSTOM_16)) {
-               /* LSB of custom tx idle specified in tx idle register */
-               val = (unsigned char)(info->idle_mode & 0xff);
-       } else {
-               /* standard 8 bit idle patterns */
-               switch(info->idle_mode)
-               {
-               case HDLC_TXIDLE_FLAGS:          val = 0x7e; break;
-               case HDLC_TXIDLE_ALT_ZEROS_ONES:
-               case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break;
-               case HDLC_TXIDLE_ZEROS:
-               case HDLC_TXIDLE_SPACE:          val = 0x00; break;
-               default:                         val = 0xff;
-               }
+       switch(info->idle_mode)
+       {
+       case HDLC_TXIDLE_FLAGS:          val = 0x7e; break;
+       case HDLC_TXIDLE_ALT_ZEROS_ONES: val = 0xaa; break;
+       case HDLC_TXIDLE_ZEROS:          val = 0x00; break;
+       case HDLC_TXIDLE_ONES:           val = 0xff; break;
+       case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break;
+       case HDLC_TXIDLE_SPACE:          val = 0x00; break;
+       case HDLC_TXIDLE_MARK:           val = 0xff; break;
        }
 
        wr_reg8(info, TIR, val);
@@ -4344,12 +4313,6 @@ static int rx_get_frame(struct slgt_info *info)
        unsigned long flags;
        struct tty_struct *tty = info->tty;
        unsigned char addr_field = 0xff;
-       unsigned int crc_size = 0;
-
-       switch (info->params.crc_type & HDLC_CRC_MASK) {
-       case HDLC_CRC_16_CCITT: crc_size = 2; break;
-       case HDLC_CRC_32_CCITT: crc_size = 4; break;
-       }
 
 check_again:
 
@@ -4394,7 +4357,7 @@ check_again:
        status = desc_status(info->rbufs[end]);
 
        /* ignore CRC bit if not using CRC (bit is undefined) */
-       if ((info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_NONE)
+       if (info->params.crc_type == HDLC_CRC_NONE)
                status &= ~BIT1;
 
        if (framesize == 0 ||
@@ -4403,34 +4366,34 @@ check_again:
                goto check_again;
        }
 
-       if (framesize < (2 + crc_size) || status & BIT0) {
-               info->icount.rxshort++;
+       if (framesize < 2 || status & (BIT1+BIT0)) {
+               if (framesize < 2 || (status & BIT0))
+                       info->icount.rxshort++;
+               else
+                       info->icount.rxcrc++;
                framesize = 0;
-       } else if (status & BIT1) {
-               info->icount.rxcrc++;
-               if (!(info->params.crc_type & HDLC_CRC_RETURN_EX))
-                       framesize = 0;
-       }
 
 #ifdef CONFIG_HDLC
-       if (framesize == 0) {
-               struct net_device_stats *stats = hdlc_stats(info->netdev);
-               stats->rx_errors++;
-               stats->rx_frame_errors++;
-       }
+               {
+                       struct net_device_stats *stats = hdlc_stats(info->netdev);
+                       stats->rx_errors++;
+                       stats->rx_frame_errors++;
+               }
 #endif
+       } else {
+               /* adjust frame size for CRC, if any */
+               if (info->params.crc_type == HDLC_CRC_16_CCITT)
+                       framesize -= 2;
+               else if (info->params.crc_type == HDLC_CRC_32_CCITT)
+                       framesize -= 4;
+       }
 
        DBGBH(("%s rx frame status=%04X size=%d\n",
                info->device_name, status, framesize));
        DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx");
 
        if (framesize) {
-               if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) {
-                       framesize -= crc_size;
-                       crc_size = 0;
-               }
-
-               if (framesize > info->max_frame_size + crc_size)
+               if (framesize > info->max_frame_size)
                        info->icount.rxlong++;
                else {
                        /* copy dma buffer(s) to contiguous temp buffer */
@@ -4450,11 +4413,6 @@ check_again:
                                        i = 0;
                        }
 
-                       if (info->params.crc_type & HDLC_CRC_RETURN_EX) {
-                               *p = (status & BIT1) ? RX_CRC_ERROR : RX_OK;
-                               framesize++;
-                       }
-
 #ifdef CONFIG_HDLC
                        if (info->netcount)
                                hdlcdev_rx(info,info->tmp_rbuf, framesize);
@@ -4713,13 +4671,13 @@ static int loopback_test(struct slgt_info *info)
 static int adapter_test(struct slgt_info *info)
 {
        DBGINFO(("testing %s\n", info->device_name));
-       if (register_test(info) < 0) {
+       if ((info->init_error = register_test(info)) < 0) {
                printk("register test failure %s addr=%08X\n",
                        info->device_name, info->phys_reg_addr);
-       } else if (irq_test(info) < 0) {
+       } else if ((info->init_error = irq_test(info)) < 0) {
                printk("IRQ test failure %s IRQ=%d\n",
                        info->device_name, info->irq_level);
-       } else if (loopback_test(info) < 0) {
+       } else if ((info->init_error = loopback_test(info)) < 0) {
                printk("loopback test failure %s\n", info->device_name);
        }
        return info->init_error;