Exemplo n.º 1
0
/*
 * drain on-chip fifo
 */
void
zs_iflush(struct zs_chanstate *cs)
{
	uint8_t c, rr0, rr1;
	int i;

	/*
	 * Count how many times we loop. Some systems, such as some
	 * Apple PowerBooks, claim to have SCC's which they really don't.
	 */
	for (i = 0; i < 32; i++) {
		/* Is there input available? */
		rr0 = zs_read_csr(cs);
		if ((rr0 & ZSRR0_RX_READY) == 0)
			break;

		/*
		 * First read the status, because reading the data
		 * destroys the status of this char.
		 */
		rr1 = zs_read_reg(cs, 1);
		c = zs_read_data(cs);

		if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
			/* Clear the receive error. */
			zs_write_csr(cs, ZSWR0_RESET_ERRORS);
		}
	}
}
Exemplo n.º 2
0
void
zskbd_rxint(struct zs_chanstate *cs)
{
	struct zskbd_softc     *sc = cs->cs_private;
	struct zskbd_devconfig *dc = sc->sc_dc;
	uint8_t			c, r;

	/* clear errors */
	r = zs_read_reg(cs, 1);
	if (r & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
		zs_write_csr(cs, ZSWR0_RESET_ERRORS);

	/* read byte and append to our queue */
	c = zs_read_data(cs);

	dc->rxq[dc->rxq_tail] = c;
	dc->rxq_tail = (dc->rxq_tail + 1) & ~ZSKBD_RXQ_LEN;

	cs->cs_softreq = 1;
}
Exemplo n.º 3
0
/*
 * Polled input char.
 */
static int
zs_getc(void)
{
	int s, c, rr0;

	s = splzs();
	/* Wait for a character to arrive. */
	do {
		rr0 = zs_read_csr(&zscn_cs);
	} while ((rr0 & ZSRR0_RX_READY) == 0);

	c = zs_read_data(&zscn_cs);
	splx(s);

	/*
	 * This is used by the kd driver to read scan codes,
	 * so don't translate '\r' ==> '\n' here...
	 */
	return (c);
}
Exemplo n.º 4
0
/* expects to be in splzs() */
int
zskbd_poll(struct zs_chanstate *cs, uint8_t *key)
{
	u_int i;
	int rr0, rr1, c;

	for (i = 1000; i != 0; i--) {
		rr0 = zs_read_csr(cs);
		if ((rr0 & ZSRR0_RX_READY) != 0)
			break;
		delay(100);
	}
	if (i == 0)
		return ENXIO;

	rr1 = zs_read_reg(cs, 1);
	c = zs_read_data(cs);

	if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
		return EIO;

	*key = (uint8_t)c;
	return 0;
}
Exemplo n.º 5
0
void
zskbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct zskbd_softc	       *sc = (struct zskbd_softc *)self;
	struct zsc_softc      	       *zsc = (struct zsc_softc *)parent;
	struct zsc_attach_args	       *args = aux;
	struct zs_chanstate	       *cs;
	struct wskbddev_attach_args	wskaa;
	int				s, channel, rc;
	uint8_t				key;

	printf(": ");

	/* Establish ourself with the MD z8530 driver */
	channel = args->channel;
	cs = zsc->zsc_cs[channel];
	cs->cs_ops = &zskbd_zsops;
	cs->cs_private = sc;

	sc->sc_dc = malloc(sizeof(struct zskbd_devconfig), M_DEVBUF,
	    M_WAITOK | M_ZERO);

	s = splzs();
	zs_write_reg(cs, 9, (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET);
	cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_TIE;
	cs->cs_preg[4] = (cs->cs_preg[4] & ZSWR4_CLK_MASK) |
			 (ZSWR4_ONESB | ZSWR4_PARENB);	/* 1 stop, odd parity */
	cs->cs_preg[15] &= ~ZSWR15_ENABLE_ENHANCED;
	zs_set_speed(cs, ZSKBD_BAUD);
	zs_loadchannelregs(cs);

	/*
	 * Empty the keyboard input buffer (if the keyboard is the console
	 * input device and the user invoked UKC, the `enter key up' event
	 * will still be pending in the buffer).
	 */
	while ((zs_read_csr(cs) & ZSRR0_RX_READY) != 0)
		(void)zs_read_data(cs);

	/*
	 * Ask the keyboard for its DIP switch settings. This will also let
	 * us know whether the keyboard is connected.
	 */
	sc->sc_dc->expected = 2;
	zskbd_ctrl(cs, ZSKBD_CTRL_A_RCB, 0, 0, 0);
	while (sc->sc_dc->expected != 0) {
		rc = zskbd_poll(cs, &key);
		if (rc != 0) {
			if (rc == ENXIO && sc->sc_dc->expected == 2) {
				printf("no keyboard");
				/*
				 * Attach wskbd nevertheless, in case the
				 * keyboard is plugged late.
				 */
				sc->sc_dc->expected = 0;
				goto dip;
			} else {
				printf("i/o error\n");
				return;
			}
		}

		zskbd_process(cs, key);
	}

	printf("dip switches %02x", sc->sc_dc->dip);
dip:

	/*
	 * Disable key click by default. Note that if the keyboard is not
	 * currently connected, the bit will nevertheless stick and will
	 * disable the click as soon as a keyboard led needs to be lit.
	 */
	zskbd_ctrl(cs, ZSKBD_CTRL_A_NOCLICK, 0, 0, 0);

	splx(s);

	printf("\n");

	if (zskbd_is_console)
		sc->sc_dc->enabled = 1;

	/* attach wskbd */
	wskaa.console =		zskbd_is_console;
	wskaa.keymap =		&sgikbd_wskbd_keymapdata;
	wskaa.accessops =	&zskbd_wskbd_accessops;
	wskaa.accesscookie =	cs;
	sc->sc_dc->wskbddev =	config_found(self, &wskaa, wskbddevprint);
}
Exemplo n.º 6
0
/*
 * Receiver Ready interrupt.
 * Called at splzs().
 */
void
zstty_rxint(struct zs_chanstate *cs)
{
	struct zstty_softc *zst = cs->cs_private;
	uint8_t *put, *end;
	u_int cc;
	uint8_t rr0, rr1, c;

	end = zst->zst_ebuf;
	put = zst->zst_rbput;
	cc = zst->zst_rbavail;

	while (cc > 0) {
		/*
		 * First read the status, because reading the received char
		 * destroys the status of this char.
		 */
		rr1 = zs_read_reg(cs, 1);
		c = zs_read_data(cs);

		if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
			/* Clear the receive error. */
			zs_write_csr(cs, ZSWR0_RESET_ERRORS);
		}

		put[0] = c;
		put[1] = rr1;
		put += 2;
		if (put >= end)
			put = zst->zst_rbuf;
		cc--;

		rr0 = zs_read_csr(cs);
		if (!ISSET(rr0, ZSRR0_RX_READY))
			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.
	 */
	zst->zst_rbput = put;
	zst->zst_rbavail = cc;
	if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
		zst->zst_rx_ready = 1;
		cs->cs_softreq = 1;
	}

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

	/*
	 * If we're out of space, disable receive interrupts
	 * until the queue has drained a bit.
	 */
	if (!cc) {
		SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
		CLR(cs->cs_preg[1], ZSWR1_RIE);
		cs->cs_creg[1] = cs->cs_preg[1];
		zs_write_reg(cs, 1, cs->cs_creg[1]);
	}
}