From owner-p4-projects@FreeBSD.ORG Thu Jan 3 13:04:13 2013 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E334939F; Thu, 3 Jan 2013 13:04:12 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 9B70039D for ; Thu, 3 Jan 2013 13:04:12 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 7C67D727 for ; Thu, 3 Jan 2013 13:04:12 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.5/8.14.5) with ESMTP id r03D4CBa049616 for ; Thu, 3 Jan 2013 13:04:12 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.5/8.14.5/Submit) id r03D4B5u049613 for perforce@freebsd.org; Thu, 3 Jan 2013 13:04:11 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Thu, 3 Jan 2013 13:04:11 GMT Message-Id: <201301031304.r03D4B5u049613@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson Subject: PERFORCE change 219940 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.14 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Jan 2013 13:04:13 -0000 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 -/* - * 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); }