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