1#!/bin/sh 2# This writes a skeleton driver and puts it into the kernel tree for you 3#arg1 is lowercase "foo" 4# 5# Trust me, RUN THIS SCRIPT :) 6# 7#-------cut here------------------ 8cd /sys/i386/conf 9 10if [ "${1}X" = "X" ] 11then 12 echo "Hey , how about some help here.. give me a device name!" 13 exit 1 14fi 15 16UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"` 17cat >files.${UPPER} <<DONE 18dev/${1}.c optional ${1} device-driver 19DONE 20 21cat >${UPPER} <<DONE 22# Configuration file for kernel type: ${UPPER} 23ident ${UPPER} 24# \$FreeBSD: src/share/examples/drivers/make_pseudo_driver.sh,v 1.5.2.1 2001/07/25 15:56:09 dd Exp $" 25# \$DragonFly: src/share/examples/drivers/make_pseudo_driver.sh,v 1.2 2003/06/17 04:36:57 dillon Exp $" 26DONE 27 28grep -v GENERIC < GENERIC >>${UPPER} 29 30cat >>${UPPER} <<DONE 31# trust me, you'll need this 32options DDB 33pseudo-device ${1} 4 # might as well allow 4 of them 34DONE 35 36cat >../../dev/${1}.c <<DONE 37/* 38 * Copyright ME 39 * 40 * ${1} driver 41 * \$FreeBSD: src/share/examples/drivers/make_pseudo_driver.sh,v 1.5.2.1 2001/07/25 15:56:09 dd Exp $ 42 */ 43 44 45#include "${1}.h" /* generated file.. defines N${UPPER} */ 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/kernel.h> /* SYSINIT stuff */ 49#include <sys/conf.h> /* cdevsw stuff */ 50#include <sys/malloc.h> /* malloc region definitions */ 51#include <machine/clock.h> /* DELAY() */ 52#include <sys/${1}io.h> /* ${1} IOCTL definitions */ 53 54 55 56/* Function prototypes (these should all be static) */ 57static d_open_t ${1}open; 58static d_close_t ${1}close; 59static d_read_t ${1}read; 60static d_write_t ${1}write; 61static d_ioctl_t ${1}ioctl; 62static d_mmap_t ${1}mmap; 63static d_poll_t ${1}poll; 64 65#define CDEV_MAJOR 20 66static struct cdevsw ${1}_cdevsw = { 67 ${1}open, 68 ${1}close, 69 ${1}read, 70 ${1}write, 71 ${1}ioctl, 72 nullstop, 73 nullreset, 74 nodevtotty, 75 ${1}poll, 76 ${1}mmap, 77 NULL, 78 "${1}", 79 NULL, 80 -1 }; 81 82/* 83 * device specific Misc defines 84 */ 85#define BUFFERSIZE 1024 86#define UNIT(dev) minor(dev) /* assume one minor number per unit */ 87 88/* 89 * One of these per allocated device 90 */ 91struct ${1}_softc { 92 struct isa_device *dev; 93 char buffer[BUFFERSIZE]; 94} ; 95 96typedef struct ${1}_softc *sc_p; 97 98static sc_p sca[N${UPPER}]; 99 100/* 101 * Macro to check that the unit number is valid 102 * Often this isn't needed as once the open() is performed, 103 * the unit number is pretty much safe.. The exception would be if we 104 * implemented devices that could "go away". in which case all these routines 105 * would be wise to check the number, DIAGNOSTIC or not. 106 */ 107#define CHECKUNIT(RETVAL) \ 108do { /* the do-while is a safe way to do this grouping */ \ 109 if (unit > N${UPPER}) { \ 110 printf(__FUNCTION__ ":bad unit %d\n", unit); \ 111 return (RETVAL); \ 112 } \ 113 if (scp == NULL) { \ 114 printf( __FUNCTION__ ": unit %d not attached\n", unit);\ 115 return (RETVAL); \ 116 } \ 117} while (0) 118#ifdef DIAGNOSTIC 119#define CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL) 120#else /* DIAGNOSTIC */ 121#define CHECKUNIT_DIAG(RETVAL) 122#endif /* DIAGNOSTIC */ 123 124int ${1}ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 125{ 126 int unit = UNIT (dev); 127 sc_p scp = sca[unit]; 128 129 CHECKUNIT_DIAG(ENXIO); 130 131 switch (cmd) { 132 case DHIOCRESET: 133 /* whatever resets it */ 134 outb(scp->dev->id_iobase, 0xff); 135 break; 136 default: 137 return ENXIO; 138 } 139 return (0); 140} 141/* 142 * You also need read, write, open, close routines. 143 * This should get you started 144 */ 145static int 146${1}open(dev_t dev, int oflags, int devtype, struct proc *p) 147{ 148 int unit = UNIT (dev); 149 sc_p scp = sca[unit]; 150 151 CHECKUNIT(ENXIO); 152 153 /* 154 * Do processing 155 */ 156 return (0); 157} 158 159static int 160${1}close(dev_t dev, int fflag, int devtype, struct proc *p) 161{ 162 int unit = UNIT (dev); 163 sc_p scp = sca[unit]; 164 165 CHECKUNIT_DIAG(ENXIO); 166 167 /* 168 * Do processing 169 */ 170 return (0); 171} 172 173static int 174${1}read(dev_t dev, struct uio *uio, int ioflag) 175{ 176 int unit = UNIT (dev); 177 sc_p scp = sca[unit]; 178 int toread; 179 180 181 CHECKUNIT_DIAG(ENXIO); 182 183 /* 184 * Do processing 185 * read from buffer 186 */ 187 toread = (min(uio->uio_resid, sizeof(scp->buffer))); 188 return(uiomove(scp->buffer, toread, uio)); 189} 190 191static int 192${1}write(dev_t dev, struct uio *uio, int ioflag) 193{ 194 int unit = UNIT (dev); 195 sc_p scp = sca[unit]; 196 int towrite; 197 198 CHECKUNIT_DIAG(ENXIO); 199 200 /* 201 * Do processing 202 * write to buffer 203 */ 204 towrite = (min(uio->uio_resid, sizeof(scp->buffer))); 205 return(uiomove(scp->buffer, towrite, uio)); 206} 207 208static int 209${1}mmap(dev_t dev, int offset, int nprot) 210{ 211 int unit = UNIT (dev); 212 sc_p scp = sca[unit]; 213 214 CHECKUNIT_DIAG(-1); 215 216 /* 217 * Do processing 218 */ 219#if 0 /* if we had a frame buffer or whatever.. do this */ 220 if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) { 221 return (-1); 222 } 223 return i386_btop((FRAMEBASE + offset)); 224#else 225 return (-1); 226#endif 227} 228 229static int 230${1}poll(dev_t dev, int which, struct proc *p) 231{ 232 int unit = UNIT (dev); 233 sc_p scp = sca[unit]; 234 235 CHECKUNIT_DIAG(ENXIO); 236 237 /* 238 * Do processing 239 */ 240 return (0); /* this is the wrong value I'm sure */ 241} 242 243/* 244 * Now for some driver initialisation. 245 * Occurs ONCE during boot (very early). 246 */ 247static void 248${1}_drvinit(void *unused) 249{ 250 dev_t dev; 251 int unit; 252 sc_p scp = sca[unit]; 253 254 dev = makedev(CDEV_MAJOR, 0); 255 cdevsw_add(&dev, &${1}_cdevsw, NULL); 256 for (unit = 0; unit < N${UPPER}; unit++) { 257 /* 258 * Allocate storage for this instance . 259 */ 260 scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT); 261 if( scp == NULL) { 262 printf("${1}%d failed to allocate strorage\n", unit); 263 return ; 264 } 265 bzero(scp, sizeof(*scp)); 266 sca[unit] = scp; 267 } 268} 269 270SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR, 271 ${1}_drvinit, NULL) 272 273 274DONE 275 276cat >../../sys/${1}io.h <<DONE 277/* 278 * Definitions needed to access the ${1} device (ioctls etc) 279 * see mtio.h , ioctl.h as examples 280 */ 281#ifndef SYS_DHIO_H 282#define SYS_DHIO_H 283 284#ifndef KERNEL 285#include <sys/types.h> 286#endif 287#include <sys/ioccom.h> 288 289/* 290 * define an ioctl here 291 */ 292#define DHIOCRESET _IO('D', 0) /* reset the ${1} device */ 293#endif 294DONE 295 296config ${UPPER} 297cd ../../compile/${UPPER} 298make depend 299make ${1}.o 300make 301exit 302 303#--------------end of script--------------- 304# 305#you also need to add an entry into the cdevsw[] 306#array in conf.c, but it's too hard to do in a script.. 307# 308#edit to your taste.. 309# 310# 311 312 313