linux/drivers/char/serial167.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/char/serial167.c
   3 *
   4 * Driver for MVME166/7 board serial ports, which are via a CD2401.
   5 * Based very much on cyclades.c.
   6 *
   7 * MVME166/7 work by Richard Hirst [richard@sleepie.demon.co.uk]
   8 *
   9 * ==============================================================
  10 *
  11 * static char rcsid[] =
  12 * "$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $";
  13 *
  14 *  linux/kernel/cyclades.c
  15 *
  16 * Maintained by Marcio Saito (cyclades@netcom.com) and
  17 * Randolph Bentson (bentson@grieg.seaslug.org)
  18 *
  19 * Much of the design and some of the code came from serial.c
  20 * which was copyright (C) 1991, 1992  Linus Torvalds.  It was
  21 * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
  22 * and then fixed as suggested by Michael K. Johnson 12/12/92.
  23 *
  24 * This version does not support shared irq's.
  25 *
  26 * $Log: cyclades.c,v $
  27 * Revision 1.36.1.4  1995/03/29  06:14:14  bentson
  28 * disambiguate between Cyclom-16Y and Cyclom-32Ye;
  29 *
  30 * Changes:
  31 *
  32 * 200 lines of changes record removed - RGH 11-10-95, starting work on
  33 * converting this to drive serial ports on mvme166 (cd2401).
  34 *
  35 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/08/25
  36 * - get rid of verify_area
  37 * - use get_user to access memory from userspace in set_threshold,
  38 *   set_default_threshold and set_timeout
  39 * - don't use the panic function in serial167_init
  40 * - do resource release on failure on serial167_init
  41 * - include missing restore_flags in mvme167_serial_console_setup
  42 *
  43 * Kars de Jong <jongk@linux-m68k.org> - 2004/09/06
  44 * - replace bottom half handler with task queue handler
  45 */
  46
  47#include <linux/errno.h>
  48#include <linux/signal.h>
  49#include <linux/sched.h>
  50#include <linux/timer.h>
  51#include <linux/tty.h>
  52#include <linux/interrupt.h>
  53#include <linux/serial.h>
  54#include <linux/serialP.h>
  55#include <linux/string.h>
  56#include <linux/fcntl.h>
  57#include <linux/ptrace.h>
  58#include <linux/serial167.h>
  59#include <linux/delay.h>
  60#include <linux/major.h>
  61#include <linux/mm.h>
  62#include <linux/console.h>
  63#include <linux/module.h>
  64#include <linux/bitops.h>
  65#include <linux/tty_flip.h>
  66
  67#include <asm/system.h>
  68#include <asm/io.h>
  69#include <asm/mvme16xhw.h>
  70#include <asm/bootinfo.h>
  71#include <asm/setup.h>
  72
  73#include <linux/types.h>
  74#include <linux/kernel.h>
  75
  76#include <asm/uaccess.h>
  77#include <linux/init.h>
  78
  79#define SERIAL_PARANOIA_CHECK
  80#undef  SERIAL_DEBUG_OPEN
  81#undef  SERIAL_DEBUG_THROTTLE
  82#undef  SERIAL_DEBUG_OTHER
  83#undef  SERIAL_DEBUG_IO
  84#undef  SERIAL_DEBUG_COUNT
  85#undef  SERIAL_DEBUG_DTR
  86#undef  CYCLOM_16Y_HACK
  87#define  CYCLOM_ENABLE_MONITORING
  88
  89#define WAKEUP_CHARS 256
  90
  91#define STD_COM_FLAGS (0)
  92
  93#define SERIAL_TYPE_NORMAL  1
  94
  95static struct tty_driver *cy_serial_driver;
  96extern int serial_console;
  97static struct cyclades_port *serial_console_info = NULL;
  98static unsigned int serial_console_cflag = 0;
  99u_char initial_console_speed;
 100
 101/* Base address of cd2401 chip on mvme166/7 */
 102
 103#define BASE_ADDR (0xfff45000)
 104#define pcc2chip        ((volatile u_char *)0xfff42000)
 105#define PccSCCMICR      0x1d
 106#define PccSCCTICR      0x1e
 107#define PccSCCRICR      0x1f
 108#define PccTPIACKR      0x25
 109#define PccRPIACKR      0x27
 110#define PccIMLR         0x3f
 111
 112/* This is the per-port data structure */
 113struct cyclades_port cy_port[] = {
 114        /* CARD#  */
 115        {-1},                   /* ttyS0 */
 116        {-1},                   /* ttyS1 */
 117        {-1},                   /* ttyS2 */
 118        {-1},                   /* ttyS3 */
 119};
 120
 121#define NR_PORTS        ARRAY_SIZE(cy_port)
 122
 123/*
 124 * This is used to look up the divisor speeds and the timeouts
 125 * We're normally limited to 15 distinct baud rates.  The extra
 126 * are accessed via settings in info->flags.
 127 *         0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
 128 *        10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
 129 *                                                  HI            VHI
 130 */
 131static int baud_table[] = {
 132        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
 133        1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
 134        0
 135};
 136
 137#if 0
 138static char baud_co[] = {       /* 25 MHz clock option table */
 139        /* value =>    00    01   02    03    04 */
 140        /* divide by    8    32   128   512  2048 */
 141        0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
 142        0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 143};
 144
 145static char baud_bpr[] = {      /* 25 MHz baud rate period table */
 146        0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
 147        0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
 148};
 149#endif
 150
 151/* I think 166 brd clocks 2401 at 20MHz.... */
 152
 153/* These values are written directly to tcor, and >> 5 for writing to rcor */
 154static u_char baud_co[] = {     /* 20 MHz clock option table */
 155        0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40,
 156        0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 157};
 158
 159/* These values written directly to tbpr/rbpr */
 160static u_char baud_bpr[] = {    /* 20 MHz baud rate period table */
 161        0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81,
 162        0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10
 163};
 164
 165static u_char baud_cor4[] = {   /* receive threshold */
 166        0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 167        0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07
 168};
 169
 170static void shutdown(struct cyclades_port *);
 171static int startup(struct cyclades_port *);
 172static void cy_throttle(struct tty_struct *);
 173static void cy_unthrottle(struct tty_struct *);
 174static void config_setup(struct cyclades_port *);
 175extern void console_print(const char *);
 176#ifdef CYCLOM_SHOW_STATUS
 177static void show_status(int);
 178#endif
 179
 180#ifdef CONFIG_REMOTE_DEBUG
 181static void debug_setup(void);
 182void queueDebugChar(int c);
 183int getDebugChar(void);
 184
 185#define DEBUG_PORT      1
 186#define DEBUG_LEN       256
 187
 188typedef struct {
 189        int in;
 190        int out;
 191        unsigned char buf[DEBUG_LEN];
 192} debugq;
 193
 194debugq debugiq;
 195#endif
 196
 197/*
 198 * I have my own version of udelay(), as it is needed when initialising
 199 * the chip, before the delay loop has been calibrated.  Should probably
 200 * reference one of the vmechip2 or pccchip2 counter for an accurate
 201 * delay, but this wild guess will do for now.
 202 */
 203
 204void my_udelay(long us)
 205{
 206        u_char x;
 207        volatile u_char *p = &x;
 208        int i;
 209
 210        while (us--)
 211                for (i = 100; i; i--)
 212                        x |= *p;
 213}
 214
 215static inline int serial_paranoia_check(struct cyclades_port *info, char *name,
 216                const char *routine)
 217{
 218#ifdef SERIAL_PARANOIA_CHECK
 219        if (!info) {
 220                printk("Warning: null cyclades_port for (%s) in %s\n", name,
 221                                routine);
 222                return 1;
 223        }
 224
 225        if ((long)info < (long)(&cy_port[0])
 226            || (long)(&cy_port[NR_PORTS]) < (long)info) {
 227                printk("Warning: cyclades_port out of range for (%s) in %s\n",
 228                                name, routine);
 229                return 1;
 230        }
 231
 232        if (info->magic != CYCLADES_MAGIC) {
 233                printk("Warning: bad magic number for serial struct (%s) in "
 234                                "%s\n", name, routine);
 235                return 1;
 236        }
 237#endif
 238        return 0;
 239}                               /* serial_paranoia_check */
 240
 241#if 0
 242/* The following diagnostic routines allow the driver to spew
 243   information on the screen, even (especially!) during interrupts.
 244 */
 245void SP(char *data)
 246{
 247        unsigned long flags;
 248        local_irq_save(flags);
 249        console_print(data);
 250        local_irq_restore(flags);
 251}
 252
 253char scrn[2];
 254void CP(char data)
 255{
 256        unsigned long flags;
 257        local_irq_save(flags);
 258        scrn[0] = data;
 259        console_print(scrn);
 260        local_irq_restore(flags);
 261}                               /* CP */
 262
 263void CP1(int data)
 264{
 265        (data < 10) ? CP(data + '0') : CP(data + 'A' - 10);
 266}                               /* CP1 */
 267void CP2(int data)
 268{
 269        CP1((data >> 4) & 0x0f);
 270        CP1(data & 0x0f);
 271}                               /* CP2 */
 272void CP4(int data)
 273{
 274        CP2((data >> 8) & 0xff);
 275        CP2(data & 0xff);
 276}                               /* CP4 */
 277void CP8(long data)
 278{
 279        CP4((data >> 16) & 0xffff);
 280        CP4(data & 0xffff);
 281}                               /* CP8 */
 282#endif
 283
 284/* This routine waits up to 1000 micro-seconds for the previous
 285   command to the Cirrus chip to complete and then issues the
 286   new command.  An error is returned if the previous command
 287   didn't finish within the time limit.
 288 */
 289u_short write_cy_cmd(volatile u_char * base_addr, u_char cmd)
 290{
 291        unsigned long flags;
 292        volatile int i;
 293
 294        local_irq_save(flags);
 295        /* Check to see that the previous command has completed */
 296        for (i = 0; i < 100; i++) {
 297                if (base_addr[CyCCR] == 0) {
 298                        break;
 299                }
 300                my_udelay(10L);
 301        }
 302        /* if the CCR never cleared, the previous command
 303           didn't finish within the "reasonable time" */
 304        if (i == 10) {
 305                local_irq_restore(flags);
 306                return (-1);
 307        }
 308
 309        /* Issue the new command */
 310        base_addr[CyCCR] = cmd;
 311        local_irq_restore(flags);
 312        return (0);
 313}                               /* write_cy_cmd */
 314
 315/* cy_start and cy_stop provide software output flow control as a
 316   function of XON/XOFF, software CTS, and other such stuff. */
 317
 318static void cy_stop(struct tty_struct *tty)
 319{
 320        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 321        volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
 322        int channel;
 323        unsigned long flags;
 324
 325#ifdef SERIAL_DEBUG_OTHER
 326        printk("cy_stop %s\n", tty->name);      /* */
 327#endif
 328
 329        if (serial_paranoia_check(info, tty->name, "cy_stop"))
 330                return;
 331
 332        channel = info->line;
 333
 334        local_irq_save(flags);
 335        base_addr[CyCAR] = (u_char) (channel);  /* index channel */
 336        base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
 337        local_irq_restore(flags);
 338}                               /* cy_stop */
 339
 340static void cy_start(struct tty_struct *tty)
 341{
 342        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 343        volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
 344        int channel;
 345        unsigned long flags;
 346
 347#ifdef SERIAL_DEBUG_OTHER
 348        printk("cy_start %s\n", tty->name);     /* */
 349#endif
 350
 351        if (serial_paranoia_check(info, tty->name, "cy_start"))
 352                return;
 353
 354        channel = info->line;
 355
 356        local_irq_save(flags);
 357        base_addr[CyCAR] = (u_char) (channel);
 358        base_addr[CyIER] |= CyTxMpty;
 359        local_irq_restore(flags);
 360}                               /* cy_start */
 361
 362/*
 363 * This routine is used by the interrupt handler to schedule
 364 * processing in the software interrupt portion of the driver
 365 * (also known as the "bottom half").  This can be called any
 366 * number of times for any channel without harm.
 367 */
 368static inline void cy_sched_event(struct cyclades_port *info, int event)
 369{
 370        info->event |= 1 << event;      /* remember what kind of event and who */
 371        schedule_work(&info->tqueue);
 372}                               /* cy_sched_event */
 373
 374/* The real interrupt service routines are called
 375   whenever the card wants its hand held--chars
 376   received, out buffer empty, modem change, etc.
 377 */
 378static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id)
 379{
 380        struct tty_struct *tty;
 381        struct cyclades_port *info;
 382        volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
 383        unsigned char err, rfoc;
 384        int channel;
 385        char data;
 386
 387        /* determine the channel and change to that context */
 388        channel = (u_short) (base_addr[CyLICR] >> 2);
 389        info = &cy_port[channel];
 390        info->last_active = jiffies;
 391
 392        if ((err = base_addr[CyRISR]) & CyTIMEOUT) {
 393                /* This is a receive timeout interrupt, ignore it */
 394                base_addr[CyREOIR] = CyNOTRANS;
 395                return IRQ_HANDLED;
 396        }
 397
 398        /* Read a byte of data if there is any - assume the error
 399         * is associated with this character */
 400
 401        if ((rfoc = base_addr[CyRFOC]) != 0)
 402                data = base_addr[CyRDR];
 403        else
 404                data = 0;
 405
 406        /* if there is nowhere to put the data, discard it */
 407        if (info->tty == 0) {
 408                base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
 409                return IRQ_HANDLED;
 410        } else {                /* there is an open port for this data */
 411                tty = info->tty;
 412                if (err & info->ignore_status_mask) {
 413                        base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
 414                        return IRQ_HANDLED;
 415                }
 416                if (tty_buffer_request_room(tty, 1) != 0) {
 417                        if (err & info->read_status_mask) {
 418                                if (err & CyBREAK) {
 419                                        tty_insert_flip_char(tty, data,
 420                                                             TTY_BREAK);
 421                                        if (info->flags & ASYNC_SAK) {
 422                                                do_SAK(tty);
 423                                        }
 424                                } else if (err & CyFRAME) {
 425                                        tty_insert_flip_char(tty, data,
 426                                                             TTY_FRAME);
 427                                } else if (err & CyPARITY) {
 428                                        tty_insert_flip_char(tty, data,
 429                                                             TTY_PARITY);
 430                                } else if (err & CyOVERRUN) {
 431                                        tty_insert_flip_char(tty, 0,
 432                                                             TTY_OVERRUN);
 433                                        /*
 434                                           If the flip buffer itself is
 435                                           overflowing, we still loose
 436                                           the next incoming character.
 437                                         */
 438                                        if (tty_buffer_request_room(tty, 1) !=
 439                                            0) {
 440                                                tty_insert_flip_char(tty, data,
 441                                                                     TTY_FRAME);
 442                                        }
 443                                        /* These two conditions may imply */
 444                                        /* a normal read should be done. */
 445                                        /* else if(data & CyTIMEOUT) */
 446                                        /* else if(data & CySPECHAR) */
 447                                } else {
 448                                        tty_insert_flip_char(tty, 0,
 449                                                             TTY_NORMAL);
 450                                }
 451                        } else {
 452                                tty_insert_flip_char(tty, data, TTY_NORMAL);
 453                        }
 454                } else {
 455                        /* there was a software buffer overrun
 456                           and nothing could be done about it!!! */
 457                }
 458        }
 459        tty_schedule_flip(tty);
 460        /* end of service */
 461        base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
 462        return IRQ_HANDLED;
 463}                               /* cy_rxerr_interrupt */
 464
 465static irqreturn_t cd2401_modem_interrupt(int irq, void *dev_id)
 466{
 467        struct cyclades_port *info;
 468        volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
 469        int channel;
 470        int mdm_change;
 471        int mdm_status;
 472
 473        /* determine the channel and change to that context */
 474        channel = (u_short) (base_addr[CyLICR] >> 2);
 475        info = &cy_port[channel];
 476        info->last_active = jiffies;
 477
 478        mdm_change = base_addr[CyMISR];
 479        mdm_status = base_addr[CyMSVR1];
 480
 481        if (info->tty == 0) {   /* nowhere to put the data, ignore it */
 482                ;
 483        } else {
 484                if ((mdm_change & CyDCD)
 485                    && (info->flags & ASYNC_CHECK_CD)) {
 486                        if (mdm_status & CyDCD) {
 487/* CP('!'); */
 488                                cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
 489                        } else {
 490/* CP('@'); */
 491                                cy_sched_event(info, Cy_EVENT_HANGUP);
 492                        }
 493                }
 494                if ((mdm_change & CyCTS)
 495                    && (info->flags & ASYNC_CTS_FLOW)) {
 496                        if (info->tty->stopped) {
 497                                if (mdm_status & CyCTS) {
 498                                        /* !!! cy_start isn't used because... */
 499                                        info->tty->stopped = 0;
 500                                        base_addr[CyIER] |= CyTxMpty;
 501                                        cy_sched_event(info,
 502                                                       Cy_EVENT_WRITE_WAKEUP);
 503                                }
 504                        } else {
 505                                if (!(mdm_status & CyCTS)) {
 506                                        /* !!! cy_stop isn't used because... */
 507                                        info->tty->stopped = 1;
 508                                        base_addr[CyIER] &=
 509                                            ~(CyTxMpty | CyTxRdy);
 510                                }
 511                        }
 512                }
 513                if (mdm_status & CyDSR) {
 514                }
 515        }
 516        base_addr[CyMEOIR] = 0;
 517        return IRQ_HANDLED;
 518}                               /* cy_modem_interrupt */
 519
 520static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id)
 521{
 522        struct cyclades_port *info;
 523        volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
 524        int channel;
 525        int char_count, saved_cnt;
 526        int outch;
 527
 528        /* determine the channel and change to that context */
 529        channel = (u_short) (base_addr[CyLICR] >> 2);
 530
 531#ifdef CONFIG_REMOTE_DEBUG
 532        if (channel == DEBUG_PORT) {
 533                panic("TxInt on debug port!!!");
 534        }
 535#endif
 536
 537        info = &cy_port[channel];
 538
 539        /* validate the port number (as configured and open) */
 540        if ((channel < 0) || (NR_PORTS <= channel)) {
 541                base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
 542                base_addr[CyTEOIR] = CyNOTRANS;
 543                return IRQ_HANDLED;
 544        }
 545        info->last_active = jiffies;
 546        if (info->tty == 0) {
 547                base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
 548                if (info->xmit_cnt < WAKEUP_CHARS) {
 549                        cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
 550                }
 551                base_addr[CyTEOIR] = CyNOTRANS;
 552                return IRQ_HANDLED;
 553        }
 554
 555        /* load the on-chip space available for outbound data */
 556        saved_cnt = char_count = base_addr[CyTFTC];
 557
 558        if (info->x_char) {     /* send special char */
 559                outch = info->x_char;
 560                base_addr[CyTDR] = outch;
 561                char_count--;
 562                info->x_char = 0;
 563        }
 564
 565        if (info->x_break) {
 566                /*  The Cirrus chip requires the "Embedded Transmit
 567                   Commands" of start break, delay, and end break
 568                   sequences to be sent.  The duration of the
 569                   break is given in TICs, which runs at HZ
 570                   (typically 100) and the PPR runs at 200 Hz,
 571                   so the delay is duration * 200/HZ, and thus a
 572                   break can run from 1/100 sec to about 5/4 sec.
 573                   Need to check these values - RGH 141095.
 574                 */
 575                base_addr[CyTDR] = 0;   /* start break */
 576                base_addr[CyTDR] = 0x81;
 577                base_addr[CyTDR] = 0;   /* delay a bit */
 578                base_addr[CyTDR] = 0x82;
 579                base_addr[CyTDR] = info->x_break * 200 / HZ;
 580                base_addr[CyTDR] = 0;   /* terminate break */
 581                base_addr[CyTDR] = 0x83;
 582                char_count -= 7;
 583                info->x_break = 0;
 584        }
 585
 586        while (char_count > 0) {
 587                if (!info->xmit_cnt) {
 588                        base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
 589                        break;
 590                }
 591                if (info->xmit_buf == 0) {
 592                        base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
 593                        break;
 594                }
 595                if (info->tty->stopped || info->tty->hw_stopped) {
 596                        base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
 597                        break;
 598                }
 599                /* Because the Embedded Transmit Commands have been
 600                   enabled, we must check to see if the escape
 601                   character, NULL, is being sent.  If it is, we
 602                   must ensure that there is room for it to be
 603                   doubled in the output stream.  Therefore we
 604                   no longer advance the pointer when the character
 605                   is fetched, but rather wait until after the check
 606                   for a NULL output character. (This is necessary
 607                   because there may not be room for the two chars
 608                   needed to send a NULL.
 609                 */
 610                outch = info->xmit_buf[info->xmit_tail];
 611                if (outch) {
 612                        info->xmit_cnt--;
 613                        info->xmit_tail = (info->xmit_tail + 1)
 614                            & (PAGE_SIZE - 1);
 615                        base_addr[CyTDR] = outch;
 616                        char_count--;
 617                } else {
 618                        if (char_count > 1) {
 619                                info->xmit_cnt--;
 620                                info->xmit_tail = (info->xmit_tail + 1)
 621                                    & (PAGE_SIZE - 1);
 622                                base_addr[CyTDR] = outch;
 623                                base_addr[CyTDR] = 0;
 624                                char_count--;
 625                                char_count--;
 626                        } else {
 627                                break;
 628                        }
 629                }
 630        }
 631
 632        if (info->xmit_cnt < WAKEUP_CHARS) {
 633                cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
 634        }
 635        base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS;
 636        return IRQ_HANDLED;
 637}                               /* cy_tx_interrupt */
 638
 639static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id)
 640{
 641        struct tty_struct *tty;
 642        struct cyclades_port *info;
 643        volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
 644        int channel;
 645        char data;
 646        int char_count;
 647        int save_cnt;
 648        int len;
 649
 650        /* determine the channel and change to that context */
 651        channel = (u_short) (base_addr[CyLICR] >> 2);
 652        info = &cy_port[channel];
 653        info->last_active = jiffies;
 654        save_cnt = char_count = base_addr[CyRFOC];
 655
 656#ifdef CONFIG_REMOTE_DEBUG
 657        if (channel == DEBUG_PORT) {
 658                while (char_count--) {
 659                        data = base_addr[CyRDR];
 660                        queueDebugChar(data);
 661                }
 662        } else
 663#endif
 664                /* if there is nowhere to put the data, discard it */
 665        if (info->tty == 0) {
 666                while (char_count--) {
 667                        data = base_addr[CyRDR];
 668                }
 669        } else {                /* there is an open port for this data */
 670                tty = info->tty;
 671                /* load # characters available from the chip */
 672
 673#ifdef CYCLOM_ENABLE_MONITORING
 674                ++info->mon.int_count;
 675                info->mon.char_count += char_count;
 676                if (char_count > info->mon.char_max)
 677                        info->mon.char_max = char_count;
 678                info->mon.char_last = char_count;
 679#endif
 680                len = tty_buffer_request_room(tty, char_count);
 681                while (len--) {
 682                        data = base_addr[CyRDR];
 683                        tty_insert_flip_char(tty, data, TTY_NORMAL);
 684#ifdef CYCLOM_16Y_HACK
 685                        udelay(10L);
 686#endif
 687                }
 688                tty_schedule_flip(tty);
 689        }
 690        /* end of service */
 691        base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
 692        return IRQ_HANDLED;
 693}                               /* cy_rx_interrupt */
 694
 695/*
 696 * This routine is used to handle the "bottom half" processing for the
 697 * serial driver, known also the "software interrupt" processing.
 698 * This processing is done at the kernel interrupt level, after the
 699 * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
 700 * is where time-consuming activities which can not be done in the
 701 * interrupt driver proper are done; the interrupt driver schedules
 702 * them using cy_sched_event(), and they get done here.
 703 *
 704 * This is done through one level of indirection--the task queue.
 705 * When a hardware interrupt service routine wants service by the
 706 * driver's bottom half, it enqueues the appropriate tq_struct (one
 707 * per port) to the keventd work queue and sets a request flag
 708 * that the work queue be processed.
 709 *
 710 * Although this may seem unwieldy, it gives the system a way to
 711 * pass an argument (in this case the pointer to the cyclades_port
 712 * structure) to the bottom half of the driver.  Previous kernels
 713 * had to poll every port to see if that port needed servicing.
 714 */
 715static void do_softint(struct work_struct *ugly_api)
 716{
 717        struct cyclades_port *info =
 718            container_of(ugly_api, struct cyclades_port, tqueue);
 719        struct tty_struct *tty;
 720
 721        tty = info->tty;
 722        if (!tty)
 723                return;
 724
 725        if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
 726                tty_hangup(info->tty);
 727                wake_up_interruptible(&info->open_wait);
 728                info->flags &= ~ASYNC_NORMAL_ACTIVE;
 729        }
 730        if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
 731                wake_up_interruptible(&info->open_wait);
 732        }
 733        if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
 734                tty_wakeup(tty);
 735        }
 736}                               /* do_softint */
 737
 738/* This is called whenever a port becomes active;
 739   interrupts are enabled and DTR & RTS are turned on.
 740 */
 741static int startup(struct cyclades_port *info)
 742{
 743        unsigned long flags;
 744        volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
 745        int channel;
 746
 747        if (info->flags & ASYNC_INITIALIZED) {
 748                return 0;
 749        }
 750
 751        if (!info->type) {
 752                if (info->tty) {
 753                        set_bit(TTY_IO_ERROR, &info->tty->flags);
 754                }
 755                return 0;
 756        }
 757        if (!info->xmit_buf) {
 758                info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
 759                if (!info->xmit_buf) {
 760                        return -ENOMEM;
 761                }
 762        }
 763
 764        config_setup(info);
 765
 766        channel = info->line;
 767
 768#ifdef SERIAL_DEBUG_OPEN
 769        printk("startup channel %d\n", channel);
 770#endif
 771
 772        local_irq_save(flags);
 773        base_addr[CyCAR] = (u_char) channel;
 774        write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR);
 775
 776        base_addr[CyCAR] = (u_char) channel;    /* !!! Is this needed? */
 777        base_addr[CyMSVR1] = CyRTS;
 778/* CP('S');CP('1'); */
 779        base_addr[CyMSVR2] = CyDTR;
 780
 781#ifdef SERIAL_DEBUG_DTR
 782        printk("cyc: %d: raising DTR\n", __LINE__);
 783        printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
 784               base_addr[CyMSVR2]);
 785#endif
 786
 787        base_addr[CyIER] |= CyRxData;
 788        info->flags |= ASYNC_INITIALIZED;
 789
 790        if (info->tty) {
 791                clear_bit(TTY_IO_ERROR, &info->tty->flags);
 792        }
 793        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 794
 795        local_irq_restore(flags);
 796
 797#ifdef SERIAL_DEBUG_OPEN
 798        printk(" done\n");
 799#endif
 800        return 0;
 801}                               /* startup */
 802
 803void start_xmit(struct cyclades_port *info)
 804{
 805        unsigned long flags;
 806        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
 807        int channel;
 808
 809        channel = info->line;
 810        local_irq_save(flags);
 811        base_addr[CyCAR] = channel;
 812        base_addr[CyIER] |= CyTxMpty;
 813        local_irq_restore(flags);
 814}                               /* start_xmit */
 815
 816/*
 817 * This routine shuts down a serial port; interrupts are disabled,
 818 * and DTR is dropped if the hangup on close termio flag is on.
 819 */
 820static void shutdown(struct cyclades_port *info)
 821{
 822        unsigned long flags;
 823        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
 824        int channel;
 825
 826        if (!(info->flags & ASYNC_INITIALIZED)) {
 827/* CP('$'); */
 828                return;
 829        }
 830
 831        channel = info->line;
 832
 833#ifdef SERIAL_DEBUG_OPEN
 834        printk("shutdown channel %d\n", channel);
 835#endif
 836
 837        /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE
 838           SENT BEFORE DROPPING THE LINE !!!  (Perhaps
 839           set some flag that is read when XMTY happens.)
 840           Other choices are to delay some fixed interval
 841           or schedule some later processing.
 842         */
 843        local_irq_save(flags);
 844        if (info->xmit_buf) {
 845                free_page((unsigned long)info->xmit_buf);
 846                info->xmit_buf = NULL;
 847        }
 848
 849        base_addr[CyCAR] = (u_char) channel;
 850        if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
 851                base_addr[CyMSVR1] = 0;
 852/* CP('C');CP('1'); */
 853                base_addr[CyMSVR2] = 0;
 854#ifdef SERIAL_DEBUG_DTR
 855                printk("cyc: %d: dropping DTR\n", __LINE__);
 856                printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
 857                       base_addr[CyMSVR2]);
 858#endif
 859        }
 860        write_cy_cmd(base_addr, CyDIS_RCVR);
 861        /* it may be appropriate to clear _XMIT at
 862           some later date (after testing)!!! */
 863
 864        if (info->tty) {
 865                set_bit(TTY_IO_ERROR, &info->tty->flags);
 866        }
 867        info->flags &= ~ASYNC_INITIALIZED;
 868        local_irq_restore(flags);
 869
 870#ifdef SERIAL_DEBUG_OPEN
 871        printk(" done\n");
 872#endif
 873}                               /* shutdown */
 874
 875/*
 876 * This routine finds or computes the various line characteristics.
 877 */
 878static void config_setup(struct cyclades_port *info)
 879{
 880        unsigned long flags;
 881        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
 882        int channel;
 883        unsigned cflag;
 884        int i;
 885        unsigned char ti, need_init_chan = 0;
 886
 887        if (!info->tty || !info->tty->termios) {
 888                return;
 889        }
 890        if (info->line == -1) {
 891                return;
 892        }
 893        cflag = info->tty->termios->c_cflag;
 894
 895        /* baud rate */
 896        i = cflag & CBAUD;
 897#ifdef CBAUDEX
 898/* Starting with kernel 1.1.65, there is direct support for
 899   higher baud rates.  The following code supports those
 900   changes.  The conditional aspect allows this driver to be
 901   used for earlier as well as later kernel versions.  (The
 902   mapping is slightly different from serial.c because there
 903   is still the possibility of supporting 75 kbit/sec with
 904   the Cyclades board.)
 905 */
 906        if (i & CBAUDEX) {
 907                if (i == B57600)
 908                        i = 16;
 909                else if (i == B115200)
 910                        i = 18;
 911#ifdef B78600
 912                else if (i == B78600)
 913                        i = 17;
 914#endif
 915                else
 916                        info->tty->termios->c_cflag &= ~CBAUDEX;
 917        }
 918#endif
 919        if (i == 15) {
 920                if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 921                        i += 1;
 922                if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 923                        i += 3;
 924        }
 925        /* Don't ever change the speed of the console port.  It will
 926         * run at the speed specified in bootinfo, or at 19.2K */
 927        /* Actually, it should run at whatever speed 166Bug was using */
 928        /* Note info->timeout isn't used at present */
 929        if (info != serial_console_info) {
 930                info->tbpr = baud_bpr[i];       /* Tx BPR */
 931                info->tco = baud_co[i]; /* Tx CO */
 932                info->rbpr = baud_bpr[i];       /* Rx BPR */
 933                info->rco = baud_co[i] >> 5;    /* Rx CO */
 934                if (baud_table[i] == 134) {
 935                        info->timeout =
 936                            (info->xmit_fifo_size * HZ * 30 / 269) + 2;
 937                        /* get it right for 134.5 baud */
 938                } else if (baud_table[i]) {
 939                        info->timeout =
 940                            (info->xmit_fifo_size * HZ * 15 / baud_table[i]) +
 941                            2;
 942                        /* this needs to be propagated into the card info */
 943                } else {
 944                        info->timeout = 0;
 945                }
 946        }
 947        /* By tradition (is it a standard?) a baud rate of zero
 948           implies the line should be/has been closed.  A bit
 949           later in this routine such a test is performed. */
 950
 951        /* byte size and parity */
 952        info->cor7 = 0;
 953        info->cor6 = 0;
 954        info->cor5 = 0;
 955        info->cor4 = (info->default_threshold ? info->default_threshold : baud_cor4[i]);        /* receive threshold */
 956        /* Following two lines added 101295, RGH. */
 957        /* It is obviously wrong to access CyCORx, and not info->corx here,
 958         * try and remember to fix it later! */
 959        channel = info->line;
 960        base_addr[CyCAR] = (u_char) channel;
 961        if (C_CLOCAL(info->tty)) {
 962                if (base_addr[CyIER] & CyMdmCh)
 963                        base_addr[CyIER] &= ~CyMdmCh;   /* without modem intr */
 964                /* ignore 1->0 modem transitions */
 965                if (base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD))
 966                        base_addr[CyCOR4] &= ~(CyDSR | CyCTS | CyDCD);
 967                /* ignore 0->1 modem transitions */
 968                if (base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD))
 969                        base_addr[CyCOR5] &= ~(CyDSR | CyCTS | CyDCD);
 970        } else {
 971                if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh)
 972                        base_addr[CyIER] |= CyMdmCh;    /* with modem intr */
 973                /* act on 1->0 modem transitions */
 974                if ((base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) !=
 975                    (CyDSR | CyCTS | CyDCD))
 976                        base_addr[CyCOR4] |= CyDSR | CyCTS | CyDCD;
 977                /* act on 0->1 modem transitions */
 978                if ((base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) !=
 979                    (CyDSR | CyCTS | CyDCD))
 980                        base_addr[CyCOR5] |= CyDSR | CyCTS | CyDCD;
 981        }
 982        info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP;
 983        info->cor2 = CyETC;
 984        switch (cflag & CSIZE) {
 985        case CS5:
 986                info->cor1 = Cy_5_BITS;
 987                break;
 988        case CS6:
 989                info->cor1 = Cy_6_BITS;
 990                break;
 991        case CS7:
 992                info->cor1 = Cy_7_BITS;
 993                break;
 994        case CS8:
 995                info->cor1 = Cy_8_BITS;
 996                break;
 997        }
 998        if (cflag & PARENB) {
 999                if (cflag & PARODD) {
1000                        info->cor1 |= CyPARITY_O;
1001                } else {
1002                        info->cor1 |= CyPARITY_E;
1003                }
1004        } else {
1005                info->cor1 |= CyPARITY_NONE;
1006        }
1007
1008        /* CTS flow control flag */
1009#if 0
1010        /* Don't complcate matters for now! RGH 141095 */
1011        if (cflag & CRTSCTS) {
1012                info->flags |= ASYNC_CTS_FLOW;
1013                info->cor2 |= CyCtsAE;
1014        } else {
1015                info->flags &= ~ASYNC_CTS_FLOW;
1016                info->cor2 &= ~CyCtsAE;
1017        }
1018#endif
1019        if (cflag & CLOCAL)
1020                info->flags &= ~ASYNC_CHECK_CD;
1021        else
1022                info->flags |= ASYNC_CHECK_CD;
1023
1024     /***********************************************
1025        The hardware option, CyRtsAO, presents RTS when
1026        the chip has characters to send.  Since most modems
1027        use RTS as reverse (inbound) flow control, this
1028        option is not used.  If inbound flow control is
1029        necessary, DTR can be programmed to provide the
1030        appropriate signals for use with a non-standard
1031        cable.  Contact Marcio Saito for details.
1032     ***********************************************/
1033
1034        channel = info->line;
1035
1036        local_irq_save(flags);
1037        base_addr[CyCAR] = (u_char) channel;
1038
1039        /* CyCMR set once only in mvme167_init_serial() */
1040        if (base_addr[CyLICR] != channel << 2)
1041                base_addr[CyLICR] = channel << 2;
1042        if (base_addr[CyLIVR] != 0x5c)
1043                base_addr[CyLIVR] = 0x5c;
1044
1045        /* tx and rx baud rate */
1046
1047        if (base_addr[CyCOR1] != info->cor1)
1048                need_init_chan = 1;
1049        if (base_addr[CyTCOR] != info->tco)
1050                base_addr[CyTCOR] = info->tco;
1051        if (base_addr[CyTBPR] != info->tbpr)
1052                base_addr[CyTBPR] = info->tbpr;
1053        if (base_addr[CyRCOR] != info->rco)
1054                base_addr[CyRCOR] = info->rco;
1055        if (base_addr[CyRBPR] != info->rbpr)
1056                base_addr[CyRBPR] = info->rbpr;
1057
1058        /* set line characteristics  according configuration */
1059
1060        if (base_addr[CySCHR1] != START_CHAR(info->tty))
1061                base_addr[CySCHR1] = START_CHAR(info->tty);
1062        if (base_addr[CySCHR2] != STOP_CHAR(info->tty))
1063                base_addr[CySCHR2] = STOP_CHAR(info->tty);
1064        if (base_addr[CySCRL] != START_CHAR(info->tty))
1065                base_addr[CySCRL] = START_CHAR(info->tty);
1066        if (base_addr[CySCRH] != START_CHAR(info->tty))
1067                base_addr[CySCRH] = START_CHAR(info->tty);
1068        if (base_addr[CyCOR1] != info->cor1)
1069                base_addr[CyCOR1] = info->cor1;
1070        if (base_addr[CyCOR2] != info->cor2)
1071                base_addr[CyCOR2] = info->cor2;
1072        if (base_addr[CyCOR3] != info->cor3)
1073                base_addr[CyCOR3] = info->cor3;
1074        if (base_addr[CyCOR4] != info->cor4)
1075                base_addr[CyCOR4] = info->cor4;
1076        if (base_addr[CyCOR5] != info->cor5)
1077                base_addr[CyCOR5] = info->cor5;
1078        if (base_addr[CyCOR6] != info->cor6)
1079                base_addr[CyCOR6] = info->cor6;
1080        if (base_addr[CyCOR7] != info->cor7)
1081                base_addr[CyCOR7] = info->cor7;
1082
1083        if (need_init_chan)
1084                write_cy_cmd(base_addr, CyINIT_CHAN);
1085
1086        base_addr[CyCAR] = (u_char) channel;    /* !!! Is this needed? */
1087
1088        /* 2ms default rx timeout */
1089        ti = info->default_timeout ? info->default_timeout : 0x02;
1090        if (base_addr[CyRTPRL] != ti)
1091                base_addr[CyRTPRL] = ti;
1092        if (base_addr[CyRTPRH] != 0)
1093                base_addr[CyRTPRH] = 0;
1094
1095        /* Set up RTS here also ????? RGH 141095 */
1096        if (i == 0) {           /* baud rate is zero, turn off line */
1097                if ((base_addr[CyMSVR2] & CyDTR) == CyDTR)
1098                        base_addr[CyMSVR2] = 0;
1099#ifdef SERIAL_DEBUG_DTR
1100                printk("cyc: %d: dropping DTR\n", __LINE__);
1101                printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1102                       base_addr[CyMSVR2]);
1103#endif
1104        } else {
1105                if ((base_addr[CyMSVR2] & CyDTR) != CyDTR)
1106                        base_addr[CyMSVR2] = CyDTR;
1107#ifdef SERIAL_DEBUG_DTR
1108                printk("cyc: %d: raising DTR\n", __LINE__);
1109                printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1110                       base_addr[CyMSVR2]);
1111#endif
1112        }
1113
1114        if (info->tty) {
1115                clear_bit(TTY_IO_ERROR, &info->tty->flags);
1116        }
1117
1118        local_irq_restore(flags);
1119
1120}                               /* config_setup */
1121
1122static void cy_put_char(struct tty_struct *tty, unsigned char ch)
1123{
1124        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1125        unsigned long flags;
1126
1127#ifdef SERIAL_DEBUG_IO
1128        printk("cy_put_char %s(0x%02x)\n", tty->name, ch);
1129#endif
1130
1131        if (serial_paranoia_check(info, tty->name, "cy_put_char"))
1132                return;
1133
1134        if (!info->xmit_buf)
1135                return;
1136
1137        local_irq_save(flags);
1138        if (info->xmit_cnt >= PAGE_SIZE - 1) {
1139                local_irq_restore(flags);
1140                return;
1141        }
1142
1143        info->xmit_buf[info->xmit_head++] = ch;
1144        info->xmit_head &= PAGE_SIZE - 1;
1145        info->xmit_cnt++;
1146        local_irq_restore(flags);
1147}                               /* cy_put_char */
1148
1149static void cy_flush_chars(struct tty_struct *tty)
1150{
1151        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1152        unsigned long flags;
1153        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1154        int channel;
1155
1156#ifdef SERIAL_DEBUG_IO
1157        printk("cy_flush_chars %s\n", tty->name);       /* */
1158#endif
1159
1160        if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
1161                return;
1162
1163        if (info->xmit_cnt <= 0 || tty->stopped
1164            || tty->hw_stopped || !info->xmit_buf)
1165                return;
1166
1167        channel = info->line;
1168
1169        local_irq_save(flags);
1170        base_addr[CyCAR] = channel;
1171        base_addr[CyIER] |= CyTxMpty;
1172        local_irq_restore(flags);
1173}                               /* cy_flush_chars */
1174
1175/* This routine gets called when tty_write has put something into
1176    the write_queue.  If the port is not already transmitting stuff,
1177    start it off by enabling interrupts.  The interrupt service
1178    routine will then ensure that the characters are sent.  If the
1179    port is already active, there is no need to kick it.
1180 */
1181static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
1182{
1183        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1184        unsigned long flags;
1185        int c, total = 0;
1186
1187#ifdef SERIAL_DEBUG_IO
1188        printk("cy_write %s\n", tty->name);     /* */
1189#endif
1190
1191        if (serial_paranoia_check(info, tty->name, "cy_write")) {
1192                return 0;
1193        }
1194
1195        if (!info->xmit_buf) {
1196                return 0;
1197        }
1198
1199        while (1) {
1200                local_irq_save(flags);
1201                c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1202                                          SERIAL_XMIT_SIZE - info->xmit_head));
1203                if (c <= 0) {
1204                        local_irq_restore(flags);
1205                        break;
1206                }
1207
1208                memcpy(info->xmit_buf + info->xmit_head, buf, c);
1209                info->xmit_head =
1210                    (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
1211                info->xmit_cnt += c;
1212                local_irq_restore(flags);
1213
1214                buf += c;
1215                count -= c;
1216                total += c;
1217        }
1218
1219        if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
1220                start_xmit(info);
1221        }
1222        return total;
1223}                               /* cy_write */
1224
1225static int cy_write_room(struct tty_struct *tty)
1226{
1227        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1228        int ret;
1229
1230#ifdef SERIAL_DEBUG_IO
1231        printk("cy_write_room %s\n", tty->name);        /* */
1232#endif
1233
1234        if (serial_paranoia_check(info, tty->name, "cy_write_room"))
1235                return 0;
1236        ret = PAGE_SIZE - info->xmit_cnt - 1;
1237        if (ret < 0)
1238                ret = 0;
1239        return ret;
1240}                               /* cy_write_room */
1241
1242static int cy_chars_in_buffer(struct tty_struct *tty)
1243{
1244        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1245
1246#ifdef SERIAL_DEBUG_IO
1247        printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt);        /* */
1248#endif
1249
1250        if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
1251                return 0;
1252
1253        return info->xmit_cnt;
1254}                               /* cy_chars_in_buffer */
1255
1256static void cy_flush_buffer(struct tty_struct *tty)
1257{
1258        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1259        unsigned long flags;
1260
1261#ifdef SERIAL_DEBUG_IO
1262        printk("cy_flush_buffer %s\n", tty->name);      /* */
1263#endif
1264
1265        if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
1266                return;
1267        local_irq_save(flags);
1268        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1269        local_irq_restore(flags);
1270        tty_wakeup(tty);
1271}                               /* cy_flush_buffer */
1272
1273/* This routine is called by the upper-layer tty layer to signal
1274   that incoming characters should be throttled or that the
1275   throttle should be released.
1276 */
1277static void cy_throttle(struct tty_struct *tty)
1278{
1279        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1280        unsigned long flags;
1281        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1282        int channel;
1283
1284#ifdef SERIAL_DEBUG_THROTTLE
1285        char buf[64];
1286
1287        printk("throttle %s: %d....\n", tty_name(tty, buf),
1288               tty->ldisc.chars_in_buffer(tty));
1289        printk("cy_throttle %s\n", tty->name);
1290#endif
1291
1292        if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) {
1293                return;
1294        }
1295
1296        if (I_IXOFF(tty)) {
1297                info->x_char = STOP_CHAR(tty);
1298                /* Should use the "Send Special Character" feature!!! */
1299        }
1300
1301        channel = info->line;
1302
1303        local_irq_save(flags);
1304        base_addr[CyCAR] = (u_char) channel;
1305        base_addr[CyMSVR1] = 0;
1306        local_irq_restore(flags);
1307}                               /* cy_throttle */
1308
1309static void cy_unthrottle(struct tty_struct *tty)
1310{
1311        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1312        unsigned long flags;
1313        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1314        int channel;
1315
1316#ifdef SERIAL_DEBUG_THROTTLE
1317        char buf[64];
1318
1319        printk("throttle %s: %d....\n", tty_name(tty, buf),
1320               tty->ldisc.chars_in_buffer(tty));
1321        printk("cy_unthrottle %s\n", tty->name);
1322#endif
1323
1324        if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) {
1325                return;
1326        }
1327
1328        if (I_IXOFF(tty)) {
1329                info->x_char = START_CHAR(tty);
1330                /* Should use the "Send Special Character" feature!!! */
1331        }
1332
1333        channel = info->line;
1334
1335        local_irq_save(flags);
1336        base_addr[CyCAR] = (u_char) channel;
1337        base_addr[CyMSVR1] = CyRTS;
1338        local_irq_restore(flags);
1339}                               /* cy_unthrottle */
1340
1341static int
1342get_serial_info(struct cyclades_port *info,
1343                struct serial_struct __user * retinfo)
1344{
1345        struct serial_struct tmp;
1346
1347/* CP('g'); */
1348        if (!retinfo)
1349                return -EFAULT;
1350        memset(&tmp, 0, sizeof(tmp));
1351        tmp.type = info->type;
1352        tmp.line = info->line;
1353        tmp.port = info->line;
1354        tmp.irq = 0;
1355        tmp.flags = info->flags;
1356        tmp.baud_base = 0;      /*!!! */
1357        tmp.close_delay = info->close_delay;
1358        tmp.custom_divisor = 0; /*!!! */
1359        tmp.hub6 = 0;           /*!!! */
1360        return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
1361}                               /* get_serial_info */
1362
1363static int
1364set_serial_info(struct cyclades_port *info,
1365                struct serial_struct __user * new_info)
1366{
1367        struct serial_struct new_serial;
1368        struct cyclades_port old_info;
1369
1370/* CP('s'); */
1371        if (!new_info)
1372                return -EFAULT;
1373        if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
1374                return -EFAULT;
1375        old_info = *info;
1376
1377        if (!capable(CAP_SYS_ADMIN)) {
1378                if ((new_serial.close_delay != info->close_delay) ||
1379                    ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
1380                     (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
1381                        return -EPERM;
1382                info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1383                               (new_serial.flags & ASYNC_USR_MASK));
1384                goto check_and_exit;
1385        }
1386
1387        /*
1388         * OK, past this point, all the error checking has been done.
1389         * At this point, we start making changes.....
1390         */
1391
1392        info->flags = ((info->flags & ~ASYNC_FLAGS) |
1393                       (new_serial.flags & ASYNC_FLAGS));
1394        info->close_delay = new_serial.close_delay;
1395
1396check_and_exit:
1397        if (info->flags & ASYNC_INITIALIZED) {
1398                config_setup(info);
1399                return 0;
1400        }
1401        return startup(info);
1402}                               /* set_serial_info */
1403
1404static int cy_tiocmget(struct tty_struct *tty, struct file *file)
1405{
1406        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1407        int channel;
1408        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1409        unsigned long flags;
1410        unsigned char status;
1411
1412        channel = info->line;
1413
1414        local_irq_save(flags);
1415        base_addr[CyCAR] = (u_char) channel;
1416        status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
1417        local_irq_restore(flags);
1418
1419        return ((status & CyRTS) ? TIOCM_RTS : 0)
1420            | ((status & CyDTR) ? TIOCM_DTR : 0)
1421            | ((status & CyDCD) ? TIOCM_CAR : 0)
1422            | ((status & CyDSR) ? TIOCM_DSR : 0)
1423            | ((status & CyCTS) ? TIOCM_CTS : 0);
1424}                               /* cy_tiocmget */
1425
1426static int
1427cy_tiocmset(struct tty_struct *tty, struct file *file,
1428            unsigned int set, unsigned int clear)
1429{
1430        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1431        int channel;
1432        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1433        unsigned long flags;
1434
1435        channel = info->line;
1436
1437        if (set & TIOCM_RTS) {
1438                local_irq_save(flags);
1439                base_addr[CyCAR] = (u_char) channel;
1440                base_addr[CyMSVR1] = CyRTS;
1441                local_irq_restore(flags);
1442        }
1443        if (set & TIOCM_DTR) {
1444                local_irq_save(flags);
1445                base_addr[CyCAR] = (u_char) channel;
1446/* CP('S');CP('2'); */
1447                base_addr[CyMSVR2] = CyDTR;
1448#ifdef SERIAL_DEBUG_DTR
1449                printk("cyc: %d: raising DTR\n", __LINE__);
1450                printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1451                       base_addr[CyMSVR2]);
1452#endif
1453                local_irq_restore(flags);
1454        }
1455
1456        if (clear & TIOCM_RTS) {
1457                local_irq_save(flags);
1458                base_addr[CyCAR] = (u_char) channel;
1459                base_addr[CyMSVR1] = 0;
1460                local_irq_restore(flags);
1461        }
1462        if (clear & TIOCM_DTR) {
1463                local_irq_save(flags);
1464                base_addr[CyCAR] = (u_char) channel;
1465/* CP('C');CP('2'); */
1466                base_addr[CyMSVR2] = 0;
1467#ifdef SERIAL_DEBUG_DTR
1468                printk("cyc: %d: dropping DTR\n", __LINE__);
1469                printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1470                       base_addr[CyMSVR2]);
1471#endif
1472                local_irq_restore(flags);
1473        }
1474
1475        return 0;
1476}                               /* set_modem_info */
1477
1478static void send_break(struct cyclades_port *info, int duration)
1479{                               /* Let the transmit ISR take care of this (since it
1480                                   requires stuffing characters into the output stream).
1481                                 */
1482        info->x_break = duration;
1483        if (!info->xmit_cnt) {
1484                start_xmit(info);
1485        }
1486}                               /* send_break */
1487
1488static int
1489get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon)
1490{
1491
1492        if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
1493                return -EFAULT;
1494        info->mon.int_count = 0;
1495        info->mon.char_count = 0;
1496        info->mon.char_max = 0;
1497        info->mon.char_last = 0;
1498        return 0;
1499}
1500
1501static int set_threshold(struct cyclades_port *info, unsigned long __user * arg)
1502{
1503        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1504        unsigned long value;
1505        int channel;
1506
1507        if (get_user(value, arg))
1508                return -EFAULT;
1509
1510        channel = info->line;
1511        info->cor4 &= ~CyREC_FIFO;
1512        info->cor4 |= value & CyREC_FIFO;
1513        base_addr[CyCOR4] = info->cor4;
1514        return 0;
1515}
1516
1517static int
1518get_threshold(struct cyclades_port *info, unsigned long __user * value)
1519{
1520        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1521        int channel;
1522        unsigned long tmp;
1523
1524        channel = info->line;
1525
1526        tmp = base_addr[CyCOR4] & CyREC_FIFO;
1527        return put_user(tmp, value);
1528}
1529
1530static int
1531set_default_threshold(struct cyclades_port *info, unsigned long __user * arg)
1532{
1533        unsigned long value;
1534
1535        if (get_user(value, arg))
1536                return -EFAULT;
1537
1538        info->default_threshold = value & 0x0f;
1539        return 0;
1540}
1541
1542static int
1543get_default_threshold(struct cyclades_port *info, unsigned long __user * value)
1544{
1545        return put_user(info->default_threshold, value);
1546}
1547
1548static int set_timeout(struct cyclades_port *info, unsigned long __user * arg)
1549{
1550        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1551        int channel;
1552        unsigned long value;
1553
1554        if (get_user(value, arg))
1555                return -EFAULT;
1556
1557        channel = info->line;
1558
1559        base_addr[CyRTPRL] = value & 0xff;
1560        base_addr[CyRTPRH] = (value >> 8) & 0xff;
1561        return 0;
1562}
1563
1564static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
1565{
1566        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1567        int channel;
1568        unsigned long tmp;
1569
1570        channel = info->line;
1571
1572        tmp = base_addr[CyRTPRL];
1573        return put_user(tmp, value);
1574}
1575
1576static int set_default_timeout(struct cyclades_port *info, unsigned long value)
1577{
1578        info->default_timeout = value & 0xff;
1579        return 0;
1580}
1581
1582static int
1583get_default_timeout(struct cyclades_port *info, unsigned long __user * value)
1584{
1585        return put_user(info->default_timeout, value);
1586}
1587
1588static int
1589cy_ioctl(struct tty_struct *tty, struct file *file,
1590         unsigned int cmd, unsigned long arg)
1591{
1592        unsigned long val;
1593        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1594        int ret_val = 0;
1595        void __user *argp = (void __user *)arg;
1596
1597#ifdef SERIAL_DEBUG_OTHER
1598        printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg);       /* */
1599#endif
1600
1601        switch (cmd) {
1602        case CYGETMON:
1603                ret_val = get_mon_info(info, argp);
1604                break;
1605        case CYGETTHRESH:
1606                ret_val = get_threshold(info, argp);
1607                break;
1608        case CYSETTHRESH:
1609                ret_val = set_threshold(info, argp);
1610                break;
1611        case CYGETDEFTHRESH:
1612                ret_val = get_default_threshold(info, argp);
1613                break;
1614        case CYSETDEFTHRESH:
1615                ret_val = set_default_threshold(info, argp);
1616                break;
1617        case CYGETTIMEOUT:
1618                ret_val = get_timeout(info, argp);
1619                break;
1620        case CYSETTIMEOUT:
1621                ret_val = set_timeout(info, argp);
1622                break;
1623        case CYGETDEFTIMEOUT:
1624                ret_val = get_default_timeout(info, argp);
1625                break;
1626        case CYSETDEFTIMEOUT:
1627                ret_val = set_default_timeout(info, (unsigned long)arg);
1628                break;
1629        case TCSBRK:            /* SVID version: non-zero arg --> no break */
1630                ret_val = tty_check_change(tty);
1631                if (ret_val)
1632                        break;
1633                tty_wait_until_sent(tty, 0);
1634                if (!arg)
1635                        send_break(info, HZ / 4);       /* 1/4 second */
1636                break;
1637        case TCSBRKP:           /* support for POSIX tcsendbreak() */
1638                ret_val = tty_check_change(tty);
1639                if (ret_val)
1640                        break;
1641                tty_wait_until_sent(tty, 0);
1642                send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
1643                break;
1644
1645/* The following commands are incompletely implemented!!! */
1646        case TIOCGSOFTCAR:
1647                ret_val =
1648                    put_user(C_CLOCAL(tty) ? 1 : 0,
1649                             (unsigned long __user *)argp);
1650                break;
1651        case TIOCSSOFTCAR:
1652                ret_val = get_user(val, (unsigned long __user *)argp);
1653                if (ret_val)
1654                        break;
1655                tty->termios->c_cflag =
1656                    ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
1657                break;
1658        case TIOCGSERIAL:
1659                ret_val = get_serial_info(info, argp);
1660                break;
1661        case TIOCSSERIAL:
1662                ret_val = set_serial_info(info, argp);
1663                break;
1664        default:
1665                ret_val = -ENOIOCTLCMD;
1666        }
1667
1668#ifdef SERIAL_DEBUG_OTHER
1669        printk("cy_ioctl done\n");
1670#endif
1671
1672        return ret_val;
1673}                               /* cy_ioctl */
1674
1675static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1676{
1677        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1678
1679#ifdef SERIAL_DEBUG_OTHER
1680        printk("cy_set_termios %s\n", tty->name);
1681#endif
1682
1683        if (tty->termios->c_cflag == old_termios->c_cflag)
1684                return;
1685        config_setup(info);
1686
1687        if ((old_termios->c_cflag & CRTSCTS) &&
1688            !(tty->termios->c_cflag & CRTSCTS)) {
1689                tty->stopped = 0;
1690                cy_start(tty);
1691        }
1692#ifdef tytso_patch_94Nov25_1726
1693        if (!(old_termios->c_cflag & CLOCAL) &&
1694            (tty->termios->c_cflag & CLOCAL))
1695                wake_up_interruptible(&info->open_wait);
1696#endif
1697}                               /* cy_set_termios */
1698
1699static void cy_close(struct tty_struct *tty, struct file *filp)
1700{
1701        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1702
1703/* CP('C'); */
1704#ifdef SERIAL_DEBUG_OTHER
1705        printk("cy_close %s\n", tty->name);
1706#endif
1707
1708        if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
1709                return;
1710        }
1711#ifdef SERIAL_DEBUG_OPEN
1712        printk("cy_close %s, count = %d\n", tty->name, info->count);
1713#endif
1714
1715        if ((tty->count == 1) && (info->count != 1)) {
1716                /*
1717                 * Uh, oh.  tty->count is 1, which means that the tty
1718                 * structure will be freed.  Info->count should always
1719                 * be one in these conditions.  If it's greater than
1720                 * one, we've got real problems, since it means the
1721                 * serial port won't be shutdown.
1722                 */
1723                printk("cy_close: bad serial port count; tty->count is 1, "
1724                       "info->count is %d\n", info->count);
1725                info->count = 1;
1726        }
1727#ifdef SERIAL_DEBUG_COUNT
1728        printk("cyc: %d: decrementing count to %d\n", __LINE__,
1729               info->count - 1);
1730#endif
1731        if (--info->count < 0) {
1732                printk("cy_close: bad serial port count for ttys%d: %d\n",
1733                       info->line, info->count);
1734#ifdef SERIAL_DEBUG_COUNT
1735                printk("cyc: %d: setting count to 0\n", __LINE__);
1736#endif
1737                info->count = 0;
1738        }
1739        if (info->count)
1740                return;
1741        info->flags |= ASYNC_CLOSING;
1742        if (info->flags & ASYNC_INITIALIZED)
1743                tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
1744        shutdown(info);
1745        if (tty->driver->flush_buffer)
1746                tty->driver->flush_buffer(tty);
1747        tty_ldisc_flush(tty);
1748        info->event = 0;
1749        info->tty = NULL;
1750        if (info->blocked_open) {
1751                if (info->close_delay) {
1752                        msleep_interruptible(jiffies_to_msecs
1753                                             (info->close_delay));
1754                }
1755                wake_up_interruptible(&info->open_wait);
1756        }
1757        info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1758        wake_up_interruptible(&info->close_wait);
1759
1760#ifdef SERIAL_DEBUG_OTHER
1761        printk("cy_close done\n");
1762#endif
1763}                               /* cy_close */
1764
1765/*
1766 * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
1767 */
1768void cy_hangup(struct tty_struct *tty)
1769{
1770        struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1771
1772#ifdef SERIAL_DEBUG_OTHER
1773        printk("cy_hangup %s\n", tty->name);    /* */
1774#endif
1775
1776        if (serial_paranoia_check(info, tty->name, "cy_hangup"))
1777                return;
1778
1779        shutdown(info);
1780#if 0
1781        info->event = 0;
1782        info->count = 0;
1783#ifdef SERIAL_DEBUG_COUNT
1784        printk("cyc: %d: setting count to 0\n", __LINE__);
1785#endif
1786        info->tty = 0;
1787#endif
1788        info->flags &= ~ASYNC_NORMAL_ACTIVE;
1789        wake_up_interruptible(&info->open_wait);
1790}                               /* cy_hangup */
1791
1792/*
1793 * ------------------------------------------------------------
1794 * cy_open() and friends
1795 * ------------------------------------------------------------
1796 */
1797
1798static int
1799block_til_ready(struct tty_struct *tty, struct file *filp,
1800                struct cyclades_port *info)
1801{
1802        DECLARE_WAITQUEUE(wait, current);
1803        unsigned long flags;
1804        int channel;
1805        int retval;
1806        volatile u_char *base_addr = (u_char *) BASE_ADDR;
1807
1808        /*
1809         * If the device is in the middle of being closed, then block
1810         * until it's done, and then try again.
1811         */
1812        if (info->flags & ASYNC_CLOSING) {
1813                interruptible_sleep_on(&info->close_wait);
1814                if (info->flags & ASYNC_HUP_NOTIFY) {
1815                        return -EAGAIN;
1816                } else {
1817                        return -ERESTARTSYS;
1818                }
1819        }
1820
1821        /*
1822         * If non-blocking mode is set, then make the check up front
1823         * and then exit.
1824         */
1825        if (filp->f_flags & O_NONBLOCK) {
1826                info->flags |= ASYNC_NORMAL_ACTIVE;
1827                return 0;
1828        }
1829
1830        /*
1831         * Block waiting for the carrier detect and the line to become
1832         * free (i.e., not in use by the callout).  While we are in
1833         * this loop, info->count is dropped by one, so that
1834         * cy_close() knows when to free things.  We restore it upon
1835         * exit, either normal or abnormal.
1836         */
1837        retval = 0;
1838        add_wait_queue(&info->open_wait, &wait);
1839#ifdef SERIAL_DEBUG_OPEN
1840        printk("block_til_ready before block: %s, count = %d\n",
1841               tty->name, info->count);
1842        /**/
1843#endif
1844            info->count--;
1845#ifdef SERIAL_DEBUG_COUNT
1846        printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
1847#endif
1848        info->blocked_open++;
1849
1850        channel = info->line;
1851
1852        while (1) {
1853                local_irq_save(flags);
1854                base_addr[CyCAR] = (u_char) channel;
1855                base_addr[CyMSVR1] = CyRTS;
1856/* CP('S');CP('4'); */
1857                base_addr[CyMSVR2] = CyDTR;
1858#ifdef SERIAL_DEBUG_DTR
1859                printk("cyc: %d: raising DTR\n", __LINE__);
1860                printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1861                       base_addr[CyMSVR2]);
1862#endif
1863                local_irq_restore(flags);
1864                set_current_state(TASK_INTERRUPTIBLE);
1865                if (tty_hung_up_p(filp)
1866                    || !(info->flags & ASYNC_INITIALIZED)) {
1867                        if (info->flags & ASYNC_HUP_NOTIFY) {
1868                                retval = -EAGAIN;
1869                        } else {
1870                                retval = -ERESTARTSYS;
1871                        }
1872                        break;
1873                }
1874                local_irq_save(flags);
1875                base_addr[CyCAR] = (u_char) channel;
1876/* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */
1877                if (!(info->flags & ASYNC_CLOSING)
1878                    && (C_CLOCAL(tty)
1879                        || (base_addr[CyMSVR1] & CyDCD))) {
1880                        local_irq_restore(flags);
1881                        break;
1882                }
1883                local_irq_restore(flags);
1884                if (signal_pending(current)) {
1885                        retval = -ERESTARTSYS;
1886                        break;
1887                }
1888#ifdef SERIAL_DEBUG_OPEN
1889                printk("block_til_ready blocking: %s, count = %d\n",
1890                       tty->name, info->count);
1891                /**/
1892#endif
1893                    schedule();
1894        }
1895        __set_current_state(TASK_RUNNING);
1896        remove_wait_queue(&info->open_wait, &wait);
1897        if (!tty_hung_up_p(filp)) {
1898                info->count++;
1899#ifdef SERIAL_DEBUG_COUNT
1900                printk("cyc: %d: incrementing count to %d\n", __LINE__,
1901                       info->count);
1902#endif
1903        }
1904        info->blocked_open--;
1905#ifdef SERIAL_DEBUG_OPEN
1906        printk("block_til_ready after blocking: %s, count = %d\n",
1907               tty->name, info->count);
1908        /**/
1909#endif
1910            if (retval)
1911                return retval;
1912        info->flags |= ASYNC_NORMAL_ACTIVE;
1913        return 0;
1914}                               /* block_til_ready */
1915
1916/*
1917 * This routine is called whenever a serial port is opened.  It
1918 * performs the serial-specific initialization for the tty structure.
1919 */
1920int cy_open(struct tty_struct *tty, struct file *filp)
1921{
1922        struct cyclades_port *info;
1923        int retval, line;
1924
1925/* CP('O'); */
1926        line = tty->index;
1927        if ((line < 0) || (NR_PORTS <= line)) {
1928                return -ENODEV;
1929        }
1930        info = &cy_port[line];
1931        if (info->line < 0) {
1932                return -ENODEV;
1933        }
1934#ifdef SERIAL_DEBUG_OTHER
1935        printk("cy_open %s\n", tty->name);      /* */
1936#endif
1937        if (serial_paranoia_check(info, tty->name, "cy_open")) {
1938                return -ENODEV;
1939        }
1940#ifdef SERIAL_DEBUG_OPEN
1941        printk("cy_open %s, count = %d\n", tty->name, info->count);
1942        /**/
1943#endif
1944            info->count++;
1945#ifdef SERIAL_DEBUG_COUNT
1946        printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
1947#endif
1948        tty->driver_data = info;
1949        info->tty = tty;
1950
1951        /*
1952         * Start up serial port
1953         */
1954        retval = startup(info);
1955        if (retval) {
1956                return retval;
1957        }
1958
1959        retval = block_til_ready(tty, filp, info);
1960        if (retval) {
1961#ifdef SERIAL_DEBUG_OPEN
1962                printk("cy_open returning after block_til_ready with %d\n",
1963                       retval);
1964#endif
1965                return retval;
1966        }
1967#ifdef SERIAL_DEBUG_OPEN
1968        printk("cy_open done\n");
1969        /**/
1970#endif
1971            return 0;
1972}                               /* cy_open */
1973
1974/*
1975 * ---------------------------------------------------------------------
1976 * serial167_init() and friends
1977 *
1978 * serial167_init() is called at boot-time to initialize the serial driver.
1979 * ---------------------------------------------------------------------
1980 */
1981
1982/*
1983 * This routine prints out the appropriate serial driver version
1984 * number, and identifies which options were configured into this
1985 * driver.
1986 */
1987static void show_version(void)
1988{
1989        printk("MVME166/167 cd2401 driver\n");
1990}                               /* show_version */
1991
1992/* initialize chips on card -- return number of valid
1993   chips (which is number of ports/4) */
1994
1995/*
1996 * This initialises the hardware to a reasonable state.  It should
1997 * probe the chip first so as to copy 166-Bug setup as a default for
1998 * port 0.  It initialises CMR to CyASYNC; that is never done again, so
1999 * as to limit the number of CyINIT_CHAN commands in normal running.
2000 *
2001 * ... I wonder what I should do if this fails ...
2002 */
2003
2004void mvme167_serial_console_setup(int cflag)
2005{
2006        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
2007        int ch;
2008        u_char spd;
2009        u_char rcor, rbpr, badspeed = 0;
2010        unsigned long flags;
2011
2012        local_irq_save(flags);
2013
2014        /*
2015         * First probe channel zero of the chip, to see what speed has
2016         * been selected.
2017         */
2018
2019        base_addr[CyCAR] = 0;
2020
2021        rcor = base_addr[CyRCOR] << 5;
2022        rbpr = base_addr[CyRBPR];
2023
2024        for (spd = 0; spd < sizeof(baud_bpr); spd++)
2025                if (rbpr == baud_bpr[spd] && rcor == baud_co[spd])
2026                        break;
2027        if (spd >= sizeof(baud_bpr)) {
2028                spd = 14;       /* 19200 */
2029                badspeed = 1;   /* Failed to identify speed */
2030        }
2031        initial_console_speed = spd;
2032
2033        /* OK, we have chosen a speed, now reset and reinitialise */
2034
2035        my_udelay(20000L);      /* Allow time for any active o/p to complete */
2036        if (base_addr[CyCCR] != 0x00) {
2037                local_irq_restore(flags);
2038                /* printk(" chip is never idle (CCR != 0)\n"); */
2039                return;
2040        }
2041
2042        base_addr[CyCCR] = CyCHIP_RESET;        /* Reset the chip */
2043        my_udelay(1000L);
2044
2045        if (base_addr[CyGFRCR] == 0x00) {
2046                local_irq_restore(flags);
2047                /* printk(" chip is not responding (GFRCR stayed 0)\n"); */
2048                return;
2049        }
2050
2051        /*
2052         * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms
2053         * tick
2054         */
2055
2056        base_addr[CyTPR] = 10;
2057
2058        base_addr[CyPILR1] = 0x01;      /* Interrupt level for modem change */
2059        base_addr[CyPILR2] = 0x02;      /* Interrupt level for tx ints */
2060        base_addr[CyPILR3] = 0x03;      /* Interrupt level for rx ints */
2061
2062        /*
2063         * Attempt to set up all channels to something reasonable, and
2064         * bang out a INIT_CHAN command.  We should then be able to limit
2065         * the ammount of fiddling we have to do in normal running.
2066         */
2067
2068        for (ch = 3; ch >= 0; ch--) {
2069                base_addr[CyCAR] = (u_char) ch;
2070                base_addr[CyIER] = 0;
2071                base_addr[CyCMR] = CyASYNC;
2072                base_addr[CyLICR] = (u_char) ch << 2;
2073                base_addr[CyLIVR] = 0x5c;
2074                base_addr[CyTCOR] = baud_co[spd];
2075                base_addr[CyTBPR] = baud_bpr[spd];
2076                base_addr[CyRCOR] = baud_co[spd] >> 5;
2077                base_addr[CyRBPR] = baud_bpr[spd];
2078                base_addr[CySCHR1] = 'Q' & 0x1f;
2079                base_addr[CySCHR2] = 'X' & 0x1f;
2080                base_addr[CySCRL] = 0;
2081                base_addr[CySCRH] = 0;
2082                base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
2083                base_addr[CyCOR2] = 0;
2084                base_addr[CyCOR3] = Cy_1_STOP;
2085                base_addr[CyCOR4] = baud_cor4[spd];
2086                base_addr[CyCOR5] = 0;
2087                base_addr[CyCOR6] = 0;
2088                base_addr[CyCOR7] = 0;
2089                base_addr[CyRTPRL] = 2;
2090                base_addr[CyRTPRH] = 0;
2091                base_addr[CyMSVR1] = 0;
2092                base_addr[CyMSVR2] = 0;
2093                write_cy_cmd(base_addr, CyINIT_CHAN | CyDIS_RCVR | CyDIS_XMTR);
2094        }
2095
2096        /*
2097         * Now do specials for channel zero....
2098         */
2099
2100        base_addr[CyMSVR1] = CyRTS;
2101        base_addr[CyMSVR2] = CyDTR;
2102        base_addr[CyIER] = CyRxData;
2103        write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR);
2104
2105        local_irq_restore(flags);
2106
2107        my_udelay(20000L);      /* Let it all settle down */
2108
2109        printk("CD2401 initialised,  chip is rev 0x%02x\n", base_addr[CyGFRCR]);
2110        if (badspeed)
2111                printk
2112                    ("  WARNING:  Failed to identify line speed, rcor=%02x,rbpr=%02x\n",
2113                     rcor >> 5, rbpr);
2114}                               /* serial_console_init */
2115
2116static const struct tty_operations cy_ops = {
2117        .open = cy_open,
2118        .close = cy_close,
2119        .write = cy_write,
2120        .put_char = cy_put_char,
2121        .flush_chars = cy_flush_chars,
2122        .write_room = cy_write_room,
2123        .chars_in_buffer = cy_chars_in_buffer,
2124        .flush_buffer = cy_flush_buffer,
2125        .ioctl = cy_ioctl,
2126        .throttle = cy_throttle,
2127        .unthrottle = cy_unthrottle,
2128        .set_termios = cy_set_termios,
2129        .stop = cy_stop,
2130        .start = cy_start,
2131        .hangup = cy_hangup,
2132        .tiocmget = cy_tiocmget,
2133        .tiocmset = cy_tiocmset,
2134};
2135
2136/* The serial driver boot-time initialization code!
2137    Hardware I/O ports are mapped to character special devices on a
2138    first found, first allocated manner.  That is, this code searches
2139    for Cyclom cards in the system.  As each is found, it is probed
2140    to discover how many chips (and thus how many ports) are present.
2141    These ports are mapped to the tty ports 64 and upward in monotonic
2142    fashion.  If an 8-port card is replaced with a 16-port card, the
2143    port mapping on a following card will shift.
2144
2145    This approach is different from what is used in the other serial
2146    device driver because the Cyclom is more properly a multiplexer,
2147    not just an aggregation of serial ports on one card.
2148
2149    If there are more cards with more ports than have been statically
2150    allocated above, a warning is printed and the extra ports are ignored.
2151 */
2152static int __init serial167_init(void)
2153{
2154        struct cyclades_port *info;
2155        int ret = 0;
2156        int good_ports = 0;
2157        int port_num = 0;
2158        int index;
2159        int DefSpeed;
2160#ifdef notyet
2161        struct sigaction sa;
2162#endif
2163
2164        if (!(mvme16x_config & MVME16x_CONFIG_GOT_CD2401))
2165                return 0;
2166
2167        cy_serial_driver = alloc_tty_driver(NR_PORTS);
2168        if (!cy_serial_driver)
2169                return -ENOMEM;
2170
2171#if 0
2172        scrn[1] = '\0';
2173#endif
2174
2175        show_version();
2176
2177        /* Has "console=0,9600n8" been used in bootinfo to change speed? */
2178        if (serial_console_cflag)
2179                DefSpeed = serial_console_cflag & 0017;
2180        else {
2181                DefSpeed = initial_console_speed;
2182                serial_console_info = &cy_port[0];
2183                serial_console_cflag = DefSpeed | CS8;
2184#if 0
2185                serial_console = 64;    /*callout_driver.minor_start */
2186#endif
2187        }
2188
2189        /* Initialize the tty_driver structure */
2190
2191        cy_serial_driver->owner = THIS_MODULE;
2192        cy_serial_driver->name = "ttyS";
2193        cy_serial_driver->major = TTY_MAJOR;
2194        cy_serial_driver->minor_start = 64;
2195        cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
2196        cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
2197        cy_serial_driver->init_termios = tty_std_termios;
2198        cy_serial_driver->init_termios.c_cflag =
2199            B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2200        cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
2201        tty_set_operations(cy_serial_driver, &cy_ops);
2202
2203        ret = tty_register_driver(cy_serial_driver);
2204        if (ret) {
2205                printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
2206                put_tty_driver(cy_serial_driver);
2207                return ret;
2208        }
2209
2210        port_num = 0;
2211        info = cy_port;
2212        for (index = 0; index < 1; index++) {
2213
2214                good_ports = 4;
2215
2216                if (port_num < NR_PORTS) {
2217                        while (good_ports-- && port_num < NR_PORTS) {
2218                /*** initialize port ***/
2219                                info->magic = CYCLADES_MAGIC;
2220                                info->type = PORT_CIRRUS;
2221                                info->card = index;
2222                                info->line = port_num;
2223                                info->flags = STD_COM_FLAGS;
2224                                info->tty = NULL;
2225                                info->xmit_fifo_size = 12;
2226                                info->cor1 = CyPARITY_NONE | Cy_8_BITS;
2227                                info->cor2 = CyETC;
2228                                info->cor3 = Cy_1_STOP;
2229                                info->cor4 = 0x08;      /* _very_ small receive threshold */
2230                                info->cor5 = 0;
2231                                info->cor6 = 0;
2232                                info->cor7 = 0;
2233                                info->tbpr = baud_bpr[DefSpeed];        /* Tx BPR */
2234                                info->tco = baud_co[DefSpeed];  /* Tx CO */
2235                                info->rbpr = baud_bpr[DefSpeed];        /* Rx BPR */
2236                                info->rco = baud_co[DefSpeed] >> 5;     /* Rx CO */
2237                                info->close_delay = 0;
2238                                info->x_char = 0;
2239                                info->event = 0;
2240                                info->count = 0;
2241#ifdef SERIAL_DEBUG_COUNT
2242                                printk("cyc: %d: setting count to 0\n",
2243                                       __LINE__);
2244#endif
2245                                info->blocked_open = 0;
2246                                info->default_threshold = 0;
2247                                info->default_timeout = 0;
2248                                INIT_WORK(&info->tqueue, do_softint);
2249                                init_waitqueue_head(&info->open_wait);
2250                                init_waitqueue_head(&info->close_wait);
2251                                /* info->session */
2252                                /* info->pgrp */
2253/*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/
2254                                info->read_status_mask =
2255                                    CyTIMEOUT | CySPECHAR | CyBREAK | CyPARITY |
2256                                    CyFRAME | CyOVERRUN;
2257                                /* info->timeout */
2258
2259                                printk("ttyS%d ", info->line);
2260                                port_num++;
2261                                info++;
2262                                if (!(port_num & 7)) {
2263                                        printk("\n               ");
2264                                }
2265                        }
2266                }
2267                printk("\n");
2268        }
2269        while (port_num < NR_PORTS) {
2270                info->line = -1;
2271                port_num++;
2272                info++;
2273        }
2274#ifdef CONFIG_REMOTE_DEBUG
2275        debug_setup();
2276#endif
2277        ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
2278                          "cd2401_errors", cd2401_rxerr_interrupt);
2279        if (ret) {
2280                printk(KERN_ERR "Could't get cd2401_errors IRQ");
2281                goto cleanup_serial_driver;
2282        }
2283
2284        ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
2285                          "cd2401_modem", cd2401_modem_interrupt);
2286        if (ret) {
2287                printk(KERN_ERR "Could't get cd2401_modem IRQ");
2288                goto cleanup_irq_cd2401_errors;
2289        }
2290
2291        ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
2292                          "cd2401_txints", cd2401_tx_interrupt);
2293        if (ret) {
2294                printk(KERN_ERR "Could't get cd2401_txints IRQ");
2295                goto cleanup_irq_cd2401_modem;
2296        }
2297
2298        ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
2299                          "cd2401_rxints", cd2401_rx_interrupt);
2300        if (ret) {
2301                printk(KERN_ERR "Could't get cd2401_rxints IRQ");
2302                goto cleanup_irq_cd2401_txints;
2303        }
2304
2305        /* Now we have registered the interrupt handlers, allow the interrupts */
2306
2307        pcc2chip[PccSCCMICR] = 0x15;    /* Serial ints are level 5 */
2308        pcc2chip[PccSCCTICR] = 0x15;
2309        pcc2chip[PccSCCRICR] = 0x15;
2310
2311        pcc2chip[PccIMLR] = 3;  /* Allow PCC2 ints above 3!? */
2312
2313        return 0;
2314cleanup_irq_cd2401_txints:
2315        free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt);
2316cleanup_irq_cd2401_modem:
2317        free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
2318cleanup_irq_cd2401_errors:
2319        free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
2320cleanup_serial_driver:
2321        if (tty_unregister_driver(cy_serial_driver))
2322                printk(KERN_ERR
2323                       "Couldn't unregister MVME166/7 serial driver\n");
2324        put_tty_driver(cy_serial_driver);
2325        return ret;
2326}                               /* serial167_init */
2327
2328module_init(serial167_init);
2329
2330#ifdef CYCLOM_SHOW_STATUS
2331static void show_status(int line_num)
2332{
2333        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
2334        int channel;
2335        struct cyclades_port *info;
2336        unsigned long flags;
2337
2338        info = &cy_port[line_num];
2339        channel = info->line;
2340        printk("  channel %d\n", channel);
2341        /**/ printk(" cy_port\n");
2342        printk("  card line flags = %d %d %x\n",
2343               info->card, info->line, info->flags);
2344        printk
2345            ("  *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
2346             (long)info->tty, info->read_status_mask, info->timeout,
2347             info->xmit_fifo_size);
2348        printk("  cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n",
2349               info->cor1, info->cor2, info->cor3, info->cor4, info->cor5,
2350               info->cor6, info->cor7);
2351        printk("  tbpr,tco,rbpr,rco = %d %d %d %d\n", info->tbpr, info->tco,
2352               info->rbpr, info->rco);
2353        printk("  close_delay event count = %d %d %d\n", info->close_delay,
2354               info->event, info->count);
2355        printk("  x_char blocked_open = %x %x\n", info->x_char,
2356               info->blocked_open);
2357        printk("  open_wait = %lx %lx %lx\n", (long)info->open_wait);
2358
2359        local_irq_save(flags);
2360
2361/* Global Registers */
2362
2363        printk(" CyGFRCR %x\n", base_addr[CyGFRCR]);
2364        printk(" CyCAR %x\n", base_addr[CyCAR]);
2365        printk(" CyRISR %x\n", base_addr[CyRISR]);
2366        printk(" CyTISR %x\n", base_addr[CyTISR]);
2367        printk(" CyMISR %x\n", base_addr[CyMISR]);
2368        printk(" CyRIR %x\n", base_addr[CyRIR]);
2369        printk(" CyTIR %x\n", base_addr[CyTIR]);
2370        printk(" CyMIR %x\n", base_addr[CyMIR]);
2371        printk(" CyTPR %x\n", base_addr[CyTPR]);
2372
2373        base_addr[CyCAR] = (u_char) channel;
2374
2375/* Virtual Registers */
2376
2377#if 0
2378        printk(" CyRIVR %x\n", base_addr[CyRIVR]);
2379        printk(" CyTIVR %x\n", base_addr[CyTIVR]);
2380        printk(" CyMIVR %x\n", base_addr[CyMIVR]);
2381        printk(" CyMISR %x\n", base_addr[CyMISR]);
2382#endif
2383
2384/* Channel Registers */
2385
2386        printk(" CyCCR %x\n", base_addr[CyCCR]);
2387        printk(" CyIER %x\n", base_addr[CyIER]);
2388        printk(" CyCOR1 %x\n", base_addr[CyCOR1]);
2389        printk(" CyCOR2 %x\n", base_addr[CyCOR2]);
2390        printk(" CyCOR3 %x\n", base_addr[CyCOR3]);
2391        printk(" CyCOR4 %x\n", base_addr[CyCOR4]);
2392        printk(" CyCOR5 %x\n", base_addr[CyCOR5]);
2393#if 0
2394        printk(" CyCCSR %x\n", base_addr[CyCCSR]);
2395        printk(" CyRDCR %x\n", base_addr[CyRDCR]);
2396#endif
2397        printk(" CySCHR1 %x\n", base_addr[CySCHR1]);
2398        printk(" CySCHR2 %x\n", base_addr[CySCHR2]);
2399#if 0
2400        printk(" CySCHR3 %x\n", base_addr[CySCHR3]);
2401        printk(" CySCHR4 %x\n", base_addr[CySCHR4]);
2402        printk(" CySCRL %x\n", base_addr[CySCRL]);
2403        printk(" CySCRH %x\n", base_addr[CySCRH]);
2404        printk(" CyLNC %x\n", base_addr[CyLNC]);
2405        printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]);
2406        printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]);
2407#endif
2408        printk(" CyRTPRL %x\n", base_addr[CyRTPRL]);
2409        printk(" CyRTPRH %x\n", base_addr[CyRTPRH]);
2410        printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]);
2411        printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]);
2412        printk(" CyRBPR %x\n", base_addr[CyRBPR]);
2413        printk(" CyRCOR %x\n", base_addr[CyRCOR]);
2414        printk(" CyTBPR %x\n", base_addr[CyTBPR]);
2415        printk(" CyTCOR %x\n", base_addr[CyTCOR]);
2416
2417        local_irq_restore(flags);
2418}                               /* show_status */
2419#endif
2420
2421#if 0
2422/* Dummy routine in mvme16x/config.c for now */
2423
2424/* Serial console setup. Called from linux/init/main.c */
2425
2426void console_setup(char *str, int *ints)
2427{
2428        char *s;
2429        int baud, bits, parity;
2430        int cflag = 0;
2431
2432        /* Sanity check. */
2433        if (ints[0] > 3 || ints[1] > 3)
2434                return;
2435
2436        /* Get baud, bits and parity */
2437        baud = 2400;
2438        bits = 8;
2439        parity = 'n';
2440        if (ints[2])
2441                baud = ints[2];
2442        if ((s = strchr(str, ','))) {
2443                do {
2444                        s++;
2445                } while (*s >= '0' && *s <= '9');
2446                if (*s)
2447                        parity = *s++;
2448                if (*s)
2449                        bits = *s - '0';
2450        }
2451
2452        /* Now construct a cflag setting. */
2453        switch (baud) {
2454        case 1200:
2455                cflag |= B1200;
2456                break;
2457        case 9600:
2458                cflag |= B9600;
2459                break;
2460        case 19200:
2461                cflag |= B19200;
2462                break;
2463        case 38400:
2464                cflag |= B38400;
2465                break;
2466        case 2400:
2467        default:
2468                cflag |= B2400;
2469                break;
2470        }
2471        switch (bits) {
2472        case 7:
2473                cflag |= CS7;
2474                break;
2475        default:
2476        case 8:
2477                cflag |= CS8;
2478                break;
2479        }
2480        switch (parity) {
2481        case 'o':
2482        case 'O':
2483                cflag |= PARODD;
2484                break;
2485        case 'e':
2486        case 'E':
2487                cflag |= PARENB;
2488                break;
2489        }
2490
2491        serial_console_info = &cy_port[ints[1]];
2492        serial_console_cflag = cflag;
2493        serial_console = ints[1] + 64;  /*callout_driver.minor_start */
2494}
2495#endif
2496
2497/*
2498 * The following is probably out of date for 2.1.x serial console stuff.
2499 *
2500 * The console is registered early on from arch/m68k/kernel/setup.c, and
2501 * it therefore relies on the chip being setup correctly by 166-Bug.  This
2502 * seems reasonable, as the serial port has been used to invoke the system
2503 * boot.  It also means that this function must not rely on any data
2504 * initialisation performed by serial167_init() etc.
2505 *
2506 * Of course, once the console has been registered, we had better ensure
2507 * that serial167_init() doesn't leave the chip non-functional.
2508 *
2509 * The console must be locked when we get here.
2510 */
2511
2512void serial167_console_write(struct console *co, const char *str,
2513                             unsigned count)
2514{
2515        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
2516        unsigned long flags;
2517        volatile u_char sink;
2518        u_char ier;
2519        int port;
2520        u_char do_lf = 0;
2521        int i = 0;
2522
2523        local_irq_save(flags);
2524
2525        /* Ensure transmitter is enabled! */
2526
2527        port = 0;
2528        base_addr[CyCAR] = (u_char) port;
2529        while (base_addr[CyCCR])
2530                ;
2531        base_addr[CyCCR] = CyENB_XMTR;
2532
2533        ier = base_addr[CyIER];
2534        base_addr[CyIER] = CyTxMpty;
2535
2536        while (1) {
2537                if (pcc2chip[PccSCCTICR] & 0x20) {
2538                        /* We have a Tx int. Acknowledge it */
2539                        sink = pcc2chip[PccTPIACKR];
2540                        if ((base_addr[CyLICR] >> 2) == port) {
2541                                if (i == count) {
2542                                        /* Last char of string is now output */
2543                                        base_addr[CyTEOIR] = CyNOTRANS;
2544                                        break;
2545                                }
2546                                if (do_lf) {
2547                                        base_addr[CyTDR] = '\n';
2548                                        str++;
2549                                        i++;
2550                                        do_lf = 0;
2551                                } else if (*str == '\n') {
2552                                        base_addr[CyTDR] = '\r';
2553                                        do_lf = 1;
2554                                } else {
2555                                        base_addr[CyTDR] = *str++;
2556                                        i++;
2557                                }
2558                                base_addr[CyTEOIR] = 0;
2559                        } else
2560                                base_addr[CyTEOIR] = CyNOTRANS;
2561                }
2562        }
2563
2564        base_addr[CyIER] = ier;
2565
2566        local_irq_restore(flags);
2567}
2568
2569static struct tty_driver *serial167_console_device(struct console *c,
2570                                                   int *index)
2571{
2572        *index = c->index;
2573        return cy_serial_driver;
2574}
2575
2576static struct console sercons = {
2577        .name = "ttyS",
2578        .write = serial167_console_write,
2579        .device = serial167_console_device,
2580        .flags = CON_PRINTBUFFER,
2581        .index = -1,
2582};
2583
2584static int __init serial167_console_init(void)
2585{
2586        if (vme_brdtype == VME_TYPE_MVME166 ||
2587            vme_brdtype == VME_TYPE_MVME167 ||
2588            vme_brdtype == VME_TYPE_MVME177) {
2589                mvme167_serial_console_setup(0);
2590                register_console(&sercons);
2591        }
2592        return 0;
2593}
2594
2595console_initcall(serial167_console_init);
2596
2597#ifdef CONFIG_REMOTE_DEBUG
2598void putDebugChar(int c)
2599{
2600        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
2601        unsigned long flags;
2602        volatile u_char sink;
2603        u_char ier;
2604        int port;
2605
2606        local_irq_save(flags);
2607
2608        /* Ensure transmitter is enabled! */
2609
2610        port = DEBUG_PORT;
2611        base_addr[CyCAR] = (u_char) port;
2612        while (base_addr[CyCCR])
2613                ;
2614        base_addr[CyCCR] = CyENB_XMTR;
2615
2616        ier = base_addr[CyIER];
2617        base_addr[CyIER] = CyTxMpty;
2618
2619        while (1) {
2620                if (pcc2chip[PccSCCTICR] & 0x20) {
2621                        /* We have a Tx int. Acknowledge it */
2622                        sink = pcc2chip[PccTPIACKR];
2623                        if ((base_addr[CyLICR] >> 2) == port) {
2624                                base_addr[CyTDR] = c;
2625                                base_addr[CyTEOIR] = 0;
2626                                break;
2627                        } else
2628                                base_addr[CyTEOIR] = CyNOTRANS;
2629                }
2630        }
2631
2632        base_addr[CyIER] = ier;
2633
2634        local_irq_restore(flags);
2635}
2636
2637int getDebugChar()
2638{
2639        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
2640        unsigned long flags;
2641        volatile u_char sink;
2642        u_char ier;
2643        int port;
2644        int i, c;
2645
2646        i = debugiq.out;
2647        if (i != debugiq.in) {
2648                c = debugiq.buf[i];
2649                if (++i == DEBUG_LEN)
2650                        i = 0;
2651                debugiq.out = i;
2652                return c;
2653        }
2654        /* OK, nothing in queue, wait in poll loop */
2655
2656        local_irq_save(flags);
2657
2658        /* Ensure receiver is enabled! */
2659
2660        port = DEBUG_PORT;
2661        base_addr[CyCAR] = (u_char) port;
2662#if 0
2663        while (base_addr[CyCCR])
2664                ;
2665        base_addr[CyCCR] = CyENB_RCVR;
2666#endif
2667        ier = base_addr[CyIER];
2668        base_addr[CyIER] = CyRxData;
2669
2670        while (1) {
2671                if (pcc2chip[PccSCCRICR] & 0x20) {
2672                        /* We have a Rx int. Acknowledge it */
2673                        sink = pcc2chip[PccRPIACKR];
2674                        if ((base_addr[CyLICR] >> 2) == port) {
2675                                int cnt = base_addr[CyRFOC];
2676                                while (cnt-- > 0) {
2677                                        c = base_addr[CyRDR];
2678                                        if (c == 0)
2679                                                printk
2680                                                    ("!! debug char is null (cnt=%d) !!",
2681                                                     cnt);
2682                                        else
2683                                                queueDebugChar(c);
2684                                }
2685                                base_addr[CyREOIR] = 0;
2686                                i = debugiq.out;
2687                                if (i == debugiq.in)
2688                                        panic("Debug input queue empty!");
2689                                c = debugiq.buf[i];
2690                                if (++i == DEBUG_LEN)
2691                                        i = 0;
2692                                debugiq.out = i;
2693                                break;
2694                        } else
2695                                base_addr[CyREOIR] = CyNOTRANS;
2696                }
2697        }
2698
2699        base_addr[CyIER] = ier;
2700
2701        local_irq_restore(flags);
2702
2703        return (c);
2704}
2705
2706void queueDebugChar(int c)
2707{
2708        int i;
2709
2710        i = debugiq.in;
2711        debugiq.buf[i] = c;
2712        if (++i == DEBUG_LEN)
2713                i = 0;
2714        if (i != debugiq.out)
2715                debugiq.in = i;
2716}
2717
2718static void debug_setup()
2719{
2720        unsigned long flags;
2721        volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
2722        int i, cflag;
2723
2724        cflag = B19200;
2725
2726        local_irq_save(flags);
2727
2728        for (i = 0; i < 4; i++) {
2729                base_addr[CyCAR] = i;
2730                base_addr[CyLICR] = i << 2;
2731        }
2732
2733        debugiq.in = debugiq.out = 0;
2734
2735        base_addr[CyCAR] = DEBUG_PORT;
2736
2737        /* baud rate */
2738        i = cflag & CBAUD;
2739
2740        base_addr[CyIER] = 0;
2741
2742        base_addr[CyCMR] = CyASYNC;
2743        base_addr[CyLICR] = DEBUG_PORT << 2;
2744        base_addr[CyLIVR] = 0x5c;
2745
2746        /* tx and rx baud rate */
2747
2748        base_addr[CyTCOR] = baud_co[i];
2749        base_addr[CyTBPR] = baud_bpr[i];
2750        base_addr[CyRCOR] = baud_co[i] >> 5;
2751        base_addr[CyRBPR] = baud_bpr[i];
2752
2753        /* set line characteristics  according configuration */
2754
2755        base_addr[CySCHR1] = 0;
2756        base_addr[CySCHR2] = 0;
2757        base_addr[CySCRL] = 0;
2758        base_addr[CySCRH] = 0;
2759        base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
2760        base_addr[CyCOR2] = 0;
2761        base_addr[CyCOR3] = Cy_1_STOP;
2762        base_addr[CyCOR4] = baud_cor4[i];
2763        base_addr[CyCOR5] = 0;
2764        base_addr[CyCOR6] = 0;
2765        base_addr[CyCOR7] = 0;
2766
2767        write_cy_cmd(base_addr, CyINIT_CHAN);
2768        write_cy_cmd(base_addr, CyENB_RCVR);
2769
2770        base_addr[CyCAR] = DEBUG_PORT;  /* !!! Is this needed? */
2771
2772        base_addr[CyRTPRL] = 2;
2773        base_addr[CyRTPRH] = 0;
2774
2775        base_addr[CyMSVR1] = CyRTS;
2776        base_addr[CyMSVR2] = CyDTR;
2777
2778        base_addr[CyIER] = CyRxData;
2779
2780        local_irq_restore(flags);
2781
2782}                               /* debug_setup */
2783
2784#endif
2785
2786MODULE_LICENSE("GPL");
2787