Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
Browse files Browse the repository at this point in the history
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
  [SPARC64]: Avoid JBUS errors on some Niagara systems.
  [FUSION]: Fix mptspi.c build with CONFIG_PM not set.
  [TG3]: Handle Sun onboard tg3 chips more correctly.
  [SPARC64]: Dump local cpu registers in sun4v_log_error()
  • Loading branch information
Linus Torvalds committed Jun 10, 2006
2 parents 938473b + 46b3049 commit 1f4d4a7
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 107 deletions.
124 changes: 118 additions & 6 deletions arch/sparc64/kernel/pci_sun4v.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,18 +599,128 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = {

/* SUN4V PCI configuration space accessors. */

static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func)
struct pdev_entry {
struct pdev_entry *next;
u32 devhandle;
unsigned int bus;
unsigned int device;
unsigned int func;
};

#define PDEV_HTAB_SIZE 16
#define PDEV_HTAB_MASK (PDEV_HTAB_SIZE - 1)
static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE];

static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func)
{
if (bus == pbm->pci_first_busno) {
if (device == 0 && func == 0)
return 0;
return 1;
unsigned int val;

val = (devhandle ^ (devhandle >> 4));
val ^= bus;
val ^= device;
val ^= func;

return val & PDEV_HTAB_MASK;
}

static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func)
{
struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL);
struct pdev_entry **slot;

if (!p)
return -ENOMEM;

slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)];
p->next = *slot;
*slot = p;

p->devhandle = devhandle;
p->bus = bus;
p->device = device;
p->func = func;

return 0;
}

/* Recursively descend into the OBP device tree, rooted at toplevel_node,
* looking for a PCI device matching bus and devfn.
*/
static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn)
{
toplevel_node = prom_getchild(toplevel_node);

while (toplevel_node != 0) {
int ret = obp_find(pregs, toplevel_node, bus, devfn);

if (ret != 0)
return ret;

ret = prom_getproperty(toplevel_node, "reg", (char *) pregs,
sizeof(*pregs) * PROMREG_MAX);
if (ret == 0 || ret == -1)
goto next_sibling;

if (((pregs[0].phys_hi >> 16) & 0xff) == bus &&
((pregs[0].phys_hi >> 8) & 0xff) == devfn)
break;

next_sibling:
toplevel_node = prom_getsibling(toplevel_node);
}

return toplevel_node;
}

static int pdev_htab_populate(struct pci_pbm_info *pbm)
{
struct linux_prom_pci_registers pr[PROMREG_MAX];
u32 devhandle = pbm->devhandle;
unsigned int bus;

for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) {
unsigned int devfn;

for (devfn = 0; devfn < 256; devfn++) {
unsigned int device = PCI_SLOT(devfn);
unsigned int func = PCI_FUNC(devfn);

if (obp_find(pr, pbm->prom_node, bus, devfn)) {
int err = pdev_htab_add(devhandle, bus,
device, func);
if (err)
return err;
}
}
}

return 0;
}

static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func)
{
struct pdev_entry *p;

p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)];
while (p) {
if (p->devhandle == devhandle &&
p->bus == bus &&
p->device == device &&
p->func == func)
break;

p = p->next;
}

return p;
}

static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func)
{
if (bus < pbm->pci_first_busno ||
bus > pbm->pci_last_busno)
return 1;
return 0;
return pdev_find(pbm->devhandle, bus, device, func) == NULL;
}

static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
Expand Down Expand Up @@ -1063,6 +1173,8 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32

pci_sun4v_get_bus_range(pbm);
pci_sun4v_iommu_init(pbm);

pdev_htab_populate(pbm);
}

void sun4v_pci_init(int node, char *model_name)
Expand Down
11 changes: 7 additions & 4 deletions arch/sparc64/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1797,7 +1797,9 @@ static const char *sun4v_err_type_to_str(u32 type)
};
}

static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
extern void __show_regs(struct pt_regs * regs);

static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
{
int cnt;

Expand Down Expand Up @@ -1830,6 +1832,8 @@ static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char *
pfx,
ent->err_raddr, ent->err_size, ent->err_cpu);

__show_regs(regs);

if ((cnt = atomic_read(ocnt)) != 0) {
atomic_set(ocnt, 0);
wmb();
Expand Down Expand Up @@ -1862,7 +1866,7 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)

put_cpu();

sun4v_log_error(&local_copy, cpu,
sun4v_log_error(regs, &local_copy, cpu,
KERN_ERR "RESUMABLE ERROR",
&sun4v_resum_oflow_cnt);
}
Expand Down Expand Up @@ -1910,7 +1914,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset)
}
#endif

sun4v_log_error(&local_copy, cpu,
sun4v_log_error(regs, &local_copy, cpu,
KERN_EMERG "NON-RESUMABLE ERROR",
&sun4v_nonresum_oflow_cnt);

Expand Down Expand Up @@ -2200,7 +2204,6 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
void die_if_kernel(char *str, struct pt_regs *regs)
{
static int die_counter;
extern void __show_regs(struct pt_regs * regs);
extern void smp_report_regs(void);
int count = 0;

Expand Down
2 changes: 2 additions & 0 deletions drivers/message/fusion/mptspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
return rc;
}

#ifdef CONFIG_PM
/*
* spi module resume handler
*/
Expand All @@ -846,6 +847,7 @@ mptspi_resume(struct pci_dev *pdev)

return rc;
}
#endif

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
Expand Down
Loading

0 comments on commit 1f4d4a7

Please sign in to comment.