Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Nov 2006 16:59:17 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 110037 for review
Message-ID:  <200611151659.kAFGxHrb007310@repoman.freebsd.org>

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

Change 110037 by marcel@marcel_nfs on 2006/11/15 16:58:17

	Hide the uart_ops instances and instead have the device class
	point to them. By going through the class we can implement the
	DT tag in uart_getenv() as well as use the correct I/O range
	in bus_space_map().

Affected files ...

.. //depot/projects/uart/dev/uart/uart.h#11 edit
.. //depot/projects/uart/dev/uart/uart_bus.h#48 edit
.. //depot/projects/uart/dev/uart/uart_core.c#55 edit
.. //depot/projects/uart/dev/uart/uart_cpu.h#20 edit
.. //depot/projects/uart/dev/uart/uart_cpu_amd64.c#11 edit
.. //depot/projects/uart/dev/uart/uart_cpu_i386.c#12 edit
.. //depot/projects/uart/dev/uart/uart_cpu_ia64.c#13 edit
.. //depot/projects/uart/dev/uart/uart_cpu_pc98.c#13 edit
.. //depot/projects/uart/dev/uart/uart_cpu_sparc64.c#26 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#46 edit
.. //depot/projects/uart/dev/uart/uart_dev_sab82532.c#42 edit
.. //depot/projects/uart/dev/uart/uart_dev_z8530.c#33 edit
.. //depot/projects/uart/dev/uart/uart_kbd_sun.c#11 edit
.. //depot/projects/uart/dev/uart/uart_subr.c#7 edit

Differences ...

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

@@ -60,6 +60,16 @@
 	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
 
 /*
+ * UART device classes.
+ */
+struct uart_class;
+
+extern struct uart_class uart_ns8250_class;
+extern struct uart_class uart_quicc_class;
+extern struct uart_class uart_sab82532_class;
+extern struct uart_class uart_z8530_class;
+
+/*
  * Device flags.
  */
 #define	UART_FLAGS_CONSOLE(f)		((f) & 0x10)

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

@@ -67,14 +67,11 @@
  */
 struct uart_class {
 	KOBJ_CLASS_FIELDS;
+	struct uart_ops *uc_ops;	/* Low-level console operations. */
 	u_int	uc_range;		/* Bus space address range. */
 	u_int	uc_rclk;		/* Default rclk for this device. */
 };
 
-extern struct uart_class uart_ns8250_class;
-extern struct uart_class uart_sab82532_class;
-extern struct uart_class uart_z8530_class;
-
 struct uart_softc {
 	KOBJ_FIELDS;
 	struct uart_class *sc_class;

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

@@ -70,6 +70,18 @@
 	SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
 }
 
+struct uart_ops *
+uart_getops(struct uart_class *uc)
+{
+	return (uc->uc_ops);
+}
+
+int
+uart_getrange(struct uart_class *uc)
+{
+	return (uc->uc_range);
+}
+
 /*
  * Schedule a soft interrupt. We do this on the 0 to !0 transition
  * of the TTY pending interrupt status.

==== //depot/projects/uart/dev/uart/uart_cpu.h#20 (text+ko) ====

@@ -45,11 +45,6 @@
 	int (*getc)(struct uart_bas *, struct mtx *);
 };
 
-extern struct uart_ops uart_i8251_ops;
-extern struct uart_ops uart_ns8250_ops;
-extern struct uart_ops uart_sab82532_ops;
-extern struct uart_ops uart_z8530_ops;
-
 extern bus_space_tag_t uart_bus_space_io;
 extern bus_space_tag_t uart_bus_space_mem;
 
@@ -59,7 +54,7 @@
 struct uart_softc;
 struct uart_devinfo {
 	SLIST_ENTRY(uart_devinfo) next;
-	struct uart_ops ops;
+	struct uart_ops *ops;
 	struct uart_bas bas;
 	int	baudrate;
 	int	databits;
@@ -77,7 +72,10 @@
 
 int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
 int uart_cpu_getdev(int, struct uart_devinfo *);
-int uart_getenv(int, struct uart_devinfo *);
+
+int uart_getenv(int, struct uart_devinfo *, struct uart_class *);
+struct uart_ops *uart_getops(struct uart_class *);
+int uart_getrange(struct uart_class *);
 
 void uart_add_sysdev(struct uart_devinfo *);
 
@@ -106,7 +104,7 @@
 	int res;
 
 	uart_lock(di->hwmtx);
-	res = di->ops.probe(&di->bas);
+	res = di->ops->probe(&di->bas);
 	uart_unlock(di->hwmtx);
 	return (res);
 }
@@ -115,7 +113,7 @@
 uart_init(struct uart_devinfo *di)
 {
 	uart_lock(di->hwmtx);
-	di->ops.init(&di->bas, di->baudrate, di->databits, di->stopbits,
+	di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits,
 	    di->parity);
 	uart_unlock(di->hwmtx);
 }
@@ -124,7 +122,7 @@
 uart_term(struct uart_devinfo *di)
 {
 	uart_lock(di->hwmtx);
-	di->ops.term(&di->bas);
+	di->ops->term(&di->bas);
 	uart_unlock(di->hwmtx);
 }
 
@@ -132,7 +130,7 @@
 uart_putc(struct uart_devinfo *di, int c)
 {
 	uart_lock(di->hwmtx);
-	di->ops.putc(&di->bas, c);
+	di->ops->putc(&di->bas, c);
 	uart_unlock(di->hwmtx);
 }
 
@@ -142,7 +140,7 @@
 	int res;
 
 	uart_lock(di->hwmtx);
-	res = di->ops.poll(&di->bas);
+	res = di->ops->poll(&di->bas);
 	uart_unlock(di->hwmtx);
 	return (res);
 }
@@ -151,7 +149,7 @@
 uart_getc(struct uart_devinfo *di)
 {
 
-	return (di->ops.getc(&di->bas, di->hwmtx));
+	return (di->ops->getc(&di->bas, di->hwmtx));
 }
 
 #endif /* _DEV_UART_CPU_H_ */

