Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Aug 2003 10:47:21 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 36967 for review
Message-ID:  <200308261747.h7QHlLmC091875@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=36967

Change 36967 by marcel@marcel_nfs on 2003/08/26 10:47:16

	Finalize the split. It's a step in the right direction.
	So, now all tty related code, including the low-level
	console support is on uart_tty.c. The core of the uart
	driver calls helper attach and detach functions depending
	on the kind of interface. By default this will be tty.
	The helper attach is responsible to setup the SWI. It's
	non-optional.
	
	Currently the high-level interface specific data has been
	put in a union. We may want to do that differently. Also,
	we may want to create a scalable way to call the helper
	functions. It's not really ideal to have them explicit
	in bus_attach/bus_detach. We'll see..
	
	Feedback from: jake

Affected files ...

.. //depot/projects/uart/conf/files#17 edit
.. //depot/projects/uart/dev/uart/uart_bus.h#17 edit
.. //depot/projects/uart/dev/uart/uart_cons.c#2 delete
.. //depot/projects/uart/dev/uart/uart_core.c#23 edit

Differences ...

==== //depot/projects/uart/conf/files#17 (text+ko) ====

@@ -786,12 +786,12 @@
 dev/uart/uart_bus_pci.c		optional	uart cardbus
 dev/uart/uart_bus_pci.c		optional	uart pci
 dev/uart/uart_bus_puc.c		optional	uart puc
-dev/uart/uart_cons.c		optional	uart
 dev/uart/uart_core.c		optional	uart
 dev/uart/uart_dev_ns8250.c	optional	uart
 dev/uart/uart_dev_sab82532.c	optional	uart
 dev/uart/uart_dev_z8530.c	optional	uart
 dev/uart/uart_subr.c		optional	uart
+dev/uart/uart_tty.c		optional	uart
 dev/ubsec/ubsec.c	optional ubsec
 #
 # USB support

==== //depot/projects/uart/dev/uart/uart_bus.h#17 (text+ko) ====

@@ -110,6 +110,7 @@
 	int		sc_fastintr:1;	/* This UART uses fast interrupts. */
 	int		sc_hasfifo:1;	/* This UART has FIFOs. */
 	int		sc_leaving:1;	/* This UART is going away. */
+	int		sc_keyboard:1;	/* This UART is a keyboard device. */
 	int		sc_opened:1;	/* This UART is open for business. */
 	int		sc_polled:1;	/* This UART has no interrupts. */
 	int		sc_txbusy:1;	/* This UART is transmitting. */
@@ -129,10 +130,19 @@
 	int		sc_txdatasz;
 	int		sc_txfifosz;	/* Size of TX FIFO and buffer. */
 
-	dev_t		sc_si[2];	/* We have 2 device special files. */
+	/* Upper layer data. */
 	void		*sc_softih;
-	struct tty	*sc_tty;
 	uint32_t	sc_ttypend;
+	union {
+		/* TTY specific data. */
+		struct {
+			dev_t	si[2];	/* We have 2 device special files. */
+			struct tty *tp;
+		} u_tty;
+		/* Keyboard specific data. */
+		struct {
+		} u_kbd;
+	} sc_u;
 };
 
 extern devclass_t uart_devclass;

==== //depot/projects/uart/dev/uart/uart_core.c#23 (text+ko) ====

@@ -62,159 +62,6 @@
 
 MALLOC_DEFINE(M_UART, "UART", "UART driver");
 
