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