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);