acpi: Narrow workaround for broken interrupt settings
[dragonfly.git] / share / examples / drivers / make_pseudo_driver.sh
blobef134d9693aa8fd0500696d5efa69c64545cce74
1 #!/bin/sh
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------------------
8 cd /sys/config
10 if [ "${1}X" = "X" ]
11 then
12 echo "Hey , how about some help here.. give me a device name!"
13 exit 1
16 UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"`
17 cat >files.${UPPER} <<DONE
18 dev/${1}.c optional ${1} device-driver
19 DONE
21 cat >${UPPER} <<DONE
22 # Configuration file for kernel type: ${UPPER}
23 ident ${UPPER}
24 DONE
26 grep -v X86_64_GENERIC < X86_64_GENERIC >>${UPPER}
28 cat >>${UPPER} <<DONE
29 # trust me, you'll need this
30 options DDB
31 pseudo-device ${1} 4 # might as well allow 4 of them
32 DONE
34 cat >../../dev/${1}.c <<DONE
36 * Copyright ME
38 * ${1} driver
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 */
53 /* Function prototypes (these should all be static) */
54 static d_open_t ${1}open;
55 static d_close_t ${1}close;
56 static d_read_t ${1}read;
57 static d_write_t ${1}write;
58 static d_ioctl_t ${1}ioctl;
59 static d_mmap_t ${1}mmap;
60 static d_poll_t ${1}poll;
62 #define CDEV_MAJOR 20
63 static 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 };
79 /*
80 * device specific Misc defines
82 #define BUFFERSIZE 1024
83 #define UNIT(dev) minor(dev) /* assume one minor number per unit */
86 * One of these per allocated device
88 struct ${1}_softc {
89 struct isa_device *dev;
90 char buffer[BUFFERSIZE];
91 } ;
93 typedef struct ${1}_softc *sc_p;
95 static sc_p sca[N${UPPER}];
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.
104 #define CHECKUNIT(RETVAL) \
105 do { /* 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); \
110 if (scp == NULL) { \
111 printf("%s: unit %d not attached\n", __func__, unit);\
112 return (RETVAL); \
114 } while (0)
115 #ifdef DIAGNOSTIC
116 #define CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL)
117 #else /* DIAGNOSTIC */
118 #define CHECKUNIT_DIAG(RETVAL)
119 #endif /* DIAGNOSTIC */
121 int ${1}ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
123 int unit = UNIT (dev);
124 sc_p scp = sca[unit];
126 CHECKUNIT_DIAG(ENXIO);
128 switch (cmd) {
129 case DHIOCRESET:
130 /* whatever resets it */
131 outb(scp->dev->id_iobase, 0xff);
132 break;
133 default:
134 return ENXIO;
136 return (0);
139 * You also need read, write, open, close routines.
140 * This should get you started
142 static int
143 ${1}open(dev_t dev, int oflags, int devtype, struct proc *p)
145 int unit = UNIT (dev);
146 sc_p scp = sca[unit];
148 CHECKUNIT(ENXIO);
151 * Do processing
153 return (0);
156 static int
157 ${1}close(dev_t dev, int fflag, int devtype, struct proc *p)
159 int unit = UNIT (dev);
160 sc_p scp = sca[unit];
162 CHECKUNIT_DIAG(ENXIO);
165 * Do processing
167 return (0);
170 static int
171 ${1}read(dev_t dev, struct uio *uio, int ioflag)
173 int unit = UNIT (dev);
174 sc_p scp = sca[unit];
175 int toread;
178 CHECKUNIT_DIAG(ENXIO);
181 * Do processing
182 * read from buffer
184 toread = (min(uio->uio_resid, sizeof(scp->buffer)));
185 return(uiomove(scp->buffer, toread, uio));
188 static int
189 ${1}write(dev_t dev, struct uio *uio, int ioflag)
191 int unit = UNIT (dev);
192 sc_p scp = sca[unit];
193 int towrite;
195 CHECKUNIT_DIAG(ENXIO);
198 * Do processing
199 * write to buffer
201 towrite = (min(uio->uio_resid, sizeof(scp->buffer)));
202 return(uiomove(scp->buffer, towrite, uio));
205 static int
206 ${1}mmap(dev_t dev, int offset, int nprot)
208 int unit = UNIT (dev);
209 sc_p scp = sca[unit];
211 CHECKUNIT_DIAG(-1);
214 * Do processing
216 #if 0 /* if we had a frame buffer or whatever.. do this */
217 if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) {
218 return (-1);
220 return i386_btop((FRAMEBASE + offset));
221 #else
222 return (-1);
223 #endif
226 static int
227 ${1}poll(dev_t dev, int which, struct proc *p)
229 int unit = UNIT (dev);
230 sc_p scp = sca[unit];
232 CHECKUNIT_DIAG(ENXIO);
235 * Do processing
237 return (0); /* this is the wrong value I'm sure */
241 * Now for some driver initialisation.
242 * Occurs ONCE during boot (very early).
244 static void
245 ${1}_drvinit(void *unused)
247 dev_t dev;
248 int unit;
249 sc_p scp = sca[unit];
251 dev = makedev(CDEV_MAJOR, 0);
252 cdevsw_add(&dev, &${1}_cdevsw, NULL);
253 for (unit = 0; unit < N${UPPER}; unit++) {
255 * Allocate storage for this instance .
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 ;
262 bzero(scp, sizeof(*scp));
263 sca[unit] = scp;
267 SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR,
268 ${1}_drvinit, NULL)
271 DONE
273 cat >../../sys/${1}io.h <<DONE
275 * Definitions needed to access the ${1} device (ioctls etc)
276 * see mtio.h , ioctl.h as examples
278 #ifndef SYS_DHIO_H
279 #define SYS_DHIO_H
281 #ifndef KERNEL
282 #include <sys/types.h>
283 #endif
284 #include <sys/ioccom.h>
287 * define an ioctl here
289 #define DHIOCRESET _IO('D', 0) /* reset the ${1} device */
290 #endif
291 DONE
293 config ${UPPER}
294 cd ../../compile/${UPPER}
295 make depend
296 make ${1}.o
297 make
298 exit
300 #--------------end of script---------------
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..
305 #edit to your taste..