Exemplo n.º 1
0
int
xenconscn_getc(dev_t dev)
{
    char c;
    int s = spltty();
    XENCONS_RING_IDX cons, prod;

    if (xencons_console_device && xencons_console_device->polling == 0) {
        printf("xenconscn_getc() but not polling\n");
        splx(s);
        return 0;
    }
    if (xendomain_is_dom0()) {
        while (HYPERVISOR_console_io(CONSOLEIO_read, 1, &c) == 0)
            ;
        cn_check_magic(dev, c, xencons_cnm_state);
        splx(s);
        return c;
    }
    if (xencons_console_device == NULL) {
        printf("xenconscn_getc(): not console\n");
        while (1)
            ;  /* loop here instead of in ddb */
        splx(s);
        return 0;
    }

    if (xencons_console_device->polling == 0) {
        printf("xenconscn_getc() but not polling\n");
        splx(s);
        return 0;
    }

    cons = xencons_interface->in_cons;
    prod = xencons_interface->in_prod;
    xen_rmb();
    while (cons == prod) {
        HYPERVISOR_yield();
        prod = xencons_interface->in_prod;
    }
    xen_rmb();
    c = xencons_interface->in[MASK_XENCONS_IDX(xencons_interface->in_cons,
                              xencons_interface->in)];
    xen_rmb();
    xencons_interface->in_cons = cons + 1;
    cn_check_magic(dev, c, xencons_cnm_state);
    splx(s);
    return c;
}
Exemplo n.º 2
0
void
xencons_tty_input(struct xencons_softc *sc, char* buf, int len)
{
    struct tty *tp;
    int i;

    tp = sc->sc_tty;
    if (tp == NULL)
        return;

    for (i = 0; i < len; i++) {
        cn_check_magic(sc->sc_tty->t_dev, buf[i], xencons_cnm_state);
        (*tp->t_linesw->l_rint)(buf[i], tp);
    }
}
Exemplo n.º 3
0
static void 
pcons_poll(void *aux)
{
	struct pconssoftc *sc = aux;
	struct tty *tp = sc->of_tty;
	int c;
	char ch;
	
	while ((c = prom_peekchar()) >= 0) {
		ch = c;
		cn_check_magic(tp->t_dev, ch, pcons_cnm_state);
		if (tp && (tp->t_state & TS_ISOPEN))
			(*tp->t_linesw->l_rint)(ch, tp);
	}
	callout_reset(&sc->sc_poll_ch, 1, pcons_poll, sc);
}
Exemplo n.º 4
0
/*
 * Console kernel output character routine.
 */
