summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-04-15 03:42:12 +0000
committerjhb <jhb@FreeBSD.org>2016-04-15 03:42:12 +0000
commit784a797eede7e9e2ee3e82efedc1fc47547ca85b (patch)
treef27f63561d0afda441fc0921b7455bd4dce5e730
parentde393d2ab18de0224c30483ed700a7388058f4e9 (diff)
downloadFreeBSD-src-784a797eede7e9e2ee3e82efedc1fc47547ca85b.zip
FreeBSD-src-784a797eede7e9e2ee3e82efedc1fc47547ca85b.tar.gz
Add a new PCI bus interface method to alloc the ivars (dinfo) for a device.
The ACPI and OFW PCI bus drivers as well as CardBus override this to allocate the larger ivars to hold additional info beyond the stock PCI ivars. This removes the need to pass the size to functions like pci_add_iov_child() and pci_read_device() simplifying IOV and bus rescanning implementations. As a result of this and earlier changes, the ACPI PCI bus driver no longer needs its own device_attach and pci_create_iov_child methods but can use the methods in the stock PCI bus driver instead. Differential Revision: https://reviews.freebsd.org/D5891
-rw-r--r--sys/dev/acpica/acpi_pci.c77
-rw-r--r--sys/dev/cardbus/cardbus.c15
-rw-r--r--sys/dev/pci/pci.c62
-rw-r--r--sys/dev/pci/pci_if.m4
-rw-r--r--sys/dev/pci/pci_iov.c2
-rw-r--r--sys/dev/pci/pci_private.h12
-rw-r--r--sys/dev/pci/pcivar.h1
-rw-r--r--sys/mips/nlm/xlp_pci.c4
-rw-r--r--sys/powerpc/ofw/ofw_pcibus.c17
-rw-r--r--sys/sparc64/pci/ofw_pcibus.c19
10 files changed, 103 insertions, 110 deletions
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
index 1dee131..44b5804 100644
--- a/sys/dev/acpica/acpi_pci.c
+++ b/sys/dev/acpica/acpi_pci.c
@@ -70,7 +70,7 @@ CTASSERT(ACPI_STATE_D1 == PCI_POWERSTATE_D1);
CTASSERT(ACPI_STATE_D2 == PCI_POWERSTATE_D2);
CTASSERT(ACPI_STATE_D3 == PCI_POWERSTATE_D3);
-static int acpi_pci_attach(device_t dev);
+static struct pci_devinfo *acpi_pci_alloc_devinfo(device_t dev);
static void acpi_pci_child_deleted(device_t dev, device_t child);
static int acpi_pci_child_location_str_method(device_t cbdev,
device_t child, char *buf, size_t buflen);
@@ -86,15 +86,9 @@ static int acpi_pci_set_powerstate_method(device_t dev, device_t child,
static void acpi_pci_update_device(ACPI_HANDLE handle, device_t pci_child);
static bus_dma_tag_t acpi_pci_get_dma_tag(device_t bus, device_t child);
-#ifdef PCI_IOV
-static device_t acpi_pci_create_iov_child(device_t bus, device_t pf,
- uint16_t rid, uint16_t vid, uint16_t did);
-#endif
-
static device_method_t acpi_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, acpi_pci_probe),
- DEVMETHOD(device_attach, acpi_pci_attach),
/* Bus interface */
DEVMETHOD(bus_read_ivar, acpi_pci_read_ivar),
@@ -105,11 +99,9 @@ static device_method_t acpi_pci_methods[] = {
DEVMETHOD(bus_get_domain, acpi_get_domain),
/* PCI interface */
+ DEVMETHOD(pci_alloc_devinfo, acpi_pci_alloc_devinfo),
DEVMETHOD(pci_child_added, acpi_pci_child_added),
DEVMETHOD(pci_set_powerstate, acpi_pci_set_powerstate_method),
-#ifdef PCI_IOV
- DEVMETHOD(pci_create_iov_child, acpi_pci_create_iov_child),
-#endif
DEVMETHOD_END
};
@@ -123,6 +115,15 @@ MODULE_DEPEND(acpi_pci, acpi, 1, 1, 1);
MODULE_DEPEND(acpi_pci, pci, 1, 1, 1);
MODULE_VERSION(acpi_pci, 1);
+static struct pci_devinfo *
+acpi_pci_alloc_devinfo(device_t dev)
+{
+ struct acpi_pci_devinfo *dinfo;
+
+ dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
+ return (&dinfo->ap_dinfo);
+}
+
static int
acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
@@ -298,38 +299,6 @@ void
acpi_pci_child_added(device_t dev, device_t child)
{
- AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
- acpi_pci_save_handle, NULL, child, NULL);
-}
-
-static int
-acpi_pci_probe(device_t dev)
-{
-
- if (acpi_get_handle(dev) == NULL)
- return (ENXIO);
- device_set_desc(dev, "ACPI PCI bus");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-acpi_pci_attach(device_t dev)
-{
- int busno, domain, error;
-
- error = pci_attach_common(dev);
- if (error)
- return (error);
-
- /*
- * Since there can be multiple independantly numbered PCI
- * busses on systems with multiple PCI domains, we can't use
- * the unit number to decide which bus we are probing. We ask
- * the parent pcib what our domain and bus numbers are.
- */
- domain = pcib_get_domain(dev);
- busno = pcib_get_bus(dev);
-
/*
* PCI devices are added via the bus scan in the normal PCI
* bus driver. As each device is added, the
@@ -342,9 +311,18 @@ acpi_pci_attach(device_t dev)
* pci_add_children() doesn't find. We currently just ignore
* these devices.
*/
- pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
+ AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
+ acpi_pci_save_handle, NULL, child, NULL);
+}
+
+static int
+acpi_pci_probe(device_t dev)
+{
- return (bus_generic_attach(dev));
+ if (acpi_get_handle(dev) == NULL)
+ return (ENXIO);
+ device_set_desc(dev, "ACPI PCI bus");
+ return (BUS_PROBE_DEFAULT);
}
#ifdef ACPI_DMAR
@@ -372,14 +350,3 @@ acpi_pci_get_dma_tag(device_t bus, device_t child)
}
#endif
-#ifdef PCI_IOV
-static device_t
-acpi_pci_create_iov_child(device_t bus, device_t pf, uint16_t rid, uint16_t vid,
- uint16_t did)
-{
-
- return (pci_add_iov_child(bus, pf, sizeof(struct acpi_pci_devinfo), rid,
- vid, did));
-}
-#endif
-
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c
index e785b0f..a6037e1 100644
--- a/sys/dev/cardbus/cardbus.c
+++ b/sys/dev/cardbus/cardbus.c
@@ -169,6 +169,15 @@ cardbus_device_setup_regs(pcicfgregs *cfg)
pci_write_config(dev, PCIR_MAXLAT, 0x14, 1);
}
+static struct pci_devinfo *
+cardbus_alloc_devinfo(device_t dev)
+{
+ struct cardbus_devinfo *dinfo;
+
+ dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
+ return (&dinfo->pci);
+}
+
static int
cardbus_attach_card(device_t cbdev)
{
@@ -191,8 +200,7 @@ cardbus_attach_card(device_t cbdev)
struct cardbus_devinfo *dinfo;
dinfo = (struct cardbus_devinfo *)
- pci_read_device(brdev, domain, bus, slot, func,
- sizeof(struct cardbus_devinfo));
+ pci_read_device(brdev, cbdev, domain, bus, slot, func);
if (dinfo == NULL)
continue;
if (dinfo->pci.cfg.mfdev)
@@ -343,6 +351,9 @@ static device_method_t cardbus_methods[] = {
DEVMETHOD(card_attach_card, cardbus_attach_card),
DEVMETHOD(card_detach_card, cardbus_detach_card),
+ /* PCI interface */
+ DEVMETHOD(pci_alloc_devinfo, cardbus_alloc_devinfo),
+
{0,0}
};
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index fbe9abd..273ab4b 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -126,8 +126,8 @@ static int pci_remap_intr_method(device_t bus, device_t dev,
static uint16_t pci_get_rid_method(device_t dev, device_t child);
-static struct pci_devinfo * pci_fill_devinfo(device_t pcib, int d, int b, int s,
- int f, uint16_t vid, uint16_t did, size_t size);
+static struct pci_devinfo * pci_fill_devinfo(device_t pcib, device_t bus, int d,
+ int b, int s, int f, uint16_t vid, uint16_t did);
static device_method_t pci_methods[] = {
/* Device interface */
@@ -196,6 +196,7 @@ static device_method_t pci_methods[] = {
DEVMETHOD(pci_msix_pba_bar, pci_msix_pba_bar_method),
DEVMETHOD(pci_msix_table_bar, pci_msix_table_bar_method),
DEVMETHOD(pci_get_rid, pci_get_rid_method),
+ DEVMETHOD(pci_alloc_devinfo, pci_alloc_devinfo_method),
DEVMETHOD(pci_child_added, pci_child_added_method),
#ifdef PCI_IOV
DEVMETHOD(pci_iov_attach, pci_iov_attach_method),
@@ -619,7 +620,7 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
/* read configuration header into pcicfgregs structure */
struct pci_devinfo *
-pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size)
+pci_read_device(device_t pcib, device_t bus, int d, int b, int s, int f)
{
#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w)
uint16_t vid, did;
@@ -627,19 +628,27 @@ pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size)
vid = REG(PCIR_VENDOR, 2);
did = REG(PCIR_DEVICE, 2);
if (vid != 0xffff)
- return (pci_fill_devinfo(pcib, d, b, s, f, vid, did, size));
+ return (pci_fill_devinfo(pcib, bus, d, b, s, f, vid, did));
return (NULL);
}
+struct pci_devinfo *
+pci_alloc_devinfo_method(device_t dev)
+{
+
+ return (malloc(sizeof(struct pci_devinfo), M_DEVBUF,
+ M_WAITOK | M_ZERO));
+}
+
static struct pci_devinfo *
-pci_fill_devinfo(device_t pcib, int d, int b, int s, int f, uint16_t vid,
- uint16_t did, size_t size)
+pci_fill_devinfo(device_t pcib, device_t bus, int d, int b, int s, int f,
+ uint16_t vid, uint16_t did)
{
struct pci_devinfo *devlist_entry;
pcicfgregs *cfg;
- devlist_entry = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
+ devlist_entry = PCI_ALLOC_DEVINFO(bus);
cfg = &devlist_entry->cfg;
@@ -665,7 +674,6 @@ pci_fill_devinfo(device_t pcib, int d, int b, int s, int f, uint16_t vid,
cfg->hdrtype &= ~PCIM_MFDEV;
STAILQ_INIT(&cfg->maps);
- cfg->devinfo_size = size;
cfg->iov = NULL;
pci_fixancient(cfg);
@@ -3854,11 +3862,11 @@ pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask)
static struct pci_devinfo *
pci_identify_function(device_t pcib, device_t dev, int domain, int busno,
- int slot, int func, size_t dinfo_size)
+ int slot, int func)
{
struct pci_devinfo *dinfo;
- dinfo = pci_read_device(pcib, domain, busno, slot, func, dinfo_size);
+ dinfo = pci_read_device(pcib, dev, domain, busno, slot, func);
if (dinfo != NULL)
pci_add_child(dev, dinfo);
@@ -3866,7 +3874,7 @@ pci_identify_function(device_t pcib, device_t dev, int domain, int busno,
}
void
-pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size)
+pci_add_children(device_t dev, int domain, int busno)
{
#define REG(n, w) PCIB_READ_CONFIG(pcib, busno, s, f, n, w)
device_t pcib = device_get_parent(dev);
@@ -3882,8 +3890,7 @@ pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size)
* functions on this bus as ARI changes the set of slots and functions
* that are legal on this bus.
*/
- dinfo = pci_identify_function(pcib, dev, domain, busno, 0, 0,
- dinfo_size);
+ dinfo = pci_identify_function(pcib, dev, domain, busno, 0, 0);
if (dinfo != NULL && pci_enable_ari)
PCIB_TRY_ENABLE_ARI(pcib, dinfo->cfg.dev);
@@ -3893,8 +3900,6 @@ pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size)
*/
first_func = 1;
- KASSERT(dinfo_size >= sizeof(struct pci_devinfo),
- ("dinfo_size too small"));
maxslots = PCIB_MAXSLOTS(pcib);
for (s = 0; s <= maxslots; s++, first_func = 0) {
pcifunchigh = 0;
@@ -3906,16 +3911,15 @@ pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size)
if (hdrtype & PCIM_MFDEV)
pcifunchigh = PCIB_MAXFUNCS(pcib);
for (f = first_func; f <= pcifunchigh; f++)
- pci_identify_function(pcib, dev, domain, busno, s, f,
- dinfo_size);
+ pci_identify_function(pcib, dev, domain, busno, s, f);
}
#undef REG
}
#ifdef PCI_IOV
device_t
-pci_add_iov_child(device_t bus, device_t pf, size_t size, uint16_t rid,
- uint16_t vid, uint16_t did)
+pci_add_iov_child(device_t bus, device_t pf, uint16_t rid, uint16_t vid,
+ uint16_t did)
{
struct pci_devinfo *pf_dinfo, *vf_dinfo;
device_t pcib;
@@ -3923,23 +3927,12 @@ pci_add_iov_child(device_t bus, device_t pf, size_t size, uint16_t rid,
pf_dinfo = device_get_ivars(pf);
- /*
- * Do a sanity check that we have been passed the correct size. If this
- * test fails then likely the pci subclass hasn't implemented the
- * pci_create_iov_child method like it's supposed it.
- */
- if (size != pf_dinfo->cfg.devinfo_size) {
- device_printf(pf,
- "PCI subclass does not properly implement PCI_IOV\n");
- return (NULL);
- }
-
pcib = device_get_parent(bus);
PCIB_DECODE_RID(pcib, rid, &busno, &slot, &func);
- vf_dinfo = pci_fill_devinfo(pcib, pci_get_domain(pcib), busno, slot, func,
- vid, did, size);
+ vf_dinfo = pci_fill_devinfo(pcib, bus, pci_get_domain(pcib), busno,
+ slot, func, vid, did);
vf_dinfo->cfg.flags |= PCICFG_VF;
pci_add_child(bus, vf_dinfo);
@@ -3952,8 +3945,7 @@ pci_create_iov_child_method(device_t bus, device_t pf, uint16_t rid,
uint16_t vid, uint16_t did)
{
- return (pci_add_iov_child(bus, pf, sizeof(struct pci_devinfo), rid, vid,
- did));
+ return (pci_add_iov_child(bus, pf, rid, vid, did));
}
#endif
@@ -4050,7 +4042,7 @@ pci_attach(device_t dev)
*/
domain = pcib_get_domain(dev);
busno = pcib_get_bus(dev);
- pci_add_children(dev, domain, busno, sizeof(struct pci_devinfo));
+ pci_add_children(dev, domain, busno);
return (bus_generic_attach(dev));
}
diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m
index 7049b9f..da80305 100644
--- a/sys/dev/pci/pci_if.m
+++ b/sys/dev/pci/pci_if.m
@@ -213,6 +213,10 @@ METHOD uint16_t get_rid {
device_t child;
};
+METHOD struct pci_devinfo * alloc_devinfo {
+ device_t dev;
+};
+
METHOD void child_added {
device_t dev;
device_t child;
diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c
index d216557..287f5a2 100644
--- a/sys/dev/pci/pci_iov.c
+++ b/sys/dev/pci/pci_iov.c
@@ -600,14 +600,12 @@ pci_iov_enumerate_vfs(struct pci_devinfo *dinfo, const nvlist_t *config,
device_t bus, dev, vf;
struct pcicfg_iov *iov;
struct pci_devinfo *vfinfo;
- size_t size;
int i, error;
uint16_t vid, did, next_rid;
iov = dinfo->cfg.iov;
dev = dinfo->cfg.dev;
bus = device_get_parent(dev);
- size = dinfo->cfg.devinfo_size;
next_rid = first_rid;
vid = pci_get_vendor(dev);
did = IOV_READ(dinfo, PCIR_SRIOV_VF_DID, 2);
diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h
index e11dcfa..222ffb8 100644
--- a/sys/dev/pci/pci_private.h
+++ b/sys/dev/pci/pci_private.h
@@ -48,14 +48,14 @@ struct pci_softc {
extern int pci_do_power_resume;
extern int pci_do_power_suspend;
-void pci_add_children(device_t dev, int domain, int busno,
- size_t dinfo_size);
+void pci_add_children(device_t dev, int domain, int busno);
void pci_add_child(device_t bus, struct pci_devinfo *dinfo);
-device_t pci_add_iov_child(device_t bus, device_t pf, size_t dinfo_size,
- uint16_t rid, uint16_t vid, uint16_t did);
+device_t pci_add_iov_child(device_t bus, device_t pf, uint16_t rid,
+ uint16_t vid, uint16_t did);
void pci_add_resources(device_t bus, device_t dev, int force,
uint32_t prefetchmask);
void pci_add_resources_ea(device_t bus, device_t dev, int alloc_iov);
+struct pci_devinfo *pci_alloc_devinfo_method(device_t dev);
int pci_attach_common(device_t dev);
void pci_driver_added(device_t dev, driver_t *driver);
int pci_ea_is_enabled(device_t dev, int rid);
@@ -117,8 +117,8 @@ int pci_deactivate_resource(device_t dev, device_t child, int type,
void pci_delete_resource(device_t dev, device_t child,
int type, int rid);
struct resource_list *pci_get_resource_list (device_t dev, device_t child);
-struct pci_devinfo *pci_read_device(device_t pcib, int d, int b, int s, int f,
- size_t size);
+struct pci_devinfo *pci_read_device(device_t pcib, device_t bus, int d, int b,
+ int s, int f);
void pci_print_verbose(struct pci_devinfo *dinfo);
int pci_freecfg(struct pci_devinfo *dinfo);
void pci_child_deleted(device_t dev, device_t child);
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index c829292..8d9ea7e 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -209,7 +209,6 @@ typedef struct pcicfg {
uint8_t func; /* config space function number */
uint32_t flags; /* flags defined above */
- size_t devinfo_size; /* Size of devinfo for this bus type. */
struct pcicfg_bridge bridge; /* Bridges */
struct pcicfg_pp pp; /* Power management */
diff --git a/sys/mips/nlm/xlp_pci.c b/sys/mips/nlm/xlp_pci.c
index 863c6aa..9e91146 100644
--- a/sys/mips/nlm/xlp_pci.c
+++ b/sys/mips/nlm/xlp_pci.c
@@ -125,8 +125,8 @@ xlp_pci_attach(device_t dev)
XLP_PCI_DEVSCRATCH_REG0 << 2,
(1 << 8) | irq, 4);
}
- dinfo = pci_read_device(pcib, pcib_get_domain(dev),
- busno, s, f, sizeof(*dinfo));
+ dinfo = pci_read_device(pcib, dev, pcib_get_domain(dev),
+ busno, s, f);
pci_add_child(dev, dinfo);
}
}
diff --git a/sys/powerpc/ofw/ofw_pcibus.c b/sys/powerpc/ofw/ofw_pcibus.c
index 4ce6e73..01e2343 100644
--- a/sys/powerpc/ofw/ofw_pcibus.c
+++ b/sys/powerpc/ofw/ofw_pcibus.c
@@ -59,6 +59,7 @@ typedef uint32_t ofw_pci_intr_t;
/* Methods */
static device_probe_t ofw_pcibus_probe;
static device_attach_t ofw_pcibus_attach;
+static pci_alloc_devinfo_t ofw_pcibus_alloc_devinfo;
static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
static bus_child_deleted_t ofw_pcibus_child_deleted;
@@ -78,6 +79,7 @@ static device_method_t ofw_pcibus_methods[] = {
DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_child_pnpinfo_str_method),
/* PCI interface */
+ DEVMETHOD(pci_alloc_devinfo, ofw_pcibus_alloc_devinfo),
DEVMETHOD(pci_assign_interrupt, ofw_pcibus_assign_interrupt),
/* ofw_bus interface */
@@ -144,6 +146,15 @@ ofw_pcibus_attach(device_t dev)
return (bus_generic_attach(dev));
}
+struct pci_devinfo *
+ofw_pcibus_alloc_devinfo(device_t dev)
+{
+ struct ofw_pcibus_devinfo *dinfo;
+
+ dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
+ return (&dinfo->opd_dinfo);
+}
+
static void
ofw_pcibus_enum_devtree(device_t dev, u_int domain, u_int busno)
{
@@ -185,8 +196,8 @@ ofw_pcibus_enum_devtree(device_t dev, u_int domain, u_int busno)
* to the PCI bus.
*/
- dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
- domain, busno, slot, func, sizeof(*dinfo));
+ dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, dev,
+ domain, busno, slot, func);
if (dinfo == NULL)
continue;
if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
@@ -244,7 +255,7 @@ ofw_pcibus_enum_bus(device_t dev, u_int domain, u_int busno)
continue;
dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(
- pcib, domain, busno, s, f, sizeof(*dinfo));
+ pcib, dev, domain, busno, s, f);
if (dinfo == NULL)
continue;
diff --git a/sys/sparc64/pci/ofw_pcibus.c b/sys/sparc64/pci/ofw_pcibus.c
index 08ffa5d..11f19cf 100644
--- a/sys/sparc64/pci/ofw_pcibus.c
+++ b/sys/sparc64/pci/ofw_pcibus.c
@@ -70,6 +70,7 @@ static bus_child_pnpinfo_str_t ofw_pcibus_pnpinfo_str;
static device_attach_t ofw_pcibus_attach;
static device_probe_t ofw_pcibus_probe;
static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
+static pci_alloc_devinfo_t ofw_pcibus_alloc_devinfo;
static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
static device_method_t ofw_pcibus_methods[] = {
@@ -82,6 +83,7 @@ static device_method_t ofw_pcibus_methods[] = {
DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_pnpinfo_str),
/* PCI interface */
+ DEVMETHOD(pci_alloc_devinfo, ofw_pcibus_alloc_devinfo),
DEVMETHOD(pci_assign_interrupt, ofw_pcibus_assign_interrupt),
/* ofw_bus interface */
@@ -250,8 +252,8 @@ ofw_pcibus_attach(device_t dev)
if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 &&
ofw_bus_get_type(pcib) != NULL &&
strcmp(ofw_bus_get_type(pcib), OFW_TYPE_PCIE) != 0 &&
- (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
- domain, busno, 0, 0, sizeof(*dinfo))) != NULL) {
+ (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, dev,
+ domain, busno, 0, 0)) != NULL) {
if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0)
pci_freecfg((struct pci_devinfo *)dinfo);
else
@@ -270,8 +272,8 @@ ofw_pcibus_attach(device_t dev)
if (pci_find_dbsf(domain, busno, slot, func) != NULL)
continue;
ofw_pcibus_setup_device(pcib, clock, busno, slot, func);
- dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
- domain, busno, slot, func, sizeof(*dinfo));
+ dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, dev,
+ domain, busno, slot, func);
if (dinfo == NULL)
continue;
if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
@@ -286,6 +288,15 @@ ofw_pcibus_attach(device_t dev)
return (bus_generic_attach(dev));
}
+struct pci_devinfo *
+ofw_pcibus_alloc_devinfo(device_t dev)
+{
+ struct ofw_pcibus_devinfo *dinfo;
+
+ dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
+ return (&dinfo->opd_dinfo);
+}
+
static int
ofw_pcibus_assign_interrupt(device_t dev, device_t child)
{
OpenPOWER on IntegriCloud