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