void
sscomcnputc(dev_t dev, int c)
{
	int s = splserial();
	int timo;

	int cin;
	int __attribute__((__unused__)) stat;
	if (sscom_readaheadcount < MAX_READAHEAD && 
	    sscom_rxrdy(sscomconstag, sscomconsioh)) {
	    
		int __attribute__((__unused__))cn_trapped = 0;
		cin = sscom_getc(sscomconstag, sscomconsioh);
		stat = sscom_geterr(sscomconstag, sscomconsioh);
		cn_check_magic(dev, cin, sscom_cnm_state);
		sscom_readahead[sscom_readaheadcount++] = cin;
	}
int
at91usart_cn_getc(dev_t dev)
{
	int			c, sr;
	int			s;
#if 0
	bus_space_tag_t		iot = usart_cn_sc.sc_iot;
	bus_space_handle_t	ioh = usart_cn_sc.sc_ioh;
#endif

        s = spltty();

	while ((c = USART_PEEKC()) == -1) {
	  splx(s);
	  s = spltty();
	}
		;
	sr = USARTREG(USART_SR);
	if (ISSET(sr, USART_SR_FRAME) && c == 0) {
		USARTREG(USART_CR) = USART_CR_RSTSTA;	// reset status bits
		c = CNC_BREAK;
	}
#ifdef DDB
	extern int db_active;
	if (!db_active)
#endif
	{
		int cn_trapped = 0; /* unused */

		cn_check_magic(dev, c, at91usart_cnm_state);
	}
	splx(s);

	c &= 0xff;

	return (c);
}
Exemplo n.º 6
0
int
sscomcngetc(dev_t dev)
{
	int s = splserial();
	u_char __attribute__((__unused__)) stat;
	u_char c;

	/* got a character from reading things earlier */
	if (sscom_readaheadcount > 0) {
		int i;

		c = sscom_readahead[0];
		for (i = 1; i < sscom_readaheadcount; i++) {
			sscom_readahead[i-1] = sscom_readahead[i];
		}
		sscom_readaheadcount--;
		splx(s);
		return c;
	}

	/* block until a character becomes available */
	while (!sscom_rxrdy(sscomconstag, sscomconsioh))
		;

	c = sscom_getc(sscomconstag, sscomconsioh);
	stat = sscom_geterr(sscomconstag, sscomconsioh);
	{
		int __attribute__((__unused__))cn_trapped = 0;
#ifdef DDB
		extern int db_active;
		if (!db_active)
#endif
			cn_check_magic(dev, c, sscom_cnm_state);
	}
	splx(s);
	return c;
}
Exemplo n.º 7
0
static int
dbgu_intr(void* arg)
{
	struct at91dbgu_softc *sc = arg;
#if 0
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;
#endif
	u_char *put, *end;
	u_int cc;
	uint32_t imr, sr;
	int c = 0;
	imr = DBGUREG(DBGU_IMR);
#if 0
	if (!imr)
		return 0;
#endif
	sr = DBGUREG(DBGU_SR);
	if (!(sr & imr)) {
		if (sr & DBGU_SR_RXRDY) {
//			printf("sr=0x%08x imr=0x%08x\n", sr, imr);
		}
		return 0;
	}

	end = sc->sc_ebuf;
	put = sc->sc_rbput;
	cc = sc->sc_rbavail;

	// ok, we DO have some interrupts to serve!
	if (sr & DBGU_SR_RXRDY) {
		int cn_trapped = 0;

		c = DBGUREG(DBGU_RHR);
		if (ISSET(sr, (DBGU_SR_OVRE | DBGU_SR_FRAME | DBGU_SR_PARE)))
			DBGUREG(DBGU_CR) = DBGU_CR_RSTSTA;
		if (ISSET(sr, DBGU_SR_FRAME) && c == 0) {
			c = CNC_BREAK;
		}
#ifdef DDB
		extern int db_active;
		if (!db_active)
#endif
			cn_check_magic(cn_tab->cn_dev, c, at91dbgu_cnm_state);
		if (!cn_trapped && cc) {
			put[0] = c & 0xff;
			put[1] = sr & 0xff;
			put += 2;
			if (put >= end)
				put = sc->sc_rbuf;
			cc--;
			/*
			 * Current string of incoming characters ended because
			 * no more data was available or we ran out of space.
			 * Schedule a receive event if any data was received.
			 * If we're out of space, turn off receive interrupts.
			 */
			sc->sc_rbput = put;
			sc->sc_rbavail = cc;
			if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
				sc->sc_rx_ready = 1;

			/*
			 * See if we are in danger of overflowing a buffer. If
			 * so, use hardware flow control to ease the pressure.
			 */

			/* but at91dbgu cannot (yet). X-( */

			/*
			 * If we're out of space, disable receive interrupts
			 * until the queue has drained a bit.
			 */
			if (!cc) {
				SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
			}
		}
	}

	/*
	 * Done handling any receive interrupts. See if data can be
	 * transmitted as well. Schedule tx done event if no data left
	 * and tty was marked busy.
	 */

	if (ISSET(sr, DBGU_SR_TXRDY) && sc->sc_tbc > 0) {
		/* Output the next chunk of the contiguous buffer, if any. */
		at91dbgu_filltx(sc);
	} else {
		/* Disable transmit completion interrupts if necessary. */
		DBGUREG(DBGU_IDR) = DBGU_INT_TXRDY;
		if (sc->sc_tx_busy) {
			sc->sc_tx_busy = 0;
			sc->sc_tx_done = 1;
		}
	}

	/* Wake up the poller. */
	softint_schedule(sc->sc_si);
#if 0
#ifdef RND_COM
	rnd_add_uint32(&sc->rnd_source, imr ^ sr ^ c);
#endif
#endif

	return (1);
}
Exemplo n.º 8
0
int
sabtty_intr(struct sabtty_softc *sc, int *needsoftp)
{
	uint8_t isr0, isr1;
	int i, len = 0, needsoft = 0, r = 0, clearfifo = 0;

	isr0 = SAB_READ(sc, SAB_ISR0);
	isr1 = SAB_READ(sc, SAB_ISR1);

	if (isr0 || isr1)
		r = 1;

	if (isr0 & SAB_ISR0_RPF) {
		len = 32;
		clearfifo = 1;
	}
	if (isr0 & SAB_ISR0_TCD) {
		len = (32 - 1) & SAB_READ(sc, SAB_RBCL);
		clearfifo = 1;
	}
	if (isr0 & SAB_ISR0_TIME) {
		sabtty_cec_wait(sc);
		SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD);
	}
	if (isr0 & SAB_ISR0_RFO) {
		sc->sc_flags |= SABTTYF_RINGOVERFLOW;
		clearfifo = 1;
	}
	if (len != 0) {
		uint8_t *ptr, b;

		ptr = sc->sc_rput;
		for (i = 0; i < len; i++) {
			b = SAB_READ(sc, SAB_RFIFO);
			if (i % 2 == 0) /* skip status byte */
				cn_check_magic(sc->sc_tty->t_dev,
					       b, sabtty_cnm_state);
			*ptr++ = b;
			if (ptr == sc->sc_rend)
				ptr = sc->sc_rbuf;
			if (ptr == sc->sc_rget) {
				if (ptr == sc->sc_rbuf)
					ptr = sc->sc_rend;
				ptr--;
				sc->sc_flags |= SABTTYF_RINGOVERFLOW;
			}
		}
		sc->sc_rput = ptr;
		needsoft = 1;
	}

	if (clearfifo) {
		sabtty_cec_wait(sc);
		SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC);
	}

	if (isr0 & SAB_ISR0_CDSC) {
		sc->sc_flags |= SABTTYF_CDCHG;
		needsoft = 1;
	}

	if (isr1 & SAB_ISR1_BRKT)
		cn_check_magic(sc->sc_tty->t_dev,
			       CNC_BREAK, sabtty_cnm_state);

	if (isr1 & (SAB_ISR1_XPR | SAB_ISR1_ALLS)) {
		if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_XFW) &&
		    (sc->sc_flags & SABTTYF_STOP) == 0) {
			if (sc->sc_txc < 32)
				len = sc->sc_txc;
			else
				len = 32;

			if (len > 0) {
				SAB_WRITE_BLOCK(sc, SAB_XFIFO, sc->sc_txp, len);
				sc->sc_txp += len;
				sc->sc_txc -= len;

				sabtty_cec_wait(sc);
				SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XF);

				/*
				 * Prevent the false end of xmit from
				 * confusing things below.
				 */
				isr1 &= ~SAB_ISR1_ALLS;
			}
		}

		if ((sc->sc_txc == 0) || (sc->sc_flags & SABTTYF_STOP)) {
			if ((sc->sc_imr1 & SAB_IMR1_XPR) == 0) {
				sc->sc_imr1 |= SAB_IMR1_XPR;
				sc->sc_imr1 &= ~SAB_IMR1_ALLS;
				SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
			}
		}
	}

	if ((isr1 & SAB_ISR1_ALLS) && ((sc->sc_txc == 0) ||
	    (sc->sc_flags & SABTTYF_STOP))) {
		if (sc->sc_flags & SABTTYF_TXDRAIN)
			wakeup(sc);
		sc->sc_flags &= ~SABTTYF_STOP;
		sc->sc_flags |= SABTTYF_DONE;
		sc->sc_imr1 |= SAB_IMR1_ALLS;
		SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
		needsoft = 1;
	}

	if (needsoft)
		*needsoftp = needsoft;
	return (r);
}
Exemplo n.º 9
0
int
sscomrxintr(void *arg)
{
	struct sscom_softc *sc = arg;
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;
	u_char *put, *end;
	u_int cc;

	if (SSCOM_ISALIVE(sc) == 0)
		return 0;

	SSCOM_LOCK(sc);

	end = sc->sc_ebuf;
	put = sc->sc_rbput;
	cc = sc->sc_rbavail;

	do {
		u_char	msts, delta;
		u_char  uerstat;
		uint32_t ufstat;

		ufstat = bus_space_read_4(iot, ioh, SSCOM_UFSTAT);

		/* XXX: break interrupt with no character? */

		if ( (ufstat & (UFSTAT_RXCOUNT|UFSTAT_RXFULL)) &&
		    !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {

			while (cc > 0) {
				int cn_trapped = 0;

				/* get status and received character.
				   read status register first */
				uerstat = sscom_geterr(iot, ioh);
				put[0] = sscom_getc(iot, ioh);

				if (ISSET(uerstat, UERSTAT_BREAK)) {
					int con_trapped = 0;
					cn_check_magic(sc->sc_tty->t_dev,
					    CNC_BREAK, sscom_cnm_state);
					if (con_trapped)
						continue;
#if defined(KGDB)
					if (ISSET(sc->sc_hwflags,
					    SSCOM_HW_KGDB)) {
						kgdb_connect(1);
						continue;
					}
#endif
				}

				put[1] = uerstat;
				cn_check_magic(sc->sc_tty->t_dev,
					       put[0], sscom_cnm_state);
				if (!cn_trapped) {
					put += 2;
					if (put >= end)
						put = sc->sc_rbuf;
					cc--;
				}

				ufstat = bus_space_read_4(iot, ioh, SSCOM_UFSTAT);
				if ( (ufstat & (UFSTAT_RXFULL|UFSTAT_RXCOUNT)) == 0 )
					break;
			}

			/*
			 * Current string of incoming characters ended because
			 * no more data was available or we ran out of space.
			 * Schedule a receive event if any data was received.
			 * If we're out of space, turn off receive interrupts.
			 */
			sc->sc_rbput = put;
			sc->sc_rbavail = cc;
			if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
				sc->sc_rx_ready = 1;

			/*
			 * See if we are in danger of overflowing a buffer. If
			 * so, use hardware flow control to ease the pressure.
			 */
			if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
			    cc < sc->sc_r_hiwat) {
				SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
				sscom_hwiflow(sc);
			}

			/*
			 * If we're out of space, disable receive interrupts
			 * until the queue has drained a bit.
			 */
			if (!cc) {
				SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
				sscom_disable_rxint(sc);
				sc->sc_ucon &= ~UCON_ERRINT;
				bus_space_write_4(iot, ioh, SSCOM_UCON, sc->sc_ucon);
			}
		}


		msts = sc->sc_read_modem_status(sc);
		delta = msts ^ sc->sc_msts;
		sc->sc_msts = msts;

#ifdef notyet
		/*
		 * Pulse-per-second (PSS) signals on edge of DCD?
		 * Process these even if line discipline is ignoring DCD.
		 */
		if (delta & sc->sc_ppsmask) {
			struct timeval tv;
		    	if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) {
				/* XXX nanotime() */
				microtime(&tv);
				TIMEVAL_TO_TIMESPEC(&tv, 
				    &sc->ppsinfo.assert_timestamp);
				if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
					timespecadd(&sc->ppsinfo.assert_timestamp,
					    &sc->ppsparam.assert_offset,
						    &sc->ppsinfo.assert_timestamp);
				}

#ifdef PPS_SYNC
				if (sc->ppsparam.mode & PPS_HARDPPSONASSERT)
					hardpps(&tv, tv.tv_usec);
#endif
				sc->ppsinfo.assert_sequence++;
				sc->ppsinfo.current_mode = sc->ppsparam.mode;

			} else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) {
				/* XXX nanotime() */
				microtime(&tv);
				TIMEVAL_TO_TIMESPEC(&tv, 
				    &sc->ppsinfo.clear_timestamp);
				if (sc->ppsparam.mode & PPS_OFFSETCLEAR) {
					timespecadd(&sc->ppsinfo.clear_timestamp,
					    &sc->ppsparam.clear_offset,
					    &sc->ppsinfo.clear_timestamp);
				}

#ifdef PPS_SYNC
				if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR)
					hardpps(&tv, tv.tv_usec);
