patch-2.4.23 linux-2.4.23/arch/sparc64/kernel/pci_sabre.c
Next file: linux-2.4.23/arch/sparc64/kernel/pci_schizo.c
Previous file: linux-2.4.23/arch/sparc64/kernel/pci_psycho.c
Back to the patch index
Back to the overall index
- Lines: 309
- Date:
2003-11-28 10:26:19.000000000 -0800
- Orig file:
linux-2.4.22/arch/sparc64/kernel/pci_sabre.c
- Orig date:
2003-08-25 04:44:40.000000000 -0700
diff -urN linux-2.4.22/arch/sparc64/kernel/pci_sabre.c linux-2.4.23/arch/sparc64/kernel/pci_sabre.c
@@ -219,6 +219,7 @@
((unsigned long)(REG)))
static int hummingbird_p;
+static struct pci_bus *sabre_root_bus;
static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,
unsigned char bus,
@@ -630,7 +631,6 @@
struct pci_dev *pdev,
unsigned int ino)
{
- struct pci_controller_info *p = pbm->parent;
struct ino_bucket *bucket;
unsigned long imap, iclr;
unsigned long imap_off, iclr_off;
@@ -655,11 +655,11 @@
if (PIL_RESERVED(pil))
BUG();
- imap = p->controller_regs + imap_off;
+ imap = pbm->controller_regs + imap_off;
imap += 4;
iclr_off = sabre_iclr_offset(ino);
- iclr = p->controller_regs + iclr_off;
+ iclr = pbm->controller_regs + iclr_off;
iclr += 4;
if ((ino & 0x20) == 0)
@@ -737,7 +737,7 @@
sabre_write(iommu->iommu_control,
(control | SABRE_IOMMUCTRL_DENAB));
for (i = 0; i < 16; i++) {
- unsigned long base = p->controller_regs;
+ unsigned long base = p->pbm_A.controller_regs;
iommu_tag[i] =
sabre_read(base + SABRE_IOMMU_TAG + (i * 8UL));
@@ -786,8 +786,8 @@
static void sabre_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct pci_controller_info *p = dev_id;
- unsigned long afsr_reg = p->controller_regs + SABRE_UE_AFSR;
- unsigned long afar_reg = p->controller_regs + SABRE_UECE_AFAR;
+ unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_UE_AFSR;
+ unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR;
unsigned long afsr, afar, error_bits;
int reported;
@@ -844,8 +844,8 @@
static void sabre_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct pci_controller_info *p = dev_id;
- unsigned long afsr_reg = p->controller_regs + SABRE_CE_AFSR;
- unsigned long afar_reg = p->controller_regs + SABRE_UECE_AFAR;
+ unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_CE_AFSR;
+ unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR;
unsigned long afsr, afar, error_bits;
int reported;
@@ -895,6 +895,38 @@
printk("]\n");
}
+static void sabre_pcierr_intr_other(struct pci_controller_info *p)
+{
+ unsigned long csr_reg, csr, csr_error_bits;
+ u16 stat;
+
+ csr_reg = p->pbm_A.controller_regs + SABRE_PCICTRL;
+ csr = sabre_read(csr_reg);
+ csr_error_bits =
+ csr & SABRE_PCICTRL_SERR;
+ if (csr_error_bits) {
+ /* Clear the errors. */
+ sabre_write(csr_reg, csr);
+
+ /* Log 'em. */
+ if (csr_error_bits & SABRE_PCICTRL_SERR)
+ printk("SABRE%d: PCI SERR signal asserted.\n",
+ p->index);
+ }
+ pci_read_config_word(sabre_root_bus->self,
+ PCI_STATUS, &stat);
+ if (stat & (PCI_STATUS_PARITY |
+ PCI_STATUS_SIG_TARGET_ABORT |
+ PCI_STATUS_REC_TARGET_ABORT |
+ PCI_STATUS_REC_MASTER_ABORT |
+ PCI_STATUS_SIG_SYSTEM_ERROR)) {
+ printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n",
+ p->index, stat);
+ pci_write_config_word(sabre_root_bus->self,
+ PCI_STATUS, 0xffff);
+ }
+}
+
static void sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct pci_controller_info *p = dev_id;
@@ -902,8 +934,8 @@
unsigned long afsr, afar, error_bits;
int reported;
- afsr_reg = p->controller_regs + SABRE_PIOAFSR;
- afar_reg = p->controller_regs + SABRE_PIOAFAR;
+ afsr_reg = p->pbm_A.controller_regs + SABRE_PIOAFSR;
+ afar_reg = p->pbm_A.controller_regs + SABRE_PIOAFAR;
/* Latch error status. */
afar = sabre_read(afar_reg);
@@ -916,7 +948,7 @@
SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA |
SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR);
if (!error_bits)
- return;
+ return sabre_pcierr_intr_other(p);
sabre_write(afsr_reg, error_bits);
/* Log the error. */
@@ -995,8 +1027,8 @@
static void __init sabre_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
- unsigned long base = p->controller_regs;
- unsigned long irq, portid = p->portid;
+ unsigned long base = pbm->controller_regs;
+ unsigned long irq, portid = pbm->portid;
u64 tmp;
/* We clear the error bits in the appropriate AFSR before
@@ -1044,13 +1076,12 @@
struct resource *root)
{
struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
- struct pci_controller_info *p = pbm->parent;
unsigned long base;
if (res->flags & IORESOURCE_IO)
- base = p->controller_regs + SABRE_IOSPACE;
+ base = pbm->controller_regs + SABRE_IOSPACE;
else
- base = p->controller_regs + SABRE_MEMSPACE;
+ base = pbm->controller_regs + SABRE_MEMSPACE;
res->start += base;
res->end += base;
@@ -1060,7 +1091,6 @@
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
- struct pci_controller_info *p = pbm->parent;
struct resource *res;
unsigned long base;
u32 reg;
@@ -1078,9 +1108,9 @@
is_64bit = 0;
if (res->flags & IORESOURCE_IO)
- base = p->controller_regs + SABRE_IOSPACE;
+ base = pbm->controller_regs + SABRE_IOSPACE;
else {
- base = p->controller_regs + SABRE_MEMSPACE;
+ base = pbm->controller_regs + SABRE_MEMSPACE;
if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
== PCI_BASE_ADDRESS_MEM_TYPE_64)
is_64bit = 1;
@@ -1197,6 +1227,8 @@
pci_fixup_host_bridge_self(sabre_bus);
sabre_bus->self->sysdata = cookie;
+ sabre_root_bus = sabre_bus;
+
apb_init(p, sabre_bus);
sabres_scanned = 0;
@@ -1256,21 +1288,21 @@
iommu->iommu_cur_ctx = 0;
/* Register addresses. */
- iommu->iommu_control = p->controller_regs + SABRE_IOMMU_CONTROL;
- iommu->iommu_tsbbase = p->controller_regs + SABRE_IOMMU_TSBBASE;
- iommu->iommu_flush = p->controller_regs + SABRE_IOMMU_FLUSH;
- iommu->write_complete_reg = p->controller_regs + SABRE_WRSYNC;
+ iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
+ iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE;
+ iommu->iommu_flush = p->pbm_A.controller_regs + SABRE_IOMMU_FLUSH;
+ iommu->write_complete_reg = p->pbm_A.controller_regs + SABRE_WRSYNC;
/* Sabre's IOMMU lacks ctx flushing. */
iommu->iommu_ctxflush = 0;
/* Invalidate TLB Entries. */
- control = sabre_read(p->controller_regs + SABRE_IOMMU_CONTROL);
+ control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
control |= SABRE_IOMMUCTRL_DENAB;
- sabre_write(p->controller_regs + SABRE_IOMMU_CONTROL, control);
+ sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
for(i = 0; i < 16; i++) {
- sabre_write(p->controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0);
- sabre_write(p->controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0);
+ sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0);
+ sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0);
}
/* Leave diag mode enabled for full-flushing done
@@ -1287,9 +1319,9 @@
iommu->dma_addr_mask = dma_mask;
memset((char *)tsbbase, 0, PAGE_SIZE << order);
- sabre_write(p->controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
+ sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
- control = sabre_read(p->controller_regs + SABRE_IOMMU_CONTROL);
+ control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
control |= SABRE_IOMMUCTRL_ENAB;
switch(tsbsize) {
@@ -1306,7 +1338,7 @@
prom_halt();
break;
}
- sabre_write(p->controller_regs + SABRE_IOMMU_CONTROL, control);
+ sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
/* We start with no consistent mappings. */
iommu->lowest_consistent_map =
@@ -1322,8 +1354,8 @@
struct pci_pbm_info *pbm)
{
char *name = pbm->name;
- unsigned long ibase = p->controller_regs + SABRE_IOSPACE;
- unsigned long mbase = p->controller_regs + SABRE_MEMSPACE;
+ unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE;
+ unsigned long mbase = p->pbm_A.controller_regs + SABRE_MEMSPACE;
unsigned int devfn;
unsigned long first, last, i;
u8 *addr, map;
@@ -1416,6 +1448,7 @@
pbm = &p->pbm_B;
else
pbm = &p->pbm_A;
+ pbm->chip_type = PBM_CHIP_TYPE_SABRE;
pbm->parent = p;
pbm->prom_node = node;
pbm->pci_first_slot = 1;
@@ -1511,11 +1544,11 @@
pbm->io_space.name = pbm->mem_space.name = pbm->name;
/* Hack up top-level resources. */
- pbm->io_space.start = p->controller_regs + SABRE_IOSPACE;
+ pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE;
pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL;
pbm->io_space.flags = IORESOURCE_IO;
- pbm->mem_space.start = p->controller_regs + SABRE_MEMSPACE;
+ pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE;
pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL;
pbm->mem_space.flags = IORESOURCE_MEM;
@@ -1591,7 +1624,8 @@
pci_controller_root = p;
spin_unlock_irqrestore(&pci_controller_lock, flags);
- p->portid = upa_portid;
+ p->pbm_A.portid = upa_portid;
+ p->pbm_B.portid = upa_portid;
p->index = pci_num_controllers++;
p->pbms_same_domain = 1;
p->scan_bus = sabre_scan_bus;
@@ -1614,30 +1648,31 @@
/*
* First REG in property is base of entire SABRE register space.
*/
- p->controller_regs = pr_regs[0].phys_addr;
- pci_dma_wsync = p->controller_regs + SABRE_WRSYNC;
+ p->pbm_A.controller_regs = pr_regs[0].phys_addr;
+ p->pbm_B.controller_regs = pr_regs[0].phys_addr;
+ pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC;
printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n",
- p->controller_regs, pci_dma_wsync);
+ p->pbm_A.controller_regs, pci_dma_wsync);
/* Clear interrupts */
/* PCI first */
for (clear_irq = SABRE_ICLR_A_SLOT0; clear_irq < SABRE_ICLR_B_SLOT0 + 0x80; clear_irq += 8)
- sabre_write(p->controller_regs + clear_irq, 0x0UL);
+ sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL);
/* Then OBIO */
for (clear_irq = SABRE_ICLR_SCSI; clear_irq < SABRE_ICLR_SCSI + 0x80; clear_irq += 8)
- sabre_write(p->controller_regs + clear_irq, 0x0UL);
+ sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL);
/* Error interrupts are enabled later after the bus scan. */
- sabre_write(p->controller_regs + SABRE_PCICTRL,
+ sabre_write(p->pbm_A.controller_regs + SABRE_PCICTRL,
(SABRE_PCICTRL_MRLEN | SABRE_PCICTRL_SERR |
SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN));
/* Now map in PCI config space for entire SABRE. */
p->pbm_A.config_space = p->pbm_B.config_space =
- (p->controller_regs + SABRE_CONFIGSPACE);
+ (p->pbm_A.controller_regs + SABRE_CONFIGSPACE);
printk("SABRE: Shared PCI config space at %016lx\n",
p->pbm_A.config_space);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)