PERFORCE change 110092 for review

Marcel Moolenaar marcel at FreeBSD.org
Thu Nov 16 03:20:40 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=110092

Change 110092 by marcel at marcel_nfs on 2006/11/16 03:19:58

	Declare the classes as weak. This allows device driver classes
	to be compiled-out without causing unresolved symbols.
	Implement the DT tag fully.

Affected files ...

.. //depot/projects/uart/dev/uart/uart.h#12 edit
.. //depot/projects/uart/dev/uart/uart_core.c#56 edit
.. //depot/projects/uart/dev/uart/uart_cpu.h#21 edit
.. //depot/projects/uart/dev/uart/uart_cpu_amd64.c#12 edit
.. //depot/projects/uart/dev/uart/uart_cpu_i386.c#13 edit
.. //depot/projects/uart/dev/uart/uart_cpu_ia64.c#14 edit
.. //depot/projects/uart/dev/uart/uart_cpu_pc98.c#14 edit
.. //depot/projects/uart/dev/uart/uart_cpu_powerpc.c#3 edit
.. //depot/projects/uart/dev/uart/uart_subr.c#8 edit

Differences ...

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

@@ -64,10 +64,9 @@
  */
 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;
+extern struct uart_class uart_ns8250_class __attribute__((weak));
+extern struct uart_class uart_sab82532_class __attribute__((weak));
+extern struct uart_class uart_z8530_class __attribute__((weak));
 
 /*
  * Device flags.

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

@@ -70,16 +70,22 @@
 	SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
 }
 
+const char *
+uart_getname(struct uart_class *uc)
+{
+	return ((uc != NULL) ? uc->name : NULL);
+}
+
 struct uart_ops *
 uart_getops(struct uart_class *uc)
 {
-	return (uc->uc_ops);
+	return ((uc != NULL) ? uc->uc_ops : NULL);
 }
 
 int
 uart_getrange(struct uart_class *uc)
 {
-	return (uc->uc_range);
+	return ((uc != NULL) ? uc->uc_range : 0);
 }
 
 /*
@@ -303,18 +309,26 @@
 	struct uart_devinfo *sysdev;
 	int error;
 
+	sc = device_get_softc(dev);
+
 	/*
+	 * All uart_class references are weak. Check that the needed
+	 * class has been compiled-in. Fail if not.
+	 */
+	if (sc->sc_class == NULL)
+		return (ENXIO);
+
+	/*
 	 * Initialize the instance. Note that the instance (=softc) does
 	 * not necessarily match the hardware specific softc. We can't do
 	 * anything about it now, because we may not attach to the device.
 	 * Hardware drivers cannot use any of the class specific fields
 	 * while probing.
 	 */
-	sc = device_get_softc(dev);
 	kobj_init((kobj_t)sc, (kobj_class_t)sc->sc_class);
 	sc->sc_dev = dev;
 	if (device_get_desc(dev) == NULL)
-		device_set_desc(dev, sc->sc_class->name);
+		device_set_desc(dev, uart_getname(sc->sc_class));
 
 	/*
 	 * Allocate the register resource. We assume that all UARTs have
@@ -326,12 +340,13 @@
 	sc->sc_rrid = rid;
 	sc->sc_rtype = SYS_RES_IOPORT;
 	sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
-	    0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
+	    0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE);
 	if (sc->sc_rres == NULL) {
 		sc->sc_rrid = rid;
 		sc->sc_rtype = SYS_RES_MEMORY;
 		sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype,
-		    &sc->sc_rrid, 0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
+		    &sc->sc_rrid, 0, ~0, uart_getrange(sc->sc_class),
+		    RF_ACTIVE);
 		if (sc->sc_rres == NULL)
 			return (ENXIO);
 	}
@@ -400,7 +415,7 @@
 	 * collected by uart_bus_probe() intact.
 	 */
 	sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
-	    0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
+	    0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE);
 	if (sc->sc_rres == NULL) {
 		mtx_destroy(&sc->sc_hwmtx_s);
 		return (ENXIO);

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

@@ -74,6 +74,7 @@
 int uart_cpu_getdev(int, struct uart_devinfo *);
 
 int uart_getenv(int, struct uart_devinfo *, struct uart_class *);
+const char *uart_getname(struct uart_class *);
 struct uart_ops *uart_getops(struct uart_class *);
 int uart_getrange(struct uart_class *);
 

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

@@ -53,6 +53,8 @@
 	unsigned int i, ivar;
 
 	class = &uart_ns8250_class;
+	if (class == NULL)
+		return (ENXIO);
 
 	/* Check the environment. */
 	if (uart_getenv(devtype, di, class) == 0)

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

@@ -53,6 +53,8 @@
 	unsigned int i, ivar;
 
 	class = &uart_ns8250_class;
+	if (class == NULL)
+		return (ENXIO);
 
 	/* Check the environment. */
 	if (uart_getenv(devtype, di, class) == 0)

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

@@ -65,6 +65,8 @@
 	unsigned int i;
 
 	class = &uart_ns8250_class;
+	if (class == NULL)
+		return (ENXIO);
 
 	/*
 	 * Use the DIG64 HCDP table if present.

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

@@ -53,6 +53,8 @@
 	unsigned int i, ivar, flags;
 
 	class = &uart_ns8250_class;
+	if (class == NULL)
+		return (ENXIO);
 
 	/* Check the environment. */
 	if (uart_getenv(devtype, di, class) == 0)

==== //depot/projects/uart/dev/uart/uart_cpu_powerpc.c#3 (text) ====

@@ -52,9 +52,14 @@
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
 	char buf[64];
+	struct uart_class *class;
 	phandle_t input, opts;
 	int error;
 
+	class = &uart_z8530_class;
+	if (class == NULL)
+		return (ENXIO);
+
 	if ((opts = OF_finddevice("/options")) == -1)
 		return (ENXIO);
 	switch (devtype) {
@@ -93,7 +98,7 @@
 	if (error)
 		return (error);
 
-	di->ops = uart_z8530_ops;
+	di->ops = uart_getops(class);
 
 	di->bas.rclk = 230400;
 	di->bas.chan = 1;

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

@@ -48,6 +48,13 @@
 #define	UART_TAG_SB	8
 #define	UART_TAG_XO	9
 
+static struct uart_class *uart_classes[] = {
+	&uart_ns8250_class,
+	&uart_sab82532_class,
+	&uart_z8530_class,
+};
+static size_t uart_nclasses = sizeof(uart_classes) / sizeof(uart_classes[0]);
+
 static bus_addr_t
 uart_parse_addr(__const char **p)
 {
@@ -57,6 +64,22 @@
 static struct uart_class *
 uart_parse_class(struct uart_class *class, __const char **p)
 {
+	struct uart_class *uc;
+	const char *nm;
+	size_t len;
+	u_int i;
+
+	for (i = 0; i < uart_nclasses; i++) {
+		uc = uart_classes[i];
+		nm = uart_getname(uc);
+		if (nm == NULL || *nm == '\0')
+			continue;
+		len = strlen(nm);
+		if (strncmp(nm, *p, len) == 0) {
+			*p += len;
+			return (uc);
+		}
+	}
 	return (class);
 }
 
@@ -173,9 +196,12 @@
 	bus_addr_t addr = ~0U;
 	int error;
 
-	/* We must get a valid default device class. */
+	/*
+	 * All uart_class references are weak. Make sure the default
+	 * device class has been compiled-in.
+	 */
 	if (class == NULL)
-		return (EDOOFUS);
+		return (ENXIO);
 
 	/*
 	 * Check the environment variables "hw.uart.console" and


More information about the p4-projects mailing list