==== //depot/projects/uart/dev/uart/uart_cpu_amd64.c#11 (text+ko) ====

@@ -49,11 +49,13 @@
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
+	struct uart_class *class;
 	unsigned int i, ivar;
 
+	class = &uart_ns8250_class;
+
 	/* Check the environment. */
-	di->ops = uart_ns8250_ops;
-	if (uart_getenv(devtype, di) == 0)
+	if (uart_getenv(devtype, di, class) == 0)
 		return (0);
 
 	/*
@@ -82,10 +84,11 @@
 		 * Got it. Fill in the instance and return it. We only have
 		 * ns8250 and successors on i386.
 		 */
-		di->ops = uart_ns8250_ops;
+		di->ops = uart_getops(class);
 		di->bas.chan = 0;
 		di->bas.bst = uart_bus_space_io;
-		if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
+		if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0,
+		    &di->bas.bsh) != 0)
 			continue;
 		di->bas.regshft = 0;
 		di->bas.rclk = 0;

==== //depot/projects/uart/dev/uart/uart_cpu_i386.c#12 (text+ko) ====

@@ -49,11 +49,13 @@
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
+	struct uart_class *class;
 	unsigned int i, ivar;
 
+	class = &uart_ns8250_class;
+
 	/* Check the environment. */
-	di->ops = uart_ns8250_ops;
-	if (uart_getenv(devtype, di) == 0)
+	if (uart_getenv(devtype, di, class) == 0)
 		return (0);
 
 	/*
@@ -82,10 +84,11 @@
 		 * Got it. Fill in the instance and return it. We only have
 		 * ns8250 and successors on i386.
 		 */
-		di->ops = uart_ns8250_ops;
+		di->ops = uart_getops(class);
 		di->bas.chan = 0;
 		di->bas.bst = uart_bus_space_io;
-		if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
+		if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0,
+		    &di->bas.bsh) != 0)
 			continue;
 		di->bas.regshft = 0;
 		di->bas.rclk = 0;

==== //depot/projects/uart/dev/uart/uart_cpu_ia64.c#13 (text+ko) ====

@@ -59,10 +59,13 @@
 {
 	struct dig64_hcdp_table *tbl;
 	struct dig64_hcdp_entry *ent;
+	struct uart_class *class;
 	bus_addr_t addr;
 	uint64_t hcdp;
 	unsigned int i;
 
+	class = &uart_ns8250_class;
+
 	/*
 	 * Use the DIG64 HCDP table if present.
 	 */
@@ -82,12 +85,12 @@
 
 			addr = ent->address.addr_high;
 			addr = (addr << 32) + ent->address.addr_low;
-			di->ops = uart_ns8250_ops;
+			di->ops = uart_getops(class);
 			di->bas.chan = 0;
 			di->bas.bst = (ent->address.addr_space == 0)
 			    ? uart_bus_space_mem : uart_bus_space_io;
-			if (bus_space_map(di->bas.bst, addr, 8, 0,
-			    &di->bas.bsh) != 0)
+			if (bus_space_map(di->bas.bst, addr,
+			    uart_getrange(class), 0, &di->bas.bsh) != 0)
 				continue;
 			di->bas.regshft = 0;
 			di->bas.rclk = ent->pclock << 4;
@@ -104,6 +107,5 @@
 	}
 
 	/* Check the environment. */
