fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / serial / icom.c
index c15c8a0..71e6a24 100644 (file)
@@ -24,8 +24,6 @@
   */
 #define SERIAL_DO_RESTART
 #include <linux/module.h>
-#include <linux/config.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/spinlock.h>
 #include <linux/kobject.h>
 #include <linux/firmware.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
-#include <asm/bitops.h>
 
 #include "icom.h"
 
@@ -105,25 +102,25 @@ static const struct pci_device_id icom_pci_table[] = {
 };
 
 struct lookup_proc_table start_proc[4] = {
-       {0, ICOM_CONTROL_START_A},
-       {0, ICOM_CONTROL_START_B},
-       {0, ICOM_CONTROL_START_C},
-       {0, ICOM_CONTROL_START_D}
+       {NULL, ICOM_CONTROL_START_A},
+       {NULL, ICOM_CONTROL_START_B},
+       {NULL, ICOM_CONTROL_START_C},
+       {NULL, ICOM_CONTROL_START_D}
 };
 
 
 struct lookup_proc_table stop_proc[4] = {
-       {0, ICOM_CONTROL_STOP_A},
-       {0, ICOM_CONTROL_STOP_B},
-       {0, ICOM_CONTROL_STOP_C},
-       {0, ICOM_CONTROL_STOP_D}
+       {NULL, ICOM_CONTROL_STOP_A},
+       {NULL, ICOM_CONTROL_STOP_B},
+       {NULL, ICOM_CONTROL_STOP_C},
+       {NULL, ICOM_CONTROL_STOP_D}
 };
 
 struct lookup_int_table int_mask_tbl[4] = {
-       {0, ICOM_INT_MASK_PRC_A},
-       {0, ICOM_INT_MASK_PRC_B},
-       {0, ICOM_INT_MASK_PRC_C},
-       {0, ICOM_INT_MASK_PRC_D},
+       {NULL, ICOM_INT_MASK_PRC_A},
+       {NULL, ICOM_INT_MASK_PRC_B},
+       {NULL, ICOM_INT_MASK_PRC_C},
+       {NULL, ICOM_INT_MASK_PRC_D},
 };
 
 
@@ -140,12 +137,6 @@ static inline void trace(struct icom_port *, char *, unsigned long) {};
 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
 #endif
 
-static void msleep(unsigned long msecs)
-{
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(MSECS_TO_JIFFIES(msecs));
-}
-
 static void free_port_memory(struct icom_port *icom_port)
 {
        struct pci_dev *dev = icom_port->adapter->pci_dev;
@@ -154,23 +145,23 @@ static void free_port_memory(struct icom_port *icom_port)
        if (icom_port->recv_buf) {
                pci_free_consistent(dev, 4096, icom_port->recv_buf,
                                    icom_port->recv_buf_pci);
-               icom_port->recv_buf = 0;
+               icom_port->recv_buf = NULL;
        }
        if (icom_port->xmit_buf) {
                pci_free_consistent(dev, 4096, icom_port->xmit_buf,
                                    icom_port->xmit_buf_pci);
-               icom_port->xmit_buf = 0;
+               icom_port->xmit_buf = NULL;
        }
        if (icom_port->statStg) {
                pci_free_consistent(dev, 4096, icom_port->statStg,
                                    icom_port->statStg_pci);
-               icom_port->statStg = 0;
+               icom_port->statStg = NULL;
        }
 
        if (icom_port->xmitRestart) {
                pci_free_consistent(dev, 4096, icom_port->xmitRestart,
                                    icom_port->xmitRestart_pci);
-               icom_port->xmitRestart = 0;
+               icom_port->xmitRestart = NULL;
        }
 }
 
