svn commit: r220994 - in projects/altix/sys: conf dev/uart ia64/sgisn

Marcel Moolenaar marcel at FreeBSD.org
Sun Apr 24 17:13:42 UTC 2011


Author: marcel
Date: Sun Apr 24 17:13:42 2011
New Revision: 220994
URL: http://svn.freebsd.org/changeset/base/220994

Log:
  Use a seperate driver for the SAL-based console on Altix. While initially
  uart(4) seemed like a good idea (and for the low-level console it wasn't
  a bad idea), the fact that the SAL-based console doesn't have any I/O port
  or memory mapped I/O resources and uart(4) expects and needs that means
  that uart(4) is simply not a good idea.
  
  The new driver in its current form is almost functional complete. It only
  lacks proper interrupt handling. The reason for that is that interrupts
  aren't exactly working on Altix, so it's a bit hard to test. Also, SAL
  only allows us to have receive interrupts, not transmit interrupts. As
  such, a bit more effort is required to make sure the TX path doesn't
  stall (read: polling and/or timeouts are needed).
  
  The uart(4) driver changes are reverted.

Added:
  projects/altix/sys/ia64/sgisn/sgisn_console.c   (contents, props changed)
Deleted:
  projects/altix/sys/dev/uart/uart_dev_sgisn.c
Modified:
  projects/altix/sys/conf/files.ia64
  projects/altix/sys/dev/uart/uart.h
  projects/altix/sys/dev/uart/uart_cpu_ia64.c
  projects/altix/sys/dev/uart/uart_subr.c

Modified: projects/altix/sys/conf/files.ia64
==============================================================================
--- projects/altix/sys/conf/files.ia64	Sun Apr 24 16:56:34 2011	(r220993)
+++ projects/altix/sys/conf/files.ia64	Sun Apr 24 17:13:42 2011	(r220994)
@@ -60,7 +60,6 @@ dev/syscons/scterm-teken.c	optional	sc
 dev/syscons/scvgarndr.c		optional	sc vga
 dev/syscons/scvtb.c		optional	sc
 dev/uart/uart_cpu_ia64.c	optional	uart
-dev/uart/uart_dev_sgisn.c	optional	uart
 dev/acpica/acpi_if.m		standard
 ia64/acpica/OsdEnvironment.c	optional	acpi
 ia64/acpica/acpi_machdep.c	optional	acpi
@@ -117,6 +116,7 @@ ia64/ia64/vm_machdep.c		standard
 ia64/isa/isa.c			optional	isa
 ia64/isa/isa_dma.c		optional	isa
 ia64/pci/pci_cfgreg.c		optional	pci
+ia64/sgisn/sgisn_console.c	standard
 ia64/sgisn/sgisn_pcib.c		standard
 ia64/sgisn/sgisn_shub.c		standard
 isa/syscons_isa.c		optional	sc

Modified: projects/altix/sys/dev/uart/uart.h
==============================================================================
--- projects/altix/sys/dev/uart/uart.h	Sun Apr 24 16:56:34 2011	(r220993)
+++ projects/altix/sys/dev/uart/uart.h	Sun Apr 24 17:13:42 2011	(r220994)
@@ -68,7 +68,6 @@ extern struct uart_class uart_ns8250_cla
 extern struct uart_class uart_quicc_class __attribute__((weak));
 extern struct uart_class uart_sab82532_class __attribute__((weak));
 extern struct uart_class uart_sbbc_class __attribute__((weak));
-extern struct uart_class uart_sgisn_class __attribute__((weak));
 extern struct uart_class uart_z8530_class __attribute__((weak));
 
 #ifdef PC98

