Subject: pci_bus_devorder() & pci_dev_funcorder().
To: None <tech-kern@netbsd.org>
From: matthew green <mrg@eterna.com.au>
List: tech-kern
Date: 02/28/2001 00:37:58
hi folks.
to solve the `want to control PCI bus probe ordering' problem, i have
come up with the following patch after discussion with cgd. it implements
two new interfaces for the MD PCI code:
int pci_bus_devorder(pci_chipset_tag_t, int bus, char list[32]);
int pci_dev_funcorder(pci_chipset_tag_t, int bus, int dev, char list[8]);
devorder returns a list of values (from -1 to 31) in an array of char's,
and the PCI probe code probdes this list of devices until either the end
of the list or -1 is reached. funcorder is the same, except from -1 to 7.
initially, i plan on switching these functions over separately and with
preprocessor symbols to declare their presence. this interface is
intended to replace the pci_bus_maxdevs() interface, but until all MD
PCI code is updated, and all current callers of pci_bus_maxdev() are
converted, both shall exist. i plan on doing the bulk of this work
myself (but hope to have testers for code i can not test personally.)
the following patch to sys/dev/pci.c allows my ultra5 to probe it's
devices in the correct order (given an <machine/pci_machdep.h> that
provides __PCI_BUS_DEVORDER & __PCI_DEV_FUNCORDER, not included in
this patch). it fixes only one caller of pci_bus_maxdevs() (most
of the others are MD.)
OK to commit? (i will of course provide documentation for both
these functions.)
Index: pci.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/pci.c,v
retrieving revision 1.50
diff -p -r1.50 pci.c
*** pci.c 2001/02/12 09:14:53 1.50
--- pci.c 2001/02/27 13:25:43
*************** pci_probe_bus(self)
*** 134,148 ****
bus_space_tag_t iot, memt;
pci_chipset_tag_t pc;
const struct pci_quirkdata *qd;
! int bus, device, maxndevs, function, nfunctions;
iot = sc->sc_iot;
memt = sc->sc_memt;
pc = sc->sc_pc;
bus = sc->sc_bus;
! maxndevs = sc->sc_maxndevs;
!
! for (device = 0; device < maxndevs; device++) {
pcitag_t tag;
pcireg_t id, class, intr, bhlcr, csr;
struct pci_attach_args pa;
--- 134,160 ----
bus_space_tag_t iot, memt;
pci_chipset_tag_t pc;
const struct pci_quirkdata *qd;
! int bus, device, function, nfunctions;
! #ifdef __PCI_BUS_DEVORDER
! char devs[32];
! int i;
! #endif
! #ifdef __PCI_DEV_FUNCORDER
! char funcs[8];
! int j;
! #endif
iot = sc->sc_iot;
memt = sc->sc_memt;
pc = sc->sc_pc;
bus = sc->sc_bus;
! #ifdef __PCI_BUS_DEVORDER
! pci_bus_devorder(sc->sc_pc, sc->sc_bus, devs);
! for (i = 0; (device = devs[i]) < 32 && device >= 0; i++)
! #else
! for (device = 0; device < sc->sc_maxndevs; device++)
! #endif
! {
pcitag_t tag;
pcireg_t id, class, intr, bhlcr, csr;
struct pci_attach_args pa;
*************** pci_probe_bus(self)
*** 168,174 ****
else
nfunctions = 1;
! for (function = 0; function < nfunctions; function++) {
tag = pci_make_tag(pc, bus, device, function);
id = pci_conf_read(pc, tag, PCI_ID_REG);
csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
--- 180,193 ----
else
nfunctions = 1;
! #ifdef __PCI_DEV_FUNCORDER
! pci_dev_funcorder(sc->sc_pc, sc->sc_bus, device, funcs);
! for (j = 0; (function = funcs[j]) < nfunctions &&
! function >= 0; j++)
! #else
! for (function = 0; function < nfunctions; function++)
! #endif
! {
tag = pci_make_tag(pc, bus, device, function);
id = pci_conf_read(pc, tag, PCI_ID_REG);
csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);