@@ -350,17 +341,17 @@ static void start_processor(struct icom_port *icom_port)
 static void load_code(struct icom_port *icom_port)
 {
        const struct firmware *fw;
-       char *iram_ptr;
+       char __iomem *iram_ptr;
        int index;
        int status = 0;
-       char *dram_ptr = (char *) icom_port->dram;
+       void __iomem *dram_ptr = icom_port->dram;
        dma_addr_t temp_pci;
        unsigned char *new_page = NULL;
        unsigned char cable_id = NO_CABLE;
        struct pci_dev *dev = icom_port->adapter->pci_dev;
 
        /* Clear out any pending interrupts */
-       writew(0x3FFF, (void *) icom_port->int_reg);
+       writew(0x3FFF, icom_port->int_reg);
 
        trace(icom_port, "CLEAR_INTERRUPTS", 0);
 
@@ -384,7 +375,7 @@ static void load_code(struct icom_port *icom_port)
                goto load_code_exit;
        }
 
-       iram_ptr = (char *) icom_port->dram + ICOM_IRAM_OFFSET;
+       iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
        for (index = 0; index < fw->size; index++)
                writeb(fw->data[index], &iram_ptr[index]);
 
@@ -404,7 +395,7 @@ static void load_code(struct icom_port *icom_port)
                goto load_code_exit;
        }
 
-       iram_ptr = (char *) icom_port->dram + ICOM_IRAM_OFFSET;
+       iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
        for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
                writeb(fw->data[index], &iram_ptr[index]);
 
