xref: /freebsd/share/examples/drivers/make_device_driver.sh (revision 45b4f5af9eabae3fe7f7763cdca4ebb51b0fe9d8)
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 :)
945b4f5afSJulian Elischer# $FreeBSD$"
105e176f9aSJulian Elischer#
115e176f9aSJulian Elischer#-------cut here------------------
125e176f9aSJulian Elischerif [ "${1}X" = "X" ]
135e176f9aSJulian Elischerthen
145e176f9aSJulian Elischer	echo "Hey , how about some help here.. give me a device name!"
155e176f9aSJulian Elischer	exit 1
165e176f9aSJulian Elischerfi
1745b4f5afSJulian ElischerUPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"`
185e176f9aSJulian Elischer
1945b4f5afSJulian ElischerHERE=`pwd`
2045b4f5afSJulian Elischercd /sys
2145b4f5afSJulian ElischerTOP=`pwd`
2245b4f5afSJulian Elischer
2345b4f5afSJulian Elischerecho ${TOP}/modules/${1}
2445b4f5afSJulian Elischerecho ${TOP}/i386/conf/files.${UPPER}
2545b4f5afSJulian Elischerecho ${TOP}/i386/conf/${UPPER}
2645b4f5afSJulian Elischerecho ${TOP}/dev/${1}
2745b4f5afSJulian Elischerecho ${TOP}/dev/${1}/${1}.c
2845b4f5afSJulian Elischerecho ${TOP}/sys/${1}io.h
2945b4f5afSJulian Elischerecho ${TOP}/modules/${1}
3045b4f5afSJulian Elischerecho ${TOP}/modules/${1}/Makefile
3145b4f5afSJulian Elischer
3245b4f5afSJulian Elischerrm -rf ${TOP}/dev/${1}
3345b4f5afSJulian Elischerrm -rf ${TOP}/modules/${1}
3445b4f5afSJulian Elischerrm ${TOP}/i386/conf/files.${UPPER}
3545b4f5afSJulian Elischerrm ${TOP}/i386/conf/${UPPER}
3645b4f5afSJulian Elischerrm ${TOP}/sys/${1}io.h
3745b4f5afSJulian Elischer
3845b4f5afSJulian Elischerif [ -d ${TOP}/modules/${1} ]
394308b695SJulian Elischerthen
4045b4f5afSJulian Elischer	echo "There appears to already be a module called ${1}"
4145b4f5afSJulian Elischer	exit 1
4245b4f5afSJulian Elischerelse
4345b4f5afSJulian Elischer	mkdir ${TOP}/modules/${1}
444308b695SJulian Elischerfi
454308b695SJulian Elischer
4645b4f5afSJulian Elischer#######################################################################
4745b4f5afSJulian Elischer#######################################################################
4845b4f5afSJulian Elischer#
4945b4f5afSJulian Elischer# Create configuration information needed to create a kernel
5045b4f5afSJulian Elischer# containing this driver.
5145b4f5afSJulian Elischer#
5245b4f5afSJulian Elischer# Not really needed if we are going to do this as a module.
5345b4f5afSJulian Elischer#######################################################################
5445b4f5afSJulian Elischer# First add the file to a local file list.
5545b4f5afSJulian Elischer#######################################################################
5645b4f5afSJulian Elischer
5745b4f5afSJulian Elischercat >${TOP}/i386/conf/files.${UPPER} <<DONE
585e176f9aSJulian Elischeri386/isa/${1}.c	 optional ${1} device-driver
595e176f9aSJulian ElischerDONE
605e176f9aSJulian Elischer
6145b4f5afSJulian Elischer#######################################################################
6245b4f5afSJulian Elischer# Then create a configuration file for a kernel that contains this driver.
6345b4f5afSJulian Elischer#######################################################################
6445b4f5afSJulian Elischercat >${TOP}/i386/conf/${UPPER} <<DONE
655e176f9aSJulian Elischer# Configuration file for kernel type: ${UPPER}
665e176f9aSJulian Elischerident	${UPPER}
677f3dea24SPeter Wemm# \$FreeBSD$"
685e176f9aSJulian ElischerDONE
695e176f9aSJulian Elischer
7045b4f5afSJulian Elischergrep -v GENERIC < /sys/i386/conf/GENERIC >>${TOP}/i386/conf/${UPPER}
715e176f9aSJulian Elischer
7245b4f5afSJulian Elischercat >>${TOP}/i386/conf/${UPPER} <<DONE
7345b4f5afSJulian Elischeroptions	DDB		# trust me, you'll need this
7445b4f5afSJulian Elischerdevice ${1} at isa?
755e176f9aSJulian ElischerDONE
765e176f9aSJulian Elischer
7745b4f5afSJulian Elischerif [ ! -d ${TOP}/dev/${1} ]
7845b4f5afSJulian Elischerthen
7945b4f5afSJulian Elischer	mkdir -p ${TOP}/dev/${1}
8045b4f5afSJulian Elischerfi
8145b4f5afSJulian Elischer
8245b4f5afSJulian Elischer
8345b4f5afSJulian Elischer
8445b4f5afSJulian Elischer
8545b4f5afSJulian Elischer
8645b4f5afSJulian Elischer
8745b4f5afSJulian Elischer
8845b4f5afSJulian Elischer
8945b4f5afSJulian Elischer
9045b4f5afSJulian Elischer
9145b4f5afSJulian Elischer
9245b4f5afSJulian Elischer
9345b4f5afSJulian Elischer
9445b4f5afSJulian Elischer
9545b4f5afSJulian Elischer
9645b4f5afSJulian Elischer
9745b4f5afSJulian Elischer
9845b4f5afSJulian Elischer
9945b4f5afSJulian Elischercat >${TOP}/dev/${1}/${1}.c <<DONE
1005e176f9aSJulian Elischer/*
1015e176f9aSJulian Elischer * Copyright ME
1025e176f9aSJulian Elischer *
1035e176f9aSJulian Elischer * ${1} driver
1047f3dea24SPeter Wemm * \$FreeBSD$
1055e176f9aSJulian Elischer */
1065e176f9aSJulian Elischer
1075e176f9aSJulian Elischer
1085e176f9aSJulian Elischer#include <sys/param.h>
1095e176f9aSJulian Elischer#include <sys/systm.h>
1105e176f9aSJulian Elischer#include <sys/conf.h>		/* cdevsw stuff */
11145b4f5afSJulian Elischer#include <sys/kernel.h>		/* SYSINIT stuff */
11245b4f5afSJulian Elischer#include <sys/uio.h>		/* SYSINIT stuff */
1135e176f9aSJulian Elischer#include <sys/malloc.h>		/* malloc region definitions */
11445b4f5afSJulian Elischer#include <sys/module.h>
11545b4f5afSJulian Elischer#include <sys/bus.h>
11645b4f5afSJulian Elischer#include <machine/bus.h>
11745b4f5afSJulian Elischer#include <machine/resource.h>
11845b4f5afSJulian Elischer#include <sys/rman.h>
11945b4f5afSJulian Elischer#include <sys/time.h>
1205e176f9aSJulian Elischer
12145b4f5afSJulian Elischer#include <isa/isavar.h>
12245b4f5afSJulian Elischer#include "isa_if.h"
12345b4f5afSJulian Elischer#include <sys/${1}io.h>		/* ${1} IOCTL definitions */
12445b4f5afSJulian Elischer
12545b4f5afSJulian Elischer#define ${UPPER}DEV2SOFTC(dev) ((dev)->si_drv1)
12645b4f5afSJulian Elischer#define ${UPPER}_INB(port) bus_space_read_1( bt, bh, (port))
12745b4f5afSJulian Elischer#define ${UPPER}_OUTB(port, val) bus_space_write_1( bt, bh, (port), (val))
12845b4f5afSJulian Elischer#define SOME_PORT 123
12945b4f5afSJulian Elischer#define EXPECTED_VALUE 0x42
1305e176f9aSJulian Elischer
1315e176f9aSJulian Elischer
13264b2faf8SBruce Evans/* Function prototypes (these should all be static) */
13345b4f5afSJulian Elischerstatic int ${1}_isa_probe (device_t);
13445b4f5afSJulian Elischerstatic int ${1}_isa_attach (device_t);
13545b4f5afSJulian Elischerstatic int ${1}_isa_detach (device_t);
13645b4f5afSJulian Elischer
1375e176f9aSJulian Elischerstatic d_open_t		${1}open;
1385e176f9aSJulian Elischerstatic d_close_t	${1}close;
1395e176f9aSJulian Elischerstatic d_read_t		${1}read;
1405e176f9aSJulian Elischerstatic d_write_t	${1}write;
1415e176f9aSJulian Elischerstatic d_ioctl_t	${1}ioctl;
1425e176f9aSJulian Elischerstatic d_mmap_t		${1}mmap;
143f7fa6f64SJulian Elischerstatic d_poll_t		${1}poll;
1444308b695SJulian Elischer#ifdef ${UPPER}_MODULE
14564b2faf8SBruce Evansstatic	ointhand2_t	${1}intr; /* should actually have type inthand2_t */
1464308b695SJulian Elischer#endif
1475e176f9aSJulian Elischer 
1485e176f9aSJulian Elischer#define CDEV_MAJOR 20
1495e176f9aSJulian Elischerstatic struct cdevsw ${1}_cdevsw = {
15045b4f5afSJulian Elischer	/* open */	${1}open,
15145b4f5afSJulian Elischer	/* close */	${1}close,
15245b4f5afSJulian Elischer	/* read */	${1}read,
15345b4f5afSJulian Elischer	/* write */	${1}write,
15445b4f5afSJulian Elischer	/* ioctl */	${1}ioctl,
15545b4f5afSJulian Elischer	/* poll */	${1}poll,
15645b4f5afSJulian Elischer	/* mmap */	${1}mmap,
15745b4f5afSJulian Elischer	/* strategy */	nostrategy,	/* not a block type device */
15845b4f5afSJulian Elischer	/* name */	"${1}",
15945b4f5afSJulian Elischer	/* maj */	CDEV_MAJOR,
16045b4f5afSJulian Elischer	/* dump */	nodump,		/* not a block type device */
16145b4f5afSJulian Elischer	/* psize */	nopsize,	/* not a block type device */
16245b4f5afSJulian Elischer	/* flags */	0,
16345b4f5afSJulian Elischer	/* bmaj */	-1
16445b4f5afSJulian Elischer};
1655e176f9aSJulian Elischer 
1665e176f9aSJulian Elischer/* 
1675e176f9aSJulian Elischer * device specific Misc defines 
1685e176f9aSJulian Elischer */
1695e176f9aSJulian Elischer#define BUFFERSIZE 1024
1705e176f9aSJulian Elischer#define NUMPORTS 4
1715e176f9aSJulian Elischer
1725e176f9aSJulian Elischer/*
1735e176f9aSJulian Elischer * One of these per allocated device
1745e176f9aSJulian Elischer */
1755e176f9aSJulian Elischerstruct ${1}_softc {
17645b4f5afSJulian Elischer	bus_space_tag_t bt;
17745b4f5afSJulian Elischer	bus_space_handle_t bh;
17845b4f5afSJulian Elischer	int port_rid;
17945b4f5afSJulian Elischer	struct resource* port_res;	/* resource for port range */
18045b4f5afSJulian Elischer	dev_t dev;
18145b4f5afSJulian Elischer	device_t device;
1825e176f9aSJulian Elischer	char	buffer[BUFFERSIZE];
1835e176f9aSJulian Elischer} ;
1845e176f9aSJulian Elischer
1855e176f9aSJulian Elischertypedef	struct ${1}_softc *sc_p;
1865e176f9aSJulian Elischer
18745b4f5afSJulian Elischerdevclass_t ${1}_devclass;
1885e176f9aSJulian Elischer
18945b4f5afSJulian Elischerstatic struct isa_pnp_id ${1}_ids[] = {
19045b4f5afSJulian Elischer	{0x12345678, "ABCco Widget"},
19145b4f5afSJulian Elischer	{0xfedcba98, "shining moon Widget ripoff"},
19245b4f5afSJulian Elischer	{0}
19345b4f5afSJulian Elischer};
19445b4f5afSJulian Elischer
19545b4f5afSJulian Elischerstatic device_method_t ${1}_methods[] = {
19645b4f5afSJulian Elischer	DEVMETHOD(device_probe,		${1}_isa_probe),
19745b4f5afSJulian Elischer	DEVMETHOD(device_attach,	${1}_isa_attach),
19845b4f5afSJulian Elischer	DEVMETHOD(device_detach,	${1}_isa_detach),
19945b4f5afSJulian Elischer	{ 0, 0 }
20045b4f5afSJulian Elischer};
20145b4f5afSJulian Elischer
20245b4f5afSJulian Elischerstatic driver_t ${1}_isa_driver = {
20345b4f5afSJulian Elischer	"${1}",
20445b4f5afSJulian Elischer	${1}_methods,
20545b4f5afSJulian Elischer	sizeof (struct ${1}_softc)
20645b4f5afSJulian Elischer};
20745b4f5afSJulian Elischer
20845b4f5afSJulian ElischerDRIVER_MODULE(${1}, isa, ${1}_isa_driver, ${1}_devclass, 0, 0);
20945b4f5afSJulian Elischer
21045b4f5afSJulian Elischer
21145b4f5afSJulian Elischer/*
21245b4f5afSJulian Elischer * The ISA code calls this for each device it knows about,
21345b4f5afSJulian Elischer * whether via the PNP code or via the hints etc.
21445b4f5afSJulian Elischer */
2155e176f9aSJulian Elischerstatic int
21645b4f5afSJulian Elischer${1}_isa_probe (device_t device)
2175e176f9aSJulian Elischer{
21845b4f5afSJulian Elischer	int error;
21945b4f5afSJulian Elischer	sc_p scp = device_get_softc(device);
22045b4f5afSJulian Elischer	bus_space_handle_t  bh;
22145b4f5afSJulian Elischer	bus_space_tag_t bt;
22245b4f5afSJulian Elischer	struct resource *port_res;
22345b4f5afSJulian Elischer	int rid = 0;
22445b4f5afSJulian Elischer	int	size = 16; /* SIZE of port range used */
22545b4f5afSJulian Elischer
22645b4f5afSJulian Elischer
22745b4f5afSJulian Elischer	bzero(scp, sizeof(*scp));
22845b4f5afSJulian Elischer	scp->device = device;
2295e176f9aSJulian Elischer
2305e176f9aSJulian Elischer	/*
23145b4f5afSJulian Elischer	 * Check for a PNP match..
23245b4f5afSJulian Elischer	 * There are several possible outcomes.
23345b4f5afSJulian Elischer	 * error == 0		We match a PNP device (possibly several?).
23445b4f5afSJulian Elischer	 * error == ENXIO,	It is a PNP device but not ours.
23545b4f5afSJulian Elischer	 * error == ENOENT,	I is not a PNP device.. try heuristic probes.
23645b4f5afSJulian Elischer	 *    -- logic from if_ed_isa.c, added info from isa/isa_if.m:
2375e176f9aSJulian Elischer	 */
23845b4f5afSJulian Elischer	error = ISA_PNP_PROBE(device_get_parent(device), device, ${1}_ids);
23945b4f5afSJulian Elischer	switch (error) {
24045b4f5afSJulian Elischer	case 0:
24145b4f5afSJulian Elischer		/*
24245b4f5afSJulian Elischer		 * We found a PNP device.
24345b4f5afSJulian Elischer		 * Fall through into the code that just looks
24445b4f5afSJulian Elischer		 * for a non PNP device as that should 
24545b4f5afSJulian Elischer		 * act as a good filter for bad stuff.
24645b4f5afSJulian Elischer		 */
24745b4f5afSJulian Elischer	case ENOENT:
24845b4f5afSJulian Elischer		/*
24945b4f5afSJulian Elischer		 * Well it didn't show up in the PNP tables
25045b4f5afSJulian Elischer		 * so look directly at known ports (if we have any)
25145b4f5afSJulian Elischer		 * in case we are looking for an old pre-PNP card.
25245b4f5afSJulian Elischer		 *
25345b4f5afSJulian Elischer		 * The ports etc should come from a 'hints' section
25445b4f5afSJulian Elischer		 * buried somewhere. XXX - still not figured out.
25545b4f5afSJulian Elischer		 * which is read in by code in isa/isahint.c
25645b4f5afSJulian Elischer		 */
25745b4f5afSJulian Elischer  
25845b4f5afSJulian Elischer        	port_res = bus_alloc_resource(device, SYS_RES_IOPORT, &rid,
25945b4f5afSJulian Elischer                                 0ul, ~0ul, size, RF_ACTIVE);
26045b4f5afSJulian Elischer        	if (port_res == NULL) {
26145b4f5afSJulian Elischer			error = ENXIO;
26245b4f5afSJulian Elischer			break;
2635e176f9aSJulian Elischer        	}
2645e176f9aSJulian Elischer
26545b4f5afSJulian Elischer                scp->port_rid = rid;
26645b4f5afSJulian Elischer                scp->port_res = port_res;
26745b4f5afSJulian Elischer		scp->bt = bt = rman_get_bustag(port_res);
26845b4f5afSJulian Elischer		scp->bh = bh = rman_get_bushandle(port_res);
2695e176f9aSJulian Elischer
27045b4f5afSJulian Elischer		if ( ${UPPER}_INB(SOME_PORT) != EXPECTED_VALUE) {
2715e176f9aSJulian Elischer			/* 
27245b4f5afSJulian Elischer			 * It isn't what we expected,
27345b4f5afSJulian Elischer			 * so release everything and quit looking for it.
2745e176f9aSJulian Elischer			 */
27545b4f5afSJulian Elischer			bus_release_resource(device, SYS_RES_IOPORT,
27645b4f5afSJulian Elischer							rid, port_res);
27745b4f5afSJulian Elischer			return (ENXIO);
27845b4f5afSJulian Elischer		}
27945b4f5afSJulian Elischer		error = 0;
28045b4f5afSJulian Elischer		break;
28145b4f5afSJulian Elischer	case  ENXIO:
28245b4f5afSJulian Elischer		/* not ours, leave imediatly */
28345b4f5afSJulian Elischer	default:
28445b4f5afSJulian Elischer		error = ENXIO;
28545b4f5afSJulian Elischer	}
28645b4f5afSJulian Elischer	return (error);
2875e176f9aSJulian Elischer}
2885e176f9aSJulian Elischer
2895e176f9aSJulian Elischer/*
2905e176f9aSJulian Elischer * Called if the probe succeeded.
2915e176f9aSJulian Elischer * We can be destructive here as we know we have the device.
2925e176f9aSJulian Elischer */
2935e176f9aSJulian Elischerstatic int
29445b4f5afSJulian Elischer${1}_isa_attach (device_t device)
2955e176f9aSJulian Elischer{
29645b4f5afSJulian Elischer	int	unit = device_get_unit(device);
29745b4f5afSJulian Elischer	sc_p scp = device_get_softc(device);
2985e176f9aSJulian Elischer
29945b4f5afSJulian Elischer	scp->dev = make_dev(&${1}_cdevsw, 0, 0, 0, 0600, "${1}%d", unit);
30045b4f5afSJulian Elischer	scp->dev->si_drv1 = scp;
30145b4f5afSJulian Elischer	return 0;
30245b4f5afSJulian Elischer}
30364b2faf8SBruce Evans
30445b4f5afSJulian Elischerstatic int
30545b4f5afSJulian Elischer${1}_isa_detach (device_t device)
30645b4f5afSJulian Elischer{
30745b4f5afSJulian Elischer	sc_p scp = device_get_softc(device);
30845b4f5afSJulian Elischer
30945b4f5afSJulian Elischer	bus_release_resource(device, SYS_RES_IOPORT,
31045b4f5afSJulian Elischer					scp->port_rid, scp->port_res);
31145b4f5afSJulian Elischer	destroy_dev(scp->dev);
3125e176f9aSJulian Elischer	return (0);
3135e176f9aSJulian Elischer}
3145e176f9aSJulian Elischer
31564b2faf8SBruce Evansstatic void
31645b4f5afSJulian Elischer${1}intr(void *arg)
3175e176f9aSJulian Elischer{
31845b4f5afSJulian Elischer	/*device_t dev = (device_t)arg;*/
31945b4f5afSJulian Elischer	/* sc_p scp	= device_get_softc(dev);*/
3205e176f9aSJulian Elischer
3215e176f9aSJulian Elischer	/* 
3225e176f9aSJulian Elischer	 * well we got an interupt, now what?
3235e176f9aSJulian Elischer	 */
3245e176f9aSJulian Elischer	return;
3255e176f9aSJulian Elischer}
3265e176f9aSJulian Elischer
32745b4f5afSJulian Elischerstatic int
32845b4f5afSJulian Elischer${1}ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
3295e176f9aSJulian Elischer{
33045b4f5afSJulian Elischer	sc_p scp	= ${UPPER}DEV2SOFTC(dev);
33145b4f5afSJulian Elischer	bus_space_handle_t  bh = scp->bh;
33245b4f5afSJulian Elischer	bus_space_tag_t bt = scp->bt;
3335e176f9aSJulian Elischer
3345e176f9aSJulian Elischer	switch (cmd) {
3355e176f9aSJulian Elischer	case DHIOCRESET:
3365e176f9aSJulian Elischer		/* whatever resets it */
33745b4f5afSJulian Elischer		${UPPER}_OUTB(SOME_PORT, 0xff) ;
3385e176f9aSJulian Elischer		break;
3395e176f9aSJulian Elischer	default:
3405e176f9aSJulian Elischer		return ENXIO;
3415e176f9aSJulian Elischer	}
3425e176f9aSJulian Elischer	return (0);
3435e176f9aSJulian Elischer}
3445e176f9aSJulian Elischer/*
3455e176f9aSJulian Elischer * You also need read, write, open, close routines.
3465e176f9aSJulian Elischer * This should get you started
3475e176f9aSJulian Elischer */
3485e176f9aSJulian Elischerstatic int
3495e176f9aSJulian Elischer${1}open(dev_t dev, int oflags, int devtype, struct proc *p)
3505e176f9aSJulian Elischer{
35145b4f5afSJulian Elischer	sc_p scp	= ${UPPER}DEV2SOFTC(dev);
3525e176f9aSJulian Elischer
3535e176f9aSJulian Elischer	/* 
3545e176f9aSJulian Elischer	 * Do processing
3555e176f9aSJulian Elischer	 */
3565e176f9aSJulian Elischer	return (0);
3575e176f9aSJulian Elischer}
3585e176f9aSJulian Elischer
3595e176f9aSJulian Elischerstatic int
3605e176f9aSJulian Elischer${1}close(dev_t dev, int fflag, int devtype, struct proc *p)
3615e176f9aSJulian Elischer{
36245b4f5afSJulian Elischer	sc_p scp	= ${UPPER}DEV2SOFTC(dev);
3635e176f9aSJulian Elischer
3645e176f9aSJulian Elischer	/* 
3655e176f9aSJulian Elischer	 * Do processing
3665e176f9aSJulian Elischer	 */
3675e176f9aSJulian Elischer	return (0);
3685e176f9aSJulian Elischer}
3695e176f9aSJulian Elischer
3705e176f9aSJulian Elischerstatic int
3715e176f9aSJulian Elischer${1}read(dev_t dev, struct uio *uio, int ioflag)
3725e176f9aSJulian Elischer{
37345b4f5afSJulian Elischer	sc_p scp	= ${UPPER}DEV2SOFTC(dev);
3745e176f9aSJulian Elischer	int	 toread;
3755e176f9aSJulian Elischer
3765e176f9aSJulian Elischer
3775e176f9aSJulian Elischer	/* 
3785e176f9aSJulian Elischer	 * Do processing
3795e176f9aSJulian Elischer	 * read from buffer
3805e176f9aSJulian Elischer	 */
3815e176f9aSJulian Elischer	toread = (min(uio->uio_resid, sizeof(scp->buffer)));
3825e176f9aSJulian Elischer	return(uiomove(scp->buffer, toread, uio));
3835e176f9aSJulian Elischer}
3845e176f9aSJulian Elischer
3855e176f9aSJulian Elischerstatic int
3865e176f9aSJulian Elischer${1}write(dev_t dev, struct uio *uio, int ioflag)
3875e176f9aSJulian Elischer{
38845b4f5afSJulian Elischer	sc_p scp	= ${UPPER}DEV2SOFTC(dev);
3895e176f9aSJulian Elischer	int	towrite;
3905e176f9aSJulian Elischer
3915e176f9aSJulian Elischer	/* 
3925e176f9aSJulian Elischer	 * Do processing
3935e176f9aSJulian Elischer	 * write to buffer
3945e176f9aSJulian Elischer	 */
3955e176f9aSJulian Elischer	towrite = (min(uio->uio_resid, sizeof(scp->buffer)));
3965e176f9aSJulian Elischer	return(uiomove(scp->buffer, towrite, uio));
3975e176f9aSJulian Elischer}
3985e176f9aSJulian Elischer
3995e176f9aSJulian Elischerstatic int
40045b4f5afSJulian Elischer${1}mmap(dev_t dev, vm_offset_t offset, int nprot)
4015e176f9aSJulian Elischer{
40245b4f5afSJulian Elischer	sc_p scp	= ${UPPER}DEV2SOFTC(dev);
4035e176f9aSJulian Elischer
4045e176f9aSJulian Elischer	/* 
4055e176f9aSJulian Elischer	 * Do processing
4065e176f9aSJulian Elischer	 */
4075e176f9aSJulian Elischer#if 0	/* if we had a frame buffer or whatever.. do this */
4085e176f9aSJulian Elischer	if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) {
4095e176f9aSJulian Elischer		return (-1);
4105e176f9aSJulian Elischer	}
4115e176f9aSJulian Elischer	return i386_btop((FRAMEBASE + offset));
4125e176f9aSJulian Elischer#else
4135e176f9aSJulian Elischer	return (-1);
4145e176f9aSJulian Elischer#endif
4155e176f9aSJulian Elischer}
4165e176f9aSJulian Elischer
4175e176f9aSJulian Elischerstatic int
418f7fa6f64SJulian Elischer${1}poll(dev_t dev, int which, struct proc *p)
4195e176f9aSJulian Elischer{
42045b4f5afSJulian Elischer	sc_p scp	= ${UPPER}DEV2SOFTC(dev);
4215e176f9aSJulian Elischer
4225e176f9aSJulian Elischer	/* 
4235e176f9aSJulian Elischer	 * Do processing
4245e176f9aSJulian Elischer	 */
4255e176f9aSJulian Elischer	return (0); /* this is the wrong value I'm sure */
4265e176f9aSJulian Elischer}
4275e176f9aSJulian Elischer
4285e176f9aSJulian ElischerDONE
4295e176f9aSJulian Elischer
43045b4f5afSJulian Elischercat >${TOP}/sys/${1}io.h <<DONE
4315e176f9aSJulian Elischer/*
4325e176f9aSJulian Elischer * Definitions needed to access the ${1} device (ioctls etc)
4335e176f9aSJulian Elischer * see mtio.h , ioctl.h as examples
4345e176f9aSJulian Elischer */
4355e176f9aSJulian Elischer#ifndef SYS_DHIO_H
4365e176f9aSJulian Elischer#define SYS_DHIO_H
4375e176f9aSJulian Elischer
4385e176f9aSJulian Elischer#ifndef KERNEL
4395e176f9aSJulian Elischer#include <sys/types.h>
4405e176f9aSJulian Elischer#endif
4415e176f9aSJulian Elischer#include <sys/ioccom.h>
4425e176f9aSJulian Elischer
4435e176f9aSJulian Elischer/*
4445e176f9aSJulian Elischer * define an ioctl here
4455e176f9aSJulian Elischer */
4465e176f9aSJulian Elischer#define DHIOCRESET _IO('D', 0) /* reset the ${1} device */
4475e176f9aSJulian Elischer#endif
4485e176f9aSJulian ElischerDONE
4495e176f9aSJulian Elischer
45045b4f5afSJulian Elischerif [ ! -d ${TOP}/modules/${1} ]
4514308b695SJulian Elischerthen
45245b4f5afSJulian Elischer	mkdir -p ${TOP}/modules/${1}
45345b4f5afSJulian Elischerfi
45445b4f5afSJulian Elischer
45545b4f5afSJulian Elischercat >${TOP}/modules/${1}/Makefile <<DONE
4564308b695SJulian Elischer#	${UPPER} Loadable Kernel Module
4574308b695SJulian Elischer#
45845b4f5afSJulian Elischer# $FreeBSD$
4594308b695SJulian Elischer 
46045b4f5afSJulian Elischer.PATH:  \${.CURDIR}/../../dev/${1}
46145b4f5afSJulian ElischerKMOD    = ${1}
46245b4f5afSJulian ElischerSRCS    = ${1}.c
46345b4f5afSJulian ElischerSRCS    += opt_inet.h device_if.h bus_if.h pci_if.h isa_if.h
4644308b695SJulian Elischer  
46545b4f5afSJulian Elischer# you may need to do this is your device is an if_xxx driver
46645b4f5afSJulian Elischeropt_inet.h:
46745b4f5afSJulian Elischer	echo "#define INET 1" > opt_inet.h
4684308b695SJulian Elischer	   
4694308b695SJulian Elischer.include <bsd.kmod.mk>
4704308b695SJulian ElischerDONE
47145b4f5afSJulian Elischer
47245b4f5afSJulian Elischer(cd ${TOP}/modules/${1}; make depend; make )
47345b4f5afSJulian Elischerexit
4744308b695SJulian Elischer
4755e176f9aSJulian Elischerconfig ${UPPER}
4765e176f9aSJulian Elischercd ../../compile/${UPPER}
4775e176f9aSJulian Elischermake depend
4785e176f9aSJulian Elischermake ${1}.o
4795e176f9aSJulian Elischermake
4805e176f9aSJulian Elischerexit
4815e176f9aSJulian Elischer
4825e176f9aSJulian Elischer#--------------end of script---------------
4835e176f9aSJulian Elischer#
4845e176f9aSJulian Elischer#edit to your taste..
4855e176f9aSJulian Elischer#
4865e176f9aSJulian Elischer#
4875e176f9aSJulian Elischer
4885e176f9aSJulian Elischer
4895e176f9aSJulian Elischer
4905e176f9aSJulian Elischer
491