-	di->ops = uart_ns8250_ops;
-	return (uart_getenv(devtype, di));
+	return (uart_getenv(devtype, di, class));
 }

==== //depot/projects/uart/dev/uart/uart_cpu_pc98.c#13 (text+ko) ====

@@ -49,11 +49,13 @@
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
+	struct uart_class *class;
 	unsigned int i, ivar, flags;
 
+	class = &uart_ns8250_class;
+
 	/* Check the environment. */
-	di->ops = uart_ns8250_ops;
-	if (uart_getenv(devtype, di) == 0)
+	if (uart_getenv(devtype, di, class) == 0)
 		return (0);
 
 	/*
@@ -81,10 +83,11 @@
 		    ivar == 0)
 			continue;
 
-		di->ops = uart_ns8250_ops;
+		di->ops = uart_getops(class);
 		di->bas.chan = 0;
 		di->bas.bst = uart_bus_space_io;
-		if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
+		if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0,
+		    &di->bas.bsh) != 0)
 			continue;
 		di->bas.regshft = 0;
 		di->bas.rclk = 0;

==== //depot/projects/uart/dev/uart/uart_cpu_sparc64.c#26 (text+ko) ====

@@ -194,9 +194,10 @@
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
 	char buf[32], compat[32], dev[64];
+	struct uart_class *class;
 	phandle_t input, options;
 	bus_addr_t addr;
-	int baud, bits, error, space, stop;
+	int baud, bits, error, range, space, stop;
 	char flag, par;
 
 	if ((options = OF_finddevice("/options")) == -1)
@@ -228,14 +229,15 @@
 		compat[0] = '\0';
 	di->bas.regshft = 0;
 	di->bas.rclk = 0;
+	class = NULL;
 	if (!strcmp(buf, "se") || !strcmp(compat, "sab82532")) {
-		di->ops = uart_sab82532_ops;
+		class = &uart_sab82532_class;
 		/* SAB82532 are only known to be used for TTYs. */
 		if ((di->bas.chan = uart_cpu_channel(dev)) == 0)
 			return (ENXIO);
