Skip site navigation (1)Skip section navigation (2)
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>