diff options
author | roger <roger@FreeBSD.org> | 1999-05-31 22:13:37 +0000 |
---|---|---|
committer | roger <roger@FreeBSD.org> | 1999-05-31 22:13:37 +0000 |
commit | 4d37f3729be0a83ecedc31dfe8b0811bdf1bcfd2 (patch) | |
tree | 914bbff488d9b51275d2629f388e23048b220b2f /sys/pci/pci.c | |
parent | d17fc0888d6a250d427fdecad8c383a01d53df57 (diff) | |
download | FreeBSD-src-4d37f3729be0a83ecedc31dfe8b0811bdf1bcfd2.zip FreeBSD-src-4d37f3729be0a83ecedc31dfe8b0811bdf1bcfd2.tar.gz |
On the new Meteor cards, the Philips SAA 7116 is connected to the PCI bus
via an IBM PCI-PCI bridge (82351 or 82352 or 82353)
The driver must identify if it is on a secondary PCI bus, which is
created via the IBM PCI-PCI bridge. If it is, then it must initialise
the IBM PCI-PCI bridge correctly.
To do this, the following new functions are added.
Because they use the pcici_t tag, they are considered 2.2 compatibility APIs
pcici_t * pci_get_parent_from_tag(pcici_t tag);
int pci_get_bus_from_tag(pcici_t tag);
(The _from_tag suffix is used to prevent clashes with similarly named
newbus PCI API functions)
Submitted by: Anton Berezin <tobez@plab.ku.dk>
Reviewed by: Doug Rabson <dfr@nlsystems.com>
Reworked by: Me (roger)
Diffstat (limited to 'sys/pci/pci.c')
-rw-r--r-- | sys/pci/pci.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/sys/pci/pci.c b/sys/pci/pci.c index 8bc9c1d..2c86832 100644 --- a/sys/pci/pci.c +++ b/sys/pci/pci.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pci.c,v 1.106 1999/05/30 16:53:36 phk Exp $ + * $Id: pci.c,v 1.107 1999/05/31 11:29:01 phk Exp $ * */ @@ -555,6 +555,52 @@ pci_conf_match(struct pci_match_conf *matches, int num_matches, return(1); } +/* + * Locate the parent of a PCI device by scanning the PCI devlist + * and return the entry for the parent. + * For devices on PCI Bus 0 (the host bus), this is the PCI Host. + * For devices on secondary PCI busses, this is that bus' PCI-PCI Bridge. + */ + +pcicfgregs * +pci_devlist_get_parent(pcicfgregs *cfg) +{ + struct devlist *devlist_head; + struct pci_devinfo *dinfo; + pcicfgregs *bridge_cfg; + int i; + + dinfo = STAILQ_FIRST(devlist_head = &pci_devq); + + /* If the device is on PCI bus 0, look for the host */ + if (cfg->bus == 0) { + for (i = 0; (dinfo != NULL) && (i < pci_numdevs); + dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { + bridge_cfg = &dinfo->cfg; + if (bridge_cfg->baseclass == PCIC_BRIDGE + && bridge_cfg->subclass == PCIS_BRIDGE_HOST + && bridge_cfg->bus == cfg->bus) { + return bridge_cfg; + } + } + } + + /* If the device is not on PCI bus 0, look for the PCI-PCI bridge */ + if (cfg->bus > 0) { + for (i = 0; (dinfo != NULL) && (i < pci_numdevs); + dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { + bridge_cfg = &dinfo->cfg; + if (bridge_cfg->baseclass == PCIC_BRIDGE + && bridge_cfg->subclass == PCIS_BRIDGE_PCI + && bridge_cfg->secondarybus == cfg->bus) { + return bridge_cfg; + } + } + } + + return NULL; +} + static int pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { |