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)
This commit is contained in:
Roger Hardiman 1999-05-31 22:13:37 +00:00
parent dcad3b0027
commit 153eb46fb6
5 changed files with 121 additions and 5 deletions

View File

@ -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)
{

View File

@ -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: pcivar.h,v 1.32 1999/05/18 20:48:38 peter Exp $
* $Id: pcivar.h,v 1.33 1999/05/20 15:33:33 gallatin Exp $
*
*/
@ -185,6 +185,9 @@ vm_offset_t pci_cvt_to_dense (vm_offset_t);
vm_offset_t pci_cvt_to_bwx (vm_offset_t);
#endif /* __alpha__ */
/* low level devlist operations for the 2.2 compatibility code in pci.c */
pcicfgregs * pci_devlist_get_parent(pcicfgregs *cfg);
#ifdef _SYS_BUS_H_
#include "pci_if.h"
@ -325,6 +328,9 @@ int pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
intrmask_t *maskptr, u_int flags);
int pci_unmap_int (pcici_t tag);
pcici_t pci_get_parent_from_tag(pcici_t tag);
int pci_get_bus_from_tag(pcici_t tag);
struct module;
int compat_pci_handler (struct module *, int, void *);
#define COMPAT_PCI_DRIVER(name, pcidata) \

View File

@ -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)
{

View File

@ -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_compat.c,v 1.27 1999/05/10 16:06:32 peter Exp $
* $Id: pci_compat.c,v 1.28 1999/05/11 15:28:38 peter Exp $
*
*/
@ -269,5 +269,17 @@ pci_unmap_int(pcici_t cfg)
return (0); /* not supported, yet, since cfg doesn't know about idesc */
}
pcici_t
pci_get_parent_from_tag(pcici_t tag)
{
return (pcici_t)pci_devlist_get_parent(tag);
}
int
pci_get_bus_from_tag(pcici_t tag)
{
return tag->bus;
}
#endif /* PCI_COMPAT */
#endif /* NPCI > 0 */

View File

@ -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: pcivar.h,v 1.32 1999/05/18 20:48:38 peter Exp $
* $Id: pcivar.h,v 1.33 1999/05/20 15:33:33 gallatin Exp $
*
*/
@ -185,6 +185,9 @@ vm_offset_t pci_cvt_to_dense (vm_offset_t);
vm_offset_t pci_cvt_to_bwx (vm_offset_t);
#endif /* __alpha__ */
/* low level devlist operations for the 2.2 compatibility code in pci.c */
pcicfgregs * pci_devlist_get_parent(pcicfgregs *cfg);
#ifdef _SYS_BUS_H_
#include "pci_if.h"
@ -325,6 +328,9 @@ int pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
intrmask_t *maskptr, u_int flags);
int pci_unmap_int (pcici_t tag);
pcici_t pci_get_parent_from_tag(pcici_t tag);
int pci_get_bus_from_tag(pcici_t tag);
struct module;
int compat_pci_handler (struct module *, int, void *);
#define COMPAT_PCI_DRIVER(name, pcidata) \