Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Mar 1999 20:10:02 -0800 (PST)
From:      "Christopher R. Bowman" <crb@ChrisBowman.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: misc/8139: [patch] missing /usr/src/share/examples/drivers/make_pci_driver.sh
Message-ID:  <199903190410.UAA04696@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR misc/8139; it has been noted by GNATS.

From: "Christopher R. Bowman" <crb@ChrisBowman.com>
To: freebsd-gnats-submit@freebsd.org, crb@ChrisBowman.com
Cc:  
Subject: Re: misc/8139: [patch] missing
  /usr/src/share/examples/drivers/make_pci_driver.sh
Date: Thu, 18 Mar 1999 23:04:37 -0500

 --=====================_172594468==_
 Content-Type: text/plain; charset="us-ascii"
 
 attached find a new version suitable for 3.1 RELEASE 
 --=====================_172594468==_
 Content-Type: text/plain; charset="iso-8859-1"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename="make_pci_driver3.0.sh"
 
 #!/bin/sh 
 # This writes a skeleton pci driver and puts it into the kernel tree for=
  you
 #arg1 is lowercase "foo" 
 #
 # It also creates a directory under /usr/src/sys/modules to help you=
  create
 # kernel loadable modules, though without much use except for=
  development.
 #
 # files=
  created:
 #=
 	/sys/i386/conf/files.FOO
 #=
 	/sys/i386/conf/FOO
 #	/sys/pci/foo.c
 #	/sys/sys/fooio.h
 #	/usr/src/sys/modules/foo
 #
 # Trust me, RUN THIS SCRIPT :)
 #
 #-------cut here------------------
 cd /sys/i386/conf
 
 if [ "${1}X" =3D "X" ] 
 then
 	echo "Hey , how about some help here.. give me a device name!"
 	exit 1
 fi
 
 if [ -d /usr/src/sys/modules ]
 then
 	mkdir /usr/src/sys/modules/${1}
 fi
 
 UPPER=3D`echo ${1} |tr "[:lower:]" "[:upper:]"` 
 cat >files.${UPPER} <<DONE
 pci/${1}.c      optional ${1} device-driver
 DONE
 
 cat >${UPPER} <<DONE
 # Configuration file for kernel type: ${UPPER}
 ident	${UPPER}
 # \$Id: make_pci_driver.sh,v 1.0 1999/03/15 16:10:29 crb Exp $"
 DONE
 
 grep -v GENERIC < GENERIC >>${UPPER}
 
 cat >>${UPPER} <<DONE
 # trust me, you'll need this
 options	DDB		
 device ${1}0
 DONE
 
 cat >../../pci/${1}.c <<DONE
 /*
  * Copyright ME
  *
  * ${1} driver
  * \$Id: make_pci_driver.sh,v 1.4 1998/03/15 16:10:29 crb Exp $
  */
 
 
 #include "pci.h"
 #if NPCI >0
 
 #include "${1}.h"		/* generated file.. defines N${UPPER} */
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/uio.h>
 #include <sys/kernel.h>		/* SYSINIT stuff */
 #include <sys/conf.h>		/* cdevsw stuff */
 #include <sys/malloc.h>		/* malloc region definitions */
 #include <machine/clock.h>	/* DELAY() */
 #include <pci.h>                /* NCPI definitions */
 #include <pci/pcivar.h>         /* pci variables etc. */
 #include <pci/pcireg.h>         /* pci register definitions etc. */
 #include <sys/${1}io.h>		/* ${1} IOCTL definitions */
 #ifdef DEVFS
 #include <sys/devfsext.h>	/* DEVFS defintitions */
 #endif /* DEVFS */
 #ifdef ${UPPER}_KLD_MODULE
 #include <sys/module.h>		/* KLD module definitions */
 #endif
 #endif
 
 #define ${1}_DEV_PCI_ID CHANGE_ME       /* pci device id of your device */  =
      
 
 /* Function prototypes (these should all be static) */
 static  d_open_t		${1}open;
 static  d_close_t		${1}close;
 static  d_read_t		${1}read;
 static  d_write_t		${1}write;
 static  d_ioctl_t		${1}ioctl;
 static  d_mmap_t		${1}mmap;
 static  d_poll_t		${1}poll;
 static  const char			*${1}probe(pcici_t tag, pcidi_t type);
 static  void			${1}attach(pcici_t tag, int     unit);
 static  pci_inthand_t   ${1}intr;
 #ifdef ${UPPER}_KLD_MODULE
 static	ointhand2_t	${1}intr; /* should actually have type inthand2_t=
  */
 #endif
  
 #define CDEV_MAJOR 20
 static struct cdevsw ${1}_cdevsw =3D=
  {
 	${1}open,
 	${1}close,
 	${1}read,
 	${1}write,        
 	${1}ioctl,
 	nullstop,
 	nullreset,
 	nodevtotty, 
 	${1}poll,
 	${1}mmap,
 	NULL,
 	"${1}",
 	NULL,
 	-1 };
  
 static u_long ${1}count;
 
 struct pci_device ${1}driver =3D {
         "${1}",
         ${1}probe,
         ${1}attach,
         &${1}count,
         NULL
 };
 
 /* The DATA_SET macro includes the pci device in the set of pci devices
  * that will be probed at config time.
  */
 
 DATA_SET (pcidevice_set, ${1}driver);
 
 /* 
  * 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 ${1}_softc {
 #ifdef DEVFS
         static void *devfs_token;
 #endif
         char    buffer[BUFFERSIZE];
         pcici_t     tag;            /* PCI tag, for doing PCI commands */
 
 } ;
 
 
 typedef	struct ${1}_softc *sc_p;
 
 static sc_p sca[N${UPPER}];
 
 /* this function should discriminate if this device is
  * or is not handled by this driver, often this will be
  * as simple as testing the pci id of the device
  */
 
 static const char *
 ${1}probe(pcici_t tag, pcidi_t type)
 {
         switch (type) {
         case ${1}_DEV_PCI_ID:        
                 return("${1}");
         };
         return ((char *)0);
 }
 
 /*
  * Called if the probe succeeded.
  */
 static void
 ${1}attach(pcici_t tag, int unit)
 {
         sc_p scp  =3D sca[unit];
         
         /* 
          * Allocate storage for this instance .
          */
         scp =3D malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT);
         if( scp =3D=3D NULL) {
                 printf("${1}%d failed to allocage driver strorage\n",=
  unit);
                 return;
         }
         bzero(scp, sizeof(*scp));
         sca[unit] =3D scp;
 
         /*
          * Store whatever seems wise.
          */
         scp->tag =3D tag;
 #if DEVFS
         scp->devfs_token =3D devfs_add_devswf(&${1}_cdevsw, unit, DV_CHR,
             UID_ROOT, GID_KMEM, 0600, "${1}%d", unit);
 #endif
         return;
 }
 
 /* 
  * 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 > N${UPPER}) {					\
 		printf(__FUNCTION__ ":bad unit %d\n", unit);	\
 		return (RETVAL);				\
 	}							\
 	if (scp =3D=3D NULL) { 					\
 		printf( __FUNCTION__ ": unit %d not attached\n", unit);\
 		return (RETVAL);				\
 	}							\
 } while (0)						
 #ifdef	DIAGNOSTIC
 #define	CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL)
 #else	/* DIAGNOSTIC */
 #define	CHECKUNIT_DIAG(RETVAL)
 #endif 	/* DIAGNOSTIC */
 
 static void
 ${1}intr(void *arg)
 
 {
         
         /* 
          * well we got an interupt, now what?
          * Theoretically we don't need to check the unit.
          */
         return;
 }
 
 int ${1}ioctl (dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc=
  *p)
 {
 	int unit =3D UNIT (dev);
 	sc_p scp  =3D sca[unit];
 	
 	CHECKUNIT_DIAG(ENXIO);
     
 	switch (cmd) {
 	    case DHIOCRESET:
 		/*  whatever resets it */
 		break;
 	    default:
 		return ENXIO;
 	}
 	return (0);
 }   
 /*
  * You also need read, write, open, close routines.
  * This should get you started
  */
 static  int
 ${1}open(dev_t dev, int oflags, int devtype, struct proc *p)
 {
 	int unit =3D UNIT (dev);
 	sc_p scp  =3D sca[unit];
 	
 	CHECKUNIT(ENXIO);
 
 	/* 
 	 * Do processing
 	 */
 	return (0);
 }
 
 static  int
 ${1}close(dev_t dev, int fflag, int devtype, struct proc *p)
 {
 	int unit =3D UNIT (dev);
 	sc_p scp  =3D sca[unit];
 	
 	CHECKUNIT_DIAG(ENXIO);
 
 	/* 
 	 * Do processing
 	 */
 	return (0);
 }
 
 static  int
 ${1}read(dev_t dev, struct uio *uio, int ioflag)
 {
 	int unit =3D UNIT (dev);
 	sc_p scp  =3D sca[unit];
 	int     toread;
 	
 	
 	CHECKUNIT_DIAG(ENXIO);
 
 	/* 
 	 * Do processing
 	 * read from buffer
 	 */
 	toread =3D (min(uio->uio_resid,=
  sizeof(scp->buffer)));
 	return(uiomove(scp->buffer, toread, uio));
 }
 
 static  int
 ${1}write(dev_t dev, struct uio *uio, int ioflag)
 {
 	int unit =3D UNIT (dev);
 	sc_p scp  =3D sca[unit];
 	int	towrite;
 	
 	CHECKUNIT_DIAG(ENXIO);
 
 	/* 
 	 * Do processing
 	 * write to buffer
 	 */
 	towrite =3D (min(uio->uio_resid,=
  sizeof(scp->buffer)));
 	return(uiomove(scp->buffer, towrite, uio));
 }
 
 static  int
 ${1}mmap(dev_t dev, vm_offset_t offset, int nprot)
 {
 	int unit =3D UNIT (dev);
 	sc_p scp  =3D sca[unit];
 	
 	CHECKUNIT_DIAG(-1);
 
 	/* 
 	 * 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
 ${1}poll(dev_t dev, int which, struct proc *p)
 {
 	int unit =3D UNIT (dev);
 	sc_p scp  =3D sca[unit];
 	
 	CHECKUNIT_DIAG(ENXIO);
 
 	/* 
 	 * Do processing
 	 */
 	return (0); /* this is the wrong value I'm sure */
 }
 
 #ifndef ${UPPER}_KLD_MODULE
 
 /*
  * Now  for some driver initialisation.
  * Occurs ONCE during boot (very early).
  * This is if we are NOT a loadable module.
  */
 static void             
 ${1}_drvinit(void *unused)
 {
         dev_t dev;
 
 	dev =3D makedev(CDEV_MAJOR, 0);
 	cdevsw_add(&dev, &${1}_cdevsw, NULL);
 }
 
 SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR,
 		${1}_drvinit, NULL)
 
 #else  /* ${UPPER}_KLD_MODULE */
 
 static int
 ${1}_modevent(module_t mod, int type, void *unused)
 {
         
         switch (type) {
         case MOD_LOAD:
                 break;
         case MOD_UNLOAD:
                 break;
         case MOD_SHUTDOWN:
                 break;
         default:
                 break;
         }
         return 0;
 }
 
 static moduledata_t ${1}mod =3D {
         "${1}",
         ${1}_modevent,
         NULL
 };
 
 DECLARE_MODULE(${1}, ${1}mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
 
 #endif /* ${UPPER}_MODULE */
 
 DONE
 
 cat >../../sys/${1}io.h <<DONE
 /*
  * Definitions needed to access the ${1} device (ioctls etc)
  * see mtio.h , ioctl.h as examples
  */
 #ifndef SYS_DHIO_H
 #define SYS_DHIO_H
 
 #ifndef KERNEL
 #include <sys/types.h>
 #endif
 #include <sys/ioccom.h>
 
 /*
  * define an ioctl here
  */
 #define DHIOCRESET _IO('D', 0)   /* reset the ${1} device */
 #endif
 DONE
 
 if [ -d /usr/src/sys/modules/${1} ]
 then
 	cat >/usr/src/sys/modules/${1}/Makefile <<DONE
 #       $Id: Makefile,v 1.0 1999/03/15 04:30:46 crb Exp $
 #	${UPPER} KLD Module
 #
 #	This happens not to work, pci devices can't be modules
 #	unless you preload them at kernel load=
  time
 
 .PATH:	\${.CURDIR}/../..pci/
 KMOD	=3D ${1}
 SRCS	=3D ${1}.c ${1}.h
 
 CFLAGS		+=3D -I. -D${UPPER}_KLD_MODULE
 CLEANFILES	+=3D ${1}.h
 
 .include <bsd.kmod.mk>
 DONE
 fi
 
 config ${UPPER}
 cd ../../compile/${UPPER}
 make depend
 make ${1}.o
 make
 exit
 
 #--------------end of script---------------
 #
 #edit to your taste..
 #
 # 
 
 
 
 
 
 --=====================_172594468==_
 Content-Type: text/plain; charset="us-ascii"
 
 --------
 Christopher R. Bowman
 crb@ChrisBowman.com
 http://www.ChrisBowman.com/
 --=====================_172594468==_--
 
 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199903190410.UAA04696>