#endif
				sc->ppsinfo.clear_sequence++;
				sc->ppsinfo.current_mode = sc->ppsparam.mode;
			}
		}
#endif

		/*
		 * Process normal status changes
		 */
		if (ISSET(delta, sc->sc_msr_mask)) {
			SET(sc->sc_msr_delta, delta);

			/*
			 * Stop output immediately if we lose the output
			 * flow control signal or carrier detect.
			 */
			if (ISSET(~msts, sc->sc_msr_mask)) {
				sc->sc_tbc = 0;
				sc->sc_heldtbc = 0;
#ifdef SSCOM_DEBUG
				if (sscom_debug)
					sscomstatus(sc, "sscomintr  ");
#endif
			}

			sc->sc_st_check = 1;
		}

		/* 
		 * Done handling any receive interrupts. 
		 */

		/*
		 * If we've delayed a parameter change, do it
		 * now, and restart * output.
		 */
		if ((ufstat & UFSTAT_TXCOUNT) == 0) {
			/* XXX: we should check transmitter empty also */

			if (sc->sc_heldchange) {
				sscom_loadchannelregs(sc);
				sc->sc_heldchange = 0;
				sc->sc_tbc = sc->sc_heldtbc;
				sc->sc_heldtbc = 0;
			}
		}


	} while (0);

	SSCOM_UNLOCK(sc);

	/* Wake up the poller. */
	softint_schedule(sc->sc_si);