-		addr += 64 * (di->bas.chan - 1);
+		addr += uart_getrange(class) * (di->bas.chan - 1);
 	} else if (!strcmp(buf, "zs")) {
-		di->ops = uart_z8530_ops;
+		class = &uart_z8530_class;
 		if ((di->bas.chan = uart_cpu_channel(dev)) == 0) {
 			/*
 			 * There's no way to determine from OF which
@@ -248,16 +250,19 @@
 				return (ENXIO);
 		}
 		di->bas.regshft = 1;
-		addr += 4 - 4 * (di->bas.chan - 1);
+		range = uart_getrange(class) << di->bas.regshft;
+		addr += range - range * (di->bas.chan - 1);
 	} else if (!strcmp(buf, "lom-console") || !strcmp(buf, "su") ||
 	    !strcmp(buf, "su_pnp") || !strcmp(compat, "rsc-console") ||
 	    !strcmp(compat, "su") || !strcmp(compat, "su16550")) {
-		di->ops = uart_ns8250_ops;
+		class = &uart_ns8250_class;
 		di->bas.chan = 0;
-	} else
+	}
+	if (class == NULL)
 		return (ENXIO);
 
 	/* Fill in the device info. */
+	di->ops = uart_getops(class);
 	di->bas.bst = &bst_store[devtype];
 	di->bas.bsh = sparc64_fake_bustag(space, addr, di->bas.bst);
 

==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#46 (text+ko) ====

@@ -220,7 +220,7 @@
 static int ns8250_poll(struct uart_bas *bas);
 static int ns8250_getc(struct uart_bas *bas, struct mtx *);
 
-struct uart_ops uart_ns8250_ops = {
+static struct uart_ops uart_ns8250_ops = {
 	.probe = ns8250_probe,
 	.init = ns8250_init,
 	.term = ns8250_term,
@@ -368,9 +368,10 @@
 };
 
 struct uart_class uart_ns8250_class = {
-	"ns8250 class",
+	"ns8250",
 	ns8250_methods,
 	sizeof(struct ns8250_softc),
+	.uc_ops = &uart_ns8250_ops,
 	.uc_range = 8,
 	.uc_rclk = DEFAULT_RCLK
 };

==== //depot/projects/uart/dev/uart/uart_dev_sab82532.c#42 (text+ko) ====

@@ -176,7 +176,7 @@
 static int sab82532_poll(struct uart_bas *bas);
 static int sab82532_getc(struct uart_bas *bas, struct mtx *);
 
-struct uart_ops uart_sab82532_ops = {
+static struct uart_ops uart_sab82532_ops = {
 	.probe = sab82532_probe,
 	.init = sab82532_init,
 	.term = sab82532_term,
@@ -384,9 +384,10 @@
 };
 
 struct uart_class uart_sab82532_class = {
-	"sab82532 class",
+	"sab82532",
 	sab82532_methods,
 	sizeof(struct sab82532_softc),
+	.uc_ops = &uart_sab82532_ops,
 	.uc_range = 64,
 	.uc_rclk = DEFAULT_RCLK
 };

==== //depot/projects/uart/dev/uart/uart_dev_z8530.c#33 (text+ko) ====

@@ -195,7 +195,7 @@
 static int z8530_poll(struct uart_bas *bas);
 static int z8530_getc(struct uart_bas *bas, struct mtx *);
 
-struct uart_ops uart_z8530_ops = {
+static struct uart_ops uart_z8530_ops = {
 	.probe = z8530_probe,
 	.init = z8530_init,
 	.term = z8530_term,
@@ -300,9 +300,10 @@
 };
 
 struct uart_class uart_z8530_class = {
-	"z8530 class",
+	"z8530",
 	z8530_methods,
 	sizeof(struct z8530_softc),
+	.uc_ops = &uart_z8530_ops,
 	.uc_range = 2,
 	.uc_rclk = DEFAULT_RCLK
 };

==== //depot/projects/uart/dev/uart/uart_kbd_sun.c#11 (text+ko) ====

@@ -719,8 +719,8 @@
 		if (*(int *)data & SLKED)
 			c |= SKBD_LED_SCROLLLOCK;
 		uart_lock(sc->sc_sysdev->hwmtx);
-		sc->sc_sysdev->ops.putc(&sc->sc_sysdev->bas, SKBD_CMD_SETLED);
-		sc->sc_sysdev->ops.putc(&sc->sc_sysdev->bas, c);
+		sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, SKBD_CMD_SETLED);
+		sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, c);
 		uart_unlock(sc->sc_sysdev->hwmtx);
 		KBD_LED_VAL(kbd) = *(int *)data;
 		break;

==== //depot/projects/uart/dev/uart/uart_subr.c#7 (text+ko) ====

@@ -54,6 +54,12 @@
 	return (strtoul(*p, (char**)(uintptr_t)p, 0));
 }
 
+static struct uart_class *
+uart_parse_class(struct uart_class *class, __const char **p)
+{
+	return (class);
+}
+
 static long
 uart_parse_long(__const char **p)
 {
@@ -161,10 +167,15 @@
  */
 
 int
-uart_getenv(int devtype, struct uart_devinfo *di)
+uart_getenv(int devtype, struct uart_devinfo *di, struct uart_class *class)
 {
 	__const char *spec;
 	bus_addr_t addr = ~0U;
+	int error;
+
+	/* We must get a valid default device class. */
+	if (class == NULL)
+		return (EDOOFUS);
 
 	/*
 	 * Check the environment variables "hw.uart.console" and
@@ -203,7 +214,7 @@
 			di->databits = uart_parse_long(&spec);
 			break;
 		case UART_TAG_DT:
-			return (EINVAL);	/* XXX not yet implemented. */
+			class = uart_parse_class(class, &spec);
 			break;
 		case UART_TAG_IO:
 			di->bas.bst = uart_bus_space_io;
@@ -261,8 +272,9 @@
 	} else
 		di->baudrate = 0;
 
-	/* XXX the size of the mapping depends on the UART class. */
-	if (bus_space_map(di->bas.bst, addr, 8, 0, &di->bas.bsh) != 0)
-		return (EINVAL);
-	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);
 }



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