-#define	UART_MINOR_CALLOUT	0x10000
-
-static d_open_t uart_open;
-static d_close_t uart_close;
-static d_ioctl_t uart_ioctl;
-
-static struct cdevsw uart_cdevsw = {
-	.d_open = uart_open,
-	.d_close = uart_close,
-	.d_read = ttyread,
-	.d_write = ttywrite,
-	.d_ioctl = uart_ioctl,
-	.d_poll = ttypoll,
-	.d_name = uart_driver_name,
-	.d_maj = MAJOR_AUTO,
-	.d_flags = D_TTY,
-	.d_kqfilter = ttykqfilter,
-};
-
-static void
-uart_tty_oproc(struct tty *tp)
-{
-	struct uart_softc *sc;
-
-	KASSERT(tp->t_dev != NULL, ("foo"));
-	sc = tp->t_dev->si_drv1;
-	if (sc == NULL || sc->sc_leaving)
-		return;
-
-	if (tp->t_state & TS_TBLOCK)
-		UART_SETSIG(sc, UART_SIG_DRTS);
-	else
-		UART_SETSIG(sc, UART_SIG_DRTS|UART_SIG_RTS);
-
-	if (tp->t_state & (TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) {
-		ttwwakeup(tp);
-		return;
-	}
-
-	if (tp->t_outq.c_cc > 0 && !sc->sc_txbusy) {
-		sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf,
-		    sc->sc_txfifosz);
-		tp->t_state |= TS_BUSY;
-		UART_TRANSMIT(sc);
-	}
-	ttwwakeup(tp);
-}
-
-static int
-uart_tty_param(struct tty *tp, struct termios *t)
-{
-	struct uart_softc *sc;
-	int databits, parity, stopbits;
-
-	KASSERT(tp->t_dev != NULL, ("foo"));
-	sc = tp->t_dev->si_drv1;
-	if (sc == NULL || sc->sc_leaving)
-		return (ENODEV);
-	if (t->c_ispeed != t->c_ospeed && t->c_ospeed != 0)
-		return (EINVAL);
-	/* Hardwire the console speed. */
-	if (sc->sc_console)
-		t->c_ispeed = t->c_ospeed = uart_console.baudrate;
-	if (t->c_ospeed == 0) {
-		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
-		return (0);
-	}
-	switch (t->c_cflag & CSIZE) {
-	case CS5:	databits = 5; break;
-	case CS6:	databits = 6; break;
-	case CS7:	databits = 7; break;
-	default:	databits = 8; break;
-	}
-	stopbits = (t->c_cflag & CSTOPB) ? 2 : 1;
-	if (t->c_cflag & PARENB)
-		parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD
-		    : UART_PARITY_EVEN;
-	else
-		parity = UART_PARITY_NONE;
-	UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity);
-	UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR);
-	if ((t->c_cflag & CRTS_IFLOW) == 0)
-		UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS);
-	ttsetwater(tp);
-	if (sc->sc_console) {
-		tp->t_cflag |= CLOCAL;
-		tp->t_cflag &= ~HUPCL;
-	}
-	return (0);
-}
-
-static void
-uart_tty_stop(struct tty *tp, int rw)
-{
-	struct uart_softc *sc;
-
-	KASSERT(tp->t_dev != NULL, ("foo"));
-	sc = tp->t_dev->si_drv1;
-	if (sc == NULL || sc->sc_leaving)
-		return;
-	if (rw & FWRITE) {
-		if (sc->sc_txbusy) {
-			sc->sc_txbusy = 0;
-			UART_FLUSH(sc, UART_FLUSH_TRANSMITTER);
-		}
-		tp->t_state &= ~TS_BUSY;
-	}
-	if (rw & FREAD) {
-		UART_FLUSH(sc, UART_FLUSH_RECEIVER);
-		sc->sc_rxget = sc->sc_rxput = 0;
-	}
-}
-
-void
-uart_tty_intr(void *arg)
-{
-	struct uart_softc *sc = arg;
-	struct tty *tp;
-	int c, pend, sig, xc;
-
-	if (sc->sc_leaving)
-		return;
-
-	pend = atomic_readandclear_32(&sc->sc_ttypend);
-	if (!(pend & UART_IPEND_MASK))
-		return;
-
-	tp = sc->sc_tty;
-
-	if (pend & UART_IPEND_RXREADY) {
-		while (!uart_rx_empty(sc)) {
-			xc = uart_rx_get(sc);
-			c = xc & 0xff;
-			if (xc & UART_STAT_FRAMERR)
-				c |= TTY_FE;
-			if (xc & UART_STAT_PARERR)
-				c |= TTY_PE;
-			(*linesw[tp->t_line].l_rint)(c, tp);
-		}
-	}
-
-	if (pend & UART_IPEND_SIGCHG) {
-		sig = pend & UART_IPEND_SIGMASK;
-		if (sig & UART_SIG_DDCD)
-			(*linesw[tp->t_line].l_modem)(tp, sig & UART_SIG_DCD);
-	}
-
-	if (pend & UART_IPEND_TXIDLE) {
-		tp->t_state &= ~TS_BUSY;
-		(*linesw[tp->t_line].l_start)(tp);
-	}
-}
-
 /*
  * A break condition has been detected. We treat the break condition as
  * a special case that should not happen during normal operation. When
@@ -234,13 +81,8 @@
 		return;
 	}
 #endif
-	if (!sc->sc_opened)
-		return;
-	if (sc->sc_tty == NULL || sc->sc_tty->t_iflag & IGNBRK)
-		return;
-	if (uart_rx_put(sc, UART_STAT_BREAK))
-		sc->sc_rxbuf[sc->sc_rxput] |= UART_STAT_BREAK;
-	atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
+	if (sc->sc_opened)
+		atomic_set_32(&sc->sc_ttypend, UART_IPEND_BREAK);
 }
 
 /*
@@ -428,7 +270,6 @@
 {
 	struct uart_softc *sc, *sc0;
 	const char *sep;
-	struct tty *tp;
 	int error;
 
 	/*
@@ -525,31 +366,14 @@
 		printf("\n");
 	}
 
-	tp = ttymalloc(NULL);
-	sc->sc_tty = tp;
+	if (sc->sc_keyboard) {
+		/* Keyboard specific attachment. */
+	} else
+		error = uart_tty_attach(sc);
 
