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