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