Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Jan 2013 13:04:11 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 219940 for review
Message-ID:  <201301031304.r03D4B5u049613@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@219940?ac=10

Change 219940 by rwatson@rwatson_zenith_cl_cam_ac_uk on 2013/01/03 13:03:38

	Rework altera_avgen(4) to cleanly(ish) separate nexus bus
	attachment from the driver itself.  This should allow us to
	plug in an fdt attachment more easily.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/conf/files#12 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/avgen/altera_avgen.c#8 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/avgen/altera_avgen.h#4 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/avgen/altera_avgen_nexus.c#2 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/conf/files#12 (text+ko) ====

@@ -638,6 +638,7 @@
 dev/alc/if_alc.c		optional alc pci
 dev/ale/if_ale.c		optional ale pci
 dev/altera/avgen/altera_avgen.c		optional altera_avgen
+dev/altera/avgen/altera_avgen_nexus.c	optional altera_avgen
 dev/altera/sdcard/altera_sdcard.c	optional altera_sdcard
 dev/altera/sdcard/altera_sdcard_disk.c	optional altera_sdcard
 dev/altera/sdcard/altera_sdcard_io.c	optional altera_sdcard

==== //depot/projects/ctsrd/beribsd/src/sys/dev/altera/avgen/altera_avgen.c#8 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2012 Robert N. M. Watson
+ * Copyright (c) 2012-2013 Robert N. M. Watson
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -226,13 +226,6 @@
 	return (0);
 }
 
-static int
-altera_avgen_nexus_probe(device_t dev)
-{
-
-	device_set_desc(dev, "Generic Altera Avalon device attachment");
-	return (BUS_PROBE_DEFAULT);
-}
 
 static int
 altera_avgen_process_options(struct altera_avgen_softc *sc,
@@ -321,42 +314,14 @@
 	return (0);
 }
 
-static int
-altera_avgen_nexus_attach(device_t dev)
+int
+altera_avgen_attach(struct altera_avgen_softc *sc, const char *str_fileio,
+    const char *str_mmapio, const char *str_devname, int devunit)
 {
-	struct altera_avgen_softc *sc;
-	const char *str_fileio, *str_mmapio;
-	const char *str_devname;
+	device_t dev = sc->avg_dev;
 	char devname[SPECNAMELEN + 1];
-	int devunit, error;
-
-	sc = device_get_softc(dev);
-	sc->avg_dev = dev;
-	sc->avg_unit = device_get_unit(dev);
+	int error;
 
-	/*
-	 * Query non-standard hints to find out what operations are permitted
-	 * on the device, and whether it is cached.
-	 */
-	str_fileio = NULL;
-	str_mmapio = NULL;
-	str_devname = NULL;
-	devunit = -1;
-	sc->avg_width = 1;
-	error = resource_int_value(device_get_name(dev), device_get_unit(dev),
-	    ALTERA_AVALON_STR_WIDTH, &sc->avg_width);
-	if (error != 0 && error != ENOENT) {
-		device_printf(dev, "invalid %s\n", ALTERA_AVALON_STR_WIDTH);
-		return (error);
-	}
-	(void)resource_string_value(device_get_name(dev),
-	    device_get_unit(dev), ALTERA_AVALON_STR_FILEIO, &str_fileio);
-	(void)resource_string_value(device_get_name(dev),
-	    device_get_unit(dev), ALTERA_AVALON_STR_MMAPIO, &str_mmapio);
-	(void)resource_string_value(device_get_name(dev),
-	    device_get_unit(dev), ALTERA_AVALON_STR_DEVNAME, &str_devname);
-	(void)resource_int_value(device_get_name(dev), device_get_unit(dev),
-	    ALTERA_AVALON_STR_DEVUNIT, &devunit);
 	error = altera_avgen_process_options(sc, str_fileio, str_mmapio,
 	    str_devname, devunit);
 	if (error)
@@ -374,25 +339,15 @@
 		snprintf(devname, sizeof(devname), "%s%d", "avgen",
 		    sc->avg_unit);
 
-	/* Memory allocation and checking. */
-	sc->avg_rid = 0;
-	sc->avg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
-	    &sc->avg_rid, RF_ACTIVE);
-	if (sc->avg_res == NULL) {
-		device_printf(dev, "couldn't map memory\n");
-		return (ENXIO);
-	}
 	if (rman_get_size(sc->avg_res) >= PAGE_SIZE || str_mmapio != NULL) {
 		if (rman_get_size(sc->avg_res) % PAGE_SIZE != 0) {
 			device_printf(dev,
 			    "memory region not even multiple of page size\n");
-			error = ENXIO;
-			goto error;
+			return (ENXIO);
 		}
 		if (rman_get_start(sc->avg_res) % PAGE_SIZE != 0) {
 			device_printf(dev, "memory region not page-aligned\n");
-			error = ENXIO;
-			goto error;
+			return (ENXIO);
 		}
 	}
 
