PERFORCE change 44670 for review
Warner Losh
imp at FreeBSD.org
Thu Jan 1 21:53:53 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=44670
Change 44670 by imp at imp_pacopaco on 2004/01/01 21:53:31
Integrate from newcard to get imp's power/resource stuff.
Affected files ...
.. //depot/projects/power/sys/dev/pci/pci.c#7 integrate
.. //depot/projects/power/sys/dev/pci/pci_pci.c#4 integrate
.. //depot/projects/power/sys/dev/pci/pci_private.h#5 integrate
.. //depot/projects/power/sys/dev/pci/pci_user.c#4 integrate
.. //depot/projects/power/sys/dev/pci/pcireg.h#4 integrate
.. //depot/projects/power/sys/dev/pci/pcivar.h#4 integrate
Differences ...
==== //depot/projects/power/sys/dev/pci/pci.c#7 (text+ko) ====
@@ -68,8 +68,9 @@
static int pci_porten(device_t pcib, int b, int s, int f);
static int pci_memen(device_t pcib, int b, int s, int f);
-static int pci_add_map(device_t pcib, int b, int s, int f,
- int reg, struct resource_list *rl);
+static int pci_add_map(device_t pcib, device_t bus, device_t dev,
+ int b, int s, int f, int reg,
+ struct resource_list *rl);
static void pci_add_resources(device_t pcib, device_t bus,
device_t dev);
static int pci_probe(device_t dev);
@@ -615,6 +616,7 @@
return (EINVAL);
}
pci_set_command_bit(dev, child, bit);
+ /* Some devices seem to need a brief stall here, what do to? */
command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
if (command & bit)
return (0);
@@ -721,11 +723,12 @@
* register is a 32bit map register or 2 if it is a 64bit register.
*/
static int
-pci_add_map(device_t pcib, int b, int s, int f, int reg,
- struct resource_list *rl)
+pci_add_map(device_t pcib, device_t bus, device_t dev,
+ int b, int s, int f, int reg, struct resource_list *rl)
{
uint32_t map;
uint64_t base;
+ uint64_t start, end, count;
uint8_t ln2size;
uint8_t ln2range;
uint32_t testval;
@@ -733,7 +736,6 @@
int type;
map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
-
PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4);
testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4);
@@ -759,10 +761,9 @@
(type == SYS_RES_IOPORT && ln2size < 3))
return (1);
- if (ln2range == 64) {
+ if (ln2range == 64)
/* Read the other half of a 64bit map register */
base |= (uint64_t) PCIB_READ_CONFIG(pcib, b, s, f, reg + 4, 4) << 32;
- }
if (bootverbose) {
printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d",
@@ -778,9 +779,10 @@
/*
* This code theoretically does the right thing, but has
- * undesirable side effects in some cases where
- * peripherals respond oddly to having these bits
- * enabled. Leave them alone by default.
+ * undesirable side effects in some cases where peripherals
+ * respond oddly to having these bits enabled. Let the user
+ * be able to turn them off (since pci_enable_io_modes is 1 by
+ * default).
*/
if (pci_enable_io_modes) {
/* Turn on resources that have been left off by a lazy BIOS */
@@ -802,13 +804,21 @@
}
/*
* If base is 0, then we have problems. It is best to ignore
- * such entires for the moment. XXX
+ * such entires for the moment. These will be allocated later if
+ * the driver specifically requests them.
*/
if (base == 0)
return 1;
- resource_list_add(rl, type, reg, base, base + (1 << ln2size) - 1,
- (1 << ln2size));
+ start = base;
+ end = base + (1 << ln2size) - 1;
+ count = 1 << ln2size;
+ resource_list_add(rl, type, reg, start, end, count);
+ /*
+ * Not quite sure what to do on failure of allocating the resource
+ * since I can postulate several right answers.
+ */
+ resource_list_alloc(rl, bus, dev, type, ®, start, end, count, 0);
return ((ln2range == 64) ? 2 : 1);
}
@@ -824,14 +834,13 @@
b = cfg->bus;
s = cfg->slot;
f = cfg->func;
- for (i = 0; i < cfg->nummaps;) {
- i += pci_add_map(pcib, b, s, f, PCIR_BAR(i), rl);
- }
+ for (i = 0; i < cfg->nummaps;)
+ i += pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(i), rl);
for (q = &pci_quirks[0]; q->devid; q++) {
if (q->devid == ((cfg->device << 16) | cfg->vendor)
&& q->type == PCI_QUIRK_MAP_REG)
- pci_add_map(pcib, b, s, f, q->arg1, rl);
+ pci_add_map(pcib, bus, dev, b, s, f, q->arg1, rl);
}
if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) {
@@ -892,6 +901,7 @@
pcib = device_get_parent(bus);
dinfo->cfg.dev = device_add_child(bus, NULL, -1);
device_set_ivars(dinfo->cfg.dev, dinfo);
+ pci_cfg_save(dinfo->cfg.dev, dinfo, 0);
pci_cfg_restore(dinfo->cfg.dev, dinfo);
pci_add_resources(pcib, bus, dinfo->cfg.dev);
pci_print_verbose(dinfo);
@@ -1421,18 +1431,74 @@
}
#endif /* DDB */
+/*
+ * XXX I'm not sure the following is good for 64-bit bars.
+ */
+static struct resource *
+pci_alloc_map(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ struct resource_list *rl = &dinfo->resources;
+ struct resource_list_entry *rle;
+ struct resource *res;
+ uint32_t map, testval;
+
+ /*
+ * Weed out the bogons, and figure out how large the BAR/map is.
+ */
+ map = pci_read_config(child, *rid, 4);
+ if (pci_maptype(map) & PCI_MAPMEM) {
+ if (type != SYS_RES_MEMORY) {
+ device_printf(child, "rid %#x says memory, driver wants %d failed.\n", *rid, type);
+ return (NULL);
+ }
+ } else {
+ if (type != SYS_RES_IOPORT) {
+ device_printf(child, "rid %#x says ioport, driver wants %d failed.\n", *rid, type);
+ return (NULL);
+ }
+ }
+ pci_write_config(child, *rid, 0xffffffff, 4);
+ testval = pci_read_config(child, *rid, 4);
+
+ /*
+ * Allocate enough resource, and then write back the
+ * appropriate bar for that resource (this is the part
+ * I'm not sure is good for 64-bit bars).
+ */
+ count = 1 << pci_mapsize(testval);
+ res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid,
+ start, end, count, flags);
+ if (res == NULL) {
+ device_printf(child, "%#lx bytes of rid %#x res %d failed.\n",
+ count, *rid, type);
+ pci_write_config(child, *rid, map, 4);
+ return (NULL);
+ }
+ resource_list_add(rl, type, *rid, start, end, count);
+ rle = resource_list_find(rl, type, *rid);
+ if (rle == NULL)
+ panic("pci_alloc_map: unexpedly can't find resource.");
+ rle->res = res;
+ device_printf(child, "Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n",
+ count, *rid, type, rman_get_start(res));
+ pci_write_config(child, *rid, rman_get_start(res), 4);
+ return (res);
+}
+
+
struct resource *
pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct pci_devinfo *dinfo = device_get_ivars(child);
struct resource_list *rl = &dinfo->resources;
+ struct resource_list_entry *rle;
pcicfgregs *cfg = &dinfo->cfg;
/*
* Perform lazy resource allocation
- *
- * XXX add support here for SYS_RES_IOPORT and SYS_RES_MEMORY
*/
if (device_get_parent(child) == dev) {
switch (type) {
@@ -1458,16 +1524,39 @@
if (*rid < PCIR_BAR(cfg->nummaps)) {
/*
* Enable the I/O mode. We should
- * also be allocating resources
- * too. XXX
+ * also be assigning resources too
+ * when none are present. The
+ * resource_list_alloc kind of sorta does
+ * this...
*/
if (PCI_ENABLE_IO(dev, child, type))
return (NULL);
}
+ rle = resource_list_find(rl, type, *rid);
+ if (rle == NULL)
+ return (pci_alloc_map(dev, child, type, rid,
+ start, end, count, flags));
break;
}
+ /*
+ * If we've already allocated the resource, then
+ * return it now. But first we may need to activate
+ * it, since we don't allocate the resource as active
+ * above. Normally this would be done down in the
+ * nexus, but since we short-circuit that path we have
+ * to do its job here. Not sure if we should free the
+ * resource if it fails to activate.
+ */
+ rle = resource_list_find(rl, type, *rid);
+ if (rle != NULL && rle->res != NULL) {
+ device_printf(child, "Bus reserved %#lx bytes for rid %#x type %d at %#lx\n", rman_get_size(rle->res), *rid, type, rman_get_start(rle->res));
+ if ((flags & RF_ACTIVE) &&
+ bus_generic_activate_resource(dev, child, type,
+ *rid, rle->res) != 0)
+ return NULL;
+ return (rle->res);
+ }
}
-
return (resource_list_alloc(rl, dev, child, type, rid,
start, end, count, flags));
}
@@ -1511,13 +1600,9 @@
struct resource_list *
pci_get_resource_list (device_t dev, device_t child)
{
- struct pci_devinfo * dinfo = device_get_ivars(child);
- struct resource_list * rl = &dinfo->resources;
+ struct pci_devinfo *dinfo = device_get_ivars(child);
- if (!rl)
- return (NULL);
-
- return (rl);
+ return (&dinfo->resources);
}
uint32_t
@@ -1604,35 +1689,77 @@
static void
pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
{
-#define NBAR 7
int i;
- uint32_t bar[NBAR];
+ /*
+ * Only do header type 0 devices. Type 1 devices are bridges, which
+ * we know need special treatment. Type 2 devices are cardbus bridges
+ * which also require special treatment. Other types are unknown, and
+ * we err on the side of safety by ignoring them.
+ */
if (dinfo->cfg.hdrtype != 0)
return;
- for (i = 0; i < NBAR; i++)
- bar[i] = pci_read_config(dev, PCIR_MAPS + i * 4, 4);
printf("pci%d:%d:%d: setting power state D0\n", dinfo->cfg.bus,
dinfo->cfg.slot, dinfo->cfg.func);
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
- for (i = 0; i < NBAR; i++)
- pci_write_config(dev, PCIR_MAPS + i * 4, bar[i], 4);
+ for (i = 0; i < dinfo->cfg.nummaps; i++)
+ pci_write_config(dev, PCIR_MAPS + i * 4, dinfo->cfg.bar[i], 4);
+ 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);
pci_write_config(dev, PCIR_MINGNT, dinfo->cfg.mingnt, 1);
pci_write_config(dev, PCIR_MAXLAT, dinfo->cfg.maxlat, 1);
- if (dinfo->cfg.intpin > 0 && PCI_INTERRUPT_VALID(dinfo->cfg.intline))
- dinfo->cfg.intline = PCI_ASSIGN_INTERRUPT(
- device_get_parent(dev), dev);
- pci_write_config(dev, PCIR_INTLINE, dinfo->cfg.intline, 1);
- pci_write_config(dev, PCIR_INTPIN, dinfo->cfg.intpin, 1);
+ pci_write_config(dev, PCIR_CACHELNSZ, dinfo->cfg.cachelnsz, 1);
+ pci_write_config(dev, PCIR_LATTIMER, dinfo->cfg.lattimer, 1);
}
static void
pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate)
{
+ int i;
uint32_t cls;
+ /*
+ * Only do header type 0 devices. Type 1 devices are bridges, which
+ * we know need special treatment. Type 2 devices are cardbus bridges
+ * which also require special treatment. Other types are unknown, and
+ * we err on the side of safety by ignoring them. Powering down
+ * bridges should not be undertaken lightly.
+ */
if (dinfo->cfg.hdrtype != 0)
return;
+ for (i = 0; i < dinfo->cfg.nummaps; i++)
+ dinfo->cfg.bar[i] = pci_read_config(dev, PCIR_MAPS + i * 4, 4);
+
+ /*
+ * Some drivers apparently write to these registers w/o
+ * updating our cahced copy. No harm happens if we update the
+ * copy, so do so here so we can restore them. The COMMAND
+ * register is modified by the bus w/o updating the cache. This
+ * should represent the normally writable portion of the 'defined'
+ * part of type 0 headers. In theory we also need to save/restore
+ * the PCI capability structures we know about, but apart from power
+ * we don't know any that are writable.
+ */
+ dinfo->cfg.cmdreg = pci_read_config(dev, PCIR_COMMAND, 2);
+ dinfo->cfg.intline = pci_read_config(dev, PCIR_INTLINE, 1);
+ dinfo->cfg.intpin = pci_read_config(dev, PCIR_INTPIN, 1);
+ dinfo->cfg.mingnt = pci_read_config(dev, PCIR_MINGNT, 1);
+ dinfo->cfg.maxlat = pci_read_config(dev, PCIR_MAXLAT, 1);
+ dinfo->cfg.cachelnsz = pci_read_config(dev, PCIR_CACHELNSZ, 1);
+ dinfo->cfg.lattimer = pci_read_config(dev, PCIR_LATTIMER, 1);
+
+ /*
+ * don't set the state for display devices and for memory devices
+ * since bad things happen. we should (a) have drivers that can easily
+ * detach and (b) use generic drivers for these devices so that some
+ * device actually attaches. We need to make sure that when we
+ * implement (a) we don't power the device down on a reattach.
+ *
+ * John and Nate also tell me that we should be running the power up
+ * and power down hooks when we change power state for those nodes
+ * that have ACPI hooks in the tree.
+ */
cls = pci_get_class(dev);
if (setstate && cls != PCIC_DISPLAY && cls != PCIC_MEMORY) {
pci_set_powerstate(dev, PCI_POWERSTATE_D3);
==== //depot/projects/power/sys/dev/pci/pci_pci.c#4 (text+ko) ====
@@ -311,144 +311,133 @@
pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- struct pcib_softc *sc = device_get_softc(dev);
- int ok;
+ struct pcib_softc *sc = device_get_softc(dev);
+ int ok;
- /*
- * If this is a "default" allocation against this rid, we can't work
- * out where it's coming from (we should actually never see these) so we
- * just have to punt.
- */
- if ((start == 0) && (end == ~0)) {
- device_printf(dev, "can't decode default resource id %d for %s%d, bypassing\n",
- *rid, device_get_name(child), device_get_unit(child));
- } else {
/*
* Fail the allocation for this range if it's not supported.
*/
switch (type) {
case SYS_RES_IOPORT:
- ok = 1;
- if (!pcib_is_isa_io(start)) {
- ok = 0;
- if (pcib_is_io_open(sc))
- ok = (start >= sc->iobase && end <= sc->iolimit);
- if (!pci_allow_unsupported_io_range) {
- if (!ok) {
- if (start < sc->iobase)
- start = sc->iobase;
- if (end > sc->iolimit)
- end = sc->iolimit;
- }
- } else {
- if (start < sc->iobase)
- printf("start (%lx) < sc->iobase (%x)\n", start,
- sc->iobase);
- if (end > sc->iolimit)
- printf("end (%lx) > sc->iolimit (%x)\n",
- end, sc->iolimit);
- if (end < start)
- printf("end (%lx) < start (%lx)\n", end, start);
+ ok = 1;
+ if (!pcib_is_isa_io(start)) {
+ ok = 0;
+ if (pcib_is_io_open(sc))
+ ok = (start >= sc->iobase && end <= sc->iolimit);
+ if (!pci_allow_unsupported_io_range) {
+ if (!ok) {
+ if (start < sc->iobase)
+ start = sc->iobase;
+ if (end > sc->iolimit)
+ end = sc->iolimit;
+ }
+ } else {
+ if (start < sc->iobase)
+ printf("start (%lx) < sc->iobase (%x)\n", start,
+ sc->iobase);
+ if (end > sc->iolimit)
+ printf("end (%lx) > sc->iolimit (%x)\n",
+ end, sc->iolimit);
+ if (end < start)
+ printf("end (%lx) < start (%lx)\n", end, start);
+ }
+ }
+ if (end < start) {
+ start = 0;
+ end = 0;
+ ok = 0;
+ }
+ if (!ok) {
+ device_printf(dev, "device %s%d requested unsupported I/O "
+ "range 0x%lx-0x%lx (decoding 0x%x-0x%x)\n",
+ device_get_name(child), device_get_unit(child), start, end,
+ sc->iobase, sc->iolimit);
+ return (NULL);
}
- }
- if (end < start) {
- start = 0;
- end = 0;
- ok = 0;
- }
- if (!ok) {
- device_printf(dev, "device %s%d requested unsupported I/O "
- "range 0x%lx-0x%lx (decoding 0x%x-0x%x)\n",
- device_get_name(child), device_get_unit(child), start, end,
- sc->iobase, sc->iolimit);
- return (NULL);
- }
- if (bootverbose)
- device_printf(sc->dev, "device %s%d requested decoded I/O range 0x%lx-0x%lx\n",
- device_get_name(child), device_get_unit(child), start, end);
- break;
+ if (bootverbose)
+ device_printf(sc->dev, "device %s%d requested decoded I/O range 0x%lx-0x%lx\n",
+ device_get_name(child), device_get_unit(child), start, end);
+ break;
case SYS_RES_MEMORY:
- ok = 1;
- if (!pcib_is_isa_mem(start)) {
- ok = 0;
- if (pcib_is_nonprefetch_open(sc))
- ok = ok || (start >= sc->membase && end <= sc->memlimit);
- if (pcib_is_prefetch_open(sc))
- ok = ok || (start >= sc->pmembase && end <= sc->pmemlimit);
- if (!pci_allow_unsupported_io_range) {
- if (!ok) {
- ok = 1;
- if (flags & RF_PREFETCHABLE) {
- if (pcib_is_prefetch_open(sc)) {
- if (start < sc->pmembase)
- start = sc->pmembase;
- if (end > sc->pmemlimit)
- end = sc->pmemlimit;
- } else {
- ok = 0;
- }
- } else { /* non-prefetchable */
- if (pcib_is_nonprefetch_open(sc)) {
- if (start < sc->membase)
- start = sc->membase;
- if (end > sc->memlimit)
- end = sc->memlimit;
- } else {
- ok = 0;
- }
+ ok = 1;
+ if (!pcib_is_isa_mem(start)) {
+ ok = 0;
+ if (pcib_is_nonprefetch_open(sc))
+ ok = ok || (start >= sc->membase && end <= sc->memlimit);
+ if (pcib_is_prefetch_open(sc))
+ ok = ok || (start >= sc->pmembase && end <= sc->pmemlimit);
+ if (!pci_allow_unsupported_io_range) {
+ if (!ok) {
+ ok = 1;
+ if (flags & RF_PREFETCHABLE) {
+ if (pcib_is_prefetch_open(sc)) {
+ if (start < sc->pmembase)
+ start = sc->pmembase;
+ if (end > sc->pmemlimit)
+ end = sc->pmemlimit;
+ } else {
+ ok = 0;
+ }
+ } else { /* non-prefetchable */
+ if (pcib_is_nonprefetch_open(sc)) {
+ if (start < sc->membase)
+ start = sc->membase;
+ if (end > sc->memlimit)
+ end = sc->memlimit;
+ } else {
+ ok = 0;
+ }
+ }
+ }
+ } else if (!ok) {
+ ok = 1; /* pci_allow_unsupported_ranges -> always ok */
+ if (pcib_is_nonprefetch_open(sc)) {
+ if (start < sc->membase)
+ printf("start (%lx) < sc->membase (%x)\n",
+ start, sc->membase);
+ if (end > sc->memlimit)
+ printf("end (%lx) > sc->memlimit (%x)\n",
+ end, sc->memlimit);
+ }
+ if (pcib_is_prefetch_open(sc)) {
+ if (start < sc->pmembase)
+ printf("start (%lx) < sc->pmembase (%x)\n",
+ start, sc->pmembase);
+ if (end > sc->pmemlimit)
+ printf("end (%lx) > sc->pmemlimit (%x)\n",
+ end, sc->memlimit);
+ }
+ if (end < start)
+ printf("end (%lx) < start (%lx)\n", end, start);
}
- }
- } else if (!ok) {
- ok = 1; /* pci_allow_unsupported_ranges -> always ok */
- if (pcib_is_nonprefetch_open(sc)) {
- if (start < sc->membase)
- printf("start (%lx) < sc->membase (%x)\n",
- start, sc->membase);
- if (end > sc->memlimit)
- printf("end (%lx) > sc->memlimit (%x)\n",
- end, sc->memlimit);
- }
- if (pcib_is_prefetch_open(sc)) {
- if (start < sc->pmembase)
- printf("start (%lx) < sc->pmembase (%x)\n",
- start, sc->pmembase);
- if (end > sc->pmemlimit)
- printf("end (%lx) > sc->pmemlimit (%x)\n",
- end, sc->memlimit);
- }
- if (end < start)
- printf("end (%lx) < start (%lx)\n", end, start);
+ }
+ if (end < start) {
+ start = 0;
+ end = 0;
+ ok = 0;
}
- }
- if (end < start) {
- start = 0;
- end = 0;
- ok = 0;
- }
- if (!ok && bootverbose)
- device_printf(dev,
- "device %s%d requested unsupported memory range "
- "0x%lx-0x%lx (decoding 0x%x-0x%x, 0x%x-0x%x)\n",
- device_get_name(child), device_get_unit(child), start,
- end, sc->membase, sc->memlimit, sc->pmembase,
- sc->pmemlimit);
- if (!ok)
- return (NULL);
- if (bootverbose)
- device_printf(sc->dev, "device %s%d requested decoded memory range 0x%lx-0x%lx\n",
- device_get_name(child), device_get_unit(child), start, end);
- break;
+ if (!ok && bootverbose)
+ device_printf(dev,
+ "device %s%d requested unsupported memory range "
+ "0x%lx-0x%lx (decoding 0x%x-0x%x, 0x%x-0x%x)\n",
+ device_get_name(child), device_get_unit(child), start,
+ end, sc->membase, sc->memlimit, sc->pmembase,
+ sc->pmemlimit);
+ if (!ok)
+ return (NULL);
+ if (bootverbose)
+ device_printf(sc->dev,"device %s%d requested decoded memory range 0x%lx-0x%lx\n",
+ device_get_name(child), device_get_unit(child), start, end);
+ break;
default:
- break;
+ break;
}
- }
-
- /*
- * Bridge is OK decoding this resource, so pass it up.
- */
- return(bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags));
+ /*
+ * Bridge is OK decoding this resource, so pass it up.
+ */
+ return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags));
}
/*
==== //depot/projects/power/sys/dev/pci/pci_private.h#5 (text+ko) ====
==== //depot/projects/power/sys/dev/pci/pci_user.c#4 (text+ko) ====
@@ -429,4 +429,3 @@
return (error);
}
-
==== //depot/projects/power/sys/dev/pci/pcireg.h#4 (text+ko) ====
==== //depot/projects/power/sys/dev/pci/pcivar.h#4 (text+ko) ====
@@ -66,16 +66,12 @@
uint16_t msi_data; /* Location of MSI data word */
};
-/* Additional data saved on power events */
-struct pci_save
-{
- uint32_t bar[7]; /* 7 bars to save */
-};
-
/* config header information common to all header types */
typedef struct pcicfg {
struct device *dev; /* device which owns this */
+ uint32_t bar[PCI_MAXMAPS_0]; /* BARs */
+
uint16_t subvendor; /* card vendor ID */
uint16_t subdevice; /* card device ID, assigned by card vendor */
uint16_t vendor; /* chip vendor ID */
More information about the p4-projects
mailing list