#ifdef RND_COM
	rnd_add_uint32(&sc->rnd_source, iir | rsr);
#endif

	return 1;
}
Exemplo n.º 10
0
STATIC void
gtmpsc_intr_rx(struct gtmpsc_softc *sc)
{
	gtmpsc_pollrx_t *vrxp;
	uint32_t csr;
	int kick, ix;

	kick = 0;

	/* already handled in gtmpsc_common_getc() */
	if (sc->sc_rcvdrx == sc->sc_rcvrx)
		return;

	ix = sc->sc_rcvdrx;
	vrxp = &sc->sc_poll_sdmapage->rx[ix];
	bus_dmamap_sync(sc->sc_dmat, sc->sc_txdma_map,
	    ix * sizeof(gtmpsc_pollrx_t),
	    sizeof(sdma_desc_t),
	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
	csr = vrxp->rxdesc.sdma_csr;
	while (!(csr & SDMA_CSR_RX_OWN)) {
		bus_dmamap_sync(sc->sc_dmat, sc->sc_rxdma_map,
		    ix * sizeof(gtmpsc_pollrx_t) + sizeof(sdma_desc_t),
		    sizeof(vrxp->rxbuf),
		    BUS_DMASYNC_POSTREAD);
		vrxp->rxdesc.sdma_cnt &= SDMA_RX_CNT_BCNT_MASK;
		if (vrxp->rxdesc.sdma_csr & SDMA_CSR_RX_BR) {
			int cn_trapped = 0;

			cn_check_magic(sc->sc_tty->t_dev,
			    CNC_BREAK, gtmpsc_cnm_state);
			if (cn_trapped)
				continue;
#if defined(KGDB) && !defined(DDB)
			if (ISSET(sc->sc_flags, GTMPSC_KGDB)) {
				kgdb_connect(1);
				continue;
			}
#endif
		}

		sc->sc_rcvcnt += vrxp->rxdesc.sdma_cnt;
		kick = 1;

		ix = (ix + 1) % GTMPSC_NTXDESC;
		vrxp = &sc->sc_poll_sdmapage->rx[ix];
		bus_dmamap_sync(sc->sc_dmat, sc->sc_txdma_map,
		    ix * sizeof(gtmpsc_pollrx_t),
		    sizeof(sdma_desc_t),
		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
		csr = vrxp->rxdesc.sdma_csr;
	}
	bus_dmamap_sync(sc->sc_dmat, sc->sc_txdma_map,
	    ix * sizeof(gtmpsc_pollrx_t),
	    sizeof(sdma_desc_t),
	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);

	if (kick) {
		sc->sc_rcvdrx = ix;
		sc->sc_rx_ready = 1;
		softint_schedule(sc->sc_si);
	}
}