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