Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Apr 2006 21:24:14 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 95355 for review
Message-ID:  <200604152124.k3FLOE5H089293@repoman.freebsd.org>

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

Change 95355 by marcel@marcel_nfs on 2006/04/15 21:23:24

	o  Create child devices
	o  Probe and attach child devices

Affected files ...

.. //depot/projects/uart/dev/puc/puc.c#22 edit
.. //depot/projects/uart/dev/puc/pucvar.h#19 edit

Differences ...

==== //depot/projects/uart/dev/puc/puc.c#22 (text+ko) ====

@@ -113,16 +113,17 @@
 puc_attach(device_t dev)
 {
 	struct puc_bar *bar;
+	struct puc_port *port;
 	struct puc_softc *sc;
 	struct rman *rm;
 	intptr_t res;
 	u_long start;
-	int error, i, port;
+	int error, idx;
 
 	sc = device_get_softc(dev);
 
-	for (i = 0; i < PUC_PCI_BARS; i++)
-		sc->sc_bar[i].b_rid = -1;
+	for (idx = 0; idx < PUC_PCI_BARS; idx++)
+		sc->sc_bar[idx].b_rid = -1;
 
 	sc->sc_ioport.rm_type = RMAN_ARRAY;
 	sc->sc_ioport.rm_descr = "I/O port space";
@@ -143,13 +144,14 @@
 	sc->sc_port = malloc(sc->sc_nports * sizeof(struct puc_port),
 	    M_PUC, M_WAITOK|M_ZERO);
 
-	for (port = 0; port < sc->sc_nports; port++) {
-		sc->sc_port[port].p_nr = port + 1;
-		error = puc_query(sc->sc_cfg, PUC_QUERY_TYPE, port, &res);
+	for (idx = 0; idx < sc->sc_nports; idx++) {
+		port = &sc->sc_port[idx];
+		port->p_nr = idx + 1;
+		error = puc_query(sc->sc_cfg, PUC_QUERY_TYPE, idx, &res);
 		if (error)
 			goto fail;
-		sc->sc_port[port].p_type = res;
-		error = puc_query(sc->sc_cfg, PUC_QUERY_RID, port, &res);
+		port->p_type = res;
+		error = puc_query(sc->sc_cfg, PUC_QUERY_RID, idx, &res);
 		if (error)
 			goto fail;
 		bar = puc_get_bar(sc, res);
@@ -157,19 +159,30 @@
 			error = ENXIO;
 			goto fail;
 		}
-		sc->sc_port[port].p_bar = bar;
-		error = puc_query(sc->sc_cfg, PUC_QUERY_OFS, port, &res);
+		port->p_bar = bar;
+		error = puc_query(sc->sc_cfg, PUC_QUERY_OFS, idx, &res);
 		if (error)
 			goto fail;
 		start = rman_get_start(bar->b_res) + res;
-		error = puc_query(sc->sc_cfg, PUC_QUERY_LEN, port, &res);
+		error = puc_query(sc->sc_cfg, PUC_QUERY_LEN, idx, &res);
 		if (error)
 			goto fail;
 
 		rm = (bar->b_type == SYS_RES_IOPORT)
 		    ? &sc->sc_ioport: &sc->sc_iomem;
-		sc->sc_port[port].p_res = rman_reserve_resource(rm, start,
+		port->p_res = rman_reserve_resource(rm, start,
 		    start + res - 1, res, 0, sc->sc_dev);
+		if (port->p_res == NULL)
+			continue;
+
+		port->p_dev = device_add_child(dev, NULL, -1);
+		if (port->p_dev == NULL) {
+			rman_release_resource(port->p_res);
+			port->p_res = NULL;
+			continue;
+		}
+
+		device_set_ivars(port->p_dev, (void *)port);
 	}
 
 	sc->sc_irid = 0;
@@ -197,17 +210,31 @@
 		sc->sc_polled = 1;
 	}
 
+	/* Probe and attach our children. */
+	for (idx = 0; idx < sc->sc_nports; idx++) {
+		port = &sc->sc_port[idx];
+		error = device_probe_and_attach(port->p_dev);
+		if (error) {
+			device_delete_child(dev, port->p_dev);
+			port->p_dev = NULL;
+		}
+	}
+
 	return (0);
 
 fail:
-	for (port = 0; port < sc->sc_nports; port++) {
-		if (sc->sc_port[port].p_res != NULL)
-			rman_release_resource(sc->sc_port[port].p_res);
+	for (idx = 0; idx < sc->sc_nports; idx++) {
+		port = &sc->sc_port[idx];
+		if (port->p_dev != NULL)
+			device_delete_child(dev, port->p_dev);
+		if (port->p_res != NULL)
+			rman_release_resource(port->p_res);
 	}
-	for (i = 0; i < PUC_PCI_BARS; i++) {
-		if (sc->sc_bar[i].b_res != NULL)
-			bus_release_resource(sc->sc_dev, sc->sc_bar[i].b_type,
-			    sc->sc_bar[i].b_rid, sc->sc_bar[i].b_res);
+	for (idx = 0; idx < PUC_PCI_BARS; idx++) {
+		bar = &sc->sc_bar[idx];
+		if (bar->b_res != NULL)
+			bus_release_resource(sc->sc_dev, bar->b_type,
+			    bar->b_rid, bar->b_res);
 	}
 	rman_fini(&sc->sc_iomem);
 	rman_fini(&sc->sc_ioport);

==== //depot/projects/uart/dev/puc/pucvar.h#19 (text+ko) ====

@@ -40,6 +40,7 @@
 struct puc_port {
 	struct puc_bar	*p_bar;
 	struct resource	*p_res;
+	device_t	p_dev;
 	int		p_nr;
 	int		p_type;
 	int		p_rclk;



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