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