pcib allocation failure
John Baldwin
jhb at freebsd.org
Mon Jun 6 14:52:34 UTC 2011
On Saturday, May 28, 2011 9:45:48 pm deeptech71 at gmail.com wrote:
> On Thu, May 26, 2011 at 3:40 PM, John Baldwin <jhb at freebsd.org> wrote:
> > Ohh, you have two devices behind this bridge that have prefetch ranges.
> >
> > As a hack, can you try this:
> >
> > Index: pci_pci.c
> > ===================================================================
> > --- pci_pci.c (revision 222285)
> > +++ pci_pci.c (working copy)
> > @@ -162,8 +162,13 @@ pcib_write_windows(struct pcib_softc *sc, int mask
> > {
> > device_t dev;
> > uint32_t val;
> > + uint16_t cmd;
> >
> > dev = sc->dev;
> > + cmd = pci_read_config(dev, PCIR_COMMAND, 2);
> > + if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN))
> > + pci_write_config(dev, PCIR_COMMAND,
> > + cmd & ~(PCIM_CMD_PORTEN | PCIM_CMD_MEMEN), 2);
> > if (sc->io.valid && mask & WIN_IO) {
> > val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
> > if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
> > @@ -192,6 +197,8 @@ pcib_write_windows(struct pcib_softc *sc, int mask
> > pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2);
> > pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2);
> > }
> > + if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN))
> > + pci_write_config(dev, PCIR_COMMAND, cmd, 2);
> > }
> >
> > static void
> > @@ -337,6 +344,9 @@ pcib_probe_windows(struct pcib_softc *sc)
> > pci_read_config(dev, PCIR_PMLIMITL_1, 2));
> > max = 0xffffffff;
> > }
> > + /* XXX: Testing hack */
> > + if (device_get_unit(sc->sc_dev) == 1)
>
> i'm assuming that "sc->sc_dev" should be "dev" (this fixes a compilation error).
>
> > + sc->pmem.limit = 0xefffffff;
> > pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY,
> > RF_PREFETCHABLE, max);
> > }
>
> that seems to work!
>
> btw, is my machine a test-pig for an upcoming change to the PCI bus driver?
Can you try out this change. It is a possible "real" solution (or at least a
stopgap until we start using multipass to untangle the resource mess a bit
further):
Index: dev/acpica/acpi_pcib_pci.c
===================================================================
--- dev/acpica/acpi_pcib_pci.c (revision 222747)
+++ dev/acpica/acpi_pcib_pci.c (working copy)
@@ -114,13 +114,16 @@
acpi_pcib_pci_attach(device_t dev)
{
struct acpi_pcib_softc *sc;
+ int error;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
pcib_attach_common(dev);
sc = device_get_softc(dev);
sc->ap_handle = acpi_get_handle(dev);
- return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_pcibsc.secbus));
+ error = acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_pcibsc.secbus);
+ pcib_attach_final(dev);
+ return (error);
}
static int
Index: dev/pci/pci_pci.c
===================================================================
--- dev/pci/pci_pci.c (revision 222747)
+++ dev/pci/pci_pci.c (working copy)
@@ -162,8 +162,13 @@
{
device_t dev;
uint32_t val;
+ uint16_t cmd;
dev = sc->dev;
+ cmd = pci_read_config(dev, PCIR_COMMAND, 2);
+ if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN))
+ pci_write_config(dev, PCIR_COMMAND,
+ cmd & ~(PCIM_CMD_PORTEN | PCIM_CMD_MEMEN), 2);
if (sc->io.valid && mask & WIN_IO) {
val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
@@ -192,6 +197,8 @@
pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2);
pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2);
}
+ if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN))
+ pci_write_config(dev, PCIR_COMMAND, cmd, 2);
}
static void
@@ -231,7 +238,7 @@
w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
w->base = max_address;
w->limit = 0;
- pcib_write_windows(sc, w->mask);
+ sc->win_deferred |= w->mask;
return;
}
pcib_activate_window(sc, type);
@@ -690,22 +697,33 @@
*/
}
+void
+pcib_attach_final(device_t dev)
+{
+#ifdef NEW_PCIB
+ struct pcib_softc *sc;
+
+ sc = device_get_softc(dev);
+ if (sc->win_deferred) {
+ pcib_write_windows(sc, sc->win_deferred);
+ sc->win_deferred = 0;
+ }
+#endif
+}
+
int
pcib_attach(device_t dev)
{
struct pcib_softc *sc;
- device_t child;
+ int error;
pcib_attach_common(dev);
sc = device_get_softc(dev);
- if (sc->secbus != 0) {
- child = device_add_child(dev, "pci", sc->secbus);
- if (child != NULL)
- return(bus_generic_attach(dev));
- }
-
- /* no secondary bus; we should have fixed this */
- return(0);
+ if (sc->secbus != 0)
+ device_add_child(dev, "pci", sc->secbus);
+ error = bus_generic_attach(dev);
+ pcib_attach_final(dev);
+ return (error);
}
int
@@ -1020,7 +1038,8 @@
("start address is not aligned"));
KASSERT((w->limit & ((1ul << w->step) - 1)) == (1ul << w->step) - 1,
("end address is not aligned"));
- pcib_write_windows(sc, w->mask);
+ if (!(sc->win_deferred & w->mask))
+ pcib_write_windows(sc, w->mask);
return (0);
}
Index: dev/pci/pcib_private.h
===================================================================
--- dev/pci/pcib_private.h (revision 222747)
+++ dev/pci/pcib_private.h (working copy)
@@ -75,6 +75,7 @@
struct pcib_window io; /* I/O port window */
struct pcib_window mem; /* memory window */
struct pcib_window pmem; /* prefetchable memory window */
+ u_int win_deferred;
#else
pci_addr_t pmembase; /* base address of prefetchable memory */
pci_addr_t pmemlimit; /* topmost address of prefetchable memory */
@@ -94,6 +95,7 @@
int slot, int func, uint8_t *busnum);
int pcib_attach(device_t dev);
void pcib_attach_common(device_t dev);
+void pcib_attach_final(device_t dev);
int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result);
int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
Index: powerpc/ofw/ofw_pcib_pci.c
===================================================================
--- powerpc/ofw/ofw_pcib_pci.c (revision 222747)
+++ powerpc/ofw/ofw_pcib_pci.c (working copy)
@@ -126,6 +126,7 @@
ofw_pcib_pci_attach(device_t dev)
{
struct ofw_pcib_softc *sc;
+ int error;
sc = device_get_softc(dev);
sc->ops_pcib_sc.dev = dev;
@@ -138,7 +139,9 @@
device_add_child(dev, "pci", -1);
- return (bus_generic_attach(dev));
+ error = bus_generic_attach(dev);
+ pcib_attach_final(dev);
+ return (error);
}
static phandle_t
Index: sparc64/pci/ofw_pcib.c
===================================================================
--- sparc64/pci/ofw_pcib.c (revision 222747)
+++ sparc64/pci/ofw_pcib.c (working copy)
@@ -116,6 +116,7 @@
ofw_pcib_attach(device_t dev)
{
struct ofw_pcib_gen_softc *sc;
+ int error;
sc = device_get_softc(dev);
@@ -135,5 +136,7 @@
ofw_pcib_gen_setup(dev);
pcib_attach_common(dev);
device_add_child(dev, "pci", -1);
- return (bus_generic_attach(dev));
+ error = bus_generic_attach(dev);
+ pcib_attach_final(dev);
+ return (error);
}
--
John Baldwin
More information about the freebsd-current
mailing list