Deleted Added
sdiff udiff text old ( 50476 ) new ( 76175 )
full compact
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: head/share/examples/drivers/make_pseudo_driver.sh 50476 1999-08-28 00:22:10Z peter $"
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 * \$FreeBSD: head/share/examples/drivers/make_pseudo_driver.sh 50476 1999-08-28 00:22:10Z peter $
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