/* Each PCI controller found gets a unique index. */
int pci_num_controllers = 0;
-/* Given an 8-bit PCI bus number, this yields the
- * controlling PBM module info.
- *
- * Some explanation is in order here. The Linux APIs for
- * the PCI subsystem require that the configuration space
- * types are enough to signify PCI configuration space
- * accesses correctly. This gives us 8-bits for the bus
- * number, however we have multiple PCI controllers on
- * UltraSparc systems.
- *
- * So what we do is give the PCI busses under each controller
- * a unique portion of the 8-bit PCI bus number space.
- * Therefore one can obtain the controller from the bus
- * number. For example, say PSYCHO PBM-A a subordinate bus
- * space of 0 to 4, and PBM-B has a space of 0 to 2. PBM-A
- * will use 0 to 4, and PBM-B will use 5 to 7.
- */
-struct pci_pbm_info *pci_bus2pbm[256];
-unsigned char pci_highest_busnum = 0;
-
/* At boot time the user can give the kernel a command
* line option which controls if and how PCI devices
* are reordered at PCI bus probing time.
pbus->resource[1] = &pbm->mem_space;
}
-/* NOTE: This can get called before we've fixed up pdev->sysdata. */
int pci_claim_resource(struct pci_dev *pdev, int resource)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
+ struct pci_pbm_info *pbm = pdev->bus->sysdata;
struct resource *res = &pdev->resource[resource];
struct resource *root;
void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region,
struct resource *res)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
+ struct pci_pbm_info *pbm = pdev->bus->sysdata;
struct resource zero_res, *root;
zero_res.start = 0;
void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
struct pci_bus_region *region)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
+ struct pci_pbm_info *pbm = pdev->bus->sysdata;
struct resource *root;
res->start = region->start;
extern spinlock_t pci_controller_lock;
extern struct pci_controller_info *pci_controller_root;
-extern struct pci_pbm_info *pci_bus2pbm[256];
-extern unsigned char pci_highest_busnum;
extern int pci_num_controllers;
/* PCI bus scanning and fixup support. */
static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 *value)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
unsigned char bus = bus_dev->number;
u32 *addr;
u16 tmp16;
static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 value)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
unsigned char bus = bus_dev->number;
u32 *addr;
pci_write_config_dword(pdev, where + 4, 0);
}
-/* We have to do the config space accesses by hand, thus... */
-#define PBM_BRIDGE_BUS 0x40
-#define PBM_BRIDGE_SUBORDINATE 0x41
-static void __init pbm_renumber(struct pci_pbm_info *pbm, u8 orig_busno)
-{
- u8 *addr, busno;
- int nbus;
-
- busno = pci_highest_busnum;
- nbus = pbm->pci_last_busno - pbm->pci_first_busno;
-
- addr = psycho_pci_config_mkaddr(pbm, orig_busno,
- 0, PBM_BRIDGE_BUS);
- pci_config_write8(addr, busno);
- addr = psycho_pci_config_mkaddr(pbm, busno,
- 0, PBM_BRIDGE_SUBORDINATE);
- pci_config_write8(addr, busno + nbus);
-
- pbm->pci_first_busno = busno;
- pbm->pci_last_busno = busno + nbus;
- pci_highest_busnum = busno + nbus + 1;
-
- do {
- pci_bus2pbm[busno++] = pbm;
- } while (nbus--);
-}
-
-/* We have to do the config space accesses by hand here since
- * the pci_bus2pbm array is not ready yet.
- */
-static void __init pbm_pci_bridge_renumber(struct pci_pbm_info *pbm,
- u8 busno)
-{
- u32 devfn, l, class;
- u8 hdr_type;
- int is_multi = 0;
-
- for(devfn = 0; devfn < 0xff; ++devfn) {
- u32 *dwaddr;
- u8 *baddr;
-
- if (PCI_FUNC(devfn) != 0 && is_multi == 0)
- continue;
-
- /* Anything there? */
- dwaddr = psycho_pci_config_mkaddr(pbm, busno, devfn, PCI_VENDOR_ID);
- l = 0xffffffff;
- pci_config_read32(dwaddr, &l);
- if (l == 0xffffffff || l == 0x00000000 ||
- l == 0x0000ffff || l == 0xffff0000) {
- is_multi = 0;
- continue;
- }
-
- baddr = psycho_pci_config_mkaddr(pbm, busno, devfn, PCI_HEADER_TYPE);
- pci_config_read8(baddr, &hdr_type);
- if (PCI_FUNC(devfn) == 0)
- is_multi = hdr_type & 0x80;
-
- dwaddr = psycho_pci_config_mkaddr(pbm, busno, devfn, PCI_CLASS_REVISION);
- class = 0xffffffff;
- pci_config_read32(dwaddr, &class);
- if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
- u32 buses = 0xffffffff;
-
- dwaddr = psycho_pci_config_mkaddr(pbm, busno, devfn,
- PCI_PRIMARY_BUS);
- pci_config_read32(dwaddr, &buses);
- pbm_pci_bridge_renumber(pbm, (buses >> 8) & 0xff);
- buses &= 0xff000000;
- pci_config_write32(dwaddr, buses);
- }
- }
-}
-
-static void __init pbm_bridge_reconfigure(struct pci_controller_info *p)
-{
- struct pci_pbm_info *pbm;
- u8 *addr;
-
- /* Clear out primary/secondary/subordinate bus numbers on
- * all PCI-to-PCI bridges under each PBM. The generic bus
- * probing will fix them up.
- */
- pbm_pci_bridge_renumber(&p->pbm_B, p->pbm_B.pci_first_busno);
- pbm_pci_bridge_renumber(&p->pbm_A, p->pbm_A.pci_first_busno);
-
- /* Move PBM A out of the way. */
- pbm = &p->pbm_A;
- addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno,
- 0, PBM_BRIDGE_BUS);
- pci_config_write8(addr, 0xff);
- addr = psycho_pci_config_mkaddr(pbm, 0xff,
- 0, PBM_BRIDGE_SUBORDINATE);
- pci_config_write8(addr, 0xff);
-
- /* Now we can safely renumber both PBMs. */
- pbm_renumber(&p->pbm_B, p->pbm_B.pci_first_busno);
- pbm_renumber(&p->pbm_A, 0xff);
-}
-
static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
{
u8 *addr;
static void __init psycho_scan_bus(struct pci_controller_info *p)
{
- pbm_bridge_reconfigure(p);
pbm_config_busmastering(&p->pbm_B);
p->pbm_B.is_66mhz_capable = 0;
pbm_config_busmastering(&p->pbm_A);
static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 *value)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
unsigned char bus = bus_dev->number;
u32 *addr;
u16 tmp16;
static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 value)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
unsigned char bus = bus_dev->number;
u32 *addr;
struct resource *res,
struct resource *root)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
+ struct pci_pbm_info *pbm = pdev->bus->sysdata;
struct pci_controller_info *p = pbm->parent;
unsigned long base;
p->pbm_A.is_66mhz_capable = 0;
p->pbm_B.is_66mhz_capable = 0;
- /* Unlike for PSYCHO, we can only have one SABRE
- * in a system. Having multiple SABREs is thus
- * and error, and as a consequence we do not need
- * to do any bus renumbering but we do have to have
- * the pci_bus2pbm array setup properly.
+ /* This driver has not been verified to handle
+ * multiple SABREs yet, so trap this.
*
* Also note that the SABRE host bridge is hardwired
* to live at bus 0.
cookie = alloc_bridge_cookie(&p->pbm_A);
- /* The pci_bus2pbm table has already been setup in sabre_init. */
sabre_bus = pci_scan_bus(p->pci_first_busno,
p->pci_ops,
&p->pbm_A);
pbm->pci_first_slot = 1;
pbm->pci_first_busno = busrange[0];
pbm->pci_last_busno = busrange[1];
- for (err = pbm->pci_first_busno;
- err <= pbm->pci_last_busno;
- err++)
- pci_bus2pbm[err] = pbm;
-
prom_getstring(node, "name", pbm->prom_name, sizeof(pbm->prom_name));
err = prom_getproperty(node, "ranges",
pbm->prom_node = sabre_node;
pbm->pci_first_busno = p->pci_first_busno;
pbm->pci_last_busno = p->pci_last_busno;
- for (err = pbm->pci_first_busno;
- err <= pbm->pci_last_busno;
- err++)
- pci_bus2pbm[err] = pbm;
prom_getstring(sabre_node, "name", pbm->prom_name, sizeof(pbm->prom_name));
err = prom_getproperty(sabre_node, "ranges",
u32 vdma[2];
u32 upa_portid, dma_mask;
u64 clear_irq;
- int bus;
hummingbird_p = 0;
if (!strcmp(model_name, "pci108e,a001"))
p->pci_first_busno = busrange[0];
p->pci_last_busno = busrange[1];
- /*
- * Handle config space reads through any Simba on APB.
- */
- for (bus = p->pci_first_busno; bus <= p->pci_last_busno; bus++)
- pci_bus2pbm[bus] = &p->pbm_A;
-
/*
* Look for APB underneath.
*/
static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 *value)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
unsigned char bus = bus_dev->number;
u32 *addr;
u16 tmp16;
return PCIBIOS_SUCCESSFUL;
}
pci_config_read32(addr, value);
-
-#warning DaveM, reminder, Tomatillo support is hosed.
-#if 0
- /* Crap how to do this in 2.5.x? I need the pdev :(
- * Actually, just move over to more sane domain
- * support to deal with this. -DaveM
- */
- if (where == PCI_PRIMARY_BUS &&
- dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
- *value != 0xffffffff) {
- u8 *busp = ((u8 *) value) + 1;
- int i;
-
- for (i = 0; i < 3; i++)
- busp[i] += pbm->pci_first_busno;
- }
-#endif
break;
}
return PCIBIOS_SUCCESSFUL;
static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 value)
{
- struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
unsigned char bus = bus_dev->number;
u32 *addr;
return PCIBIOS_SUCCESSFUL;
}
-#warning DaveM, reminder, Tomatillo support is hosed.
-#if 0
- /* Crap how to do this in 2.5.x? I need the pdev :(
- * Actually, just move over to more sane domain
- * support to deal with this. -DaveM
- */
- if (where == PCI_PRIMARY_BUS &&
- dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- u8 *busp = ((u8 *) &value) + 1;
- int i;
-
- for (i = 0; i < 3; i++) {
- if (busp[i] >= pbm->pci_first_busno)
- busp[i] += pbm->pci_first_busno;
- else
- busp[i] = 0;
- }
- }
-#endif
-
pci_config_write32(addr, value);
}
return PCIBIOS_SUCCESSFUL;
(SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
}
-/* We have to do the config space accesses by hand, thus... */
-static void __init pbm_renumber(struct pci_pbm_info *pbm, u8 orig_busno)
-{
- u8 busno;
- int nbus;
-
- busno = pci_highest_busnum;
- nbus = pbm->pci_last_busno - pbm->pci_first_busno;
-
- pbm->pci_first_busno = busno;
- pbm->pci_last_busno = busno + nbus;
- pci_highest_busnum = busno + nbus + 1;
-
- do {
- pci_bus2pbm[busno++] = pbm;
- } while (nbus--);
-}
-
-static void __init pbm_bridge_reconfigure(struct pci_controller_info *p)
-{
- /* Now we can safely renumber both PBMs. */
- pbm_renumber(&p->pbm_B, p->pbm_B.pci_first_busno);
- pbm_renumber(&p->pbm_A, 0xff);
-}
-
static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
{
u8 *addr;
return;
}
- pbm_bridge_reconfigure(p);
pbm_config_busmastering(&p->pbm_B);
p->pbm_B.is_66mhz_capable =
prom_getbool(p->pbm_B.prom_node, "66mhz-capable");