pci.c revision 48432
1/* 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $Id: pci.c,v 1.108 1999/05/31 22:13:34 roger Exp $ 27 * 28 */ 29 30#include "opt_bus.h" 31 32#include "pci.h" 33#if NPCI > 0 34 35#include "opt_devfs.h" 36#include "opt_simos.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/module.h> 42#include <sys/fcntl.h> 43#include <sys/conf.h> 44#include <sys/kernel.h> 45#include <sys/queue.h> 46#include <sys/types.h> 47#include <sys/buf.h> 48#ifdef DEVFS 49#include <sys/devfsext.h> 50#endif /* DEVFS */ 51 52#include <vm/vm.h> 53#include <vm/pmap.h> 54#include <vm/vm_extern.h> 55 56#include <sys/bus.h> 57#include <machine/bus.h> 58#include <sys/rman.h> 59#include <machine/resource.h> 60#include <machine/md_var.h> /* For the Alpha */ 61 62#include <pci/pcireg.h> 63#include <pci/pcivar.h> 64#include <pci/pci_ioctl.h> 65 66#ifdef APIC_IO 67#include <machine/smp.h> 68#endif /* APIC_IO */ 69 70static STAILQ_HEAD(devlist, pci_devinfo) pci_devq; 71u_int32_t pci_numdevs = 0; 72static u_int32_t pci_generation = 0; 73 74/* return base address of memory or port map */ 75 76static int 77pci_mapbase(unsigned mapreg) 78{ 79 int mask = 0x03; 80 if ((mapreg & 0x01) == 0) 81 mask = 0x0f; 82 return (mapreg & ~mask); 83} 84 85/* return map type of memory or port map */ 86 87static int 88pci_maptype(unsigned mapreg) 89{ 90 static u_int8_t maptype[0x10] = { 91 PCI_MAPMEM, PCI_MAPPORT, 92 PCI_MAPMEM, 0, 93 PCI_MAPMEM, PCI_MAPPORT, 94 0, 0, 95 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, 96 PCI_MAPMEM|PCI_MAPMEMP, 0, 97 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, 98 0, 0, 99 }; 100 101 return maptype[mapreg & 0x0f]; 102} 103 104/* return log2 of map size decoded for memory or port map */ 105 106static int 107pci_mapsize(unsigned testval) 108{ 109 int ln2size; 110 111 testval = pci_mapbase(testval); 112 ln2size = 0; 113 if (testval != 0) { 114 while ((testval & 1) == 0) 115 { 116 ln2size++; 117 testval >>= 1; 118 } 119 } 120 return (ln2size); 121} 122 123/* return log2 of address range supported by map register */ 124 125static int 126pci_maprange(unsigned mapreg) 127{ 128 int ln2range = 0; 129 switch (mapreg & 0x07) { 130 case 0x00: 131 case 0x01: 132 case 0x05: 133 ln2range = 32; 134 break; 135 case 0x02: 136 ln2range = 20; 137 break; 138 case 0x04: 139 ln2range = 64; 140 break; 141 } 142 return (ln2range); 143} 144 145/* extract map parameters into newly allocated array of pcimap structures */ 146 147static pcimap * 148pci_readmaps(pcicfgregs *cfg, int maxmaps) 149{ 150 int i, j = 0; 151 pcimap *map; 152 int map64 = 0; 153 int reg = PCIR_MAPS; 154 155 for (i = 0; i < maxmaps; i++) { 156 int reg = PCIR_MAPS + i*4; 157 u_int32_t base; 158 u_int32_t ln2range; 159 160 base = pci_cfgread(cfg, reg, 4); 161 ln2range = pci_maprange(base); 162 163 if (base == 0 || ln2range == 0 || base == 0xffffffff) 164 continue; /* skip invalid entry */ 165 else { 166 j++; 167 if (ln2range > 32) { 168 i++; 169 j++; 170 } 171 } 172 } 173 174 map = malloc(j * sizeof (pcimap), M_DEVBUF, M_WAITOK); 175 if (map != NULL) { 176 bzero(map, sizeof(pcimap) * j); 177 cfg->nummaps = j; 178 179 for (i = 0, j = 0; i < maxmaps; i++, reg += 4) { 180 u_int32_t base; 181 u_int32_t testval; 182 183 base = pci_cfgread(cfg, reg, 4); 184 185 if (map64 == 0) { 186 if (base == 0 || base == 0xffffffff) 187 continue; /* skip invalid entry */ 188 pci_cfgwrite(cfg, reg, 0xffffffff, 4); 189 testval = pci_cfgread(cfg, reg, 4); 190 pci_cfgwrite(cfg, reg, base, 4); 191 192 map[j].reg = reg; 193 map[j].base = pci_mapbase(base); 194 map[j].type = pci_maptype(base); 195 map[j].ln2size = pci_mapsize(testval); 196 map[j].ln2range = pci_maprange(testval); 197 map64 = map[j].ln2range == 64; 198 } else { 199 /* only fill in base, other fields are 0 */ 200 map[j].base = base; 201 map64 = 0; 202 } 203#ifdef __alpha__ 204 /* 205 * XXX: encode hose number in the base addr, 206 * This will go away once the bus_space functions 207 * can deal with multiple hoses 208 */ 209 210 if(cfg->hose){ 211 if(map[j].base & 0x80000000){ 212 printf("base addr = 0x%x\n", map[j].base); 213 printf("hacked addr = 0x%x\n", 214 map[j].base | (cfg->hose << 31)); 215 216 panic("hose encoding hack would clobber base addr"); 217 } 218 if(cfg->hose > 1 ) 219 panic("only one hose supported!"); 220 map[j].base |= (cfg->hose << 31); 221 } 222#endif 223 j++; 224 } 225 } 226 return (map); 227} 228 229/* adjust some values from PCI 1.0 devices to match 2.0 standards ... */ 230 231static void 232pci_fixancient(pcicfgregs *cfg) 233{ 234 if (cfg->hdrtype != 0) 235 return; 236 237 /* PCI to PCI bridges use header type 1 */ 238 if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI) 239 cfg->hdrtype = 1; 240} 241 242/* read config data specific to header type 1 device (PCI to PCI bridge) */ 243 244static void * 245pci_readppb(pcicfgregs *cfg) 246{ 247 pcih1cfgregs *p; 248 249 p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK); 250 if (p == NULL) 251 return (NULL); 252 253 bzero(p, sizeof *p); 254 255 p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2); 256 p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2); 257 258 p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1); 259 260 p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2), 261 pci_cfgread(cfg, PCIR_IOBASEL_1, 1)); 262 p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2), 263 pci_cfgread(cfg, PCIR_IOLIMITL_1, 1)); 264 265 p->membase = PCI_PPBMEMBASE (0, 266 pci_cfgread(cfg, PCIR_MEMBASE_1, 2)); 267 p->memlimit = PCI_PPBMEMLIMIT (0, 268 pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2)); 269 270 p->pmembase = PCI_PPBMEMBASE ( 271 (pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4), 272 pci_cfgread(cfg, PCIR_PMBASEL_1, 2)); 273 274 p->pmemlimit = PCI_PPBMEMLIMIT ( 275 (pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4), 276 pci_cfgread(cfg, PCIR_PMLIMITL_1, 2)); 277 return (p); 278} 279 280/* read config data specific to header type 2 device (PCI to CardBus bridge) */ 281 282static void * 283pci_readpcb(pcicfgregs *cfg) 284{ 285 pcih2cfgregs *p; 286 287 p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK); 288 if (p == NULL) 289 return (NULL); 290 291 bzero(p, sizeof *p); 292 293 p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2); 294 p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2); 295 296 p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1); 297 298 p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4); 299 p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4); 300 p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4); 301 p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4); 302 303 p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4); 304 p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4); 305 p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4); 306 p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4); 307 308 p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4); 309 return p; 310} 311 312/* extract header type specific config data */ 313 314static void 315pci_hdrtypedata(pcicfgregs *cfg) 316{ 317 switch (cfg->hdrtype) { 318 case 0: 319 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_0, 2); 320 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_0, 2); 321 cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_0); 322 break; 323 case 1: 324 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_1, 2); 325 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_1, 2); 326 cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_1, 1); 327 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1); 328 cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_1); 329 cfg->hdrspec = pci_readppb(cfg); 330 break; 331 case 2: 332 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_2, 2); 333 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_2, 2); 334 cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_2, 1); 335 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1); 336 cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_2); 337 cfg->hdrspec = pci_readpcb(cfg); 338 break; 339 } 340} 341 342/* read configuration header into pcicfgrect structure */ 343 344static struct pci_devinfo * 345pci_readcfg(pcicfgregs *probe) 346{ 347 pcicfgregs *cfg = NULL; 348 struct pci_devinfo *devlist_entry; 349 struct devlist *devlist_head; 350 351 devlist_head = &pci_devq; 352 353 devlist_entry = NULL; 354 355 if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) { 356 devlist_entry = malloc(sizeof(struct pci_devinfo), 357 M_DEVBUF, M_WAITOK); 358 if (devlist_entry == NULL) 359 return (NULL); 360 bzero(devlist_entry, sizeof *devlist_entry); 361 362 cfg = &devlist_entry->cfg; 363 364 cfg->hose = probe->hose; 365 cfg->bus = probe->bus; 366 cfg->slot = probe->slot; 367 cfg->func = probe->func; 368 cfg->vendor = pci_cfgread(cfg, PCIR_VENDOR, 2); 369 cfg->device = pci_cfgread(cfg, PCIR_DEVICE, 2); 370 cfg->cmdreg = pci_cfgread(cfg, PCIR_COMMAND, 2); 371 cfg->statreg = pci_cfgread(cfg, PCIR_STATUS, 2); 372 cfg->baseclass = pci_cfgread(cfg, PCIR_CLASS, 1); 373 cfg->subclass = pci_cfgread(cfg, PCIR_SUBCLASS, 1); 374 cfg->progif = pci_cfgread(cfg, PCIR_PROGIF, 1); 375 cfg->revid = pci_cfgread(cfg, PCIR_REVID, 1); 376 cfg->hdrtype = pci_cfgread(cfg, PCIR_HEADERTYPE, 1); 377 cfg->cachelnsz = pci_cfgread(cfg, PCIR_CACHELNSZ, 1); 378 cfg->lattimer = pci_cfgread(cfg, PCIR_LATTIMER, 1); 379 cfg->intpin = pci_cfgread(cfg, PCIR_INTPIN, 1); 380 cfg->intline = pci_cfgread(cfg, PCIR_INTLINE, 1); 381#ifdef __alpha__ 382 alpha_platform_assign_pciintr(cfg); 383#endif 384 385#ifdef APIC_IO 386 if (cfg->intpin != 0) { 387 int airq; 388 389 airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin); 390 if (airq >= 0) { 391 /* PCI specific entry found in MP table */ 392 if (airq != cfg->intline) { 393 undirect_pci_irq(cfg->intline); 394 cfg->intline = airq; 395 } 396 } else { 397 /* 398 * PCI interrupts might be redirected to the 399 * ISA bus according to some MP tables. Use the 400 * same methods as used by the ISA devices 401 * devices to find the proper IOAPIC int pin. 402 */ 403 airq = isa_apic_irq(cfg->intline); 404 if ((airq >= 0) && (airq != cfg->intline)) { 405 /* XXX: undirect_pci_irq() ? */ 406 undirect_isa_irq(cfg->intline); 407 cfg->intline = airq; 408 } 409 } 410 } 411#endif /* APIC_IO */ 412 413 cfg->mingnt = pci_cfgread(cfg, PCIR_MINGNT, 1); 414 cfg->maxlat = pci_cfgread(cfg, PCIR_MAXLAT, 1); 415 416 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 417 cfg->hdrtype &= ~PCIM_MFDEV; 418 419 pci_fixancient(cfg); 420 pci_hdrtypedata(cfg); 421 422 STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links); 423 424 devlist_entry->conf.pc_sel.pc_bus = cfg->bus; 425 devlist_entry->conf.pc_sel.pc_dev = cfg->slot; 426 devlist_entry->conf.pc_sel.pc_func = cfg->func; 427 devlist_entry->conf.pc_hdr = cfg->hdrtype; 428 429 devlist_entry->conf.pc_subvendor = cfg->subvendor; 430 devlist_entry->conf.pc_subdevice = cfg->subdevice; 431 devlist_entry->conf.pc_vendor = cfg->vendor; 432 devlist_entry->conf.pc_device = cfg->device; 433 434 devlist_entry->conf.pc_class = cfg->baseclass; 435 devlist_entry->conf.pc_subclass = cfg->subclass; 436 devlist_entry->conf.pc_progif = cfg->progif; 437 devlist_entry->conf.pc_revid = cfg->revid; 438 439 pci_numdevs++; 440 pci_generation++; 441 } 442 return (devlist_entry); 443} 444 445#if 0 446/* free pcicfgregs structure and all depending data structures */ 447 448static int 449pci_freecfg(struct pci_devinfo *dinfo) 450{ 451 struct devlist *devlist_head; 452 453 devlist_head = &pci_devq; 454 455 if (dinfo->cfg.hdrspec != NULL) 456 free(dinfo->cfg.hdrspec, M_DEVBUF); 457 if (dinfo->cfg.map != NULL) 458 free(dinfo->cfg.map, M_DEVBUF); 459 /* XXX this hasn't been tested */ 460 STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links); 461 free(dinfo, M_DEVBUF); 462 463 /* increment the generation count */ 464 pci_generation++; 465 466 /* we're losing one device */ 467 pci_numdevs--; 468 return (0); 469} 470#endif 471 472 473/* 474 * This is the user interface to PCI configuration space. 475 */ 476 477static int 478pci_open(dev_t dev, int oflags, int devtype, struct proc *p) 479{ 480 if ((oflags & FWRITE) && securelevel > 0) { 481 return EPERM; 482 } 483 return 0; 484} 485 486static int 487pci_close(dev_t dev, int flag, int devtype, struct proc *p) 488{ 489 return 0; 490} 491 492/* 493 * Match a single pci_conf structure against an array of pci_match_conf 494 * structures. The first argument, 'matches', is an array of num_matches 495 * pci_match_conf structures. match_buf is a pointer to the pci_conf 496 * structure that will be compared to every entry in the matches array. 497 * This function returns 1 on failure, 0 on success. 498 */ 499static int 500pci_conf_match(struct pci_match_conf *matches, int num_matches, 501 struct pci_conf *match_buf) 502{ 503 int i; 504 505 if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0)) 506 return(1); 507 508 for (i = 0; i < num_matches; i++) { 509 /* 510 * I'm not sure why someone would do this...but... 511 */ 512 if (matches[i].flags == PCI_GETCONF_NO_MATCH) 513 continue; 514 515 /* 516 * Look at each of the match flags. If it's set, do the 517 * comparison. If the comparison fails, we don't have a 518 * match, go on to the next item if there is one. 519 */ 520 if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0) 521 && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus)) 522 continue; 523 524 if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0) 525 && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev)) 526 continue; 527 528 if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0) 529 && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func)) 530 continue; 531 532 if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0) 533 && (match_buf->pc_vendor != matches[i].pc_vendor)) 534 continue; 535 536 if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0) 537 && (match_buf->pc_device != matches[i].pc_device)) 538 continue; 539 540 if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0) 541 && (match_buf->pc_class != matches[i].pc_class)) 542 continue; 543 544 if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0) 545 && (match_buf->pd_unit != matches[i].pd_unit)) 546 continue; 547 548 if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0) 549 && (strncmp(matches[i].pd_name, match_buf->pd_name, 550 sizeof(match_buf->pd_name)) != 0)) 551 continue; 552 553 return(0); 554 } 555 556 return(1); 557} 558 559/* 560 * Locate the parent of a PCI device by scanning the PCI devlist 561 * and return the entry for the parent. 562 * For devices on PCI Bus 0 (the host bus), this is the PCI Host. 563 * For devices on secondary PCI busses, this is that bus' PCI-PCI Bridge. 564 */ 565 566pcicfgregs * 567pci_devlist_get_parent(pcicfgregs *cfg) 568{ 569 struct devlist *devlist_head; 570 struct pci_devinfo *dinfo; 571 pcicfgregs *bridge_cfg; 572 int i; 573 574 dinfo = STAILQ_FIRST(devlist_head = &pci_devq); 575 576 /* If the device is on PCI bus 0, look for the host */ 577 if (cfg->bus == 0) { 578 for (i = 0; (dinfo != NULL) && (i < pci_numdevs); 579 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { 580 bridge_cfg = &dinfo->cfg; 581 if (bridge_cfg->baseclass == PCIC_BRIDGE 582 && bridge_cfg->subclass == PCIS_BRIDGE_HOST 583 && bridge_cfg->bus == cfg->bus) { 584 return bridge_cfg; 585 } 586 } 587 } 588 589 /* If the device is not on PCI bus 0, look for the PCI-PCI bridge */ 590 if (cfg->bus > 0) { 591 for (i = 0; (dinfo != NULL) && (i < pci_numdevs); 592 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { 593 bridge_cfg = &dinfo->cfg; 594 if (bridge_cfg->baseclass == PCIC_BRIDGE 595 && bridge_cfg->subclass == PCIS_BRIDGE_PCI 596 && bridge_cfg->secondarybus == cfg->bus) { 597 return bridge_cfg; 598 } 599 } 600 } 601 602 return NULL; 603} 604 605static int 606pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 607{ 608 struct pci_io *io; 609 const char *name; 610 int error; 611 612 if (!(flag & FWRITE)) 613 return EPERM; 614 615 616 switch(cmd) { 617 case PCIOCGETCONF: 618 { 619 struct pci_devinfo *dinfo; 620 struct pci_conf_io *cio; 621 struct devlist *devlist_head; 622 struct pci_match_conf *pattern_buf; 623 int num_patterns; 624 size_t iolen; 625 int ionum, i; 626 627 cio = (struct pci_conf_io *)data; 628 629 num_patterns = 0; 630 dinfo = NULL; 631 632 /* 633 * Hopefully the user won't pass in a null pointer, but it 634 * can't hurt to check. 635 */ 636 if (cio == NULL) { 637 error = EINVAL; 638 break; 639 } 640 641 /* 642 * If the user specified an offset into the device list, 643 * but the list has changed since they last called this 644 * ioctl, tell them that the list has changed. They will 645 * have to get the list from the beginning. 646 */ 647 if ((cio->offset != 0) 648 && (cio->generation != pci_generation)){ 649 cio->num_matches = 0; 650 cio->status = PCI_GETCONF_LIST_CHANGED; 651 error = 0; 652 break; 653 } 654 655 /* 656 * Check to see whether the user has asked for an offset 657 * past the end of our list. 658 */ 659 if (cio->offset >= pci_numdevs) { 660 cio->num_matches = 0; 661 cio->status = PCI_GETCONF_LAST_DEVICE; 662 error = 0; 663 break; 664 } 665 666 /* get the head of the device queue */ 667 devlist_head = &pci_devq; 668 669 /* 670 * Determine how much room we have for pci_conf structures. 671 * Round the user's buffer size down to the nearest 672 * multiple of sizeof(struct pci_conf) in case the user 673 * didn't specify a multiple of that size. 674 */ 675 iolen = min(cio->match_buf_len - 676 (cio->match_buf_len % sizeof(struct pci_conf)), 677 pci_numdevs * sizeof(struct pci_conf)); 678 679 /* 680 * Since we know that iolen is a multiple of the size of 681 * the pciconf union, it's okay to do this. 682 */ 683 ionum = iolen / sizeof(struct pci_conf); 684 685 /* 686 * If this test is true, the user wants the pci_conf 687 * structures returned to match the supplied entries. 688 */ 689 if ((cio->num_patterns > 0) 690 && (cio->pat_buf_len > 0)) { 691 /* 692 * pat_buf_len needs to be: 693 * num_patterns * sizeof(struct pci_match_conf) 694 * While it is certainly possible the user just 695 * allocated a large buffer, but set the number of 696 * matches correctly, it is far more likely that 697 * their kernel doesn't match the userland utility 698 * they're using. It's also possible that the user 699 * forgot to initialize some variables. Yes, this 700 * may be overly picky, but I hazard to guess that 701 * it's far more likely to just catch folks that 702 * updated their kernel but not their userland. 703 */ 704 if ((cio->num_patterns * 705 sizeof(struct pci_match_conf)) != cio->pat_buf_len){ 706 /* The user made a mistake, return an error*/ 707 cio->status = PCI_GETCONF_ERROR; 708 printf("pci_ioctl: pat_buf_len %d != " 709 "num_patterns (%d) * sizeof(struct " 710 "pci_match_conf) (%d)\npci_ioctl: " 711 "pat_buf_len should be = %d\n", 712 cio->pat_buf_len, cio->num_patterns, 713 (int)sizeof(struct pci_match_conf), 714 (int)sizeof(struct pci_match_conf) * 715 cio->num_patterns); 716 printf("pci_ioctl: do your headers match your " 717 "kernel?\n"); 718 cio->num_matches = 0; 719 error = EINVAL; 720 break; 721 } 722 723 /* 724 * Check the user's buffer to make sure it's readable. 725 */ 726 if ((error = useracc((caddr_t)cio->patterns, 727 cio->pat_buf_len, B_READ)) != 1){ 728 printf("pci_ioctl: pattern buffer %p, " 729 "length %u isn't user accessible for" 730 " READ\n", cio->patterns, 731 cio->pat_buf_len); 732 error = EACCES; 733 break; 734 } 735 /* 736 * Allocate a buffer to hold the patterns. 737 */ 738 pattern_buf = malloc(cio->pat_buf_len, M_TEMP, 739 M_WAITOK); 740 error = copyin(cio->patterns, pattern_buf, 741 cio->pat_buf_len); 742 if (error != 0) 743 break; 744 num_patterns = cio->num_patterns; 745 746 } else if ((cio->num_patterns > 0) 747 || (cio->pat_buf_len > 0)) { 748 /* 749 * The user made a mistake, spit out an error. 750 */ 751 cio->status = PCI_GETCONF_ERROR; 752 cio->num_matches = 0; 753 printf("pci_ioctl: invalid GETCONF arguments\n"); 754 error = EINVAL; 755 break; 756 } else 757 pattern_buf = NULL; 758 759 /* 760 * Make sure we can write to the match buffer. 761 */ 762 if ((error = useracc((caddr_t)cio->matches, cio->match_buf_len, 763 B_WRITE)) != 1) { 764 printf("pci_ioctl: match buffer %p, length %u " 765 "isn't user accessible for WRITE\n", 766 cio->matches, cio->match_buf_len); 767 error = EACCES; 768 break; 769 } 770 771 /* 772 * Go through the list of devices and copy out the devices 773 * that match the user's criteria. 774 */ 775 for (cio->num_matches = 0, error = 0, i = 0, 776 dinfo = STAILQ_FIRST(devlist_head); 777 (dinfo != NULL) && (cio->num_matches < ionum) 778 && (error == 0) && (i < pci_numdevs); 779 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { 780 781 if (i < cio->offset) 782 continue; 783 784 /* Populate pd_name and pd_unit */ 785 name = NULL; 786 if (dinfo->cfg.dev && dinfo->conf.pd_name[0] == '\0') 787 name = device_get_name(dinfo->cfg.dev); 788 if (name) { 789 strncpy(dinfo->conf.pd_name, name, 790 sizeof(dinfo->conf.pd_name)); 791 dinfo->conf.pd_name[PCI_MAXNAMELEN] = 0; 792 dinfo->conf.pd_unit = 793 device_get_unit(dinfo->cfg.dev); 794 } 795 796 if ((pattern_buf == NULL) || 797 (pci_conf_match(pattern_buf, num_patterns, 798 &dinfo->conf) == 0)) { 799 800 /* 801 * If we've filled up the user's buffer, 802 * break out at this point. Since we've 803 * got a match here, we'll pick right back 804 * up at the matching entry. We can also 805 * tell the user that there are more matches 806 * left. 807 */ 808 if (cio->num_matches >= ionum) 809 break; 810 811 error = copyout(&dinfo->conf, 812 &cio->matches[cio->num_matches], 813 sizeof(struct pci_conf)); 814 cio->num_matches++; 815 } 816 } 817 818 /* 819 * Set the pointer into the list, so if the user is getting 820 * n records at a time, where n < pci_numdevs, 821 */ 822 cio->offset = i; 823 824 /* 825 * Set the generation, the user will need this if they make 826 * another ioctl call with offset != 0. 827 */ 828 cio->generation = pci_generation; 829 830 /* 831 * If this is the last device, inform the user so he won't 832 * bother asking for more devices. If dinfo isn't NULL, we 833 * know that there are more matches in the list because of 834 * the way the traversal is done. 835 */ 836 if (dinfo == NULL) 837 cio->status = PCI_GETCONF_LAST_DEVICE; 838 else 839 cio->status = PCI_GETCONF_MORE_DEVS; 840 841 if (pattern_buf != NULL) 842 free(pattern_buf, M_TEMP); 843 844 break; 845 } 846 case PCIOCREAD: 847 io = (struct pci_io *)data; 848 switch(io->pi_width) { 849 pcicfgregs probe; 850 case 4: 851 case 2: 852 case 1: 853 probe.bus = io->pi_sel.pc_bus; 854 probe.slot = io->pi_sel.pc_dev; 855 probe.func = io->pi_sel.pc_func; 856 io->pi_data = pci_cfgread(&probe, 857 io->pi_reg, io->pi_width); 858 error = 0; 859 break; 860 default: 861 error = ENODEV; 862 break; 863 } 864 break; 865 866 case PCIOCWRITE: 867 io = (struct pci_io *)data; 868 switch(io->pi_width) { 869 pcicfgregs probe; 870 case 4: 871 case 2: 872 case 1: 873 probe.bus = io->pi_sel.pc_bus; 874 probe.slot = io->pi_sel.pc_dev; 875 probe.func = io->pi_sel.pc_func; 876 pci_cfgwrite(&probe, 877 io->pi_reg, io->pi_data, io->pi_width); 878 error = 0; 879 break; 880 default: 881 error = ENODEV; 882 break; 883 } 884 break; 885 886 default: 887 error = ENOTTY; 888 break; 889 } 890 891 return (error); 892} 893 894#define PCI_CDEV 78 895 896static struct cdevsw pcicdev = { 897 /* open */ pci_open, 898 /* close */ pci_close, 899 /* read */ noread, 900 /* write */ nowrite, 901 /* ioctl */ pci_ioctl, 902 /* stop */ nostop, 903 /* reset */ noreset, 904 /* devtotty */ nodevtotty, 905 /* poll */ nopoll, 906 /* mmap */ nommap, 907 /* strategy */ nostrategy, 908 /* name */ "pci", 909 /* parms */ noparms, 910 /* maj */ PCI_CDEV, 911 /* dump */ nodump, 912 /* psize */ nopsize, 913 /* flags */ 0, 914 /* maxio */ 0, 915 /* bmaj */ -1 916}; 917 918#ifdef DEVFS 919static void *pci_devfs_token; 920#endif 921 922static void 923pci_cdevinit(void *dummy) 924{ 925 cdevsw_add(&pcicdev); 926#ifdef DEVFS 927 pci_devfs_token = devfs_add_devswf(&pcicdev, 0, DV_CHR, 928 UID_ROOT, GID_WHEEL, 0644, "pci"); 929#endif 930} 931 932SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL); 933 934#include "pci_if.h" 935 936/* 937 * A simple driver to wrap the old pci driver mechanism for back-compat. 938 */ 939 940static int 941pci_compat_probe(device_t dev) 942{ 943 struct pci_device *dvp; 944 struct pci_devinfo *dinfo; 945 pcicfgregs *cfg; 946 const char *name; 947 int error; 948 949 dinfo = device_get_ivars(dev); 950 cfg = &dinfo->cfg; 951 dvp = device_get_driver(dev)->priv; 952 953 /* 954 * Do the wrapped probe. 955 */ 956 error = ENXIO; 957 if (dvp && dvp->pd_probe) { 958 name = dvp->pd_probe(cfg, (cfg->device << 16) + cfg->vendor); 959 if (name) { 960 device_set_desc_copy(dev, name); 961 error = 0; 962 } 963 } 964 965 return error; 966} 967 968static int 969pci_compat_attach(device_t dev) 970{ 971 struct pci_device *dvp; 972 struct pci_devinfo *dinfo; 973 pcicfgregs *cfg; 974 int unit; 975 976 dinfo = device_get_ivars(dev); 977 cfg = &dinfo->cfg; 978 dvp = device_get_driver(dev)->priv; 979 980 unit = device_get_unit(dev); 981 if (unit > *dvp->pd_count) 982 *dvp->pd_count = unit; 983 if (dvp->pd_attach) 984 dvp->pd_attach(cfg, unit); 985 return 0; 986} 987 988static device_method_t pci_compat_methods[] = { 989 /* Device interface */ 990 DEVMETHOD(device_probe, pci_compat_probe), 991 DEVMETHOD(device_attach, pci_compat_attach), 992 993 { 0, 0 } 994}; 995 996static devclass_t pci_devclass; 997 998/* 999 * Create a new style driver around each old pci driver. 1000 */ 1001int 1002compat_pci_handler(module_t mod, int type, void *data) 1003{ 1004 struct pci_device *dvp = (struct pci_device *)data; 1005 driver_t *driver; 1006 1007 switch (type) { 1008 case MOD_LOAD: 1009 driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT); 1010 if (!driver) 1011 return ENOMEM; 1012 bzero(driver, sizeof(driver_t)); 1013 driver->name = dvp->pd_name; 1014 driver->methods = pci_compat_methods; 1015 driver->softc = sizeof(struct pci_devinfo *); 1016 driver->priv = dvp; 1017 devclass_add_driver(pci_devclass, driver); 1018 break; 1019 case MOD_UNLOAD: 1020 printf("%s: module unload not supported!\n", dvp->pd_name); 1021 return EOPNOTSUPP; 1022 default: 1023 break; 1024 } 1025 return 0; 1026} 1027 1028/* 1029 * New style pci driver. Parent device is either a pci-host-bridge or a 1030 * pci-pci-bridge. Both kinds are represented by instances of pcib. 1031 */ 1032 1033static void 1034pci_print_verbose(struct pci_devinfo *dinfo) 1035{ 1036 if (bootverbose) { 1037 int i; 1038 pcicfgregs *cfg = &dinfo->cfg; 1039 1040 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 1041 cfg->vendor, cfg->device, cfg->revid); 1042 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 1043 cfg->baseclass, cfg->subclass, cfg->progif, 1044 cfg->hdrtype, cfg->mfdev); 1045 printf("\tsubordinatebus=%x \tsecondarybus=%x\n", 1046 cfg->subordinatebus, cfg->secondarybus); 1047#ifdef PCI_DEBUG 1048 printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", 1049 cfg->cmdreg, cfg->statreg, cfg->cachelnsz); 1050 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n", 1051 cfg->lattimer, cfg->lattimer * 30, 1052 cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250); 1053#endif /* PCI_DEBUG */ 1054 if (cfg->intpin > 0) 1055 printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline); 1056 1057 for (i = 0; i < cfg->nummaps; i++) { 1058 pcimap *m = &cfg->map[i]; 1059 printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n", 1060 i, m->type, m->ln2range, m->base, m->ln2size); 1061 } 1062 } 1063} 1064 1065static int 1066pci_add_children(device_t dev, int busno) 1067{ 1068 pcicfgregs probe; 1069 int bushigh = busno; 1070 1071#ifdef SIMOS 1072#undef PCI_SLOTMAX 1073#define PCI_SLOTMAX 0 1074#endif 1075 1076 bzero(&probe, sizeof probe); 1077#ifdef __alpha__ 1078 probe.hose = pcib_get_hose(dev); 1079#endif 1080#ifdef __i386__ 1081 probe.hose = 0; 1082#endif 1083 probe.bus = busno; 1084 1085 for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { 1086 int pcifunchigh = 0; 1087 for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { 1088 struct pci_devinfo *dinfo = pci_readcfg(&probe); 1089 if (dinfo != NULL) { 1090 if (dinfo->cfg.mfdev) 1091 pcifunchigh = 7; 1092 1093 pci_print_verbose(dinfo); 1094 dinfo->cfg.dev = 1095 device_add_child(dev, NULL, -1, dinfo); 1096 1097 if (bushigh < dinfo->cfg.subordinatebus) 1098 bushigh = dinfo->cfg.subordinatebus; 1099 if (bushigh < dinfo->cfg.secondarybus) 1100 bushigh = dinfo->cfg.secondarybus; 1101 } 1102 } 1103 } 1104 1105 return bushigh; 1106} 1107 1108static int 1109pci_new_probe(device_t dev) 1110{ 1111 device_set_desc(dev, "PCI bus"); 1112 1113 pci_add_children(dev, device_get_unit(dev)); 1114 1115 return 0; 1116} 1117 1118static void 1119pci_print_child(device_t dev, device_t child) 1120{ 1121 struct pci_devinfo *dinfo; 1122 pcicfgregs *cfg; 1123 1124 dinfo = device_get_ivars(child); 1125 cfg = &dinfo->cfg; 1126 if (cfg->intpin > 0 && cfg->intline != 255) 1127 printf(" irq %d", cfg->intline); 1128 printf(" at device %d.%d", pci_get_slot(child), pci_get_function(child)); 1129 printf(" on %s%d", device_get_name(dev), device_get_unit(dev)); 1130} 1131 1132static int 1133pci_read_ivar(device_t dev, device_t child, int which, u_long *result) 1134{ 1135 struct pci_devinfo *dinfo; 1136 pcicfgregs *cfg; 1137 1138 dinfo = device_get_ivars(child); 1139 cfg = &dinfo->cfg; 1140 1141 switch (which) { 1142 case PCI_IVAR_SUBVENDOR: 1143 *result = cfg->subvendor; 1144 break; 1145 case PCI_IVAR_SUBDEVICE: 1146 *result = cfg->subdevice; 1147 break; 1148 case PCI_IVAR_VENDOR: 1149 *result = cfg->vendor; 1150 break; 1151 case PCI_IVAR_DEVICE: 1152 *result = cfg->device; 1153 break; 1154 case PCI_IVAR_DEVID: 1155 *result = (cfg->device << 16) | cfg->vendor; 1156 break; 1157 case PCI_IVAR_CLASS: 1158 *result = cfg->baseclass; 1159 break; 1160 case PCI_IVAR_SUBCLASS: 1161 *result = cfg->subclass; 1162 break; 1163 case PCI_IVAR_PROGIF: 1164 *result = cfg->progif; 1165 break; 1166 case PCI_IVAR_REVID: 1167 *result = cfg->revid; 1168 break; 1169 case PCI_IVAR_INTPIN: 1170 *result = cfg->intpin; 1171 break; 1172 case PCI_IVAR_IRQ: 1173 *result = cfg->intline; 1174 break; 1175 case PCI_IVAR_BUS: 1176 *result = cfg->bus; 1177 break; 1178 case PCI_IVAR_SLOT: 1179 *result = cfg->slot; 1180 break; 1181 case PCI_IVAR_FUNCTION: 1182 *result = cfg->func; 1183 break; 1184 case PCI_IVAR_SECONDARYBUS: 1185 *result = cfg->secondarybus; 1186 break; 1187 case PCI_IVAR_SUBORDINATEBUS: 1188 *result = cfg->subordinatebus; 1189 break; 1190 case PCI_IVAR_HOSE: 1191 /* 1192 * Pass up to parent bridge. 1193 */ 1194 *result = pcib_get_hose(dev); 1195 break; 1196 default: 1197 return ENOENT; 1198 } 1199 return 0; 1200} 1201 1202static int 1203pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 1204{ 1205 struct pci_devinfo *dinfo; 1206 pcicfgregs *cfg; 1207 1208 dinfo = device_get_ivars(child); 1209 cfg = &dinfo->cfg; 1210 1211 switch (which) { 1212 case PCI_IVAR_SUBVENDOR: 1213 case PCI_IVAR_SUBDEVICE: 1214 case PCI_IVAR_VENDOR: 1215 case PCI_IVAR_DEVICE: 1216 case PCI_IVAR_DEVID: 1217 case PCI_IVAR_CLASS: 1218 case PCI_IVAR_SUBCLASS: 1219 case PCI_IVAR_PROGIF: 1220 case PCI_IVAR_REVID: 1221 case PCI_IVAR_INTPIN: 1222 case PCI_IVAR_IRQ: 1223 case PCI_IVAR_BUS: 1224 case PCI_IVAR_SLOT: 1225 case PCI_IVAR_FUNCTION: 1226 return EINVAL; /* disallow for now */ 1227 1228 case PCI_IVAR_SECONDARYBUS: 1229 cfg->secondarybus = value; 1230 break; 1231 case PCI_IVAR_SUBORDINATEBUS: 1232 cfg->subordinatebus = value; 1233 break; 1234 default: 1235 return ENOENT; 1236 } 1237 return 0; 1238} 1239 1240static int 1241pci_mapno(pcicfgregs *cfg, int reg) 1242{ 1243 int i, nummaps; 1244 pcimap *map; 1245 1246 nummaps = cfg->nummaps; 1247 map = cfg->map; 1248 1249 for (i = 0; i < nummaps; i++) 1250 if (map[i].reg == reg) 1251 return (i); 1252 return (-1); 1253} 1254 1255static int 1256pci_porten(pcicfgregs *cfg) 1257{ 1258 return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0); 1259} 1260 1261static int 1262pci_isportmap(pcicfgregs *cfg, int map) 1263 1264{ 1265 return ((unsigned)map < cfg->nummaps 1266 && (cfg->map[map].type & PCI_MAPPORT) != 0); 1267} 1268 1269static int 1270pci_memen(pcicfgregs *cfg) 1271{ 1272 return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0); 1273} 1274 1275static int 1276pci_ismemmap(pcicfgregs *cfg, int map) 1277{ 1278 return ((unsigned)map < cfg->nummaps 1279 && (cfg->map[map].type & PCI_MAPMEM) != 0); 1280} 1281 1282static struct resource * 1283pci_alloc_resource(device_t dev, device_t child, int type, int *rid, 1284 u_long start, u_long end, u_long count, u_int flags) 1285{ 1286 int isdefault; 1287 struct pci_devinfo *dinfo = device_get_ivars(child); 1288 pcicfgregs *cfg = &dinfo->cfg; 1289 struct resource *rv, **rvp = 0; 1290 int map; 1291 1292 isdefault = (device_get_parent(child) == dev 1293 && start == 0UL && end == ~0UL); 1294 1295 switch (type) { 1296 case SYS_RES_IRQ: 1297 if (*rid != 0) 1298 return 0; 1299 if (isdefault && cfg->intline != 255) { 1300 start = cfg->intline; 1301 end = cfg->intline; 1302 count = 1; 1303 } 1304 break; 1305 1306 case SYS_RES_DRQ: /* passthru for child isa */ 1307 break; 1308 1309 case SYS_RES_MEMORY: 1310 if (isdefault) { 1311 map = pci_mapno(cfg, *rid); 1312 if (pci_memen(cfg) && pci_ismemmap(cfg, map)) { 1313 start = cfg->map[map].base; 1314 count = 1 << cfg->map[map].ln2size; 1315 end = start + count; 1316 rvp = &cfg->map[map].res; 1317 } else 1318 return 0; 1319 } 1320 break; 1321 1322 case SYS_RES_IOPORT: 1323 if (isdefault) { 1324 map = pci_mapno(cfg, *rid); 1325 if (pci_porten(cfg) && pci_isportmap(cfg, map)) { 1326 start = cfg->map[map].base; 1327 count = 1 << cfg->map[map].ln2size; 1328 end = start + count; 1329 rvp = &cfg->map[map].res; 1330 } else 1331 return 0; 1332 } 1333 break; 1334 1335 default: 1336 return 0; 1337 } 1338 1339 rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 1340 type, rid, start, end, count, flags); 1341 if (rvp) 1342 *rvp = rv; 1343 1344 return rv; 1345} 1346 1347static int 1348pci_release_resource(device_t dev, device_t child, int type, int rid, 1349 struct resource *r) 1350{ 1351 int rv; 1352 struct pci_devinfo *dinfo = device_get_ivars(child); 1353 pcicfgregs *cfg = &dinfo->cfg; 1354 int map = 0; 1355 1356 switch (type) { 1357 case SYS_RES_IRQ: 1358 if (rid != 0) 1359 return EINVAL; 1360 break; 1361 1362 case SYS_RES_DRQ: /* passthru for child isa */ 1363 break; 1364 1365 case SYS_RES_MEMORY: 1366 case SYS_RES_IOPORT: 1367 /* 1368 * Only check the map registers if this is a direct 1369 * descendant. 1370 */ 1371 if (device_get_parent(child) == dev) 1372 map = pci_mapno(cfg, rid); 1373 else 1374 map = -1; 1375 break; 1376 1377 default: 1378 return (ENOENT); 1379 } 1380 1381 rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r); 1382 1383 if (rv == 0) { 1384 switch (type) { 1385 case SYS_RES_IRQ: 1386 cfg->irqres = 0; 1387 break; 1388 1389 case SYS_RES_DRQ: /* passthru for child isa */ 1390 break; 1391 1392 case SYS_RES_MEMORY: 1393 case SYS_RES_IOPORT: 1394 if (map != -1) 1395 cfg->map[map].res = 0; 1396 break; 1397 1398 default: 1399 return ENOENT; 1400 } 1401 } 1402 1403 return rv; 1404} 1405 1406static u_int32_t 1407pci_read_config_method(device_t dev, device_t child, int reg, int width) 1408{ 1409 struct pci_devinfo *dinfo = device_get_ivars(child); 1410 pcicfgregs *cfg = &dinfo->cfg; 1411 return pci_cfgread(cfg, reg, width); 1412} 1413 1414static void 1415pci_write_config_method(device_t dev, device_t child, int reg, 1416 u_int32_t val, int width) 1417{ 1418 struct pci_devinfo *dinfo = device_get_ivars(child); 1419 pcicfgregs *cfg = &dinfo->cfg; 1420 pci_cfgwrite(cfg, reg, val, width); 1421} 1422 1423static int 1424pci_modevent(module_t mod, int what, void *arg) 1425{ 1426 switch (what) { 1427 case MOD_LOAD: 1428 STAILQ_INIT(&pci_devq); 1429 break; 1430 1431 case MOD_UNLOAD: 1432 break; 1433 } 1434 1435 return 0; 1436} 1437 1438static device_method_t pci_methods[] = { 1439 /* Device interface */ 1440 DEVMETHOD(device_probe, pci_new_probe), 1441 DEVMETHOD(device_attach, bus_generic_attach), 1442 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1443 DEVMETHOD(device_suspend, bus_generic_suspend), 1444 DEVMETHOD(device_resume, bus_generic_resume), 1445 1446 /* Bus interface */ 1447 DEVMETHOD(bus_print_child, pci_print_child), 1448 DEVMETHOD(bus_read_ivar, pci_read_ivar), 1449 DEVMETHOD(bus_write_ivar, pci_write_ivar), 1450 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 1451 DEVMETHOD(bus_alloc_resource, pci_alloc_resource), 1452 DEVMETHOD(bus_release_resource, pci_release_resource), 1453 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1454 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1455 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 1456 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 1457 1458 /* PCI interface */ 1459 DEVMETHOD(pci_read_config, pci_read_config_method), 1460 DEVMETHOD(pci_write_config, pci_write_config_method), 1461 1462 { 0, 0 } 1463}; 1464 1465static driver_t pci_driver = { 1466 "pci", 1467 pci_methods, 1468 1, /* no softc */ 1469}; 1470 1471DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0); 1472 1473#endif /* NPCI > 0 */ 1474