+no_regs:
+ len = prom_getproperty(prom_node, "ranges",
+ (char *)sdev->device_ranges,
+ sizeof(sdev->device_ranges));
+ if (len == -1) {
+ sdev->num_device_ranges = 0;
+ goto no_ranges;
+ }
+ if (len % sizeof(struct linux_prom_ranges)) {
+ prom_printf("fill_sbus_device: proplen for ranges of %s "
+ " was %d, need multiple of %d\n",
+ sdev->prom_name, len,
+ (int) sizeof(struct linux_prom_ranges));
+ prom_halt();
+ }
+ if (len > (sizeof(struct linux_prom_ranges) * PROMREG_MAX)) {
+ prom_printf("fill_sbus_device: Too many range properties "
+ "for device %s, len=%d\n",
+ sdev->prom_name, len);
+ prom_halt();
+ }
+ sdev->num_device_ranges =
+ len / sizeof(struct linux_prom_ranges);
+
+no_ranges:
+ /* XXX Unfortunately, IRQ issues are very arch specific.
+ * XXX Pull this crud out into an arch specific area
+ * XXX at some point. -DaveM
+ */
+#ifdef CONFIG_SPARC64
+ len = prom_getproperty(prom_node, "interrupts",
+ (char *) irqs, sizeof(irqs));
+ if (len == -1 || len == 0) {
+ sdev->irqs[0] = 0;
+ sdev->num_irqs = 0;
+ } else {
+ unsigned int pri = irqs[0].pri;
+
+ sdev->num_irqs = 1;
+ if (pri < 0x20)
+ pri += sdev->slot * 8;
+
+ sdev->irqs[0] = sbus_build_irq(sdev->bus, pri);
+ }
+#endif /* CONFIG_SPARC64 */
+
+#ifdef CONFIG_SPARC32
+ len = prom_getproperty(prom_node, "intr",
+ (char *)irqs, sizeof(irqs));
+ if (len != -1) {
+ sdev->num_irqs = len / 8;
+ if (sdev->num_irqs == 0) {
+ sdev->irqs[0] = 0;
+ } else if (sparc_cpu_model == sun4d) {
+ extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
+
+ for (len = 0; len < sdev->num_irqs; len++)
+ sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri);
+ } else {
+ for (len = 0; len < sdev->num_irqs; len++)
+ sdev->irqs[len] = irqs[len].pri;
+ }
+ } else {
+ /* No "intr" node found-- check for "interrupts" node.
+ * This node contains SBus interrupt levels, not IPLs
+ * as in "intr", and no vector values. We convert
+ * SBus interrupt levels to PILs (platform specific).
+ */
+ len = prom_getproperty(prom_node, "interrupts",
+ (char *)interrupts, sizeof(interrupts));
+ if (len == -1) {
+ sdev->irqs[0] = 0;
+ sdev->num_irqs = 0;
+ } else {
+ sdev->num_irqs = len / sizeof(int);
+ for (len = 0; len < sdev->num_irqs; len++) {
+ sdev->irqs[len] = sbint_to_irq(sdev, interrupts[len]);
+ }
+ }
+ }
+#endif /* CONFIG_SPARC32 */