@@ -496,7 +487,7 @@ static void load_code(struct icom_port *icom_port)
 
        if (status != 0) {
                /* Clear out any pending interrupts */
-               writew(0x3FFF, (void *) icom_port->int_reg);
+               writew(0x3FFF, icom_port->int_reg);
 
                /* Turn off port */
                writeb(ICOM_DISABLE, &(icom_port->dram->disable));
@@ -520,8 +511,8 @@ static int startup(struct icom_port *icom_port)
 
        trace(icom_port, "STARTUP", 0);
 
-       if (icom_port->dram == 0x00000000) {
-               /* should NEVER be zero */
+       if (!icom_port->dram) {
+               /* should NEVER be NULL */
                dev_err(&icom_port->adapter->pci_dev->dev,
                        "Unusable Port, port configuration missing\n");
                return -ENODEV;
@@ -562,9 +553,9 @@ static int startup(struct icom_port *icom_port)
                int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
 
        if (port == 0 || port == 2)
-               writew(0x00FF,(void *) icom_port->int_reg);
+               writew(0x00FF, icom_port->int_reg);
        else
-               writew(0x3F00,(void *) icom_port->int_reg);
+               writew(0x3F00, icom_port->int_reg);
        if (port < 4) {
                temp = readl(int_mask_tbl[port].global_int_mask);
                writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
@@ -737,19 +728,20 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
        unsigned short int status;
        struct uart_icount *icount;
        unsigned long offset;
+       unsigned char flag;
 
        trace(icom_port, "RCV_COMPLETE", 0);
        rcv_buff = icom_port->next_rcv;
 
        status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
        while (status & SA_FL_RCV_DONE) {
+               int first = -1;
 
                trace(icom_port, "FID_STATUS", status);
                count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
 
+                count = tty_buffer_request_room(tty, count);
                trace(icom_port, "RCV_COUNT", count);
-               if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
-                       count = TTY_FLIPBUF_SIZE - tty->flip.count;
 
                trace(icom_port, "REAL_COUNT", count);
 
@@ -757,15 +749,10 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
                        cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
                        icom_port->recv_buf_pci;
 
-               memcpy(tty->flip.char_buf_ptr,(unsigned char *)
-                      ((unsigned long)icom_port->recv_buf + offset), count);
-
+               /* Block copy all but the last byte as this may have status */
                if (count > 0) {
-                       tty->flip.count += count - 1;
-                       tty->flip.char_buf_ptr += count - 1;
-
-                       memset(tty->flip.flag_buf_ptr, 0, count);
-                       tty->flip.flag_buf_ptr += count - 1;
+                       first = icom_port->recv_buf[offset];
+                       tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
                }
 
                icount = &icom_port->uart_port.icount;
@@ -773,12 +760,14 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 
                /* Break detect logic */
                if ((status & SA_FLAGS_FRAME_ERROR)
-                   && (tty->flip.char_buf_ptr[0] == 0x00)) {
+                   && first == 0) {
                        status &= ~SA_FLAGS_FRAME_ERROR;
                        status |= SA_FLAGS_BREAK_DET;
                        trace(icom_port, "BREAK_DET", 0);
                }
 
+               flag = TTY_NORMAL;
+
                if (status &
                    (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
                     SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
@@ -805,33 +794,26 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
                        status &= icom_port->read_status_mask;
 
                        if (status & SA_FLAGS_BREAK_DET) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (status & SA_FLAGS_PARITY_ERROR) {
                                trace(icom_port, "PARITY_ERROR", 0);
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        } else if (status & SA_FLAGS_FRAME_ERROR)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
-
-                       if (status & SA_FLAGS_OVERRUN) {
-                               /*
-                                * 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;
-                               }
-                       }
+                               flag = TTY_FRAME;
+
                }
 
-               tty->flip.flag_buf_ptr++;
-               tty->flip.char_buf_ptr++;
-               tty->flip.count++;
-               ignore_char:
-                       icom_port->statStg->rcv[rcv_buff].flags = 0;
+               tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
+
+               if (status & SA_FLAGS_OVERRUN)
+                       /*
+                        * Overrun is special, since it's
+                        * reported immediately, and doesn't
+                        * affect the current character
+                        */
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ignore_char:
+               icom_port->statStg->rcv[rcv_buff].flags = 0;
                icom_port->statStg->rcv[rcv_buff].leLength = 0;
                icom_port->statStg->rcv[rcv_buff].WorkingLength =
                        (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
@@ -862,10 +844,9 @@ static void process_interrupt(u16 port_int_reg,
        spin_unlock(&icom_port->uart_port.lock);
 }
 
-static irqreturn_t icom_interrupt(int irq, void *dev_id,
-                                 struct pt_regs *regs)
+static irqreturn_t icom_interrupt(int irq, void *dev_id)
 {
-       unsigned long int_reg;
+       void __iomem * int_reg;
        u32 adapter_interrupts;
        u16 port_int_reg;
        struct icom_adapter *icom_adapter;
@@ -877,7 +858,7 @@ static irqreturn_t icom_interrupt(int irq, void *dev_id,
        if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
                int_reg = icom_adapter->base_addr + 0x8024;
 
-               adapter_interrupts = readl((void *) int_reg);
+               adapter_interrupts = readl(int_reg);
 
                if (adapter_interrupts & 0x00003FFF) {
                        /* port 2 interrupt,  NOTE:  for all ADAPTER_V2, port 2 will be active */
@@ -898,14 +879,14 @@ static irqreturn_t icom_interrupt(int irq, void *dev_id,
                }
 
                /* Clear out any pending interrupts */
-               writel(adapter_interrupts, (void *) int_reg);
+               writel(adapter_interrupts, int_reg);
 
                int_reg = icom_adapter->base_addr + 0x8004;
        } else {
                int_reg = icom_adapter->base_addr + 0x4004;
        }
 
-       adapter_interrupts = readl((void *) int_reg);
+       adapter_interrupts = readl(int_reg);
 
        if (adapter_interrupts & 0x00003FFF) {
                /* port 0 interrupt, NOTE:  for all adapters, port 0 will be active */
@@ -925,10 +906,10 @@ static irqreturn_t icom_interrupt(int irq, void *dev_id,
        }
 
        /* Clear out any pending interrupts */
-       writel(adapter_interrupts, (void *) int_reg);
+       writel(adapter_interrupts, int_reg);
 
        /* flush the write */
-       adapter_interrupts = readl((void *) int_reg);
+       adapter_interrupts = readl(int_reg);
 
        return IRQ_HANDLED;
 }
@@ -996,18 +977,16 @@ static unsigned int icom_get_mctrl(struct uart_port *port)
        return result;
 }
 
-static void icom_stop_tx(struct uart_port *port, unsigned int tty_stop)
+static void icom_stop_tx(struct uart_port *port)
 {
        unsigned char cmdReg;
 
-       if (tty_stop) {
-               trace(ICOM_PORT, "STOP", 0);
-               cmdReg = readb(&ICOM_PORT->dram->CmdReg);
-               writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
-       }
+       trace(ICOM_PORT, "STOP", 0);
+       cmdReg = readb(&ICOM_PORT->dram->CmdReg);
+       writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
 }
 
-static void icom_start_tx(struct uart_port *port, unsigned int tty_start)
+static void icom_start_tx(struct uart_port *port)
 {
        unsigned char cmdReg;
 
@@ -1108,8 +1087,8 @@ static void icom_close(struct uart_port *port)
 }
 
 static void icom_set_termios(struct uart_port *port,
-                            struct termios *termios,
-                            struct termios *old_termios)
+                            struct ktermios *termios,
+                            struct ktermios *old_termios)
 {
        int baud;
        unsigned cflag, iflag;
@@ -1389,18 +1368,16 @@ static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
 {
        if (icom_adapter->version == ADAPTER_V1) {
-               icom_port->global_reg = (struct icom_regs *) ((char *)
-                       icom_adapter->base_addr + 0x4000);
-               icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
+               icom_port->global_reg = icom_adapter->base_addr + 0x4000;
+               icom_port->int_reg = icom_adapter->base_addr +
                    0x4004 + 2 - 2 * port_num;
        } else {
-               icom_port->global_reg = (struct icom_regs *) ((char *)
-                       icom_adapter->base_addr + 0x8000);
+               icom_port->global_reg = icom_adapter->base_addr + 0x8000;
                if (icom_port->port < 2)
-                       icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
+                       icom_port->int_reg = icom_adapter->base_addr +
                            0x8004 + 2 - 2 * icom_port->port;
                else
-                       icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
+                       icom_port->int_reg = icom_adapter->base_addr +
                            0x8024 + 2 - 2 * (icom_port->port - 2);
        }
 }
@@ -1416,9 +1393,8 @@ static int __init icom_load_ports(struct icom_adapter *icom_adapter)
 
                if (icom_port->status == ICOM_PORT_ACTIVE) {
                        icom_port_active(icom_port, icom_adapter, port_num);
-                       icom_port->dram = (struct func_dram *) ((char *)
-                                       icom_adapter->base_addr +
-                                       0x2000 * icom_port->port);
+                       icom_port->dram = icom_adapter->base_addr +
+                                       0x2000 * icom_port->port;
 
                        icom_port->adapter = icom_adapter;
 
@@ -1501,7 +1477,7 @@ static void icom_remove_adapter(struct icom_adapter *icom_adapter)
        }
 
        free_irq(icom_adapter->irq_number, (void *) icom_adapter);
-       iounmap((void *) icom_adapter->base_addr);
+       iounmap(icom_adapter->base_addr);
        icom_free_adapter(icom_adapter);
        pci_release_regions(icom_adapter->pci_dev);
 }
@@ -1534,7 +1510,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
        }
 
        if ( (retval = pci_request_regions(dev, "icom"))) {
-                dev_err(&dev->dev, "pci_request_region FAILED\n");
+                dev_err(&dev->dev, "pci_request_regions FAILED\n");
                 pci_disable_device(dev);
                 return retval;
         }
@@ -1578,8 +1554,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
                goto probe_exit1;
        }
 
-        icom_adapter->base_addr =
-            (unsigned long) ioremap(icom_adapter->base_addr_pci,
+        icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
                                                pci_resource_len(dev, 0));
 
        if (!icom_adapter->base_addr)
@@ -1587,7 +1562,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
 
         /* save off irq and request irq line */
         if ( (retval = request_irq(dev->irq, icom_interrupt,
-                                  SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
+                                  IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
                                   (void *) icom_adapter))) {
                  goto probe_exit2;
         }
@@ -1620,7 +1595,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
        return 0;
 
 probe_exit2:
-       iounmap((void *) icom_adapter->base_addr);
+       iounmap(icom_adapter->base_addr);
 probe_exit1:
        icom_free_adapter(icom_adapter);
 
@@ -1662,7 +1637,6 @@ static int __init icom_init(void)
        int ret;
 
        spin_lock_init(&icom_lock);
-       icom_lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
 
        ret = uart_register_driver(&icom_uart_driver);
        if (ret)