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