The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/chips/scc_8530_hdw.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1993-1989 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        scc_8530_hdw.c,v $
   29  * Revision 2.15  93/11/17  16:13:30  dbg
   30  *      Import kern/time_out.h for 'hz'.
   31  *      [93/06/11            dbg]
   32  * 
   33  * Revision 2.14  93/08/05  16:50:01  mrt
   34  *      Quick workaround for bad cabling on Flamingo. Tzk tzk...
   35  *      [93/08/05            af]
   36  * 
   37  * Revision 2.13  93/05/30  21:07:25  rvb
   38  *      Handle CTS transitions, for modem CTS/RTS flow control.
   39  *      [93/05/29  09:45:48  af]
   40  * 
   41  * Revision 2.12  93/05/20  19:32:56  rvb
   42  *      Added first (working) cut at true modem support, but I have
   43  *      a bad cable and needs finessing.
   44  *      Also, 3max+ support, from John Wroclawski (jtw@lcs.mit.edu).
   45  *      [93/05/08            af]
   46  *
   47  * Revision 2.11  93/05/17  17:10:46  rvb
   48  *      include machparam.h -> machspl.h
   49  * 
   50  * Revision 2.10  93/05/10  20:08:37  rvb
   51  *      Fixed types.
   52  *      [93/05/06  10:01:41  af]
   53  * 
   54  * Revision 2.9  93/03/26  17:58:01  mrt
   55  *      No minor()s, no dev_t.
   56  *      [93/03/18            af]
   57  * 
   58  * Revision 2.8  93/03/09  10:52:21  danner
   59  *      GCC quiet.
   60  *      [93/03/07  13:29:58  af]
   61  * 
   62  *      Post-debugging lint.
   63  *      [93/03/05            af]
   64  * 
   65  * Revision 2.7  93/02/05  08:05:17  danner
   66  *      Flamingo, full_modem and isa_console per-line.
   67  *      [93/02/04            af]
   68  * 
   69  * Revision 2.6  93/01/14  17:21:44  danner
   70  *      static/extern cleanups.
   71  *      [93/01/14            danner]
   72  * 
   73  *      Proper spl typing.
   74  *      [92/11/30            af]
   75  * 
   76  * Revision 2.5  92/05/05  10:04:59  danner
   77  *      Fixed how the interrupt routine plays with priorities.
   78  *      Ask for buffering on all lines.
   79  *      [92/05/04  11:15:43  af]
   80  * 
   81  *      Fixed for more than just rconsole-ing.  Two bugs: the chip
   82  *      needs one char out to generate the xmit-empty (so it really
   83  *      is a xmit-done) interrupt, and the t_addr game was not played
   84  *      properly.
   85  *      Tested both on maxine and the two serial lines kmin has.
   86  *      [92/04/14  11:47:26  af]
   87  * 
   88  * Revision 2.4  92/02/19  16:46:10  elf
   89  *      Uhmm, lotsa changes.  Basically, got channel B working
   90  *      and made it possible to use it as rconsole line.
   91  *      Missing modem bitsies only.
   92  *      A joint Terri&Sandro feature presentation.
   93  *      [92/02/10  17:03:08  af]
   94  * 
   95  * Revision 2.3  91/08/28  11:09:53  jsb
   96  *      Fixed scc_scan to actually check the tp->state each time,
   97  *      we are not notified when the MI code brutally zeroes it
   98  *      on close and so we cannot update our software CARrier.
   99  *      [91/08/27  16:18:05  af]
  100  * 
  101  * Revision 2.2  91/08/24  11:52:54  af
  102  *      Created, from the Zilog specs:
  103  *      "Z8530 SCC Serial Communications Controller, Product Specification"
  104  *      in the "1983/84 Components Data Book" pp 409-429, September 1983
  105  *      Zilog, Campbell, CA 95008
  106  *      [91/06/28            af]
  107  * 
  108  */
  109 /*
  110  *      File: scc_8530_hdw.c
  111  *      Author: Alessandro Forin, Carnegie Mellon University
  112  *      Date:   6/91
  113  *
  114  *      Hardware-level operations for the SCC Serial Line Driver
  115  */
  116 
  117 #include <scc.h>
  118 #if     NSCC > 0
  119 #include <bm.h>
  120 #include <platforms.h>
  121 
  122 #include <mach_kdb.h>
  123 
  124 #include <machine/machspl.h>            /* spl definitions */
  125 #include <mach/std_types.h>
  126 #include <kern/time_out.h>              /* hz */
  127 #include <device/io_req.h>
  128 #include <device/tty.h>
  129 
  130 #include <chips/busses.h>
  131 #include <chips/serial_defs.h>
  132 #include <chips/screen_defs.h>
  133 
  134 /* Alignment and padding */
  135 #if     defined(DECSTATION)
  136 /*
  137  * 3min's padding
  138  */
  139 typedef struct {
  140         char                    pad0;
  141         volatile unsigned char  datum;
  142         char                    pad1[2];
  143 } scc_padded1_register_t;
  144 
  145 #define scc_register_t  scc_padded1_register_t
  146 #endif
  147 
  148 #if     defined(FLAMINGO)
  149 typedef struct {
  150         volatile unsigned int   datum;
  151         unsigned int            pad1;
  152 } scc_padded1_register_t;
  153 
  154 #define scc_register_t  scc_padded1_register_t
  155 
  156 #define scc_set_datum(d,v)      (d) = (volatile unsigned int) (v) << 8, wbflush()
  157 #define scc_get_datum(d,v)      (v) = ((d) >> 8) & 0xff
  158 
  159 #endif
  160 
  161 #include <chips/scc_8530.h>     /* needs the above defs */
  162 
  163 #define private static
  164 #define public
  165 
  166 /*
  167  * Forward decls
  168  */
  169 private void check_car( struct tty *, boolean_t );
  170 
  171 /*
  172  * On the 3min keyboard and mouse come in on channels A
  173  * of the two units.  The MI code expects them at 'lines'
  174  * 0 and 1, respectively.  So we map here back and forth.
  175  * Note also the MI code believes unit 0 has four lines.
  176  */
  177 
  178 #define SCC_KBDUNIT     1
  179 #define SCC_PTRUNIT     0
  180 
  181 void mi_to_scc(
  182         int     *unitp,
  183         int     *linep)
  184 {
  185         /* only play games on MI 'unit' 0 */
  186         if (*unitp) {
  187                 /* e.g. by mapping the first four lines specially */
  188                 *unitp++;
  189                 return;
  190         }
  191 
  192         /* always get unit=0 (console) and line = 0|1 */
  193         if (*linep == SCREEN_LINE_KEYBOARD) {
  194                 *unitp = SCC_KBDUNIT;
  195                 *linep = SCC_CHANNEL_A;
  196         } else if (*linep == SCREEN_LINE_POINTER) {
  197                 *unitp = SCC_PTRUNIT;
  198                 *linep = SCC_CHANNEL_A;
  199         } else {
  200                 *unitp = (*linep & 1);
  201                 *linep = SCC_CHANNEL_B;
  202         }
  203 /* line 0 is channel B, line 1 is channel A */
  204 }
  205 
  206 #define NSCC_LINE       2       /* 2 ttys per chip */
  207 
  208 /* only care for mapping to ttyno */
  209 int scc_to_mi(
  210         int     sccunit,
  211         int     sccline)
  212 {
  213         if (sccunit > 1)
  214                 return (sccunit * NSCC_LINE + sccline);
  215         /* only for console (first pair of SCCs): */
  216         if (sccline == SCC_CHANNEL_A)
  217                 return ((!sccunit) & 1);
  218         return 2+sccunit;
  219 }
  220 
  221 
  222 /*
  223  * Driver status
  224  */
  225 struct scc_softc {
  226         scc_regmap_t    *regs;
  227 
  228         /* software copy of some write regs, for reg |= */
  229         struct softreg {
  230                 unsigned char   wr1;
  231                 unsigned char   wr4;
  232                 unsigned char   wr5;
  233                 unsigned char   wr14;
  234         } softr[2];     /* per channel */
  235 
  236         unsigned char   last_rr0[2];    /* for modem signals */
  237         unsigned short  fake;   /* missing rs232 bits, channel A */
  238         char            polling_mode;
  239         char            softCAR, osoftCAR;
  240         char            probed_once;
  241 
  242         boolean_t       full_modem;
  243         boolean_t       isa_console;
  244 
  245 } scc_softc_data[NSCC];
  246 
  247 typedef struct scc_softc *scc_softc_t;
  248 
  249 scc_softc_t     scc_softc[NSCC];
  250 
  251 void scc_softCAR(
  252         int     unit,
  253         int     line,
  254         int     on)
  255 {
  256         mi_to_scc(&unit, &line);
  257         if (on)
  258                 scc_softc[unit]->softCAR |= 1<<line;
  259         else
  260                 scc_softc[unit]->softCAR &= ~(1 << line);
  261 }
  262 
  263 
  264 /*
  265  * BRG formula is:
  266  *                              ClockFrequency
  267  *      BRGconstant =   ---------------------------  -  2
  268  *                      2 * BaudRate * ClockDivider
  269  */
  270 /* Speed selections with Pclk=7.3728Mhz, clock x16 */
  271 static
  272 short   scc_speeds[] =
  273         /* 0   50    75    110  134.5  150  200   300  600 1200 1800 2400 */
  274         {  0, 4606, 3070, 2093, 1711, 1534, 1150, 766, 382, 190, 126, 94,
  275 
  276         /* 4800 9600 19.2k 38.4k */
  277           46,   22,  10,    4};
  278 
  279 /*
  280  * Definition of the driver for the auto-configuration program.
  281  */
  282 
  283 boolean_t scc_probe(
  284         vm_offset_t     address,
  285         struct bus_device *ui);
  286 
  287 static void
  288 scc_attach(
  289         register struct bus_device *ui);
  290 
  291 vm_offset_t     scc_std[NSCC] = { 0 };
  292 struct  bus_device *scc_info[NSCC];
  293 struct  bus_driver scc_driver = 
  294         { scc_probe, 0, scc_attach, 0, scc_std, "scc", scc_info,};
  295 
  296 /*
  297  * Adapt/Probe/Attach functions
  298  */
  299 boolean_t               scc_uses_modem_control = FALSE;/* patch this with adb */
  300 
  301 void scc_param(
  302         struct tty      *tp,
  303         int             line);          /* forward */
  304 void scc_start(
  305         struct tty      *tp);
  306 
  307 void scc_putc(
  308         int             unit,
  309         int             line,
  310         int             c);
  311 
  312 int scc_getc(
  313         int             unit,
  314         int             line,
  315         boolean_t       wait,
  316         boolean_t       raw);
  317 
  318 void scc_pollc(
  319         int             unit,
  320         boolean_t       on);
  321 
  322 int  scc_mctl(
  323         int             dev,
  324         int             bits,
  325         int             how);
  326 
  327 void scc_set_modem_control(
  328         scc_softc_t     scc,
  329         boolean_t       on);
  330 
  331 void scc_modem_intr(
  332         scc_softc_t     scc,
  333         int             chan,
  334         int             unit);
  335 
  336 /*
  337  *      Set up console to point to SCC.
  338  */
  339 void set_scc_address(
  340         int             sccunit,
  341         vm_offset_t     regs,
  342         boolean_t       has_modem,
  343         boolean_t       isa_console)
  344 {
  345         scc_std[sccunit] = regs;
  346         scc_softc_data[sccunit].full_modem = has_modem & scc_uses_modem_control;
  347         scc_softc_data[sccunit].isa_console = isa_console;
  348 
  349         /* Do this here */
  350         console_probe           = scc_probe;
  351         console_param           = scc_param;
  352         console_start           = scc_start;
  353         console_putc            = scc_putc;
  354         console_getc            = scc_getc;
  355         console_pollc           = scc_pollc;
  356         console_mctl            = scc_mctl;
  357         console_softCAR         = scc_softCAR;
  358 
  359 }
  360 
  361 boolean_t scc_probe(
  362         vm_offset_t     address,
  363         struct bus_device *ui)
  364 {
  365         int             sccunit = ui->unit;
  366         scc_softc_t     scc;
  367         register int    val;
  368         register scc_regmap_t   *regs;
  369 
  370         regs = (scc_regmap_t *)scc_std[sccunit];
  371         if (regs == 0)
  372                 return 0;
  373 
  374         /*
  375          * See if we are here
  376          */
  377         if (check_memory(regs, 0)) {
  378                 /* no rides today */
  379                 return 0;
  380         }
  381 
  382         scc = &scc_softc_data[sccunit];
  383 
  384         if (scc->probed_once++){
  385                 return 1;
  386         }
  387         /*
  388          * Chip once-only initialization
  389          *
  390          * NOTE: The wiring we assume is the one on the 3min:
  391          *
  392          *      out     A-TxD   -->     TxD     keybd or mouse
  393          *      in      A-RxD   -->     RxD     keybd or mouse
  394          *      out     A-DTR~  -->     DTR     comm
  395          *      out     A-RTS~  -->     RTS     comm
  396          *      in      A-CTS~  -->     SI      comm
  397          *      in      A-DCD~  -->     RI      comm
  398          *      in      A-SYNCH~-->     DSR     comm
  399          *      out     B-TxD   -->     TxD     comm
  400          *      in      B-RxD   -->     RxD     comm
  401          *      in      B-RxC   -->     TRxCB   comm
  402          *      in      B-TxC   -->     RTxCB   comm
  403          *      out     B-RTS~  -->     SS      comm
  404          *      in      B-CTS~  -->     CTS     comm
  405          *      in      B-DCD~  -->     CD      comm
  406          */
  407 
  408         scc_softc[sccunit] = scc;
  409         scc->regs = regs;
  410 
  411         scc->fake = 1<<SCC_CHANNEL_A;
  412 
  413         { 
  414                 register int i;
  415                 /* We need this in scc_start only, hence the funny
  416                    value: we need it non-zero and we want to avoid
  417                    too much overhead in getting to (scc,regs,line) */
  418                 for (i = 0; i < NSCC_LINE; i++) {
  419                         register struct tty     *tp;
  420 
  421                         tp = console_tty[scc_to_mi(sccunit,i)];
  422                         tp->t_addr = (char*)(0x80000000L + (sccunit<<1) + (i&1));
  423                         /* do min buffering */
  424                         tp->t_state |= TS_MIN;
  425                 }
  426         }
  427 
  428         /* make sure reg pointer is in known state */
  429         scc_init_reg(regs, SCC_CHANNEL_A);
  430         scc_init_reg(regs, SCC_CHANNEL_B);
  431 
  432         /* reset chip, fully */
  433         scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR9, SCC_WR9_HW_RESET);
  434         delay(50000);/*enough ? */
  435         scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR9, 0);
  436 
  437         /* program the interrupt vector */
  438         scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR2, 0xf0);
  439         scc_write_reg(regs, SCC_CHANNEL_B, SCC_WR2, 0xf0);
  440         scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR9, SCC_WR9_VIS);
  441 
  442         /* most of the init is in scc_param() */
  443 
  444         /* timing base defaults */
  445         scc->softr[SCC_CHANNEL_A].wr4 = SCC_WR4_CLK_x16;
  446         scc->softr[SCC_CHANNEL_B].wr4 = SCC_WR4_CLK_x16;
  447 
  448         /* enable DTR, RTS and dont SS */
  449 #if     0
  450         /* According to one book I have this signal (pin 23, "SS")
  451            is "specified by the provider", meaning the EIA-232-D
  452            standard does not define what it is.  Better leave
  453            it alone */
  454         scc->softr[SCC_CHANNEL_B].wr5 = SCC_WR5_RTS;
  455 #else
  456         scc->softr[SCC_CHANNEL_B].wr5 = 0;
  457 #endif
  458         scc->softr[SCC_CHANNEL_A].wr5 = SCC_WR5_RTS | SCC_WR5_DTR;
  459 
  460         /* baud rates */
  461         val = SCC_WR14_BAUDR_ENABLE|SCC_WR14_BAUDR_SRC;
  462         scc->softr[SCC_CHANNEL_B].wr14 = val;
  463         scc->softr[SCC_CHANNEL_A].wr14 = val;
  464 
  465         /* interrupt conditions */
  466         val =   SCC_WR1_RXI_ALL_CHAR | SCC_WR1_PARITY_IE |
  467                 SCC_WR1_EXT_IE | SCC_WR1_TX_IE;         
  468         scc->softr[SCC_CHANNEL_A].wr1 = val;
  469         scc->softr[SCC_CHANNEL_B].wr1 = val;
  470 
  471         scc_read_reg_zero(regs, SCC_CHANNEL_A, scc->last_rr0[SCC_CHANNEL_A]);
  472         scc_read_reg_zero(regs, SCC_CHANNEL_B, scc->last_rr0[SCC_CHANNEL_B]);
  473 
  474         /*
  475          * After probing, any line that should be active
  476          * (keybd,mouse,rcline) is activated via scc_param().
  477          */
  478 
  479         scc_set_modem_control(scc, scc->full_modem);
  480 
  481 #if defined(KMIN) || defined (FLAMINGO) || defined(KN03)
  482         /*
  483          * Crock: MI code knows of unit 0 as console, we need
  484          * unit 1 as well since the keyboard is there
  485          * This is acceptable on maxine, which has to call its
  486          * only one chip unit 1 so that rconsole is happy.
  487          */
  488         if (sccunit == 0) {
  489                 struct bus_device d;
  490                 d = *ui;
  491                 d.unit = 1;
  492                 scc_probe(address, &d);
  493         }
  494 #endif
  495         return 1;
  496 }
  497 
  498 boolean_t scc_timer_started = FALSE;
  499 
  500 void scc_scan(void);    /* forward */
  501 
  502 static void
  503 scc_attach(
  504         register struct bus_device *ui)
  505 {
  506         int sccunit = ui->unit;
  507         extern int tty_inq_size;
  508         int i;
  509 
  510         /* We only have 4 ttys, but always at 9600
  511          * Give em a lot of room (plus dma..)
  512          */
  513         tty_inq_size = 4096;
  514         if (!scc_timer_started) {
  515                 /* do all of them, before we call scc_scan() */
  516                 /* harmless if done already */
  517                 for (i = 0; i < NSCC*NSCC_LINE; i++)
  518                         ttychars(console_tty[i]);
  519 
  520                 scc_timer_started = TRUE;
  521                 scc_scan();
  522         }
  523 
  524 #if     NBM > 0
  525         if (SCREEN_ISA_CONSOLE() && scc_softc[sccunit]->isa_console) {
  526                 printf("\n sl0: ");
  527                 if (sccunit && rcline == 3) printf("( rconsole )");
  528 
  529                 if (sccunit == SCC_KBDUNIT) {
  530                         printf("\n sl1: "); lk201_attach(0, sccunit >> 1);
  531                 } else if (sccunit == SCC_PTRUNIT) {
  532                         printf("\n sl1: "); mouse_attach(0, sccunit >> 1);
  533                 }
  534         } else
  535 #endif  /* NBM > 0 */
  536         {
  537                 printf("%s", (sccunit == 1) ?
  538                         "\n sl0: ( alternate console )\n sl1:" :
  539                         "\n sl0:\n sl1:");
  540         }
  541 }
  542 
  543 /*
  544  * Would you like to make a phone call ?
  545  */
  546 void
  547 scc_set_modem_control(
  548         scc_softc_t     scc,
  549         boolean_t       on)
  550 {
  551         if (on)
  552                 /* your problem if the hardware then is broke */
  553                 scc->fake = 0;
  554         else
  555                 scc->fake = 3;
  556         scc->full_modem = on;
  557         /* user should do an scc_param() ifchanged */
  558 }
  559 
  560 /*
  561  * Polled I/O (debugger)
  562  */
  563 void
  564 scc_pollc(
  565         int             unit,
  566         boolean_t       on)
  567 {
  568         scc_softc_t     scc;
  569         int             line = SCREEN_LINE_KEYBOARD,
  570                         sccunit = unit;
  571 
  572         mi_to_scc(&sccunit, &line);
  573 
  574         scc = scc_softc[sccunit];
  575         if (on) {
  576                 scc->polling_mode++;
  577 #if     NBM > 0
  578                 screen_on_off(unit, TRUE);
  579 #endif  /* NBM > 0 */
  580         } else
  581                 scc->polling_mode--;
  582 }
  583 
  584 /*
  585  * Interrupt routine
  586  */
  587 int scc_intr_count;
  588 
  589 void scc_intr(
  590         int     unit,
  591         spl_t   spllevel)
  592 {
  593         scc_softc_t             scc = scc_softc[unit];
  594         register scc_regmap_t   *regs = scc->regs;
  595         register int            rr1, rr2;
  596         register int            c;
  597 
  598 scc_intr_count++;
  599 
  600 #if     mips
  601         splx(spllevel);         /* lower priority */
  602 #endif
  603 
  604         while (1) {
  605 
  606           scc_read_reg(regs, SCC_CHANNEL_B, SCC_RR2, rr2);
  607 
  608           rr2 = SCC_RR2_STATUS(rr2);
  609 
  610           /* are we done yet ? */
  611           if (rr2 == 6) {       /* strange, distinguished value */
  612                 register int rr3;
  613                 scc_read_reg(regs, SCC_CHANNEL_A, SCC_RR3, rr3);
  614                 if (rr3 == 0)
  615                         return;
  616           }
  617 
  618           if ((rr2 == SCC_RR2_A_XMIT_DONE) || (rr2 == SCC_RR2_B_XMIT_DONE)) {
  619 
  620                 register chan = (rr2 == SCC_RR2_A_XMIT_DONE) ?
  621                                         SCC_CHANNEL_A : SCC_CHANNEL_B;
  622 
  623                 scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
  624                 c = cons_simple_tint(scc_to_mi(unit,chan), FALSE);
  625 
  626                 if (c == -1) {
  627                         /* no more data for this line */
  628 
  629                         scc_read_reg(regs, chan, SCC_RR15, c);
  630                         c &= ~SCC_WR15_TX_UNDERRUN_IE;
  631                         scc_write_reg(regs, chan, SCC_WR15, c);
  632 
  633                         c = scc->softr[chan].wr1 & ~SCC_WR1_TX_IE;
  634                         scc_write_reg(regs, chan, SCC_WR1, c);
  635                         scc->softr[chan].wr1 = c;
  636 
  637                         c = cons_simple_tint(scc_to_mi(unit,chan), TRUE);
  638                         if (c != -1)
  639                                 /* funny race, scc_start has been called already */
  640                                 scc_write_data(regs, chan, c);
  641                 } else {
  642                         scc_write_data(regs, chan, c);
  643                         /* and leave it enabled */
  644                 }
  645           }
  646 
  647           else if (rr2 == SCC_RR2_A_RECV_DONE) {
  648 
  649                 scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
  650                 if (scc->polling_mode)
  651                         continue;
  652 
  653                 scc_read_data(regs, SCC_CHANNEL_A, c);
  654                 rr1 = scc_to_mi(unit,SCC_CHANNEL_A);
  655                 cons_simple_rint (rr1, rr1, c, 0);
  656           }
  657 
  658           else if (rr2 == SCC_RR2_B_RECV_DONE) {
  659 
  660                 scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
  661                 if (scc->polling_mode)
  662                         continue;
  663 
  664                 scc_read_data(regs, SCC_CHANNEL_B, c);
  665                 rr1 = scc_to_mi(unit,SCC_CHANNEL_B);
  666                 cons_simple_rint (rr1, rr1, c, 0);
  667           }
  668 
  669           else if ((rr2 == SCC_RR2_A_EXT_STATUS) || (rr2 == SCC_RR2_B_EXT_STATUS)) {
  670                 int chan = (rr2 == SCC_RR2_A_EXT_STATUS) ?
  671                         SCC_CHANNEL_A : SCC_CHANNEL_B;
  672                 scc_write_reg(regs, chan, SCC_RR0, SCC_RESET_EXT_IP);
  673                 scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
  674                 scc_modem_intr(scc, chan, unit);
  675           }
  676 
  677           else if ((rr2 == SCC_RR2_A_RECV_SPECIAL) || (rr2 == SCC_RR2_B_RECV_SPECIAL)) {
  678                 register int chan = (rr2 == SCC_RR2_A_RECV_SPECIAL) ?
  679                         SCC_CHANNEL_A : SCC_CHANNEL_B;
  680 
  681                 scc_read_reg(regs, chan, SCC_RR1, rr1);
  682                 if (rr1 & (SCC_RR1_PARITY_ERR | SCC_RR1_RX_OVERRUN | SCC_RR1_FRAME_ERR)) {
  683                         int err;
  684                         /* map to CONS_ERR_xxx MI error codes */
  685                         err =   ((rr1 & SCC_RR1_PARITY_ERR)<<8) |
  686                                 ((rr1 & SCC_RR1_RX_OVERRUN)<<9) |
  687                                 ((rr1 & SCC_RR1_FRAME_ERR)<<7);
  688                         scc_write_reg(regs, chan, SCC_RR0, SCC_RESET_ERROR);
  689                         rr1 = scc_to_mi(unit,chan);
  690                         cons_simple_rint(rr1, rr1, 0, err);
  691                 }
  692                 scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
  693           }
  694 
  695         }
  696 
  697 }
  698 
  699 void
  700 scc_start(
  701         struct tty *tp)
  702 {
  703         register scc_regmap_t   *regs;
  704         register int            chan, temp;
  705         register struct softreg *sr;
  706 
  707         temp = (natural_t)tp->t_addr;
  708         chan = (temp & 1);      /* channel */
  709         temp = (temp >> 1)&0xff;/* sccunit */
  710         regs = scc_softc[temp]->regs;
  711         sr   = &scc_softc[temp]->softr[chan];
  712 
  713         scc_read_reg(regs, chan, SCC_RR15, temp);
  714         temp |= SCC_WR15_TX_UNDERRUN_IE;
  715         scc_write_reg(regs, chan, SCC_WR15, temp);
  716 
  717         temp = sr->wr1 | SCC_WR1_TX_IE;
  718         scc_write_reg(regs, chan, SCC_WR1, temp);
  719         sr->wr1 = temp;
  720 
  721         /* but we need a first char out or no cookie */
  722         scc_read_reg(regs, chan, SCC_RR0, temp);
  723         if (temp & SCC_RR0_TX_EMPTY)
  724         {
  725                 register char   c;
  726 
  727                 c = getc(&tp->t_outq);
  728                 scc_write_data(regs, chan, c);
  729         }
  730 }
  731 
  732 /*
  733  * Get a char from a specific SCC line
  734  * [this is only used for console&screen purposes]
  735  */
  736 int scc_getc(
  737         int             unit,
  738         int             line,
  739         boolean_t       wait,
  740         boolean_t       raw)
  741 {
  742         scc_softc_t     scc;
  743         register scc_regmap_t *regs;
  744         unsigned char   c;
  745         int             value, mi_line, rcvalue, from_line;
  746 
  747         mi_line = line;
  748         mi_to_scc(&unit, &line);
  749 
  750         scc = scc_softc[unit];
  751         regs = scc->regs;
  752 
  753         /*
  754          * wait till something available
  755          *
  756          * NOTE: we know! that rcline==3
  757          */
  758         if (rcline) rcline = 3;
  759 again:
  760         rcvalue = 0;
  761         while (1) {
  762                 scc_read_reg_zero(regs, line, value);
  763                 if (rcline && (mi_line == SCREEN_LINE_KEYBOARD)) {
  764                         scc_read_reg_zero(regs, SCC_CHANNEL_B, rcvalue);
  765                         value |= rcvalue;
  766                 }
  767                 if (((value & SCC_RR0_RX_AVAIL) == 0) && wait)
  768                         delay(10);
  769                 else
  770                         break;
  771         }
  772 
  773         /*
  774          * if nothing found return -1 
  775          */
  776         from_line = (rcvalue & SCC_RR0_RX_AVAIL) ? SCC_CHANNEL_B : line;
  777 
  778         if (value & SCC_RR0_RX_AVAIL) {
  779                 scc_read_reg(regs, from_line, SCC_RR1, value);
  780                 scc_read_data(regs, from_line, c);
  781         } else {
  782 /*              splx(s);*/
  783                 return -1;
  784         }
  785 
  786         /*
  787          * bad chars not ok 
  788          */
  789         if (value&(SCC_RR1_PARITY_ERR | SCC_RR1_RX_OVERRUN | SCC_RR1_FRAME_ERR)) {
  790 /* scc_state(unit,from_line); */
  791                 scc_write_reg(regs, from_line, SCC_RR0, SCC_RESET_ERROR);
  792                 if (wait) {
  793                         scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
  794                         goto again;
  795                 }
  796         }
  797         scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
  798 /*      splx(s);*/
  799 
  800 
  801 #if     NBM > 0
  802         if ((mi_line == SCREEN_LINE_KEYBOARD) && (from_line == SCC_CHANNEL_A) &&
  803             !raw && SCREEN_ISA_CONSOLE() && scc->isa_console)
  804                 return lk201_rint(SCREEN_CONS_UNIT(), c, wait, scc->polling_mode);
  805         else
  806 #endif  /* NBM > 0 */
  807                 return c;
  808 }
  809 
  810 /*
  811  * Put a char on a specific SCC line
  812  */
  813 void scc_putc(
  814         int     unit,
  815         int     line,
  816         int     c)
  817 {
  818         scc_softc_t      scc;
  819         register scc_regmap_t *regs;
  820         spl_t             s = spltty();
  821         register int    value;
  822 
  823         mi_to_scc(&unit, &line);
  824 
  825         scc = scc_softc[unit];
  826         regs = scc->regs;
  827 
  828         do {
  829                 scc_read_reg(regs, line, SCC_RR0, value);
  830                 if (value & SCC_RR0_TX_EMPTY)
  831                         break;
  832                 delay(100);
  833         } while (1);
  834 
  835         scc_write_data(regs, line, c);
  836 /* wait for it to swallow the char ? */
  837 
  838         splx(s);
  839 }
  840 
  841 void scc_param(
  842         struct tty      *tp,
  843         int             line)
  844 {
  845         scc_regmap_t    *regs;
  846         int             value, sccline, unit;
  847         struct softreg  *sr;
  848         scc_softc_t     scc;
  849  
  850         line = tp->t_dev;
  851         /* MI code wants us to handle 4 lines on unit 0 */
  852         unit = (line < 4) ? 0 : (line / NSCC_LINE);
  853         sccline = line;
  854         mi_to_scc(&unit, &sccline);
  855 
  856         if ((scc = scc_softc[unit]) == 0) return;       /* sanity */
  857         regs = scc->regs;
  858 
  859         sr = &scc->softr[sccline];
  860 
  861         /*
  862          * Do not let user fool around with kbd&mouse
  863          */
  864 #if     NBM > 0
  865         if (screen_captures(line)) {
  866                 tp->t_ispeed = tp->t_ospeed = B4800;
  867                 tp->t_flags |= TF_LITOUT;
  868         }
  869 #endif  /* NBM > 0 */
  870 
  871         if (tp->t_ispeed == 0) {
  872                 (void) scc_mctl(tp->t_dev, TM_HUP, DMSET);      /* hang up line */
  873                 return;
  874         }
  875 
  876         /* reset line */
  877         value = (sccline == SCC_CHANNEL_A) ? SCC_WR9_RESET_CHA_A : SCC_WR9_RESET_CHA_B;
  878         scc_write_reg(regs, sccline, SCC_WR9, value);
  879         delay(25);
  880 
  881         /* stop bits, normally 1 */
  882         value = sr->wr4 & 0xf0;
  883         value |= (tp->t_ispeed == B110) ? SCC_WR4_2_STOP : SCC_WR4_1_STOP;
  884 
  885         /* .. and parity */
  886         if ((tp->t_flags & (TF_ODDP | TF_EVENP)) == TF_ODDP)
  887                 value |= SCC_WR4_PARITY_ENABLE;
  888 
  889         /* set it now, remember it must be first after reset */
  890         sr->wr4 = value;
  891         scc_write_reg(regs, sccline, SCC_WR4, value);
  892 
  893         /* vector again */
  894         scc_write_reg(regs, sccline, SCC_WR2, 0xf0);
  895 
  896         /* we only do 8 bits per char */
  897         value = SCC_WR3_RX_8_BITS;
  898         scc_write_reg(regs, sccline, SCC_WR3, value);
  899 
  900         /* clear break, keep rts dtr */
  901         value = sr->wr5 & (SCC_WR5_DTR|SCC_WR5_RTS);
  902         value |= SCC_WR5_TX_8_BITS;
  903         sr->wr5 = value;
  904         scc_write_reg(regs, sccline, SCC_WR5, value);
  905         /* some are on the other channel, which might
  906            never be used (e.g. maxine has only one line) */
  907         {
  908                 register int otherline = (sccline+1)&1;
  909 
  910                 scc_write_reg(regs, otherline, SCC_WR5, scc->softr[otherline].wr5);
  911         }
  912 
  913         scc_write_reg(regs, sccline, SCC_WR6, 0);
  914         scc_write_reg(regs, sccline, SCC_WR7, 0);
  915 
  916         scc_write_reg(regs, sccline, SCC_WR9, SCC_WR9_VIS);
  917 
  918         scc_write_reg(regs, sccline, SCC_WR10, 0);
  919 
  920         /* clock config */
  921         value = SCC_WR11_RCLK_BAUDR | SCC_WR11_XTLK_BAUDR |
  922                 SCC_WR11_TRc_OUT | SCC_WR11_TRcOUT_BAUDR;
  923         scc_write_reg(regs, sccline, SCC_WR11, value);
  924 
  925         value = scc_speeds[tp->t_ispeed];
  926         scc_set_timing_base(regs,sccline,value);
  927 
  928         value = sr->wr14;
  929         scc_write_reg(regs, sccline, SCC_WR14, value);
  930 
  931 #if     FLAMINGO
  932         if (unit != 1)
  933 #else
  934         if (1)
  935 #endif
  936         {
  937                 /* Chan-A: CTS==SI DCD==RI DSR=SYNCH */
  938                 value = SCC_WR15_CTS_IE | SCC_WR15_DCD_IE | SCC_WR15_SYNCHUNT_IE;
  939                 scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR15, value);
  940 
  941                 /* Chan-B: CTS==CTS DCD==DCD */
  942                 value = SCC_WR15_BREAK_IE | SCC_WR15_CTS_IE | SCC_WR15_DCD_IE;
  943                 scc_write_reg(regs, SCC_CHANNEL_B, SCC_WR15, value);
  944         } else {
  945                 /* Here if modem bits are floating noise, keep quiet */
  946                 value = SCC_WR15_BREAK_IE;
  947                 scc_write_reg(regs, sccline, SCC_WR15, value);
  948         }
  949 
  950         /* and now the enables */
  951         value = SCC_WR3_RX_8_BITS | SCC_WR3_RX_ENABLE;
  952         scc_write_reg(regs, sccline, SCC_WR3, value);
  953 
  954         value = sr->wr5 | SCC_WR5_TX_ENABLE;
  955         sr->wr5 = value;
  956         scc_write_reg(regs, sccline, SCC_WR5, value);
  957 
  958         /* master inter enable */
  959         scc_write_reg(regs,sccline,SCC_WR9,SCC_WR9_MASTER_IE|SCC_WR9_VIS);
  960 
  961         scc_write_reg(regs, sccline, SCC_WR1, sr->wr1);
  962 
  963 }
  964  
  965 /*
  966  * Modem control functions
  967  */
  968 int
  969 scc_mctl(
  970         int     dev,
  971         int     bits,
  972         int     how)
  973 {
  974         register scc_regmap_t *regs;
  975         struct softreg  *sra, *srb, *sr;
  976         int unit, sccline;
  977         int b = 0;
  978         spl_t   s;
  979         scc_softc_t      scc;
  980 
  981         /* MI code wants us to handle 4 lines on unit 0 */
  982         unit = (dev < 4) ? 0 : (dev / NSCC_LINE);
  983         sccline = dev;
  984         mi_to_scc(&unit, &sccline);
  985 
  986         if ((scc = scc_softc[unit]) == 0) return 0;     /* sanity */
  987         regs = scc->regs;
  988 
  989         sr  = &scc->softr[sccline];
  990         sra = &scc->softr[SCC_CHANNEL_A];
  991         srb = &scc->softr[SCC_CHANNEL_B];
  992 
  993         if (bits == TM_HUP) {   /* close line (internal) */
  994                 bits = TM_DTR | TM_RTS;
  995                 how = DMBIC;
  996                 /* xxx interrupts too ?? */
  997         }
  998 
  999         if (bits & TM_BRK) {
 1000                 switch (how) {
 1001                 case DMSET:
 1002                 case DMBIS:
 1003                         sr->wr5 |= SCC_WR5_SEND_BREAK;
 1004                         break;
 1005                 case DMBIC:
 1006                         sr->wr5 &= ~SCC_WR5_SEND_BREAK;
 1007                         break;
 1008                 default:
 1009                         goto dontbrk;
 1010                 }
 1011                 s = spltty();
 1012                 scc_write_reg(regs, sccline, SCC_WR5, sr->wr5);
 1013                 splx(s);
 1014 dontbrk:
 1015                 b |= (sr->wr5 & SCC_WR5_SEND_BREAK) ? TM_BRK : 0;
 1016         }
 1017 
 1018         /* no modem support on channel A */
 1019         if (sccline == SCC_CHANNEL_A)
 1020                 return (b | TM_LE | TM_DTR | TM_CTS | TM_CAR | TM_DSR);
 1021 
 1022         sra = &scc->softr[SCC_CHANNEL_A];
 1023         srb = &scc->softr[SCC_CHANNEL_B];
 1024 
 1025 #if 0
 1026         /* do I need to do something on this ? */
 1027         if (bits & TM_LE) {     /* line enable */
 1028         }
 1029 #endif
 1030 
 1031         if (bits & (TM_DTR|TM_RTS)) {   /* data terminal ready, request to send */
 1032                 register int    w = 0;
 1033 
 1034                 if (bits & TM_DTR) w |= SCC_WR5_DTR;
 1035                 if (bits & TM_RTS) w |= SCC_WR5_RTS;
 1036 
 1037                 switch (how) {
 1038                 case DMSET:
 1039                 case DMBIS:
 1040                         sra->wr5 |= w;
 1041                         break;
 1042                 case DMBIC:
 1043                         sra->wr5 &= ~w;
 1044                         break;
 1045                 default:
 1046                         goto dontdtr;
 1047                 }
 1048                 s = spltty();
 1049                 scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR5, sra->wr5);
 1050                 splx(s);
 1051 dontdtr:
 1052                 b |= (sra->wr5 & w) ? (bits & (TM_DTR|TM_RTS)) : 0;
 1053         }
 1054 
 1055         s = spltty();
 1056 
 1057 #if 0
 1058         /* Unsupported */
 1059         if (bits & TM_ST) {     /* secondary transmit */
 1060         }
 1061         if (bits & TM_SR) {     /* secondary receive */
 1062         }
 1063 #endif
 1064 
 1065         if (bits & TM_CTS) {    /* clear to send */
 1066                 register int value;
 1067                 scc_read_reg(regs, SCC_CHANNEL_B, SCC_RR0, value);
 1068                 b |= (value & SCC_RR0_CTS) ? TM_CTS : 0;
 1069         }
 1070 
 1071         if (bits & TM_CAR) {    /* carrier detect */
 1072                 register int value;
 1073                 scc_read_reg(regs, SCC_CHANNEL_B, SCC_RR0, value);
 1074                 b |= (value & SCC_RR0_DCD) ? TM_CAR : 0;
 1075         }
 1076 
 1077         if (bits & TM_RNG) {    /* ring */
 1078                 register int value;
 1079                 scc_read_reg(regs, SCC_CHANNEL_A, SCC_RR0, value);
 1080                 b |= (value & SCC_RR0_DCD) ? TM_RNG : 0;
 1081         }
 1082 
 1083         if (bits & TM_DSR) {    /* data set ready */
 1084                 register int value;
 1085                 scc_read_reg(regs, SCC_CHANNEL_A, SCC_RR0, value);
 1086                 b |= (value & SCC_RR0_SYNCH) ? TM_DSR : 0;
 1087         }
 1088 
 1089         splx(s);
 1090 
 1091         return b;
 1092 }
 1093 
 1094 #define debug 0
 1095 
 1096 void
 1097 scc_modem_intr(
 1098         scc_softc_t     scc,
 1099         int             chan,
 1100         int             unit)
 1101 {
 1102         register int value, changed;
 1103 
 1104         scc_read_reg_zero(scc->regs, chan, value);
 1105 
 1106         /* See what changed */
 1107         changed = value ^ scc->last_rr0[chan];
 1108         scc->last_rr0[chan] = value;
 1109 
 1110 #if debug
 1111 printf("sccmodem: chan %c now %x, changed %x : ",
 1112         (chan == SCC_CHANNEL_B) ? 'B' : 'A',
 1113         value, changed);
 1114 #endif
 1115 
 1116         if (chan == SCC_CHANNEL_A) {
 1117                 if (changed & SCC_RR0_CTS) {
 1118                         /* Speed indicator, ignore XXX */
 1119 #if debug
 1120 printf("%s-speed ", (value & SCC_RR0_CTS) ? "Full" : "Half");
 1121 #endif
 1122                 }
 1123                 if (changed & SCC_RR0_DCD) {
 1124                         /* Ring indicator */
 1125 #if debug
 1126 printf("Ring ");
 1127 #endif
 1128                 }
 1129                 if (changed & SCC_RR0_SYNCH) {
 1130                         /* Data Set Ready */
 1131 #if debug
 1132 printf("DSR ");
 1133 #endif
 1134                         /* If modem went down then CD will also go down,
 1135                            or it did already.
 1136                            If modem came up then we have to wait for CD
 1137                            anyways before enabling the line.
 1138                            Either way, nothing to do here */
 1139                 }
 1140         } else {
 1141                 if (changed & SCC_RR0_CTS) {
 1142                         /* Clear To Send */
 1143 #if debug
 1144 printf("CTS ");
 1145 #endif
 1146                         tty_cts(console_tty[scc_to_mi(unit,chan)],
 1147                                 value & SCC_RR0_CTS);
 1148                 }
 1149                 if (changed & SCC_RR0_DCD) {
 1150 #if debug
 1151 printf("CD ");
 1152 #endif
 1153                         check_car(console_tty[scc_to_mi(unit,chan)],
 1154                                   value & SCC_RR0_DCD);
 1155                 }
 1156         }
 1157 #if debug
 1158 printf(".\n");
 1159 #endif
 1160 }
 1161 
 1162 private void check_car(
 1163         register struct tty *tp,
 1164         boolean_t car)
 1165 {
 1166         if (car) {
 1167 #if notyet
 1168                 /* cancel modem timeout if need to */
 1169                 if (car & (SCC_MSR_CD2 | SCC_MSR_CD3))
 1170                         untimeout(scc_hup, (vm_offset_t)tp);
 1171 #endif
 1172 
 1173                 /* I think this belongs in the MI code */
 1174                 if (tp->t_state & TS_WOPEN)
 1175                         tp->t_state |= TS_ISOPEN;
 1176                 /* carrier present */
 1177                 if ((tp->t_state & TS_CARR_ON) == 0)
 1178                         (void)ttymodem(tp, 1);
 1179         } else if ((tp->t_state&TS_CARR_ON) && ttymodem(tp, 0) == 0)
 1180                 scc_mctl( tp->t_dev, TM_DTR, DMBIC);
 1181 }
 1182 
 1183 /*
 1184  * Periodically look at the CD signals:
 1185  * they do generate interrupts but we
 1186  * must fake them on channel A.  We might
 1187  * also fake them on channel B.
 1188  */
 1189 void scc_scan(void)
 1190 {
 1191         register i;
 1192         spl_t s = spltty();
 1193 
 1194         for (i = 0; i < NSCC; i++) {
 1195                 register scc_softc_t    scc;
 1196                 register int            car;
 1197                 register struct tty     **tpp;
 1198 
 1199                 scc = scc_softc[i];
 1200                 if (scc == 0)
 1201                         continue;
 1202                 car = scc->softCAR | scc->fake;
 1203 
 1204                 tpp = &console_tty[i * NSCC_LINE];
 1205 
 1206                 while (car) {
 1207                         if (car & 1)
 1208                                 check_car(*tpp, 1);
 1209                         tpp++;
 1210                         car  = car>>1;
 1211                 }
 1212 
 1213         }
 1214         splx(s);
 1215         timeout(scc_scan, (vm_offset_t)0, 5*hz);
 1216 }
 1217 
 1218 
 1219 #if debug
 1220 scc_rr0(unit,chan)
 1221 {
 1222         int val;
 1223         scc_read_reg_zero(scc_softc[unit]->regs, chan, val);
 1224         return val;
 1225 }
 1226 
 1227 scc_rreg(unit,chan,n)
 1228 {
 1229         int val;
 1230         scc_read_reg(scc_softc[unit]->regs, chan, n, val);
 1231         return val;
 1232 }
 1233 
 1234 scc_wreg(unit,chan,n,val)
 1235 {
 1236         scc_write_reg(scc_softc[unit]->regs, chan, n, val);
 1237 }
 1238 
 1239 scc_state(unit,soft)
 1240 {
 1241         int     rr0, rr1, rr3, rr12, rr13, rr15;
 1242 
 1243         rr0 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR0);
 1244         rr1 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR1);
 1245         rr3 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR3);
 1246         rr12 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR12);
 1247         rr13 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR13);
 1248         rr15 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR15);
 1249         printf("{%d intr, A: R0 %x R1 %x R3 %x baudr %x R15 %x}\n",
 1250                 scc_intr_count, rr0, rr1, rr3, 
 1251                 (rr13 << 8) | rr12, rr15);
 1252 
 1253         rr0 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR0);
 1254         rr1 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR1);
 1255         rr3 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR2);
 1256         rr12 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR12);
 1257         rr13 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR13);
 1258         rr15 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR15);
 1259         printf("{B: R0 %x R1 %x R2 %x baudr %x R15 %x}\n",
 1260                 rr0, rr1, rr3, 
 1261                 (rr13 << 8) | rr12, rr15);
 1262 
 1263         if (soft) {
 1264                 struct softreg *sr;
 1265                 sr = scc_softc[unit]->softr;
 1266                 printf("{B: W1 %x W4 %x W5 %x W14 %x}",
 1267                         sr->wr1, sr->wr4, sr->wr5, sr->wr14);
 1268                 sr++;
 1269                 printf("{A: W1 %x W4 %x W5 %x W14 %x}\n",
 1270                         sr->wr1, sr->wr4, sr->wr5, sr->wr14);
 1271         }
 1272 }
 1273 
 1274 #endif
 1275 
 1276 #endif  /* NSCC > 0 */

Cache object: 91831ce37330f305140308cf270934cc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.