diff options
| author | cvs2svn <cvs2svn@FreeBSD.org> | 1999-01-21 00:55:31 +0000 |
|---|---|---|
| committer | cvs2svn <cvs2svn@FreeBSD.org> | 1999-01-21 00:55:31 +0000 |
| commit | 4b4d01da6f07f7754ff6a6e4f5223e9f0984d1a6 (patch) | |
| tree | 9ef395ed57f97b5613d996298d19e60c8e518010 /sys/dev/pci | |
| parent | 99af619cb2f1dac921ef1dd9fe5661503220f524 (diff) | |
Notes
Diffstat (limited to 'sys/dev/pci')
| -rw-r--r-- | sys/dev/pci/pci.c | 948 | ||||
| -rw-r--r-- | sys/dev/pci/pcireg.h | 257 | ||||
| -rw-r--r-- | sys/dev/pci/pcivar.h | 234 |
3 files changed, 0 insertions, 1439 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c deleted file mode 100644 index 73b8142a89c0..000000000000 --- a/sys/dev/pci/pci.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * Copyright (c) 1997, Stefan Esser <se@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id: pci.c,v 1.92 1999/01/12 01:44:42 eivind Exp $ - * - */ - -#include "pci.h" -#if NPCI > 0 - -#include "opt_devfs.h" -#include "opt_simos.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/fcntl.h> -#include <sys/conf.h> -#include <sys/kernel.h> -#include <sys/queue.h> -#include <sys/types.h> -#include <sys/buf.h> -#ifdef DEVFS -#include <sys/devfsext.h> -#endif /* DEVFS */ - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_extern.h> - -#include <pci/pcireg.h> -#include <pci/pcivar.h> -#include <pci/pci_ioctl.h> - -#ifdef APIC_IO -#include <machine/smp.h> -#endif /* APIC_IO */ - -STAILQ_HEAD(devlist, pci_devinfo) pci_devq; -u_int32_t pci_numdevs = 0; -u_int32_t pci_generation = 0; - -/* return highest PCI bus number known to be used, or -1 if none */ - -static int -pci_bushigh(void) -{ - if (pci_cfgopen() == 0) - return (-1); - return (0); -} - -/* return base address of memory or port map */ - -static int -pci_mapbase(unsigned mapreg) -{ - int mask = 0x03; - if ((mapreg & 0x01) == 0) - mask = 0x0f; - return (mapreg & ~mask); -} - -/* return map type of memory or port map */ - -static int -pci_maptype(unsigned mapreg) -{ - static u_int8_t maptype[0x10] = { - PCI_MAPMEM, PCI_MAPPORT, - PCI_MAPMEM, 0, - PCI_MAPMEM, PCI_MAPPORT, - 0, 0, - PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, - PCI_MAPMEM|PCI_MAPMEMP, 0, - PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, - 0, 0, - }; - - return maptype[mapreg & 0x0f]; -} - -/* return log2 of map size decoded for memory or port map */ - -static int -pci_mapsize(unsigned testval) -{ - int ln2size; - - testval = pci_mapbase(testval); - ln2size = 0; - if (testval != 0) { - while ((testval & 1) == 0) - { - ln2size++; - testval >>= 1; - } - } - return (ln2size); -} - -/* return log2 of address range supported by map register */ - -static int -pci_maprange(unsigned mapreg) -{ - int ln2range = 0; - switch (mapreg & 0x07) { - case 0x00: - case 0x01: - case 0x05: - ln2range = 32; - break; - case 0x02: - ln2range = 20; - break; - case 0x04: - ln2range = 64; - break; - } - return (ln2range); -} - -/* extract map parameters into newly allocated array of pcimap structures */ - -static pcimap * -pci_readmaps(pcicfgregs *cfg, int maxmaps) -{ - int i, j = 0; - pcimap *map; - int map64 = 0; - int reg = PCIR_MAPS; - - for (i = 0; i < maxmaps; i++) { - int reg = PCIR_MAPS + i*4; - u_int32_t base; - u_int32_t ln2range; - - base = pci_cfgread(cfg, reg, 4); - ln2range = pci_maprange(base); - - if (base == 0 || ln2range == 0 || base == 0xffffffff) - continue; /* skip invalid entry */ - else { - j++; - if (ln2range > 32) { - i++; - j++; - } - } - } - - map = malloc(j * sizeof (pcimap), M_DEVBUF, M_WAITOK); - if (map != NULL) { - bzero(map, sizeof(pcimap) * j); - cfg->nummaps = j; - - for (i = 0, j = 0; i < maxmaps; i++, reg += 4) { - u_int32_t base; - u_int32_t testval; - - base = pci_cfgread(cfg, reg, 4); - - if (map64 == 0) { - if (base == 0 || base == 0xffffffff) - continue; /* skip invalid entry */ - pci_cfgwrite(cfg, reg, 0xffffffff, 4); - testval = pci_cfgread(cfg, reg, 4); - pci_cfgwrite(cfg, reg, base, 4); - - map[j].reg = reg; - map[j].base = pci_mapbase(base); - map[j].type = pci_maptype(base); - map[j].ln2size = pci_mapsize(testval); - map[j].ln2range = pci_maprange(testval); - map64 = map[j].ln2range == 64; - } else { - /* only fill in base, other fields are 0 */ - map[j].base = base; - map64 = 0; - } - j++; - } - } - return (map); -} - -/* adjust some values from PCI 1.0 devices to match 2.0 standards ... */ - -static void -pci_fixancient(pcicfgregs *cfg) -{ - if (cfg->hdrtype != 0) - return; - - /* PCI to PCI bridges use header type 1 */ - if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI) - cfg->hdrtype = 1; -} - -/* read config data specific to header type 1 device (PCI to PCI bridge) */ - -static void * -pci_readppb(pcicfgregs *cfg) -{ - pcih1cfgregs *p; - - p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK); - if (p == NULL) - return (NULL); - - bzero(p, sizeof *p); - - p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2); - p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2); - - p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1); - - p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2), - pci_cfgread(cfg, PCIR_IOBASEL_1, 1)); - p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2), - pci_cfgread(cfg, PCIR_IOLIMITL_1, 1)); - - p->membase = PCI_PPBMEMBASE (0, - pci_cfgread(cfg, PCIR_MEMBASE_1, 2)); - p->memlimit = PCI_PPBMEMLIMIT (0, - pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2)); - - p->pmembase = PCI_PPBMEMBASE ( - (pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4), - pci_cfgread(cfg, PCIR_PMBASEL_1, 2)); - - p->pmemlimit = PCI_PPBMEMLIMIT ( - (pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4), - pci_cfgread(cfg, PCIR_PMLIMITL_1, 2)); - return (p); -} - -/* read config data specific to header type 2 device (PCI to CardBus bridge) */ - -static void * -pci_readpcb(pcicfgregs *cfg) -{ - pcih2cfgregs *p; - - p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK); - if (p == NULL) - return (NULL); - - bzero(p, sizeof *p); - - p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2); - p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2); - - p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1); - - p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4); - p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4); - p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4); - p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4); - - p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4); - p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4); - p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4); - p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4); - - p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4); - return p; -} - -/* extract header type specific config data */ - -static void -pci_hdrtypedata(pcicfgregs *cfg) -{ - switch (cfg->hdrtype) { - case 0: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_0, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_0, 2); - cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_0); - break; - case 1: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_1, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_1, 2); - cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_1, 1); - cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1); - cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_1); - cfg->hdrspec = pci_readppb(cfg); - break; - case 2: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_2, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_2, 2); - cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_2, 1); - cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1); - cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_2); - cfg->hdrspec = pci_readpcb(cfg); - break; - } -} - -/* read configuration header into pcicfgrect structure */ - -static struct pci_devinfo * -pci_readcfg(pcicfgregs *probe) -{ - pcicfgregs *cfg = NULL; - struct pci_devinfo *devlist_entry; - struct devlist *devlist_head; - - devlist_head = &pci_devq; - - devlist_entry = NULL; - - if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) { - devlist_entry = malloc(sizeof(struct pci_devinfo), - M_DEVBUF, M_WAITOK); - if (devlist_entry == NULL) - return (NULL); - - cfg = &devlist_entry->cfg; - - bzero(cfg, sizeof *cfg); - - cfg->bus = probe->bus; - cfg->slot = probe->slot; - cfg->func = probe->func; - cfg->vendor = pci_cfgread(cfg, PCIR_VENDOR, 2); - cfg->device = pci_cfgread(cfg, PCIR_DEVICE, 2); - cfg->cmdreg = pci_cfgread(cfg, PCIR_COMMAND, 2); - cfg->statreg = pci_cfgread(cfg, PCIR_STATUS, 2); - cfg->baseclass = pci_cfgread(cfg, PCIR_CLASS, 1); - cfg->subclass = pci_cfgread(cfg, PCIR_SUBCLASS, 1); - cfg->progif = pci_cfgread(cfg, PCIR_PROGIF, 1); - cfg->revid = pci_cfgread(cfg, PCIR_REVID, 1); - cfg->hdrtype = pci_cfgread(cfg, PCIR_HEADERTYPE, 1); - cfg->cachelnsz = pci_cfgread(cfg, PCIR_CACHELNSZ, 1); - cfg->lattimer = pci_cfgread(cfg, PCIR_LATTIMER, 1); - cfg->intpin = pci_cfgread(cfg, PCIR_INTPIN, 1); - cfg->intline = pci_cfgread(cfg, PCIR_INTLINE, 1); -#ifdef __alpha__ - alpha_platform_assign_pciintr(cfg); -#endif - -#ifdef APIC_IO - if (cfg->intpin != 0) { - int airq; - - airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin); - if (airq >= 0) { - /* PCI specific entry found in MP table */ - if (airq != cfg->intline) { - undirect_pci_irq(cfg->intline); - cfg->intline = airq; - } - } else { - /* - * PCI interrupts might be redirected to the - * ISA bus according to some MP tables. Use the - * same methods as used by the ISA devices - * devices to find the proper IOAPIC int pin. - */ - airq = isa_apic_irq(cfg->intline); - if ((airq >= 0) && (airq != cfg->intline)) { - /* XXX: undirect_pci_irq() ? */ - undirect_isa_irq(cfg->intline); - cfg->intline = airq; - } - } - } -#endif /* APIC_IO */ - - cfg->mingnt = pci_cfgread(cfg, PCIR_MINGNT, 1); - cfg->maxlat = pci_cfgread(cfg, PCIR_MAXLAT, 1); - - cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; - cfg->hdrtype &= ~PCIM_MFDEV; - - pci_fixancient(cfg); - pci_hdrtypedata(cfg); - - STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links); - - devlist_entry->conf.pc_sel.pc_bus = cfg->bus; - devlist_entry->conf.pc_sel.pc_dev = cfg->slot; - devlist_entry->conf.pc_sel.pc_func = cfg->func; - devlist_entry->conf.pc_hdr = cfg->hdrtype; - - devlist_entry->conf.pc_subvendor = cfg->subvendor; - devlist_entry->conf.pc_subdevice = cfg->subdevice; - devlist_entry->conf.pc_vendor = cfg->vendor; - devlist_entry->conf.pc_device = cfg->device; - - devlist_entry->conf.pc_class = cfg->baseclass; - devlist_entry->conf.pc_subclass = cfg->subclass; - devlist_entry->conf.pc_progif = cfg->progif; - devlist_entry->conf.pc_revid = cfg->revid; - - pci_numdevs++; - pci_generation++; - } - return (devlist_entry); -} - -#if 0 -/* free pcicfgregs structure and all depending data structures */ - -static int -pci_freecfg(struct pci_devinfo *dinfo) -{ - struct devlist *devlist_head; - - devlist_head = &pci_devq; - - if (dinfo->cfg.hdrspec != NULL) - free(dinfo->cfg.hdrspec, M_DEVBUF); - if (dinfo->cfg.map != NULL) - free(dinfo->cfg.map, M_DEVBUF); - /* XXX this hasn't been tested */ - STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links); - free(dinfo, M_DEVBUF); - - /* increment the generation count */ - pci_generation++; - - /* we're losing one device */ - pci_numdevs--; - return (0); -} -#endif - -static void -pci_addcfg(struct pci_devinfo *dinfo) -{ - if (bootverbose) { - int i; - pcicfgregs *cfg = &dinfo->cfg; - - printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", - cfg->vendor, cfg->device, cfg->revid); - printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", - cfg->baseclass, cfg->subclass, cfg->progif, - cfg->hdrtype, cfg->mfdev); - printf("\tsubordinatebus=%x \tsecondarybus=%x\n", - cfg->subordinatebus, cfg->secondarybus); -#ifdef PCI_DEBUG - printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", - cfg->cmdreg, cfg->statreg, cfg->cachelnsz); - printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n", - cfg->lattimer, cfg->lattimer * 30, - cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250); -#endif /* PCI_DEBUG */ - if (cfg->intpin > 0) - printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline); - - for (i = 0; i < cfg->nummaps; i++) { - pcimap *m = &cfg->map[i]; - printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n", - i, m->type, m->ln2range, m->base, m->ln2size); - } - } - pci_drvattach(dinfo); /* XXX currently defined in pci_compat.c */ -} - -/* scan one PCI bus for devices */ - -static int -pci_probebus(int bus) -{ - pcicfgregs probe; - int bushigh = bus; - -#ifdef SIMOS -#undef PCI_SLOTMAX -#define PCI_SLOTMAX 0 -#endif - - bzero(&probe, sizeof probe); - /* XXX KDM */ - /* probe.parent = pci_bridgeto(bus); */ - probe.bus = bus; - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - int pcifunchigh = 0; - for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { - struct pci_devinfo *dinfo = pci_readcfg(&probe); - if (dinfo != NULL) { - if (dinfo->cfg.mfdev) - pcifunchigh = 7; - /* - * XXX: Temporarily move pci_addcfg() up before - * the use of cfg->subordinatebus. This is - * necessary, since pci_addcfg() calls the - * device's probe(), which may read the bus# - * from some device dependent register of - * some host to PCI bridges. The probe will - * eventually be moved to pci_readcfg(), and - * pci_addcfg() will then be moved back down - * below the conditional statement ... - */ - pci_addcfg(dinfo); - - if (bushigh < dinfo->cfg.subordinatebus) - bushigh = dinfo->cfg.subordinatebus; - if (bushigh < dinfo->cfg.secondarybus) - bushigh = dinfo->cfg.secondarybus; - - /* XXX KDM */ - /* cfg = NULL; we don't own this anymore ... */ - } - } - } - return (bushigh); -} - -/* scan a PCI bus tree reached through one PCI attachment point */ - -int -pci_probe(pciattach *parent) -{ - int bushigh; - int bus = 0; - - STAILQ_INIT(&pci_devq); - - bushigh = pci_bushigh(); - while (bus <= bushigh) { - int newbushigh; - - printf("Probing for devices on PCI bus %d:\n", bus); - newbushigh = pci_probebus(bus); - - if (bushigh < newbushigh) - bushigh = newbushigh; - bus++; - } - return (bushigh); -} - -/* - * This is the user interface to PCI configuration space. - */ - -static int -pci_open(dev_t dev, int oflags, int devtype, struct proc *p) -{ - if ((oflags & FWRITE) && securelevel > 0) { - return EPERM; - } - return 0; -} - -static int -pci_close(dev_t dev, int flag, int devtype, struct proc *p) -{ - return 0; -} - -/* - * Match a single pci_conf structure against an array of pci_match_conf - * structures. The first argument, 'matches', is an array of num_matches - * pci_match_conf structures. match_buf is a pointer to the pci_conf - * structure that will be compared to every entry in the matches array. - * This function returns 1 on failure, 0 on success. - */ -static int -pci_conf_match(struct pci_match_conf *matches, int num_matches, - struct pci_conf *match_buf) -{ - int i; - - if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0)) - return(1); - - for (i = 0; i < num_matches; i++) { - /* - * I'm not sure why someone would do this...but... - */ - if (matches[i].flags == PCI_GETCONF_NO_MATCH) - continue; - - /* - * Look at each of the match flags. If it's set, do the - * comparison. If the comparison fails, we don't have a - * match, go on to the next item if there is one. - */ - if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0) - && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus)) - continue; - - if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0) - && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev)) - continue; - - if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0) - && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func)) - continue; - - if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0) - && (match_buf->pc_vendor != matches[i].pc_vendor)) - continue; - - if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0) - && (match_buf->pc_device != matches[i].pc_device)) - continue; - - if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0) - && (match_buf->pc_class != matches[i].pc_class)) - continue; - - if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0) - && (match_buf->pd_unit != matches[i].pd_unit)) - continue; - - if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0) - && (strncmp(matches[i].pd_name, match_buf->pd_name, - sizeof(match_buf->pd_name)) != 0)) - continue; - - return(0); - } - - return(1); -} - -static int -pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) -{ - struct pci_io *io; - int error; - - if (!(flag & FWRITE)) - return EPERM; - - - switch(cmd) { - case PCIOCGETCONF: - { - struct pci_devinfo *dinfo; - struct pci_conf_io *cio; - struct devlist *devlist_head; - struct pci_match_conf *pattern_buf; - int num_patterns; - size_t iolen; - int ionum, i; - - cio = (struct pci_conf_io *)data; - - num_patterns = 0; - dinfo = NULL; - - /* - * Hopefully the user won't pass in a null pointer, but it - * can't hurt to check. - */ - if (cio == NULL) { - error = EINVAL; - break; - } - - /* - * If the user specified an offset into the device list, - * but the list has changed since they last called this - * ioctl, tell them that the list has changed. They will - * have to get the list from the beginning. - */ - if ((cio->offset != 0) - && (cio->generation != pci_generation)){ - cio->num_matches = 0; - cio->status = PCI_GETCONF_LIST_CHANGED; - error = 0; - break; - } - - /* - * Check to see whether the user has asked for an offset - * past the end of our list. - */ - if (cio->offset >= pci_numdevs) { - cio->num_matches = 0; - cio->status = PCI_GETCONF_LAST_DEVICE; - error = 0; - break; - } - - /* get the head of the device queue */ - devlist_head = &pci_devq; - - /* - * Determine how much room we have for pci_conf structures. - * Round the user's buffer size down to the nearest - * multiple of sizeof(struct pci_conf) in case the user - * didn't specify a multiple of that size. - */ - iolen = min(cio->match_buf_len - - (cio->match_buf_len % sizeof(struct pci_conf)), - pci_numdevs * sizeof(struct pci_conf)); - - /* - * Since we know that iolen is a multiple of the size of - * the pciconf union, it's okay to do this. - */ - ionum = iolen / sizeof(struct pci_conf); - - /* - * If this test is true, the user wants the pci_conf - * structures returned to match the supplied entries. - */ - if ((cio->num_patterns > 0) - && (cio->pat_buf_len > 0)) { - /* - * pat_buf_len needs to be: - * num_patterns * sizeof(struct pci_match_conf) - * While it is certainly possible the user just - * allocated a large buffer, but set the number of - * matches correctly, it is far more likely that - * their kernel doesn't match the userland utility - * they're using. It's also possible that the user - * forgot to initialize some variables. Yes, this - * may be overly picky, but I hazard to guess that - * it's far more likely to just catch folks that - * updated their kernel but not their userland. - */ - if ((cio->num_patterns * - sizeof(struct pci_match_conf)) != cio->pat_buf_len){ - /* The user made a mistake, return an error*/ - cio->status = PCI_GETCONF_ERROR; - printf("pci_ioctl: pat_buf_len %d != " - "num_patterns (%d) * sizeof(struct " - "pci_match_conf) (%d)\npci_ioctl: " - "pat_buf_len should be = %d\n", - cio->pat_buf_len, cio->num_patterns, - sizeof(struct pci_match_conf), - sizeof(struct pci_match_conf) * - cio->num_patterns); - printf("pci_ioctl: do your headers match your " - "kernel?\n"); - cio->num_matches = 0; - error = EINVAL; - break; - } - - /* - * Check the user's buffer to make sure it's readable. - */ - if ((error = useracc((caddr_t)cio->patterns, - cio->pat_buf_len, B_READ)) != 1){ - printf("pci_ioctl: pattern buffer %p, " - "length %u isn't user accessible for" - " READ\n", cio->patterns, - cio->pat_buf_len); - error = EACCES; - break; - } - /* - * Allocate a buffer to hold the patterns. - */ - pattern_buf = malloc(cio->pat_buf_len, M_TEMP, - M_WAITOK); - error = copyin(cio->patterns, pattern_buf, - cio->pat_buf_len); - if (error != 0) - break; - num_patterns = cio->num_patterns; - - } else if ((cio->num_patterns > 0) - || (cio->pat_buf_len > 0)) { - /* - * The user made a mistake, spit out an error. - */ - cio->status = PCI_GETCONF_ERROR; - cio->num_matches = 0; - printf("pci_ioctl: invalid GETCONF arguments\n"); - error = EINVAL; - break; - } else - pattern_buf = NULL; - - /* - * Make sure we can write to the match buffer. - */ - if ((error = useracc((caddr_t)cio->matches, cio->match_buf_len, - B_WRITE)) != 1) { - printf("pci_ioctl: match buffer %p, length %u " - "isn't user accessible for WRITE\n", - cio->matches, cio->match_buf_len); - error = EACCES; - break; - } - - /* - * Go through the list of devices and copy out the devices - * that match the user's criteria. - */ - for (cio->num_matches = 0, error = 0, i = 0, - dinfo = STAILQ_FIRST(devlist_head); - (dinfo != NULL) && (cio->num_matches < ionum) - && (error == 0) && (i < pci_numdevs); - dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { - - if (i < cio->offset) - continue; - - if ((pattern_buf == NULL) || - (pci_conf_match(pattern_buf, num_patterns, - &dinfo->conf) == 0)) { - - /* - * If we've filled up the user's buffer, - * break out at this point. Since we've - * got a match here, we'll pick right back - * up at the matching entry. We can also - * tell the user that there are more matches - * left. - */ - if (cio->num_matches >= ionum) - break; - - error = copyout(&dinfo->conf, - &cio->matches[cio->num_matches], - sizeof(struct pci_conf)); - cio->num_matches++; - } - } - - /* - * Set the pointer into the list, so if the user is getting - * n records at a time, where n < pci_numdevs, - */ - cio->offset = i; - - /* - * Set the generation, the user will need this if they make - * another ioctl call with offset != 0. - */ - cio->generation = pci_generation; - - /* - * If this is the last device, inform the user so he won't - * bother asking for more devices. If dinfo isn't NULL, we - * know that there are more matches in the list because of - * the way the traversal is done. - */ - if (dinfo == NULL) - cio->status = PCI_GETCONF_LAST_DEVICE; - else - cio->status = PCI_GETCONF_MORE_DEVS; - - if (pattern_buf != NULL) - free(pattern_buf, M_TEMP); - - break; - } - case PCIOCREAD: - io = (struct pci_io *)data; - switch(io->pi_width) { - pcicfgregs probe; - case 4: - case 2: - case 1: - probe.bus = io->pi_sel.pc_bus; - probe.slot = io->pi_sel.pc_dev; - probe.func = io->pi_sel.pc_func; - io->pi_data = pci_cfgread(&probe, - io->pi_reg, io->pi_width); - error = 0; - break; - default: - error = ENODEV; - break; - } - break; - - case PCIOCWRITE: - io = (struct pci_io *)data; - switch(io->pi_width) { - pcicfgregs probe; - case 4: - case 2: - case 1: - probe.bus = io->pi_sel.pc_bus; - probe.slot = io->pi_sel.pc_dev; - probe.func = io->pi_sel.pc_func; - pci_cfgwrite(&probe, - io->pi_reg, io->pi_data, io->pi_width); - error = 0; - break; - default: - error = ENODEV; - break; - } - break; - - default: - error = ENOTTY; - break; - } - - return (error); -} - -#define PCI_CDEV 78 - -static struct cdevsw pcicdev = { - pci_open, pci_close, noread, nowrite, pci_ioctl, nostop, noreset, - nodevtotty, seltrue, nommap, nostrategy, "pci", 0, PCI_CDEV -}; - -#ifdef DEVFS -static void *pci_devfs_token; -#endif - -static void -pci_cdevinit(void *dummy) -{ - dev_t dev; - - dev = makedev(PCI_CDEV, 0); - cdevsw_add(&dev, &pcicdev, NULL); -#ifdef DEVFS - pci_devfs_token = devfs_add_devswf(&pcicdev, 0, DV_CHR, - UID_ROOT, GID_WHEEL, 0644, "pci"); -#endif -} - -SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL); - -#endif /* NPCI > 0 */ diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h deleted file mode 100644 index 0adb5404021e..000000000000 --- a/sys/dev/pci/pcireg.h +++ /dev/null @@ -1,257 +0,0 @@ -#ifndef PCI_COMPAT -#define PCI_COMPAT -#endif -/* - * Copyright (c) 1997, Stefan Esser <se@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id: pcireg.h,v 1.19 1997/09/20 07:41:58 dyson Exp $ - * - */ - -/* - * PCIM_xxx: mask to locate subfield in register - * PCIR_xxx: config register offset - * PCIC_xxx: device class - * PCIS_xxx: device subclass - * PCIP_xxx: device programming interface - * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) - * PCID_xxx: device ID - */ - -/* some PCI bus constants */ - -#define PCI_BUSMAX 255 -#define PCI_SLOTMAX 31 -#define PCI_FUNCMAX 7 -#define PCI_REGMAX 255 - -/* PCI config header registers for all devices */ - -#define PCIR_DEVVENDOR 0x00 -#define PCIR_VENDOR 0x00 -#define PCIR_DEVICE 0x02 -#define PCIR_COMMAND 0x04 -#define PCIM_CMD_PORTEN 0x0001 -#define PCIM_CMD_MEMEN 0x0002 -#define PCIM_CMD_BUSMASTEREN 0x0004 -#define PCIM_CMD_PERRESPEN 0x0040 -#define PCIR_STATUS 0x06 -#define PCIR_REVID 0x08 -#define PCIR_PROGIF 0x09 -#define PCIR_SUBCLASS 0x0a -#define PCIR_CLASS 0x0b -#define PCIR_CACHELNSZ 0x0c -#define PCIR_LATTIMER 0x0d -#define PCIR_HEADERTYPE 0x0e -#define PCIM_MFDEV 0x80 -#define PCIR_BIST 0x0f - -/* config registers for header type 0 devices */ - -#define PCIR_MAPS 0x10 -#define PCIR_CARDBUSCIS 0x28 -#define PCIR_SUBVEND_0 0x2c -#define PCIR_SUBDEV_0 0x2e -#define PCIR_INTLINE 0x3c -#define PCIR_INTPIN 0x3d -#define PCIR_MINGNT 0x3e -#define PCIR_MAXLAT 0x3f - -/* config registers for header type 1 devices */ - -#define PCIR_SECSTAT_1 0 /**/ - -#define PCIR_PRIBUS_1 0x18 -#define PCIR_SECBUS_1 0x19 -#define PCIR_SUBBUS_1 0x1a -#define PCIR_SECLAT_1 0x1b - -#define PCIR_IOBASEL_1 0x1c -#define PCIR_IOLIMITL_1 0x1d -#define PCIR_IOBASEH_1 0 /**/ -#define PCIR_IOLIMITH_1 0 /**/ - -#define PCIR_MEMBASE_1 0x20 -#define PCIR_MEMLIMIT_1 0x22 - -#define PCIR_PMBASEL_1 0x24 -#define PCIR_PMLIMITL_1 0x26 -#define PCIR_PMBASEH_1 0 /**/ -#define PCIR_PMLIMITH_1 0 /**/ - -#define PCIR_BRIDGECTL_1 0 /**/ - -#define PCIR_SUBVEND_1 0x34 -#define PCIR_SUBDEV_1 0x36 - -/* config registers for header type 2 devices */ - -#define PCIR_SECSTAT_2 0x16 - -#define PCIR_PRIBUS_2 0x18 -#define PCIR_SECBUS_2 0x19 -#define PCIR_SUBBUS_2 0x1a -#define PCIR_SECLAT_2 0x1b - -#define PCIR_MEMBASE0_2 0x1c -#define PCIR_MEMLIMIT0_2 0x20 -#define PCIR_MEMBASE1_2 0x24 -#define PCIR_MEMLIMIT1_2 0x28 -#define PCIR_IOBASE0_2 0x2c -#define PCIR_IOLIMIT0_2 0x30 -#define PCIR_IOBASE1_2 0x34 -#define PCIR_IOLIMIT1_2 0x38 - -#define PCIR_BRIDGECTL_2 0x3e - -#define PCIR_SUBVEND_2 0x40 -#define PCIR_SUBDEV_2 0x42 - -#define PCIR_PCCARDIF_2 0x44 - -/* PCI device class, subclass and programming interface definitions */ - -#define PCIC_OLD 0x00 -#define PCIS_OLD_NONVGA 0x00 -#define PCIS_OLD_VGA 0x01 - -#define PCIC_STORAGE 0x01 -#define PCIS_STORAGE_SCSI 0x00 -#define PCIS_STORAGE_IDE 0x01 -#define PCIP_STORAGE_IDE_MODEPRIM 0x01 -#define PCIP_STORAGE_IDE_PROGINDPRIM 0x02 -#define PCIP_STORAGE_IDE_MODESEC 0x04 -#define PCIP_STORAGE_IDE_PROGINDSEC 0x08 -#define PCIP_STORAGE_IDE_MASTERDEV 0x80 -#define PCIS_STORAGE_FLOPPY 0x02 -#define PCIS_STORAGE_IPI 0x03 -#define PCIS_STORAGE_RAID 0x04 -#define PCIS_STORAGE_OTHER 0x80 - -#define PCIC_NETWORK 0x02 -#define PCIS_NETWORK_ETHERNET 0x00 -#define PCIS_NETWORK_TOKENRING 0x01 -#define PCIS_NETWORK_FDDI 0x02 -#define PCIS_NETWORK_ATM 0x03 -#define PCIS_NETWORK_OTHER 0x80 - -#define PCIC_DISPLAY 0x03 -#define PCIS_DISPLAY_VGA 0x00 -#define PCIS_DISPLAY_XGA 0x01 -#define PCIS_DISPLAY_OTHER 0x80 - -#define PCIC_MULTIMEDIA 0x04 -#define PCIS_MULTIMEDIA_VIDEO 0x00 -#define PCIS_MULTIMEDIA_AUDIO 0x01 -#define PCIS_MULTIMEDIA_OTHER 0x80 - -#define PCIC_MEMORY 0x05 -#define PCIS_MEMORY_RAM 0x00 -#define PCIS_MEMORY_FLASH 0x01 -#define PCIS_MEMORY_OTHER 0x80 - -#define PCIC_BRIDGE 0x06 -#define PCIS_BRDIGE_HOST 0x00 -#define PCIS_BRIDGE_ISA 0x01 -#define PCIS_BRIDGE_EISA 0x02 -#define PCIS_BRIDGE_MCA 0x03 -#define PCIS_BRIDGE_PCI 0x04 -#define PCIS_BRIDGE_PCMCIA 0x05 -#define PCIS_BRIDGE_NUBUS 0x06 -#define PCIS_BRIDGE_CARDBUS 0x07 -#define PCIS_BRIDGE_OTHER 0x80 - -#define PCIC_SIMPLECOMM 0x07 -#define PCIS_SIMPLECOMM_UART 0x00 -#define PCIS_SIMPLECOMM_PAR 0x01 -#define PCIS_SIMPLECOMM_OTHER 0x80 - -#define PCIC_BASEPERIPH 0x08 -#define PCIS_BASEPERIPH_PIC 0x00 -#define PCIS_BASEPERIPH_DMA 0x01 -#define PCIS_BASEPERIPH_TIMER 0x02 -#define PCIS_BASEPERIPH_RTC 0x03 -#define PCIS_BASEPERIPH_OTHER 0x80 - -#define PCIC_INPUTDEV 0x09 -#define PCIS_INPUTDEV_KEYBOARD 0x00 -#define PCIS_INPUTDEV_DIGITIZER 0x01 -#define PCIS_INPUTDEV_MOUSE 0x02 -#define PCIS_INPUTDEV_OTHER 0x80 - -#define PCIC_DOCKING 0x0a -#define PCIS_DOCKING_GENERIC 0x00 -#define PCIS_DOCKING_OTHER 0x80 - -#define PCIC_PROCESSOR 0x0b -#define PCIS_PROCESSOR_386 0x00 -#define PCIS_PROCESSOR_486 0x01 -#define PCIS_PROCESSOR_PENTIUM 0x02 -#define PCIS_PROCESSOR_ALPHA 0x10 -#define PCIS_PROCESSOR_POWERPC 0x20 -#define PCIS_PROCESSOR_COPROC 0x40 - -#define PCIC_SERIALBUS 0x0c -#define PCIS_SERIALBUS_FW 0x00 -#define PCIS_SERIALBUS_ACCESS 0x01 -#define PCIS_SERIALBUS_SSA 0x02 -#define PCIS_SERIALBUS_USB 0x03 -#define PCIS_SERIALBUS_FC 0x04 -#define PCIS_SERIALBUS -#define PCIS_SERIALBUS - -#define PCIC_OTHER 0xff - -/* some PCI vendor definitions (only used to identify ancient devices !!! */ - -#define PCIV_INTEL 0x8086 - -#define PCID_INTEL_SATURN 0x0483 -#define PCID_INTEL_ORION 0x84c4 - -/* for compatibility to FreeBSD-2.2 version of PCI code */ - -#ifdef PCI_COMPAT - -#define PCI_ID_REG 0x00 -#define PCI_COMMAND_STATUS_REG 0x04 -#define PCI_COMMAND_IO_ENABLE 0x00000001 -#define PCI_COMMAND_MEM_ENABLE 0x00000002 -#define PCI_CLASS_REG 0x08 -#define PCI_CLASS_MASK 0xff000000 -#define PCI_SUBCLASS_MASK 0x00ff0000 -#define PCI_REVISION_MASK 0x000000ff -#define PCI_CLASS_PREHISTORIC 0x00000000 -#define PCI_SUBCLASS_PREHISTORIC_VGA 0x00010000 -#define PCI_CLASS_MASS_STORAGE 0x01000000 -#define PCI_CLASS_DISPLAY 0x03000000 -#define PCI_SUBCLASS_DISPLAY_VGA 0x00000000 -#define PCI_CLASS_BRIDGE 0x06000000 -#define PCI_MAP_REG_START 0x10 -#define PCI_MAP_REG_END 0x28 -#define PCI_MAP_IO 0x00000001 -#define PCI_INTERRUPT_REG 0x3c - -#endif /* PCI_COMPAT */ diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h deleted file mode 100644 index 7843e3a6d656..000000000000 --- a/sys/dev/pci/pcivar.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 1997, Stefan Esser <se@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id: pcivar.h,v 1.24 1999/01/13 04:59:19 bde Exp $ - * - */ - -#ifndef _PCIVAR_H_ -#define _PCIVAR_H_ - -#ifndef PCI_COMPAT -#define PCI_COMPAT -#endif - -#include <pci/pci_ioctl.h> /* XXX KDM */ -#include <sys/queue.h> - -/* some PCI bus constants */ - -#define PCI_BUSMAX 255 /* highest supported bus number */ -#define PCI_SLOTMAX 31 /* highest supported slot number */ -#define PCI_FUNCMAX 7 /* highest supported function number */ -#define PCI_REGMAX 255 /* highest supported config register addr. */ - -#define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */ -#define PCI_MAXMAPS_1 2 /* max. no. of maps for PCI to PCI bridge */ -#define PCI_MAXMAPS_2 1 /* max. no. of maps for CardBus bridge */ - -/* pci_addr_t covers this system's PCI bus address space: 32 or 64 bit */ - -#ifdef PCI_A64 -typedef u_int64_t pci_addr_t; /* u_int64_t for system with 64bit addresses */ -#else -typedef u_int32_t pci_addr_t; /* u_int64_t for system with 64bit addresses */ -#endif - -/* map register information */ - -typedef struct { - u_int32_t base; - u_int8_t type; -#define PCI_MAPMEM 0x01 /* memory map */ -#define PCI_MAPMEMP 0x02 /* prefetchable memory map */ -#define PCI_MAPPORT 0x04 /* port map */ - u_int8_t ln2size; - u_int8_t ln2range; - u_int8_t reg; /* offset of map register in config space */ -} pcimap; - -/* config header information common to all header types */ - -typedef struct pcicfg { - pcimap *map; /* pointer to array of PCI maps */ - void *hdrspec; /* pointer to header type specific data */ - - u_int16_t subvendor; /* card vendor ID */ - u_int16_t subdevice; /* card device ID, assigned by card vendor */ - u_int16_t vendor; /* chip vendor ID */ - u_int16_t device; /* chip device ID, assigned by chip vendor */ - - u_int16_t cmdreg; /* disable/enable chip and PCI options */ - u_int16_t statreg; /* supported PCI features and error state */ - - u_int8_t baseclass; /* chip PCI class */ - u_int8_t subclass; /* chip PCI subclass */ - u_int8_t progif; /* chip PCI programming interface */ - u_int8_t revid; /* chip revision ID */ - - u_int8_t hdrtype; /* chip config header type */ - u_int8_t cachelnsz; /* cache line size in 4byte units */ - u_int8_t intpin; /* PCI interrupt pin */ - u_int8_t intline; /* interrupt line (IRQ for PC arch) */ - - u_int8_t mingnt; /* min. useful bus grant time in 250ns units */ - u_int8_t maxlat; /* max. tolerated bus grant latency in 250ns */ - u_int8_t lattimer; /* latency timer in units of 30ns bus cycles */ - - u_int8_t mfdev; /* multi-function device (from hdrtype reg) */ - u_int8_t nummaps; /* actual number of PCI maps used */ - - u_int8_t bus; /* config space bus address */ - u_int8_t slot; /* config space slot address */ - u_int8_t func; /* config space function number */ - - u_int8_t secondarybus; /* bus on secondary side of bridge, if any */ - u_int8_t subordinatebus; /* topmost bus number behind bridge, if any */ -} pcicfgregs; - -/* additional type 1 device config header information (PCI to PCI bridge) */ - -#ifdef PCI_A64 -#define PCI_PPBMEMBASE(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) & ~0xfffff) -#define PCI_PPBMEMLIMIT(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) | 0xfffff) -#else -#define PCI_PPBMEMBASE(h,l) (((l)<<16) & ~0xfffff) -#define PCI_PPBMEMLIMIT(h,l) (((l)<<16) | 0xfffff) -#endif /* PCI_A64 */ - -#define PCI_PPBIOBASE(h,l) ((((h)<<16) + ((l)<<8)) & ~0xfff) -#define PCI_PPBIOLIMIT(h,l) ((((h)<<16) + ((l)<<8)) | 0xfff) - -typedef struct { - pci_addr_t pmembase; /* base address of prefetchable memory */ - pci_addr_t pmemlimit; /* topmost address of prefetchable memory */ - u_int32_t membase; /* base address of memory window */ - u_int32_t memlimit; /* topmost address of memory window */ - u_int32_t iobase; /* base address of port window */ - u_int32_t iolimit; /* topmost address of port window */ - u_int16_t secstat; /* secondary bus status register */ - u_int16_t bridgectl; /* bridge control register */ - u_int8_t seclat; /* CardBus latency timer */ -} pcih1cfgregs; - -/* additional type 2 device config header information (CardBus bridge) */ - -typedef struct { - u_int32_t membase0; /* base address of memory window */ - u_int32_t memlimit0; /* topmost address of memory window */ - u_int32_t membase1; /* base address of memory window */ - u_int32_t memlimit1; /* topmost address of memory window */ - u_int32_t iobase0; /* base address of port window */ - u_int32_t iolimit0; /* topmost address of port window */ - u_int32_t iobase1; /* base address of port window */ - u_int32_t iolimit1; /* topmost address of port window */ - u_int32_t pccardif; /* PC Card 16bit IF legacy more base addr. */ - u_int16_t secstat; /* secondary bus status register */ - u_int16_t bridgectl; /* bridge control register */ - u_int8_t seclat; /* CardBus latency timer */ -} pcih2cfgregs; - -/* PCI bus attach definitions (there could be multiple PCI bus *trees* ... */ - -typedef struct pciattach { - int unit; - int pcibushigh; - struct pciattach *next; -} pciattach; - -struct pci_devinfo { - STAILQ_ENTRY(pci_devinfo) pci_links; - struct pci_device *device; /* should this be ifdefed? */ - pcicfgregs cfg; - struct pci_conf conf; -}; - -extern u_int32_t pci_numdevs; - - -/* externally visible functions */ - -int pci_probe (pciattach *attach); -void pci_drvattach(struct pci_devinfo *dinfo); - -/* low level PCI config register functions provided by pcibus.c */ - -int pci_cfgopen (void); -int pci_cfgread (pcicfgregs *cfg, int reg, int bytes); -void pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes); -#ifdef __alpha__ -vm_offset_t pci_cvt_to_dense (vm_offset_t); -vm_offset_t pci_cvt_to_bwx (vm_offset_t); -#endif /* __alpha__ */ -/* for compatibility to FreeBSD-2.2 version of PCI code */ - -#ifdef PCI_COMPAT - -typedef pcicfgregs *pcici_t; -typedef unsigned pcidi_t; -typedef void pci_inthand_t(void *arg); - -#define pci_max_burst_len (3) - -/* just copied from old PCI code for now ... */ - -extern struct linker_set pcidevice_set; -extern int pci_mechanism; - -struct pci_device { - char* pd_name; - const char* (*pd_probe ) (pcici_t tag, pcidi_t type); - void (*pd_attach) (pcici_t tag, int unit); - u_long *pd_count; - int (*pd_shutdown) (int, int); -}; - -struct pci_lkm { - struct pci_device *dvp; - struct pci_lkm *next; -}; - -#ifdef __i386__ -typedef u_short pci_port_t; -#else -typedef u_int pci_port_t; -#endif - -u_long pci_conf_read (pcici_t tag, u_long reg); -void pci_conf_write (pcici_t tag, u_long reg, u_long data); -void pci_configure (void); -int pci_map_port (pcici_t tag, u_long reg, pci_port_t* pa); -int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa); -int pci_map_dense (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa); -int pci_map_bwx (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa); -int pci_map_int (pcici_t tag, pci_inthand_t *handler, void *arg, - intrmask_t *maskptr); -int pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg, - intrmask_t *maskptr, u_int flags); -int pci_unmap_int (pcici_t tag); -int pci_register_lkm (struct pci_device *dvp, int if_revision); - -#endif /* PCI_COMPAT */ -#endif /* _PCIVAR_H_ */ |
