Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Apr 2006 16:30:02 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 95383 for review
Message-ID:  <200604161630.k3GGU2d6052348@repoman.freebsd.org>

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

Change 95383 by marcel@marcel_nfs on 2006/04/16 16:29:03

	o  Set the bus tag and handle on the resources we create.
	o  Implement bus_alloc_resource().

Affected files ...

.. //depot/projects/uart/dev/puc/puc.c#23 edit

Differences ...

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

@@ -117,7 +117,10 @@
 	struct puc_softc *sc;
 	struct rman *rm;
 	intptr_t res;
-	u_long start;
+	bus_addr_t ofs, start;
+	bus_size_t size;
+	bus_space_handle_t bsh;
+	bus_space_tag_t bst;
 	int error, idx;
 
 	sc = device_get_softc(dev);
@@ -160,29 +163,30 @@
 			goto fail;
 		}
 		port->p_bar = bar;
+		start = rman_get_start(bar->b_res);
 		error = puc_query(sc->sc_cfg, PUC_QUERY_OFS, idx, &res);
 		if (error)
 			goto fail;
-		start = rman_get_start(bar->b_res) + res;
+		ofs = res;
 		error = puc_query(sc->sc_cfg, PUC_QUERY_LEN, idx, &res);
 		if (error)
 			goto fail;
-
+		size = res;
 		rm = (bar->b_type == SYS_RES_IOPORT)
 		    ? &sc->sc_ioport: &sc->sc_iomem;
-		port->p_res = rman_reserve_resource(rm, start,
-		    start + res - 1, res, 0, sc->sc_dev);
-		if (port->p_res == NULL)
-			continue;
+		port->p_res = rman_reserve_resource(rm, start + ofs,
+		    start + ofs + size - 1, size, 0, sc->sc_dev);
+		if (port->p_res != NULL) {
+			bsh = rman_get_bushandle(bar->b_res);
+			bst = rman_get_bustag(bar->b_res);
+			bus_space_subregion(bst, bsh, ofs, size, &bsh);
+			rman_set_bushandle(port->p_res, bsh);
+			rman_set_bustag(port->p_res, bst);
+		}
 
 		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);
+		if (port->p_dev != NULL)
+			device_set_ivars(port->p_dev, (void *)port);
 	}
 
 	sc->sc_irid = 0;
@@ -213,6 +217,8 @@
 	/* Probe and attach our children. */
 	for (idx = 0; idx < sc->sc_nports; idx++) {
 		port = &sc->sc_port[idx];
+		if (port->p_dev == NULL)
+			continue;
 		error = device_probe_and_attach(port->p_dev);
 		if (error) {
 			device_delete_child(dev, port->p_dev);
@@ -269,8 +275,11 @@
 puc_alloc_resource(device_t dev, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
 {
-	struct puc_port *p;
+	struct puc_port *port;
+	u_int fl;
+	int error;
 
+	/* Get our immediate child. */
 	while (child != NULL && device_get_parent(child) != dev)
 		child = device_get_parent(child);
 	if (child == NULL)
@@ -280,8 +289,22 @@
 	if (*rid != 0 || start != 0UL || end != ~0UL)
 		return (NULL);
 
-	p = device_get_ivars(child);
-	return (NULL);
+	port = device_get_ivars(child);
+	if (port->p_res == NULL)
+		return (NULL);
+	if (rman_get_device(port->p_res) == dev)
+		rman_set_device(port->p_res, child);
+	else if (rman_get_device(port->p_res) != child)
+		return (NULL);
+	fl = rman_get_flags(port->p_res);
+	if ((flags & RF_ACTIVE) != 0 && (fl & RF_ACTIVE) == 0) {
+		error = rman_activate_resource(port->p_res);
+		if (error) {
+			rman_set_device(port->p_res, dev);
+			return (NULL);
+		}
+	}
+	return (port->p_res);
 }
 
 int
@@ -290,6 +313,7 @@
 {
 	struct puc_port *p;
 
+	/* Get our immediate child. */
 	while (child != NULL && device_get_parent(child) != dev)
 		child = device_get_parent(child);
 	if (child == NULL)
@@ -347,21 +371,22 @@
 int
 puc_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
 {
-	struct puc_port *p;
+	struct puc_port *port;
 
+	/* Get our immediate child. */
 	while (child != NULL && device_get_parent(child) != dev)
 		child = device_get_parent(child);
 	if (child == NULL)
 		return (EINVAL);
 
-	p = device_get_ivars(child);
+	port = device_get_ivars(child);
 
 	switch(index) {
 	case PUC_IVAR_CLOCK:
-		*result = p->p_rclk;
+		*result = port->p_rclk;
 		break;
 	case PUC_IVAR_TYPE:
-		*result = p->p_type;
+		*result = port->p_type;
 		break;
 	default:
 		return (ENOENT);



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