Date: Sun, 10 Aug 2008 23:56:48 GMT From: Fritz Katz <frtzkatz@yahoo.com> To: freebsd-gnats-submit@FreeBSD.org Subject: misc/126435: FreeBSD example: make_pseudo_driver.sh fails to compile. Message-ID: <200808102356.m7ANumRB095388@www.freebsd.org> Resent-Message-ID: <200808110000.m7B00BRl053363@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 126435 >Category: misc >Synopsis: FreeBSD example: make_pseudo_driver.sh fails to compile. >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Aug 11 00:00:10 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Fritz Katz >Release: 7.0-RELEASE i386 >Organization: AAArt >Environment: FreeBSD nvdev.aaart.com 7.0-RELEASE FreeBSD 7.0-RELEASE #0: Wed May 21 13:31:32 PDT 2008 root@nvdev.aaart.com:/usr/obj/usr/src/sys/AAART i386 >Description: /usr/share/examples/drivers/make_pseudo_driver.sh creates a bad example. >How-To-Repeat: # ./make_pseudo_driver.sh pseudo Using /usr/src/sys as the path to the kernel sources! The following files will be created: /usr/src/sys/modules/pseudo /usr/src/sys/conf/files.PSEUDO /usr/src/sys/i386/conf/PSEUDO /usr/src/sys/dev/pseudo /usr/src/sys/dev/pseudo/pseudo.c /usr/src/sys/sys/pseudoio.h /usr/src/sys/modules/pseudo /usr/src/sys/modules/pseudo/Makefile Answer [Y] to create the files and [Y] to create the new kernel called 'PSEUDO'. Attempts to build the kernel, but dies when attempting to compile file the script created: cc -c -O -pipe -std=c99 -g -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual -Wundef -Wno-pointer-sign -fformat-extensions -nostdinc -I. -I../../.. -I../../../contrib/altq -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -ffreestanding -Werror ../../../dev/pseudo/pseudo.c cc1: warnings being treated as errors ./../../dev/pseudo/pseudo.c: In function 'pseudo_drvinit': ./../../dev/pseudo/pseudo.c:241: warning: 'unit' is used uninitialized in this function *** Error code 1 ---------------------- here's the created code: ---------------------- static void pseudo_drvinit(void *unused) { int unit; sc_p scp = sca[unit]; for (unit = 0; unit < NPSEUDO; unit++) { /* * Allocate storage for this instance . */ scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT | M_ZERO); if( scp == NULL) { printf("pseudo%d failed to allocate strorage\n", unit); return; } sca[unit] = scp; scp->dev = make_dev(&pseudo_cdevsw, unit, UID_ROOT, GID_KMEM, 0640, "pseudo%d", unit); } } --------------------- >Fix: Easy fix, replace the first line in pseudo_drvinit() function with: int unit = UNIT(dev); Patch attached with submission follows: /* * Copyright (c) [year] [your name] * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * pseudo driver */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> /* SYSINIT stuff */ #include <sys/uio.h> /* SYSINIT stuff */ #include <sys/conf.h> /* cdevsw stuff */ #include <sys/malloc.h> /* malloc region definitions */ #include <sys/proc.h> #include <sys/pseudoio.h> /* pseudo IOCTL definitions */ #include <machine/clock.h> /* DELAY() */ #define NPSEUDO 3 /* defines number of instances */ /* XXX These should be defined in terms of bus-space ops. */ #define PSEUDO_INB(port) inb(port) #define PSEUDO_OUTB(port, val) (port, (val)) /* Function prototypes (these should all be static) */ static d_open_t pseudoopen; static d_close_t pseudoclose; static d_read_t pseudoread; static d_write_t pseudowrite; static d_ioctl_t pseudoioctl; static d_mmap_t pseudommap; static d_poll_t pseudopoll; #define CDEV_MAJOR 20 static struct cdevsw pseudo_cdevsw = { .d_version = D_VERSION, .d_open = pseudoopen, .d_close = pseudoclose, .d_read = pseudoread, .d_write = pseudowrite, .d_ioctl = pseudoioctl, .d_poll = pseudopoll, .d_mmap = pseudommap, .d_name = "pseudo", }; /* * device specific Misc defines */ #define BUFFERSIZE 1024 #define UNIT(dev) minor(dev) /* assume one minor number per unit */ /* * One of these per allocated device */ struct pseudo_softc { u_long iobase; char buffer[BUFFERSIZE]; struct cdev *dev; }; typedef struct pseudo_softc *sc_p; static sc_p sca[NPSEUDO]; /* * Macro to check that the unit number is valid * Often this isn't needed as once the open() is performed, * the unit number is pretty much safe.. The exception would be if we * implemented devices that could "go away". in which case all these routines * would be wise to check the number, DIAGNOSTIC or not. */ #define CHECKUNIT(RETVAL) do { /* the do-while is a safe way to do this grouping */ if (unit > NPSEUDO) { printf("%s: bad unit %d\n", __func__, unit); return (RETVAL); } if (scp == NULL) { printf("%s: unit %d not attached\n", __func__, unit); return (RETVAL); } } while (0) #ifdef DIAGNOSTIC #define CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL) #else /* DIAGNOSTIC */ #define CHECKUNIT_DIAG(RETVAL) #endif /* DIAGNOSTIC */ static int pseudoioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) { int unit = UNIT(dev); sc_p scp = sca[unit]; CHECKUNIT_DIAG(ENXIO); switch (cmd) { case DHIOCRESET: /* whatever resets it */ (void)scp; /* Delete this line after using scp. */ #if 0 PSEUDO_OUTB(scp->iobase, 0xff); #endif break; default: return ENXIO; } return (0); } /* * You also need read, write, open, close routines. * This should get you started */ static int pseudoopen(struct cdev *dev, int oflags, int devtype, struct thread *td) { int unit = UNIT(dev); sc_p scp = sca[unit]; CHECKUNIT(ENXIO); (void)scp; /* Delete this line after using scp. */ /* * Do processing */ return (0); } static int pseudoclose(struct cdev *dev, int fflag, int devtype, struct thread *td) { int unit = UNIT(dev); sc_p scp = sca[unit]; CHECKUNIT_DIAG(ENXIO); (void)scp; /* Delete this line after using scp. */ /* * Do processing */ return (0); } static int pseudoread(struct cdev *dev, struct uio *uio, int ioflag) { int unit = UNIT(dev); sc_p scp = sca[unit]; int toread; CHECKUNIT_DIAG(ENXIO); /* * Do processing * read from buffer */ toread = (min(uio->uio_resid, sizeof(scp->buffer))); return(uiomove(scp->buffer, toread, uio)); } static int pseudowrite(struct cdev *dev, struct uio *uio, int ioflag) { int unit = UNIT(dev); sc_p scp = sca[unit]; int towrite; CHECKUNIT_DIAG(ENXIO); /* * Do processing * write to buffer */ towrite = (min(uio->uio_resid, sizeof(scp->buffer))); return(uiomove(scp->buffer, towrite, uio)); } static int pseudommap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) { int unit = UNIT(dev); sc_p scp = sca[unit]; CHECKUNIT_DIAG(-1); (void)scp; /* Delete this line after using scp. */ /* * Do processing */ #if 0 /* if we had a frame buffer or whatever.. do this */ if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) { return (-1); } return i386_btop((FRAMEBASE + offset)); #else return (-1); #endif } static int pseudopoll(struct cdev *dev, int which, struct thread *td) { int unit = UNIT(dev); sc_p scp = sca[unit]; CHECKUNIT_DIAG(ENXIO); (void)scp; /* Delete this line after using scp. */ /* * Do processing */ return (0); /* this is the wrong value I'm sure */ } /* * Now for some driver initialisation. * Occurs ONCE during boot (very early). */ static void pseudo_drvinit(void *unused) { int unit; sc_p scp = sca[unit]; for (unit = 0; unit < NPSEUDO; unit++) { /* * Allocate storage for this instance . */ scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT | M_ZERO); if( scp == NULL) { printf("pseudo%d failed to allocate strorage\n", unit); return; } sca[unit] = scp; scp->dev = make_dev(&pseudo_cdevsw, unit, UID_ROOT, GID_KMEM, 0640, "pseudo%d", unit); } } SYSINIT(pseudodev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR, pseudo_drvinit, NULL) >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808102356.m7ANumRB095388>