@@ -409,43 +364,16 @@
 		    GID_WHEEL, S_IRUSR | S_IWUSR, str_devname);
 	if (sc->avg_cdev == NULL) {
 		device_printf(sc->avg_dev, "%s: make_dev failed\n", __func__);
-		error = ENXIO;
-		goto error;
+		return (ENXIO);
 	}
 	/* XXXRW: Slight race between make_dev(9) and here. */
 	sc->avg_cdev->si_drv1 = sc;
 	return (0);
-
-error:
-	bus_release_resource(dev, SYS_RES_MEMORY, sc->avg_rid, sc->avg_res);
-	return (error);
 }
 
-static int
-altera_avgen_nexus_detach(device_t dev)
+void
+altera_avgen_detach(struct altera_avgen_softc *sc)
 {
-	struct altera_avgen_softc *sc;
 
-	sc = device_get_softc(dev);
 	destroy_dev(sc->avg_cdev);
-	bus_release_resource(dev, SYS_RES_MEMORY, sc->avg_rid, sc->avg_res);
-	return (0);
 }
-
-static device_method_t altera_avgen_nexus_methods[] = {
-	DEVMETHOD(device_probe,		altera_avgen_nexus_probe),
-	DEVMETHOD(device_attach,	altera_avgen_nexus_attach),
-	DEVMETHOD(device_detach,	altera_avgen_nexus_detach),
-	{ 0, 0 }
-};
-
-static driver_t altera_avgen_nexus_driver = {
-	"altera_avgen",
-	altera_avgen_nexus_methods,
-	sizeof(struct altera_avgen_softc),
-};
-
-static devclass_t altera_avgen_devclass;
-
-DRIVER_MODULE(avgen, nexus, altera_avgen_nexus_driver, altera_avgen_devclass,
-    0, 0);

==== //depot/projects/ctsrd/beribsd/src/sys/dev/altera/avgen/altera_avgen.h#4 (text+ko) ====

@@ -77,7 +77,9 @@
 /*
  * Driver setup routines from the bus attachment/teardown.
  */
-int	altera_avgen_attach(struct altera_avgen_softc *sc);
+int	altera_avgen_attach(struct altera_avgen_softc *sc,
+	    const char *str_fileio, const char *str_mmapio,
+	    const char *str_devname, int devunit);
 void	altera_avgen_detach(struct altera_avgen_softc *sc);
 
 #endif /* _DEV_ALTERA_AVALON_H_ */

==== //depot/projects/ctsrd/beribsd/src/sys/dev/altera/avgen/altera_avgen_nexus.c#2 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2012 Robert N. M. Watson
+ * Copyright (c) 2012-2013 Robert N. M. Watson
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -53,179 +53,6 @@
 
 #include <dev/altera/avgen/altera_avgen.h>
 
