Home | History | Annotate | Line # | Download | only in marvell
gtmpsc.c revision 1.37
      1  1.37    cegger /*	$NetBSD: gtmpsc.c,v 1.37 2009/05/12 14:30:25 cegger 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.37    cegger __KERNEL_RCSID(0, "$NetBSD: gtmpsc.c,v 1.37 2009/05/12 14:30:25 cegger 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.37    cegger STATIC int  gtmpscmatch(device_t, cfdata_t, void *);
    122  1.37    cegger STATIC void gtmpscattach(device_t, device_t, 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.31  gmcgarry     __aligned(PAGE_SIZE);
    224   1.6   thorpej STATIC unsigned char gtmpsc_fake_dmapage[PAGE_SIZE]
    225  1.31  gmcgarry     __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.37    cegger gtmpscmatch(device_t parent, cfdata_t 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.37    cegger gtmpscattach(device_t parent, device_t 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.28    cegger 		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.28    cegger 			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.28    cegger 		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.30    cegger 	sc = device_lookup_private(&gtmpsc_cd, unit);
    599   1.1      matt 	if (!sc)
    600   1.1      matt 		return ENXIO;
    601   1.1      matt #ifdef KGDB
    602   1.1      matt 	/*
    603   1.1      matt 	 * If this is the kgdb port, no other use is permitted.
    604   1.1      matt 	 */
    605   1.1      matt 	if (sc->gtmpsc_flags & GTMPSCF_KGDB != 0)
    606   1.1      matt 		return (EBUSY);
    607   1.1      matt #endif
    608   1.1      matt 	tp = sc->gtmpsc_tty;
    609  1.21      elad 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
    610   1.1      matt 		return (EBUSY);
    611   1.1      matt 
    612   1.1      matt 	s = spltty();
    613   1.1      matt 
    614   1.1      matt 	if (!(tp->t_state & TS_ISOPEN)) {
    615   1.1      matt 		struct termios t;
    616   1.1      matt 
    617   1.1      matt 		tp->t_dev = dev;
    618   1.1      matt 		s2 = splserial();
    619   1.3      matt 		SDMA_IMASK_ENABLE(sc, SDMA_INTR_RXBUF(unit));
    620   1.1      matt 		splx(s2);
    621   1.1      matt 		t.c_ispeed = 0;
    622   1.1      matt #if 0
    623   1.1      matt 		t.c_ospeed = TTYDEF_SPEED;
    624   1.1      matt #else
    625   1.1      matt 		t.c_ospeed = GT_MPSC_DEFAULT_BAUD_RATE;
    626   1.1      matt #endif
    627   1.1      matt 		t.c_cflag = TTYDEF_CFLAG;
    628   1.1      matt 		/* Make sure gtmpscparam() will do something. */
    629   1.1      matt 		tp->t_ospeed = 0;
    630   1.1      matt 		(void) gtmpscparam(tp, &t);
    631   1.1      matt 		tp->t_iflag = TTYDEF_IFLAG;
    632   1.1      matt 		tp->t_oflag = TTYDEF_OFLAG;
    633   1.1      matt 		tp->t_lflag = TTYDEF_LFLAG;
    634   1.1      matt 		ttychars(tp);
    635   1.1      matt 		ttsetwater(tp);
    636   1.1      matt 		s2 = splserial();
    637   1.1      matt 		/* Clear the input ring */
    638   1.1      matt 		sc->gtmpsc_rxfifo_putix = 0;
    639   1.1      matt 		sc->gtmpsc_rxfifo_getix = 0;
    640   1.1      matt 		sc->gtmpsc_rxfifo_navail = GTMPSC_RXFIFOSZ;
    641   1.1      matt 		gtmpsc_iflush(sc);
    642   1.1      matt 		splx(s2);
    643   1.1      matt 	}
    644   1.1      matt 	splx(s);
    645   1.1      matt 	error = ttyopen(tp, GTMPSCDIALOUT(dev), ISSET(flag, O_NONBLOCK));
    646   1.1      matt 	if (error)
    647   1.1      matt 		goto bad;
    648   1.1      matt 
    649   1.1      matt 	error = (*tp->t_linesw->l_open)(dev, tp);
    650   1.1      matt 	if (error)
    651   1.1      matt 		goto bad;
    652   1.1      matt 
    653   1.1      matt 	return (0);
    654   1.1      matt 
    655   1.1      matt bad:
    656   1.1      matt 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
    657   1.1      matt 		/*
    658   1.1      matt 		 * We failed to open the device, and nobody else had it opened.
    659   1.1      matt 		 * Clean up the state as appropriate.
    660   1.1      matt 		 */
    661   1.1      matt 		gtmpscshutdown(sc);
    662   1.1      matt 	}
    663   1.1      matt 
    664   1.1      matt 	return (error);
    665   1.1      matt }
    666   1.1      matt 
    667   1.1      matt int
    668  1.13  christos gtmpscclose(dev_t dev, int flag, int mode, struct lwp *l)
    669   1.1      matt {
    670   1.1      matt 	int unit = GTMPSCUNIT(dev);
    671  1.30    cegger 	struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, unit);
    672   1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    673   1.1      matt 	int s;
    674   1.1      matt 
    675   1.1      matt 	s = splserial();
    676   1.1      matt 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
    677   1.1      matt 		splx(s);
    678   1.1      matt 		return (0);
    679   1.1      matt 	}
    680   1.1      matt 
    681   1.1      matt 	(*tp->t_linesw->l_close)(tp, flag);
    682   1.1      matt 	ttyclose(tp);
    683   1.1      matt 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
    684   1.1      matt 		/*
    685   1.1      matt 		 * Although we got a last close, the device may still be in
    686   1.1      matt 		 * use; e.g. if this was the dialout node, and there are still
    687   1.1      matt 		 * processes waiting for carrier on the non-dialout node.
    688   1.1      matt 		 */
    689   1.1      matt 		gtmpscshutdown(sc);
    690   1.1      matt 	}
    691   1.1      matt 
    692   1.1      matt 	splx(s);
    693   1.1      matt 	return (0);
    694   1.1      matt }
    695   1.1      matt 
    696   1.1      matt int
    697   1.1      matt gtmpscread(dev_t dev, struct uio *uio, int flag)
    698   1.1      matt {
    699  1.30    cegger 	struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, GTMPSCUNIT(dev));
    700   1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    701  1.10     perry 
    702   1.1      matt 	return (*tp->t_linesw->l_read)(tp, uio, flag);
    703   1.1      matt }
    704   1.1      matt 
    705   1.1      matt int
    706   1.1      matt gtmpscwrite(dev_t dev, struct uio *uio, int flag)
    707   1.1      matt {
    708  1.30    cegger 	struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, GTMPSCUNIT(dev));
    709   1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    710  1.10     perry 
    711   1.1      matt 	return (*tp->t_linesw->l_write)(tp, uio, flag);
    712   1.1      matt }
    713   1.1      matt 
    714   1.1      matt int
    715  1.13  christos gtmpscpoll(dev_t dev, int events, struct lwp *l)
    716   1.1      matt {
    717  1.30    cegger 	struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, GTMPSCUNIT(dev));
    718   1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    719   1.1      matt 
    720  1.13  christos 	return ((*tp->t_linesw->l_poll)(tp, events, l));
    721   1.1      matt }
    722   1.1      matt 
    723   1.1      matt int
    724  1.23  christos gtmpscioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
    725   1.1      matt {
    726  1.30    cegger 	struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, GTMPSCUNIT(dev));
    727   1.1      matt 	struct tty *tp = sc->gtmpsc_tty;
    728   1.1      matt 	int error;
    729  1.10     perry 
    730  1.13  christos 	if ((error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l)) >= 0)
    731   1.1      matt 		return error;
    732  1.13  christos 	if ((error = ttioctl(tp, cmd, data, flag, l)) >= 0)
    733   1.1      matt 		return error;
    734   1.1      matt 	return ENOTTY;
    735   1.1      matt }
    736   1.1      matt 
    737   1.1      matt struct tty *
    738   1.1      matt gtmpsctty(dev_t dev)
    739   1.1      matt {
    740  1.30    cegger 	struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, GTMPSCUNIT(dev));
    741   1.1      matt 
    742   1.1      matt 	return sc->gtmpsc_tty;
    743   1.1      matt }
    744   1.1      matt 
    745   1.1      matt void
    746   1.1      matt gtmpscstop(struct tty *tp, int flag)
    747   1.1      matt {
    748   1.1      matt }
    749   1.1      matt 
    750   1.1      matt STATIC void
    751   1.1      matt gtmpscstart(struct tty *tp)
    752   1.1      matt {
    753   1.4      matt 	struct gtmpsc_softc *sc;
    754   1.1      matt 	unsigned char *tba;
    755   1.1      matt 	unsigned int unit;
    756   1.1      matt 	int s, s2, tbc;
    757   1.1      matt 
    758   1.1      matt 	unit = GTMPSCUNIT(tp->t_dev);
    759  1.30    cegger 	sc = device_lookup_private(&gtmpsc_cd, unit);
    760   1.1      matt 	if (sc == NULL)
    761   1.1      matt 		return;
    762   1.1      matt 
    763   1.1      matt 	s = spltty();
    764   1.1      matt 	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
    765   1.1      matt 		goto out;
    766   1.1      matt 	if (sc->sc_tx_stopped)
    767   1.1      matt 		goto out;
    768  1.27        ad 	if (!ttypull(tp))
    769  1.27        ad 		goto out;
    770   1.1      matt 
    771   1.1      matt 	/* Grab the first contiguous region of buffer space. */
    772   1.1      matt 	tba = tp->t_outq.c_cf;
    773   1.1      matt 	tbc = ndqb(&tp->t_outq, 0);
    774   1.1      matt 
    775   1.1      matt 	s2 = splserial();
    776   1.1      matt 
    777   1.1      matt 	sc->sc_tba = tba;
    778   1.1      matt 	sc->sc_tbc = tbc;
    779   1.1      matt 	sc->cnt_tx_from_ldisc += tbc;
    780   1.3      matt 	SDMA_IMASK_ENABLE(sc, SDMA_INTR_TXBUF(unit));
    781   1.1      matt 	tp->t_state |= TS_BUSY;
    782   1.1      matt 	sc->sc_tx_busy = 1;
    783   1.1      matt 	gtmpsc_common_putn(sc);
    784   1.1      matt 
    785   1.1      matt 	splx(s2);
    786   1.1      matt out:
    787   1.1      matt 	splx(s);
    788   1.1      matt }
    789   1.1      matt 
    790   1.1      matt STATIC int
    791   1.1      matt gtmpscparam(struct tty *tp, struct termios *t)
    792   1.1      matt {
    793  1.30    cegger 	struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, GTMPSCUNIT(tp->t_dev));
    794   1.1      matt 	int ospeed = compute_cdv(t->c_ospeed);
    795   1.1      matt 	int s;
    796   1.1      matt 
    797   1.1      matt 	/* Check requested parameters. */
    798   1.1      matt 	if (ospeed < 0)
    799   1.1      matt 		return (EINVAL);
    800   1.1      matt 	if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
    801   1.1      matt 		return (EINVAL);
    802   1.1      matt 
    803   1.1      matt 	/*
    804   1.1      matt 	 * If there were no changes, don't do anything.  This avoids dropping
    805   1.1      matt 	 * input and improves performance when all we did was frob things like
    806   1.1      matt 	 * VMIN and VTIME.
    807   1.1      matt 	 */
    808   1.1      matt 	if (tp->t_ospeed == t->c_ospeed &&
    809   1.1      matt 	    tp->t_cflag == t->c_cflag)
    810   1.1      matt 		return (0);
    811   1.1      matt 
    812   1.1      matt 	s = splserial();
    813   1.1      matt 
    814   1.4      matt 	sc->gtmpsc_brg_bcr = BRG_BCR_EN | GT_MPSC_CLOCK_SOURCE | ospeed;
    815   1.1      matt 	sc->gtmpsc_chr3 = GTMPSC_MAXIDLE(t->c_ospeed);
    816   1.1      matt 
    817   1.1      matt 	/* And copy to tty. */
    818   1.1      matt 	tp->t_ispeed = 0;
    819   1.1      matt 	tp->t_ospeed = t->c_ospeed;
    820   1.1      matt 	tp->t_cflag = t->c_cflag;
    821   1.1      matt 
    822   1.1      matt 	if (!sc->sc_heldchange) {
    823   1.1      matt 		if (sc->sc_tx_busy) {
    824   1.1      matt 			sc->sc_heldtbc = sc->sc_tbc;
    825   1.1      matt 			sc->sc_tbc = 0;
    826   1.1      matt 			sc->sc_heldchange = 1;
    827   1.1      matt 		} else
    828   1.1      matt 			gtmpsc_loadchannelregs(sc);
    829   1.1      matt 	}
    830   1.1      matt 
    831   1.1      matt 	splx(s);
    832   1.1      matt 
    833   1.1      matt 	/* Fake carrier on */
    834   1.1      matt 	(void) (*tp->t_linesw->l_modem)(tp, 1);
    835   1.1      matt 
    836   1.1      matt 	return 0;
    837   1.1      matt }
    838   1.1      matt 
    839   1.1      matt STATIC int
    840   1.1      matt gtmpsc_probe(void)
    841   1.1      matt {
    842   1.1      matt 	return 1;		/* XXX */
    843   1.1      matt }
    844   1.1      matt 
    845   1.1      matt STATIC unsigned int
    846   1.1      matt gtmpsc_get_causes(void)
    847   1.1      matt {
    848   1.1      matt 	int                     i;
    849   1.1      matt 	struct gtmpsc_softc       *sc;
    850   1.1      matt 	unsigned int            cause = 0;
    851   1.1      matt 	static unsigned int     bits[4] = {
    852   1.1      matt 				SDMA_INTR_RXBUF(0),
    853   1.1      matt 				SDMA_INTR_TXBUF(0),
    854   1.1      matt 				SDMA_INTR_RXBUF(1),
    855   1.1      matt 				SDMA_INTR_TXBUF(1),
    856   1.1      matt 	};
    857   1.1      matt 	sdma_desc_t             *desc_addr[4];
    858   1.1      matt 	static unsigned int     fake_once = SDMA_INTR_RXBUF(0)
    859   1.1      matt 						| SDMA_INTR_RXBUF(1);
    860   1.1      matt 
    861   1.1      matt 	desc_addr[0] = 0;
    862   1.1      matt 	desc_addr[1] = 0;
    863   1.1      matt 	desc_addr[2] = 0;
    864   1.1      matt 	desc_addr[3] = 0;
    865  1.30    cegger 	sc = device_lookup_private(&gtmpsc_cd, 0);
    866   1.1      matt 	if (sc != 0) {
    867   1.1      matt 	    if (sdma_imask & SDMA_INTR_RXBUF(0)) {
    868   1.1      matt 		desc_addr[0] =
    869   1.1      matt 		    &sc->gtmpsc_poll_sdmapage->rx[sc->gtmpsc_poll_rxix].rxdesc;
    870   1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[0]);
    871  1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[0]));
    872   1.1      matt 	    }
    873   1.1      matt 	    if (sdma_imask & SDMA_INTR_TXBUF(0)) {
    874   1.1      matt 		desc_addr[1] =
    875   1.1      matt 		    &sc->gtmpsc_poll_sdmapage->tx[sc->gtmpsc_poll_txix].txdesc;
    876   1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[1]);
    877  1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[1]));
    878   1.1      matt 	    }
    879   1.1      matt 	}
    880  1.30    cegger 	sc = device_lookup_private(&gtmpsc_cd, 1);
    881   1.1      matt 	if (sc != 0) {
    882   1.1      matt 	    if (sdma_imask & SDMA_INTR_RXBUF(1)) {
    883   1.1      matt 		desc_addr[2] =
    884   1.1      matt 		    &sc->gtmpsc_poll_sdmapage->rx[sc->gtmpsc_poll_rxix].rxdesc;
    885   1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[2]);
    886  1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[2]));
    887   1.1      matt 	    }
    888   1.1      matt 	    if (sdma_imask & SDMA_INTR_TXBUF(1)) {
    889   1.1      matt 		desc_addr[3] =
    890   1.1      matt 		    &sc->gtmpsc_poll_sdmapage->tx[sc->gtmpsc_poll_txix].txdesc;
    891   1.1      matt 		    GTMPSC_CACHE_INVALIDATE(desc_addr[3]);
    892  1.14     perry 		    __asm volatile ("dcbt 0,%0" :: "r"(desc_addr[3]));
    893   1.1      matt 	    }
    894   1.1      matt 	}
    895   1.1      matt 
    896   1.1      matt 	for (i = 0; i < 4; ++i)
    897   1.1      matt 		if ((sdma_imask & bits[i]) && desc_addr[i] != 0 &&
    898   1.1      matt 			    (desc_addr[i]->sdma_csr & SDMA_CSR_TX_OWN) == 0)
    899   1.1      matt 			cause |= bits[i];
    900   1.1      matt 	if (fake_once & sdma_imask) {
    901   1.1      matt 		cause |= fake_once & sdma_imask;
    902   1.1      matt 	/*	fake_once &= ~(cause & fake_once); */
    903   1.1      matt 	}
    904   1.1      matt 	return cause;
    905   1.1      matt }
    906   1.1      matt 
    907   1.1      matt STATIC int
    908   1.1      matt gtmpsc_intr(void *arg)
    909   1.1      matt {
    910   1.1      matt 	struct gtmpsc_softc       *sc;
    911   1.1      matt 	unsigned int            unit;
    912   1.1      matt 	int                     spurious = 1;
    913   1.1      matt 	unsigned int            r;
    914   1.1      matt 	unsigned int            cause=0;
    915   1.1      matt 
    916   1.1      matt 	if (gt_reva_gtmpsc_bug)
    917   1.1      matt 		cause = gtmpsc_get_causes();
    918   1.1      matt 
    919   1.1      matt #ifdef KGDB
    920   1.1      matt 	if (kgdb_break_immediate) {
    921   1.1      matt 		unit = comkgdbport;
    922  1.30    cegger 		sc = device_lookup_private(&gtmpsc_cd, unit);
    923   1.1      matt 		if (sc == 0 || (sc->gtmpsc_flags & GTMPSCF_KGDB) == 0)
    924   1.1      matt 			goto skip_kgdb;
    925   1.1      matt 		if (gt_reva_gtmpsc_bug)
    926   1.1      matt 			r = cause & sdma_imask;
    927   1.1      matt 		else {
    928   1.3      matt 			r = GT_READ(sc, SDMA_ICAUSE);
    929   1.3      matt 			r &= GT_READ(sc, SDMA_IMASK);
    930   1.1      matt 		}
    931   1.1      matt 		r &= SDMA_INTR_RXBUF(unit);
    932   1.1      matt 		if (r == 0)
    933   1.1      matt 			goto skip_kgdb;
    934   1.3      matt 		GT_WRITE(sc, SDMA_ICAUSE, ~r);
    935   1.1      matt 		spurious = 0;
    936   1.1      matt 		gtmpsc_kgdb_poll(sc);
    937   1.1      matt 	}
    938   1.1      matt skip_kgdb:
    939   1.1      matt #endif
    940   1.1      matt 	for (unit = 0; unit < GTMPSC_NCHAN; ++unit) {
    941  1.30    cegger 		sc = device_lookup_private(&gtmpsc_cd, unit);
    942  1.30    cegger 		if (sc == NULL)
    943   1.1      matt 			continue;
    944   1.1      matt 		if (gt_reva_gtmpsc_bug)
    945   1.1      matt 			r = cause & sdma_imask;
    946   1.1      matt 		else {
    947   1.3      matt 			r = GT_READ(sc, SDMA_ICAUSE);
    948   1.3      matt 			r &= GT_READ(sc, SDMA_IMASK);
    949   1.1      matt 		}
    950   1.1      matt 		r &= SDMA_U_INTR_MASK(unit);
    951   1.1      matt 		if (r == 0)
    952   1.1      matt 			continue;
    953   1.3      matt 		GT_WRITE(sc, SDMA_ICAUSE, ~r);
    954   1.1      matt 		spurious = 0;
    955   1.1      matt 		if (r & SDMA_INTR_RXBUF(unit)) {
    956   1.1      matt #ifdef KGDB
    957   1.1      matt 			if (sc->gtmpsc_flags & GTMPSCF_KGDB)
    958   1.1      matt 				gtmpsc_kgdb_poll(sc);
    959   1.1      matt 			else
    960   1.1      matt #endif
    961   1.1      matt 				gtmpsc_poll(sc);
    962   1.1      matt 		}
    963   1.1      matt 		if (r & SDMA_INTR_TXBUF(unit)) {
    964   1.1      matt 			/*
    965   1.1      matt 			 * If we've delayed a parameter change, do it now,
    966   1.1      matt 			 * and restart output.
    967   1.1      matt 			 */
    968   1.1      matt 			if (sc->sc_heldchange) {
    969   1.1      matt 				gtmpsc_loadchannelregs(sc);
    970   1.1      matt 				sc->sc_heldchange = 0;
    971   1.1      matt 				sc->sc_tbc = sc->sc_heldtbc;
    972   1.1      matt 				sc->sc_heldtbc = 0;
    973   1.1      matt 			}
    974   1.1      matt 
    975   1.1      matt 			/* Output the next chunk of the contiguous buffer,
    976   1.1      matt 								if any. */
    977   1.1      matt 			if (sc->sc_tbc > 0)
    978   1.1      matt 				gtmpsc_common_putn(sc);
    979   1.1      matt 			if (sc->sc_tbc == 0 && sc->sc_tx_busy) {
    980   1.1      matt 				sc->sc_tx_busy = 0;
    981   1.1      matt 				sc->sc_tx_done = 1;
    982  1.24        ad 				softint_schedule(sc->sc_si);
    983   1.3      matt 				SDMA_IMASK_DISABLE(sc, SDMA_INTR_TXBUF(unit));
    984   1.1      matt 			}
    985   1.1      matt 		}
    986   1.1      matt 	}
    987   1.1      matt 	return 1;
    988   1.1      matt 	/* return !spurious; */
    989   1.1      matt }
    990   1.1      matt 
    991   1.3      matt STATIC void
    992   1.3      matt gtmpsc_softintr(void *arg)
    993   1.1      matt {
    994   1.3      matt 	struct gtmpsc_softc	*sc = arg;
    995   1.1      matt 	struct tty              *tp;
    996   1.2      matt 	int                     (*rint)(int, struct tty *);
    997   1.1      matt 	int                     jobs;
    998   1.1      matt 	int                     s;
    999   1.1      matt 
   1000   1.3      matt 	tp = sc->gtmpsc_tty;
   1001   1.3      matt 	rint = tp->t_linesw->l_rint;
   1002   1.3      matt 	do {
   1003   1.3      matt 		jobs = 0;
   1004   1.3      matt 		if (sc->gtmpsc_rxfifo_navail < GTMPSC_RXFIFOSZ) {
   1005   1.1      matt 			s = spltty();
   1006   1.1      matt 			rint(sc->gtmpsc_rxfifo[sc->gtmpsc_rxfifo_getix++],
   1007   1.1      matt 								tp);
   1008   1.1      matt 			if (sc->gtmpsc_rxfifo_getix >= GTMPSC_RXFIFOSZ)
   1009   1.1      matt 				sc->gtmpsc_rxfifo_getix = 0;
   1010   1.1      matt 			++sc->cnt_rx_from_fifo;
   1011   1.1      matt 			/* atomic_add() returns the previous value */
   1012   1.1      matt 			jobs += atomic_add(&sc->gtmpsc_rxfifo_navail, 1) + 1
   1013   1.1      matt 								< GTMPSC_RXFIFOSZ;
   1014   1.1      matt 			splx(s);
   1015   1.3      matt 		}
   1016   1.3      matt 		if (sc->sc_tx_done) {
   1017   1.1      matt 			++jobs;
   1018   1.1      matt 			sc->sc_tx_done = 0;
   1019   1.1      matt 			s = spltty();
   1020   1.1      matt 			tp->t_state &= ~TS_BUSY;
   1021   1.1      matt 			if ((tp->t_state & TS_FLUSH) != 0)
   1022   1.1      matt 			    tp->t_state &= ~TS_FLUSH;
   1023   1.1      matt 			else
   1024   1.1      matt 			    ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
   1025   1.1      matt 			(*tp->t_linesw->l_start)(tp);
   1026   1.1      matt 			splx(s);
   1027   1.3      matt 		}
   1028   1.3      matt 	} while (jobs);
   1029   1.1      matt }
   1030   1.1      matt 
   1031   1.1      matt /*
   1032   1.1      matt  * Console support functions
   1033   1.1      matt  */
   1034   1.1      matt void
   1035   1.1      matt gtmpsccnprobe(struct consdev *cd)
   1036   1.1      matt {
   1037   1.1      matt 	int maj;
   1038   1.1      matt /* {extern void return_to_dink(int); return_to_dink(gtbase);} */
   1039   1.1      matt 
   1040   1.1      matt 	if (!gtmpsc_probe())
   1041   1.1      matt 		return;
   1042   1.1      matt 
   1043   1.1      matt 	maj = cdevsw_lookup_major(&gtmpsc_cdevsw);
   1044   1.1      matt 	cd->cn_dev = makedev(maj, 0);
   1045   1.1      matt 	cd->cn_pri = CN_INTERNAL;
   1046   1.1      matt }
   1047   1.1      matt 
   1048   1.1      matt /*
   1049   1.1      matt  * gtmpsc_hackinit - hacks required to supprt GTMPSC console
   1050   1.1      matt  */
   1051   1.1      matt STATIC void
   1052   1.3      matt gtmpsc_hackinit(struct gtmpsc_softc *sc, bus_space_tag_t memt,
   1053   1.3      matt 	bus_space_handle_t memh, int unit)
   1054   1.1      matt {
   1055   1.1      matt 	gtmpsc_poll_sdma_t *vmps;
   1056   1.1      matt 	gtmpsc_poll_sdma_t *pmps;
   1057   1.1      matt 
   1058   1.1      matt 	DPRINTF(("hackinit\n"));
   1059   1.1      matt 
   1060  1.33    cegger 	memset(sc, 0, sizeof(struct gtmpsc_softc));
   1061   1.3      matt 	sc->gtmpsc_memt = memt;
   1062   1.3      matt 	sc->gtmpsc_memh = memh;
   1063   1.3      matt 	sc->gtmpsc_unit = unit;
   1064   1.1      matt 	gtmpsc_scp[sc->gtmpsc_unit] = sc;
   1065   1.1      matt 
   1066   1.1      matt 	vmps = (gtmpsc_poll_sdma_t *)gtmpsc_fake_dmapage;	/* KVA */
   1067   1.1      matt 	pmps = (gtmpsc_poll_sdma_t *)gtmpsc_fake_dmapage;	/* PA */
   1068   1.1      matt 
   1069   1.1      matt 	gtmpsc_txdesc_init(vmps, pmps);
   1070   1.1      matt 	gtmpsc_rxdesc_init(vmps, pmps);
   1071   1.1      matt 
   1072   1.1      matt 	sc->gtmpsc_poll_sdmapage = vmps;
   1073   1.1      matt }
   1074   1.1      matt 
   1075   1.1      matt /*
   1076   1.1      matt  * gtmpsc_txflush - wait for output to drain
   1077   1.1      matt  */
   1078   1.1      matt STATIC void
   1079   1.1      matt gtmpsc_txflush(gtmpsc_softc_t *sc)
   1080   1.1      matt {
   1081   1.1      matt 	unsigned int csr;
   1082   1.1      matt 	unsigned int *csrp;
   1083   1.1      matt 	gtmpsc_polltx_t *vtxp;
   1084   1.1      matt 	int limit = 4000000;	/* 4 seconds */
   1085   1.1      matt 	int ix;
   1086   1.1      matt 
   1087   1.1      matt 	ix = sc->gtmpsc_poll_txix - 1;
   1088   1.1      matt 	if (ix < 0)
   1089   1.1      matt 		ix = GTMPSC_NTXDESC - 1;
   1090   1.1      matt 
   1091   1.1      matt 	vtxp = &sc->gtmpsc_poll_sdmapage->tx[ix];
   1092   1.1      matt 	csrp = &vtxp->txdesc.sdma_csr;
   1093   1.1      matt 	while (limit > 0) {
   1094   1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1095   1.1      matt 		csr = desc_read(csrp);
   1096   1.1      matt 		if ((csr & SDMA_CSR_TX_OWN) == 0)
   1097   1.1      matt 			break;
   1098   1.1      matt 		DELAY(GTMPSC_POLL_DELAY);
   1099   1.1      matt 		limit -= GTMPSC_POLL_DELAY;
   1100  1.10     perry 	}
   1101   1.1      matt }
   1102   1.1      matt 
   1103   1.1      matt STATIC void
   1104   1.1      matt gtmpsc_iflush(gtmpsc_softc_t *sc)
   1105   1.1      matt {
   1106   1.1      matt 	int     timo;
   1107   1.1      matt 	char    c;
   1108   1.1      matt 	int     stat;
   1109   1.1      matt 
   1110   1.1      matt 	for (timo = 50000; timo; timo--)
   1111   1.1      matt 		if (gtmpsc_common_pollc(sc->gtmpsc_unit, &c, &stat) == 0)
   1112   1.1      matt 			return;
   1113   1.1      matt #ifdef DIAGNOSTIC
   1114  1.28    cegger 	printf("%s: gtmpsc_iflush timeout %02x\n", device_xname(&sc->gtmpsc_dev), c);
   1115   1.1      matt #endif
   1116   1.1      matt }
   1117   1.1      matt 
   1118   1.1      matt STATIC void
   1119   1.1      matt gtmpscinit_stop(struct gtmpsc_softc *sc, int once)
   1120   1.1      matt {
   1121   1.1      matt 	unsigned int r;
   1122   1.1      matt 	unsigned int unit = sc->gtmpsc_unit;
   1123   1.1      matt 
   1124   1.1      matt 	/*
   1125   1.1      matt 	 * XXX HACK FIXME
   1126   1.1      matt 	 * PMON output has not been flushed.  give him a chance
   1127   1.1      matt 	 */
   1128   1.1      matt #if 1
   1129   1.1      matt 	if (! once)
   1130   1.1      matt 		DELAY(100000);	/* XXX */
   1131   1.1      matt #endif
   1132   1.1      matt 
   1133   1.5      matt 	DPRINTF(("gtmpscinit_stop: unit 0x%x\n", unit));
   1134   1.1      matt 	if (unit >= GTMPSC_NCHAN) {
   1135   1.1      matt 		PRINTF(("mpscinit: undefined unit %d\n", sc->gtmpsc_unit));
   1136   1.1      matt 		return;
   1137   1.1      matt 	}
   1138   1.1      matt 
   1139   1.1      matt 	sc->gtmpsc_chr2 = 0;      /* Default value of CHR2 */
   1140   1.1      matt 
   1141   1.1      matt 	/*
   1142   1.1      matt 	 * stop GTMPSC unit
   1143   1.1      matt 	 */
   1144   1.1      matt 	r = sc->gtmpsc_chr2 | GTMPSC_CHR2_RXABORT|GTMPSC_CHR2_TXABORT;
   1145   1.3      matt 	GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1146   1.1      matt 
   1147   1.1      matt 	DELAY(GTMPSC_RESET_DELAY);
   1148   1.1      matt 
   1149   1.1      matt 	/*
   1150   1.1      matt 	 * abort SDMA TX, RX for GTMPSC unit
   1151   1.1      matt 	 */
   1152   1.4      matt 	GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_AR|SDMA_SDCM_AT);
   1153   1.1      matt 
   1154   1.1      matt 	if (once == 0) {
   1155   1.1      matt 		/*
   1156   1.1      matt 		 * Determine if this is the buggy GT-64260A case.
   1157   1.1      matt 		 * If this is, then most of GTMPSC and SDMA registers
   1158   1.1      matt 		 * are unreadable.
   1159   1.1      matt 		 * (They always yield -1).
   1160   1.1      matt 		 */
   1161   1.3      matt 		GT_WRITE(sc, SDMA_IMASK, 0);
   1162   1.3      matt 		r = GT_READ(sc, SDMA_IMASK);
   1163   1.1      matt 		gt_reva_gtmpsc_bug = r == ~0;
   1164   1.1      matt 		sdma_imask = 0;
   1165   1.1      matt 	}
   1166   1.7       scw 
   1167   1.7       scw 	/*
   1168   1.7       scw 	 * If Rx is disabled, we don't need to wait around for
   1169   1.7       scw 	 * abort completion.
   1170   1.7       scw 	 */
   1171   1.7       scw 	if ((GT_READ(sc, GTMPSC_U_MMCR_LO(unit)) & GTMPSC_MMCR_LO_ER) == 0)
   1172   1.7       scw 		return;
   1173   1.7       scw 
   1174   1.1      matt 	/*
   1175   1.1      matt 	 * poll for GTMPSC RX abort completion
   1176   1.1      matt 	 */
   1177   1.1      matt 	if (gt_reva_gtmpsc_bug) {
   1178   1.1      matt 		/* Sync up with the device first */
   1179   1.3      matt 		r = GT_READ(sc, GTMPSC_U_CHRN(unit, 2));
   1180   1.1      matt 		DELAY(GTMPSC_RESET_DELAY);
   1181   1.1      matt 	} else
   1182   1.1      matt 		for (;;) {
   1183   1.5      matt 			r = GT_READ(sc, GTMPSC_U_CHRN(unit, 2));
   1184   1.1      matt 			if (! (r & GTMPSC_CHR2_RXABORT))
   1185   1.1      matt 				break;
   1186   1.1      matt 		}
   1187   1.1      matt 
   1188   1.1      matt 	/*
   1189   1.1      matt 	 * poll for SDMA RX abort completion
   1190   1.1      matt 	 */
   1191   1.1      matt 	for (;;) {
   1192   1.3      matt 		r = GT_READ(sc, SDMA_U_SDCM(unit));
   1193   1.5      matt 		if (! (r & (SDMA_SDCM_AR|SDMA_SDCM_AT)))
   1194   1.1      matt 			break;
   1195   1.5      matt 		DELAY(50);
   1196   1.1      matt 	}
   1197   1.1      matt 
   1198   1.1      matt }
   1199   1.1      matt 
   1200   1.1      matt STATIC void
   1201   1.1      matt gtmpscinit_start(struct gtmpsc_softc *sc, int once)
   1202   1.1      matt {
   1203   1.1      matt 	unsigned int r;
   1204   1.1      matt 	unsigned int unit = sc->gtmpsc_unit;
   1205   1.1      matt 
   1206   1.1      matt 	/*
   1207   1.1      matt 	 * initialize softc's "current" transfer indicies & counts
   1208   1.1      matt 	 */
   1209   1.1      matt 	sc->gtmpsc_cx = 0;
   1210   1.1      matt 	sc->gtmpsc_nc = 0;
   1211   1.1      matt 	sc->gtmpsc_poll_txix = 0;
   1212   1.1      matt 	sc->gtmpsc_poll_rxix = 0;
   1213   1.1      matt 
   1214   1.1      matt 	/*
   1215   1.1      matt 	 * initialize softc's RX softintr FIFO
   1216   1.1      matt 	 */
   1217   1.1      matt 	sc->gtmpsc_rxfifo_putix = 0;
   1218   1.1      matt 	sc->gtmpsc_rxfifo_getix = 0;
   1219   1.1      matt 	sc->gtmpsc_rxfifo_navail = GTMPSC_RXFIFOSZ;
   1220   1.1      matt 	memset(&sc->gtmpsc_rxfifo[0], 0, GTMPSC_RXFIFOSZ);
   1221   1.1      matt 
   1222   1.1      matt 	/*
   1223   1.1      matt 	 * set SDMA unit port TX descriptor pointers
   1224   1.1      matt 	 * "next" pointer of last descriptor is start of ring
   1225   1.1      matt 	 */
   1226   1.1      matt 	r = desc_read(
   1227   1.5      matt 	    &sc->gtmpsc_poll_sdmapage->tx[GTMPSC_NTXDESC-1].txdesc.sdma_next);
   1228   1.3      matt 	GT_WRITE(sc, SDMA_U_SCTDP(unit), r);   /* current */
   1229   1.5      matt 	(void)GT_READ(sc, SDMA_U_SCTDP(unit));
   1230   1.3      matt 	GT_WRITE(sc, SDMA_U_SFTDP(unit), r);   /* first   */
   1231   1.5      matt 	(void)GT_READ(sc, SDMA_U_SFTDP(unit));
   1232   1.1      matt 	/*
   1233   1.1      matt 	 * set SDMA unit port RX descriptor pointer
   1234   1.1      matt 	 * "next" pointer of last descriptor is start of ring
   1235   1.1      matt 	 */
   1236   1.1      matt 	r = desc_read(
   1237   1.5      matt 	    &sc->gtmpsc_poll_sdmapage->rx[GTMPSC_NRXDESC-1].rxdesc.sdma_next);
   1238   1.3      matt 	GT_WRITE(sc, SDMA_U_SCRDP(unit), r);   /* current */
   1239   1.1      matt 
   1240   1.1      matt 	/*
   1241   1.1      matt 	 * initialize SDMA unit Configuration Register
   1242   1.1      matt 	 */
   1243   1.1      matt 	r = SDMA_SDC_BSZ_8x64|SDMA_SDC_SFM|SDMA_SDC_RFT;
   1244   1.3      matt 	GT_WRITE(sc, SDMA_U_SDC(unit), r);
   1245   1.1      matt 
   1246   1.1      matt 	/*
   1247   1.1      matt 	 * enable SDMA receive
   1248   1.1      matt 	 */
   1249   1.3      matt 	GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_ERD);
   1250   1.1      matt 
   1251   1.5      matt 	if (once == 0) {
   1252   1.1      matt 		/*
   1253   1.1      matt 		 * GTMPSC Routing:
   1254   1.1      matt 		 *	MR0 --> Serial Port 0
   1255   1.1      matt 		 *	MR1 --> Serial Port 1
   1256   1.1      matt 		 */
   1257   1.3      matt 		GT_WRITE(sc, GTMPSC_MRR, GTMPSC_MRR_RES);
   1258  1.10     perry 
   1259   1.1      matt 		/*
   1260   1.1      matt 		 * RX and TX Clock Routing:
   1261   1.1      matt 		 *      CRR0 --> BRG0
   1262   1.1      matt 		 *      CRR1 --> BRG1
   1263   1.1      matt 		 */
   1264   1.1      matt 		r = GTMPSC_CRR_BRG0 | (GTMPSC_CRR_BRG1 << GTMPSC_CRR1_SHIFT);
   1265   1.3      matt 		GT_WRITE(sc, GTMPSC_RCRR, r);
   1266   1.3      matt 		GT_WRITE(sc, GTMPSC_TCRR, r);
   1267   1.1      matt 	}
   1268   1.4      matt 	sc->gtmpsc_brg_bcr = BRG_BCR_EN | GT_MPSC_CLOCK_SOURCE |
   1269   1.4      matt 	    compute_cdv(GT_MPSC_DEFAULT_BAUD_RATE);
   1270   1.1      matt 	sc->gtmpsc_chr3 = GTMPSC_MAXIDLE(GT_MPSC_DEFAULT_BAUD_RATE);
   1271   1.1      matt 	gtmpsc_loadchannelregs(sc);
   1272   1.1      matt 
   1273   1.1      matt 	/*
   1274   1.1      matt 	 * set MPSC Protocol configuration register for GTMPSC unit
   1275   1.1      matt 	 */
   1276   1.3      matt 	GT_WRITE(sc, GTMPSC_U_MPCR(unit), GTMPSC_MPCR_CL_8);
   1277   1.1      matt 
   1278   1.1      matt 	/*
   1279   1.1      matt 	 * set MPSC LO and HI port config registers for GTMPSC unit
   1280   1.1      matt  	 */
   1281   1.1      matt 	r = GTMPSC_MMCR_LO_MODE_UART
   1282   1.1      matt 	   |GTMPSC_MMCR_LO_ET
   1283   1.1      matt 	   |GTMPSC_MMCR_LO_ER
   1284   1.1      matt 	   |GTMPSC_MMCR_LO_NLM;
   1285   1.3      matt 	GT_WRITE(sc, GTMPSC_U_MMCR_LO(unit), r);
   1286   1.1      matt 
   1287   1.1      matt 	r =
   1288   1.1      matt 	    GTMPSC_MMCR_HI_TCDV_DEFAULT
   1289   1.1      matt 	   |GTMPSC_MMCR_HI_RDW
   1290   1.1      matt 	   |GTMPSC_MMCR_HI_RCDV_DEFAULT;
   1291   1.3      matt 	GT_WRITE(sc, GTMPSC_U_MMCR_HI(unit), r);
   1292   1.1      matt 
   1293   1.1      matt 	/*
   1294   1.1      matt 	 * tell MPSC receive the Enter Hunt
   1295   1.1      matt 	 */
   1296   1.1      matt 	r = sc->gtmpsc_chr2 | GTMPSC_CHR2_EH;
   1297   1.3      matt 	GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1298   1.1      matt 
   1299   1.1      matt 	/*
   1300   1.1      matt 	 * clear any pending SDMA interrupts for this unit
   1301   1.1      matt 	 */
   1302   1.3      matt 	r = GT_READ(sc, SDMA_ICAUSE);
   1303   1.1      matt 	r &= ~SDMA_U_INTR_MASK(unit);
   1304   1.3      matt 	GT_WRITE(sc, SDMA_ICAUSE, r);	/* ??? */
   1305   1.1      matt 
   1306   1.1      matt 	DPRINTF(("gtmpscinit: OK\n"));
   1307   1.1      matt }
   1308   1.1      matt 
   1309   1.1      matt /*
   1310   1.1      matt  * gtmpscinit - prepare MPSC for operation
   1311   1.1      matt  *
   1312   1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1313   1.1      matt  */
   1314   1.1      matt STATIC void
   1315   1.1      matt gtmpscinit(struct gtmpsc_softc *sc)
   1316   1.1      matt {
   1317   1.1      matt 	static int once = 0;
   1318   1.1      matt 
   1319   1.1      matt 	gtmpscinit_stop(sc, once);
   1320   1.1      matt 	gtmpscinit_start(sc, once);
   1321   1.5      matt 	once = 1;
   1322   1.1      matt }
   1323   1.1      matt 
   1324   1.1      matt /*
   1325   1.1      matt  * gtmpsccninit - initialize the driver and the mpsc device
   1326   1.1      matt  */
   1327   1.1      matt void
   1328   1.1      matt gtmpsccninit(struct consdev *cd)
   1329   1.1      matt {
   1330   1.1      matt }
   1331   1.1      matt 
   1332   1.1      matt int
   1333   1.1      matt gtmpsccngetc(dev_t dev)
   1334   1.1      matt {
   1335   1.4      matt 	unsigned int unit = 0;
   1336   1.1      matt 	int c;
   1337  1.10     perry 
   1338   1.1      matt 	unit = GTMPSCUNIT(dev);
   1339   1.4      matt 	if (major(dev) != 0) {
   1340  1.29    cegger 		struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, unit);
   1341   1.4      matt 		if (sc == NULL)
   1342   1.4      matt 			return 0;
   1343   1.4      matt 		unit = sc->gtmpsc_unit;
   1344   1.4      matt 	}
   1345   1.1      matt 	if (unit >= GTMPSC_NCHAN)
   1346   1.1      matt 		return 0;
   1347   1.1      matt 	c = gtmpsc_common_getc(unit);
   1348   1.1      matt 
   1349   1.1      matt 	return c;
   1350   1.1      matt }
   1351   1.1      matt 
   1352   1.1      matt void
   1353   1.1      matt gtmpsccnputc(dev_t dev, int c)
   1354   1.1      matt {
   1355   1.4      matt 	unsigned int unit = 0;
   1356   1.1      matt 	char ch = c;
   1357   1.1      matt 	static int ix = 0;
   1358  1.10     perry 
   1359   1.1      matt 	if (gtmpsccninit_done == 0) {
   1360   1.1      matt 		if ((minor(dev) == 0) && (ix < sizeof(gtmpsc_earlybuf)))
   1361   1.1      matt 			gtmpsc_earlybuf[ix++] = (unsigned char)c;
   1362   1.1      matt 		return;
   1363   1.1      matt 	}
   1364   1.1      matt 
   1365   1.1      matt 	unit = GTMPSCUNIT(dev);
   1366   1.4      matt 	if (major(dev) != 0) {
   1367  1.29    cegger 		struct gtmpsc_softc *sc = device_lookup_private(&gtmpsc_cd, unit);
   1368   1.4      matt 		if (sc == NULL)
   1369   1.4      matt 			return;
   1370   1.4      matt 		unit = sc->gtmpsc_unit;
   1371   1.4      matt 	}
   1372   1.1      matt 
   1373   1.1      matt 	if (unit >= GTMPSC_NCHAN)
   1374   1.1      matt 		return;
   1375   1.4      matt 
   1376   1.1      matt 	gtmpsc_common_putc(unit, ch);
   1377   1.1      matt }
   1378   1.1      matt 
   1379   1.1      matt void
   1380   1.1      matt gtmpsccnpollc(dev_t dev, int on)
   1381   1.1      matt {
   1382   1.1      matt }
   1383   1.1      matt 
   1384   1.3      matt int
   1385   1.3      matt gtmpsccnattach(bus_space_tag_t memt, bus_space_handle_t memh, int unit,
   1386   1.3      matt 	int speed, tcflag_t tcflag)
   1387   1.3      matt {
   1388   1.3      matt 	struct gtmpsc_softc *sc = &gtmpsc_fake_softc;
   1389   1.3      matt 	unsigned char *cp;
   1390   1.3      matt 	unsigned char c;
   1391   1.3      matt 	unsigned int i;
   1392   1.3      matt 
   1393   1.4      matt 	if (gtmpsccninit_done)
   1394   1.4      matt 		return 0;
   1395   1.4      matt 
   1396   1.4      matt 	DPRINTF(("gtmpsccnattach\n"));
   1397   1.3      matt 	gtmpsc_hackinit(sc, memt, memh, unit);
   1398   1.4      matt 	DPRINTF(("gtmpscinit\n"));
   1399   1.3      matt 	gtmpscinit(sc);
   1400   1.3      matt 	gtmpsccninit_done = 1;
   1401   1.3      matt 	cp = gtmpsc_earlybuf;
   1402   1.4      matt 	strcpy(gtmpsc_earlybuf, "\r\nMPSC Lives!\r\n");
   1403   1.3      matt 	for (i=0; i < sizeof(gtmpsc_earlybuf); i++) {
   1404   1.3      matt 		c = *cp++;
   1405   1.3      matt 		if (c == 0)
   1406   1.3      matt 			break;
   1407   1.4      matt 		gtmpsc_common_putc(unit, c);
   1408   1.3      matt 	}
   1409   1.4      matt 	DPRINTF(("switching cn_tab\n"));
   1410   1.4      matt 	gtmpsc_consdev.cn_dev = makedev(0, unit);
   1411   1.4      matt 	cn_tab = &gtmpsc_consdev;
   1412   1.4      matt 	DPRINTF(("switched cn_tab!\n"));
   1413   1.3      matt 	return 0;
   1414   1.3      matt }
   1415   1.3      matt 
   1416   1.1      matt /*
   1417   1.1      matt  * gtmpsc_common_pollc - non-blocking console read
   1418   1.1      matt  *
   1419   1.1      matt  *	if there is an RX char, return it in *cp
   1420   1.1      matt  *	set *statp if Break detected
   1421   1.1      matt  *
   1422   1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1423   1.1      matt  *
   1424   1.1      matt  * return 1 if there is RX data
   1425   1.1      matt  * otherwise return 0
   1426   1.1      matt  */
   1427   1.1      matt STATIC int
   1428   1.1      matt gtmpsc_common_pollc(unsigned int unit, char *cp, int *statp)
   1429   1.1      matt {
   1430   1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_scp[unit];
   1431   1.1      matt 	gtmpsc_pollrx_t *vrxp;
   1432   1.1      matt 	unsigned int ix;
   1433   1.1      matt 	unsigned int cx;
   1434   1.1      matt 	unsigned int nc;
   1435   1.1      matt 
   1436   1.1      matt 	*statp = GTMPSC_STAT_NONE;
   1437   1.1      matt 	ix = sc->gtmpsc_poll_rxix;
   1438   1.1      matt 	nc = sc->gtmpsc_nc;
   1439   1.1      matt 	cx = sc->gtmpsc_cx;
   1440   1.1      matt 	if (nc == 0) {
   1441   1.1      matt 		unsigned int *csrp;
   1442   1.1      matt 		unsigned int csr;
   1443   1.1      matt 
   1444   1.1      matt 		vrxp = &sc->gtmpsc_poll_sdmapage->rx[ix];
   1445   1.1      matt 		csrp = &vrxp->rxdesc.sdma_csr;
   1446   1.1      matt 		cx = 0;
   1447   1.1      matt 
   1448   1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1449   1.1      matt 		csr = desc_read(csrp);
   1450   1.1      matt 		if (csr & SDMA_CSR_RX_OWN)
   1451   1.1      matt 			return 0;
   1452   1.1      matt 		if (csr & SDMA_CSR_RX_BR)
   1453   1.1      matt 			*statp = GTMPSC_STAT_BREAK;
   1454   1.1      matt 		if (csr & SDMA_CSR_RX_ES)
   1455   1.1      matt 			PRINTF(("mpsc 0 RX error, rxdesc csr 0x%x\n", csr));
   1456   1.1      matt 
   1457   1.1      matt 		nc = desc_read(&vrxp->rxdesc.sdma_cnt);
   1458   1.1      matt 		nc &= SDMA_RX_CNT_BCNT_MASK;
   1459   1.1      matt 		csr = SDMA_CSR_RX_L|SDMA_CSR_RX_F|SDMA_CSR_RX_OWN
   1460   1.1      matt 							      |SDMA_CSR_RX_EI;
   1461   1.1      matt 		if (nc == 0) {
   1462   1.1      matt 			if ((++ix) >= GTMPSC_NRXDESC)
   1463   1.1      matt 				ix = 0;
   1464   1.1      matt 			sc->gtmpsc_poll_rxix = ix;
   1465   1.1      matt 			desc_write(csrp, csr);
   1466   1.1      matt 			GTMPSC_CACHE_FLUSH(csrp);
   1467   1.1      matt 			return 0;
   1468   1.1      matt 		}
   1469  1.35   tsutsui 		memcpy(sc->gtmpsc_rxbuf, vrxp->rxbuf, nc);
   1470   1.1      matt 		desc_write(csrp, csr);
   1471   1.1      matt 		GTMPSC_CACHE_FLUSH(csrp);
   1472   1.1      matt 	}
   1473   1.1      matt 	gtmpsc_poll_pollc_cnt++;
   1474   1.1      matt 	nc--;
   1475   1.1      matt 	*cp = sc->gtmpsc_rxbuf[cx++];
   1476   1.1      matt 	if (nc == 0) {
   1477   1.1      matt 		if ((++ix) >= GTMPSC_NRXDESC)
   1478   1.1      matt 			ix = 0;
   1479   1.1      matt 		sc->gtmpsc_poll_rxix = ix;
   1480   1.1      matt 	}
   1481   1.1      matt 	sc->gtmpsc_cx = cx;
   1482   1.1      matt 	sc->gtmpsc_nc = nc;
   1483   1.1      matt 	return 1;
   1484   1.1      matt }
   1485   1.1      matt 
   1486   1.1      matt /*
   1487   1.1      matt  * gtmpsc_common_getc - polled console read
   1488   1.1      matt  *
   1489   1.1      matt  *	We copy data from the DMA buffers into a buffer in the softc
   1490   1.1      matt  *	to reduce descriptor ownership turnaround time
   1491   1.1      matt  *	MPSC can crater if it wraps descriptor rings,
   1492   1.1      matt  *	which is asynchronous and throttled only by line speed.
   1493   1.1      matt  *
   1494   1.1      matt  *	This code assumes the buffer PA==KVA
   1495   1.1      matt  *	and assumes we are called at ipl >= IPL_SERIAL
   1496   1.1      matt  */
   1497   1.1      matt STATIC int
   1498   1.1      matt gtmpsc_common_getc(unsigned int unit)
   1499   1.1      matt {
   1500   1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_scp[unit];
   1501   1.1      matt 	gtmpsc_pollrx_t *vrxp;
   1502   1.1      matt 	unsigned int ix;
   1503   1.1      matt 	unsigned int cx;
   1504   1.1      matt 	unsigned int nc;
   1505   1.8       scw 	unsigned int wdog_interval;
   1506   1.1      matt 	int c;
   1507   1.1      matt 
   1508   1.1      matt 	ix = sc->gtmpsc_poll_rxix;
   1509   1.1      matt 	nc = sc->gtmpsc_nc;
   1510   1.1      matt 	cx = sc->gtmpsc_cx;
   1511   1.8       scw 	wdog_interval = 0;
   1512   1.1      matt 	while (nc == 0) {
   1513   1.1      matt 		unsigned int *csrp;
   1514   1.1      matt 		unsigned int csr;
   1515   1.1      matt 		unsigned int r;
   1516   1.1      matt 
   1517   1.1      matt 		vrxp = &sc->gtmpsc_poll_sdmapage->rx[ix];
   1518   1.1      matt 		csrp = &vrxp->rxdesc.sdma_csr;
   1519   1.1      matt 		cx = 0;
   1520   1.1      matt 
   1521   1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1522   1.1      matt 		csr = desc_read(csrp);
   1523   1.1      matt 		if (csr & SDMA_CSR_RX_OWN) {
   1524   1.1      matt 			r = sc->gtmpsc_chr2 | GTMPSC_CHR2_CRD;
   1525   1.4      matt 			GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1526   1.1      matt 			do {
   1527   1.8       scw 				if (wdog_interval++ % 32)
   1528   1.8       scw 					gt_watchdog_service();
   1529   1.1      matt 				gtmpsc_poll_getc_miss++;
   1530   1.1      matt 				GTMPSC_CACHE_INVALIDATE(csrp);
   1531   1.4      matt 				DELAY(50);
   1532   1.1      matt 				csr = desc_read(csrp);
   1533   1.1      matt 			} while (csr & SDMA_CSR_RX_OWN);
   1534   1.8       scw 		} else
   1535   1.8       scw 		if (wdog_interval++ % 32)
   1536   1.8       scw 			gt_watchdog_service();
   1537   1.1      matt 		if (csr & SDMA_CSR_RX_ES)
   1538   1.1      matt 			PRINTF(("mpsc 0 RX error, rxdesc csr 0x%x\n", csr));
   1539   1.1      matt 
   1540   1.1      matt 		nc = desc_read(&vrxp->rxdesc.sdma_cnt);
   1541   1.1      matt 		nc &= SDMA_RX_CNT_BCNT_MASK;
   1542   1.1      matt 		if (nc) {
   1543  1.35   tsutsui 			memcpy(sc->gtmpsc_rxbuf, vrxp->rxbuf, nc);
   1544   1.1      matt 		} else {
   1545   1.1      matt 			if ((++ix) >= GTMPSC_NRXDESC)
   1546   1.1      matt 				ix = 0;
   1547   1.1      matt 			sc->gtmpsc_poll_rxix = ix;
   1548   1.1      matt 		}
   1549   1.1      matt 		csr = SDMA_CSR_RX_L|SDMA_CSR_RX_F|SDMA_CSR_RX_OWN
   1550   1.1      matt 							|SDMA_CSR_RX_EI;
   1551   1.1      matt 		desc_write(csrp, csr);
   1552   1.1      matt 		GTMPSC_CACHE_FLUSH(csrp);
   1553   1.1      matt #ifdef KGDB
   1554   1.1      matt 		if (unit == comkgdbport && gt_reva_gtmpsc_bug)
   1555   1.4      matt 			GT_WRITE(sc, SDMA_ICAUSE, ~SDMA_INTR_RXBUF(unit));
   1556   1.1      matt #endif
   1557   1.1      matt 	}
   1558   1.1      matt 	gtmpsc_poll_getc_cnt++;
   1559   1.1      matt 	nc--;
   1560   1.1      matt 	c = (int)sc->gtmpsc_rxbuf[cx++];
   1561   1.1      matt 	if (nc == 0) {
   1562   1.1      matt 		if ((++ix) >= GTMPSC_NRXDESC)
   1563   1.1      matt 			ix = 0;
   1564   1.1      matt 		sc->gtmpsc_poll_rxix = ix;
   1565   1.1      matt 	}
   1566   1.1      matt 	sc->gtmpsc_cx = cx;
   1567   1.1      matt 	sc->gtmpsc_nc = nc;
   1568   1.8       scw 	gt_watchdog_service();
   1569   1.1      matt 	return c;
   1570   1.1      matt }
   1571   1.1      matt 
   1572   1.1      matt /*
   1573   1.1      matt  * gtmpsc_common_putn - write a buffer into the hardware
   1574   1.1      matt  *
   1575   1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1576   1.1      matt  */
   1577   1.1      matt STATIC void
   1578   1.1      matt gtmpsc_common_putn(struct gtmpsc_softc *sc)
   1579   1.1      matt 
   1580   1.1      matt {
   1581   1.1      matt 	int     unit = sc->gtmpsc_unit;
   1582   1.1      matt 	int     n;
   1583   1.1      matt 	int     kick;
   1584   1.1      matt 	gtmpsc_polltx_t *vtxp;
   1585   1.1      matt 	unsigned int *csrp;
   1586   1.1      matt 	unsigned int csr;
   1587   1.1      matt 	unsigned int ix;
   1588   1.1      matt 	unsigned int sdcm;
   1589   1.1      matt 
   1590   1.1      matt 	kick = 0;
   1591   1.1      matt 	for (ix = sc->gtmpsc_poll_txix; sc->sc_tbc;) {
   1592   1.1      matt 		vtxp = &sc->gtmpsc_poll_sdmapage->tx[ix];
   1593   1.1      matt 		csrp = &vtxp->txdesc.sdma_csr;
   1594   1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1595   1.1      matt 		csr = desc_read(csrp);
   1596   1.1      matt 		if ((csr & SDMA_CSR_TX_OWN) != 0)
   1597   1.1      matt 			break;
   1598   1.1      matt 		n = sc->sc_tbc;
   1599   1.1      matt 		if (n > GTMPSC_TXBUFSZ)
   1600   1.1      matt 			n = GTMPSC_TXBUFSZ;
   1601  1.35   tsutsui 		memcpy(vtxp->txbuf, sc->sc_tba, n);
   1602   1.1      matt 		csr = SDMA_CSR_TX_L | SDMA_CSR_TX_F
   1603   1.1      matt 					| SDMA_CSR_TX_EI | SDMA_CSR_TX_OWN;
   1604   1.1      matt 		desc_write(&vtxp->txdesc.sdma_cnt,
   1605   1.1      matt 				(n << SDMA_TX_CNT_BCNT_SHIFT) | n);
   1606   1.1      matt 		desc_write(csrp, csr);
   1607   1.1      matt 		GTMPSC_CACHE_FLUSH(csrp);
   1608   1.1      matt 		sc->sc_tbc -= n;
   1609   1.1      matt 		sc->sc_tba += n;
   1610   1.1      matt 		gtmpsc_poll_putn_cnt += n;
   1611   1.1      matt 		sc->cnt_tx_to_sdma += n;
   1612   1.1      matt 		kick = 1;
   1613   1.1      matt 
   1614   1.1      matt 		if (++ix >= GTMPSC_NTXDESC)
   1615   1.1      matt 			ix = 0;
   1616   1.1      matt 	}
   1617   1.1      matt 	if (kick) {
   1618   1.1      matt 		sc->gtmpsc_poll_txix = ix;
   1619   1.1      matt 
   1620   1.1      matt 		/*
   1621   1.1      matt 		 * now kick some SDMA
   1622   1.1      matt 		 */
   1623   1.3      matt 		sdcm = GT_READ(sc, SDMA_U_SDCM(unit));
   1624   1.1      matt 
   1625   1.1      matt 		if ((sdcm & SDMA_SDCM_TXD) == 0) {
   1626   1.4      matt 			GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_TXD);
   1627   1.1      matt 		}
   1628   1.1      matt 	}
   1629   1.1      matt }
   1630   1.1      matt 
   1631   1.1      matt /*
   1632   1.1      matt  * gtmpsc_common_putc - polled console putc
   1633   1.1      matt  *
   1634   1.1      matt  *	assumes we are called at ipl >= IPL_SERIAL
   1635   1.1      matt  */
   1636   1.1      matt STATIC void
   1637   1.1      matt gtmpsc_common_putc(unsigned int unit, unsigned char c)
   1638   1.1      matt {
   1639   1.1      matt 	struct gtmpsc_softc *sc = gtmpsc_scp[unit];
   1640   1.1      matt 	gtmpsc_polltx_t *vtxp;
   1641   1.1      matt 	unsigned int *csrp;
   1642   1.1      matt 	unsigned int csr;
   1643   1.1      matt 	unsigned int ix;
   1644   1.1      matt 	unsigned int nix;
   1645   1.8       scw 	unsigned int wdog_interval = 0;
   1646   1.1      matt 
   1647   1.5      matt 	DPRINTF(("gtmpsc_common_putc(%d, '%c'): cur=%#x, first=%#x", unit, c,
   1648   1.5      matt 	    GT_READ(sc, SDMA_U_SCTDP(unit)),   /* current */
   1649   1.5      matt 	    GT_READ(sc, SDMA_U_SFTDP(unit))));   /* first   */
   1650   1.1      matt 	ix = sc->gtmpsc_poll_txix;
   1651   1.1      matt 	nix = ix + 1;
   1652   1.1      matt 	if (nix >= GTMPSC_NTXDESC)
   1653   1.1      matt 		nix = 0;
   1654   1.1      matt 	sc->gtmpsc_poll_txix = nix;
   1655   1.1      matt 	vtxp = &sc->gtmpsc_poll_sdmapage->tx[ix];
   1656   1.1      matt 	csrp = &vtxp->txdesc.sdma_csr;
   1657   1.1      matt 
   1658   1.5      matt 
   1659   1.1      matt 	for (;;) {
   1660   1.1      matt 		GTMPSC_CACHE_INVALIDATE(csrp);
   1661   1.1      matt 		csr = desc_read(csrp);
   1662   1.1      matt 		if ((csr & SDMA_CSR_TX_OWN) == 0)
   1663   1.1      matt 			break;
   1664   1.1      matt 		gtmpsc_poll_putc_miss++;
   1665   1.5      matt 		DELAY(40);
   1666   1.5      matt 		DPRINTF(("."));
   1667   1.8       scw 		if (wdog_interval++ % 32)
   1668   1.8       scw 			gt_watchdog_service();
   1669   1.1      matt 	}
   1670   1.1      matt 	if (csr & SDMA_CSR_TX_ES)
   1671   1.5      matt 		PRINTF(("mpsc %d TX error, txdesc csr 0x%x\n", unit, csr));
   1672   1.1      matt 
   1673   1.1      matt 	gtmpsc_poll_putc_cnt++;
   1674   1.1      matt 	vtxp->txbuf[0] = c;
   1675   1.5      matt 	csr = SDMA_CSR_TX_L | SDMA_CSR_TX_F | SDMA_CSR_TX_EI | SDMA_CSR_TX_OWN;
   1676   1.1      matt 	desc_write(&vtxp->txdesc.sdma_cnt, (1 << SDMA_TX_CNT_BCNT_SHIFT) | 1);
   1677   1.1      matt 	desc_write(csrp, csr);
   1678   1.1      matt 	GTMPSC_CACHE_FLUSH(csrp);
   1679   1.1      matt 
   1680   1.1      matt 	/*
   1681   1.1      matt 	 * now kick some SDMA
   1682   1.1      matt 	 */
   1683   1.5      matt 	GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_TXD);
   1684   1.8       scw 	gt_watchdog_service();
   1685   1.1      matt }
   1686   1.1      matt 
   1687   1.1      matt 
   1688   1.1      matt STATIC void
   1689   1.1      matt gtmpsc_poll(void *arg)
   1690   1.1      matt {
   1691   1.1      matt 	struct gtmpsc_softc *sc = (struct gtmpsc_softc *)arg;
   1692   1.1      matt 	int kick;
   1693   1.1      matt 	char ch;
   1694   1.1      matt 	int stat;
   1695   1.1      matt 	static struct timeval   msg_time = {0,0};
   1696   1.1      matt 	static struct timeval   cur_time;
   1697   1.1      matt 	static int fifo_full = 0;
   1698   1.1      matt 
   1699   1.1      matt 	kick = 0;
   1700   1.1      matt 	while (gtmpsc_common_pollc(sc->gtmpsc_unit, &ch, &stat)) {
   1701   1.1      matt #ifdef DDB
   1702   1.1      matt 		if (stat)
   1703   1.1      matt 			break;
   1704   1.1      matt #endif
   1705   1.1      matt 		++sc->cnt_rx_from_sdma;
   1706   1.1      matt 		if (sc->gtmpsc_rxfifo_navail != 0) {
   1707   1.1      matt 			sc->gtmpsc_rxfifo[sc->gtmpsc_rxfifo_putix++] = ch;
   1708   1.1      matt 			if (sc->gtmpsc_rxfifo_putix == GTMPSC_RXFIFOSZ)
   1709   1.1      matt 				sc->gtmpsc_rxfifo_putix = 0;
   1710   1.1      matt 			atomic_add(&sc->gtmpsc_rxfifo_navail, -1);
   1711   1.1      matt 			++sc->cnt_rx_to_fifo;
   1712   1.1      matt 			fifo_full = 0;
   1713   1.1      matt 			kick = 1;
   1714   1.1      matt 		} else {
   1715   1.1      matt 			if (fifo_full == 0) {
   1716   1.1      matt 				fifo_full = 1;
   1717   1.1      matt 				microtime(&cur_time);
   1718   1.1      matt 				if (cur_time.tv_sec - msg_time.tv_sec >= 5) {
   1719   1.1      matt 					/* Only do this once in 5 sec */
   1720   1.1      matt 					msg_time = cur_time;
   1721   1.1      matt 					printf("mpsc%d: input FIFO full, "
   1722   1.1      matt 					       "dropping incoming characters\n",
   1723   1.1      matt 					       sc->gtmpsc_unit);
   1724   1.1      matt 				}
   1725   1.1      matt 			}
   1726   1.1      matt 		}
   1727   1.1      matt 	}
   1728   1.1      matt #ifdef DDB
   1729   1.1      matt 	if (stat) {
   1730   1.4      matt 		if (cn_tab == &gtmpsc_consdev) {
   1731   1.1      matt 			Debugger();
   1732   1.4      matt 		}
   1733   1.1      matt 	}
   1734   1.1      matt #endif
   1735   1.1      matt 	if (kick)
   1736  1.24        ad 		softint_schedule(sc->sc_si);
   1737   1.1      matt }
   1738   1.1      matt 
   1739   1.1      matt #ifdef KGDB
   1740   1.1      matt /* ARGSUSED */
   1741   1.1      matt STATIC int
   1742  1.32       dsl gtmpsc_kgdb_getc(void *arg)
   1743   1.1      matt {
   1744   1.1      matt 
   1745   1.1      matt 	return (gtmpsc_common_getc(comkgdbport));
   1746   1.1      matt }
   1747   1.1      matt 
   1748   1.1      matt /* ARGSUSED */
   1749   1.1      matt STATIC void
   1750  1.32       dsl gtmpsc_kgdb_putc(void *arg, int c)
   1751   1.1      matt {
   1752   1.1      matt 
   1753   1.1      matt 	return (gtmpsc_common_putc(comkgdbport, c));
   1754   1.1      matt }
   1755   1.1      matt 
   1756   1.1      matt STATIC void
   1757   1.1      matt gtmpsc_kgdb_poll(void *arg)
   1758   1.1      matt {
   1759   1.1      matt 	struct gtmpsc_softc       *sc = (struct gtmpsc_softc *)arg;
   1760   1.1      matt 	int                     s;
   1761   1.1      matt 	char                    c;
   1762   1.1      matt 	int                     brk;
   1763   1.1      matt 
   1764  1.10     perry 	s = splserial();
   1765   1.1      matt 	if (kgdb_recover == 0) { /* gdb is not currently talking to its agent */
   1766   1.1      matt 		while (gtmpsc_common_pollc(sc->gtmpsc_unit, &c, &brk)) {
   1767   1.1      matt 			if (c == CTRL('c'))
   1768   1.1      matt 				brk = GTMPSC_STAT_BREAK;
   1769   1.1      matt 			if (brk == GTMPSC_STAT_BREAK)
   1770   1.1      matt 				break;
   1771   1.1      matt 		}
   1772   1.1      matt 		if (brk == GTMPSC_STAT_BREAK) {
   1773   1.1      matt 			if (kgdb_break_immediate)
   1774   1.1      matt 				breakpoint();
   1775   1.1      matt 			else {
   1776   1.1      matt 				printf("connecting to kgdb\n");
   1777   1.1      matt 				kgdb_connect(1);
   1778   1.1      matt 			}
   1779   1.1      matt 		}
   1780   1.1      matt 	}
   1781   1.1      matt 	splx(s);
   1782   1.1      matt }
   1783   1.1      matt 
   1784   1.1      matt #endif /* KGDB */
   1785   1.1      matt 
   1786   1.2      matt #if 0
   1787   1.1      matt void
   1788   1.1      matt gtmpsc_printf(const char *fmt, ...)
   1789   1.1      matt {
   1790   1.1      matt 	struct consdev *ocd;
   1791   1.1      matt 	int s;
   1792   1.1      matt 	va_list ap;
   1793   1.1      matt 
   1794   1.1      matt 	s = splserial();
   1795   1.1      matt 	ocd = cn_tab;
   1796   1.1      matt 	cn_tab = &constab[0];
   1797   1.1      matt 	va_start(ap, fmt);
   1798   1.1      matt 	printf(fmt, ap);
   1799   1.1      matt 	va_end(ap);
   1800   1.1      matt 	cn_tab = ocd;
   1801   1.1      matt 	splx(s);
   1802   1.1      matt }
   1803   1.2      matt #endif
   1804   1.1      matt 
   1805   1.1      matt void
   1806   1.1      matt gtmpsc_mem_printf(const char *fmt, ...)
   1807   1.1      matt {
   1808   1.1      matt 	va_list ap;
   1809   1.1      matt 	static unsigned char *p = gtmpsc_print_buf;
   1810   1.1      matt 
   1811   1.1      matt 	if (p >= &gtmpsc_print_buf[GTMPSC_PRINT_BUF_SIZE - 128]) {
   1812  1.33    cegger 		memset(gtmpsc_print_buf, 0, GTMPSC_PRINT_BUF_SIZE);
   1813   1.1      matt 		p = gtmpsc_print_buf;
   1814   1.1      matt 	}
   1815   1.1      matt 	va_start(ap, fmt);
   1816   1.1      matt 	p += vsprintf(p, fmt, ap);
   1817   1.1      matt 	va_end(ap);
   1818   1.1      matt }
   1819   1.1      matt 
   1820   1.1      matt void
   1821   1.1      matt gtmpsc_shutdownhook(void *arg)
   1822   1.1      matt {
   1823   1.1      matt 	gtmpsc_softc_t *sc = (gtmpsc_softc_t *)arg;
   1824   1.1      matt 
   1825   1.1      matt 	gtmpsc_txflush(sc);
   1826   1.1      matt }
   1827   1.1      matt 
   1828   1.1      matt void
   1829   1.1      matt gtmpsccnhalt(dev_t dev)
   1830   1.1      matt {
   1831   1.1      matt 	unsigned int unit;
   1832   1.1      matt 	u_int32_t r;
   1833   1.1      matt 
   1834   1.1      matt 	for (unit = 0; unit < GTMPSC_NCHAN; unit++) {
   1835   1.4      matt 		gtmpsc_softc_t *sc = gtmpsc_scp[unit];
   1836   1.1      matt 		if (sc == NULL)
   1837   1.1      matt 			continue;
   1838   1.1      matt 
   1839   1.1      matt 		/*
   1840   1.1      matt 		 * flush TX buffers
   1841   1.1      matt 		 */
   1842   1.1      matt 		gtmpsc_txflush(sc);
   1843   1.1      matt 
   1844   1.1      matt 		/*
   1845  1.10     perry 		 * stop MPSC unit RX
   1846   1.1      matt 		 */
   1847   1.3      matt 		r = GT_READ(sc, GTMPSC_U_CHRN(unit, 2));
   1848   1.1      matt 		r &= ~GTMPSC_CHR2_EH;
   1849   1.1      matt 		r |= GTMPSC_CHR2_RXABORT;
   1850   1.3      matt 		GT_WRITE(sc, GTMPSC_U_CHRN(unit, 2), r);
   1851   1.1      matt 
   1852   1.1      matt 		DELAY(GTMPSC_RESET_DELAY);
   1853   1.1      matt 
   1854   1.1      matt 		/*
   1855   1.1      matt 		 * abort SDMA RX for MPSC unit
   1856   1.1      matt 		 */
   1857   1.4      matt 		GT_WRITE(sc, SDMA_U_SDCM(unit), SDMA_SDCM_AR);
   1858   1.1      matt 	}
   1859   1.1      matt }
   1860   1.1      matt 
   1861   1.1      matt void
   1862   1.1      matt gtmpsc_puts(char *str)
   1863   1.1      matt {
   1864   1.1      matt 	char c;
   1865   1.1      matt 
   1866   1.1      matt 	if (str == NULL)
   1867   1.1      matt 		return;
   1868   1.1      matt 	while ((c = *str++) != 0)
   1869   1.1      matt 		gtmpsccnputc(0, c);
   1870   1.1      matt }
   1871