-	sc->sc_si[0] = make_dev(&uart_cdevsw, device_get_unit(sc->sc_dev),
-	    UID_ROOT, GID_WHEEL, 0600, "ttyu%r", device_get_unit(sc->sc_dev));
-	sc->sc_si[0]->si_drv1 = sc;
-	sc->sc_si[0]->si_tty = tp;
-	sc->sc_si[1] = make_dev(&uart_cdevsw,
-	    device_get_unit(sc->sc_dev) | UART_MINOR_CALLOUT, UID_UUCP,
-	    GID_DIALER, 0660, "uart%r", device_get_unit(sc->sc_dev));
-	sc->sc_si[1]->si_drv1 = sc;
-	sc->sc_si[1]->si_tty = tp;
+	if (error)
+		goto fail;
 
-	tp->t_oproc = uart_tty_oproc;
-	tp->t_param = uart_tty_param;
-	tp->t_stop = uart_tty_stop;
-
-	if (sc->sc_console) {
-		((struct consdev *)uart_console.consdev)->cn_dev =
-		    makedev(uart_cdevsw.d_maj, device_get_unit(sc->sc_dev));
-	}
-
-	swi_add(&tty_ithd, uart_driver_name, uart_tty_intr, sc, SWI_TTY,
-	    INTR_TYPE_TTY, &sc->sc_softih);
-
 	sc->sc_leaving = 0;
 	uart_intr(sc);
 	return (0);
@@ -568,7 +392,8 @@
 	return (error);
 }
 
-int uart_bus_detach(device_t dev)
+int
+uart_bus_detach(device_t dev)
 {
 	struct uart_softc *sc;
 
@@ -578,10 +403,10 @@
 
 	UART_DETACH(sc);
 
-	ithread_remove_handler(sc->sc_softih);
-	destroy_dev(sc->sc_si[0]);
-	destroy_dev(sc->sc_si[1]);
-	/* ttyfree(sc->sc_tty); */
+	if (sc->sc_keyboard) {
+		/* Keyboard specific detachment. */
+	} else
+		uart_tty_detach(sc);
 
 	free(sc->sc_txbuf, M_UART);
 	free(sc->sc_rxbuf, M_UART);
@@ -601,205 +426,3 @@
 
 	return (0);
 }
