PERFORCE change 34229 for review

Marcel Moolenaar marcel at FreeBSD.org
Tue Jul 8 23:50:50 PDT 2003


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

Change 34229 by marcel at marcel_nfs on 2003/07/08 23:50:01

	Fix a braino. We cannot replace the softc in the probe()
	method because it will mess up bus_probe_and_attach().
	An external softc will not be replaced by the core bus
	functions.
	Instead, replace the softc in the attach() method. Hence,
	hardware drivers cannot use any of the hardware instance
	members during probe().

Affected files ...

.. //depot/projects/uart/dev/uart/uart_core.c#5 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#5 edit

Differences ...

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

@@ -167,22 +167,17 @@
 int
 uart_bus_probe(device_t dev, int regshft, int rclk, int rid)
 {
-	struct uart_softc *sc, *sc0;
+	struct uart_softc *sc;
 	int error;
 
 	/*
-	 * The sc_class field defines the type of UART we're going to work
-	 * with and thus the size of the softc. Replace the generic softc
-	 * with one that matches the UART and initialize it. Initialization
-	 * also compiles the class if not already compiled. We also set the
-	 * initial device description equal to the UART class name, unless
-	 * a description has already been set. This name can be overwritten
-	 * with a more specific description later on.
+	 * 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.
 	 */
-	sc0 = device_get_softc(dev);
-	sc = malloc(sc0->sc_class->size, M_UART, M_WAITOK|M_ZERO);
-	bcopy(sc0, sc, sizeof(*sc));
-	device_set_softc(dev, sc);
+	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)
@@ -239,11 +234,20 @@
 int
 uart_bus_attach(device_t dev)
 {
-	struct uart_softc *sc;
+	struct uart_softc *sc, *sc0;
 	const char *sep;
 	int error;
 
-	sc = device_get_softc(dev);
+	/*
+	 * The sc_class field defines the type of UART we're going to work
+	 * with and thus the size of the softc. Replace the generic softc
+	 * with one that matches the UART now that we're certain we handle
+	 * the device.
+	 */
+	sc0 = device_get_softc(dev);
+	sc = malloc(sc0->sc_class->size, M_UART, M_WAITOK|M_ZERO);
+	bcopy(sc0, sc, sizeof(*sc));
+	device_set_softc(dev, sc);
 
 	/*
 	 * Re-allocate. We expect that the softc contains the information

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

@@ -367,9 +367,9 @@
 static int
 ns8250_bus_probe(struct uart_softc *sc)
 {
-	struct ns8250_softc *ns8250 = (struct ns8250_softc *)sc;
 	struct uart_bas *bas;
 	int count, delay, error, limit;
+	uint8_t mcr;
 
 	bas = &sc->sc_bas;
 
@@ -377,12 +377,12 @@
 	if (error)
 		return (error);
 
-	ns8250->mcr = MCR_IENABLE;
+	mcr = MCR_IENABLE;
 	if (!sc->sc_console && !sc->sc_dbgport) {
 		/* By using ns8250_init() we also set DTR and RTS. */
 		ns8250_init(bas, 9600, 8, 1, UART_PARITY_NONE);
 	} else
-		ns8250->mcr |= MCR_DTR | MCR_RTS;
+		mcr |= MCR_DTR | MCR_RTS;
 
 	error = ns8250_flush(bas, UART_FLUSH_TRANSMITTER);
 	if (error)
@@ -412,7 +412,7 @@
 		 * NS16450 or INS8250. We don't bother to differentiate
 		 * between them. They're too old to be interesting.
 		 */
-		uart_setreg(bas, REG_MCR, ns8250->mcr);
+		uart_setreg(bas, REG_MCR, mcr);
 		uart_barrier(bas);
 		device_set_desc(sc->sc_dev, "8250 or 16450 or compatible");
 		return (0);
@@ -428,7 +428,7 @@
 	/* We have FIFOs. Flush the transmitter and receiver. */
 	error = ns8250_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
 	if (error) {
-		uart_setreg(bas, REG_MCR, ns8250->mcr);
+		uart_setreg(bas, REG_MCR, mcr);
 		uart_setreg(bas, REG_FCR, 0);
 		uart_barrier(bas);
 		goto describe;
@@ -454,7 +454,7 @@
 			DELAY(delay);
 		if (limit == 0) {
 			uart_setreg(bas, REG_IER, 0);
-			uart_setreg(bas, REG_MCR, ns8250->mcr);
+			uart_setreg(bas, REG_MCR, mcr);
 			uart_setreg(bas, REG_FCR, 0);
 			uart_barrier(bas);
 			count = 0;
@@ -463,11 +463,10 @@
 	}
 
 	uart_setreg(bas, REG_IER, 0);
-	uart_setreg(bas, REG_MCR, ns8250->mcr);
+	uart_setreg(bas, REG_MCR, mcr);
 
 	/* Reset FIFOs. */
-	ns8250->fcr = FCR_ENABLE;
-	uart_setreg(bas, REG_FCR, ns8250->fcr | FCR_XMT_RST | FCR_RCV_RST);
+	uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST);
 	uart_barrier(bas);
 
  describe:


More information about the p4-projects mailing list