2 # This writes a skeleton driver and puts it into the kernel tree for you
3 #arg1 is lowercase "foo"
5 # Trust me, RUN THIS SCRIPT :)
7 #-------cut here------------------
12 echo "Hey , how about some help here.. give me a device name!"
16 UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"`
17 cat >files.${UPPER} <<DONE
18 dev/${1}.c optional ${1} device-driver
22 # Configuration file for kernel type: ${UPPER}
24 # \$FreeBSD: src/share/examples/drivers/make_pseudo_driver.sh,v 1.5.2.1 2001/07/25 15:56:09 dd Exp $"
27 grep -v GENERIC < GENERIC >>${UPPER}
30 # trust me, you'll need this
32 pseudo-device ${1} 4 # might as well allow 4 of them
35 cat >../../dev/${1}.c <<DONE
40 * \$FreeBSD: src/share/examples/drivers/make_pseudo_driver.sh,v 1.5.2.1 2001/07/25 15:56:09 dd Exp $
44 #include "${1}.h" /* generated file.. defines N${UPPER} */
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h> /* SYSINIT stuff */
48 #include <sys/conf.h> /* cdevsw stuff */
49 #include <sys/malloc.h> /* malloc region definitions */
50 #include <machine/clock.h> /* DELAY() */
51 #include <sys/${1}io.h> /* ${1} IOCTL definitions */
55 /* Function prototypes (these should all be static) */
56 static d_open_t ${1}open;
57 static d_close_t ${1}close;
58 static d_read_t ${1}read;
59 static d_write_t ${1}write;
60 static d_ioctl_t ${1}ioctl;
61 static d_mmap_t ${1}mmap;
62 static d_poll_t ${1}poll;
65 static struct cdevsw ${1}_cdevsw = {
82 * device specific Misc defines
84 #define BUFFERSIZE 1024
85 #define UNIT(dev) minor(dev) /* assume one minor number per unit */
88 * One of these per allocated device
91 struct isa_device *dev;
92 char buffer[BUFFERSIZE];
95 typedef struct ${1}_softc *sc_p;
97 static sc_p sca[N${UPPER}];
100 * Macro to check that the unit number is valid
101 * Often this isn't needed as once the open() is performed,
102 * the unit number is pretty much safe.. The exception would be if we
103 * implemented devices that could "go away". in which case all these routines
104 * would be wise to check the number, DIAGNOSTIC or not.
106 #define CHECKUNIT(RETVAL) \
107 do { /* the do-while is a safe way to do this grouping */ \
108 if (unit > N${UPPER}) { \
109 printf(__FUNCTION__ ":bad unit %d\n", unit); \
113 printf( __FUNCTION__ ": unit %d not attached\n", unit);\
118 #define CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL)
119 #else /* DIAGNOSTIC */
120 #define CHECKUNIT_DIAG(RETVAL)
121 #endif /* DIAGNOSTIC */
123 int ${1}ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
125 int unit = UNIT (dev);
126 sc_p scp = sca[unit];
128 CHECKUNIT_DIAG(ENXIO);
132 /* whatever resets it */
133 outb(scp->dev->id_iobase, 0xff);
141 * You also need read, write, open, close routines.
142 * This should get you started
145 ${1}open(dev_t dev, int oflags, int devtype, struct proc *p)
147 int unit = UNIT (dev);
148 sc_p scp = sca[unit];
159 ${1}close(dev_t dev, int fflag, int devtype, struct proc *p)
161 int unit = UNIT (dev);
162 sc_p scp = sca[unit];
164 CHECKUNIT_DIAG(ENXIO);
173 ${1}read(dev_t dev, struct uio *uio, int ioflag)
175 int unit = UNIT (dev);
176 sc_p scp = sca[unit];
180 CHECKUNIT_DIAG(ENXIO);
186 toread = (min(uio->uio_resid, sizeof(scp->buffer)));
187 return(uiomove(scp->buffer, toread, uio));
191 ${1}write(dev_t dev, struct uio *uio, int ioflag)
193 int unit = UNIT (dev);
194 sc_p scp = sca[unit];
197 CHECKUNIT_DIAG(ENXIO);
203 towrite = (min(uio->uio_resid, sizeof(scp->buffer)));
204 return(uiomove(scp->buffer, towrite, uio));
208 ${1}mmap(dev_t dev, int offset, int nprot)
210 int unit = UNIT (dev);
211 sc_p scp = sca[unit];
218 #if 0 /* if we had a frame buffer or whatever.. do this */
219 if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) {
222 return i386_btop((FRAMEBASE + offset));
229 ${1}poll(dev_t dev, int which, struct proc *p)
231 int unit = UNIT (dev);
232 sc_p scp = sca[unit];
234 CHECKUNIT_DIAG(ENXIO);
239 return (0); /* this is the wrong value I'm sure */
243 * Now for some driver initialisation.
244 * Occurs ONCE during boot (very early).
247 ${1}_drvinit(void *unused)
251 sc_p scp = sca[unit];
253 dev = makedev(CDEV_MAJOR, 0);
254 cdevsw_add(&dev, &${1}_cdevsw, NULL);
255 for (unit = 0; unit < N${UPPER}; unit++) {
257 * Allocate storage for this instance .
259 scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT);
261 printf("${1}%d failed to allocate strorage\n", unit);
264 bzero(scp, sizeof(*scp));
269 SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR,
275 cat >../../sys/${1}io.h <<DONE
277 * Definitions needed to access the ${1} device (ioctls etc)
278 * see mtio.h , ioctl.h as examples
284 #include <sys/types.h>
286 #include <sys/ioccom.h>
289 * define an ioctl here
291 #define DHIOCRESET _IO('D', 0) /* reset the ${1} device */
296 cd ../../compile/${UPPER}
302 #--------------end of script---------------
304 #you also need to add an entry into the cdevsw[]
305 #array in conf.c, but it's too hard to do in a script..
307 #edit to your taste..