PERFORCE change 110037 for review
Marcel Moolenaar
marcel at FreeBSD.org
Wed Nov 15 16:59:21 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=110037
Change 110037 by marcel at 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);
}
More information about the p4-projects
mailing list