xref: /freebsd/share/examples/drivers/make_device_driver.sh (revision 4308b695794c2fc1862e6ed4f35ae47d92c0d8ec)
15e176f9aSJulian Elischer#!/bin/sh
25e176f9aSJulian Elischer# This writes a skeleton driver and puts it into the kernel tree for you
35e176f9aSJulian Elischer#arg1 is lowercase "foo"
45e176f9aSJulian Elischer#
54308b695SJulian Elischer# It also creates a directory under /usr/src/lkm to help you create
64308b695SJulian Elischer#loadable kernel modules, though without much use except for development.
74308b695SJulian Elischer#
85e176f9aSJulian Elischer# Trust me, RUN THIS SCRIPT :)
95e176f9aSJulian Elischer#
105e176f9aSJulian Elischer#-------cut here------------------
115e176f9aSJulian Elischercd /sys/i386/conf
125e176f9aSJulian Elischer
135e176f9aSJulian Elischerif [ "${1}X" = "X" ]
145e176f9aSJulian Elischerthen
155e176f9aSJulian Elischer	echo "Hey , how about some help here.. give me a device name!"
165e176f9aSJulian Elischer	exit 1
175e176f9aSJulian Elischerfi
185e176f9aSJulian Elischer
194308b695SJulian Elischerif [ -d /usr/src/lkm ]
204308b695SJulian Elischerthen
214308b695SJulian Elischer	mkdir /usr/src/lkm/${1}
224308b695SJulian Elischerfi
234308b695SJulian Elischer
245e176f9aSJulian ElischerUPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"`
255e176f9aSJulian Elischercat >files.${UPPER} <<DONE
265e176f9aSJulian Elischeri386/isa/${1}.c      optional ${1} device-driver
275e176f9aSJulian ElischerDONE
285e176f9aSJulian Elischer
295e176f9aSJulian Elischercat >${UPPER} <<DONE
305e176f9aSJulian Elischer# Configuration file for kernel type: ${UPPER}
315e176f9aSJulian Elischerident	${UPPER}
324308b695SJulian Elischer# \$Id: make_device_driver.sh,v 1.2 1997/12/30 03:23:12 julian Exp $"
335e176f9aSJulian ElischerDONE
345e176f9aSJulian Elischer
355e176f9aSJulian Elischergrep -v GENERIC < GENERIC >>${UPPER}
365e176f9aSJulian Elischer
375e176f9aSJulian Elischercat >>${UPPER} <<DONE
385e176f9aSJulian Elischer# trust me, you'll need this
395e176f9aSJulian Elischeroptions	DDB		
405e176f9aSJulian Elischerdevice ${1}0 at isa? port 0x234 bio irq 5 vector ${1}intr
415e176f9aSJulian ElischerDONE
425e176f9aSJulian Elischer
435e176f9aSJulian Elischercat >../isa/${1}.c <<DONE
445e176f9aSJulian Elischer/*
455e176f9aSJulian Elischer * Copyright ME
465e176f9aSJulian Elischer *
475e176f9aSJulian Elischer * ${1} driver
484308b695SJulian Elischer * \$Id: make_device_driver.sh,v 1.2 1997/12/30 03:23:12 julian Exp $
495e176f9aSJulian Elischer */
505e176f9aSJulian Elischer
515e176f9aSJulian Elischer
525e176f9aSJulian Elischer#include "${1}.h"		/* generated file.. defines N${UPPER} */
535e176f9aSJulian Elischer#include <sys/param.h>
545e176f9aSJulian Elischer#include <sys/systm.h>
555e176f9aSJulian Elischer#include <sys/kernel.h>		/* SYSINIT stuff */
565e176f9aSJulian Elischer#include <sys/conf.h>		/* cdevsw stuff */
575e176f9aSJulian Elischer#include <sys/malloc.h>		/* malloc region definitions */
585e176f9aSJulian Elischer#include <machine/clock.h>	/* DELAY() */
595e176f9aSJulian Elischer#include <i386/isa/isa.h>	/* ISA bus port definitions etc. */
605e176f9aSJulian Elischer#include <i386/isa/isa_device.h>/* ISA bus configuration structures */
615e176f9aSJulian Elischer#include <sys/${1}io.h>		/* ${1} IOCTL definitions */
625e176f9aSJulian Elischer#ifdef DEVFS
635e176f9aSJulian Elischer#include <sys/devfsext.h>	/* DEVFS defintitions */
645e176f9aSJulian Elischer#endif /* DEVFS */
655e176f9aSJulian Elischer
665e176f9aSJulian Elischer
675e176f9aSJulian Elischer
685e176f9aSJulian Elischer/* Function prototypes (these should all be static  except for ${1}intr()) */
695e176f9aSJulian Elischerstatic  d_open_t	${1}open;
705e176f9aSJulian Elischerstatic  d_close_t	${1}close;
715e176f9aSJulian Elischerstatic  d_read_t	${1}read;
725e176f9aSJulian Elischerstatic  d_write_t	${1}write;
735e176f9aSJulian Elischerstatic  d_ioctl_t	${1}ioctl;
745e176f9aSJulian Elischerstatic  d_mmap_t	${1}mmap;
75f7fa6f64SJulian Elischerstatic  d_poll_t	${1}poll;
765e176f9aSJulian Elischerstatic	int		${1}probe (struct isa_device *);
775e176f9aSJulian Elischerstatic	int		${1}attach (struct isa_device *);
784308b695SJulian Elischer#ifdef ${UPPER}_MODULE
794308b695SJulian Elischervoid ${1}intr(int unit); /* actually defined in ioconf.h (generated file) */
804308b695SJulian Elischer#endif
815e176f9aSJulian Elischer 
825e176f9aSJulian Elischer#define CDEV_MAJOR 20
835e176f9aSJulian Elischerstatic struct cdevsw ${1}_cdevsw = {
845e176f9aSJulian Elischer	${1}open,
855e176f9aSJulian Elischer	${1}close,
865e176f9aSJulian Elischer	${1}read,
875e176f9aSJulian Elischer	${1}write,        
885e176f9aSJulian Elischer	${1}ioctl,
895e176f9aSJulian Elischer	nullstop,
905e176f9aSJulian Elischer	nullreset,
915e176f9aSJulian Elischer	nodevtotty, 
92f7fa6f64SJulian Elischer	${1}poll,
935e176f9aSJulian Elischer	${1}mmap,
945e176f9aSJulian Elischer	NULL,
955e176f9aSJulian Elischer	"${1}",
965e176f9aSJulian Elischer	NULL,
975e176f9aSJulian Elischer	-1 };
985e176f9aSJulian Elischer 
995e176f9aSJulian Elischerstruct isa_driver ${1}driver = {
1005e176f9aSJulian Elischer	${1}probe,
1015e176f9aSJulian Elischer	${1}attach,
1025e176f9aSJulian Elischer	"${1}" };
1035e176f9aSJulian Elischer
1045e176f9aSJulian Elischer/* 
1055e176f9aSJulian Elischer * device  specific Misc defines 
1065e176f9aSJulian Elischer */
1075e176f9aSJulian Elischer#define BUFFERSIZE 1024
1085e176f9aSJulian Elischer#define NUMPORTS 4
1095e176f9aSJulian Elischer#define UNIT(dev) minor(dev)	/* assume one minor number per unit */
1105e176f9aSJulian Elischer
1115e176f9aSJulian Elischer/*
1125e176f9aSJulian Elischer * One of these per allocated device
1135e176f9aSJulian Elischer */
1145e176f9aSJulian Elischerstruct ${1}_softc {
1155e176f9aSJulian Elischer	struct isa_device *dev;
1165e176f9aSJulian Elischer	char	buffer[BUFFERSIZE];
1175e176f9aSJulian Elischer#ifdef DEVFS
1185e176f9aSJulian Elischer	static void *devfs_token;
1195e176f9aSJulian Elischer#endif
1205e176f9aSJulian Elischer} ;
1215e176f9aSJulian Elischer
1225e176f9aSJulian Elischertypedef	struct ${1}_softc *sc_p;
1235e176f9aSJulian Elischer
1245e176f9aSJulian Elischerstatic sc_p sca[N${UPPER}];
1255e176f9aSJulian Elischer
1265e176f9aSJulian Elischer/* add your own test to see if it exists */
1275e176f9aSJulian Elischer/* should return the number of ports needed */
1285e176f9aSJulian Elischerstatic int
1295e176f9aSJulian Elischer${1}probe (struct isa_device *dev)
1305e176f9aSJulian Elischer{
1315e176f9aSJulian Elischer	char val;
1325e176f9aSJulian Elischer	int unit = dev->id_unit;
1335e176f9aSJulian Elischer	sc_p scp  = sca[unit];
1345e176f9aSJulian Elischer
1355e176f9aSJulian Elischer	/*
1365e176f9aSJulian Elischer	 * Check the unit makes sense.
1375e176f9aSJulian Elischer	 */
1385e176f9aSJulian Elischer	if (unit > N${UPPER}) {
1395e176f9aSJulian Elischer		printf("bad unit (%d)\n", unit);
1405e176f9aSJulian Elischer		return (0);
1415e176f9aSJulian Elischer	}
1425e176f9aSJulian Elischer	if (scp) {
1435e176f9aSJulian Elischer		printf("unit $d already attached\n", unit);
1445e176f9aSJulian Elischer		return (0);
1455e176f9aSJulian Elischer	}
1465e176f9aSJulian Elischer
1475e176f9aSJulian Elischer	/*
1485e176f9aSJulian Elischer	 * try see if the device is there.
1495e176f9aSJulian Elischer	 */
1505e176f9aSJulian Elischer	val = inb (dev->id_iobase);
1515e176f9aSJulian Elischer	if ( val != 42 ) {
1525e176f9aSJulian Elischer		return (0);
1535e176f9aSJulian Elischer	}
1545e176f9aSJulian Elischer
1555e176f9aSJulian Elischer	/*
1565e176f9aSJulian Elischer	 * ok, we got one we think 
1575e176f9aSJulian Elischer	 * do some further (this time possibly destructive) tests.
1585e176f9aSJulian Elischer	 */
1595e176f9aSJulian Elischer	outb (dev->id_iobase, 0xff);
1605e176f9aSJulian Elischer	DELAY (10000); /*  10 ms delay */
1615e176f9aSJulian Elischer	val = inb (dev->id_iobase) & 0x0f;
1625e176f9aSJulian Elischer	return ((val & 0x0f) == 0x0f)? NUMPORTS : 0 ;
1635e176f9aSJulian Elischer}
1645e176f9aSJulian Elischer
1655e176f9aSJulian Elischer/*
1665e176f9aSJulian Elischer * Called if the probe succeeded.
1675e176f9aSJulian Elischer * We can be destructive here as we know we have the device.
1685e176f9aSJulian Elischer * we can also trust the unit number.
1695e176f9aSJulian Elischer */
1705e176f9aSJulian Elischerstatic int
1715e176f9aSJulian Elischer${1}attach (struct isa_device *dev)
1725e176f9aSJulian Elischer{
1735e176f9aSJulian Elischer	int unit = dev->id_unit;
1745e176f9aSJulian Elischer	sc_p scp  = sca[unit];
1755e176f9aSJulian Elischer	
1765e176f9aSJulian Elischer	/* 
1775e176f9aSJulian Elischer	 * Allocate storage for this instance .
1785e176f9aSJulian Elischer	 */
1795e176f9aSJulian Elischer	scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT);
1805e176f9aSJulian Elischer	if( scp == NULL) {
1815e176f9aSJulian Elischer		printf("${1}%d failed to allocage driver strorage\n", unit);
1825e176f9aSJulian Elischer		return (0);
1835e176f9aSJulian Elischer	}
1845e176f9aSJulian Elischer	bzero(scp, sizeof(*scp));
1855e176f9aSJulian Elischer	sca[unit] = scp;
1865e176f9aSJulian Elischer
1875e176f9aSJulian Elischer	/*
1885e176f9aSJulian Elischer	 * Store whatever seems wise.
1895e176f9aSJulian Elischer	 */
1905e176f9aSJulian Elischer	scp->dev = dev;
1915e176f9aSJulian Elischer#if DEVFS
1925e176f9aSJulian Elischer    	scp->devfs_token = devfs_add_devswf(&${1}_cdevsw, unit, DV_CHR,
1935e176f9aSJulian Elischer	    UID_ROOT, GID_KMEM, 0600, "${1}%d", unit);
1945e176f9aSJulian Elischer#endif
1955e176f9aSJulian Elischer	return 1;
1965e176f9aSJulian Elischer}
1975e176f9aSJulian Elischer
1985e176f9aSJulian Elischer/* 
1995e176f9aSJulian Elischer * Macro to check that the unit number is valid
2005e176f9aSJulian Elischer * Often this isn't needed as once the open() is performed,
2015e176f9aSJulian Elischer * the unit number is pretty much safe.. The exception would be if we
2025e176f9aSJulian Elischer * implemented devices that could "go away". in which case all these routines
2035e176f9aSJulian Elischer * would be wise to check the number, DIAGNOSTIC or not.
2045e176f9aSJulian Elischer */
2055e176f9aSJulian Elischer#define CHECKUNIT(RETVAL)					\
2065e176f9aSJulian Elischerdo { /* the do-while is a safe way to do this grouping */	\
2075e176f9aSJulian Elischer	if (unit > N${UPPER}) {					\
2085e176f9aSJulian Elischer		printf(__FUNCTION__ ":bad unit $d\n", unit);	\
2095e176f9aSJulian Elischer		return (RETVAL);				\
2105e176f9aSJulian Elischer	}							\
2115e176f9aSJulian Elischer	if (scp == NULL) { 					\
2125e176f9aSJulian Elischer		printf( __FUNCTION__ ": unit $d not attached\n", unit);\
2135e176f9aSJulian Elischer		return (RETVAL);				\
2145e176f9aSJulian Elischer	}							\
2155e176f9aSJulian Elischer} while (0)						
2165e176f9aSJulian Elischer#ifdef	DIAGNOSTIC
2175e176f9aSJulian Elischer#define	CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL)
2185e176f9aSJulian Elischer#else	/* DIAGNOSTIC */
2195e176f9aSJulian Elischer#define	CHECKUNIT_DIAG(RETVAL)
2205e176f9aSJulian Elischer#endif 	/* DIAGNOSTIC */
2215e176f9aSJulian Elischer
2225e176f9aSJulian Elischervoid
2235e176f9aSJulian Elischer${1}intr(int unit)
2245e176f9aSJulian Elischer{
2255e176f9aSJulian Elischer	sc_p scp  = sca[unit];
2265e176f9aSJulian Elischer	
2275e176f9aSJulian Elischer	/* 
2285e176f9aSJulian Elischer	 * well we got an interupt, now what?
2295e176f9aSJulian Elischer	 * Theoretically we don't need to check the unit.
2305e176f9aSJulian Elischer	 */
2315e176f9aSJulian Elischer	return;
2325e176f9aSJulian Elischer}
2335e176f9aSJulian Elischer
2345e176f9aSJulian Elischerint ${1}ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
2355e176f9aSJulian Elischer{
2365e176f9aSJulian Elischer	int unit = UNIT (dev);
2375e176f9aSJulian Elischer	sc_p scp  = sca[unit];
2385e176f9aSJulian Elischer	
2395e176f9aSJulian Elischer	CHECKUNIT_DIAG(ENXIO);
2405e176f9aSJulian Elischer    
2415e176f9aSJulian Elischer	switch (cmd) {
2425e176f9aSJulian Elischer	    case DHIOCRESET:
2435e176f9aSJulian Elischer		/*  whatever resets it */
2445e176f9aSJulian Elischer		outb(scp->dev->id_iobase, 0xff);
2455e176f9aSJulian Elischer		break;
2465e176f9aSJulian Elischer	    default:
2475e176f9aSJulian Elischer		return ENXIO;
2485e176f9aSJulian Elischer	}
2495e176f9aSJulian Elischer	return (0);
2505e176f9aSJulian Elischer}   
2515e176f9aSJulian Elischer/*
2525e176f9aSJulian Elischer * You also need read, write, open, close routines.
2535e176f9aSJulian Elischer * This should get you started
2545e176f9aSJulian Elischer */
2555e176f9aSJulian Elischerstatic  int
2565e176f9aSJulian Elischer${1}open(dev_t dev, int oflags, int devtype, struct proc *p)
2575e176f9aSJulian Elischer{
2585e176f9aSJulian Elischer	int unit = UNIT (dev);
2595e176f9aSJulian Elischer	sc_p scp  = sca[unit];
2605e176f9aSJulian Elischer	
2615e176f9aSJulian Elischer	CHECKUNIT(ENXIO);
2625e176f9aSJulian Elischer
2635e176f9aSJulian Elischer	/* 
2645e176f9aSJulian Elischer	 * Do processing
2655e176f9aSJulian Elischer	 */
2665e176f9aSJulian Elischer	return (0);
2675e176f9aSJulian Elischer}
2685e176f9aSJulian Elischer
2695e176f9aSJulian Elischerstatic  int
2705e176f9aSJulian Elischer${1}close(dev_t dev, int fflag, int devtype, struct proc *p)
2715e176f9aSJulian Elischer{
2725e176f9aSJulian Elischer	int unit = UNIT (dev);
2735e176f9aSJulian Elischer	sc_p scp  = sca[unit];
2745e176f9aSJulian Elischer	
2755e176f9aSJulian Elischer	CHECKUNIT_DIAG(ENXIO);
2765e176f9aSJulian Elischer
2775e176f9aSJulian Elischer	/* 
2785e176f9aSJulian Elischer	 * Do processing
2795e176f9aSJulian Elischer	 */
2805e176f9aSJulian Elischer	return (0);
2815e176f9aSJulian Elischer}
2825e176f9aSJulian Elischer
2835e176f9aSJulian Elischerstatic  int
2845e176f9aSJulian Elischer${1}read(dev_t dev, struct uio *uio, int ioflag)
2855e176f9aSJulian Elischer{
2865e176f9aSJulian Elischer	int unit = UNIT (dev);
2875e176f9aSJulian Elischer	sc_p scp  = sca[unit];
2885e176f9aSJulian Elischer	int     toread;
2895e176f9aSJulian Elischer	
2905e176f9aSJulian Elischer	
2915e176f9aSJulian Elischer	CHECKUNIT_DIAG(ENXIO);
2925e176f9aSJulian Elischer
2935e176f9aSJulian Elischer	/* 
2945e176f9aSJulian Elischer	 * Do processing
2955e176f9aSJulian Elischer	 * read from buffer
2965e176f9aSJulian Elischer	 */
2975e176f9aSJulian Elischer	toread = (min(uio->uio_resid, sizeof(scp->buffer)));
2985e176f9aSJulian Elischer	return(uiomove(scp->buffer, toread, uio));
2995e176f9aSJulian Elischer}
3005e176f9aSJulian Elischer
3015e176f9aSJulian Elischerstatic  int
3025e176f9aSJulian Elischer${1}write(dev_t dev, struct uio *uio, int ioflag)
3035e176f9aSJulian Elischer{
3045e176f9aSJulian Elischer	int unit = UNIT (dev);
3055e176f9aSJulian Elischer	sc_p scp  = sca[unit];
3065e176f9aSJulian Elischer	int	towrite;
3075e176f9aSJulian Elischer	
3085e176f9aSJulian Elischer	CHECKUNIT_DIAG(ENXIO);
3095e176f9aSJulian Elischer
3105e176f9aSJulian Elischer	/* 
3115e176f9aSJulian Elischer	 * Do processing
3125e176f9aSJulian Elischer	 * write to buffer
3135e176f9aSJulian Elischer	 */
3145e176f9aSJulian Elischer	towrite = (min(uio->uio_resid, sizeof(scp->buffer)));
3155e176f9aSJulian Elischer	return(uiomove(scp->buffer, towrite, uio));
3165e176f9aSJulian Elischer}
3175e176f9aSJulian Elischer
3185e176f9aSJulian Elischerstatic  int
3195e176f9aSJulian Elischer${1}mmap(dev_t dev, int offset, int nprot)
3205e176f9aSJulian Elischer{
3215e176f9aSJulian Elischer	int unit = UNIT (dev);
3225e176f9aSJulian Elischer	sc_p scp  = sca[unit];
3235e176f9aSJulian Elischer	
3245e176f9aSJulian Elischer	CHECKUNIT_DIAG(-1);
3255e176f9aSJulian Elischer
3265e176f9aSJulian Elischer	/* 
3275e176f9aSJulian Elischer	 * Do processing
3285e176f9aSJulian Elischer	 */
3295e176f9aSJulian Elischer#if 0	/* if we had a frame buffer or whatever.. do this */
3305e176f9aSJulian Elischer	if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) {
3315e176f9aSJulian Elischer		return (-1);
3325e176f9aSJulian Elischer	}
3335e176f9aSJulian Elischer	return i386_btop((FRAMEBASE + offset));
3345e176f9aSJulian Elischer#else
3355e176f9aSJulian Elischer	return (-1);
3365e176f9aSJulian Elischer#endif
3375e176f9aSJulian Elischer}
3385e176f9aSJulian Elischer
3395e176f9aSJulian Elischerstatic  int
340f7fa6f64SJulian Elischer${1}poll(dev_t dev, int which, struct proc *p)
3415e176f9aSJulian Elischer{
3425e176f9aSJulian Elischer	int unit = UNIT (dev);
3435e176f9aSJulian Elischer	sc_p scp  = sca[unit];
3445e176f9aSJulian Elischer	
3455e176f9aSJulian Elischer	CHECKUNIT_DIAG(ENXIO);
3465e176f9aSJulian Elischer
3475e176f9aSJulian Elischer	/* 
3485e176f9aSJulian Elischer	 * Do processing
3495e176f9aSJulian Elischer	 */
3505e176f9aSJulian Elischer	return (0); /* this is the wrong value I'm sure */
3515e176f9aSJulian Elischer}
3525e176f9aSJulian Elischer
3534308b695SJulian Elischer#ifndef ${UPPER}_MODULE
3544308b695SJulian Elischer
3555e176f9aSJulian Elischer/*
3565e176f9aSJulian Elischer * Now  for some driver initialisation.
3575e176f9aSJulian Elischer * Occurs ONCE during boot (very early).
3584308b695SJulian Elischer * This is if we are NOT a loadable module.
3595e176f9aSJulian Elischer */
3605e176f9aSJulian Elischerstatic void             
3615e176f9aSJulian Elischer${1}_drvinit(void *unused)
3625e176f9aSJulian Elischer{
3635e176f9aSJulian Elischer        dev_t dev;
3645e176f9aSJulian Elischer
3655e176f9aSJulian Elischer	dev = makedev(CDEV_MAJOR, 0);
3665e176f9aSJulian Elischer	cdevsw_add(&dev, &${1}_cdevsw, NULL);
3675e176f9aSJulian Elischer}
3685e176f9aSJulian Elischer
3695e176f9aSJulian ElischerSYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR,
3705e176f9aSJulian Elischer		${1}_drvinit, NULL)
3715e176f9aSJulian Elischer
3724308b695SJulian Elischer#else  /* ${UPPER}_MODULE */
3734308b695SJulian Elischer/* Here is the support for if we ARE a loadable kernel module */
3744308b695SJulian Elischer
3754308b695SJulian Elischer#include <sys/exec.h>
3764308b695SJulian Elischer#include <sys/sysent.h>
3774308b695SJulian Elischer#include <sys/lkm.h>
3784308b695SJulian Elischer
3794308b695SJulian ElischerMOD_DEV (${1}, LM_DT_CHAR, CDEV_MAJOR, &${1}_cdevsw);
3804308b695SJulian Elischer
3814308b695SJulian Elischerstatic struct isa_device dev = {0, &${1}driver, BASE_IO, IRQ, DMA, (caddr_t) PHYS_IO, PHYS_IO_SIZE, INT_INT, 0, FLAGS, 0, 0, 0, 0, 1, 0, 0};
3824308b695SJulian Elischer
3834308b695SJulian Elischerstatic int
3844308b695SJulian Elischer${1}_load (struct lkm_table *lkmtp, int cmd)
3854308b695SJulian Elischer{
3864308b695SJulian Elischer	if (${1}probe (&dev)) {
3874308b695SJulian Elischer		${1}attach (&dev);
3884308b695SJulian Elischer		uprintf ("${1} driver loaded\n");
3894308b695SJulian Elischer		uprintf ("${1}: interrupts not hooked\n");
3904308b695SJulian Elischer		return 0;
3914308b695SJulian Elischer	} else {
3924308b695SJulian Elischer		uprintf ("${1} driver: probe failed\n");
3934308b695SJulian Elischer		return 1;
3944308b695SJulian Elischer	}
3954308b695SJulian Elischer}
3964308b695SJulian Elischer
3974308b695SJulian Elischerstatic int
3984308b695SJulian Elischer${1}_unload (struct lkm_table *lkmtp, int cmd)
3994308b695SJulian Elischer{
4004308b695SJulian Elischer	uprintf ("${1} driver unloaded\n");
4014308b695SJulian Elischer	return 0;
4024308b695SJulian Elischer}
4034308b695SJulian Elischer
4044308b695SJulian Elischerstatic int
4054308b695SJulian Elischer${1}_stat (struct lkm_table *lkmtp, int cmd)
4064308b695SJulian Elischer{
4074308b695SJulian Elischer	return 0;
4084308b695SJulian Elischer}
4094308b695SJulian Elischer
4104308b695SJulian Elischerint
4114308b695SJulian Elischer${1}_mod (struct lkm_table *lkmtp, int cmd, int ver)
4124308b695SJulian Elischer{
4134308b695SJulian Elischer	MOD_DISPATCH(${1}, lkmtp, cmd, ver,
4144308b695SJulian Elischer		${1}_load, ${1}_unload, ${1}_stat);
4154308b695SJulian Elischer}
4164308b695SJulian Elischer
4174308b695SJulian Elischer#endif /* ${UPPER}_MODULE */
4185e176f9aSJulian Elischer
4195e176f9aSJulian ElischerDONE
4205e176f9aSJulian Elischer
4215e176f9aSJulian Elischercat >../../sys/${1}io.h <<DONE
4225e176f9aSJulian Elischer/*
4235e176f9aSJulian Elischer * Definitions needed to access the ${1} device (ioctls etc)
4245e176f9aSJulian Elischer * see mtio.h , ioctl.h as examples
4255e176f9aSJulian Elischer */
4265e176f9aSJulian Elischer#ifndef SYS_DHIO_H
4275e176f9aSJulian Elischer#define SYS_DHIO_H
4285e176f9aSJulian Elischer
4295e176f9aSJulian Elischer#ifndef KERNEL
4305e176f9aSJulian Elischer#include <sys/types.h>
4315e176f9aSJulian Elischer#endif
4325e176f9aSJulian Elischer#include <sys/ioccom.h>
4335e176f9aSJulian Elischer
4345e176f9aSJulian Elischer/*
4355e176f9aSJulian Elischer * define an ioctl here
4365e176f9aSJulian Elischer */
4375e176f9aSJulian Elischer#define DHIOCRESET _IO('D', 0)   /* reset the ${1} device */
4385e176f9aSJulian Elischer#endif
4395e176f9aSJulian ElischerDONE
4405e176f9aSJulian Elischer
4414308b695SJulian Elischerif [ -d /usr/src/lkm/${1} ]
4424308b695SJulian Elischerthen
4434308b695SJulian Elischer	cat >/usr/src/lkm/${1}/Makefile <<DONE
4444308b695SJulian Elischer#	${UPPER} Loadable Kernel Module
4454308b695SJulian Elischer#
4464308b695SJulian Elischer#	This happens not to work, actually. It's written for
4474308b695SJulian Elischer#	a character ISA device driver, but they cannot be
4484308b695SJulian Elischer#	be made into lkm's, because you have to hard code
4494308b695SJulian Elischer#	everything you'll otherwise enter into the kernel
4504308b695SJulian Elischer#	configuration file.
4514308b695SJulian Elischer
4524308b695SJulian Elischer.PATH:	\${.CURDIR}/../../sys/i386/isa
4534308b695SJulian ElischerKMOD	= ${1}_mod
4544308b695SJulian ElischerSRCS	= ${1}.c ${1}.h
4554308b695SJulian Elischer
4564308b695SJulian ElischerCFLAGS		+= -I. -D${UPPER}_MODULE
4574308b695SJulian ElischerCLEANFILES	+= ${1}.h
4584308b695SJulian Elischer
4594308b695SJulian ElischerBASE_IO=0		# Base IO address
4604308b695SJulian ElischerIRQ=0			# IRQ number
4614308b695SJulian ElischerDMA=-1			# DMA channel
4624308b695SJulian ElischerPHYS_IO=0		# Physical IO Memory base address
4634308b695SJulian ElischerPHYS_IO_SIZE=0		# Physical IO Memory size
4644308b695SJulian ElischerINT_INT=0		# Interrupt interface
4654308b695SJulian ElischerFLAGS=0			# Flags
4664308b695SJulian Elischer
4674308b695SJulian ElischerCFLAGS+= -DBASE_IO=\${BASE_IO} -DIRQ=\${IRQ} -DDMA=\${DMA} -DPHYS_IO=\${PHYS_IO} -DPHYS_IO_SIZE=\${PHYS_IO_SIZE} -DINT_INT=\${INT_INT} -DFLAGS=\${FLAGS}
4684308b695SJulian Elischer
4694308b695SJulian Elischer${1}.h:
4704308b695SJulian Elischer	echo "#define N${UPPER} 1" > ${1}.h
4714308b695SJulian Elischer
4724308b695SJulian Elischerafterinstall:
4734308b695SJulian Elischer	\${INSTALL} -c -o \${BINOWN} -g \${BINGRP} -m \${BINMODE} \
4744308b695SJulian Elischer	\${.CURDIR}/${1} \${DESTDIR}/usr/bin
4754308b695SJulian Elischer
4764308b695SJulian Elischer.include <bsd.kmod.mk>
4774308b695SJulian ElischerDONE
4784308b695SJulian Elischerfi
4794308b695SJulian Elischer
4805e176f9aSJulian Elischerconfig ${UPPER}
4815e176f9aSJulian Elischercd ../../compile/${UPPER}
4825e176f9aSJulian Elischermake depend
4835e176f9aSJulian Elischermake ${1}.o
4845e176f9aSJulian Elischermake
4855e176f9aSJulian Elischerexit
4865e176f9aSJulian Elischer
4875e176f9aSJulian Elischer#--------------end of script---------------
4885e176f9aSJulian Elischer#
4895e176f9aSJulian Elischer#edit to your taste..
4905e176f9aSJulian Elischer#
4915e176f9aSJulian Elischer#
4925e176f9aSJulian Elischer
4935e176f9aSJulian Elischer
4945e176f9aSJulian Elischer
4955e176f9aSJulian Elischer
496