-/*
- * Generic device driver for allowing read(), write(), and mmap() on
- * memory-mapped, Avalon-attached devices.  There is no actual dependence on
- * Avalon, so conceivably this should just be soc_dev or similar, since many
- * system-on-chip bus environments would work fine with the same code.
- */
-
-static d_mmap_t altera_avgen_mmap;
-static d_read_t altera_avgen_read;
-static d_write_t altera_avgen_write;
-
-static struct cdevsw avg_cdevsw = {
-	.d_version =	D_VERSION,
-	.d_mmap =	altera_avgen_mmap,
-	.d_read =	altera_avgen_read,
-	.d_write =	altera_avgen_write,
-	.d_name =	"altera_avgen",
-};
-
-static int
-altera_avgen_read(struct cdev *dev, struct uio *uio, int flag)
-{
-	struct altera_avgen_softc *sc;
-	u_long offset, size;
-#ifdef NOTYET
-	uint64_t v8;
-#endif
-	uint32_t v4;
-	uint16_t v2;
-	uint8_t v1;
-	u_int width;
-	int error;
-
-	sc = dev->si_drv1;
-	if ((sc->avg_flags & ALTERA_AVALON_FLAG_READ) == 0)
-		return (EACCES);
-	width = sc->avg_width;
-	if (uio->uio_offset < 0 || uio->uio_offset % width != 0 ||
-	    uio->uio_resid % width != 0)
-		return (ENODEV);
-	size = rman_get_size(sc->avg_res);
-	if ((uio->uio_offset + uio->uio_resid < 0) ||
-	    (uio->uio_offset + uio->uio_resid > size))
-		return (ENODEV);
-	while (uio->uio_resid > 0) {
-		offset = uio->uio_offset;
-		if (offset + width > size)
-			return (ENODEV);
-		switch (width) {
-		case 1:
-			v1 = bus_read_1(sc->avg_res, offset);
-			error = uiomove(&v1, sizeof(v1), uio);
-			break;
-			
-		case 2:
-			v2 = bus_read_2(sc->avg_res, offset);
-			error = uiomove(&v2, sizeof(v2), uio);
-			break;
-			
-		case 4:
-			v4 = bus_read_4(sc->avg_res, offset);
-			error = uiomove(&v4, sizeof(v4), uio);
-			break;
-			
-#ifdef NOTYET
-		case 8:
-			v8 = bus_read_8(sc->avg_res, offset);
-			error = uiomove(&v8, sizeof(v8), uio);
-			break;
-			
-#endif
-
-		default:
-			panic("%s: unexpected widthment %u", __func__, width);
-		}
-		if (error)
-			return (error);
-	}
-	return (0);
-}
-
-static int
-altera_avgen_write(struct cdev *dev, struct uio *uio, int flag)
-{
-	struct altera_avgen_softc *sc;
-	u_long offset, size;
-#ifdef NOTYET
-	uint64_t v8;
-#endif
-	uint32_t v4;
-	uint16_t v2;
-	uint8_t v1;
-	u_int width;
-	int error;
-
-	sc = dev->si_drv1;
-	if ((sc->avg_flags & ALTERA_AVALON_FLAG_WRITE) == 0)
-		return (EACCES);
-	width = sc->avg_width;
-	if (uio->uio_offset < 0 || uio->uio_offset % width != 0 ||
-	    uio->uio_resid % width != 0)
-		return (ENODEV);
-	size = rman_get_size(sc->avg_res);
-	while (uio->uio_resid > 0) {
-		offset = uio->uio_offset;
-		if (offset + width > size)
-			return (ENODEV);
-		switch (width) {
-		case 1:
-			error = uiomove(&v1, sizeof(v1), uio);
-			if (error)
-				return (error);
-			bus_write_1(sc->avg_res, offset, v1);
-			break;
-
-		case 2:
-			error = uiomove(&v2, sizeof(v2), uio);
-			if (error)
-				return (error);
-			bus_write_2(sc->avg_res, offset, v2);
-			break;
-
-		case 4:
-			error = uiomove(&v4, sizeof(v4), uio);
-			if (error)
-				return (error);
-			bus_write_4(sc->avg_res, offset, v4);
-			break;
-
-#ifdef NOTYET
-		case 8:
-			error = uiomove(&v8, sizeof(v8), uio);
-			if (error)
-				return (error);
-			bus_write_8(sc->avg_res, offset, v8);
-			break;
-#endif
-
-		default:
-			panic("%s: unexpected width %u", __func__, width);
-		}
-	}
-	return (0);
-}
-
-static int
-altera_avgen_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
-    int nprot, vm_memattr_t *memattr)
-{
-	struct altera_avgen_softc *sc;
-
-	sc = dev->si_drv1;
-	if (nprot & VM_PROT_READ) {
-		if ((sc->avg_flags & ALTERA_AVALON_FLAG_MMAP_READ) == 0)
-			return (EACCES);
-	}
-	if (nprot & VM_PROT_WRITE) {
-		if ((sc->avg_flags & ALTERA_AVALON_FLAG_MMAP_WRITE) == 0)
-			return (EACCES);
-	}
-	if (nprot & VM_PROT_EXECUTE) {
-		if ((sc->avg_flags & ALTERA_AVALON_FLAG_MMAP_EXEC) == 0)
-			return (EACCES);
-	}
-	if (trunc_page(offset) == offset &&
-	    rman_get_size(sc->avg_res) >= offset + PAGE_SIZE) {
-		*paddr = rman_get_start(sc->avg_res) + offset;
-		*memattr = VM_MEMATTR_UNCACHEABLE;
-	} else
-		return (ENODEV);
-	return (0);
-}
-
 static int
 altera_avgen_nexus_probe(device_t dev)
 {
@@ -235,99 +62,11 @@
 }
 
 static int
