freebsd-nq/share/examples/drivers/make_pseudo_driver.sh
Warner Losh 226a9d167b Remove 'All Rights Reserved' from the collection copyright and templates.
The original Berkeley Software Distributions were made in the 1980's
and 1990's. At that time, the Buenos Ares Convention of 1910 was in
force in most of the countries in the Americas. It required an
affirmative statement of rights reservation, typically using 'All
Rights Reserved.' The Regents included this phrase in their copyright
notices to invoke this treaty to ensure maximal copyright protection.

In the 1990's, Latin America coutries ratifeid the Berne Convention on
copyrights which prohibited them from requiring an affirmative
statement to reserve the rights. When Nicaragua ratified in 2000, the
Buenos Ares Convention of 1910 was effectively repealed. This made all
the 'All Rights Reserved' phrases obsolete and legal deadweight most
of the time, and certainly in the cases removed here.

Since it's no longer required, and is in fact meaningless, core has
decided to dropped it from the project's collection copyright and
sample templates. It encourages other rights holders to do the same
after consultation with their legal department.

More see https://en.wikipedia.org/wiki/Buenos_Aires_Convention for
more information.

Approved by: core@ (emaste@, jhb@)
Differential Review:  https://reviews.freebsd.org/D15264
2018-05-09 02:02:49 +00:00

443 lines
9.3 KiB
Bash

#!/bin/sh
# This writes a skeleton driver and puts it into the kernel tree for you
#
# arg1 is lowercase "foo"
# arg2 path to the kernel sources, "/sys" if omitted
#
# Trust me, RUN THIS SCRIPT :)
#
# $FreeBSD$
#
#-------cut here------------------
if [ "${1}X" = "X" ]
then
echo "Hey , how about some help here.. give me a device name!"
exit 1
fi
if [ "X${2}" = "X" ]; then
TOP=`cd /sys; pwd -P`
echo "Using ${TOP} as the path to the kernel sources!"
else
TOP=${2}
fi
for i in "" "conf" "i386" "i386/conf" "dev" "sys" "modules"
do
if [ -d ${TOP}/${i} ]
then
continue
fi
echo "${TOP}/${i}: no such directory."
echo "Please, correct the error and try again."
exit 1
done
UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"`
if [ -d ${TOP}/modules/${1} ]; then
echo "There appears to already be a module called ${1}"
echo -n "Should it be overwritten? [Y]"
read VAL
if [ "-z" "$VAL" ]; then
VAL=YES
fi
case ${VAL} in
[yY]*)
echo "Cleaning up from prior runs"
rm -rf ${TOP}/dev/${1}
rm -rf ${TOP}/modules/${1}
rm ${TOP}/conf/files.${UPPER}
rm ${TOP}/i386/conf/${UPPER}
rm ${TOP}/sys/${1}io.h
;;
*)
exit 1
;;
esac
fi
echo "The following files will be created:"
echo ${TOP}/modules/${1}
echo ${TOP}/conf/files.${UPPER}
echo ${TOP}/i386/conf/${UPPER}
echo ${TOP}/dev/${1}
echo ${TOP}/dev/${1}/${1}.c
echo ${TOP}/sys/${1}io.h
echo ${TOP}/modules/${1}
echo ${TOP}/modules/${1}/Makefile
mkdir ${TOP}/modules/${1}
cat >${TOP}/conf/files.${UPPER} <<DONE
dev/${1}/${1}.c optional ${1}
DONE
cat >${TOP}/i386/conf/${UPPER} <<DONE
# Configuration file for kernel type: ${UPPER}
# \$FreeBSD\$
files "${TOP}/conf/files.${UPPER}"
include GENERIC
ident ${UPPER}
# trust me, you'll need this
options KDB
options DDB
device ${1}
DONE
if [ ! -d ${TOP}/dev/${1} ]; then
mkdir -p ${TOP}/dev/${1}
fi
cat >${TOP}/dev/${1}/${1}.c <<DONE
/*
* Copyright (c) [year] [your name]
*
* 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.
*
* ${1} 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/${1}io.h> /* ${1} IOCTL definitions */
#include <machine/clock.h> /* DELAY() */
#define N${UPPER} 3 /* defines number of instances */
/* XXX These should be defined in terms of bus-space ops. */
#define ${UPPER}_INB(port) inb(port)
#define ${UPPER}_OUTB(port, val) (port, (val))
/* 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;
#define CDEV_MAJOR 20
static struct cdevsw ${1}_cdevsw = {
.d_version = D_VERSION,
.d_open = ${1}open,
.d_close = ${1}close,
.d_read = ${1}read,
.d_write = ${1}write,
.d_ioctl = ${1}ioctl,
.d_poll = ${1}poll,
.d_mmap = ${1}mmap,
.d_name = "${1}",
};
/*
* device specific Misc defines
*/
#define BUFFERSIZE 1024
#define UNIT(dev) dev2unit(dev) /* assume one minor number per unit */
/*
* One of these per allocated device
*/
struct ${1}_softc {
u_long iobase;
char buffer[BUFFERSIZE];
struct cdev *dev;
};
typedef struct ${1}_softc *sc_p;
static sc_p sca[N${UPPER}];
/*
* 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("%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
${1}ioctl (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
${UPPER}_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
${1}open(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
${1}close(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
${1}read(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
${1}write(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
${1}mmap(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
${1}poll(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
${1}_drvinit(void *unused)
{
int unit;
sc_p scp;
for (unit = 0; unit < N${UPPER}; unit++) {
/*
* Allocate storage for this instance .
*/
scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT | M_ZERO);
if( scp == NULL) {
printf("${1}%d failed to allocate strorage\n", unit);
return;
}
sca[unit] = scp;
scp->dev = make_dev(&${1}_cdevsw, unit,
UID_ROOT, GID_KMEM, 0640, "${1}%d", unit);
}
}
SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR,
${1}_drvinit, NULL);
DONE
cat >${TOP}/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 ${TOP}/modules/${1} ]; then
mkdir -p ${TOP}/modules/${1}
fi
cat >${TOP}/modules/${1}/Makefile <<DONE
# ${UPPER} Loadable Kernel Module
#
# \$FreeBSD\$
.PATH: \${.CURDIR}/../../dev/${1}
KMOD = ${1}
SRCS = ${1}.c
.include <bsd.kmod.mk>
DONE
echo -n "Do you want to build the '${1}' module? [Y]"
read VAL
if [ "-z" "$VAL" ]; then
VAL=YES
fi
case ${VAL} in
[yY]*)
(cd ${TOP}/modules/${1}; make depend; make )
;;
*)
# exit
;;
esac
echo ""
echo -n "Do you want to build the '${UPPER}' kernel? [Y]"
read VAL
if [ "-z" "$VAL" ]; then
VAL=YES
fi
case ${VAL} in
[yY]*)
(
cd ${TOP}/i386/conf; \
config ${UPPER}; \
cd ${TOP}/i386/compile/${UPPER}; \
make depend; \
make; \
)
;;
*)
# exit
;;
esac
#--------------end of script---------------
#
#edit to your taste..
#
#