From nobody@FreeBSD.org  Sun Aug 10 23:56:48 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id C6DF1106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 10 Aug 2008 23:56:48 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id B378E8FC13
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 10 Aug 2008 23:56:48 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m7ANumYX095389
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 10 Aug 2008 23:56:48 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id m7ANumRB095388;
	Sun, 10 Aug 2008 23:56:48 GMT
	(envelope-from nobody)
Message-Id: <200808102356.m7ANumRB095388@www.freebsd.org>
Date: Sun, 10 Aug 2008 23:56:48 GMT
From: Fritz Katz <frtzkatz@yahoo.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: FreeBSD example: make_pseudo_driver.sh fails to compile.
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         126435
>Category:       misc
>Synopsis:       [patch] /usr/share/examples/drivers/make_pseudo_driver.sh fails to compile.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ed
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 11 00:00:10 UTC 2008
>Closed-Date:    Fri Oct 08 09:26:56 UTC 2010
>Last-Modified:  Fri Oct 08 09:26:56 UTC 2010
>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:
Responsible-Changed-From-To: freebsd-bugs->ed 
Responsible-Changed-By: remko 
Responsible-Changed-When: Mon Aug 11 06:50:50 UTC 2008 
Responsible-Changed-Why:  
Ed, I believe that this could have b een related to your devminor work, 
can you have a look at this? (Even if I am incorrect in the devminor 
part? ;-)) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=126435 
State-Changed-From-To: open->patched 
State-Changed-By: ed 
State-Changed-When: Mon Sep 22 16:10:51 UTC 2008 
State-Changed-Why:  
This should be fixed as of r183272.  I'll MFC it after we've done our 
releases. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=126435 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: misc/126435: commit references a PR
Date: Mon, 22 Sep 2008 16:10:40 +0000 (UTC)

 ed          2008-09-22 16:10:12 UTC
 
   FreeBSD src repository
 
   Modified files:
     share/examples/drivers make_pseudo_driver.sh 
   Log:
   SVN rev 183272 on 2008-09-22 16:10:12Z by ed
   
   Make the make_pseudo_driver.sh shellscript work again.
   
   It seems this script was broken because of the SYSINIT changes and a
   rather awkward variable initialisation. For some reason the
   make_device_driver.sh script is also broken, related to BUS_SETUP_INTR.
   I have no experience with FreeBSD's interrupt handling, so I hope
   someone else is willing to take a look at that shell script.
   
   PR:             misc/126435
   MFC after:      1 month
   
   Revision  Changes    Path
   1.14      +2 -2      src/share/examples/drivers/make_pseudo_driver.sh
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: ed 
State-Changed-When: Fri Oct 8 09:26:55 UTC 2010 
State-Changed-Why:  
Woops. Forgot to MFC. Well, 8.0 has already been released. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=126435 
>Unformatted:
