]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - share/examples/drivers/make_device_driver.sh
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / share / examples / drivers / make_device_driver.sh
1 #!/bin/sh
2 # This writes a skeleton driver and puts it into the kernel tree for you.
3 # It also adds FOO and files.FOO configuration files so you can compile
4 # a kernel with your FOO driver linked in.
5 # To do so:
6 # cd /usr/src; make buildkernel KERNCONF=FOO
7 #
8 # More interestingly, it creates a modules/foo directory
9 # which it populates, to allow you to compile a FOO module
10 # which can be linked with your presently running kernel (if you feel brave).
11 # To do so:
12 # cd /sys/modules/foo; make depend; make; make install; kldload foo
13 #
14 # arg1 to this script is expected to be lowercase "foo"
15 # arg2 path to the kernel sources, "/sys" if omitted
16 #
17 # Trust me, RUN THIS SCRIPT :)
18 #
19 # TODO:
20 #   o generate foo_isa.c, foo_pci.c, foo_pccard.c, foo_cardbus.c, and foovar.h
21 #   o Put pccard stuff in here.
22 #
23 # $FreeBSD$"
24 #
25 #
26 if [ "X${1}" = "X" ]; then
27         echo "Hey, how about some help here... give me a device name!"
28         exit 1
29 fi
30 if [ "X${2}" = "X" ]; then
31         TOP=`cd /sys; pwd -P`
32         echo "Using ${TOP} as the path to the kernel sources!"
33 else
34         TOP=${2}
35 fi
36 UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"`
37
38 RCS_KEYWORD=FreeBSD
39
40 if [ -d ${TOP}/modules/${1} ]; then
41         echo "There appears to already be a module called ${1}"
42         echo -n "Should it be overwritten? [Y]"
43         read VAL
44         if [ "-z" "$VAL" ]; then
45                 VAL=YES
46         fi
47         case ${VAL} in
48         [yY]*)
49                 echo "Cleaning up from prior runs"
50                 rm -rf ${TOP}/dev/${1}
51                 rm -rf ${TOP}/modules/${1}
52                 rm ${TOP}/conf/files.${UPPER}
53                 rm ${TOP}/i386/conf/${UPPER}
54                 rm ${TOP}/sys/${1}io.h
55                 ;;
56         *)
57                 exit 1
58                 ;;
59         esac
60 fi
61
62 echo "The following files will be created:"
63 echo ${TOP}/modules/${1}
64 echo ${TOP}/conf/files.${UPPER}
65 echo ${TOP}/i386/conf/${UPPER}
66 echo ${TOP}/dev/${1}
67 echo ${TOP}/dev/${1}/${1}.c
68 echo ${TOP}/sys/${1}io.h
69 echo ${TOP}/modules/${1}
70 echo ${TOP}/modules/${1}/Makefile
71
72         mkdir ${TOP}/modules/${1}
73
74 #######################################################################
75 #######################################################################
76 #
77 # Create configuration information needed to create a kernel
78 # containing this driver.
79 #
80 # Not really needed if we are going to do this as a module.
81 #######################################################################
82 # First add the file to a local file list.
83 #######################################################################
84
85 cat >${TOP}/conf/files.${UPPER} <<DONE
86 dev/${1}/${1}.c  optional ${1}
87 DONE
88
89 #######################################################################
90 # Then create a configuration file for a kernel that contains this driver.
91 #######################################################################
92 cat >${TOP}/i386/conf/${UPPER} <<DONE
93 # Configuration file for kernel type: ${UPPER}
94 # \$${RCS_KEYWORD}$
95
96 files           "${TOP}/conf/files.${UPPER}"
97
98 include         GENERIC
99
100 ident           ${UPPER}
101
102 DONE
103
104 cat >>${TOP}/i386/conf/${UPPER} <<DONE
105 # trust me, you'll need this
106 options         KDB
107 options         DDB
108 device          ${1}
109 DONE
110
111 if [ ! -d ${TOP}/dev/${1} ]; then
112         mkdir -p ${TOP}/dev/${1}
113 fi
114
115 cat >${TOP}/dev/${1}/${1}.c <<DONE
116 /*
117  * Copyright (c) [year] [your name]
118  * All rights reserved.
119  *
120  * Redistribution and use in source and binary forms, with or without
121  * modification, are permitted provided that the following conditions
122  * are met:
123  * 1. Redistributions of source code must retain the above copyright
124  *    notice, this list of conditions and the following disclaimer.
125  * 2. Redistributions in binary form must reproduce the above copyright
126  *    notice, this list of conditions and the following disclaimer in the
127  *    documentation and/or other materials provided with the distribution.
128  *
129  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
130  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
131  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
132  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
133  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
134  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
135  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
136  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
137  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
138  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
139  * SUCH DAMAGE.
140  */
141
142 /*
143  * http://www.daemonnews.org/200008/isa.html is required reading.
144  * hopefully it will make it's way into the handbook.
145  */
146
147 #include <sys/cdefs.h>
148 __FBSDID("\$${RCS_KEYWORD}$");
149
150 #include <sys/param.h>
151 #include <sys/systm.h>
152 #include <sys/conf.h>           /* cdevsw stuff */
153 #include <sys/kernel.h>         /* SYSINIT stuff */
154 #include <sys/uio.h>            /* SYSINIT stuff */
155 #include <sys/malloc.h>         /* malloc region definitions */
156 #include <sys/module.h>
157 #include <sys/bus.h>
158 #include <sys/proc.h>
159 #include <sys/time.h>
160 #include <sys/${1}io.h>         /* ${1} IOCTL definitions */
161
162 #include <machine/bus.h>
163 #include <machine/resource.h>
164 #include <sys/rman.h>
165
166 #include <dev/pci/pcireg.h>
167 #include <dev/pci/pcivar.h>
168
169 #include <isa/isavar.h>
170
171 #include "isa_if.h"
172
173 /* XXX These should be defined in terms of bus-space ops. */
174 #define ${UPPER}_INB(port) inb(port_start)
175 #define ${UPPER}_OUTB(port, val) ( port_start, (val))
176 #define SOME_PORT 123
177 #define EXPECTED_VALUE 0x42
178
179 /*
180  * The softc is automatically allocated by the parent bus using the
181  * size specified in the driver_t declaration below.
182  */
183 #define DEV2SOFTC(dev)  ((struct ${1}_softc *) (dev)->si_drv1)
184 #define DEVICE2SOFTC(dev) ((struct ${1}_softc *) device_get_softc(dev))
185
186 /*
187  * Device specific misc defines.
188  */
189 #define BUFFERSIZE      1024
190 #define NUMPORTS        4
191 #define MEMSIZE         (4 * 1024) /* Imaginable h/w buffer size. */
192
193 /*
194  * One of these per allocated device.
195  */
196 struct ${1}_softc {
197         bus_space_tag_t bt;
198         bus_space_handle_t bh;
199         int rid_ioport;
200         int rid_memory;
201         int rid_irq;
202         int rid_drq;
203         struct resource* res_ioport;    /* Resource for port range. */
204         struct resource* res_memory;    /* Resource for mem range. */
205         struct resource* res_irq;       /* Resource for irq range. */
206         struct resource* res_drq;       /* Resource for dma channel. */
207         device_t device;
208         struct cdev *dev;
209         void    *intr_cookie;
210         void    *vaddr;                 /* Virtual address of mem resource. */
211         char    buffer[BUFFERSIZE];     /* If we need to buffer something. */
212 };
213
214 /* Function prototypes (these should all be static). */
215 static int ${1}_deallocate_resources(device_t device);
216 static int ${1}_allocate_resources(device_t device);
217 static int ${1}_attach(device_t device, struct ${1}_softc *scp);
218 static int ${1}_detach(device_t device, struct ${1}_softc *scp);
219
220 static d_open_t         ${1}open;
221 static d_close_t        ${1}close;
222 static d_read_t         ${1}read;
223 static d_write_t        ${1}write;
224 static d_ioctl_t        ${1}ioctl;
225 static d_mmap_t         ${1}mmap;
226 static d_poll_t         ${1}poll;
227 static  void            ${1}intr(void *arg);
228
229 static struct cdevsw ${1}_cdevsw = {
230         .d_version =    D_VERSION,
231         .d_open =       ${1}open,
232         .d_close =      ${1}close,
233         .d_read =       ${1}read,
234         .d_write =      ${1}write,
235         .d_ioctl =      ${1}ioctl,
236         .d_poll =       ${1}poll,
237         .d_mmap =       ${1}mmap,
238         .d_name =       "${1}",
239 };
240
241 static devclass_t ${1}_devclass;
242
243 /*
244  ******************************************
245  * ISA Attachment structures and functions.
246  ******************************************
247  */
248 static void ${1}_isa_identify (driver_t *, device_t);
249 static int ${1}_isa_probe (device_t);
250 static int ${1}_isa_attach (device_t);
251 static int ${1}_isa_detach (device_t);
252
253 static struct isa_pnp_id ${1}_ids[] = {
254         {0x12345678,    "ABCco Widget"},
255         {0xfedcba98,    "shining moon Widget ripoff"},
256         {0,             NULL}
257 };
258
259 static device_method_t ${1}_methods[] = {
260         DEVMETHOD(device_identify,      ${1}_isa_identify),
261         DEVMETHOD(device_probe,         ${1}_isa_probe),
262         DEVMETHOD(device_attach,        ${1}_isa_attach),
263         DEVMETHOD(device_detach,        ${1}_isa_detach),
264         DEVMETHOD_END
265 };
266
267 static driver_t ${1}_isa_driver = {
268         "${1}",
269         ${1}_methods,
270         sizeof (struct ${1}_softc)
271 };
272
273 DRIVER_MODULE(${1}, isa, ${1}_isa_driver, ${1}_devclass, 0, 0);
274
275 /*
276  * Here list some port addresses we might expect our widget to appear at:
277  * This list should only be used for cards that have some non-destructive
278  * (to other cards) way of probing these address.  Otherwise the driver
279  * should not go looking for instances of itself, but instead rely on
280  * the hints file.  Strange failures for people with other cards might
281  * result.
282  */
283 static struct localhints {
284         int ioport;
285         int irq;
286         int drq;
287         int mem;
288 } res[] = {
289         { 0x210, 11, 2, 0xcd000},
290         { 0x310, 12, 3, 0xdd000},
291         { 0x320, 9, 6, 0xd4000},
292         {0,0,0,0}
293 };
294
295 #define MAXHINTS 10 /* Just an arbitrary safety limit. */
296 /*
297  * Called once when the driver is somehow connected with the bus,
298  * (Either linked in and the bus is started, or loaded as a module).
299  *
300  * The aim of this routine in an ISA driver is to add child entries to
301  * the parent bus so that it looks as if the devices were detected by
302  * some pnp-like method, or at least mentioned in the hints.
303  *
304  * For NON-PNP "dumb" devices:
305  * Add entries into the bus's list of likely devices, so that
306  * our 'probe routine' will be called for them.
307  * This is similar to what the 'hints' code achieves, except this is
308  * loadable with the driver.
309  * In the 'dumb' case we end up with more children than needed but
310  * some (or all) of them will fail probe() and only waste a little memory.
311  *
312  * For NON-PNP "Smart" devices:
313  * If the device has a NON-PNP way of being detected and setting/sensing
314  * the card, then do that here and add a child for each set of
315  * hardware found.
316  *
317  * For PNP devices:
318  * If the device is always PNP capable then this function can be removed.
319  * The ISA PNP system will have automatically added it to the system and
320  * so your identify routine needn't do anything.
321  *
322  * If the device is mentioned in the 'hints' file then this
323  * function can be removed. All devices mentioned in the hints
324  * file get added as children for probing, whether or not the
325  * driver is linked in. So even as a module it MAY still be there.
326  * See isa/isahint.c for hints being added in.
327  */
328 static void
329 ${1}_isa_identify (driver_t *driver, device_t parent)
330 {
331         u_int32_t       irq=0;
332         u_int32_t       ioport;
333         device_t        child;
334         int i;
335
336         /*
337          * If we've already got ${UPPER} attached somehow, don't try again.
338          * Maybe it was in the hints file. or it was loaded before.
339          */
340         if (device_find_child(parent, "${1}", 0)) {
341                 printf("${UPPER}: already attached\n");
342                 return;
343         }
344 /* XXX Look at dev/acpica/acpi_isa.c for use of ISA_ADD_CONFIG() macro. */
345 /* XXX What is ISA_SET_CONFIG_CALLBACK(parent, child, pnpbios_set_config, 0)? */
346         for (i = 0; i < MAXHINTS; i++) {
347
348                 ioport = res[i].ioport;
349                 irq = res[i].irq;
350                 if ((ioport == 0) && (irq == 0))
351                         return; /* We've added all our local hints. */
352
353                 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "${1}", -1);
354                 bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, NUMPORTS);
355                 bus_set_resource(child, SYS_RES_IRQ,    0, irq, 1);
356                 bus_set_resource(child, SYS_RES_DRQ,    0, res[i].drq, 1);
357                 bus_set_resource(child, SYS_RES_MEMORY, 0, res[i].mem, MEMSIZE);
358
359 #if 0
360                 /*
361                  * If we wanted to pretend PNP found it
362                  * we could do this, and put matching entries
363                  * in the PNP table, but I think it's probably too hacky.
364                  * As you see, some people have done it though.
365                  * Basically EISA (remember that?) would do this I think.
366                  */
367                 isa_set_vendorid(child, PNP_EISAID("ESS1888"));
368                 isa_set_logicalid(child, PNP_EISAID("ESS1888"));
369 #endif
370         }
371 #if 0
372         /*
373          * Do some smart probing (e.g. like the lnc driver)
374          * and add a child for each one found.
375          */
376 #endif
377
378         return;
379 }
380 /*
381  * The ISA code calls this for each device it knows about,
382  * whether via the PNP code or via the hints etc.
383  * If the device nas no PNP capabilities, remove all the
384  * PNP entries, but keep the call to ISA_PNP_PROBE()
385  * As it will guard against accidentally recognising
386  * foreign hardware. This is because we will be called to check against
387  * ALL PNP hardware.
388  */
389 static int
390 ${1}_isa_probe (device_t device)
391 {
392         int error;
393         device_t parent = device_get_parent(device);
394         struct ${1}_softc *scp = DEVICE2SOFTC(device);
395         u_long  port_start, port_count;
396
397         bzero(scp, sizeof(*scp));
398         scp->device = device;
399
400         /*
401          * Check this device for a PNP match in our table.
402          * There are several possible outcomes.
403          * error == 0           We match a PNP.
404          * error == ENXIO,      It is a PNP device but not in our table.
405          * error == ENOENT,     It is not a PNP device.. try heuristic probes.
406          *    -- logic from if_ed_isa.c, added info from isa/isa_if.m:
407          *
408          * If we had a list of devices that we could handle really well,
409          * and a list which we could handle only basic functions, then
410          * we would call this twice, once for each list,
411          * and return a value of '-2' or something if we could
412          * only handle basic functions. This would allow a specific
413          * Widgetplus driver to make a better offer if it knows how to
414          * do all the extended functions. (See non-pnp part for more info).
415          */
416         error = ISA_PNP_PROBE(parent, device, ${1}_ids);
417         switch (error) {
418         case 0:
419                 /*
420                  * We found a PNP device.
421                  * Do nothing, as it's all done in attach().
422                  */
423                 break;
424         case ENOENT:
425                 /*
426                  * Well it didn't show up in the PNP tables
427                  * so look directly at known ports (if we have any)
428                  * in case we are looking for an old pre-PNP card.
429                  *
430                  * Hopefully the  'identify' routine will have picked these
431                  * up for us first if they use some proprietary detection
432                  * method.
433                  *
434                  * The ports, irqs etc should come from a 'hints' section
435                  * which is read in by code in isa/isahint.c
436                  * and kern/subr_bus.c to create resource entries,
437                  * or have been added by the 'identify routine above.
438                  * Note that HINTS based resource requests have NO
439                  * SIZE for the memory or ports requests  (just a base)
440                  * so we may need to 'correct' this before we
441                  * do any probing.
442                  */
443                 /*
444                  * Find out the values of any resources we
445                  * need for our dumb probe. Also check we have enough ports
446                  * in the request. (could be hints based).
447                  * Should probably do the same for memory regions too.
448                  */
449                 error = bus_get_resource(device, SYS_RES_IOPORT, 0,
450                     &port_start, &port_count);
451                 if (port_count != NUMPORTS) {
452                         bus_set_resource(device, SYS_RES_IOPORT, 0,
453                             port_start, NUMPORTS);
454                 }
455
456                 /*
457                  * Make a temporary resource reservation.
458                  * If we can't get the resources we need then
459                  * we need to abort.  Possibly this indicates
460                  * the resources were used by another device
461                  * in which case the probe would have failed anyhow.
462                  */
463                 if ((error = (${1}_allocate_resources(device)))) {
464                         error = ENXIO;
465                         goto errexit;
466                 }
467
468                 /* Dummy heuristic type probe. */
469                 if (inb(port_start) != EXPECTED_VALUE) {
470                         /*
471                          * It isn't what we hoped, so quit looking for it.
472                          */
473                         error = ENXIO;
474                 } else {
475                         u_long membase = bus_get_resource_start(device,
476                                         SYS_RES_MEMORY, 0 /*rid*/);
477                         u_long memsize;
478                         /*
479                          * If we discover in some way that the device has
480                          * XXX bytes of memory window, we can override
481                          * or set the memory size in the child resource list.
482                          */
483                         memsize = inb(port_start + 1) * 1024; /* for example */
484                         error = bus_set_resource(device, SYS_RES_MEMORY,
485                                 /*rid*/0, membase, memsize);
486                         /*
487                          * We found one, return non-positive numbers..
488                          * Return -N if we can't handle it, but not well.
489                          * Return -2 if we would LIKE the device.
490                          * Return -1 if we want it a lot.
491                          * Return 0 if we MUST get the device.
492                          * This allows drivers to 'bid' for a device.
493                          */
494                         device_set_desc(device, "ACME Widget model 1234");
495                         error = -1; /* We want it but someone else
496                                         may be even better. */
497                 }
498                 /*
499                  * Unreserve the resources for now because
500                  * another driver may bid for device too.
501                  * If we lose the bid, but still hold the resources, we will
502                  * effectively have disabled the other driver from getting them
503                  * which will result in neither driver getting the device.
504                  * We will ask for them again in attach if we win.
505                  */
506                 ${1}_deallocate_resources(device);
507                 break;
508         case  ENXIO:
509                 /* It was PNP but not ours, leave immediately. */
510         default:
511                 error = ENXIO;
512         }
513 errexit:
514         return (error);
515 }
516
517 /*
518  * Called if the probe succeeded and our bid won the device.
519  * We can be destructive here as we know we have the device.
520  * This is the first place we can be sure we have a softc structure.
521  * You would do ISA specific attach things here, but generically there aren't
522  * any (yay new-bus!).
523  */
524 static int
525 ${1}_isa_attach (device_t device)
526 {
527         int     error;
528         struct ${1}_softc *scp = DEVICE2SOFTC(device);
529
530         error =  ${1}_attach(device, scp);
531         if (error)
532                 ${1}_isa_detach(device);
533         return (error);
534 }
535
536 /*
537  * Detach the driver (e.g. module unload),
538  * call the bus independent version
539  * and undo anything we did in the ISA attach routine.
540  */
541 static int
542 ${1}_isa_detach (device_t device)
543 {
544         int     error;
545         struct ${1}_softc *scp = DEVICE2SOFTC(device);
546
547         error =  ${1}_detach(device, scp);
548         return (error);
549 }
550
551 /*
552  ***************************************
553  * PCI Attachment structures and code
554  ***************************************
555  */
556
557 static int      ${1}_pci_probe(device_t);
558 static int      ${1}_pci_attach(device_t);
559 static int      ${1}_pci_detach(device_t);
560
561 static device_method_t ${1}_pci_methods[] = {
562         /* Device interface */
563         DEVMETHOD(device_probe,         ${1}_pci_probe),
564         DEVMETHOD(device_attach,        ${1}_pci_attach),
565         DEVMETHOD(device_detach,        ${1}_pci_detach),
566         { 0, 0 }
567 };
568
569 static driver_t ${1}_pci_driver = {
570         "${1}",
571         ${1}_pci_methods,
572         sizeof(struct ${1}_softc),
573 };
574
575 DRIVER_MODULE(${1}, pci, ${1}_pci_driver, ${1}_devclass, 0, 0);
576 /*
577  * Cardbus is a pci bus plus extra, so use the pci driver unless special
578  * things need to be done only in the cardbus case.
579  */
580 DRIVER_MODULE(${1}, cardbus, ${1}_pci_driver, ${1}_devclass, 0, 0);
581
582 static struct _pcsid
583 {
584         u_int32_t       type;
585         const char      *desc;
586 } pci_ids[] = {
587         { 0x1234abcd,   "ACME PCI Widgetplus"   },
588         { 0x1243fedc,   "Happy moon brand RIPOFFplus"   },
589         { 0x00000000,   NULL                                    }
590 };
591
592 /*
593  * See if this card is specifically mentioned in our list of known devices.
594  * Theoretically we might also put in a weak bid for some devices that
595  * report themselves to be some generic type of device if we can handle
596  * that generic type. (other PCI_XXX calls give that info).
597  * This would allow a specific driver to over-ride us.
598  *
599  * See the comments in the ISA section regarding returning non-positive
600  * values from probe routines.
601  */
602 static int
603 ${1}_pci_probe (device_t device)
604 {
605         u_int32_t       type = pci_get_devid(device);
606         struct _pcsid   *ep =pci_ids;
607
608         while (ep->type && ep->type != type)
609                 ++ep;
610         if (ep->desc) {
611                 device_set_desc(device, ep->desc);
612                 return 0; /* If there might be a better driver, return -2 */
613         } else
614                 return ENXIO;
615 }
616
617 static int
618 ${1}_pci_attach(device_t device)
619 {
620         int     error;
621         struct ${1}_softc *scp = DEVICE2SOFTC(device);
622
623         error =  ${1}_attach(device, scp);
624         if (error)
625                 ${1}_pci_detach(device);
626         return (error);
627 }
628
629 static int
630 ${1}_pci_detach (device_t device)
631 {
632         int     error;
633         struct ${1}_softc *scp = DEVICE2SOFTC(device);
634
635         error =  ${1}_detach(device, scp);
636         return (error);
637 }
638
639 /*
640  ****************************************
641  *  Common Attachment sub-functions
642  ****************************************
643  */
644 static int
645 ${1}_attach(device_t device, struct ${1}_softc * scp)
646 {
647         device_t parent = device_get_parent(device);
648         int     unit    = device_get_unit(device);
649
650         scp->dev = make_dev(&${1}_cdevsw, 0,
651                         UID_ROOT, GID_OPERATOR, 0600, "${1}%d", unit);
652         scp->dev->si_drv1 = scp;
653
654         if (${1}_allocate_resources(device))
655                 goto errexit;
656
657         scp->bt = rman_get_bustag(scp->res_ioport);
658         scp->bh = rman_get_bushandle(scp->res_ioport);
659
660         /* Register the interrupt handler. */
661         /*
662          * The type should be one of:
663          *      INTR_TYPE_TTY
664          *      INTR_TYPE_BIO
665          *      INTR_TYPE_CAM
666          *      INTR_TYPE_NET
667          *      INTR_TYPE_MISC
668          * This will probably change with SMPng.  INTR_TYPE_FAST may be
669          * OR'd into this type to mark the interrupt fast.  However, fast
670          * interrupts cannot be shared at all so special precautions are
671          * necessary when coding fast interrupt routines.
672          */
673         if (scp->res_irq) {
674                 /* Default to the tty mask for registration. */  /* XXX */
675                 if (BUS_SETUP_INTR(parent, device, scp->res_irq, INTR_TYPE_TTY,
676                                 ${1}intr, scp, &scp->intr_cookie) == 0) {
677                         /* Do something if successful. */
678                 } else
679                         goto errexit;
680         }
681
682         /*
683          * If we want to access the memory we will need
684          * to know where it was mapped.
685          *
686          * Use of this function is discouraged, however.  You should
687          * be accessing the device with the bus_space API if at all
688          * possible.
689          */
690         scp->vaddr = rman_get_virtual(scp->res_memory);
691         return 0;
692
693 errexit:
694         /*
695          * Undo anything we may have done.
696          */
697         ${1}_detach(device, scp);
698         return (ENXIO);
699 }
700
701 static int
702 ${1}_detach(device_t device, struct ${1}_softc *scp)
703 {
704         device_t parent = device_get_parent(device);
705
706         /*
707          * At this point stick a strong piece of wood into the device
708          * to make sure it is stopped safely. The alternative is to
709          * simply REFUSE to detach if it's busy. What you do depends on
710          * your specific situation.
711          *
712          * Sometimes the parent bus will detach you anyway, even if you
713          * are busy.  You must cope with that possibility.  Your hardware
714          * might even already be gone in the case of cardbus or pccard
715          * devices.
716          */
717         /* ZAP some register */
718
719         /*
720          * Take our interrupt handler out of the list of handlers
721          * that can handle this irq.
722          */
723         if (scp->intr_cookie != NULL) {
724                 if (BUS_TEARDOWN_INTR(parent, device,
725                         scp->res_irq, scp->intr_cookie) != 0)
726                                 printf("intr teardown failed.. continuing\n");
727                 scp->intr_cookie = NULL;
728         }
729
730         /*
731          * Deallocate any system resources we may have
732          * allocated on behalf of this driver.
733          */
734         scp->vaddr = NULL;
735         return ${1}_deallocate_resources(device);
736 }
737
738 static int
739 ${1}_allocate_resources(device_t device)
740 {
741         int error;
742         struct ${1}_softc *scp = DEVICE2SOFTC(device);
743         int     size = 16; /* SIZE of port range used. */
744
745         scp->res_ioport = bus_alloc_resource(device, SYS_RES_IOPORT,
746                         &scp->rid_ioport, 0ul, ~0ul, size, RF_ACTIVE);
747         if (scp->res_ioport == NULL)
748                 goto errexit;
749
750         scp->res_irq = bus_alloc_resource(device, SYS_RES_IRQ,
751                         &scp->rid_irq, 0ul, ~0ul, 1, RF_SHAREABLE|RF_ACTIVE);
752         if (scp->res_irq == NULL)
753                 goto errexit;
754
755         scp->res_drq = bus_alloc_resource(device, SYS_RES_DRQ,
756                         &scp->rid_drq, 0ul, ~0ul, 1, RF_ACTIVE);
757         if (scp->res_drq == NULL)
758                 goto errexit;
759
760         scp->res_memory = bus_alloc_resource(device, SYS_RES_MEMORY,
761                         &scp->rid_memory, 0ul, ~0ul, MSIZE, RF_ACTIVE);
762         if (scp->res_memory == NULL)
763                 goto errexit;
764         return (0);
765
766 errexit:
767         error = ENXIO;
768         /* Cleanup anything we may have assigned. */
769         ${1}_deallocate_resources(device);
770         return (ENXIO); /* For want of a better idea. */
771 }
772
773 static int
774 ${1}_deallocate_resources(device_t device)
775 {
776         struct ${1}_softc *scp = DEVICE2SOFTC(device);
777
778         if (scp->res_irq != 0) {
779                 bus_deactivate_resource(device, SYS_RES_IRQ,
780                         scp->rid_irq, scp->res_irq);
781                 bus_release_resource(device, SYS_RES_IRQ,
782                         scp->rid_irq, scp->res_irq);
783                 scp->res_irq = 0;
784         }
785         if (scp->res_ioport != 0) {
786                 bus_deactivate_resource(device, SYS_RES_IOPORT,
787                         scp->rid_ioport, scp->res_ioport);
788                 bus_release_resource(device, SYS_RES_IOPORT,
789                         scp->rid_ioport, scp->res_ioport);
790                 scp->res_ioport = 0;
791         }
792         if (scp->res_memory != 0) {
793                 bus_deactivate_resource(device, SYS_RES_MEMORY,
794                         scp->rid_memory, scp->res_memory);
795                 bus_release_resource(device, SYS_RES_MEMORY,
796                         scp->rid_memory, scp->res_memory);
797                 scp->res_memory = 0;
798         }
799         if (scp->res_drq != 0) {
800                 bus_deactivate_resource(device, SYS_RES_DRQ,
801                         scp->rid_drq, scp->res_drq);
802                 bus_release_resource(device, SYS_RES_DRQ,
803                         scp->rid_drq, scp->res_drq);
804                 scp->res_drq = 0;
805         }
806         if (scp->dev)
807                 destroy_dev(scp->dev);
808         return (0);
809 }
810
811 static void
812 ${1}intr(void *arg)
813 {
814         struct ${1}_softc *scp = (struct ${1}_softc *) arg;
815
816         /*
817          * Well we got an interrupt, now what?
818          *
819          * Make sure that the interrupt routine will always terminate,
820          * even in the face of "bogus" data from the card.
821          */
822         (void)scp; /* Delete this line after using scp. */
823         return;
824 }
825
826 static int
827 ${1}ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
828 {
829         struct ${1}_softc *scp = DEV2SOFTC(dev);
830
831         (void)scp; /* Delete this line after using scp. */
832         switch (cmd) {
833         case DHIOCRESET:
834                 /* Whatever resets it. */
835 #if 0
836                 ${UPPER}_OUTB(SOME_PORT, 0xff);
837 #endif
838                 break;
839         default:
840                 return ENXIO;
841         }
842         return (0);
843 }
844 /*
845  * You also need read, write, open, close routines.
846  * This should get you started.
847  */
848 static int
849 ${1}open(struct cdev *dev, int oflags, int devtype, struct thread *td)
850 {
851         struct ${1}_softc *scp = DEV2SOFTC(dev);
852
853         /*
854          * Do processing.
855          */
856         (void)scp; /* Delete this line after using scp. */
857         return (0);
858 }
859
860 static int
861 ${1}close(struct cdev *dev, int fflag, int devtype, struct thread *td)
862 {
863         struct ${1}_softc *scp = DEV2SOFTC(dev);
864
865         /*
866          * Do processing.
867          */
868         (void)scp; /* Delete this line after using scp. */
869         return (0);
870 }
871
872 static int
873 ${1}read(struct cdev *dev, struct uio *uio, int ioflag)
874 {
875         struct ${1}_softc *scp = DEV2SOFTC(dev);
876         int      toread;
877
878         /*
879          * Do processing.
880          * Read from buffer.
881          */
882         (void)scp; /* Delete this line after using scp. */
883         toread = (min(uio->uio_resid, sizeof(scp->buffer)));
884         return(uiomove(scp->buffer, toread, uio));
885 }
886
887 static int
888 ${1}write(struct cdev *dev, struct uio *uio, int ioflag)
889 {
890         struct ${1}_softc *scp = DEV2SOFTC(dev);
891         int     towrite;
892
893         /*
894          * Do processing.
895          * Write to buffer.
896          */
897         (void)scp; /* Delete this line after using scp. */
898         towrite = (min(uio->uio_resid, sizeof(scp->buffer)));
899         return(uiomove(scp->buffer, towrite, uio));
900 }
901
902 static int
903 ${1}mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
904 {
905         struct ${1}_softc *scp = DEV2SOFTC(dev);
906
907         /*
908          * Given a byte offset into your device, return the PHYSICAL
909          * page number that it would map to.
910          */
911         (void)scp; /* Delete this line after using scp. */
912 #if 0   /* If we had a frame buffer or whatever... do this. */
913         if (offset > FRAMEBUFFERSIZE - PAGE_SIZE)
914                 return (-1);
915         return i386_btop((FRAMEBASE + offset));
916 #else
917         return (-1);
918 #endif
919 }
920
921 static int
922 ${1}poll(struct cdev *dev, int which, struct thread *td)
923 {
924         struct ${1}_softc *scp = DEV2SOFTC(dev);
925
926         /*
927          * Do processing.
928          */
929         (void)scp; /* Delete this line after using scp. */
930         return (0); /* This is the wrong value I'm sure. */
931 }
932
933 DONE
934
935 cat >${TOP}/sys/${1}io.h <<DONE
936 /*
937  * Definitions needed to access the ${1} device (ioctls etc)
938  * see mtio.h, ioctl.h as examples.
939  */
940 #ifndef SYS_DHIO_H
941 #define SYS_DHIO_H
942
943 #ifndef KERNEL
944 #include <sys/types.h>
945 #endif
946 #include <sys/ioccom.h>
947
948 /*
949  * Define an ioctl here.
950  */
951 #define DHIOCRESET _IO('D', 0) /* Reset the ${1} device. */
952 #endif
953 DONE
954
955 if [ ! -d ${TOP}/modules/${1} ]; then
956         mkdir -p ${TOP}/modules/${1}
957 fi
958
959 cat >${TOP}/modules/${1}/Makefile <<DONE
960 #       ${UPPER} Loadable Kernel Module
961 #
962 # \$${RCS_KEYWORD}: $
963
964 .PATH:  \${.CURDIR}/../../dev/${1}
965 KMOD    = ${1}
966 SRCS    = ${1}.c
967 SRCS    += opt_inet.h device_if.h bus_if.h pci_if.h isa_if.h
968
969 # You may need to do this is your device is an if_xxx driver.
970 opt_inet.h:
971         echo "#define INET 1" > opt_inet.h
972
973 .include <bsd.kmod.mk>
974 DONE
975
976 echo -n "Do you want to build the '${1}' module? [Y]"
977 read VAL
978 if [ "-z" "$VAL" ]; then
979         VAL=YES
980 fi
981 case ${VAL} in
982 [yY]*)
983         (cd ${TOP}/modules/${1}; make depend; make )
984         ;;
985 *)
986 #       exit
987         ;;
988 esac
989
990 echo ""
991 echo -n "Do you want to build the '${UPPER}' kernel? [Y]"
992 read VAL
993 if [ "-z" "$VAL" ]; then
994         VAL=YES
995 fi
996 case ${VAL} in
997 [yY]*)
998         (
999          cd ${TOP}/i386/conf; \
1000          config ${UPPER}; \
1001          cd ${TOP}/i386/compile/${UPPER}; \
1002          make depend; \
1003          make; \
1004         )
1005         ;;
1006 *)
1007 #       exit
1008         ;;
1009 esac
1010
1011 #--------------end of script---------------
1012 #
1013 # Edit to your taste...
1014 #
1015 #