diff options
| author | cvs2svn <cvs2svn@FreeBSD.org> | 1997-05-19 10:35:55 +0000 |
|---|---|---|
| committer | cvs2svn <cvs2svn@FreeBSD.org> | 1997-05-19 10:35:55 +0000 |
| commit | fcc0587080d3250a509550d7222e70e6cdc7d281 (patch) | |
| tree | 827c9ac8236bbd050dc5f1f0753a0ebab99e026a /share/examples/drivers | |
| parent | 8935d79733d4e5938b0f22904e35d251e8eb514d (diff) | |
This commit was manufactured by cvs2svn to create tagrelease/2.2.2
'RELENG_2_2_2_RELEASE'.
Diffstat (limited to 'share/examples/drivers')
| -rw-r--r-- | share/examples/drivers/README | 45 | ||||
| -rwxr-xr-x | share/examples/drivers/make_device_driver.sh | 400 | ||||
| -rw-r--r-- | share/examples/drivers/make_pseudo_driver.sh | 321 |
3 files changed, 0 insertions, 766 deletions
diff --git a/share/examples/drivers/README b/share/examples/drivers/README deleted file mode 100644 index d6765bdf0302..000000000000 --- a/share/examples/drivers/README +++ /dev/null @@ -1,45 +0,0 @@ -Sat Feb 1 23:30:12 PST 1997 <Julian Elischer> - -These files are shell scripts. - -They will, when run, create an example skeleton driver -for you. You can use this driver as a starting point for -writing drivers for your own devices. They have all the hooks needed -for intiialisation, probing, attaching, as well as DEVFS -node creation. They also create sample ioctl commands and a sample -ioctl definition .h file in /sys/sys. In othe rwords they are fully -functional in a 'skeleton' sort of a way. They support multiple devices -so that you may have several of your 'foobar' devices probed and atached -at once. - -I expect that these scripts will improve with time. - -At present these scripts also link the newly created driver into -the kernel sources in /sys. Possibly a better way would be -to make them interactive. (and ask what kernel tree to use as well as -a name for the driver.). - -There are presently two scripts. -One for making a real device driver for ISA devices, and -one for making a device driver for pseudo devices (e.g. /dev/null). -Hopefully they will be joined by similar scripts for creating -skeletons for PCI and EISA devices as well. - -Give them a single argument: the name of the driver. -They will use this given name in many places within the driver, -both in lower and upper case form. (conforming to normal usage). - -The skeleton driver should already link with the kernel -and in fact the shell script will compile a kernel with the new -drive linked in.. The new kernel should still be -runnable and the new driver should be -fully callable (once you get your device to probe). -You should simply edit the driver and continue to use -'make' (as done in the script) until your driver does what you want. - -The driver will end up in /sys/i386/isa for the device driver script, -and in /sys/dev for the pseudo driver script. - - - - diff --git a/share/examples/drivers/make_device_driver.sh b/share/examples/drivers/make_device_driver.sh deleted file mode 100755 index e07338d33c4b..000000000000 --- a/share/examples/drivers/make_device_driver.sh +++ /dev/null @@ -1,400 +0,0 @@ -#!/bin/sh -# This writes a skeleton driver and puts it into the kernel tree for you -#arg1 is lowercase "foo" -# -# Trust me, RUN THIS SCRIPT :) -# -#-------cut here------------------ -cd /sys/i386/conf - -if [ "${1}X" = "X" ] -then - echo "Hey , how about some help here.. give me a device name!" - exit 1 -fi - -UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"` -cat >files.${UPPER} <<DONE -i386/isa/${1}.c optional ${1} device-driver -DONE - -cat >${UPPER} <<DONE -# Configuration file for kernel type: ${UPPER} -ident ${UPPER} -# \$Id:\$" -DONE - -grep -v GENERIC < GENERIC >>${UPPER} - -cat >>${UPPER} <<DONE -# trust me, you'll need this -options DDB -device ${1}0 at isa? port 0x234 bio irq 5 vector ${1}intr -DONE - -cat >../isa/${1}.c <<DONE -/* - * Copyright ME - * - * ${1} driver - * \$Id:\$ - */ - - -#include "${1}.h" /* generated file.. defines N${UPPER} */ -#include <sys/param.h> -#include <sys/systm.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 <i386/isa/isa.h> /* ISA bus port definitions etc. */ -#include <i386/isa/isa_device.h>/* ISA bus configuration structures */ -#include <sys/${1}io.h> /* ${1} IOCTL definitions */ -#ifdef DEVFS -#include <sys/devfsext.h> /* DEVFS defintitions */ -#endif /* DEVFS */ - - - -/* Function prototypes (these should all be static except for ${1}intr()) */ -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_select_t ${1}select; -static int ${1}probe (struct isa_device *); -static int ${1}attach (struct isa_device *); -/* void ${1}intr(int unit);*//* actually defined in ioconf.h (generated file) */ - -#define CDEV_MAJOR 20 -static struct cdevsw ${1}_cdevsw = { - ${1}open, - ${1}close, - ${1}read, - ${1}write, - ${1}ioctl, - nullstop, - nullreset, - nodevtotty, - ${1}select, - ${1}mmap, - NULL, - "${1}", - NULL, - -1 }; - -struct isa_driver ${1}driver = { - ${1}probe, - ${1}attach, - "${1}" }; - -/* - * device specific Misc defines - */ -#define BUFFERSIZE 1024 -#define NUMPORTS 4 -#define UNIT(dev) minor(dev) /* assume one minor number per unit */ - -/* - * One of these per allocated device - */ -struct ${1}_softc { - struct isa_device *dev; - char buffer[BUFFERSIZE]; -#ifdef DEVFS - static void *devfs_token; -#endif -} ; - -typedef struct ${1}_softc *sc_p; - -static sc_p sca[N${UPPER}]; - -/* add your own test to see if it exists */ -/* should return the number of ports needed */ -static int -${1}probe (struct isa_device *dev) -{ - char val; - int unit = dev->id_unit; - sc_p scp = sca[unit]; - - /* - * Check the unit makes sense. - */ - if (unit > N${UPPER}) { - printf("bad unit (%d)\n", unit); - return (0); - } - if (scp) { - printf("unit $d already attached\n", unit); - return (0); - } - - /* - * try see if the device is there. - */ - val = inb (dev->id_iobase); - if ( val != 42 ) { - return (0); - } - - /* - * ok, we got one we think - * do some further (this time possibly destructive) tests. - */ - outb (dev->id_iobase, 0xff); - DELAY (10000); /* 10 ms delay */ - val = inb (dev->id_iobase) & 0x0f; - return ((val & 0x0f) == 0x0f)? NUMPORTS : 0 ; -} - -/* - * Called if the probe succeeded. - * We can be destructive here as we know we have the device. - * we can also trust the unit number. - */ -static int -${1}attach (struct isa_device *dev) -{ - int unit = dev->id_unit; - sc_p scp = sca[unit]; - - /* - * Allocate storage for this instance . - */ - scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT); - if( scp == NULL) { - printf("${1}%d failed to allocage driver strorage\n", unit); - return (0); - } - bzero(scp, sizeof(*scp)); - sca[unit] = scp; - - /* - * Store whatever seems wise. - */ - scp->dev = dev; -#if DEVFS - scp->devfs_token = devfs_add_devswf(&${1}_cdevsw, unit, DV_CHR, - UID_ROOT, GID_KMEM, 0600, "${1}%d", unit); -#endif - return 1; -} - -/* - * 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 == 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 */ - -void -${1}intr(int unit) -{ - sc_p scp = sca[unit]; - - /* - * well we got an interupt, now what? - * Theoretically we don't need to check the unit. - */ - return; -} - -int ${1}ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) -{ - int unit = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT_DIAG(ENXIO); - - switch (cmd) { - case DHIOCRESET: - /* whatever resets it */ - outb(scp->dev->id_iobase, 0xff); - 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 = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT(ENXIO); - - /* - * Do processing - */ - return (0); -} - -static int -${1}close(dev_t dev, int fflag, int devtype, struct proc *p) -{ - int unit = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT_DIAG(ENXIO); - - /* - * Do processing - */ - return (0); -} - -static int -${1}read(dev_t 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(dev_t 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(dev_t dev, int offset, int nprot) -{ - int unit = UNIT (dev); - sc_p scp = 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}select(dev_t dev, int which, struct proc *p) -{ - int unit = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT_DIAG(ENXIO); - - /* - * 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) -{ - dev_t dev; - - dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev, &${1}_cdevsw, NULL); -} - -SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR, - ${1}_drvinit, NULL) - - -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 - -config ${UPPER} -cd ../../compile/${UPPER} -make depend -make ${1}.o -make -exit - -#--------------end of script--------------- -# -#you also need to add an entry into the cdevsw[] -#array in conf.c, but it's too hard to do in a script.. -# -#edit to your taste.. -# -# - - - - diff --git a/share/examples/drivers/make_pseudo_driver.sh b/share/examples/drivers/make_pseudo_driver.sh deleted file mode 100644 index 72f9fc2f5fef..000000000000 --- a/share/examples/drivers/make_pseudo_driver.sh +++ /dev/null @@ -1,321 +0,0 @@ -#!/bin/sh -# This writes a skeleton driver and puts it into the kernel tree for you -#arg1 is lowercase "foo" -# -# Trust me, RUN THIS SCRIPT :) -# -#-------cut here------------------ -cd /sys/i386/conf - -if [ "${1}X" = "X" ] -then - echo "Hey , how about some help here.. give me a device name!" - exit 1 -fi - -UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"` -cat >files.${UPPER} <<DONE -dev/${1}.c optional ${1} device-driver -DONE - -cat >${UPPER} <<DONE -# Configuration file for kernel type: ${UPPER} -ident ${UPPER} -# \$Id:\$" -DONE - -grep -v GENERIC < GENERIC >>${UPPER} - -cat >>${UPPER} <<DONE -# trust me, you'll need this -options DDB -pseudo-device ${1} 4 # might as well allow 4 of them -DONE - -cat >../../dev/${1}.c <<DONE -/* - * Copyright ME - * - * ${1} driver - * \$Id:\$ - */ - - -#include "${1}.h" /* generated file.. defines N${UPPER} */ -#include <sys/param.h> -#include <sys/systm.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 <sys/${1}io.h> /* ${1} IOCTL definitions */ -#ifdef DEVFS -#include <sys/devfsext.h> /* DEVFS defintitions */ -#endif /* DEVFS */ - - - -/* Function prototypes (these should all be static except for ${1}intr()) */ -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_select_t ${1}select; - -#define CDEV_MAJOR 20 -static struct cdevsw ${1}_cdevsw = { - ${1}open, - ${1}close, - ${1}read, - ${1}write, - ${1}ioctl, - nullstop, - nullreset, - nodevtotty, - ${1}select, - ${1}mmap, - NULL, - "${1}", - NULL, - -1 }; - -/* - * 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 { - struct isa_device *dev; - char buffer[BUFFERSIZE]; -#ifdef DEVFS - static void *devfs_token; -#endif -} ; - -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(__FUNCTION__ ":bad unit $d\n", unit); \ - return (RETVAL); \ - } \ - if (scp == 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 */ - -int ${1}ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) -{ - int unit = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT_DIAG(ENXIO); - - switch (cmd) { - case DHIOCRESET: - /* whatever resets it */ - outb(scp->dev->id_iobase, 0xff); - 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 = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT(ENXIO); - - /* - * Do processing - */ - return (0); -} - -static int -${1}close(dev_t dev, int fflag, int devtype, struct proc *p) -{ - int unit = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT_DIAG(ENXIO); - - /* - * Do processing - */ - return (0); -} - -static int -${1}read(dev_t 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(dev_t 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(dev_t dev, int offset, int nprot) -{ - int unit = UNIT (dev); - sc_p scp = 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}select(dev_t dev, int which, struct proc *p) -{ - int unit = UNIT (dev); - sc_p scp = sca[unit]; - - CHECKUNIT_DIAG(ENXIO); - - /* - * 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) -{ - dev_t dev; - int unit; - sc_p scp = sca[unit]; - - dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev, &${1}_cdevsw, NULL); - for (unit = 0; unit < N${UPPER}; unit++) { - /* - * Allocate storage for this instance . - */ - scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT); - if( scp == NULL) { - printf("${1}%d failed to allocate strorage\n", unit); - return ; - } - bzero(scp, sizeof(*scp)); - sca[unit] = scp; -#if DEVFS - scp->devfs_token = devfs_add_devswf(&${1}_cdevsw, unit, DV_CHR, - UID_ROOT, GID_KMEM, 0640, "${1}%d", unit); -#endif - } -} - -SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR, - ${1}_drvinit, NULL) - - -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 - -config ${UPPER} -cd ../../compile/${UPPER} -make depend -make ${1}.o -make -exit - -#--------------end of script--------------- -# -#you also need to add an entry into the cdevsw[] -#array in conf.c, but it's too hard to do in a script.. -# -#edit to your taste.. -# -# - - |
