We need to iterate all busses in each domain. As it seems,

bus number 1 in domain 1 has the devices we're looking for.
For the busses that are present, the SAL call returns an
non-NULL value for the addr parameter so use that as well
as the status code to determine whether to create a child.

Save the domain, bus number and PROM address in the softc
after assigning the driver to the new device.

This yields:
	...
    pcib0: <SGI PCI-X host controller> on motherboard
    pci0: <PCI bus> on pcib0
    pci0: domain=1, physical bus=1
	...
    pcib1: <SGI PCI-X host controller> on motherboard
    pci1: <PCI bus> on pcib1
    pci1: domain=2, physical bus=1
	...
This commit is contained in:
Marcel Moolenaar 2010-04-17 04:07:38 +00:00
parent 1b1d5788b2
commit 298e9549a4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/altix/; revision=206737

View File

@ -44,10 +44,12 @@ __FBSDID("$FreeBSD$");
#include <machine/sal.h>
#include <machine/sgisn.h>
static struct sgisn_hub sgisn_pcib_hub;
static struct sgisn_hub sgisn_hub;
struct sgisn_pcib_softc {
device_t sc_dev;
void *sc_promaddr;
u_int sc_domain;
u_int sc_busnr;
};
@ -113,12 +115,13 @@ static uint32_t
sgisn_pcib_cfgread(device_t dev, u_int bus, u_int slot, u_int func,
u_int reg, int bytes)
{
u_int domain = device_get_unit(dev);
struct sgisn_pcib_softc *sc;
uint32_t val;
device_printf(dev, "%u:%u:%u: reg=%u", bus, slot, func, reg);
val = pci_cfgregread(domain << 8 | bus, slot, func, reg, bytes);
printf(" -> %u (%u bytes)\n", val, bytes);
sc = device_get_softc(dev);
val = pci_cfgregread((sc->sc_domain << 8) | bus, slot, func, reg,
bytes);
return (val);
}
@ -126,39 +129,46 @@ static void
sgisn_pcib_cfgwrite(device_t dev, u_int bus, u_int slot, u_int func,
u_int reg, uint32_t val, int bytes)
{
u_int domain = device_get_unit(dev);
struct sgisn_pcib_softc *sc;
device_printf(dev, "%u:%u:%u: reg=%u <- %u (%u bytes)\n", bus, slot,
func, reg, val, bytes);
pci_cfgregwrite(domain << 8 | bus, slot, func, reg, val, bytes);
sc = device_get_softc(dev);
pci_cfgregwrite((sc->sc_domain << 8) | bus, slot, func, reg, val,
bytes);
}
static void
sgisn_pcib_identify(driver_t *drv, device_t bus)
{
struct ia64_sal_result r;
device_t dev;
struct sgisn_pcib_softc *sc;
void *addr;
u_int seg;
u_int busno, segno;
sgisn_pcib_hub.hub_pci_maxseg = 0xffffffff;
sgisn_pcib_hub.hub_pci_maxbus = 0xff;
sgisn_hub.hub_pci_maxseg = 0xffffffff;
sgisn_hub.hub_pci_maxbus = 0xff;
r = ia64_sal_entry(SAL_SGISN_IOHUB_INFO, PCPU_GET(md.sgisn_nasid),
ia64_tpa((uintptr_t)&sgisn_pcib_hub), 0, 0, 0, 0, 0);
ia64_tpa((uintptr_t)&sgisn_hub), 0, 0, 0, 0, 0);
if (r.sal_status != 0)
return;
printf("XXX: %s: maxseg=%u, maxbus=%u\n", __func__,
sgisn_pcib_hub.hub_pci_maxseg, sgisn_pcib_hub.hub_pci_maxbus);
for (segno = 0; segno <= sgisn_hub.hub_pci_maxseg; segno++) {
for (busno = 0; busno <= sgisn_hub.hub_pci_maxbus; busno++) {
r = ia64_sal_entry(SAL_SGISN_IOBUS_INFO, segno, busno,
ia64_tpa((uintptr_t)&addr), 0, 0, 0, 0);
for (seg = 0; seg <= sgisn_pcib_hub.hub_pci_maxseg; seg++) {
r = ia64_sal_entry(SAL_SGISN_IOBUS_INFO, seg, 0,
ia64_tpa((uintptr_t)&addr), 0, 0, 0, 0);
printf("XXX: %s: seg=%u: stat=%#lx, addr=%p\n", __func__, seg,
r.sal_status, addr);
if (r.sal_status == 0)
BUS_ADD_CHILD(bus, 100 + seg, drv->name, seg);
if (r.sal_status == 0 && addr != NULL) {
dev = BUS_ADD_CHILD(bus, 0, drv->name, -1);
if (dev == NULL)
continue;
device_set_driver(dev, drv);
sc = device_get_softc(dev);
sc->sc_promaddr = addr;
sc->sc_domain = segno;
sc->sc_busnr = busno;
}
}
}
}
@ -192,7 +202,7 @@ sgisn_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *res)
*res = sc->sc_busnr;
return (0);
case PCIB_IVAR_DOMAIN:
*res = device_get_unit(dev);
*res = sc->sc_domain;
return (0);
}
return (ENOENT);