Add a wlan_ratectl(4) manual page and reference it from drivers that support
[dragonfly/vkernel-mp.git] / share / examples / drivers / make_pseudo_driver.sh
blob5061063ed83364f16ec1c91bd8fa46bcb948fce7
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 # \$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.5 2006/10/24 19:09:45 swildner Exp $"
26 DONE
28 grep -v GENERIC < GENERIC >>${UPPER}
30 cat >>${UPPER} <<DONE
31 # trust me, you'll need this
32 options DDB
33 pseudo-device ${1} 4 # might as well allow 4 of them
34 DONE
36 cat >../../dev/${1}.c <<DONE
38 * Copyright ME
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 $
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 */
56 /* Function prototypes (these should all be static) */
57 static d_open_t ${1}open;
58 static d_close_t ${1}close;
59 static d_read_t ${1}read;
60 static d_write_t ${1}write;
61 static d_ioctl_t ${1}ioctl;
62 static d_mmap_t ${1}mmap;
63 static d_poll_t ${1}poll;
65 #define CDEV_MAJOR 20
66 static 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 };
82 /*
83 * device specific Misc defines
85 #define BUFFERSIZE 1024
86 #define UNIT(dev) minor(dev) /* assume one minor number per unit */
89 * One of these per allocated device
91 struct ${1}_softc {
92 struct isa_device *dev;
93 char buffer[BUFFERSIZE];
94 } ;
96 typedef struct ${1}_softc *sc_p;
98 static sc_p sca[N${UPPER}];
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.
107 #define CHECKUNIT(RETVAL) \
108 do { /* the do-while is a safe way to do this grouping */ \
109 if (unit > N${UPPER}) { \
110 printf("%s: bad unit %d\n", __func__, unit); \
111 return (RETVAL); \
113 if (scp == NULL) { \
114 printf("%s: unit %d not attached\n", __func__, unit);\
115 return (RETVAL); \
117 } while (0)
118 #ifdef DIAGNOSTIC
119 #define CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL)
120 #else /* DIAGNOSTIC */
121 #define CHECKUNIT_DIAG(RETVAL)
122 #endif /* DIAGNOSTIC */
124 int ${1}ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
126 int unit = UNIT (dev);
127 sc_p scp = sca[unit];
129 CHECKUNIT_DIAG(ENXIO);
131 switch (cmd) {
132 case DHIOCRESET:
133 /* whatever resets it */
134 outb(scp->dev->id_iobase, 0xff);
135 break;
136 default:
137 return ENXIO;
139 return (0);
142 * You also need read, write, open, close routines.
143 * This should get you started
145 static int
146 ${1}open(dev_t dev, int oflags, int devtype, struct proc *p)
148 int unit = UNIT (dev);
149 sc_p scp = sca[unit];
151 CHECKUNIT(ENXIO);
154 * Do processing
156 return (0);
159 static int
160 ${1}close(dev_t dev, int fflag, int devtype, struct proc *p)
162 int unit = UNIT (dev);
163 sc_p scp = sca[unit];
165 CHECKUNIT_DIAG(ENXIO);
168 * Do processing
170 return (0);
173 static int
174 ${1}read(dev_t dev, struct uio *uio, int ioflag)
176 int unit = UNIT (dev);
177 sc_p scp = sca[unit];
178 int toread;
181 CHECKUNIT_DIAG(ENXIO);
184 * Do processing
185 * read from buffer
187 toread = (min(uio->uio_resid, sizeof(scp->buffer)));
188 return(uiomove(scp->buffer, toread, uio));
191 static int
192 ${1}write(dev_t dev, struct uio *uio, int ioflag)
194 int unit = UNIT (dev);
195 sc_p scp = sca[unit];
196 int towrite;
198 CHECKUNIT_DIAG(ENXIO);
201 * Do processing
202 * write to buffer
204 towrite = (min(uio->uio_resid, sizeof(scp->buffer)));
205 return(uiomove(scp->buffer, towrite, uio));
208 static int
209 ${1}mmap(dev_t dev, int offset, int nprot)
211 int unit = UNIT (dev);
212 sc_p scp = sca[unit];
214 CHECKUNIT_DIAG(-1);
217 * Do processing
219 #if 0 /* if we had a frame buffer or whatever.. do this */
220 if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) {
221 return (-1);
223 return i386_btop((FRAMEBASE + offset));
224 #else
225 return (-1);
226 #endif
229 static int
230 ${1}poll(dev_t dev, int which, struct proc *p)
232 int unit = UNIT (dev);
233 sc_p scp = sca[unit];
235 CHECKUNIT_DIAG(ENXIO);
238 * Do processing
240 return (0); /* this is the wrong value I'm sure */
244 * Now for some driver initialisation.
245 * Occurs ONCE during boot (very early).
247 static void
248 ${1}_drvinit(void *unused)
250 dev_t dev;
251 int unit;
252 sc_p scp = sca[unit];
254 dev = makedev(CDEV_MAJOR, 0);
255 cdevsw_add(&dev, &${1}_cdevsw, NULL);
256 for (unit = 0; unit < N${UPPER}; unit++) {
258 * Allocate storage for this instance .
260 scp = kmalloc(sizeof(*scp), M_DEVBUF, M_NOWAIT);
261 if( scp == NULL) {
262 printf("${1}%d failed to allocate strorage\n", unit);
263 return ;
265 bzero(scp, sizeof(*scp));
266 sca[unit] = scp;
270 SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR,
271 ${1}_drvinit, NULL)
274 DONE
276 cat >../../sys/${1}io.h <<DONE
278 * Definitions needed to access the ${1} device (ioctls etc)
279 * see mtio.h , ioctl.h as examples
281 #ifndef SYS_DHIO_H
282 #define SYS_DHIO_H
284 #ifndef KERNEL
285 #include <sys/types.h>
286 #endif
287 #include <sys/ioccom.h>
290 * define an ioctl here
292 #define DHIOCRESET _IO('D', 0) /* reset the ${1} device */
293 #endif
294 DONE
296 config ${UPPER}
297 cd ../../compile/${UPPER}
298 make depend
299 make ${1}.o
300 make
301 exit
303 #--------------end of script---------------
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..
308 #edit to your taste..