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