]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - drivers/char/cyclades.c
WorkStruct: make allyesconfig
[linux-3.10.git] / drivers / char / cyclades.c
index cf4c3648463dbf8d0cd28c9079be19e110dbefa4..acb2de5e3a985db72fa6c94c05017ca162a9d7b1 100644 (file)
@@ -281,7 +281,7 @@ static char rcsid[] =
  * make sure "cyc" appears in all kernel messages; all soft interrupts
  * handled by same routine; recognize out-of-band reception; comment
  * out some diagnostic messages; leave RTS/CTS flow control to hardware;
- * fix race condition in -Z buffer management; only -Y needs to explictly
+ * fix race condition in -Z buffer management; only -Y needs to explicitly
  * flush chars; tidy up some startup messages;
  *
  * Revision 1.36.4.18  1996/07/25 18:57:31  bentson
@@ -633,7 +633,6 @@ static char rcsid[] =
 /*
  * Include section 
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
@@ -641,6 +640,7 @@ static char rcsid[] =
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/major.h>
 #include <linux/string.h>
@@ -723,7 +723,7 @@ static unsigned int cy_isa_addresses[] = {
         0xDE000,
         0,0,0,0,0,0,0,0
 };
-#define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
+#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
 
 #ifdef MODULE
 static long maddr[NR_CARDS] = { 0, };
@@ -747,18 +747,6 @@ static struct cyclades_port cy_port[NR_PORTS];
 
 static int cy_next_channel; /* next minor available */
 
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.  This buffer is
- * allocated when the first cy_open occurs.
- */
-static unsigned char *tmp_buf;
-
 /*
  * This is used to look up the divisor speeds and the timeouts
  * We're normally limited to 15 distinct baud rates.  The extra
@@ -938,9 +926,10 @@ cy_sched_event(struct cyclades_port *info, int event)
  * had to poll every port to see if that port needed servicing.
  */
 static void
-do_softint(void *private_)
+do_softint(struct work_struct *work)
 {
-  struct cyclades_port *info = (struct cyclades_port *) private_;
+       struct cyclades_port *info =
+               container_of(work, struct cyclades_port, tqueue);
   struct tty_struct    *tty;
 
     tty = info->tty;
@@ -1069,7 +1058,7 @@ detect_isa_irq(void __iomem *address)
    received, out buffer empty, modem change, etc.
  */
 static irqreturn_t
-cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+cyy_interrupt(int irq, void *dev_id)
 {
   struct tty_struct *tty;
   int status;
@@ -1086,7 +1075,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   int had_work;
   int mdm_change;
   int mdm_status;
-
+  int len;
     if((cinfo = (struct cyclades_card *)dev_id) == 0){
 #ifdef CY_DEBUG_INTERRUPTS
        printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
@@ -1163,63 +1152,43 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                info->icount.rx++;
                                 continue;
                             }
-                            if (tty->flip.count < TTY_FLIPBUF_SIZE){
-                                tty->flip.count++;
+                            if (tty_buffer_request_room(tty, 1)) {
                                 if (data & info->read_status_mask){
                                     if(data & CyBREAK){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_BREAK;
-                                        *tty->flip.char_buf_ptr++ =
-                                         cy_readb(base_addr+(CyRDSR<<index));
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK);
                                        info->icount.rx++;
                                         if (info->flags & ASYNC_SAK){
                                             do_SAK(tty);
                                         }
                                     }else if(data & CyFRAME){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_FRAME;
-                                        *tty->flip.char_buf_ptr++ =
-                                         cy_readb(base_addr+(CyRDSR<<index));
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
                                        info->icount.rx++;
                                        info->idle_stats.frame_errs++;
                                     }else if(data & CyPARITY){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_PARITY;
-                                        *tty->flip.char_buf_ptr++ =
-                                         cy_readb(base_addr+(CyRDSR<<index));
+                                       /* Pieces of seven... */
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY);
                                        info->icount.rx++;
                                        info->idle_stats.parity_errs++;
                                     }else if(data & CyOVERRUN){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_OVERRUN;
-                                        *tty->flip.char_buf_ptr++ = 0;
+                                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                                        info->icount.rx++;
                                         /* If the flip buffer itself is
                                            overflowing, we still lose
                                            the next incoming character.
                                          */
-                                        if(tty->flip.count
-                                                  < TTY_FLIPBUF_SIZE){
-                                            tty->flip.count++;
-                                            *tty->flip.flag_buf_ptr++ =
-                                                            TTY_NORMAL;
-                                           *tty->flip.char_buf_ptr++ =
-                                           cy_readb(base_addr+(CyRDSR<<index));
-                                           info->icount.rx++;
-                                        }
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
+                                       info->icount.rx++;
                                        info->idle_stats.overruns++;
                                     /* These two conditions may imply */
                                     /* a normal read should be done. */
                                     /* }else if(data & CyTIMEOUT){ */
                                     /* }else if(data & CySPECHAR){ */
-                                    }else{
-                                        *tty->flip.flag_buf_ptr++ = 0;
-                                        *tty->flip.char_buf_ptr++ = 0;
-                                       info->icount.rx++;
+                                    }else {
+                                       tty_insert_flip_char(tty, 0, TTY_NORMAL);
+                                       info->icount.rx++;
                                     }
                                 }else{
-                                    *tty->flip.flag_buf_ptr++ = 0;
-                                    *tty->flip.char_buf_ptr++ = 0;
+                                   tty_insert_flip_char(tty, 0, TTY_NORMAL);
                                    info->icount.rx++;
                                 }
                             }else{
@@ -1240,14 +1209,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                info->mon.char_max = char_count;
                             info->mon.char_last = char_count;
 #endif
-                            while(char_count--){
-                                if (tty->flip.count >= TTY_FLIPBUF_SIZE){
-                                        break;
-                                }
-                                tty->flip.count++;
+                           len = tty_buffer_request_room(tty, char_count);
+                            while(len--){
                                 data = cy_readb(base_addr+(CyRDSR<<index));
-                                *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                                *tty->flip.char_buf_ptr++ = data;
+                               tty_insert_flip_char(tty, data, TTY_NORMAL);
                                info->idle_stats.recv_bytes++;
                                info->icount.rx++;
 #ifdef CY_16Y_HACK
@@ -1256,7 +1221,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                             }
                              info->idle_stats.recv_idle = jiffies;
                         }
-                        schedule_delayed_work(&tty->flip.work, 1);
+                       tty_schedule_flip(tty);
                     }
                     /* end of service */
                     cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f));
