Explicitly track the state of all known BARs for each PCI device. The PCI
bus driver will now remember the size of a BAR obtained during the initial bus scan and use that size when doing lazy resource allocation rather than resizing the BAR. The bus driver will now also report unallocated BARs to userland for display by 'pciconf -lb'. Psuedo-resources that are not BARs (such as the implicit I/O port resources for master/slave ATA controllers) will no longer be listed as BARs in 'pciconf -lb'. During resume, BARs are restored from their new saved state instead of having the raw registers saved and restored across resume. This also fixes restoring BARs at unusual loactions if said BAR has been allocated by a driver. Add a constant for the offset of the ROM BIOS BAR in PCI-PCI bridges and properly handle ROM BIOS BARs in PCI-PCI bridges. The PCI bus now also properly handles the lack of a ROM BIOS BAR in a PCI-Cardbus bridge. Tested by: jkim
This commit is contained in:
parent
11d2f4df50
commit
a90dd577e7
@ -69,6 +69,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include "pcib_if.h"
|
||||
#include "pci_if.h"
|
||||
|
||||
#define PCIR_IS_BIOS(cfg, reg) \
|
||||
(((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \
|
||||
((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1))
|
||||
|
||||
|
||||
static pci_addr_t pci_mapbase(uint64_t mapreg);
|
||||
static const char *pci_maptype(uint64_t mapreg);
|
||||
static int pci_mapsize(uint64_t testval);
|
||||
@ -531,6 +536,7 @@ pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size)
|
||||
|
||||
cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0;
|
||||
cfg->hdrtype &= ~PCIM_MFDEV;
|
||||
STAILQ_INIT(&cfg->maps);
|
||||
|
||||
pci_fixancient(cfg);
|
||||
pci_hdrtypedata(pcib, b, s, f, cfg);
|
||||
@ -2106,6 +2112,7 @@ int
|
||||
pci_freecfg(struct pci_devinfo *dinfo)
|
||||
{
|
||||
struct devlist *devlist_head;
|
||||
struct pci_map *pm, *next;
|
||||
int i;
|
||||
|
||||
devlist_head = &pci_devq;
|
||||
@ -2119,6 +2126,9 @@ pci_freecfg(struct pci_devinfo *dinfo)
|
||||
free(dinfo->cfg.vpd.vpd_w[i].value, M_DEVBUF);
|
||||
free(dinfo->cfg.vpd.vpd_w, M_DEVBUF);
|
||||
}
|
||||
STAILQ_FOREACH_SAFE(pm, &dinfo->cfg.maps, pm_link, next) {
|
||||
free(pm, M_DEVBUF);
|
||||
}
|
||||
STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
|
||||
free(dinfo, M_DEVBUF);
|
||||
|
||||
@ -2393,6 +2403,7 @@ pci_memen(device_t dev)
|
||||
static void
|
||||
pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
pci_addr_t map, testval;
|
||||
int ln2range;
|
||||
uint16_t cmd;
|
||||
@ -2402,7 +2413,8 @@ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp)
|
||||
* memory BAR. Bit 0 is special and should not be set when
|
||||
* sizing the BAR.
|
||||
*/
|
||||
if (reg == PCIR_BIOS) {
|
||||
dinfo = device_get_ivars(dev);
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, reg)) {
|
||||
map = pci_read_config(dev, reg, 4);
|
||||
pci_write_config(dev, reg, 0xfffffffe, 4);
|
||||
testval = pci_read_config(dev, reg, 4);
|
||||
@ -2453,20 +2465,99 @@ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp)
|
||||
}
|
||||
|
||||
static void
|
||||
pci_write_bar(device_t dev, int reg, pci_addr_t base)
|
||||
pci_write_bar(device_t dev, struct pci_map *pm, pci_addr_t base)
|
||||
{
|
||||
pci_addr_t map;
|
||||
struct pci_devinfo *dinfo;
|
||||
int ln2range;
|
||||
|
||||
map = pci_read_config(dev, reg, 4);
|
||||
|
||||
/* The device ROM BAR is always 32-bits. */
|
||||
if (reg == PCIR_BIOS)
|
||||
return;
|
||||
ln2range = pci_maprange(map);
|
||||
pci_write_config(dev, reg, base, 4);
|
||||
/* The device ROM BAR is always a 32-bit memory BAR. */
|
||||
dinfo = device_get_ivars(dev);
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg))
|
||||
ln2range = 32;
|
||||
else
|
||||
ln2range = pci_maprange(pm->pm_value);
|
||||
pci_write_config(dev, pm->pm_reg, base, 4);
|
||||
if (ln2range == 64)
|
||||
pci_write_config(dev, reg + 4, base >> 32, 4);
|
||||
pci_write_config(dev, pm->pm_reg + 4, base >> 32, 4);
|
||||
pm->pm_value = pci_read_config(dev, pm->pm_reg, 4);
|
||||
if (ln2range == 64)
|
||||
pm->pm_value |= (pci_addr_t)pci_read_config(dev, pm->pm_reg + 4, 4) << 32;
|
||||
}
|
||||
|
||||
struct pci_map *
|
||||
pci_find_bar(device_t dev, int reg)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
struct pci_map *pm;
|
||||
|
||||
dinfo = device_get_ivars(dev);
|
||||
STAILQ_FOREACH(pm, &dinfo->cfg.maps, pm_link) {
|
||||
if (pm->pm_reg == reg)
|
||||
return (pm);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
pci_bar_enabled(device_t dev, struct pci_map *pm)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
uint16_t cmd;
|
||||
|
||||
dinfo = device_get_ivars(dev);
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg) &&
|
||||
!(pm->pm_value & PCIM_BIOS_ENABLE))
|
||||
return (0);
|
||||
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg) || PCI_BAR_MEM(pm->pm_value))
|
||||
return ((cmd & PCIM_CMD_MEMEN) != 0);
|
||||
else
|
||||
return ((cmd & PCIM_CMD_PORTEN) != 0);
|
||||
}
|
||||
|
||||
static struct pci_map *
|
||||
pci_add_bar(device_t dev, int reg, pci_addr_t value, pci_addr_t size)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
struct pci_map *pm, *prev;
|
||||
|
||||
dinfo = device_get_ivars(dev);
|
||||
pm = malloc(sizeof(*pm), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
pm->pm_reg = reg;
|
||||
pm->pm_value = value;
|
||||
pm->pm_size = size;
|
||||
STAILQ_FOREACH(prev, &dinfo->cfg.maps, pm_link) {
|
||||
KASSERT(prev->pm_reg != pm->pm_reg, ("duplicate map %02x",
|
||||
reg));
|
||||
if (STAILQ_NEXT(prev, pm_link) == NULL ||
|
||||
STAILQ_NEXT(prev, pm_link)->pm_reg > pm->pm_reg)
|
||||
break;
|
||||
}
|
||||
if (prev != NULL)
|
||||
STAILQ_INSERT_AFTER(&dinfo->cfg.maps, prev, pm, pm_link);
|
||||
else
|
||||
STAILQ_INSERT_TAIL(&dinfo->cfg.maps, pm, pm_link);
|
||||
return (pm);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_restore_bars(device_t dev)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
struct pci_map *pm;
|
||||
int ln2range;
|
||||
|
||||
dinfo = device_get_ivars(dev);
|
||||
STAILQ_FOREACH(pm, &dinfo->cfg.maps, pm_link) {
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg))
|
||||
ln2range = 32;
|
||||
else
|
||||
ln2range = pci_maprange(pm->pm_value);
|
||||
pci_write_config(dev, pm->pm_reg, pm->pm_value, 4);
|
||||
if (ln2range == 64)
|
||||
pci_write_config(dev, pm->pm_reg + 4,
|
||||
pm->pm_value >> 32, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2477,6 +2568,7 @@ static int
|
||||
pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
|
||||
int force, int prefetch)
|
||||
{
|
||||
struct pci_map *pm;
|
||||
pci_addr_t base, map, testval;
|
||||
pci_addr_t start, end, count;
|
||||
int barlen, basezero, maprange, mapsize, type;
|
||||
@ -2513,6 +2605,8 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
|
||||
(type == SYS_RES_IOPORT && mapsize < 2))
|
||||
return (barlen);
|
||||
|
||||
/* Save a record of this BAR. */
|
||||
pm = pci_add_bar(dev, reg, map, mapsize);
|
||||
if (bootverbose) {
|
||||
printf("\tmap[%02x]: type %s, range %2d, base %#jx, size %2d",
|
||||
reg, pci_maptype(map), maprange, (uintmax_t)base, mapsize);
|
||||
@ -2600,7 +2694,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
|
||||
start = 0;
|
||||
} else
|
||||
start = rman_get_start(res);
|
||||
pci_write_bar(dev, reg, start);
|
||||
pci_write_bar(dev, pm, start);
|
||||
return (barlen);
|
||||
}
|
||||
|
||||
@ -3735,31 +3829,41 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
|
||||
struct resource_list *rl = &dinfo->resources;
|
||||
struct resource_list_entry *rle;
|
||||
struct resource *res;
|
||||
struct pci_map *pm;
|
||||
pci_addr_t map, testval;
|
||||
int mapsize;
|
||||
|
||||
/*
|
||||
* Weed out the bogons, and figure out how large the BAR/map
|
||||
* is. Bars that read back 0 here are bogus and unimplemented.
|
||||
* Note: atapci in legacy mode are special and handled elsewhere
|
||||
* in the code. If you have a atapci device in legacy mode and
|
||||
* it fails here, that other code is broken.
|
||||
*/
|
||||
res = NULL;
|
||||
pci_read_bar(child, *rid, &map, &testval);
|
||||
pm = pci_find_bar(child, *rid);
|
||||
if (pm != NULL) {
|
||||
/* This is a BAR that we failed to allocate earlier. */
|
||||
mapsize = pm->pm_size;
|
||||
map = pm->pm_value;
|
||||
} else {
|
||||
/*
|
||||
* Weed out the bogons, and figure out how large the
|
||||
* BAR/map is. BARs that read back 0 here are bogus
|
||||
* and unimplemented. Note: atapci in legacy mode are
|
||||
* special and handled elsewhere in the code. If you
|
||||
* have a atapci device in legacy mode and it fails
|
||||
* here, that other code is broken.
|
||||
*/
|
||||
pci_read_bar(child, *rid, &map, &testval);
|
||||
|
||||
/*
|
||||
* Determine the size of the BAR and ignore BARs with a size
|
||||
* of 0. Device ROM BARs use a different mask value.
|
||||
*/
|
||||
if (*rid == PCIR_BIOS)
|
||||
mapsize = pci_romsize(testval);
|
||||
else
|
||||
mapsize = pci_mapsize(testval);
|
||||
if (mapsize == 0)
|
||||
goto out;
|
||||
/*
|
||||
* Determine the size of the BAR and ignore BARs with a size
|
||||
* of 0. Device ROM BARs use a different mask value.
|
||||
*/
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, *rid))
|
||||
mapsize = pci_romsize(testval);
|
||||
else
|
||||
mapsize = pci_mapsize(testval);
|
||||
if (mapsize == 0)
|
||||
goto out;
|
||||
pm = pci_add_bar(child, *rid, map, mapsize);
|
||||
}
|
||||
|
||||
if (PCI_BAR_MEM(testval) || *rid == PCIR_BIOS) {
|
||||
if (PCI_BAR_MEM(map) || PCIR_IS_BIOS(&dinfo->cfg, *rid)) {
|
||||
if (type != SYS_RES_MEMORY) {
|
||||
if (bootverbose)
|
||||
device_printf(dev,
|
||||
@ -3789,12 +3893,12 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
|
||||
count = (pci_addr_t)1 << mapsize;
|
||||
if (RF_ALIGNMENT(flags) < mapsize)
|
||||
flags = (flags & ~RF_ALIGNMENT_MASK) | RF_ALIGNMENT_LOG2(mapsize);
|
||||
if (PCI_BAR_MEM(testval) && (testval & PCIM_BAR_MEM_PREFETCH))
|
||||
if (PCI_BAR_MEM(map) && (map & PCIM_BAR_MEM_PREFETCH))
|
||||
flags |= RF_PREFETCHABLE;
|
||||
|
||||
/*
|
||||
* Allocate enough resource, and then write back the
|
||||
* appropriate bar for that resource.
|
||||
* appropriate BAR for that resource.
|
||||
*/
|
||||
res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid,
|
||||
start, end, count, flags & ~RF_ACTIVE);
|
||||
@ -3818,7 +3922,7 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
|
||||
"Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n",
|
||||
count, *rid, type, rman_get_start(res));
|
||||
map = rman_get_start(res);
|
||||
pci_write_bar(child, *rid, map);
|
||||
pci_write_bar(child, pm, map);
|
||||
out:;
|
||||
return (res);
|
||||
}
|
||||
@ -3879,6 +3983,7 @@ int
|
||||
pci_activate_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
int error;
|
||||
|
||||
error = bus_generic_activate_resource(dev, child, type, rid, r);
|
||||
@ -3888,9 +3993,10 @@ pci_activate_resource(device_t dev, device_t child, int type, int rid,
|
||||
/* Enable decoding in the command register when activating BARs. */
|
||||
if (device_get_parent(child) == dev) {
|
||||
/* Device ROMs need their decoding explicitly enabled. */
|
||||
if (rid == PCIR_BIOS)
|
||||
pci_write_config(child, rid, rman_get_start(r) |
|
||||
PCIM_BIOS_ENABLE, 4);
|
||||
dinfo = device_get_ivars(child);
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, rid))
|
||||
pci_write_bar(child, pci_find_bar(child, rid),
|
||||
rman_get_start(r) | PCIM_BIOS_ENABLE);
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
case SYS_RES_MEMORY:
|
||||
@ -3905,15 +4011,20 @@ int
|
||||
pci_deactivate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
int error;
|
||||
|
||||
error = bus_generic_deactivate_resource(dev, child, type, rid, r);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/* Disable decoding for device ROMs. */
|
||||
if (rid == PCIR_BIOS)
|
||||
pci_write_config(child, rid, rman_get_start(r), 4);
|
||||
/* Disable decoding for device ROMs. */
|
||||
if (device_get_parent(child) == dev) {
|
||||
dinfo = device_get_ivars(child);
|
||||
if (PCIR_IS_BIOS(&dinfo->cfg, rid))
|
||||
pci_write_bar(child, pci_find_bar(child, rid),
|
||||
rman_get_start(r));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -3991,7 +4102,7 @@ pci_delete_resource(device_t dev, device_t child, int type, int rid)
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
case SYS_RES_MEMORY:
|
||||
pci_write_bar(child, rid, 0);
|
||||
pci_write_bar(child, pci_find_bar(child, rid), 0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -4090,7 +4201,6 @@ pci_modevent(module_t mod, int what, void *arg)
|
||||
void
|
||||
pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Only do header type 0 devices. Type 1 devices are bridges,
|
||||
@ -4112,9 +4222,7 @@ pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
|
||||
*/
|
||||
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0)
|
||||
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
|
||||
for (i = 0; i < dinfo->cfg.nummaps; i++)
|
||||
pci_write_config(dev, PCIR_BAR(i), dinfo->cfg.bar[i], 4);
|
||||
pci_write_config(dev, PCIR_BIOS, dinfo->cfg.bios, 4);
|
||||
pci_restore_bars(dev);
|
||||
pci_write_config(dev, PCIR_COMMAND, dinfo->cfg.cmdreg, 2);
|
||||
pci_write_config(dev, PCIR_INTLINE, dinfo->cfg.intline, 1);
|
||||
pci_write_config(dev, PCIR_INTPIN, dinfo->cfg.intpin, 1);
|
||||
@ -4135,7 +4243,6 @@ pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
|
||||
void
|
||||
pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate)
|
||||
{
|
||||
int i;
|
||||
uint32_t cls;
|
||||
int ps;
|
||||
|
||||
@ -4148,9 +4255,6 @@ pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate)
|
||||
*/
|
||||
if ((dinfo->cfg.hdrtype & PCIM_HDRTYPE) != PCIM_HDRTYPE_NORMAL)
|
||||
return;
|
||||
for (i = 0; i < dinfo->cfg.nummaps; i++)
|
||||
dinfo->cfg.bar[i] = pci_read_config(dev, PCIR_BAR(i), 4);
|
||||
dinfo->cfg.bios = pci_read_config(dev, PCIR_BIOS, 4);
|
||||
|
||||
/*
|
||||
* Some drivers apparently write to these registers w/o updating our
|
||||
|
@ -309,8 +309,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
||||
struct pci_io *io;
|
||||
struct pci_bar_io *bio;
|
||||
struct pci_match_conf *pattern_buf;
|
||||
struct resource_list_entry *rle;
|
||||
uint32_t value;
|
||||
struct pci_map *pm;
|
||||
size_t confsz, iolen, pbufsz;
|
||||
int error, ionum, i, num_patterns;
|
||||
#ifdef PRE7_COMPAT
|
||||
@ -685,54 +684,14 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
||||
error = ENODEV;
|
||||
break;
|
||||
}
|
||||
dinfo = device_get_ivars(pcidev);
|
||||
|
||||
/*
|
||||
* Look for a resource list entry matching the requested BAR.
|
||||
*
|
||||
* XXX: This will not find BARs that are not initialized, but
|
||||
* maybe that is ok?
|
||||
*/
|
||||
rle = resource_list_find(&dinfo->resources, SYS_RES_MEMORY,
|
||||
bio->pbi_reg);
|
||||
if (rle == NULL)
|
||||
rle = resource_list_find(&dinfo->resources,
|
||||
SYS_RES_IOPORT, bio->pbi_reg);
|
||||
if (rle == NULL || rle->res == NULL) {
|
||||
pm = pci_find_bar(pcidev, bio->pbi_reg);
|
||||
if (pm == NULL) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, we have a resource for this BAR. Read the lower
|
||||
* 32 bits to get any flags.
|
||||
*/
|
||||
value = pci_read_config(pcidev, bio->pbi_reg, 4);
|
||||
if (PCI_BAR_MEM(value)) {
|
||||
if (rle->type != SYS_RES_MEMORY) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
value &= ~PCIM_BAR_MEM_BASE;
|
||||
} else {
|
||||
if (rle->type != SYS_RES_IOPORT) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
value &= ~PCIM_BAR_IO_BASE;
|
||||
}
|
||||
bio->pbi_base = rman_get_start(rle->res) | value;
|
||||
bio->pbi_length = rman_get_size(rle->res);
|
||||
|
||||
/*
|
||||
* Check the command register to determine if this BAR
|
||||
* is enabled.
|
||||
*/
|
||||
value = pci_read_config(pcidev, PCIR_COMMAND, 2);
|
||||
if (rle->type == SYS_RES_MEMORY)
|
||||
bio->pbi_enabled = (value & PCIM_CMD_MEMEN) != 0;
|
||||
else
|
||||
bio->pbi_enabled = (value & PCIM_CMD_PORTEN) != 0;
|
||||
bio->pbi_base = pm->pm_value;
|
||||
bio->pbi_length = (pci_addr_t)1 << pm->pm_size;
|
||||
bio->pbi_enabled = pci_bar_enabled(pcidev, pm);
|
||||
error = 0;
|
||||
break;
|
||||
case PCIOCATTACHED:
|
||||
|
@ -212,6 +212,7 @@
|
||||
#define PCIM_BRPM_64 0x1
|
||||
#define PCIM_BRPM_MASK 0xf
|
||||
|
||||
#define PCIR_BIOS_1 0x38
|
||||
#define PCIR_BRIDGECTL_1 0x3e
|
||||
|
||||
/* config registers for header type 2 (CardBus) devices */
|
||||
|
@ -46,7 +46,14 @@ struct pcicfg_pp {
|
||||
uint8_t pp_bse; /* conf. space addr. of PM BSE reg */
|
||||
uint8_t pp_data; /* conf. space addr. of PM data reg */
|
||||
};
|
||||
|
||||
|
||||
struct pci_map {
|
||||
pci_addr_t pm_value; /* Raw BAR value */
|
||||
pci_addr_t pm_size;
|
||||
uint8_t pm_reg;
|
||||
STAILQ_ENTRY(pci_map) pm_link;
|
||||
};
|
||||
|
||||
struct vpd_readonly {
|
||||
char keyword[2];
|
||||
char *value;
|
||||
@ -120,8 +127,7 @@ struct pcicfg_ht {
|
||||
typedef struct pcicfg {
|
||||
struct device *dev; /* device which owns this */
|
||||
|
||||
uint32_t bar[PCI_MAXMAPS_0]; /* BARs */
|
||||
uint32_t bios; /* BIOS mapping */
|
||||
STAILQ_HEAD(, pci_map) maps; /* BARs */
|
||||
|
||||
uint16_t subvendor; /* card vendor ID */
|
||||
uint16_t subdevice; /* card device ID, assigned by card vendor */
|
||||
@ -477,4 +483,7 @@ STAILQ_HEAD(devlist, pci_devinfo);
|
||||
extern struct devlist pci_devq;
|
||||
extern uint32_t pci_generation;
|
||||
|
||||
struct pci_map *pci_find_bar(device_t dev, int reg);
|
||||
int pci_bar_enabled(device_t dev, struct pci_map *pm);
|
||||
|
||||
#endif /* _PCIVAR_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user