misc/126435: FreeBSD example: make_pseudo_driver.sh fails to
compile.
Fritz Katz
frtzkatz at yahoo.com
Mon Aug 11 00:00:16 UTC 2008
>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 at 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:
More information about the freebsd-bugs
mailing list