Modified: projects/altix/sys/dev/uart/uart_cpu_ia64.c
==============================================================================
--- projects/altix/sys/dev/uart/uart_cpu_ia64.c	Sun Apr 24 16:56:34 2011	(r220993)
+++ projects/altix/sys/dev/uart/uart_cpu_ia64.c	Sun Apr 24 17:13:42 2011	(r220994)
@@ -66,8 +66,6 @@ uart_cpu_getdev(int devtype, struct uart
 
 	class = &uart_ns8250_class;
 	if (class == NULL)
-		class = &uart_sgisn_class;
-	if (class == NULL)
 		return (ENXIO);
 
 	/*

Modified: projects/altix/sys/dev/uart/uart_subr.c
==============================================================================
--- projects/altix/sys/dev/uart/uart_subr.c	Sun Apr 24 16:56:34 2011	(r220993)
+++ projects/altix/sys/dev/uart/uart_subr.c	Sun Apr 24 17:13:42 2011	(r220994)
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
 static struct uart_class *uart_classes[] = {
 	&uart_ns8250_class,
 	&uart_sab82532_class,
-	&uart_sgisn_class,
 	&uart_z8530_class,
 };
 static size_t uart_nclasses = sizeof(uart_classes) / sizeof(uart_classes[0]);
@@ -195,7 +194,7 @@ uart_getenv(int devtype, struct uart_dev
 {
 	__const char *spec;
 	bus_addr_t addr = ~0U;
-	int error, range;
+	int error;
 
 	/*
 	 * All uart_class references are weak. Make sure the default
@@ -273,25 +272,13 @@ uart_getenv(int devtype, struct uart_dev
 		spec++;
 	}
 
-	di->ops = uart_getops(class);
-	range = uart_getrange(class);
-
 	/*
 	 * If we still have an invalid address, the specification must be
-	 * missing an I/O port or memory address. We don't like that if
-	 * the class expects an I/O port or memory range.
+	 * missing an I/O port or memory address. We don't like that.
 	 */
-	if (addr == ~0U && range != 0)
+	if (addr == ~0U)
 		return (EINVAL);
 
-	/* Create a bus space handle if applicable. */
-	if (addr != ~0U && range != 0) {
-		error = bus_space_map(di->bas.bst, addr, range, 0,
-		    &di->bas.bsh);
-		if (error)
-			return (error);
-	}
-
 	/*
 	 * Accept only the well-known baudrates. Any invalid baudrate
 	 * is silently replaced with a 0-valued baudrate. The 0 baudrate
@@ -311,5 +298,9 @@ uart_getenv(int devtype, struct uart_dev
 	} else
 		di->baudrate = 0;
 
-	return (0);
+	/* Set the ops and create a bus space handle. */
+	di->ops = uart_getops(class);
+	error = bus_space_map(di->bas.bst, addr, uart_getrange(class), 0,
+	    &di->bas.bsh);
+	return (error);
 }

