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