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# 26if [ "X${1}" = "X" ]; then 27 echo "Hey, how about some help here... give me a device name!" 28 exit 1 29fi 30if [ "X${2}" = "X" ]; then 31 TOP=`cd /sys; pwd -P` 32 echo "Using ${TOP} as the path to the kernel sources!" 33else 34 TOP=${2} 35fi 36UPPER=`echo ${1} |tr "[:lower:]" "[:upper:]"` 37 38RCS_KEYWORD=FreeBSD 39 40if [ -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 60fi 61 62echo "The following files will be created:" 63echo ${TOP}/modules/${1} 64echo ${TOP}/conf/files.${UPPER} 65echo ${TOP}/i386/conf/${UPPER} 66echo ${TOP}/dev/${1} 67echo ${TOP}/dev/${1}/${1}.c 68echo ${TOP}/sys/${1}io.h 69echo ${TOP}/modules/${1} 70echo ${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 85cat >${TOP}/conf/files.${UPPER} <<DONE 86dev/${1}/${1}.c optional ${1} 87DONE 88 89####################################################################### 90# Then create a configuration file for a kernel that contains this driver. 91####################################################################### 92cat >${TOP}/i386/conf/${UPPER} <<DONE 93# Configuration file for kernel type: ${UPPER} 94# \$${RCS_KEYWORD}$ 95 96files "${TOP}/conf/files.${UPPER}" 97 98include GENERIC 99 100ident ${UPPER} 101 102DONE 103 104cat >>${TOP}/i386/conf/${UPPER} <<DONE 105# trust me, you'll need this 106options KDB 107options DDB 108device ${1} 109DONE 110 111if [ ! -d ${TOP}/dev/${1} ]; then 112 mkdir -p ${TOP}/dev/${1} 113fi 114 115cat >${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 */ 196struct ${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). */ 215static int ${1}_deallocate_resources(device_t device); 216static int ${1}_allocate_resources(device_t device); 217static int ${1}_attach(device_t device, struct ${1}_softc *scp); 218static int ${1}_detach(device_t device, struct ${1}_softc *scp); 219 220static d_open_t ${1}open; 221static d_close_t ${1}close; 222static d_read_t ${1}read; 223static d_write_t ${1}write; 224static d_ioctl_t ${1}ioctl; 225static d_mmap_t ${1}mmap; 226static d_poll_t ${1}poll; 227static void ${1}intr(void *arg); 228 229static 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 241static devclass_t ${1}_devclass; 242 243/* 244 ****************************************** 245 * ISA Attachment structures and functions. 246 ****************************************** 247 */ 248static void ${1}_isa_identify (driver_t *, device_t); 249static int ${1}_isa_probe (device_t); 250static int ${1}_isa_attach (device_t); 251static int ${1}_isa_detach (device_t); 252 253static struct isa_pnp_id ${1}_ids[] = { 254 {0x12345678, "ABCco Widget"}, 255 {0xfedcba98, "shining moon Widget ripoff"}, 256 {0, NULL} 257}; 258 259static 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 267static driver_t ${1}_isa_driver = { 268 "${1}", 269 ${1}_methods, 270 sizeof (struct ${1}_softc) 271}; 272 273DRIVER_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 */ 283static 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 */ 328static 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 */ 389static 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 } 513errexit: 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 */ 524static 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 */ 541static 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 557static int ${1}_pci_probe(device_t); 558static int ${1}_pci_attach(device_t); 559static int ${1}_pci_detach(device_t); 560 561static 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 569static driver_t ${1}_pci_driver = { 570 "${1}", 571 ${1}_pci_methods, 572 sizeof(struct ${1}_softc), 573}; 574 575DRIVER_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 */ 580DRIVER_MODULE(${1}, cardbus, ${1}_pci_driver, ${1}_devclass, 0, 0); 581 582static 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 */ 602static 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 617static 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 629static 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 */ 644static 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 693errexit: 694 /* 695 * Undo anything we may have done. 696 */ 697 ${1}_detach(device, scp); 698 return (ENXIO); 699} 700 701static 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 738static 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 766errexit: 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 773static 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 811static 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 826static 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 */ 848static 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 860static 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 872static 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 887static 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 902static 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 921static 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 933DONE 934 935cat >${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 953DONE 954 955if [ ! -d ${TOP}/modules/${1} ]; then 956 mkdir -p ${TOP}/modules/${1} 957fi 958 959cat >${TOP}/modules/${1}/Makefile <<DONE 960# ${UPPER} Loadable Kernel Module 961# 962# \$${RCS_KEYWORD}: $ 963 964.PATH: \${.CURDIR}/../../dev/${1} 965KMOD = ${1} 966SRCS = ${1}.c 967SRCS += 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. 970opt_inet.h: 971 echo "#define INET 1" > opt_inet.h 972 973.include <bsd.kmod.mk> 974DONE 975 976echo -n "Do you want to build the '${1}' module? [Y]" 977read VAL 978if [ "-z" "$VAL" ]; then 979 VAL=YES 980fi 981case ${VAL} in 982[yY]*) 983 (cd ${TOP}/modules/${1}; make depend; make ) 984 ;; 985*) 986# exit 987 ;; 988esac 989 990echo "" 991echo -n "Do you want to build the '${UPPER}' kernel? [Y]" 992read VAL 993if [ "-z" "$VAL" ]; then 994 VAL=YES 995fi 996case ${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 ;; 1009esac 1010 1011#--------------end of script--------------- 1012# 1013# Edit to your taste... 1014# 1015# 1016