@@ -1551,6 +1516,7 @@ cyz_handle_rx(struct cyclades_port *info,
   struct cyclades_card *cinfo = &cy_card[info->card];
   struct tty_struct *tty = info->tty;
   volatile int char_count;
+  int len;
 #ifdef BLOCKMOVE
   int small_count;
 #else
@@ -1606,18 +1572,11 @@ cyz_handle_rx(struct cyclades_port *info,
                tty->flip.count += small_count;
            }
 #else
-           while(char_count--){
-               if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt)
-                    break;
-
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                   break;
-
+           len = tty_buffer_request_room(tty, char_count);
+           while(len--){
                data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get);
                new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1);
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-               *tty->flip.char_buf_ptr++ = data;
+               tty_insert_flip_char(tty, data, TTY_NORMAL);
                info->idle_stats.recv_bytes++;
                info->icount.rx++;
            }
@@ -1635,7 +1594,7 @@ cyz_handle_rx(struct cyclades_port *info,
            }
 #endif
            info->idle_stats.recv_idle = jiffies;
-           schedule_delayed_work(&tty->flip.work, 1);
+           tty_schedule_flip(tty);
        }
        /* Update rx_get */
        cy_writel(&buf_ctrl->rx_get, new_rx_get);
@@ -1763,23 +1722,17 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
 
        switch(cmd) {
            case C_CM_PR_ERROR:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
-               *tty->flip.char_buf_ptr++ = 0;
+               tty_insert_flip_char(tty, 0, TTY_PARITY);
                info->icount.rx++;
                special_count++;
                break;
            case C_CM_FR_ERROR:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-               *tty->flip.char_buf_ptr++ = 0;
+               tty_insert_flip_char(tty, 0, TTY_FRAME);
                info->icount.rx++;
                special_count++;
                break;
            case C_CM_RXBRK:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-               *tty->flip.char_buf_ptr++ = 0;
+               tty_insert_flip_char(tty, 0, TTY_BREAK);
                info->icount.rx++;
                special_count++;
                break;
@@ -1844,13 +1797,13 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
        if(delta_count)
            cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
        if(special_count)
-           schedule_delayed_work(&tty->flip.work, 1);
+           tty_schedule_flip(tty);
     }
 }
 
 #ifdef CONFIG_CYZ_INTR
 static irqreturn_t
-cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+cyz_interrupt(int irq, void *dev_id)
 {
   struct cyclades_card *cinfo;
 
@@ -2502,7 +2455,6 @@ cy_open(struct tty_struct *tty, struct file * filp)
 {
   struct cyclades_port  *info;
   int retval, line;
-  unsigned long page;
 
     line = tty->index;
     if ((line < 0) || (NR_PORTS <= line)){
@@ -2581,15 +2533,6 @@ cy_open(struct tty_struct *tty, struct file * filp)
     printk("cyc:cy_open (%d): incrementing count to %d\n",
         current->pid, info->count);
 #endif
-    if (!tmp_buf) {
-       page = get_zeroed_page(GFP_KERNEL);
-       if (!page)
-           return -ENOMEM;
-       if (tmp_buf)
-           free_page(page);
-       else
-           tmp_buf = (unsigned char *) page;
-    }
 
     /*
      * If the port is the middle of closing, bail out now
@@ -2868,9 +2811,8 @@ cy_write(struct tty_struct * tty, const unsigned char *buf, int count)
         return 0;
     }
         
-    if (!tty || !info->xmit_buf || !tmp_buf){
-        return 0;
-    }
+    if (!info->xmit_buf)
+       return 0;
 
     CY_LOCK(info, flags);
     while (1) {
@@ -2919,7 +2861,7 @@ cy_put_char(struct tty_struct *tty, unsigned char ch)
     if (serial_paranoia_check(info, tty->name, "cy_put_char"))
         return;
 
-    if (!tty || !info->xmit_buf)
+    if (!info->xmit_buf)
         return;
 
     CY_LOCK(info, flags);
@@ -4649,7 +4591,7 @@ cy_detect_isa(void)
 
                 /* allocate IRQ */
                 if(request_irq(cy_isa_irq, cyy_interrupt,
-                                  SA_INTERRUPT, "Cyclom-Y", &cy_card[j]))
+                                  IRQF_DISABLED, "Cyclom-Y", &cy_card[j]))
                 {
                         printk("Cyclom-Y/ISA found at 0x%lx ",
                                 (unsigned long) cy_isa_address);
@@ -4822,7 +4764,7 @@ cy_detect_pci(void)
 
                 /* allocate IRQ */
                 if(request_irq(cy_pci_irq, cyy_interrupt,
-                       SA_SHIRQ, "Cyclom-Y", &cy_card[j]))
+                       IRQF_SHARED, "Cyclom-Y", &cy_card[j]))
                 {
                         printk("Cyclom-Y/PCI found at 0x%lx ",
                            (ulong) cy_pci_phys2);
@@ -5002,7 +4944,7 @@ cy_detect_pci(void)
                 /* allocate IRQ only if board has an IRQ */
                if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
                    if(request_irq(cy_pci_irq, cyz_interrupt,
-                       SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
+                       IRQF_SHARED, "Cyclades-Z", &cy_card[j]))
                    {
                         printk("Cyclom-8Zo/PCI found at 0x%lx ",
                            (ulong) cy_pci_phys2);
@@ -5096,7 +5038,7 @@ cy_detect_pci(void)
                 /* allocate IRQ only if board has an IRQ */
                if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
                    if(request_irq(cy_pci_irq, cyz_interrupt,
-                       SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
+                       IRQF_SHARED, "Cyclades-Z", &cy_card[j]))
                    {
                         printk("Cyclom-Ze/PCI found at 0x%lx ",
                            (ulong) cy_pci_phys2);
@@ -5242,7 +5184,7 @@ done:
     extra ports are ignored.
  */
 
-static struct tty_operations cy_ops = {
+static const struct tty_operations cy_ops = {
     .open = cy_open,
     .close = cy_close,
     .write = cy_write,
@@ -5286,7 +5228,6 @@ cy_init(void)
     cy_serial_driver->owner = THIS_MODULE;
     cy_serial_driver->driver_name = "cyclades";
     cy_serial_driver->name = "ttyC";
-    cy_serial_driver->devfs_name = "tts/C";
     cy_serial_driver->major = CYCLADES_MAJOR;
     cy_serial_driver->minor_start = 0;
     cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
@@ -5388,7 +5329,7 @@ cy_init(void)
                     info->blocked_open = 0;
                     info->default_threshold = 0;
                     info->default_timeout = 0;
-                   INIT_WORK(&info->tqueue, do_softint, info);
+                   INIT_WORK(&info->tqueue, do_softint);
                    init_waitqueue_head(&info->open_wait);
                    init_waitqueue_head(&info->close_wait);
                    init_waitqueue_head(&info->shutdown_wait);
@@ -5463,7 +5404,7 @@ cy_init(void)
                     info->blocked_open = 0;
                     info->default_threshold = 0;
                     info->default_timeout = 0;
-                   INIT_WORK(&info->tqueue, do_softint, info);
+                   INIT_WORK(&info->tqueue, do_softint);
                    init_waitqueue_head(&info->open_wait);
                    init_waitqueue_head(&info->close_wait);
                    init_waitqueue_head(&info->shutdown_wait);
@@ -5528,10 +5469,6 @@ cy_cleanup_module(void)
 #endif
         }
     }
-    if (tmp_buf) {
-       free_page((unsigned long) tmp_buf);
-       tmp_buf = NULL;
-    }
 } /* cy_cleanup_module */
 
 module_init(cy_init);