Can not boot 7.0-BETA3 with puc

Frank Behrens frank at pinky.sax.de
Fri Nov 23 06:57:24 PST 2007


Hi, dear FreeBSD developers!

Frank Behrens <frank at pinky.sax.de> wrote on 23 Nov 2007 11:20:
> 1. The sio(4) does not attach as in RELENG_6 to the ports provided by puc(4) driver. In 
> RELENG_7 it shows as
> 
> puc0: <Oxford Semiconductor OX16PCI954 UARTs> port 0xdf00-0xdf1f,0xdec0-0xdedf mem 0xfe6f8000-0xfe6f8fff,0xfe6f7000-0xfe6f7fff irq 21 at device 13.0 on pci2
> puc0: Reserved 0x20 bytes for rid 0x10 type 4 at 0xdf00
> ioapic0: routing intpin 21 (PCI IRQ 21) to vector 54
> puc0: [FILTER]
> sio0 on puc0
> sio0: type 16550A, console
> sio0: [FILTER]
> sio1: reserved for low-level i/o
> 
> where RELENG_6 shows
> 
> puc0: <Oxford Semiconductor OX16PCI954 UARTs> port 0xdf00-0xdf1f,0xdec0-0xdedf mem 0xfe6f8000-0xfe6f8fff,0xfe6f7000-0xfe6f7fff irq 21 at device 13.0 on pci2
> sio4: <Oxford Semiconductor OX16PCI954 UARTs> on puc0
> sio4: type 16550A
> sio4: unable to activate interrupt in fast mode - using normal mode
> sio5: <Oxford Semiconductor OX16PCI954 UARTs> on puc0
> sio5: type 16550A
> sio5: unable to activate interrupt in fast mode - using normal mode
> ....
> sio0: <16550A-compatible COM port> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0
> sio0: type 16550A, console
> sio1: reserved for low-level i/o

Meanwhile I was able to restore the previous behavior. My RELENG_7 kernel boots with right 
sio port assignments. :-))

IMHO the reason for the error in 7.0 is, that it calls device_add_child(dev, NULL, -1);
The unit is not determined, so the bus subsystem assigns the 1st sio unit. That is 0 and 
wrong in my case. The patch uses some code from RELENG_6 to determine the 1st free sio 
unit. I know this is a hack, but you should see, where the problem is to be searched.

Regards,
    Frank

===================================================================
RCS file: /data/freebsd/src/sys/dev/puc/puc.c,v
retrieving revision 1.50
diff -u -w -p -r1.50 puc.c
--- puc.c	6 Jun 2007 22:17:01 -0000	1.50
+++ puc.c	23 Nov 2007 14:17:29 -0000
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD: src/sys/dev/puc/puc.
 #include <dev/puc/puc_bfe.h>
 
 #define	PUC_ISRCCNT	5
+#define PUC_DEBUG	1
 
 struct puc_port {
 	struct puc_bar	*p_bar;
@@ -70,6 +71,31 @@ const char puc_driver_name[] = "puc";
 
 MALLOC_DEFINE(M_PUC, "PUC", "PUC driver");
 
+
+static int
+puc_find_free_unit(device_t dev, char *name)
+{
+        devclass_t dc;
+        int start;
+        int unit;
+
+        unit = 0;
+        start = 0;
+        while (resource_int_value(name, unit, "port", &start) == 0 &&
+            start > 0)
+                unit++;
+        dc = devclass_find(name);
+        if (dc == NULL)
+                return (-1);
+        while (devclass_get_device(dc, unit))
+                unit++;
+#if PUC_DEBUG
+        device_printf(dev, "Using %s%d\n", name, unit);
+#endif
+        return (unit);
+}
+
+
 struct puc_bar *
 puc_get_bar(struct puc_softc *sc, int rid)
 {
@@ -201,6 +227,13 @@ puc_bfe_attach(device_t dev)
 	bus_space_handle_t bsh;
 	bus_space_tag_t bst;
 	int error, idx;
+#if PUC_DEBUG
+	int oldverbose = bootverbose;
+        bootverbose = 1;
+
+        device_printf(dev, "puc_bfe_attach\n");
+#endif
+
 
 	sc = device_get_softc(dev);
 
@@ -296,9 +329,16 @@ puc_bfe_attach(device_t dev)
 			goto fail;
 		port->p_rclk = res;
 
-		port->p_dev = device_add_child(dev, NULL, -1);
+		port->p_dev = device_add_child(dev, "sio", puc_find_free_unit(dev, "sio"));
 		if (port->p_dev != NULL)
 			device_set_ivars(port->p_dev, (void *)port);
+#if PUC_DEBUG
+                device_printf(dev, "child attached: nr %d, start %x, offset %x, dev %s\n",
+                    port->p_nr,
+                    start,
+                    ofs,
+		    device_get_nameunit(port->p_dev));
+#endif
 	}
 
 	error = puc_config(sc, PUC_CFG_GET_ILR, 0, &res);
@@ -352,6 +392,10 @@ puc_bfe_attach(device_t dev)
 	if (sc->sc_serdevs == 0UL)
 		bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie);
 
+#if PUC_DEBUG
+        bootverbose = oldverbose;
+#endif
+
 	return (0);
 
 fail:
@@ -377,6 +421,9 @@ fail:
 	rman_fini(&sc->sc_ioport);
 	free(__DECONST(void *, sc->sc_ioport.rm_descr), M_PUC);
 	free(sc->sc_port, M_PUC);
+#if PUC_DEBUG
+        bootverbose = oldverbose;
+#endif
 	return (error);
 }
 
-- 
Frank Behrens, Osterwieck, Germany
PGP-key 0x5B7C47ED on public servers available.



More information about the freebsd-current mailing list