patch-2.3.16 linux/arch/sparc64/kernel/ebus.c
Next file: linux/arch/sparc64/kernel/idprom.c
Previous file: linux/arch/sparc64/kernel/devices.c
Back to the patch index
Back to the overall index
- Lines: 365
- Date:
Tue Aug 31 11:23:30 1999
- Orig file:
v2.3.15/linux/arch/sparc64/kernel/ebus.c
- Orig date:
Fri Aug 6 11:58:00 1999
diff -u --recursive --new-file v2.3.15/linux/arch/sparc64/kernel/ebus.c linux/arch/sparc64/kernel/ebus.c
@@ -1,7 +1,8 @@
-/* $Id: ebus.c,v 1.38 1999/08/06 10:37:32 davem Exp $
+/* $Id: ebus.c,v 1.42 1999/08/31 09:12:31 davem Exp $
* ebus.c: PCI to EBus bridge device.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ * Copyright (C) 1999 David S. Miller (davem@redhat.com)
*/
#include <linux/config.h>
@@ -19,15 +20,6 @@
#include <asm/bpp.h>
#include <asm/irq.h>
-#undef PROM_DEBUG
-#undef DEBUG_FILL_EBUS_DEV
-
-#ifdef PROM_DEBUG
-#define dprintf prom_printf
-#else
-#define dprintf printk
-#endif
-
struct linux_ebus *ebus_chain = 0;
extern void prom_ebus_ranges_init(struct linux_ebus *);
@@ -46,11 +38,11 @@
extern int envctrl_init(void);
#endif
-static inline unsigned long ebus_alloc(size_t size)
+static inline void *ebus_alloc(size_t size)
{
- unsigned long mem;
+ void *mem;
- mem = (unsigned long)kmalloc(size, GFP_ATOMIC);
+ mem = kmalloc(size, GFP_ATOMIC);
if (!mem)
panic(__FUNCTION__ ": out of memory");
memset((char *)mem, 0, size);
@@ -89,23 +81,26 @@
{
int regs[PROMREG_MAX];
int irqs[PROMREG_MAX];
- char lbuf[128];
int i, len;
dev->prom_node = node;
- prom_getstring(node, "name", lbuf, sizeof(lbuf));
- strcpy(dev->prom_name, lbuf);
+ prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
+ printk("(%s)", dev->prom_name);
len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
dev->num_addrs = len / sizeof(regs[0]);
for (i = 0; i < dev->num_addrs; i++) {
- if (regs[i] >= dev->parent->num_addrs) {
+ int rnum = regs[i];
+ if (rnum >= dev->parent->num_addrs) {
prom_printf("UGH: property for %s was %d, need < %d\n",
dev->prom_name, len, dev->parent->num_addrs);
panic(__FUNCTION__);
}
- dev->base_address[i] = dev->parent->base_address[regs[i]];
+ dev->resource[i].start = dev->parent->resource[i].start;
+ dev->resource[i].end = dev->parent->resource[i].end;
+ dev->resource[i].flags = IORESOURCE_MEM;
+ dev->resource[i].name = dev->prom_name;
}
len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
@@ -129,25 +124,13 @@
} else {
dev->num_irqs = len / sizeof(irqs[0]);
for (i = 0; i < dev->num_irqs; i++) {
+ struct pci_pbm_info *pbm = dev->bus->parent;
+ struct pci_controller_info *p = pbm->parent;
+
ebus_intmap_match(dev->bus, preg, &irqs[i]);
- dev->irqs[i] = psycho_irq_build(dev->bus->parent,
- dev->bus->self, irqs[i]);
+ dev->irqs[i] = p->irq_build(p, dev->bus->self, irqs[i]);
}
}
-
-#ifdef DEBUG_FILL_EBUS_DEV
- dprintf("child '%s': address%s ", dev->prom_name,
- dev->num_addrs > 1 ? "es" : "");
- for (i = 0; i < dev->num_addrs; i++)
- dprintf("%016lx ", dev->base_address[i]);
- dprintf("\n");
- if (dev->num_irqs) {
- dprintf(" IRQ%s", dev->num_irqs > 1 ? "s" : "");
- for (i = 0; i < dev->num_irqs; i++)
- dprintf(" %s", __irq_itoa(dev->irqs[i]));
- dprintf("\n");
- }
-#endif
}
void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
@@ -155,27 +138,32 @@
struct linux_prom_registers regs[PROMREG_MAX];
struct linux_ebus_child *child;
int irqs[PROMINTR_MAX];
- char lbuf[128];
int i, n, len;
dev->prom_node = node;
- prom_getstring(node, "name", lbuf, sizeof(lbuf));
- strcpy(dev->prom_name, lbuf);
+ prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
+ printk(" [%s", dev->prom_name);
len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
if (len % sizeof(struct linux_prom_registers)) {
prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
dev->prom_name, len,
(int)sizeof(struct linux_prom_registers));
- panic(__FUNCTION__);
+ prom_halt();
}
dev->num_addrs = len / sizeof(struct linux_prom_registers);
for (i = 0; i < dev->num_addrs; i++) {
n = (regs[i].which_io - 0x10) >> 2;
- dev->base_address[i] = dev->bus->self->resource[n].start;
- dev->base_address[i] += (unsigned long)regs[i].phys_addr;
+ dev->resource[i].start = dev->bus->self->resource[n].start;
+ dev->resource[i].start += (unsigned long)regs[i].phys_addr;
+ dev->resource[i].end =
+ (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
+ dev->resource[i].flags = IORESOURCE_MEM;
+ dev->resource[i].name = dev->prom_name;
+ request_resource(&dev->bus->self->resource[n],
+ &dev->resource[i]);
}
len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
@@ -184,28 +172,17 @@
} else {
dev->num_irqs = len / sizeof(irqs[0]);
for (i = 0; i < dev->num_irqs; i++) {
+ struct pci_pbm_info *pbm = dev->bus->parent;
+ struct pci_controller_info *p = pbm->parent;
+
ebus_intmap_match(dev->bus, ®s[0], &irqs[i]);
- dev->irqs[i] = psycho_irq_build(dev->bus->parent,
- dev->bus->self, irqs[i]);
+ dev->irqs[i] = p->irq_build(p, dev->bus->self, irqs[i]);
}
}
-#ifdef DEBUG_FILL_EBUS_DEV
- dprintf("'%s': address%s ", dev->prom_name,
- dev->num_addrs > 1 ? "es" : "");
- for (i = 0; i < dev->num_addrs; i++)
- dprintf("%016lx ", dev->base_address[i]);
- dprintf("\n");
- if (dev->num_irqs) {
- dprintf(" IRQ%s", dev->num_irqs > 1 ? "s" : "");
- for (i = 0; i < dev->num_irqs; i++)
- dprintf(" %s", __irq_itoa(dev->irqs[i]));
- dprintf("\n");
- }
-#endif
if ((node = prom_getchild(node))) {
- dev->children = (struct linux_ebus_child *)
- ebus_alloc(sizeof(struct linux_ebus_child));
+ printk(" ->");
+ dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
child = dev->children;
child->next = 0;
@@ -214,8 +191,7 @@
fill_ebus_child(node, ®s[0], child);
while ((node = prom_getsibling(node))) {
- child->next = (struct linux_ebus_child *)
- ebus_alloc(sizeof(struct linux_ebus_child));
+ child->next = ebus_alloc(sizeof(struct linux_ebus_child));
child = child->next;
child->next = 0;
@@ -224,24 +200,21 @@
fill_ebus_child(node, ®s[0], child);
}
}
+ printk("]");
}
extern void clock_probe(void);
+extern void power_init(void);
void __init ebus_init(void)
{
- struct linux_prom_pci_registers regs[PROMREG_MAX];
- struct linux_pbm_info *pbm;
+ struct pci_pbm_info *pbm;
struct linux_ebus_device *dev;
struct linux_ebus *ebus;
struct pci_dev *pdev;
struct pcidev_cookie *cookie;
- char lbuf[128];
- struct resource *base;
- unsigned long addr;
unsigned short pci_command;
- int nd, len, ebusnd;
- int reg, rng, nreg;
+ int nd, ebusnd;
int num_ebus = 0;
if (!pci_present())
@@ -250,17 +223,13 @@
pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
if (!pdev) {
printk("ebus: No EBus's found.\n");
-#ifdef PROM_DEBUG
- dprintf("ebus: No EBus's found.\n");
-#endif
return;
}
cookie = pdev->sysdata;
ebusnd = cookie->prom_node;
- ebus_chain = ebus = (struct linux_ebus *)
- ebus_alloc(sizeof(struct linux_ebus));
+ ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
ebus->next = 0;
while (ebusnd) {
@@ -277,9 +246,6 @@
if (ebus == ebus_chain) {
ebus_chain = NULL;
printk("ebus: No EBus's found.\n");
-#ifdef PROM_DEBUG
- dprintf("ebus: No EBus's found.\n");
-#endif
return;
}
break;
@@ -290,14 +256,10 @@
continue;
}
printk("ebus%d:", num_ebus);
-#ifdef PROM_DEBUG
- dprintf("ebus%d:", num_ebus);
-#endif
- prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf));
+ prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
+ ebus->index = num_ebus;
ebus->prom_node = ebusnd;
- strcpy(ebus->prom_name, lbuf);
-
ebus->self = pdev;
ebus->parent = pbm = cookie->pbm;
@@ -310,56 +272,7 @@
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
/* NOTE: Cache line size is in 32-bit word units. */
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x10);
-
- len = prom_getproperty(ebusnd, "reg", (void *)regs,
- sizeof(regs));
- if (len == 0 || len == -1) {
- prom_printf("%s: can't find reg property\n",
- __FUNCTION__);
- prom_halt();
- }
- nreg = len / sizeof(struct linux_prom_pci_registers);
-
- base = &ebus->self->resource[0];
- for (reg = 0; reg < nreg; reg++) {
- if (!(regs[reg].phys_hi & 0x03000000))
- continue;
-
- for (rng = 0; rng < pbm->num_pbm_ranges; rng++) {
- struct linux_prom_pci_ranges *rp =
- &pbm->pbm_ranges[rng];
-
- if ((rp->child_phys_hi ^ regs[reg].phys_hi)
- & 0x03000000)
- continue;
-
- addr = (u64)regs[reg].phys_lo;
- addr += (u64)regs[reg].phys_mid << 32UL;
- addr += (u64)rp->parent_phys_lo;
- addr += (u64)rp->parent_phys_hi << 32UL;
-
- base->name = "EBUS";
- base->start = (unsigned long)__va(addr);
- base->end = base->start + regs[reg].size_lo - 1;
- base->flags = 0;
- request_resource(&ioport_resource, base);
-
- base += 1;
-
- printk(" %lx[%x]", (unsigned long)__va(addr),
- regs[reg].size_lo);
-#ifdef PROM_DEBUG
- dprintf(" %lx[%x]", (unsigned long)__va(addr),
- regs[reg].size_lo);
-#endif
- break;
- }
- }
- printk("\n");
-#ifdef PROM_DEBUG
- dprintf("\n");
-#endif
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 64/sizeof(u32));
prom_ebus_ranges_init(ebus);
prom_ebus_intmap_init(ebus);
@@ -368,8 +281,7 @@
if (!nd)
goto next_ebus;
- ebus->devices = (struct linux_ebus_device *)
- ebus_alloc(sizeof(struct linux_ebus_device));
+ ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
dev = ebus->devices;
dev->next = 0;
@@ -378,8 +290,7 @@
fill_ebus_device(nd, dev);
while ((nd = prom_getsibling(nd))) {
- dev->next = (struct linux_ebus_device *)
- ebus_alloc(sizeof(struct linux_ebus_device));
+ dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
dev = dev->next;
dev->next = 0;
@@ -389,6 +300,8 @@
}
next_ebus:
+ printk("\n");
+
pdev = pci_find_device(PCI_VENDOR_ID_SUN,
PCI_DEVICE_ID_SUN_EBUS, pdev);
if (!pdev)
@@ -397,8 +310,7 @@
cookie = pdev->sysdata;
ebusnd = cookie->prom_node;
- ebus->next = (struct linux_ebus *)
- ebus_alloc(sizeof(struct linux_ebus));
+ ebus->next = ebus_alloc(sizeof(struct linux_ebus));
ebus = ebus->next;
ebus->next = 0;
++num_ebus;
@@ -420,4 +332,5 @@
flash_init();
#endif
clock_probe();
+ power_init();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)