Added: projects/altix/sys/ia64/sgisn/sgisn_console.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/altix/sys/ia64/sgisn/sgisn_console.c	Sun Apr 24 17:13:42 2011	(r220994)
@@ -0,0 +1,325 @@
+/*-
+ * Copyright (c) 2011 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/interrupt.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/tty.h>
+#include <machine/resource.h>
+#include <machine/sal.h>
+#include <machine/sgisn.h>
+
+struct sncon_softc {
+	device_t	sc_dev;
+	struct tty	*sc_tp;
+	struct resource *sc_ires;
+	void		*sc_icookie;
+	void		*sc_softih;
+	int		sc_irid;
+};
+
+static char sncon_name[] = "sncon";
+static int sncon_is_console = 0;
+
+/*
+ * Low-level console section.
+ */
+
+static int  sncon_cngetc(struct consdev *);
+static void sncon_cninit(struct consdev *);
+static void sncon_cnprobe(struct consdev *);
+static void sncon_cnputc(struct consdev *, int);
+static void sncon_cnterm(struct consdev *);
+
+CONSOLE_DRIVER(sncon);
+
+static int
+sncon_cngetc(struct consdev *cp)
+{
+	struct ia64_sal_result r;
+
+	r = ia64_sal_entry(SAL_SGISN_POLL, 0, 0, 0, 0, 0, 0, 0);
+	if (r.sal_status || r.sal_result[0] == 0)
+		return (-1);
+
+	r = ia64_sal_entry(SAL_SGISN_GETC, 0, 0, 0, 0, 0, 0, 0);
+	return ((!r.sal_status) ? r.sal_result[0] : -1);
+}
+
+static void
+sncon_cninit(struct consdev *cp)
+{
+
+	sncon_is_console = 1;
+}
+
+static void
+sncon_cnprobe(struct consdev *cp)
+{
+	struct ia64_sal_result r;
+
+	r = ia64_sal_entry(SAL_SGISN_SN_INFO, 0, 0, 0, 0, 0, 0, 0);
+	if (r.sal_status != 0)
+		return;
+
+	strcpy(cp->cn_name, "sncon0");
+	cp->cn_pri = CN_INTERNAL;
+}
+
+static void
+sncon_cnputc(struct consdev *cp, int c)
+{
+	struct ia64_sal_result r;
+	char buf[1];
+
+	buf[0] = c;
+	r = ia64_sal_entry(SAL_SGISN_TXBUF, (uintptr_t)buf, 1, 0, 0, 0, 0, 0);
+}
+
+static void
+sncon_cnterm(struct consdev *cp)
+{
+
+	sncon_is_console = 0;
+}
+
+/*
+ * TTY section.
+ */
+
+static void sncon_tty_close(struct tty *);
+static void sncon_tty_free(void *);
+static void sncon_tty_inwakeup(struct tty *);
+static int  sncon_tty_ioctl(struct tty *, u_long, caddr_t, struct thread *);
+static int  sncon_tty_modem(struct tty *, int, int);
+static int  sncon_tty_open(struct tty *);
+static void sncon_tty_outwakeup(struct tty *);
+static int  sncon_tty_param(struct tty *, struct termios *);
+
+static struct ttydevsw sncon_tty_class = {
+	.tsw_flags	= TF_INITLOCK|TF_CALLOUT,
+	.tsw_open	= sncon_tty_open,
+	.tsw_close	= sncon_tty_close,
+	.tsw_outwakeup	= sncon_tty_outwakeup,
+	.tsw_inwakeup	= sncon_tty_inwakeup,
+	.tsw_ioctl	= sncon_tty_ioctl,
+	.tsw_param	= sncon_tty_param,
+	.tsw_modem	= sncon_tty_modem,
+	.tsw_free	= sncon_tty_free,
+};
+
+static void
+sncon_tty_close(struct tty *tp)
+{
+}
+
+static void
+sncon_tty_free(void *arg)
+{
+}
+
+static void
+sncon_tty_inwakeup(struct tty *tp)
+{
+	struct sncon_softc *sc;
+
+	sc = tty_softc(tp);
+	/*
+	 * Re-start reception.
+	 */
+}
+
+static int
+sncon_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
+{
+
+	return (ENOTTY);
+}
+
+static int
+sncon_tty_modem(struct tty *tp, int biton, int bitoff)
+{
+
+	return (0);
+}
+
+static int
+sncon_tty_open(struct tty *tp)
+{
+
+	return (0);
+}
+
+static void
+sncon_tty_outwakeup(struct tty *tp)
+{
+	struct sncon_softc *sc;
+
+	sc = tty_softc(tp);
+	/*
+	 * Re-start transmission.
+	 */
+}
+
+static int
+sncon_tty_param(struct tty *tp, struct termios *t)
+{
+
+	t->c_ispeed = t->c_ospeed = 9600;
+	t->c_cflag |= CLOCAL;
+	t->c_cflag &= ~HUPCL;
+	return (0);
+}
+
+/*
+ * Device section.
+ */
+
+static int sncon_attach(device_t);
+static int sncon_detach(device_t);
+static int sncon_probe(device_t);
+
+static device_method_t sncon_methods[] = {
+	DEVMETHOD(device_attach,	sncon_attach),
+	DEVMETHOD(device_detach,	sncon_detach),
+	DEVMETHOD(device_probe,		sncon_probe),
+	{ 0, 0 }
+};
+
+static driver_t sncon_driver = {
+	sncon_name,
+	sncon_methods,
+	sizeof(struct sncon_softc),
+};
+
+static devclass_t sncon_devclass;
+
+DRIVER_MODULE(sncon, shub, sncon_driver, sncon_devclass, 0, 0);
+
+static void
+sncon_rx_intr(void *arg)
+{
+}
+
+static void
+sncon_tx_intr(void *arg)
+{
+}
+
+static int
+sncon_attach(device_t dev)
+{
+	struct ia64_sal_result r;
+	struct sncon_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	do {
+		/* Enable RX interrupts. */
+		r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, 1, 0, 0, 0, 0, 0);
+		if (r.sal_status != 0)
+			break;
+
+		sc->sc_irid = 0;
+		sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+		    &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
+		if (sc->sc_ires == NULL)
+			break;
+
+		error = bus_setup_intr(dev, sc->sc_ires,
+		    INTR_TYPE_TTY | INTR_MPSAFE, NULL, sncon_rx_intr, sc,
+		    &sc->sc_icookie);
+		if (error) {
+			device_printf(dev, "could not activate interrupt\n");
+			bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
+			    sc->sc_ires);
+			sc->sc_ires = NULL;
+		}
+	} while (0);
+
+	if (sc->sc_ires == NULL) {
+		/* Disable RX interrupts. */
+		r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, 0, 0, 0, 0, 0, 0);
+	}
+
+	swi_add(&tty_intr_event, sncon_name, sncon_tx_intr, sc, SWI_TTY,
+	    INTR_TYPE_TTY, &sc->sc_softih);
+
+	sc->sc_tp = tty_alloc(&sncon_tty_class, sc);
+	if (sncon_is_console)
+		tty_init_console(sc->sc_tp, 0);
+	tty_makedev(sc->sc_tp, NULL, "s0");
+	return (0);
+}
+
+static int
+sncon_detach(device_t dev)
+{
+	struct ia64_sal_result r;
+	struct sncon_softc *sc;
+	struct tty *tp;
+
+	sc = device_get_softc(dev);
+	tp = sc->sc_tp;
+
+	tty_lock(tp);
+	swi_remove(sc->sc_softih);
+	tty_rel_gone(tp);
+
+	if (sc->sc_ires != NULL) {
+		bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie);
+		bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
+		    sc->sc_ires);
+	}
+
+	/* Disable Tx & Rx interrupts. */
+	r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, 0, 0, 0, 0, 0, 0);
+	return (0);
+}
+
+static int
+sncon_probe(device_t dev)
+{
+	struct ia64_sal_result r;
+ 
+	r = ia64_sal_entry(SAL_SGISN_SN_INFO, 0, 0, 0, 0, 0, 0, 0);
+	if (r.sal_status != 0)
+		return (ENXIO);
+
+	bus_set_resource(dev, SYS_RES_IRQ, 0, 0xe9, 1);
+	device_set_desc_copy(dev, "SGI L1 console");
+	return (0);
+}


More information about the svn-src-projects mailing list