Home | History | Annotate | Line # | Download | only in marvell
gtmpsc.c revision 1.27.14.1
      1  1.27.14.1       mjf /*	$NetBSD: gtmpsc.c,v 1.27.14.1 2008/06/02 13:23:33 mjf Exp $	*/
      2        1.1      matt 
      3        1.1      matt /*
      4        1.1      matt  * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
      5        1.1      matt  * All rights reserved.
      6        1.1      matt  *
      7        1.1      matt  * Redistribution and use in source and binary forms, with or without
      8        1.1      matt  * modification, are permitted provided that the following conditions
      9        1.1      matt  * are met:
     10        1.1      matt  * 1. Redistributions of source code must retain the above copyright
     11        1.1      matt  *    notice, this list of conditions and the following disclaimer.
     12        1.1      matt  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1      matt  *    notice, this list of conditions and the following disclaimer in the
     14        1.1      matt  *    documentation and/or other materials provided with the distribution.
     15        1.1      matt  * 3. All advertising materials mentioning features or use of this software
     16        1.1      matt  *    must display the following acknowledgement:
     17        1.1      matt  *      This product includes software developed for the NetBSD Project by
     18        1.1      matt  *      Allegro Networks, Inc., and Wasabi Systems, Inc.
     19        1.1      matt  * 4. The name of Allegro Networks, Inc. may not be used to endorse
     20        1.1      matt  *    or promote products derived from this software without specific prior
     21        1.1      matt  *    written permission.
     22        1.1      matt  * 5. The name of Wasabi Systems, Inc. may not be used to endorse
     23        1.1      matt  *    or promote products derived from this software without specific prior
     24        1.1      matt  *    written permission.
     25        1.1      matt  *
     26        1.1      matt  * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
     27        1.1      matt  * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     28        1.1      matt  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     29        1.1      matt  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     30        1.1      matt  * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
     31        1.1      matt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32        1.1      matt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33        1.1      matt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34        1.1      matt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35        1.1      matt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36        1.1      matt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37        1.1      matt  * POSSIBILITY OF SUCH DAMAGE.
     38        1.1      matt  */
     39        1.1      matt 
     40        1.1      matt /*
     41        1.1      matt  * mpsc.c - MPSC serial driver, supports UART mode only
     42        1.1      matt  *
     43        1.1      matt  *
     44        1.1      matt  * creation	Mon Apr  9 19:40:15 PDT 2001	cliff
     45        1.1      matt  */
     46        1.9     lukem 
     47        1.9     lukem #include <sys/cdefs.h>
     48  1.27.14.1       mjf __KERNEL_RCSID(0, "$NetBSD: gtmpsc.c,v 1.27.14.1 2008/06/02 13:23:33 mjf Exp $");
     49        1.1      matt 
     50        1.1      matt #include "opt_kgdb.h"
     51        1.1      matt 
     52        1.1      matt #include <sys/param.h>
     53        1.1      matt #include <sys/conf.h>
     54        1.1      matt #include <sys/device.h>
     55       1.18        he #include <sys/kauth.h>
     56        1.1      matt #include <sys/proc.h>
     57        1.1      matt #include <sys/systm.h>
     58        1.1      matt #include <sys/tty.h>
     59        1.1      matt #include <sys/callout.h>
     60        1.1      matt #include <sys/fcntl.h>
     61       1.25   garbled #include <sys/intr.h>
     62        1.1      matt #ifdef KGDB
     63        1.1      matt #include <sys/kernel.h>
     64        1.1      matt #include <sys/kgdb.h>
     65        1.1      matt #endif
     66        1.6   thorpej 
     67        1.6   thorpej #include <uvm/uvm_extern.h>
     68        1.6   thorpej 
     69        1.1      matt #include <powerpc/atomic.h>
     70        1.1      matt #include <dev/cons.h>
     71       1.26        ad #include <sys/bus.h>
     72       1.26        ad #include <sys/cpu.h>		/* for DELAY */
     73        1.1      matt #include <machine/stdarg.h>
     74        1.1      matt #include "gtmpsc.h"
     75        1.1      matt 
     76        1.1      matt 
     77        1.1      matt #include <dev/marvell/gtreg.h>
     78        1.1      matt #include <dev/marvell/gtvar.h>
     79        1.1      matt #include <dev/marvell/gtintrreg.h>
     80        1.1      matt #include <dev/marvell/gtmpscreg.h>
     81        1.1      matt #include <dev/marvell/gtsdmareg.h>
     82        1.1      matt #include <dev/marvell/gtmpscvar.h>
     83        1.1      matt #include <dev/marvell/gtbrgreg.h>
     84        1.1      matt 
     85        1.1      matt /*
     86        1.1      matt  * XXX these delays were derived empiracaly
     87        1.1      matt  */
     88        1.1      matt #define GTMPSC_POLL_DELAY	1	/* 1 usec */
     89        1.5      matt /*
     90        1.5      matt  * Wait 2 characters time for RESET_DELAY
     91        1.5      matt  */
     92        1.5      matt #define GTMPSC_RESET_DELAY	(2*8*1000000 / GT_MPSC_DEFAULT_BAUD_RATE)
     93        1.1      matt 
     94        1.1      matt #define BURSTLEN 128
     95        1.1      matt 
     96        1.1      matt /*
     97        1.1      matt  * stat values for gtmpsc_common_pollc
     98        1.1      matt  */
     99        1.1      matt #define GTMPSC_STAT_NONE	0
    100        1.1      matt #define GTMPSC_STAT_BREAK	1
    101        1.1      matt 
    102        1.1      matt 
    103        1.1      matt #define PRINTF(x)	gtmpsc_mem_printf x
    104        1.1      matt 
    105        1.1      matt #if defined(DEBUG)
    106        1.5      matt unsigned int gtmpsc_debug = 0;
    107        1.1      matt # define STATIC
    108        1.5      matt # define DPRINTF(x)	do { if (gtmpsc_debug) gtmpsc_mem_printf x ; } while (0)
    109        1.1      matt #else
    110        1.1      matt # define STATIC static
    111        1.1      matt # define DPRINTF(x)
    112        1.1      matt #endif
    113        1.1      matt 
    114        1.1      matt #define GTMPSCUNIT_MASK    0x7ffff
    115        1.1      matt #define GTMPSCDIALOUT_MASK 0x80000
    116        1.1      matt 
    117        1.1      matt #define GTMPSCUNIT(x)      (minor(x) & GTMPSCUNIT_MASK)
    118        1.1      matt #define GTMPSCDIALOUT(x)   (minor(x) & GTMPSCDIALOUT_MASK)
    119        1.1      matt 
    120        1.2      matt STATIC void gtmpscinit(struct gtmpsc_softc *);
    121        1.2      matt STATIC int  gtmpscmatch(struct device *, struct cfdata *, void *);
    122        1.2      matt STATIC void gtmpscattach(struct device *, struct device *, void *);
    123        1.2      matt STATIC int  compute_cdv(unsigned int);
    124        1.2      matt STATIC void gtmpsc_loadchannelregs(struct gtmpsc_softc *);
    125        1.2      matt STATIC void gtmpscshutdown(struct gtmpsc_softc *);
    126        1.2      matt STATIC void gtmpscstart(struct tty *);
    127        1.2      matt STATIC int  gtmpscparam(struct tty *, struct termios *);
    128        1.2      matt STATIC int  gtmpsc_probe(void);
    129        1.2      matt STATIC int  gtmpsc_intr(void *);
    130        1.3      matt STATIC void gtmpsc_softintr(void *);
    131        1.1      matt 
    132        1.2      matt STATIC void gtmpsc_common_putn(struct gtmpsc_softc *);
    133        1.2      matt STATIC void gtmpsc_common_putc(unsigned int, unsigned char);
    134        1.2      matt STATIC int  gtmpsc_common_getc(unsigned int);
    135        1.2      matt STATIC int  gtmpsc_common_pollc(unsigned int, char *, int *);
    136        1.2      matt STATIC void gtmpsc_poll(void *);
    137        1.1      matt #ifdef KGDB
    138        1.2      matt STATIC void gtmpsc_kgdb_poll(void *);
    139        1.1      matt #endif
    140        1.2      matt STATIC void gtmpsc_mem_printf(const char *, ...);
    141        1.1      matt 
    142        1.1      matt STATIC void gtmpsc_txdesc_init(gtmpsc_poll_sdma_t *, gtmpsc_poll_sdma_t *);
    143        1.1      matt STATIC void gtmpsc_rxdesc_init(gtmpsc_poll_sdma_t *, gtmpsc_poll_sdma_t *);
    144        1.1      matt STATIC unsigned int gtmpsc_get_causes(void);
    145        1.3      matt STATIC void gtmpsc_hackinit(struct gtmpsc_softc *, bus_space_tag_t,
    146        1.3      matt 	bus_space_handle_t, int);
    147        1.1      matt STATIC void gtmpscinit_stop(struct gtmpsc_softc *, int);
    148        1.1      matt STATIC void gtmpscinit_start(struct gtmpsc_softc *, int);
    149        1.2      matt #if 0
    150        1.1      matt void gtmpsc_printf(const char *fmt, ...);
    151        1.2      matt #endif
    152        1.1      matt void gtmpsc_puts(char *);
    153        1.1      matt 
    154        1.2      matt void gtmpsccnprobe(struct consdev *);
    155        1.2      matt void gtmpsccninit(struct consdev *);
    156        1.2      matt int  gtmpsccngetc(dev_t);
    157        1.2      matt void gtmpsccnputc(dev_t, int);
    158        1.2      matt void gtmpsccnpollc(dev_t, int);
    159        1.2      matt void gtmpsccnhalt(dev_t);
    160        1.2      matt 
    161        1.2      matt STATIC void gtmpsc_txflush(gtmpsc_softc_t *);
    162        1.2      matt STATIC void gtmpsc_iflush(gtmpsc_softc_t *);
    163        1.2      matt STATIC void gtmpsc_shutdownhook(void *);
    164        1.1      matt 
    165        1.1      matt dev_type_open(gtmpscopen);
    166        1.1      matt dev_type_close(gtmpscclose);
    167        1.1      matt dev_type_read(gtmpscread);
    168        1.1      matt dev_type_write(gtmpscwrite);
    169        1.1      matt dev_type_ioctl(gtmpscioctl);
    170        1.1      matt dev_type_stop(gtmpscstop);
    171        1.1      matt dev_type_tty(gtmpsctty);
    172        1.1      matt dev_type_poll(gtmpscpoll);
    173        1.1      matt 
    174        1.1      matt const struct cdevsw gtmpsc_cdevsw = {
    175        1.1      matt 	gtmpscopen, gtmpscclose, gtmpscread, gtmpscwrite, gtmpscioctl,
    176        1.1      matt 	gtmpscstop, gtmpsctty, gtmpscpoll, nommap, ttykqfilter, D_TTY
    177        1.1      matt };
    178        1.1      matt 
    179        1.1      matt CFATTACH_DECL(gtmpsc, sizeof(struct gtmpsc_softc),
    180        1.1      matt     gtmpscmatch, gtmpscattach, NULL, NULL);
    181        1.1      matt 
    182        1.1      matt extern struct cfdriver gtmpsc_cd;
    183        1.1      matt 
    184        1.4      matt static struct consdev gtmpsc_consdev = {
    185        1.4      matt 	0,
    186        1.1      matt 	gtmpsccninit,
    187        1.1      matt 	gtmpsccngetc,
    188        1.1      matt 	gtmpsccnputc,
    189        1.1      matt 	gtmpsccnpollc,
    190        1.2      matt 	NULL,		/* cn_bell */
    191        1.4      matt 	gtmpsccnhalt,
    192        1.1      matt 	NULL,		/* cn_flush */
    193        1.4      matt 	NODEV,
    194        1.4      matt 	CN_NORMAL
    195        1.1      matt };
    196        1.1      matt 
    197        1.1      matt STATIC void *gtmpsc_sdma_ih = NULL;
    198        1.1      matt 
    199        1.1      matt gtmpsc_softc_t *gtmpsc_scp[GTMPSC_NCHAN] = { 0 };
    200        1.1      matt 
    201        1.1      matt STATIC int gt_reva_gtmpsc_bug;
    202        1.1      matt unsigned int sdma_imask;        /* soft copy of SDMA IMASK reg */
    203        1.1      matt 
    204        1.1      matt #ifdef KGDB
    205        1.1      matt static int gtmpsc_kgdb_addr;
    206        1.1      matt static int gtmpsc_kgdb_attached;
    207        1.1      matt 
    208        1.1      matt int kgdb_break_immediate /* = 0 */ ;
    209        1.1      matt 
    210        1.2      matt STATIC int      gtmpsc_kgdb_getc(void *);
    211        1.2      matt STATIC void     gtmpsc_kgdb_putc(void *, int);
    212        1.1      matt #endif /* KGDB */
    213        1.1      matt 
    214        1.1      matt /*
    215        1.1      matt  * hacks for console initialization
    216        1.1      matt  * which happens prior to autoconfig "attach"
    217        1.6   thorpej  *
    218        1.6   thorpej  * XXX Assumes PAGE_SIZE is a constant!
    219        1.1      matt  */
    220        1.1      matt STATIC unsigned int gtmpsccninit_done = 0;
    221        1.1      matt STATIC gtmpsc_softc_t gtmpsc_fake_softc;
    222        1.6   thorpej STATIC unsigned char gtmpsc_earlybuf[PAGE_SIZE]
    223        1.6   thorpej     __attribute__ ((aligned(PAGE_SIZE)));
    224        1.6   thorpej STATIC unsigned char gtmpsc_fake_dmapage[PAGE_SIZE]
    225        1.6   thorpej     __attribute__ ((aligned(PAGE_SIZE)));
    226        1.1      matt 
    227        1.1      matt 
    228        1.1      matt #define GTMPSC_PRINT_BUF_SIZE	4096
    229        1.1      matt STATIC unsigned char gtmpsc_print_buf[GTMPSC_PRINT_BUF_SIZE] = { 0 };
    230        1.1      matt 
    231        1.1      matt unsigned int gtmpsc_poll_putc_cnt = 0;
    232        1.1      matt unsigned int gtmpsc_poll_putn_cnt = 0;
    233        1.1      matt unsigned int gtmpsc_poll_getc_cnt = 0;
    234        1.1      matt unsigned int gtmpsc_poll_pollc_cnt = 0;
    235        1.1      matt unsigned int gtmpsc_poll_putc_miss = 0;
    236        1.1      matt unsigned int gtmpsc_poll_putn_miss = 0;
    237        1.1      matt unsigned int gtmpsc_poll_getc_miss = 0;
    238        1.1      matt unsigned int gtmpsc_poll_pollc_miss = 0;
    239        1.1      matt 
    240        1.1      matt #ifndef SDMA_COHERENT
    241        1.1      matt /*
    242        1.1      matt  * inlines to flush, invalidate cache
    243        1.1      matt  * required if DMA cache coherency is broken
    244        1.1      matt  * note that pointer `p' args are assumed to be cache aligned
    245        1.1      matt  * and the size is assumed to be one CACHELINESIZE block
    246        1.1      matt  */
    247        1.1      matt 
    248        1.1      matt #define GTMPSC_CACHE_FLUSH(p)		gtmpsc_cache_flush(p)
    249        1.1      matt #define GTMPSC_CACHE_INVALIDATE(p)	gtmpsc_cache_invalidate(p)
    250        1.1      matt 
    251       1.19       mrg static inline void
    252        1.1      matt gtmpsc_cache_flush(void *p)
    253        1.1      matt {
    254       1.14     perry 	__asm volatile ("eieio; dcbf 0,%0; lwz %0,0(%0); sync;"
    255        1.1      matt 					: "+r"(p):);
    256        1.1      matt }
    257        1.1      matt 
    258       1.19       mrg static inline void
    259        1.1      matt gtmpsc_cache_invalidate(void *p)
    260        1.1      matt {
    261       1.14     perry 	__asm volatile ("eieio; dcbi 0,%0; sync;" :: "r"(p));
    262        1.1      matt }
    263        1.1      matt #else
    264        1.1      matt 
    265        1.1      matt #define GTMPSC_CACHE_FLUSH(p)
    266        1.1      matt #define GTMPSC_CACHE_INVALIDATE(p)
    267        1.1      matt 
    268        1.1      matt #endif	/* SDMA_COHERENT */
    269        1.1      matt 
    270        1.3      matt #define GT_READ(sc,o) \
    271        1.3      matt 	bus_space_read_4((sc)->gtmpsc_memt, (sc)->gtmpsc_memh, (o))
    272        1.3      matt #define GT_WRITE(sc,o,v) \
    273        1.3      matt 	bus_space_write_4((sc)->gtmpsc_memt, (sc)->gtmpsc_memh, (o), (v))
    274        1.1      matt 
    275        1.1      matt 
    276        1.3      matt #define SDMA_IMASK_ENABLE(sc, bit)  do { \
    277       1.11       scw 	unsigned int    __r; \
    278        1.3      matt 	GT_WRITE(sc, SDMA_ICAUSE, ~(bit)); \
    279        1.1      matt 	if (gt_reva_gtmpsc_bug) \
    280       1.11       scw 		__r = sdma_imask; \
    281        1.1      matt 	else \
    282       1.11       scw 		__r = GT_READ(sc, SDMA_IMASK); \
    283       1.11       scw 	__r |= (bit); \
    284       1.11       scw 	sdma_imask = __r; \
    285       1.11       scw 	GT_WRITE(sc, SDMA_IMASK, __r); \
    286        1.3      matt } while (/*CONSTCOND*/ 0)
    287        1.1      matt 
    288        1.3      matt #define SDMA_IMASK_DISABLE(sc, bit)  do { \
    289       1.11       scw 	unsigned int    __r; \
    290        1.1      matt 	if (gt_reva_gtmpsc_bug) \
    291       1.11       scw 		__r = sdma_imask; \
    292        1.1      matt 	else \
    293       1.11       scw 		__r = GT_READ(sc, SDMA_IMASK); \
    294       1.11       scw 	__r &= ~(bit); \
    295       1.11       scw 	sdma_imask = __r; \
    296       1.11       scw 	GT_WRITE(sc, SDMA_IMASK, __r); \
    297        1.3      matt } while (/*CONSTCOND*/ 0)
    298        1.1      matt 
    299       1.19       mrg static inline unsigned int
    300        1.1      matt desc_read(unsigned int *ip)
    301        1.1      matt {
    302        1.1      matt 	unsigned int rv;
    303        1.1      matt 
    304       1.14     perry 	__asm volatile ("lwzx %0,0,%1; eieio;"
    305        1.1      matt 		: "=r"(rv) : "r"(ip));
    306        1.1      matt 	return rv;
    307        1.1      matt }
    308        1.1      matt 
    309       1.19       mrg static inline void
    310        1.1      matt desc_write(unsigned int *ip, unsigned int val)
    311        1.1      matt {
    312       1.14     perry 	__asm volatile ("stwx %0,0,%1; eieio;"
    313        1.1      matt 		:: "r"(val), "r"(ip));
    314        1.1      matt }
    315        1.1      matt 
    316        1.1      matt 
    317        1.1      matt /*
    318        1.1      matt  * gtmpsc_txdesc_init - set up TX descriptor ring
    319        1.1      matt  */
    320        1.1      matt STATIC void
    321        1.1      matt gtmpsc_txdesc_init(gtmpsc_poll_sdma_t *vmps, gtmpsc_poll_sdma_t *pmps)
    322        1.1      matt {
    323        1.1      matt 	int n;
    324        1.1      matt 	sdma_desc_t *dp;
    325        1.1      matt 	gtmpsc_polltx_t *vtxp;
    326        1.1      matt 	gtmpsc_polltx_t *ptxp;
    327        1.1      matt 	gtmpsc_polltx_t *next_ptxp;
    328        1.1      matt 	gtmpsc_polltx_t *first_ptxp;
    329        1.1      matt 
    330        1.1      matt 	first_ptxp = ptxp = &pmps->tx[0];
    331        1.1      matt 	vtxp = &vmps->tx[0];
    332        1.1      matt 	next_ptxp = ptxp + 1;
    333        1.1      matt 	for (n = (GTMPSC_NTXDESC - 1); n--; ) {
    334        1.1      matt 		dp = &vtxp->txdesc;
    335        1.1      matt 		desc_write(&dp->sdma_csr, 0);
    336        1.1      matt 		desc_write(&dp->sdma_cnt, 0);
    337        1.1      matt 		desc_write(&dp->sdma_bufp, (u_int32_t)&ptxp->txbuf);
    338        1.1      matt 		desc_write(&dp->sdma_next, (u_int32_t)&next_ptxp->txdesc);
    339        1.1      matt 		GTMPSC_CACHE_FLUSH(dp);
    340        1.1      matt 		vtxp++;
    341        1.1      matt 		ptxp++;
    342        1.1      matt 		next_ptxp++;
    343        1.1      matt 	}
    344        1.1      matt 	dp = &vtxp->txdesc;
    345        1.1      matt 	desc_write(&dp->sdma_csr, 0);
    346        1.1      matt 	desc_write(&dp->sdma_cnt, 0);
    347        1.1      matt 	desc_write(&dp->sdma_bufp, (u_int32_t)&ptxp->txbuf);
    348        1.1      matt 	desc_write(&dp->sdma_next, (u_int32_t)&first_ptxp->txdesc);
    349        1.1      matt 	GTMPSC_CACHE_FLUSH(dp);
    350        1.1      matt }
    351        1.1      matt 
    352        1.1      matt /*
    353        1.1      matt  * gtmpsc_rxdesc_init - set up RX descriptor ring
    354        1.1      matt  */
    355        1.1      matt STATIC void
    356        1.1      matt gtmpsc_rxdesc_init(gtmpsc_poll_sdma_t *vmps, gtmpsc_poll_sdma_t *pmps)
    357        1.1      matt {
    358        1.1      matt 	int n;
    359        1.1      matt 	sdma_desc_t *dp;
    360        1.1      matt 	gtmpsc_pollrx_t *vrxp;
    361        1.1      matt 	gtmpsc_pollrx_t *prxp;
    362        1.1      matt 	gtmpsc_pollrx_t *next_prxp;
    363        1.1      matt 	gtmpsc_pollrx_t *first_prxp;
    364        1.1      matt 	unsigned int csr;
    365        1.1      matt 
    366        1.1      matt 	csr = SDMA_CSR_RX_L|SDMA_CSR_RX_F|SDMA_CSR_RX_OWN|SDMA_CSR_RX_EI;
    367        1.1      matt 	first_prxp = prxp = &pmps->rx[0];
    368        1.1      matt 	vrxp = &vmps->rx[0];
    369        1.1      matt 	next_prxp = prxp + 1;
    370        1.1      matt 	for (n = (GTMPSC_NRXDESC - 1); n--; ) {
    371        1.1      matt 		dp = &vrxp->rxdesc;
    372        1.1      matt 		desc_write(&dp->sdma_csr, csr);
    373        1.1      matt 		desc_write(&dp->sdma_cnt,
    374        1.1      matt 			GTMPSC_RXBUFSZ << SDMA_RX_CNT_BUFSZ_SHIFT);
    375        1.1      matt 		desc_write(&dp->sdma_bufp, (u_int32_t)&prxp->rxbuf);
    376        1.1      matt 		desc_write(&dp->sdma_next, (u_int32_t)&next_prxp->rxdesc);
    377        1.1      matt 		GTMPSC_CACHE_FLUSH(dp);
    378        1.1      matt 		vrxp++;
    379        1.1      matt 		prxp++;
    380        1.1      matt 		next_prxp++;
    381        1.1      matt 	}
    382        1.1      matt 	dp = &vrxp->rxdesc;
    383        1.1      matt 	desc_write(&dp->sdma_csr, SDMA_CSR_RX_OWN);
    384        1.1      matt 	desc_write(&dp->sdma_cnt,
    385        1.1      matt 		GTMPSC_RXBUFSZ << SDMA_RX_CNT_BUFSZ_SHIFT);
    386        1.1      matt 	desc_write(&dp->sdma_bufp, (u_int32_t)&prxp->rxbuf);
    387        1.1      matt 	desc_write(&dp->sdma_next, (u_int32_t)&first_prxp->rxdesc);
    388        1.1      matt 	GTMPSC_CACHE_FLUSH(dp);
    389        1.1      matt }
    390        1.1      matt 
    391        1.1      matt /*
    392        1.1      matt  * Compute the BRG countdown value (CDV in BRG_BCR)
    393        1.1      matt  */
    394        1.1      matt 
    395        1.1      matt STATIC int
    396        1.1      matt compute_cdv(unsigned int baud)
    397        1.1      matt {
    398        1.1      matt 	unsigned int    cdv;
    399        1.1      matt 
    400        1.1      matt 	if (baud == 0)
    401        1.1      matt 		return 0;
    402        1.4      matt 	cdv = (GT_MPSC_FREQUENCY / (baud * GTMPSC_CLOCK_DIVIDER) + 1) / 2 - 1;
    403        1.1      matt 	if (cdv > BRG_BCR_CDV_MAX)
    404        1.1      matt 		return -1;
    405        1.1      matt 	return cdv;
    406        1.1      matt }
    407        1.1      matt 
    408        1.1      matt STATIC void
    409        1.1      matt gtmpsc_loadchannelregs(struct gtmpsc_softc *sc)
    410        1.1      matt {
    411        1.1      matt 	u_int   brg_bcr;
    412        1.1      matt 	u_int   unit;
    413        1.1      matt 
    414        1.1      matt 	unit = sc->gtmpsc_unit;
    415        1.1      matt 	brg_bcr = unit ? BRG_BCR1 : BRG_BCR0;
    416        1.1      matt 
    417        1.3      matt 	GT_WRITE(sc, brg_bcr, sc->gtmpsc_brg_bcr);
    418        1.3      matt 	GT_WRITE(sc, GTMPSC_U_CHRN(unit, 3), sc->gtmpsc_chr3);
    419        1.1      matt }
    420        1.1      matt 
    421        1.1      matt STATIC int
    422        1.1      matt gtmpscmatch(struct device *parent, struct cfdata *self, void *aux)
    423        1.1      matt {
    424       1.16   thorpej 	struct gt_softc *gt = device_private(parent);
    425        1.1      matt 	struct gt_attach_args *ga = aux;
    426        1.1      matt 
    427        1.3      matt 	return GT_MPSCOK(gt, ga, &gtmpsc_cd);
    428        1.1      matt }
    429        1.1      matt 
    430        1.1      matt STATIC void
    431        1.1      matt gtmpscattach(struct device *parent, struct device *self, void *aux)
    432        1.1      matt {
    433        1.1      matt 	struct gt_attach_args *ga = aux;
    434       1.16   thorpej 	struct gt_softc *gt = device_private(parent);
    435       1.16   thorpej 	struct gtmpsc_softc *sc = device_private(self);
    436        1.1      matt 	gtmpsc_poll_sdma_t *vmps;
    437        1.1      matt 	gtmpsc_poll_sdma_t *pmps;
    438        1.1      matt 	struct tty *tp;
    439       1.23  christos 	void *kva;
    440        1.1      matt 	int rsegs;
    441        1.1      matt 	int err;
    442        1.1      matt 	int s;
    443        1.5      matt 	int is_console = 0;
    444        1.1      matt 
    445        1.1      matt 	DPRINTF(("mpscattach\n"));
    446        1.3      matt 
    447        1.3      matt 	GT_MPSCFOUND(gt, ga);
    448        1.1      matt 
    449        1.1      matt 	s = splhigh();
    450        1.1      matt 
    451        1.1      matt 	sc->gtmpsc_memt = ga->ga_memt;
    452        1.3      matt 	sc->gtmpsc_memh = ga->ga_memh;
    453        1.1      matt 	sc->gtmpsc_dmat = ga->ga_dmat;
    454        1.1      matt 	sc->gtmpsc_unit = ga->ga_unit;
    455        1.1      matt 
    456        1.4      matt 	aprint_normal(": SDMA");
    457        1.6   thorpej 	err = bus_dmamem_alloc(sc->gtmpsc_dmat, PAGE_SIZE, PAGE_SIZE, PAGE_SIZE,
    458        1.4      matt 	    sc->gtmpsc_dma_segs, 1, &rsegs, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW);
    459        1.1      matt 	if (err) {
    460        1.1      matt 		PRINTF(("mpscattach: bus_dmamem_alloc error 0x%x\n", err));
    461        1.1      matt 		splx(s);
    462        1.1      matt 		return;
    463        1.1      matt 	}
    464        1.1      matt #ifndef SDMA_COHERENT
    465        1.6   thorpej 	err = bus_dmamem_map(sc->gtmpsc_dmat, sc->gtmpsc_dma_segs, 1, PAGE_SIZE,
    466        1.4      matt 	    &kva, BUS_DMA_NOWAIT);
    467        1.1      matt #else
    468        1.6   thorpej 	err = bus_dmamem_map(sc->gtmpsc_dmat, sc->gtmpsc_dma_segs, 1, PAGE_SIZE,
    469        1.4      matt 	    &kva, BUS_DMA_NOWAIT|BUS_DMA_NOCACHE);
    470        1.1      matt #endif
    471        1.1      matt 	if (err) {
    472        1.1      matt 		PRINTF(("mpscattach: bus_dmamem_map error 0x%x\n", err));
    473        1.1      matt 		splx(s);
    474        1.1      matt 		return;
    475        1.1      matt 	}
    476        1.1      matt 
    477        1.6   thorpej 	err = bus_dmamap_create(sc->gtmpsc_dmat, PAGE_SIZE, 1, PAGE_SIZE,
    478        1.6   thorpej 	    PAGE_SIZE, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &sc->gtmpsc_dma_map);
    479        1.4      matt 	if (err) {
    480        1.4      matt 		PRINTF(("mpscattach: bus_dmamap_create error 0x%x\n", err));
    481        1.4      matt 		splx(s);
    482        1.4      matt 		return;
    483        1.4      matt 	}
    484        1.4      matt 
    485        1.6   thorpej 	err = bus_dmamap_load(sc->gtmpsc_dmat, sc->gtmpsc_dma_map, kva,
    486        1.6   thorpej 	    PAGE_SIZE, NULL, 0);
    487        1.4      matt 	if (err) {
    488        1.4      matt 		PRINTF(("mpscattach: bus_dmamap_load error 0x%x\n", err));
    489        1.4      matt 		splx(s);
    490        1.4      matt 		return;
    491        1.4      matt 	}
    492        1.6   thorpej 	memset(kva, 0, PAGE_SIZE);	/* paranoid/superfluous */
    493        1.1      matt 
    494        1.1      matt 	vmps = (gtmpsc_poll_sdma_t *)kva;				    /* KVA */
    495        1.4      matt 	pmps = (gtmpsc_poll_sdma_t *)sc->gtmpsc_dma_map->dm_segs[0].ds_addr;    /* PA */
    496        1.5      matt #if defined(DEBUG)
    497        1.1      matt 	printf(" at %p/%p", vmps, pmps);
    498        1.1      matt #endif
    499        1.1      matt 	gtmpsc_txdesc_init(vmps, pmps);
    500        1.1      matt 	gtmpsc_rxdesc_init(vmps, pmps);
    501        1.1      matt 	sc->gtmpsc_poll_sdmapage = vmps;
    502        1.1      matt 
    503        1.1      matt 	if (gtmpsc_scp[sc->gtmpsc_unit] != NULL)
    504        1.1      matt 		gtmpsc_txflush(gtmpsc_scp[sc->gtmpsc_unit]);
    505        1.1      matt 
    506        1.1      matt 	sc->gtmpsc_tty = tp = ttymalloc();
    507        1.1      matt 	tp->t_oproc = gtmpscstart;
    508        1.1      matt 	tp->t_param = gtmpscparam;
    509        1.1      matt 	tty_attach(tp);
    510        1.1      matt 
    511        1.3      matt 	if (gtmpsc_sdma_ih == NULL) {
    512        1.3      matt 		gtmpsc_sdma_ih = intr_establish(IRQ_SDMA, IST_LEVEL, IPL_SERIAL,
    513        1.1      matt 			gtmpsc_intr, &sc);
    514        1.3      matt 		if (gtmpsc_sdma_ih == NULL)
    515        1.1      matt 			panic("mpscattach: cannot intr_establish IRQ_SDMA");
    516        1.3      matt 	}
    517        1.1      matt 
    518       1.24        ad 	sc->sc_si = softint_establish(SOFTINT_SERIAL, gtmpsc_softintr, sc);
    519        1.3      matt 	if (sc->sc_si == NULL)
    520       1.24        ad 		panic("mpscattach: cannot softint_establish IPL_SOFTSERIAL");
    521        1.1      matt 
    522        1.1      matt 	shutdownhook_establish(gtmpsc_shutdownhook, sc);
    523        1.1      matt 
    524        1.5      matt 	gtmpsc_scp[sc->gtmpsc_unit] = sc;
    525        1.5      matt 	gtmpscinit(sc);
    526        1.5      matt 
    527        1.5      matt 	if (cn_tab == &gtmpsc_consdev &&
    528        1.5      matt 	    cn_tab->cn_dev == makedev(0, sc->gtmpsc_unit)) {
    529        1.5      matt 		cn_tab->cn_dev = makedev(cdevsw_lookup_major(&gtmpsc_cdevsw),
    530       1.15   thorpej 		    device_unit(&sc->gtmpsc_dev));
    531        1.5      matt 		is_console = 1;
    532        1.5      matt 	}
    533        1.5      matt 
    534        1.5      matt 	aprint_normal(" irq %s%s\n",
    535        1.5      matt 	    intr_string(IRQ_SDMA),
    536        1.5      matt 	    (gt_reva_gtmpsc_bug) ? " [Rev A. bug]" : "");
    537        1.5      matt 
    538        1.5      matt 	if (is_console)
    539  1.27.14.1       mjf 		aprint_normal_dev(&sc->gtmpsc_dev, "console\n");
    540        1.5      matt 
    541        1.1      matt #ifdef DDB
    542        1.5      matt 	if (is_console == 0)
    543        1.3      matt 		SDMA_IMASK_ENABLE(sc, SDMA_INTR_RXBUF(sc->gtmpsc_unit));
    544        1.1      matt #endif	/* DDB */
    545        1.1      matt 
    546        1.1      matt 	splx(s);
    547        1.1      matt #ifdef KGDB
    548        1.1      matt 	/*
    549        1.1      matt 	 * Allow kgdb to "take over" this port.  If this is
    550        1.1      matt 	 * the kgdb device, it has exclusive use.
    551        1.1      matt 	 */
    552        1.1      matt 	if (sc->gtmpsc_unit == comkgdbport) {
    553        1.1      matt 		if (comkgdbport == 0) { /* FIXME */
    554  1.27.14.1       mjf 			aprint_error_dev(&sc->gtmpsc_dev, "(kgdb): cannot share with console\n");
    555        1.1      matt 			return;
    556        1.1      matt 		}
    557        1.1      matt 
    558        1.1      matt 		sc->gtmpsc_flags |= GTMPSCF_KGDB;
    559  1.27.14.1       mjf 		printf("%s: kgdb\n", device_xname(&sc->gtmpsc_dev));
    560        1.1      matt 		gtmpsc_txflush(gtmpsc_scp[0]);
    561        1.1      matt 		kgdb_attach(gtmpsc_kgdb_getc, gtmpsc_kgdb_putc, NULL);
    562        1.1      matt 		kgdb_dev = 123; /* unneeded, only to satisfy some tests */
    563        1.1      matt 		gtmpsc_kgdb_attached = 1;
    564        1.3      matt 		SDMA_IMASK_ENABLE(sc, SDMA_INTR_RXBUF(sc->gtmpsc_unit));
    565        1.1      matt 		kgdb_connect(1);
    566        1.1      matt 	}
    567        1.1      matt #endif /* KGDB */
    568        1.1      matt }
    569        1.1      matt 
    570        1.1      matt STATIC void
    571        1.1      matt gtmpscshutdown(struct gtmpsc_softc *sc)
    572        1.1      matt {
    573        1.1      matt 	struct tty *tp;
    574        1.1      matt 	int     s;
    575        1.1      matt 
    576        1.1      matt #ifdef KGDB
    577        1.1      matt 	if (sc->gtmpsc_flags & GTMPSCF_KGDB != 0)
    578        1.1      matt 		return;
    579        1.1      matt #endif
    580        1.1      matt 	tp = sc->gtmpsc_tty;
    581        1.1      matt 	s = splserial();
    582        1.1      matt 	/* Fake carrier off */
    583        1.1      matt 	(void) (*tp->t_linesw->l_modem)(tp, 0);
    584        1.3      matt 	SDMA_IMASK_DISABLE(sc, SDMA_INTR_RXBUF(sc->gtmpsc_unit));
    585        1.1      matt 	splx(s);
    586        1.1      matt }
    587        1.1      matt 
    588        1.1      matt int
    589       1.13  christos gtmpscopen(dev_t dev, int flag, int mode, struct lwp *l)
    590        1.1      matt {
    591        1.1      matt 	struct gtmpsc_softc *sc;
    592        1.1      matt 	int unit = GTMPSCUNIT(dev);
    593        1.1      matt 	struct tty *tp;
    594        1.1      matt 	int s;
    595        1.1      matt 	int s2;
    596        1.1      matt 	int error;
    597       1.10     perry 
    598        1.1      matt 	if (unit >= gtmpsc_cd.cd_ndevs)
    599        1.1      matt 		return ENXIO;
    600        1.1      matt 	sc = gtmpsc_cd.cd_devs[unit];
    601        1.1      matt 	if (!sc)
    602        1.1      matt 		return ENXIO;
    603        1.1      matt #ifdef KGDB
    604        1.1      matt 	/*
    605        1.1      matt 	 * If this is the kgdb port, no other use is permitted.
    606        1.1      matt 	 */
    607        1.1      matt 	if (sc->gtmpsc_flags & GTMPSCF_KGDB != 0)
    608        1.1      matt 		return (EBUSY);
    609        1.1      matt #endif
    610        1.1      matt 	tp = sc->gtmpsc_tty;
    611       1.21      elad 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
    612        1.1      matt 		return (EBUSY);
    613        1.1      matt 
    614        1.1      matt 	s = spltty();
    615        1.1      matt 
    616        1.1      matt 	if (!(tp->t_state & TS_ISOPEN)) {
    617        1.1      matt 		struct termios t;
    618        1.1      matt 
    619        1.1      matt 		tp->t_dev = dev;
    620        1.1      matt 		s2 = splserial();
    621        1.3      matt 		SDMA_IMASK_ENABLE(sc, SDMA_INTR_RXBUF(unit));
    622        1.1      matt 		splx(s2);
    623        1.1      matt 		t.c_ispeed = 0;
    624        1.1      matt #if 0
    625        1.1      matt 		t.c_ospeed = TTYDEF_SPEED;
    626        1.1      matt #else
    627        1.1      matt 		t.c_ospeed = GT_MPSC_DEFAULT_BAUD_RATE;
    628        1.1      matt #endif
    629        1.1      matt 		t.c_cflag = TTYDEF_CFLAG;
    630        1.1      matt 		/* Make sure gtmpscparam() will do something. */
    631        1.1      matt 		tp->t_ospeed = 0;
    632        1.1      matt 		(void) gtmpscparam(tp, &t);
    633        1.1      matt 		tp->t_iflag = TTYDEF_IFLAG;
    634        1.1      matt 		tp->t_oflag = TTYDEF_OFLAG;
    635        1.1      matt 		tp->t_lflag = TTYDEF_LFLAG;
    636        1.1      matt 		ttychars(tp);
    637        1.1      matt 		ttsetwater(tp);
    638        1.1      matt 		s2 = splserial();
    639        1.1      matt 		/* Clear the input ring */
    640        1.1      matt 		sc->gtmpsc_rxfifo_putix = 0;
    641        1.1      matt 		sc->gtmpsc_rxfifo_getix = 0;
    642        1.1      matt 		sc->gtmpsc_rxfifo_navail = GTMPSC_RXFIFOSZ;
    643        1.1      matt 		gtmpsc_iflush(sc);
    644        1.1      matt 		splx(s2);
    645        1.1      matt 	}
    646        1.1      matt 	splx(s);
    647        1.1      matt 	error = ttyopen(tp, GTMPSCDIALOUT(dev), ISSET(flag, O_NONBLOCK));
    648        1.1      matt 	if (error)
    649        1.1      matt 		goto bad;
    650        1.1      matt 
    651        1.1      matt 	error = (*tp->t_linesw->l_open)(dev, tp);
    652        1.1      matt 	if (error)
    653        1.1      matt 		goto bad;
    654        1.1      matt 
    655        1.1      matt 	return (0);
    656        1.1      matt 
    657        1.1      matt bad:
    658        1.1      matt 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
    659        1.1      matt 		/*
    660        1.1      matt 		 * We failed to open the device, and nobody else had it opened.
    661        1.1      matt 		 * Clean up the state as appropriate.
    662        1.1      matt 		 */
    663        1.1      matt 		gtmpscshutdown(sc);
    664        1.1      matt 	}
    665        1.1      matt 
    666        1.1      matt 	return (error);
    667        1.1      matt }
    668        1.1      matt 
    669        1.1      matt int
    670       1.13  christos gtmpscclose(dev_t dev, int flag, int mode, struct lwp *l)
    671        1.1      matt {
    672        1.1      matt 	int unit = GTMPSCUNIT(dev);
    673        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_cd.cd_devs[unit];
    674        1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    675        1.1      matt 	int s;
    676        1.1      matt 
    677        1.1      matt 	s = splserial();
    678        1.1      matt 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
    679        1.1      matt 		splx(s);
    680        1.1      matt 		return (0);
    681        1.1      matt 	}
    682        1.1      matt 
    683        1.1      matt 	(*tp->t_linesw->l_close)(tp, flag);
    684        1.1      matt 	ttyclose(tp);
    685        1.1      matt 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
    686        1.1      matt 		/*
    687        1.1      matt 		 * Although we got a last close, the device may still be in
    688        1.1      matt 		 * use; e.g. if this was the dialout node, and there are still
    689        1.1      matt 		 * processes waiting for carrier on the non-dialout node.
    690        1.1      matt 		 */
    691        1.1      matt 		gtmpscshutdown(sc);
    692        1.1      matt 	}
    693        1.1      matt 
    694        1.1      matt 	splx(s);
    695        1.1      matt 	return (0);
    696        1.1      matt }
    697        1.1      matt 
    698        1.1      matt int
    699        1.1      matt gtmpscread(dev_t dev, struct uio *uio, int flag)
    700        1.1      matt {
    701        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_cd.cd_devs[GTMPSCUNIT(dev)];
    702        1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    703       1.10     perry 
    704        1.1      matt 	return (*tp->t_linesw->l_read)(tp, uio, flag);
    705        1.1      matt }
    706        1.1      matt 
    707        1.1      matt int
    708        1.1      matt gtmpscwrite(dev_t dev, struct uio *uio, int flag)
    709        1.1      matt {
    710        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_cd.cd_devs[GTMPSCUNIT(dev)];
    711        1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    712       1.10     perry 
    713        1.1      matt 	return (*tp->t_linesw->l_write)(tp, uio, flag);
    714        1.1      matt }
    715        1.1      matt 
    716        1.1      matt int
    717       1.13  christos gtmpscpoll(dev_t dev, int events, struct lwp *l)
    718        1.1      matt {
    719        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_cd.cd_devs[GTMPSCUNIT(dev)];
    720        1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    721        1.1      matt 
    722       1.13  christos 	return ((*tp->t_linesw->l_poll)(tp, events, l));
    723        1.1      matt }
    724        1.1      matt 
    725        1.1      matt int
    726       1.23  christos gtmpscioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
    727        1.1      matt {
    728        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_cd.cd_devs[GTMPSCUNIT(dev)];
    729        1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    730        1.1      matt 	int error;
    731       1.10     perry 
    732       1.13  christos 	if ((error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l)) >= 0)
    733        1.1      matt 		return error;
    734       1.13  christos 	if ((error = ttioctl(tp, cmd, data, flag, l)) >= 0)
    735        1.1      matt 		return error;
    736        1.1      matt 	return ENOTTY;
    737        1.1      matt }
    738        1.1      matt 
    739        1.1      matt struct tty *
    740        1.1      matt gtmpsctty(dev_t dev)
    741        1.1      matt {
    742        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_cd.cd_devs[GTMPSCUNIT(dev)];
    743        1.1      matt 
    744        1.1      matt 	return sc->gtmpsc_tty;
    745        1.1      matt }
    746        1.1      matt 
    747        1.1      matt void
    748        1.1      matt gtmpscstop(struct tty *tp, int flag)
    749        1.1      matt {
    750        1.1      matt }
    751        1.1      matt 
    752        1.1      matt STATIC void
    753        1.1      matt gtmpscstart(struct tty *tp)
    754        1.1      matt {
    755        1.4      matt 	struct gtmpsc_softc *sc;
    756        1.1      matt 	unsigned char *tba;
    757        1.1      matt 	unsigned int unit;
    758        1.1      matt 	int s, s2, tbc;
    759        1.1      matt 
    760        1.1      matt 	unit = GTMPSCUNIT(tp->t_dev);
    761        1.4      matt 	sc = gtmpsc_cd.cd_devs[unit];
    762        1.1      matt 	if (sc == NULL)
    763        1.1      matt 		return;
    764        1.1      matt 
    765        1.1      matt 	s = spltty();
    766        1.1      matt 	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
    767        1.1      matt 		goto out;
    768        1.1      matt 	if (sc->sc_tx_stopped)
    769        1.1      matt 		goto out;
    770       1.27        ad 	if (!ttypull(tp))
    771       1.27        ad 		goto out;
    772        1.1      matt 
    773        1.1      matt 	/* Grab the first contiguous region of buffer space. */
    774        1.1      matt 	tba = tp->t_outq.c_cf;
    775        1.1      matt 	tbc = ndqb(&tp->t_outq, 0);
    776        1.1      matt 
    777        1.1      matt 	s2 = splserial();
    778        1.1      matt 
    779        1.1      matt 	sc->sc_tba = tba;
    780        1.1      matt 	sc->sc_tbc = tbc;
    781        1.1      matt 	sc->cnt_tx_from_ldisc += tbc;
    782        1.3      matt 	SDMA_IMASK_ENABLE(sc, SDMA_INTR_TXBUF(unit));
    783        1.1      matt 	tp->t_state |= TS_BUSY;
    784        1.1      matt 	sc->sc_tx_busy = 1;
    785        1.1      matt 	gtmpsc_common_putn(sc);
    786        1.1      matt 
    787        1.1      matt 	splx(s2);
    788        1.1      matt out:
    789        1.1      matt 	splx(s);
    790        1.1      matt }
    791        1.1      matt 
    792        1.1      matt STATIC int
    793        1.1      matt gtmpscparam(struct tty *tp, struct termios *t)
    794        1.1      matt {
    795        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_cd.cd_devs[GTMPSCUNIT(tp->t_dev)];
    796        1.1      matt 	int ospeed = compute_cdv(t->c_ospeed);
    797        1.1      matt 	int s;
    798        1.1      matt 
    799        1.1      matt 	/* Check requested parameters. */
    800        1.1      matt 	if (ospeed < 0)
    801        1.1      matt 		return (EINVAL);
    802        1.1      matt 	if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
    803        1.1      matt 		return (EINVAL);
    804        1.1      matt 
    805        1.1      matt 	/*
    806        1.1      matt 	 * If there were no changes, don't do anything.  This avoids dropping
    807        1.1      matt 	 * input and improves performance when all we did was frob things like
    808        1.1      matt 	 * VMIN and VTIME.
    809        1.1      matt 	 */
    810        1.1      matt 	if (tp->t_ospeed == t->c_ospeed &&
    811        1.1      matt 	    tp->t_cflag == t->c_cflag)
    812        1.1      matt 		return (0);
    813        1.1      matt 
    814        1.1      matt 	s = splserial();
    815        1.1      matt 
    816        1.4      matt 	sc->gtmpsc_brg_bcr = BRG_BCR_EN | GT_MPSC_CLOCK_SOURCE | ospeed;
    817        1.1      matt 	sc->gtmpsc_chr3 = GTMPSC_MAXIDLE(t->c_ospeed);
    818        1.1      matt 
    819        1.1      matt 	/* And copy to tty. */
    820        1.1      matt 	tp->t_ispeed = 0;
    821        1.1      matt 	tp->t_ospeed = t->c_ospeed;
    822        1.1      matt 	tp->t_cflag = t->c_cflag;
    823        1.1      matt 
    824        1.1      matt 	if (!sc->sc_heldchange) {
    825        1.1      matt 		if (sc->sc_tx_busy) {
    826        1.1      matt 			sc->sc_heldtbc = sc->sc_tbc;
    827        1.1      matt 			sc->sc_tbc = 0;
    828        1.1      matt 			sc->sc_heldchange = 1;
    829        1.1      matt 		} else
    830        1.1      matt 			gtmpsc_loadchannelregs(sc);
    831        1.1      matt 	}
    832        1.1      matt 
    833        1.1      matt 	splx(s);
    834        1.1      matt 
    835        1.1      matt 	/* Fake carrier on */
    836        1.1      matt 	(void) (*tp->t_linesw->l_modem)(tp, 1);
    837        1.1      matt 
    838        1.1      matt 	return 0;
    839        1.1      matt }
    840        1.1      matt 
    841        1.1      matt STATIC int
    842        1.1      matt gtmpsc_probe(void)
    843        1.1      matt {
    844        1.1      matt 	return 1;		/* XXX */
    845        1.1      matt }
    846        1.1      matt 
    847        1.1      matt STATIC unsigned int
    848        1.1      matt gtmpsc_get_causes(void)
    849        1.1      matt {
    850        1.1      matt 	int                     i;
    851        1.1      matt 	struct gtmpsc_softc       *sc;
    852        1.1      matt 	unsigned int            cause = 0;
    853        1.1      matt 	static unsigned int     bits[4] = {
    854        1.1      matt 				SDMA_INTR_RXBUF(0),
    855        1.1      matt 				SDMA_INTR_TXBUF(0),
    856        1.1      matt 				SDMA_INTR_RXBUF(1),
    857        1.1      matt 				SDMA_INTR_TXBUF(1),
    858        1.1      matt 	};
    859        1.1      matt 	sdma_desc_t             *desc_addr[4];
    860        1.1      matt 	static unsigned int     fake_once = SDMA_INTR_RXBUF(0)
    861        1.1      matt 						| SDMA_INTR_RXBUF(1);
    862        1.1      matt 
    863        1.1      matt 	desc_addr[0] = 0;
    864        1.1      matt 	desc_addr[1] = 0;
    865        1.1      matt 	desc_addr[2] = 0;
    866        1.1      matt 	desc_addr[3] = 0;
    867        1.1      matt 	sc = gtmpsc_cd.cd_devs[0];
    868        1.1      matt 	if (sc != 0) {
    869        1.1      matt 	    if (sdma_imask & SDMA_INTR_RXBUF(0)) {
    870        1.1      matt 		desc_addr[0] =
    871        1.1      matt 		    &sc->gtmpsc_poll_sdmapage->rx[sc->gtmpsc_poll_rxix].rxdesc;
    872        1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[0]);
    873       1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[0]));
    874        1.1      matt 	    }
    875        1.1      matt 	    if (sdma_imask & SDMA_INTR_TXBUF(0)) {
    876        1.1      matt 		desc_addr[1] =
    877        1.1      matt 		    &sc->gtmpsc_poll_sdmapage->tx[sc->gtmpsc_poll_txix].txdesc;
    878        1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[1]);
    879       1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[1]));
    880        1.1      matt 	    }
    881        1.1      matt 	}
    882        1.1      matt 	sc = gtmpsc_cd.cd_devs[1];
    883        1.1      matt 	if (sc != 0) {
    884        1.1      matt 	    if (sdma_imask & SDMA_INTR_RXBUF(1)) {
    885        1.1      matt 		desc_addr[2] =
    886        1.1      matt 		    &sc->gtmpsc_poll_sdmapage->rx[sc->gtmpsc_poll_rxix].rxdesc;
    887        1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[2]);
    888       1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[2]));
    889        1.1      matt 	    }
    890        1.1      matt 	    if (sdma_imask & SDMA_INTR_TXBUF(1)) {
    891        1.1      matt 		desc_addr[3] =
    892        1.1      matt 		    &sc->gtmpsc_poll_sdmapage->tx[sc->gtmpsc_poll_txix].txdesc;
    893        1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[3]);
    894       1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[3]));
    895        1.1      matt 	    }
    896        1.1      matt 	}
    897        1.1      matt 
    898        1.1      matt 	for (i = 0; i < 4; ++i)
    899        1.1      matt 		if ((sdma_imask & bits[i]) && desc_addr[i] != 0 &&
    900        1.1      matt 			    (desc_addr[i]->sdma_csr & SDMA_CSR_TX_OWN) == 0)
    901        1.1      matt 			cause |= bits[i];
    902        1.1      matt 	if (fake_once & sdma_imask) {
    903        1.1      matt 		cause |= fake_once & sdma_imask;
    904        1.1      matt 	/*	fake_once &= ~(cause & fake_once); */
    905        1.1      matt 	}
    906        1.1      matt 	return cause;
    907        1.1      matt }
    908        1.1      matt 
    909        1.1      matt STATIC int
    910        1.1      matt gtmpsc_intr(void *arg)
    911        1.1      matt {
    912        1.1      matt 	struct gtmpsc_softc       *sc;
    913        1.1      matt 	unsigned int            unit;
    914        1.1      matt 	int                     spurious = 1;
    915        1.1      matt 	unsigned int            r;
    916        1.1      matt 	unsigned int            cause=0;
    917        1.1      matt 
    918        1.1      matt 	if (gt_reva_gtmpsc_bug)
    919        1.1      matt 		cause = gtmpsc_get_causes();
    920        1.1      matt 
    921        1.1      matt #ifdef KGDB
    922        1.1      matt 	if (kgdb_break_immediate) {
    923        1.1      matt 		unit = comkgdbport;
    924        1.1      matt 		sc = gtmpsc_cd.cd_devs[unit];
    925        1.1      matt 		if (sc == 0 || (sc->gtmpsc_flags & GTMPSCF_KGDB) == 0)
    926        1.1      matt 			goto skip_kgdb;
    927        1.1      matt 		if (gt_reva_gtmpsc_bug)
    928        1.1      matt 			r = cause & sdma_imask;
    929        1.1      matt 		else {
    930        1.3      matt 			r = GT_READ(sc, SDMA_ICAUSE);
    931        1.3      matt 			r &= GT_READ(sc, SDMA_IMASK);
    932        1.1      matt 		}
    933        1.1      matt 		r &= SDMA_INTR_RXBUF(unit);
    934        1.1      matt 		if (r == 0)
    935        1.1      matt 			goto skip_kgdb;
    936        1.3      matt 		GT_WRITE(sc, SDMA_ICAUSE, ~r);
    937        1.1      matt 		spurious = 0;
    938        1.1      matt 		gtmpsc_kgdb_poll(sc);
    939        1.1      matt 	}
    940        1.1      matt skip_kgdb:
    941        1.1      matt #endif
    942        1.1      matt 	for (unit = 0; unit < GTMPSC_NCHAN; ++unit) {
    943        1.1      matt 		sc = gtmpsc_cd.cd_devs[unit];
    944        1.1      matt 		if (sc == 0)
    945        1.1      matt 			continue;
    946        1.1      matt 		if (gt_reva_gtmpsc_bug)
    947        1.1      matt 			r = cause & sdma_imask;
    948        1.1      matt 		else {
    949        1.3      matt 			r = GT_READ(sc, SDMA_ICAUSE);
    950        1.3      matt 			r &= GT_READ(sc, SDMA_IMASK);
    951        1.1      matt 		}
    952        1.1      matt 		r &= SDMA_U_INTR_MASK(unit);
    953        1.1      matt 		if (r == 0)
    954        1.1      matt 			continue;
    955        1.3      matt 		GT_WRITE(sc, SDMA_ICAUSE, ~r);
    956        1.1      matt 		spurious = 0;
    957        1.1      matt 		if (r & SDMA_INTR_RXBUF(unit)) {
    958        1.1      matt #ifdef KGDB
    959        1.1      matt 			if (sc->gtmpsc_flags & GTMPSCF_KGDB)
    960        1.1      matt 				gtmpsc_kgdb_poll(sc);
    961        1.1      matt 			else
    962        1.1      matt #endif
    963        1.1      matt 				gtmpsc_poll(sc);
    964        1.1      matt 		}
    965        1.1      matt 		if (r & SDMA_INTR_TXBUF(unit)) {
    966        1.1      matt 			/*
    967        1.1      matt 			 * If we've delayed a parameter change, do it now,
    968        1.1      matt 			 * and restart output.
    969        1.1      matt 			 */
    970        1.1      matt 			if (sc->sc_heldchange) {
    971        1.1      matt 				gtmpsc_loadchannelregs(sc);
    972        1.1      matt 				sc->sc_heldchange = 0;
    973        1.1      matt 				sc->sc_tbc = sc->sc_heldtbc;
    974        1.1      matt 				sc->sc_heldtbc = 0;
    975        1.1      matt 			}
    976        1.1      matt 
    977        1.1      matt 			/* Output the next chunk of the contiguous buffer,
    978        1.1      matt 								if any. */
    979        1.1      matt 			if (sc->sc_tbc > 0)
    980        1.1      matt 				gtmpsc_common_putn(sc);
    981        1.1      matt 			if (sc->sc_tbc == 0 && sc->sc_tx_busy) {
    982        1.1      matt 				sc->sc_tx_busy = 0;
    983        1.1      matt 				sc->sc_tx_done = 1;
    984       1.24        ad 				softint_schedule(sc->sc_si);
    985        1.3      matt 				SDMA_IMASK_DISABLE(sc, SDMA_INTR_TXBUF(unit));
    986        1.1      matt 			}
    987        1.1      matt 		}
    988        1.1      matt 	}
    989        1.1      matt 	return 1;
    990        1.1      matt 	/* return !spurious; */
    991        1.1      matt }
    992        1.1      matt 
    993        1.3      matt STATIC void
    994        1.3      matt gtmpsc_softintr(void *arg)
    995        1.1      matt {
    996        1.3      matt 	struct gtmpsc_softc	*sc = arg;
    997        1.1      matt 	struct tty              *tp;
    998        1.2      matt 	int                     (*rint)(int, struct tty *);
    999        1.1      matt 	int                     jobs;
   1000        1.1      matt 	int                     s;
   1001        1.1      matt 
   1002        1.3      matt 	tp = sc->gtmpsc_tty;
   1003        1.3      matt 	rint = tp->t_linesw->l_rint;
   1004        1.3      matt 	do {
   1005        1.3      matt 		jobs = 0;
   1006        1.3      matt 		if (sc->gtmpsc_rxfifo_navail < GTMPSC_RXFIFOSZ) {
   1007        1.1      matt 			s = spltty();
   1008        1.1      matt 			rint(sc->gtmpsc_rxfifo[sc->gtmpsc_rxfifo_getix++],
   1009        1.1      matt 								tp);
   1010        1.1      matt 			if (sc->gtmpsc_rxfifo_getix >= GTMPSC_RXFIFOSZ)
   1011        1.1      matt 				sc->gtmpsc_rxfifo_getix = 0;
   1012        1.1      matt 			++sc->cnt_rx_from_fifo;
   1013        1.1      matt 			/* atomic_add() returns the previous value */
   1014        1.1      matt 			jobs += atomic_add(&sc->gtmpsc_rxfifo_navail, 1) + 1
   1015        1.1      matt 								< GTMPSC_RXFIFOSZ;
   1016        1.1      matt 			splx(s);
   1017        1.3      matt 		}
   1018        1.3      matt 		if (sc->sc_tx_done) {
   1019        1.1      matt 			++jobs;
   1020        1.1      matt 			sc->sc_tx_done = 0;
   1021        1.1      matt 			s = spltty();
   1022        1.1      matt 			tp->t_state &= ~TS_BUSY;
   1023        1.1      matt 			if ((tp->t_state & TS_FLUSH) != 0)
   1024        1.1      matt 			    tp->t_state &= ~TS_FLUSH;
   1025        1.1      matt 			else
   1026        1.1      matt 			    ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
   1027        1.1      matt 			(*tp->t_linesw->l_start)(tp);
   1028        1.1      matt 			splx(s);
   1029        1.3      matt 		}
   1030        1.3      matt 	} while (jobs);
   1031        1.1      matt }
   1032        1.1      matt 
   1033        1.1      matt /*
   1034        1.1      matt  * Console support functions
   1035        1.1      matt  */
   1036        1.1      matt void
   1037        1.1      matt gtmpsccnprobe(struct consdev *cd)
   1038        1.1      matt {
   1039        1.1      matt 	int maj;
   1040        1.1      matt /* {extern void return_to_dink(int); return_to_dink(gtbase);} */
   1041        1.1      matt 
   1042        1.1      matt 	if (!gtmpsc_probe())
   1043        1.1      matt 		return;
   1044        1.1      matt 
   1045        1.1      matt 	maj = cdevsw_lookup_major(&gtmpsc_cdevsw);
   1046        1.1      matt 	cd->cn_dev = makedev(maj, 0);
   1047        1.1      matt 	cd->cn_pri = CN_INTERNAL;
   1048        1.1      matt }
   1049        1.1      matt 
   1050        1.1      matt /*
   1051        1.1      matt  * gtmpsc_hackinit - hacks required to supprt GTMPSC console
   1052        1.1      matt  */
   1053        1.1      matt STATIC void
   1054        1.3      matt gtmpsc_hackinit(struct gtmpsc_softc *sc, bus_space_tag_t memt,
   1055        1.3      matt 	bus_space_handle_t memh, int unit)
   1056        1.1      matt {
   1057        1.1      matt 	gtmpsc_poll_sdma_t *vmps;
   1058        1.1      matt 	gtmpsc_poll_sdma_t *pmps;
   1059        1.1      matt 
   1060        1.1      matt 	DPRINTF(("hackinit\n"));
   1061        1.1      matt 
   1062        1.1      matt 	bzero(sc, sizeof(struct gtmpsc_softc));
   1063        1.3      matt 	sc->gtmpsc_memt = memt;
   1064        1.3      matt 	sc->gtmpsc_memh = memh;
   1065        1.3      matt 	sc->gtmpsc_unit = unit;
   1066        1.1      matt 	gtmpsc_scp[sc->gtmpsc_unit] = sc;
   1067        1.1      matt 
   1068        1.1      matt 	vmps = (gtmpsc_poll_sdma_t *)gtmpsc_fake_dmapage;	/* KVA */
   1069        1.1      matt 	pmps = (gtmpsc_poll_sdma_t *)gtmpsc_fake_dmapage;	/* PA */
   1070        1.1      matt 
   1071        1.1      matt 	gtmpsc_txdesc_init(vmps, pmps);
   1072        1.1      matt 	gtmpsc_rxdesc_init(vmps, pmps);
   1073        1.1      matt 
   1074        1.1      matt 	sc->gtmpsc_poll_sdmapage = vmps;
   1075        1.1      matt }
   1076        1.1      matt 
   1077        1.1      matt /*
   1078        1.1      matt  * gtmpsc_txflush - wait for output to drain
   1079        1.1      matt  */
   1080        1.1      matt STATIC void
   1081        1.1      matt gtmpsc_txflush(gtmpsc_softc_t *sc)
   1082        1.1      matt {
   1083        1.1      matt 	unsigned int csr;
   1084        1.1      matt 	unsigned int *csrp;
   1085        1.1      matt 	gtmpsc_polltx_t *vtxp;
   1086        1.1      matt 	int limit = 4000000;	/* 4 seconds */
   1087        1.1      matt 	int ix;
   1088        1.1      matt 
   1089        1.1      matt 	ix = sc->gtmpsc_poll_txix - 1;
   1090        1.1      matt 	if (ix < 0)
   1091        1.1      matt 		ix = GTMPSC_NTXDESC - 1;
   1092        1.1      matt 
   1093        1.1      matt 	vtxp = &sc->gtmpsc_poll_sdmapage->tx[ix];
   1094        1.1      matt 	csrp = &vtxp->txdesc.sdma_csr;
   1095        1.1      matt 	while (limit > 0) {
   1096        1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1097        1.1      matt 		csr = desc_read(csrp);
   1098        1.1      matt 		if ((csr & SDMA_CSR_TX_OWN) == 0)
   1099        1.1      matt 			break;
   1100        1.1      matt 		DELAY(GTMPSC_POLL_DELAY);
   1101        1.1      matt 		limit -= GTMPSC_POLL_DELAY;
   1102       1.10     perry 	}
   1103        1.1      matt }
   1104        1.1      matt 
   1105        1.1      matt STATIC void
   1106        1.1      matt gtmpsc_iflush(gtmpsc_softc_t *sc)
   1107        1.1      matt {
   1108        1.1      matt 	int     timo;
   1109        1.1      matt 	char    c;
   1110        1.1      matt 	int     stat;
   1111        1.1      matt 
   1112        1.1      matt 	for (timo = 50000; timo; timo--)
   1113        1.1      matt 		if (gtmpsc_common_pollc(sc->gtmpsc_unit, &c, &stat) == 0)
   1114        1.1      matt 			return;
   1115        1.1      matt #ifdef DIAGNOSTIC
   1116  1.27.14.1       mjf 	printf("%s: gtmpsc_iflush timeout %02x\n", device_xname(&sc->gtmpsc_dev), c);
   1117        1.1      matt #endif
   1118        1.1      matt }
   1119        1.1      matt 
   1120        1.1      matt STATIC void
   1121        1.1      matt gtmpscinit_stop(struct gtmpsc_softc *sc, int once)
   1122        1.1      matt {
   1123        1.1      matt 	unsigned int r;
   1124        1.1      matt 	unsigned int unit = sc->gtmpsc_unit;
   1125        1.1      matt 
   1126        1.1      matt 	/*
   1127        1.1      matt 	 * XXX HACK FIXME
   1128        1.1      matt 	 * PMON output has not been flushed.  give him a chance
   1129        1.1      matt 	 */
   1130        1.1      matt #if 1
   1131        1.1      matt 	if (! once)
   1132        1.1      matt 		DELAY(100000);	/* XXX */
   1133        1.1      matt #endif
   1134        1.1      matt 
   1135        1.5      matt 	DPRINTF(("gtmpscinit_stop: unit 0x%x\n", unit));
   1136        1.1      matt 	if (unit >= GTMPSC_NCHAN) {
   1137        1.1      matt 		PRINTF(("mpscinit: undefined unit %d\n", sc->gtmpsc_unit));
   1138        1.1      matt 		return;
   1139        1.1      matt 	}
   1140        1.1      matt 
   1141        1.1      matt 	sc->gtmpsc_chr2 = 0;      /* Default value of CHR2 */
   1142        1.1      matt 
   1143        1.1      matt 	/*
   1144        1.1      matt 	 * stop GTMPSC unit
   1145        1.1      matt 	 */
   1146        1.1      matt 	r = sc->gtmpsc_chr2 | GTMPSC_CHR2_RXABORT|GTMPSC_CHR2_TXABORT;
   1147        1.3      matt 	GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1148        1.1      matt 
   1149        1.1      matt 	DELAY(GTMPSC_RESET_DELAY);
   1150        1.1      matt 
   1151        1.1      matt 	/*
   1152        1.1      matt 	 * abort SDMA TX, RX for GTMPSC unit
   1153        1.1      matt 	 */
   1154        1.4      matt 	GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_AR|SDMA_SDCM_AT);
   1155        1.1      matt 
   1156        1.1      matt 	if (once == 0) {
   1157        1.1      matt 		/*
   1158        1.1      matt 		 * Determine if this is the buggy GT-64260A case.
   1159        1.1      matt 		 * If this is, then most of GTMPSC and SDMA registers
   1160        1.1      matt 		 * are unreadable.
   1161        1.1      matt 		 * (They always yield -1).
   1162        1.1      matt 		 */
   1163        1.3      matt 		GT_WRITE(sc, SDMA_IMASK, 0);
   1164        1.3      matt 		r = GT_READ(sc, SDMA_IMASK);
   1165        1.1      matt 		gt_reva_gtmpsc_bug = r == ~0;
   1166        1.1      matt 		sdma_imask = 0;
   1167        1.1      matt 	}
   1168        1.7       scw 
   1169        1.7       scw 	/*
   1170        1.7       scw 	 * If Rx is disabled, we don't need to wait around for
   1171        1.7       scw 	 * abort completion.
   1172        1.7       scw 	 */
   1173        1.7       scw 	if ((GT_READ(sc, GTMPSC_U_MMCR_LO(unit)) & GTMPSC_MMCR_LO_ER) == 0)
   1174        1.7       scw 		return;
   1175        1.7       scw 
   1176        1.1      matt 	/*
   1177        1.1      matt 	 * poll for GTMPSC RX abort completion
   1178        1.1      matt 	 */
   1179        1.1      matt 	if (gt_reva_gtmpsc_bug) {
   1180        1.1      matt 		/* Sync up with the device first */
   1181        1.3      matt 		r = GT_READ(sc, GTMPSC_U_CHRN(unit, 2));
   1182        1.1      matt 		DELAY(GTMPSC_RESET_DELAY);
   1183        1.1      matt 	} else
   1184        1.1      matt 		for (;;) {
   1185        1.5      matt 			r = GT_READ(sc, GTMPSC_U_CHRN(unit, 2));
   1186        1.1      matt 			if (! (r & GTMPSC_CHR2_RXABORT))
   1187        1.1      matt 				break;
   1188        1.1      matt 		}
   1189        1.1      matt 
   1190        1.1      matt 	/*
   1191        1.1      matt 	 * poll for SDMA RX abort completion
   1192        1.1      matt 	 */
   1193        1.1      matt 	for (;;) {
   1194        1.3      matt 		r = GT_READ(sc, SDMA_U_SDCM(unit));
   1195        1.5      matt 		if (! (r & (SDMA_SDCM_AR|SDMA_SDCM_AT)))
   1196        1.1      matt 			break;
   1197        1.5      matt 		DELAY(50);
   1198        1.1      matt 	}
   1199        1.1      matt 
   1200        1.1      matt }
   1201        1.1      matt 
   1202        1.1      matt STATIC void
   1203        1.1      matt gtmpscinit_start(struct gtmpsc_softc *sc, int once)
   1204        1.1      matt {
   1205        1.1      matt 	unsigned int r;
   1206        1.1      matt 	unsigned int unit = sc->gtmpsc_unit;
   1207        1.1      matt 
   1208        1.1      matt 	/*
   1209        1.1      matt 	 * initialize softc's "current" transfer indicies & counts
   1210        1.1      matt 	 */
   1211        1.1      matt 	sc->gtmpsc_cx = 0;
   1212        1.1      matt 	sc->gtmpsc_nc = 0;
   1213        1.1      matt 	sc->gtmpsc_poll_txix = 0;
   1214        1.1      matt 	sc->gtmpsc_poll_rxix = 0;
   1215        1.1      matt 
   1216        1.1      matt 	/*
   1217        1.1      matt 	 * initialize softc's RX softintr FIFO
   1218        1.1      matt 	 */
   1219        1.1      matt 	sc->gtmpsc_rxfifo_putix = 0;
   1220        1.1      matt 	sc->gtmpsc_rxfifo_getix = 0;
   1221        1.1      matt 	sc->gtmpsc_rxfifo_navail = GTMPSC_RXFIFOSZ;
   1222        1.1      matt 	memset(&sc->gtmpsc_rxfifo[0], 0, GTMPSC_RXFIFOSZ);
   1223        1.1      matt 
   1224        1.1      matt 	/*
   1225        1.1      matt 	 * set SDMA unit port TX descriptor pointers
   1226        1.1      matt 	 * "next" pointer of last descriptor is start of ring
   1227        1.1      matt 	 */
   1228        1.1      matt 	r = desc_read(
   1229        1.5      matt 	    &sc->gtmpsc_poll_sdmapage->tx[GTMPSC_NTXDESC-1].txdesc.sdma_next);
   1230        1.3      matt 	GT_WRITE(sc, SDMA_U_SCTDP(unit), r);   /* current */
   1231        1.5      matt 	(void)GT_READ(sc, SDMA_U_SCTDP(unit));
   1232        1.3      matt 	GT_WRITE(sc, SDMA_U_SFTDP(unit), r);   /* first   */
   1233        1.5      matt 	(void)GT_READ(sc, SDMA_U_SFTDP(unit));
   1234        1.1      matt 	/*
   1235        1.1      matt 	 * set SDMA unit port RX descriptor pointer
   1236        1.1      matt 	 * "next" pointer of last descriptor is start of ring
   1237        1.1      matt 	 */
   1238        1.1      matt 	r = desc_read(
   1239        1.5      matt 	    &sc->gtmpsc_poll_sdmapage->rx[GTMPSC_NRXDESC-1].rxdesc.sdma_next);
   1240        1.3      matt 	GT_WRITE(sc, SDMA_U_SCRDP(unit), r);   /* current */
   1241        1.1      matt 
   1242        1.1      matt 	/*
   1243        1.1      matt 	 * initialize SDMA unit Configuration Register
   1244        1.1      matt 	 */
   1245        1.1      matt 	r = SDMA_SDC_BSZ_8x64|SDMA_SDC_SFM|SDMA_SDC_RFT;
   1246        1.3      matt 	GT_WRITE(sc, SDMA_U_SDC(unit), r);
   1247        1.1      matt 
   1248        1.1      matt 	/*
   1249        1.1      matt 	 * enable SDMA receive
   1250        1.1      matt 	 */
   1251        1.3      matt 	GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_ERD);
   1252        1.1      matt 
   1253        1.5      matt 	if (once == 0) {
   1254        1.1      matt 		/*
   1255        1.1      matt 		 * GTMPSC Routing:
   1256        1.1      matt 		 *	MR0 --> Serial Port 0
   1257        1.1      matt 		 *	MR1 --> Serial Port 1
   1258        1.1      matt 		 */
   1259        1.3      matt 		GT_WRITE(sc, GTMPSC_MRR, GTMPSC_MRR_RES);
   1260       1.10     perry 
   1261        1.1      matt 		/*
   1262        1.1      matt 		 * RX and TX Clock Routing:
   1263        1.1      matt 		 *      CRR0 --> BRG0
   1264        1.1      matt 		 *      CRR1 --> BRG1
   1265        1.1      matt 		 */
   1266        1.1      matt 		r = GTMPSC_CRR_BRG0 | (GTMPSC_CRR_BRG1 << GTMPSC_CRR1_SHIFT);
   1267        1.3      matt 		GT_WRITE(sc, GTMPSC_RCRR, r);
   1268        1.3      matt 		GT_WRITE(sc, GTMPSC_TCRR, r);
   1269        1.1      matt 	}
   1270        1.4      matt 	sc->gtmpsc_brg_bcr = BRG_BCR_EN | GT_MPSC_CLOCK_SOURCE |
   1271        1.4      matt 	    compute_cdv(GT_MPSC_DEFAULT_BAUD_RATE);
   1272        1.1      matt 	sc->gtmpsc_chr3 = GTMPSC_MAXIDLE(GT_MPSC_DEFAULT_BAUD_RATE);
   1273        1.1      matt 	gtmpsc_loadchannelregs(sc);
   1274        1.1      matt 
   1275        1.1      matt 	/*
   1276        1.1      matt 	 * set MPSC Protocol configuration register for GTMPSC unit
   1277        1.1      matt 	 */
   1278        1.3      matt 	GT_WRITE(sc, GTMPSC_U_MPCR(unit), GTMPSC_MPCR_CL_8);
   1279        1.1      matt 
   1280        1.1      matt 	/*
   1281        1.1      matt 	 * set MPSC LO and HI port config registers for GTMPSC unit
   1282        1.1      matt  	 */
   1283        1.1      matt 	r = GTMPSC_MMCR_LO_MODE_UART
   1284        1.1      matt 	   |GTMPSC_MMCR_LO_ET
   1285        1.1      matt 	   |GTMPSC_MMCR_LO_ER
   1286        1.1      matt 	   |GTMPSC_MMCR_LO_NLM;
   1287        1.3      matt 	GT_WRITE(sc, GTMPSC_U_MMCR_LO(unit), r);
   1288        1.1      matt 
   1289        1.1      matt 	r =
   1290        1.1      matt 	    GTMPSC_MMCR_HI_TCDV_DEFAULT
   1291        1.1      matt 	   |GTMPSC_MMCR_HI_RDW
   1292        1.1      matt 	   |GTMPSC_MMCR_HI_RCDV_DEFAULT;
   1293        1.3      matt 	GT_WRITE(sc, GTMPSC_U_MMCR_HI(unit), r);
   1294        1.1      matt 
   1295        1.1      matt 	/*
   1296        1.1      matt 	 * tell MPSC receive the Enter Hunt
   1297        1.1      matt 	 */
   1298        1.1      matt 	r = sc->gtmpsc_chr2 | GTMPSC_CHR2_EH;
   1299        1.3      matt 	GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1300        1.1      matt 
   1301        1.1      matt 	/*
   1302        1.1      matt 	 * clear any pending SDMA interrupts for this unit
   1303        1.1      matt 	 */
   1304        1.3      matt 	r = GT_READ(sc, SDMA_ICAUSE);
   1305        1.1      matt 	r &= ~SDMA_U_INTR_MASK(unit);
   1306        1.3      matt 	GT_WRITE(sc, SDMA_ICAUSE, r);	/* ??? */
   1307        1.1      matt 
   1308        1.1      matt 	DPRINTF(("gtmpscinit: OK\n"));
   1309        1.1      matt }
   1310        1.1      matt 
   1311        1.1      matt /*
   1312        1.1      matt  * gtmpscinit - prepare MPSC for operation
   1313        1.1      matt  *
   1314        1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1315        1.1      matt  */
   1316        1.1      matt STATIC void
   1317        1.1      matt gtmpscinit(struct gtmpsc_softc *sc)
   1318        1.1      matt {
   1319        1.1      matt 	static int once = 0;
   1320        1.1      matt 
   1321        1.1      matt 	gtmpscinit_stop(sc, once);
   1322        1.1      matt 	gtmpscinit_start(sc, once);
   1323        1.5      matt 	once = 1;
   1324        1.1      matt }
   1325        1.1      matt 
   1326        1.1      matt /*
   1327        1.1      matt  * gtmpsccninit - initialize the driver and the mpsc device
   1328        1.1      matt  */
   1329        1.1      matt void
   1330        1.1      matt gtmpsccninit(struct consdev *cd)
   1331        1.1      matt {
   1332        1.1      matt }
   1333        1.1      matt 
   1334        1.1      matt int
   1335        1.1      matt gtmpsccngetc(dev_t dev)
   1336        1.1      matt {
   1337        1.4      matt 	unsigned int unit = 0;
   1338        1.1      matt 	int c;
   1339       1.10     perry 
   1340        1.1      matt 	unit = GTMPSCUNIT(dev);
   1341        1.4      matt 	if (major(dev) != 0) {
   1342        1.4      matt 		struct gtmpsc_softc *sc = device_lookup(&gtmpsc_cd, unit);
   1343        1.4      matt 		if (sc == NULL)
   1344        1.4      matt 			return 0;
   1345        1.4      matt 		unit = sc->gtmpsc_unit;
   1346        1.4      matt 	}
   1347        1.1      matt 	if (unit >= GTMPSC_NCHAN)
   1348        1.1      matt 		return 0;
   1349        1.1      matt 	c = gtmpsc_common_getc(unit);
   1350        1.1      matt 
   1351        1.1      matt 	return c;
   1352        1.1      matt }
   1353        1.1      matt 
   1354        1.1      matt void
   1355        1.1      matt gtmpsccnputc(dev_t dev, int c)
   1356        1.1      matt {
   1357        1.4      matt 	unsigned int unit = 0;
   1358        1.1      matt 	char ch = c;
   1359        1.1      matt 	static int ix = 0;
   1360       1.10     perry 
   1361        1.1      matt 	if (gtmpsccninit_done == 0) {
   1362        1.1      matt 		if ((minor(dev) == 0) && (ix < sizeof(gtmpsc_earlybuf)))
   1363        1.1      matt 			gtmpsc_earlybuf[ix++] = (unsigned char)c;
   1364        1.1      matt 		return;
   1365        1.1      matt 	}
   1366        1.1      matt 
   1367        1.1      matt 	unit = GTMPSCUNIT(dev);
   1368        1.4      matt 	if (major(dev) != 0) {
   1369        1.4      matt 		struct gtmpsc_softc *sc = device_lookup(&gtmpsc_cd, unit);
   1370        1.4      matt 		if (sc == NULL)
   1371        1.4      matt 			return;
   1372        1.4      matt 		unit = sc->gtmpsc_unit;
   1373        1.4      matt 	}
   1374        1.1      matt 
   1375        1.1      matt 	if (unit >= GTMPSC_NCHAN)
   1376        1.1      matt 		return;
   1377        1.4      matt 
   1378        1.1      matt 	gtmpsc_common_putc(unit, ch);
   1379        1.1      matt }
   1380        1.1      matt 
   1381        1.1      matt void
   1382        1.1      matt gtmpsccnpollc(dev_t dev, int on)
   1383        1.1      matt {
   1384        1.1      matt }
   1385        1.1      matt 
   1386        1.3      matt int
   1387        1.3      matt gtmpsccnattach(bus_space_tag_t memt, bus_space_handle_t memh, int unit,
   1388        1.3      matt 	int speed, tcflag_t tcflag)
   1389        1.3      matt {
   1390        1.3      matt 	struct gtmpsc_softc *sc = &gtmpsc_fake_softc;
   1391        1.3      matt 	unsigned char *cp;
   1392        1.3      matt 	unsigned char c;
   1393        1.3      matt 	unsigned int i;
   1394        1.3      matt 
   1395        1.4      matt 	if (gtmpsccninit_done)
   1396        1.4      matt 		return 0;
   1397        1.4      matt 
   1398        1.4      matt 	DPRINTF(("gtmpsccnattach\n"));
   1399        1.3      matt 	gtmpsc_hackinit(sc, memt, memh, unit);
   1400        1.4      matt 	DPRINTF(("gtmpscinit\n"));
   1401        1.3      matt 	gtmpscinit(sc);
   1402        1.3      matt 	gtmpsccninit_done = 1;
   1403        1.3      matt 	cp = gtmpsc_earlybuf;
   1404        1.4      matt 	strcpy(gtmpsc_earlybuf, "\r\nMPSC Lives!\r\n");
   1405        1.3      matt 	for (i=0; i < sizeof(gtmpsc_earlybuf); i++) {
   1406        1.3      matt 		c = *cp++;
   1407        1.3      matt 		if (c == 0)
   1408        1.3      matt 			break;
   1409        1.4      matt 		gtmpsc_common_putc(unit, c);
   1410        1.3      matt 	}
   1411        1.4      matt 	DPRINTF(("switching cn_tab\n"));
   1412        1.4      matt 	gtmpsc_consdev.cn_dev = makedev(0, unit);
   1413        1.4      matt 	cn_tab = &gtmpsc_consdev;
   1414        1.4      matt 	DPRINTF(("switched cn_tab!\n"));
   1415        1.3      matt 	return 0;
   1416        1.3      matt }
   1417        1.3      matt 
   1418        1.1      matt /*
   1419        1.1      matt  * gtmpsc_common_pollc - non-blocking console read
   1420        1.1      matt  *
   1421        1.1      matt  *	if there is an RX char, return it in *cp
   1422        1.1      matt  *	set *statp if Break detected
   1423        1.1      matt  *
   1424        1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1425        1.1      matt  *
   1426        1.1      matt  * return 1 if there is RX data
   1427        1.1      matt  * otherwise return 0
   1428        1.1      matt  */
   1429        1.1      matt STATIC int
   1430        1.1      matt gtmpsc_common_pollc(unsigned int unit, char *cp, int *statp)
   1431        1.1      matt {
   1432        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_scp[unit];
   1433        1.1      matt 	gtmpsc_pollrx_t *vrxp;
   1434        1.1      matt 	unsigned int ix;
   1435        1.1      matt 	unsigned int cx;
   1436        1.1      matt 	unsigned int nc;
   1437        1.1      matt 
   1438        1.1      matt 	*statp = GTMPSC_STAT_NONE;
   1439        1.1      matt 	ix = sc->gtmpsc_poll_rxix;
   1440        1.1      matt 	nc = sc->gtmpsc_nc;
   1441        1.1      matt 	cx = sc->gtmpsc_cx;
   1442        1.1      matt 	if (nc == 0) {
   1443        1.1      matt 		unsigned int *csrp;
   1444        1.1      matt 		unsigned int csr;
   1445        1.1      matt 
   1446        1.1      matt 		vrxp = &sc->gtmpsc_poll_sdmapage->rx[ix];
   1447        1.1      matt 		csrp = &vrxp->rxdesc.sdma_csr;
   1448        1.1      matt 		cx = 0;
   1449        1.1      matt 
   1450        1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1451        1.1      matt 		csr = desc_read(csrp);
   1452        1.1      matt 		if (csr & SDMA_CSR_RX_OWN)
   1453        1.1      matt 			return 0;
   1454        1.1      matt 		if (csr & SDMA_CSR_RX_BR)
   1455        1.1      matt 			*statp = GTMPSC_STAT_BREAK;
   1456        1.1      matt 		if (csr & SDMA_CSR_RX_ES)
   1457        1.1      matt 			PRINTF(("mpsc 0 RX error, rxdesc csr 0x%x\n", csr));
   1458        1.1      matt 
   1459        1.1      matt 		nc = desc_read(&vrxp->rxdesc.sdma_cnt);
   1460        1.1      matt 		nc &= SDMA_RX_CNT_BCNT_MASK;
   1461        1.1      matt 		csr = SDMA_CSR_RX_L|SDMA_CSR_RX_F|SDMA_CSR_RX_OWN
   1462        1.1      matt 							      |SDMA_CSR_RX_EI;
   1463        1.1      matt 		if (nc == 0) {
   1464        1.1      matt 			if ((++ix) >= GTMPSC_NRXDESC)
   1465        1.1      matt 				ix = 0;
   1466        1.1      matt 			sc->gtmpsc_poll_rxix = ix;
   1467        1.1      matt 			desc_write(csrp, csr);
   1468        1.1      matt 			GTMPSC_CACHE_FLUSH(csrp);
   1469        1.1      matt 			return 0;
   1470        1.1      matt 		}
   1471        1.1      matt 		bcopy(vrxp->rxbuf, sc->gtmpsc_rxbuf, nc);
   1472        1.1      matt 		desc_write(csrp, csr);
   1473        1.1      matt 		GTMPSC_CACHE_FLUSH(csrp);
   1474        1.1      matt 	}
   1475        1.1      matt 	gtmpsc_poll_pollc_cnt++;
   1476        1.1      matt 	nc--;
   1477        1.1      matt 	*cp = sc->gtmpsc_rxbuf[cx++];
   1478        1.1      matt 	if (nc == 0) {
   1479        1.1      matt 		if ((++ix) >= GTMPSC_NRXDESC)
   1480        1.1      matt 			ix = 0;
   1481        1.1      matt 		sc->gtmpsc_poll_rxix = ix;
   1482        1.1      matt 	}
   1483        1.1      matt 	sc->gtmpsc_cx = cx;
   1484        1.1      matt 	sc->gtmpsc_nc = nc;
   1485        1.1      matt 	return 1;
   1486        1.1      matt }
   1487        1.1      matt 
   1488        1.1      matt /*
   1489        1.1      matt  * gtmpsc_common_getc - polled console read
   1490        1.1      matt  *
   1491        1.1      matt  *	We copy data from the DMA buffers into a buffer in the softc
   1492        1.1      matt  *	to reduce descriptor ownership turnaround time
   1493        1.1      matt  *	MPSC can crater if it wraps descriptor rings,
   1494        1.1      matt  *	which is asynchronous and throttled only by line speed.
   1495        1.1      matt  *
   1496        1.1      matt  *	This code assumes the buffer PA==KVA
   1497        1.1      matt  *	and assumes we are called at ipl >= IPL_SERIAL
   1498        1.1      matt  */
   1499        1.1      matt STATIC int
   1500        1.1      matt gtmpsc_common_getc(unsigned int unit)
   1501        1.1      matt {
   1502        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_scp[unit];
   1503        1.1      matt 	gtmpsc_pollrx_t *vrxp;
   1504        1.1      matt 	unsigned int ix;
   1505        1.1      matt 	unsigned int cx;
   1506        1.1      matt 	unsigned int nc;
   1507        1.8       scw 	unsigned int wdog_interval;
   1508        1.1      matt 	int c;
   1509        1.1      matt 
   1510        1.1      matt 	ix = sc->gtmpsc_poll_rxix;
   1511        1.1      matt 	nc = sc->gtmpsc_nc;
   1512        1.1      matt 	cx = sc->gtmpsc_cx;
   1513        1.8       scw 	wdog_interval = 0;
   1514        1.1      matt 	while (nc == 0) {
   1515        1.1      matt 		unsigned int *csrp;
   1516        1.1      matt 		unsigned int csr;
   1517        1.1      matt 		unsigned int r;
   1518        1.1      matt 
   1519        1.1      matt 		vrxp = &sc->gtmpsc_poll_sdmapage->rx[ix];
   1520        1.1      matt 		csrp = &vrxp->rxdesc.sdma_csr;
   1521        1.1      matt 		cx = 0;
   1522        1.1      matt 
   1523        1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1524        1.1      matt 		csr = desc_read(csrp);
   1525        1.1      matt 		if (csr & SDMA_CSR_RX_OWN) {
   1526        1.1      matt 			r = sc->gtmpsc_chr2 | GTMPSC_CHR2_CRD;
   1527        1.4      matt 			GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1528        1.1      matt 			do {
   1529        1.8       scw 				if (wdog_interval++ % 32)
   1530        1.8       scw 					gt_watchdog_service();
   1531        1.1      matt 				gtmpsc_poll_getc_miss++;
   1532        1.1      matt 				GTMPSC_CACHE_INVALIDATE(csrp);
   1533        1.4      matt 				DELAY(50);
   1534        1.1      matt 				csr = desc_read(csrp);
   1535        1.1      matt 			} while (csr & SDMA_CSR_RX_OWN);
   1536        1.8       scw 		} else
   1537        1.8       scw 		if (wdog_interval++ % 32)
   1538        1.8       scw 			gt_watchdog_service();
   1539        1.1      matt 		if (csr & SDMA_CSR_RX_ES)
   1540        1.1      matt 			PRINTF(("mpsc 0 RX error, rxdesc csr 0x%x\n", csr));
   1541        1.1      matt 
   1542        1.1      matt 		nc = desc_read(&vrxp->rxdesc.sdma_cnt);
   1543        1.1      matt 		nc &= SDMA_RX_CNT_BCNT_MASK;
   1544        1.1      matt 		if (nc) {
   1545        1.1      matt 			bcopy(vrxp->rxbuf, sc->gtmpsc_rxbuf, nc);
   1546        1.1      matt 		} else {
   1547        1.1      matt 			if ((++ix) >= GTMPSC_NRXDESC)
   1548        1.1      matt 				ix = 0;
   1549        1.1      matt 			sc->gtmpsc_poll_rxix = ix;
   1550        1.1      matt 		}
   1551        1.1      matt 		csr = SDMA_CSR_RX_L|SDMA_CSR_RX_F|SDMA_CSR_RX_OWN
   1552        1.1      matt 							|SDMA_CSR_RX_EI;
   1553        1.1      matt 		desc_write(csrp, csr);
   1554        1.1      matt 		GTMPSC_CACHE_FLUSH(csrp);
   1555        1.1      matt #ifdef KGDB
   1556        1.1      matt 		if (unit == comkgdbport && gt_reva_gtmpsc_bug)
   1557        1.4      matt 			GT_WRITE(sc, SDMA_ICAUSE, ~SDMA_INTR_RXBUF(unit));
   1558        1.1      matt #endif
   1559        1.1      matt 	}
   1560        1.1      matt 	gtmpsc_poll_getc_cnt++;
   1561        1.1      matt 	nc--;
   1562        1.1      matt 	c = (int)sc->gtmpsc_rxbuf[cx++];
   1563        1.1      matt 	if (nc == 0) {
   1564        1.1      matt 		if ((++ix) >= GTMPSC_NRXDESC)
   1565        1.1      matt 			ix = 0;
   1566        1.1      matt 		sc->gtmpsc_poll_rxix = ix;
   1567        1.1      matt 	}
   1568        1.1      matt 	sc->gtmpsc_cx = cx;
   1569        1.1      matt 	sc->gtmpsc_nc = nc;
   1570        1.8       scw 	gt_watchdog_service();
   1571        1.1      matt 	return c;
   1572        1.1      matt }
   1573        1.1      matt 
   1574        1.1      matt /*
   1575        1.1      matt  * gtmpsc_common_putn - write a buffer into the hardware
   1576        1.1      matt  *
   1577        1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1578        1.1      matt  */
   1579        1.1      matt STATIC void
   1580        1.1      matt gtmpsc_common_putn(struct gtmpsc_softc *sc)
   1581        1.1      matt 
   1582        1.1      matt {
   1583        1.1      matt 	int     unit = sc->gtmpsc_unit;
   1584        1.1      matt 	int     n;
   1585        1.1      matt 	int     kick;
   1586        1.1      matt 	gtmpsc_polltx_t *vtxp;
   1587        1.1      matt 	unsigned int *csrp;
   1588        1.1      matt 	unsigned int csr;
   1589        1.1      matt 	unsigned int ix;
   1590        1.1      matt 	unsigned int sdcm;
   1591        1.1      matt 
   1592        1.1      matt 	kick = 0;
   1593        1.1      matt 	for (ix = sc->gtmpsc_poll_txix; sc->sc_tbc;) {
   1594        1.1      matt 		vtxp = &sc->gtmpsc_poll_sdmapage->tx[ix];
   1595        1.1      matt 		csrp = &vtxp->txdesc.sdma_csr;
   1596        1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1597        1.1      matt 		csr = desc_read(csrp);
   1598        1.1      matt 		if ((csr & SDMA_CSR_TX_OWN) != 0)
   1599        1.1      matt 			break;
   1600        1.1      matt 		n = sc->sc_tbc;
   1601        1.1      matt 		if (n > GTMPSC_TXBUFSZ)
   1602        1.1      matt 			n = GTMPSC_TXBUFSZ;
   1603        1.1      matt 		bcopy(sc->sc_tba, vtxp->txbuf, n);
   1604        1.1      matt 		csr = SDMA_CSR_TX_L | SDMA_CSR_TX_F
   1605        1.1      matt 					| SDMA_CSR_TX_EI | SDMA_CSR_TX_OWN;
   1606        1.1      matt 		desc_write(&vtxp->txdesc.sdma_cnt,
   1607        1.1      matt 				(n << SDMA_TX_CNT_BCNT_SHIFT) | n);
   1608        1.1      matt 		desc_write(csrp, csr);
   1609        1.1      matt 		GTMPSC_CACHE_FLUSH(csrp);
   1610        1.1      matt 		sc->sc_tbc -= n;
   1611        1.1      matt 		sc->sc_tba += n;
   1612        1.1      matt 		gtmpsc_poll_putn_cnt += n;
   1613        1.1      matt 		sc->cnt_tx_to_sdma += n;
   1614        1.1      matt 		kick = 1;
   1615        1.1      matt 
   1616        1.1      matt 		if (++ix >= GTMPSC_NTXDESC)
   1617        1.1      matt 			ix = 0;
   1618        1.1      matt 	}
   1619        1.1      matt 	if (kick) {
   1620        1.1      matt 		sc->gtmpsc_poll_txix = ix;
   1621        1.1      matt 
   1622        1.1      matt 		/*
   1623        1.1      matt 		 * now kick some SDMA
   1624        1.1      matt 		 */
   1625        1.3      matt 		sdcm = GT_READ(sc, SDMA_U_SDCM(unit));
   1626        1.1      matt 
   1627        1.1      matt 		if ((sdcm & SDMA_SDCM_TXD) == 0) {
   1628        1.4      matt 			GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_TXD);
   1629        1.1      matt 		}
   1630        1.1      matt 	}
   1631        1.1      matt }
   1632        1.1      matt 
   1633        1.1      matt /*
   1634        1.1      matt  * gtmpsc_common_putc - polled console putc
   1635        1.1      matt  *
   1636        1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1637        1.1      matt  */
   1638        1.1      matt STATIC void
   1639        1.1      matt gtmpsc_common_putc(unsigned int unit, unsigned char c)
   1640        1.1      matt {
   1641        1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_scp[unit];
   1642        1.1      matt 	gtmpsc_polltx_t *vtxp;
   1643        1.1      matt 	unsigned int *csrp;
   1644        1.1      matt 	unsigned int csr;
   1645        1.1      matt 	unsigned int ix;
   1646        1.1      matt 	unsigned int nix;
   1647        1.8       scw 	unsigned int wdog_interval = 0;
   1648        1.1      matt 
   1649        1.5      matt 	DPRINTF(("gtmpsc_common_putc(%d, '%c'): cur=%#x, first=%#x", unit, c,
   1650        1.5      matt 	    GT_READ(sc, SDMA_U_SCTDP(unit)),   /* current */
   1651        1.5      matt 	    GT_READ(sc, SDMA_U_SFTDP(unit))));   /* first   */
   1652        1.1      matt 	ix = sc->gtmpsc_poll_txix;
   1653        1.1      matt 	nix = ix + 1;
   1654        1.1      matt 	if (nix >= GTMPSC_NTXDESC)
   1655        1.1      matt 		nix = 0;
   1656        1.1      matt 	sc->gtmpsc_poll_txix = nix;
   1657        1.1      matt 	vtxp = &sc->gtmpsc_poll_sdmapage->tx[ix];
   1658        1.1      matt 	csrp = &vtxp->txdesc.sdma_csr;
   1659        1.1      matt 
   1660        1.5      matt 
   1661        1.1      matt 	for (;;) {
   1662        1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1663        1.1      matt 		csr = desc_read(csrp);
   1664        1.1      matt 		if ((csr & SDMA_CSR_TX_OWN) == 0)
   1665        1.1      matt 			break;
   1666        1.1      matt 		gtmpsc_poll_putc_miss++;
   1667        1.5      matt 		DELAY(40);
   1668        1.5      matt 		DPRINTF(("."));
   1669        1.8       scw 		if (wdog_interval++ % 32)
   1670        1.8       scw 			gt_watchdog_service();
   1671        1.1      matt 	}
   1672        1.1      matt 	if (csr & SDMA_CSR_TX_ES)
   1673        1.5      matt 		PRINTF(("mpsc %d TX error, txdesc csr 0x%x\n", unit, csr));
   1674        1.1      matt 
   1675        1.1      matt 	gtmpsc_poll_putc_cnt++;
   1676        1.1      matt 	vtxp->txbuf[0] = c;
   1677        1.5      matt 	csr = SDMA_CSR_TX_L | SDMA_CSR_TX_F | SDMA_CSR_TX_EI | SDMA_CSR_TX_OWN;
   1678        1.1      matt 	desc_write(&vtxp->txdesc.sdma_cnt, (1 << SDMA_TX_CNT_BCNT_SHIFT) | 1);
   1679        1.1      matt 	desc_write(csrp, csr);
   1680        1.1      matt 	GTMPSC_CACHE_FLUSH(csrp);
   1681        1.1      matt 
   1682        1.1      matt 	/*
   1683        1.1      matt 	 * now kick some SDMA
   1684        1.1      matt 	 */
   1685        1.5      matt 	GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_TXD);
   1686        1.8       scw 	gt_watchdog_service();
   1687        1.1      matt }
   1688        1.1      matt 
   1689        1.1      matt 
   1690        1.1      matt STATIC void
   1691        1.1      matt gtmpsc_poll(void *arg)
   1692        1.1      matt {
   1693        1.1      matt 	struct gtmpsc_softc *sc = (struct gtmpsc_softc *)arg;
   1694        1.1      matt 	int kick;
   1695        1.1      matt 	char ch;
   1696        1.1      matt 	int stat;
   1697        1.1      matt 	static struct timeval   msg_time = {0,0};
   1698        1.1      matt 	static struct timeval   cur_time;
   1699        1.1      matt 	static int fifo_full = 0;
   1700        1.1      matt 
   1701        1.1      matt 	kick = 0;
   1702        1.1      matt 	while (gtmpsc_common_pollc(sc->gtmpsc_unit, &ch, &stat)) {
   1703        1.1      matt #ifdef DDB
   1704        1.1      matt 		if (stat)
   1705        1.1      matt 			break;
   1706        1.1      matt #endif
   1707        1.1      matt 		++sc->cnt_rx_from_sdma;
   1708        1.1      matt 		if (sc->gtmpsc_rxfifo_navail != 0) {
   1709        1.1      matt 			sc->gtmpsc_rxfifo[sc->gtmpsc_rxfifo_putix++] = ch;
   1710        1.1      matt 			if (sc->gtmpsc_rxfifo_putix == GTMPSC_RXFIFOSZ)
   1711        1.1      matt 				sc->gtmpsc_rxfifo_putix = 0;
   1712        1.1      matt 			atomic_add(&sc->gtmpsc_rxfifo_navail, -1);
   1713        1.1      matt 			++sc->cnt_rx_to_fifo;
   1714        1.1      matt 			fifo_full = 0;
   1715        1.1      matt 			kick = 1;
   1716        1.1      matt 		} else {
   1717        1.1      matt 			if (fifo_full == 0) {
   1718        1.1      matt 				fifo_full = 1;
   1719        1.1      matt 				microtime(&cur_time);
   1720        1.1      matt 				if (cur_time.tv_sec - msg_time.tv_sec >= 5) {
   1721        1.1      matt 					/* Only do this once in 5 sec */
   1722        1.1      matt 					msg_time = cur_time;
   1723        1.1      matt 					printf("mpsc%d: input FIFO full, "
   1724        1.1      matt 					       "dropping incoming characters\n",
   1725        1.1      matt 					       sc->gtmpsc_unit);
   1726        1.1      matt 				}
   1727        1.1      matt 			}
   1728        1.1      matt 		}
   1729        1.1      matt 	}
   1730        1.1      matt #ifdef DDB
   1731        1.1      matt 	if (stat) {
   1732        1.4      matt 		if (cn_tab == &gtmpsc_consdev) {
   1733        1.1      matt 			Debugger();
   1734        1.4      matt 		}
   1735        1.1      matt 	}
   1736        1.1      matt #endif
   1737        1.1      matt 	if (kick)
   1738       1.24        ad 		softint_schedule(sc->sc_si);
   1739        1.1      matt }
   1740        1.1      matt 
   1741        1.1      matt #ifdef KGDB
   1742        1.1      matt /* ARGSUSED */
   1743        1.1      matt STATIC int
   1744        1.1      matt gtmpsc_kgdb_getc(arg)
   1745        1.1      matt 	void *arg;
   1746        1.1      matt {
   1747        1.1      matt 
   1748        1.1      matt 	return (gtmpsc_common_getc(comkgdbport));
   1749        1.1      matt }
   1750        1.1      matt 
   1751        1.1      matt /* ARGSUSED */
   1752        1.1      matt STATIC void
   1753        1.1      matt gtmpsc_kgdb_putc(arg, c)
   1754        1.1      matt 	void *arg;
   1755        1.1      matt 	int c;
   1756        1.1      matt {
   1757        1.1      matt 
   1758        1.1      matt 	return (gtmpsc_common_putc(comkgdbport, c));
   1759        1.1      matt }
   1760        1.1      matt 
   1761        1.1      matt STATIC void
   1762        1.1      matt gtmpsc_kgdb_poll(void *arg)
   1763        1.1      matt {
   1764        1.1      matt 	struct gtmpsc_softc       *sc = (struct gtmpsc_softc *)arg;
   1765        1.1      matt 	int                     s;
   1766        1.1      matt 	char                    c;
   1767        1.1      matt 	int                     brk;
   1768        1.1      matt 
   1769       1.10     perry 	s = splserial();
   1770        1.1      matt 	if (kgdb_recover == 0) { /* gdb is not currently talking to its agent */
   1771        1.1      matt 		while (gtmpsc_common_pollc(sc->gtmpsc_unit, &c, &brk)) {
   1772        1.1      matt 			if (c == CTRL('c'))
   1773        1.1      matt 				brk = GTMPSC_STAT_BREAK;
   1774        1.1      matt 			if (brk == GTMPSC_STAT_BREAK)
   1775        1.1      matt 				break;
   1776        1.1      matt 		}
   1777        1.1      matt 		if (brk == GTMPSC_STAT_BREAK) {
   1778        1.1      matt 			if (kgdb_break_immediate)
   1779        1.1      matt 				breakpoint();
   1780        1.1      matt 			else {
   1781        1.1      matt 				printf("connecting to kgdb\n");
   1782        1.1      matt 				kgdb_connect(1);
   1783        1.1      matt 			}
   1784        1.1      matt 		}
   1785        1.1      matt 	}
   1786        1.1      matt 	splx(s);
   1787        1.1      matt }
   1788        1.1      matt 
   1789        1.1      matt #endif /* KGDB */
   1790        1.1      matt 
   1791        1.2      matt #if 0
   1792        1.1      matt void
   1793        1.1      matt gtmpsc_printf(const char *fmt, ...)
   1794        1.1      matt {
   1795        1.1      matt 	struct consdev *ocd;
   1796        1.1      matt 	int s;
   1797        1.1      matt 	va_list ap;
   1798        1.1      matt 
   1799        1.1      matt 	s = splserial();
   1800        1.1      matt 	ocd = cn_tab;
   1801        1.1      matt 	cn_tab = &constab[0];
   1802        1.1      matt 	va_start(ap, fmt);
   1803        1.1      matt 	printf(fmt, ap);
   1804        1.1      matt 	va_end(ap);
   1805        1.1      matt 	cn_tab = ocd;
   1806        1.1      matt 	splx(s);
   1807        1.1      matt }
   1808        1.2      matt #endif
   1809        1.1      matt 
   1810        1.1      matt void
   1811        1.1      matt gtmpsc_mem_printf(const char *fmt, ...)
   1812        1.1      matt {
   1813        1.1      matt 	va_list ap;
   1814        1.1      matt 	static unsigned char *p = gtmpsc_print_buf;
   1815        1.1      matt 
   1816        1.1      matt 	if (p >= &gtmpsc_print_buf[GTMPSC_PRINT_BUF_SIZE - 128]) {
   1817        1.1      matt 		bzero(gtmpsc_print_buf, GTMPSC_PRINT_BUF_SIZE);
   1818        1.1      matt 		p = gtmpsc_print_buf;
   1819        1.1      matt 	}
   1820        1.1      matt 	va_start(ap, fmt);
   1821        1.1      matt 	p += vsprintf(p, fmt, ap);
   1822        1.1      matt 	va_end(ap);
   1823        1.1      matt }
   1824        1.1      matt 
   1825        1.1      matt void
   1826        1.1      matt gtmpsc_shutdownhook(void *arg)
   1827        1.1      matt {
   1828        1.1      matt 	gtmpsc_softc_t *sc = (gtmpsc_softc_t *)arg;
   1829        1.1      matt 
   1830        1.1      matt 	gtmpsc_txflush(sc);
   1831        1.1      matt }
   1832        1.1      matt 
   1833        1.1      matt void
   1834        1.1      matt gtmpsccnhalt(dev_t dev)
   1835        1.1      matt {
   1836        1.1      matt 	unsigned int unit;
   1837        1.1      matt 	u_int32_t r;
   1838        1.1      matt 
   1839        1.1      matt 	for (unit = 0; unit < GTMPSC_NCHAN; unit++) {
   1840        1.4      matt 		gtmpsc_softc_t *sc = gtmpsc_scp[unit];
   1841        1.1      matt 		if (sc == NULL)
   1842        1.1      matt 			continue;
   1843        1.1      matt 
   1844        1.1      matt 		/*
   1845        1.1      matt 		 * flush TX buffers
   1846        1.1      matt 		 */
   1847        1.1      matt 		gtmpsc_txflush(sc);
   1848        1.1      matt 
   1849        1.1      matt 		/*
   1850       1.10     perry 		 * stop MPSC unit RX
   1851        1.1      matt 		 */
   1852        1.3      matt 		r = GT_READ(sc, GTMPSC_U_CHRN(unit, 2));
   1853        1.1      matt 		r &= ~GTMPSC_CHR2_EH;
   1854        1.1      matt 		r |= GTMPSC_CHR2_RXABORT;
   1855        1.3      matt 		GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1856        1.1      matt 
   1857        1.1      matt 		DELAY(GTMPSC_RESET_DELAY);
   1858        1.1      matt 
   1859        1.1      matt 		/*
   1860        1.1      matt 		 * abort SDMA RX for MPSC unit
   1861        1.1      matt 		 */
   1862        1.4      matt 		GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_AR);
   1863        1.1      matt 	}
   1864        1.1      matt }
   1865        1.1      matt 
   1866        1.1      matt void
   1867        1.1      matt gtmpsc_puts(char *str)
   1868        1.1      matt {
   1869        1.1      matt 	char c;
   1870        1.1      matt 
   1871        1.1      matt 	if (str == NULL)
   1872        1.1      matt 		return;
   1873        1.1      matt 	while ((c = *str++) != 0)
   1874        1.1      matt 		gtmpsccnputc(0, c);
   1875        1.1      matt }
   1876