-altera_avgen_process_options(struct altera_avgen_softc *sc,
-    const char *str_fileio, const char *str_mmapio, const char *str_devname,
-    int devunit)
-{
-	const char *cp;
-	device_t dev = sc->avg_dev;
-
-	/*
-	 * Check for valid combinations of options.
-	 */
-	if (str_fileio == NULL && str_mmapio == NULL) {
-		device_printf(dev,
-		    "at least one of %s or %s must be specified\n",
-		    ALTERA_AVALON_STR_FILEIO, ALTERA_AVALON_STR_MMAPIO);
-		return (ENXIO);
-	}
-	if (str_devname == NULL && devunit != -1) {
-		device_printf(dev, "%s requires %s be specified\n",
-		    ALTERA_AVALON_STR_DEVUNIT, ALTERA_AVALON_STR_DEVNAME);
-		return (ENXIO);
-	}
-
-	/*
-	 * Extract, digest, and save values.
-	 */
-	switch (sc->avg_width) {
-	case 1:
-	case 2:
-	case 4:
-#ifdef NOTYET
-	case 8:
-#endif
-		break;
-
-	default:
-		device_printf(dev, "%s unsupported value %u\n",
-		    ALTERA_AVALON_STR_WIDTH, sc->avg_width);
-		return (ENXIO);
-	}
-	sc->avg_flags = 0;
-	if (str_fileio != NULL) {
-		for (cp = str_fileio; *cp != '\0'; cp++) {
-			switch (*cp) {
-			case ALTERA_AVALON_CHAR_READ:
-				sc->avg_flags |= ALTERA_AVALON_FLAG_READ;
-				break;
-
-			case ALTERA_AVALON_CHAR_WRITE:
-				sc->avg_flags |= ALTERA_AVALON_FLAG_WRITE;
-				break;
-
-			default:
-				device_printf(dev,
-				    "invalid %s character %c\n", 
-				    ALTERA_AVALON_STR_FILEIO, *cp);
-				return (ENXIO);
-			}
-		}
-	}
-	if (str_mmapio != NULL) {
-		for (cp = str_mmapio; *cp != '\0'; cp++) {
-			switch (*cp) {
-			case ALTERA_AVALON_CHAR_READ:
-				sc->avg_flags |= ALTERA_AVALON_FLAG_MMAP_READ;
-				break;
-
-			case ALTERA_AVALON_CHAR_WRITE:
-				sc->avg_flags |=
-				    ALTERA_AVALON_FLAG_MMAP_WRITE;
-				break;
-
-			case ALTERA_AVALON_CHAR_EXEC:
-				sc->avg_flags |= ALTERA_AVALON_FLAG_MMAP_EXEC;
-				break;
-
-			default:
-				device_printf(dev,
-				    "invalid %s character %c\n",
-				    ALTERA_AVALON_STR_MMAPIO, *cp);
-				return (ENXIO);
-			}
-		}
-	}
-	return (0);
-}
-
-static int
 altera_avgen_nexus_attach(device_t dev)
 {
 	struct altera_avgen_softc *sc;
 	const char *str_fileio, *str_mmapio;
 	const char *str_devname;
-	char devname[SPECNAMELEN + 1];
 	int devunit, error;
 
 	sc = device_get_softc(dev);
@@ -357,22 +96,6 @@
 	    device_get_unit(dev), ALTERA_AVALON_STR_DEVNAME, &str_devname);
 	(void)resource_int_value(device_get_name(dev), device_get_unit(dev),
 	    ALTERA_AVALON_STR_DEVUNIT, &devunit);
