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