-
-static int
-uart_open(dev_t dev, int flags, int mode, struct thread *td)
-{
-	struct uart_softc *sc;
-	struct tty *tp;
-	int error;
-
-	sc = dev->si_drv1;
-	if (sc == NULL || sc->sc_leaving)
-		return (ENODEV);
-
-	tp = dev->si_tty;
-
- loop:
-	if (sc->sc_opened) {
-		KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
-		/*
-		 * The device is open, so everything has been initialized.
-		 * Handle conflicts.
-		 */
-		if (minor(dev) & UART_MINOR_CALLOUT) {
-			if (!sc->sc_callout)
-				return (EBUSY);
-		} else {
-			if (sc->sc_callout) {
-				if (flags & O_NONBLOCK)
-					return (EBUSY);
-				error =	tsleep(sc, TTIPRI|PCATCH, "uartbi", 0);
-				if (error)
-					return (error);
-				sc = dev->si_drv1;
-				if (sc == NULL || sc->sc_leaving)
-					return (ENODEV);
-				goto loop;
-			}
-		}
-		if (tp->t_state & TS_XCLUDE && suser(td) != 0)
-			return (EBUSY);
-	} else {
-		KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
-		/*
-		 * The device isn't open, so there are no conflicts.
-		 * Initialize it.  Initialization is done twice in many
-		 * cases: to preempt sleeping callin opens if we are
-		 * callout, and to complete a callin open after DCD rises.
-		 */
-		sc->sc_callout = (minor(dev) & UART_MINOR_CALLOUT) ? 1 : 0;
-		tp->t_dev = dev;
-
-		tp->t_cflag = TTYDEF_CFLAG;
-		tp->t_iflag = TTYDEF_IFLAG;
-		tp->t_lflag = TTYDEF_LFLAG;
-		tp->t_oflag = TTYDEF_OFLAG;
-		if (sc->sc_console)
-			tp->t_ispeed = tp->t_ospeed = uart_console.baudrate;
-		else
-			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
-		ttychars(tp);
-		error = uart_tty_param(tp, &tp->t_termios);
-		if (error)
-			return (error);
-		/*
-		 * Handle initial DCD.
-		 */
-		if ((UART_GETSIG(sc) & UART_SIG_DCD) || sc->sc_callout)
-			(*linesw[tp->t_line].l_modem)(tp, 1);
-	}
-	/*
-	 * Wait for DCD if necessary.
-	 */
-	if (!(tp->t_state & TS_CARR_ON) && !sc->sc_callout &&
-	    !(tp->t_cflag & CLOCAL) && !(flags & O_NONBLOCK)) {
-		error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "uartdcd", 0);
-		if (error)
-			return (error);
-		sc = dev->si_drv1;
-		if (sc == NULL || sc->sc_leaving)
-			return (ENODEV);
-		goto loop;
-	}
-	error = ttyopen(dev, tp);
-	if (error)
-		return (error);
-	error = (*linesw[tp->t_line].l_open)(dev, tp);
-	if (error)
-		return (error);
-
-	KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
-	sc->sc_opened = 1;
-	return (0);
-}
-
-static int
-uart_close(dev_t dev, int flags, int mode, struct thread *td)
-{
-	struct uart_softc *sc;
-	struct tty *tp;
-
-	sc = dev->si_drv1;
-	if (sc == NULL || sc->sc_leaving)
-		return (ENODEV);
-	tp = dev->si_tty;
-	if (!sc->sc_opened) {
-		KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
-		return (0);
-	}
-	KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
-
-	if (!sc->sc_console)
-		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
-
-	(*linesw[tp->t_line].l_close)(tp, flags);
-	ttyclose(tp);
-	wakeup(sc);
-	wakeup(TSA_CARR_ON(tp));
-	KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
-	sc->sc_opened = 0;
-	return (0);
-}
-
-static int
-uart_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
-{
-	struct uart_softc *sc;
-	struct tty *tp;
-	int bits, error, sig;
-
-	sc = dev->si_drv1;
-	if (sc == NULL || sc->sc_leaving)
-		return (ENODEV);
-
-	tp = dev->si_tty;
-	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, td);
-	if (error != ENOIOCTL)
-		return (error);
-	error = ttioctl(tp, cmd, data, flags);
-	if (error != ENOIOCTL)
-		return (error);
-
-	switch (cmd) {
-	case TIOCSBRK:
-		UART_SETSIG(sc, UART_SIG_DBREAK | UART_SIG_BREAK);
-		break;
-	case TIOCCBRK:
-		UART_SETSIG(sc, UART_SIG_DBREAK);
-		break;
-	case TIOCSDTR:
-		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR);
-		break;
-	case TIOCCDTR:
-		UART_SETSIG(sc, UART_SIG_DDTR);
-		break;
-	case TIOCMSET:
-		bits = *(int*)data;
-		sig = UART_SIG_DDTR | UART_SIG_DRTS;
-		if (bits & TIOCM_DTR)
-			sig |= UART_SIG_DTR;
-		if (bits & TIOCM_RTS)
-			sig |= UART_SIG_RTS;
-		UART_SETSIG(sc, sig);
-		break;
-        case TIOCMBIS:
-		bits = *(int*)data;
-		sig = 0;
-		if (bits & TIOCM_DTR)
-			sig |= UART_SIG_DDTR | UART_SIG_DTR;
-		if (bits & TIOCM_RTS)
-			sig |= UART_SIG_DRTS | UART_SIG_RTS;
-		UART_SETSIG(sc, sig);
-		break;
-        case TIOCMBIC:
-		bits = *(int*)data;
-		sig = 0;
-		if (bits & TIOCM_DTR)
-			sig |= UART_SIG_DDTR;
-		if (bits & TIOCM_RTS)
-			sig |= UART_SIG_DRTS;
-		UART_SETSIG(sc, sig);
-		break;
-        case TIOCMGET:
-		sig = UART_GETSIG(sc);
-		bits = TIOCM_LE;
-		if (sig & UART_SIG_DTR)
-			bits |= TIOCM_DTR;
-		if (sig & UART_SIG_RTS)
-			bits |= TIOCM_RTS;
-		if (sig & UART_SIG_DSR)
-			bits |= TIOCM_DSR;
-		if (sig & UART_SIG_CTS)
-			bits |= TIOCM_CTS;
-		if (sig & UART_SIG_DCD)
-			bits |= TIOCM_CD;
-		if (sig & (UART_SIG_DRI | UART_SIG_RI))
-			bits |= TIOCM_RI;
-		*(int*)data = bits;
-		break;
-	default:
-		return (ENOTTY);
-	}
-	return (0);
-}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200308261747.h7QHlLmC091875>