-	error = altera_avgen_process_options(sc, str_fileio, str_mmapio,
-	    str_devname, devunit);
-	if (error)
-		return (error);
-
-	/* Select a device name. */
-	if (str_devname != NULL) {
-		if (devunit != -1)
-			(void)snprintf(devname, sizeof(devname), "%s%d",
-			    str_devname, devunit);
-		else
-			(void)snprintf(devname, sizeof(devname), "%s",
-			    str_devname);
-	} else
-		snprintf(devname, sizeof(devname), "%s%d", "avgen",
-		    sc->avg_unit);
 
 	/* Memory allocation and checking. */
 	sc->avg_rid = 0;
@@ -382,42 +105,11 @@
 		device_printf(dev, "couldn't map memory\n");
 		return (ENXIO);
 	}
-	if (rman_get_size(sc->avg_res) >= PAGE_SIZE || str_mmapio != NULL) {
-		if (rman_get_size(sc->avg_res) % PAGE_SIZE != 0) {
-			device_printf(dev,
-			    "memory region not even multiple of page size\n");
-			error = ENXIO;
-			goto error;
-		}
-		if (rman_get_start(sc->avg_res) % PAGE_SIZE != 0) {
-			device_printf(dev, "memory region not page-aligned\n");
-			error = ENXIO;
-			goto error;
-		}
-	}
-
-	/* Device node allocation. */
-	if (str_devname == NULL) {
-		str_devname = "altera_avgen%d";
-		devunit = sc->avg_unit;
-	}
-	if (devunit != -1)
-		sc->avg_cdev = make_dev(&avg_cdevsw, sc->avg_unit, UID_ROOT,
-		    GID_WHEEL, S_IRUSR | S_IWUSR, str_devname, devunit);
-	else
-		sc->avg_cdev = make_dev(&avg_cdevsw, sc->avg_unit, UID_ROOT,
-		    GID_WHEEL, S_IRUSR | S_IWUSR, str_devname);
-	if (sc->avg_cdev == NULL) {
-		device_printf(sc->avg_dev, "%s: make_dev failed\n", __func__);
-		error = ENXIO;
-		goto error;
-	}
-	/* XXXRW: Slight race between make_dev(9) and here. */
-	sc->avg_cdev->si_drv1 = sc;
-	return (0);
-
-error:
-	bus_release_resource(dev, SYS_RES_MEMORY, sc->avg_rid, sc->avg_res);
+	error = altera_avgen_attach(sc, str_fileio, str_mmapio, str_devname,
+	    devunit);
+	if (error != 0)
+		bus_release_resource(dev, SYS_RES_MEMORY, sc->avg_rid,
+		    sc->avg_res);
 	return (error);
 }
 
@@ -427,7 +119,7 @@
 	struct altera_avgen_softc *sc;
 
 	sc = device_get_softc(dev);
-	destroy_dev(sc->avg_cdev);
+	altera_avgen_detach(sc);
 	bus_release_resource(dev, SYS_RES_MEMORY, sc->avg_rid, sc->avg_res);
 	return (0);
 }



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