__initfunc(void ebus_init(void)) { struct linux_prom_pci_registers regs[PROMREG_MAX]; struct linux_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; struct pci_dev *pdev; struct pcidev_cookie *cookie; char lbuf[128]; unsigned long addr, *base; unsigned short pci_command; int nd, len, ebusnd; int reg, rng, nreg; int num_ebus = 0; if (!pci_present()) return; 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->next = 0; while (ebusnd) { printk("ebus%d:", num_ebus); #ifdef PROM_DEBUG dprintf("ebus%d:", num_ebus); #endif prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf)); ebus->prom_node = ebusnd; strcpy(ebus->prom_name, lbuf); ebus->self = pdev; ebus->parent = pbm = cookie->pbm; /* Enable BUS Master. */ pci_read_config_word(pdev, PCI_COMMAND, &pci_command); pci_command |= PCI_COMMAND_MASTER; pci_write_config_word(pdev, PCI_COMMAND, pci_command); 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->base_address[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++ = (unsigned long)__va(addr); 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 prom_ebus_ranges_init(ebus); prom_ebus_intmap_init(ebus); nd = prom_getchild(ebusnd); if (!nd) goto next_ebus; ebus->devices = (struct linux_ebus_device *) ebus_alloc(sizeof(struct linux_ebus_device)); dev = ebus->devices; dev->next = 0; dev->children = 0; dev->bus = ebus; fill_ebus_device(nd, dev); while ((nd = prom_getsibling(nd))) { dev->next = (struct linux_ebus_device *) ebus_alloc(sizeof(struct linux_ebus_device)); dev = dev->next; dev->next = 0; dev->children = 0; dev->bus = ebus; fill_ebus_device(nd, dev); } next_ebus: pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, pdev); if (!pdev) break; cookie = pdev->sysdata; ebusnd = cookie->prom_node; ebus->next = (struct linux_ebus *) ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; ebus->next = 0; ++num_ebus; } #ifdef CONFIG_SUN_OPENPROMIO openprom_init(); #endif #ifdef CONFIG_SPARCAUDIO sparcaudio_init(); #endif #ifdef CONFIG_SUN_BPP bpp_init(); #endif #ifdef CONFIG_SUN_AUXIO auxio_probe(); #endif #ifdef CONFIG_ENVCTRL envctrl_init(); #endif #ifdef CONFIG_OBP_FLASH flash_init(); #endif clock_probe(); }
__initfunc(void sbus_init(void)) { register int nd, this_sbus, sbus_devs, topnd, iommund; unsigned int sbus_clock; struct linux_sbus *sbus; struct linux_sbus_device *this_dev; int num_sbus = 0; /* How many did we find? */ #ifdef CONFIG_SUN4 return sun4_dvma_init(); #endif topnd = prom_getchild(prom_root_node); /* Finding the first sbus is a special case... */ iommund = 0; if(sparc_cpu_model == sun4u) { nd = prom_searchsiblings(topnd, "sbus"); if(nd == 0) { #ifdef CONFIG_PCI if (!pcibios_present()) { prom_printf("Neither SBUS nor PCI found.\n"); prom_halt(); } return; #else prom_printf("YEEE, UltraSparc sbus not found\n"); prom_halt(); #endif } } else if(sparc_cpu_model == sun4d) { if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 || (nd = prom_getchild(iommund)) == 0 || (nd = prom_searchsiblings(nd, "sbi")) == 0) { panic("sbi not found"); } } else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) { if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 || (nd = prom_getchild(iommund)) == 0 || (nd = prom_searchsiblings(nd, "sbus")) == 0) { #ifdef CONFIG_PCI if (!pcibios_present()) { prom_printf("Neither SBUS nor PCI found.\n"); prom_halt(); } return; #else /* No reason to run further - the data access trap will occur. */ panic("sbus not found"); #endif } } /* Ok, we've found the first one, allocate first SBus struct * and place in chain. */ sbus = SBus_chain = kmalloc(sizeof(struct linux_sbus), GFP_ATOMIC); sbus->next = 0; this_sbus=nd; if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d) iommu_init(iommund, sbus); /* Loop until we find no more SBUS's */ while(this_sbus) { /* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */ if(sparc_cpu_model == sun4u) iommu_init(this_sbus, sbus); #ifndef __sparc_v9__ else if (sparc_cpu_model == sun4d) iounit_init(this_sbus, iommund, sbus); #endif printk("sbus%d: ", num_sbus); sbus_clock = prom_getint(this_sbus, "clock-frequency"); if(sbus_clock==-1) sbus_clock = (25*1000*1000); printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), (int) (((sbus_clock/1000)%1000 != 0) ? (((sbus_clock/1000)%1000) + 1000) : 0)); prom_getstring(this_sbus, "name", lbuf, sizeof(lbuf)); lbuf[sizeof(sbus->prom_name) - 1] = 0; sbus->prom_node = this_sbus; strcpy(sbus->prom_name, lbuf); sbus->clock_freq = sbus_clock; #ifndef __sparc_v9__ if (sparc_cpu_model == sun4d) { sbus->devid = prom_getint(iommund, "device-id"); sbus->board = prom_getint(iommund, "board#"); } #endif prom_sbus_ranges_init (iommund, sbus); sbus_devs = prom_getchild(this_sbus); sbus->devices = kmalloc(sizeof(struct linux_sbus_device), GFP_ATOMIC); this_dev = sbus->devices; this_dev->next = 0; this_dev->my_bus = sbus; fill_sbus_device(sbus_devs, this_dev); /* Should we traverse for children? */ if(prom_getchild(sbus_devs)) { /* Allocate device node */ this_dev->child = kmalloc(sizeof(struct linux_sbus_device), GFP_ATOMIC); /* Fill it */ this_dev->child->my_bus = sbus; fill_sbus_device(prom_getchild(sbus_devs), this_dev->child); sbus_do_child_siblings(prom_getchild(sbus_devs), this_dev->child, sbus); } else { this_dev->child = 0; } while((sbus_devs = prom_getsibling(sbus_devs)) != 0) { /* Allocate device node */ this_dev->next = kmalloc(sizeof(struct linux_sbus_device), GFP_ATOMIC); this_dev=this_dev->next; this_dev->next=0; /* Fill it */ this_dev->my_bus = sbus; fill_sbus_device(sbus_devs, this_dev); /* Is there a child node hanging off of us? */ if(prom_getchild(sbus_devs)) { /* Get new device struct */ this_dev->child = kmalloc(sizeof(struct linux_sbus_device), GFP_ATOMIC); /* Fill it */ this_dev->child->my_bus = sbus; fill_sbus_device(prom_getchild(sbus_devs), this_dev->child); sbus_do_child_siblings(prom_getchild(sbus_devs), this_dev->child, sbus); } else { this_dev->child = 0; } } dvma_init(sbus); num_sbus++; if(sparc_cpu_model == sun4u) { this_sbus = prom_getsibling(this_sbus); if(!this_sbus) break; this_sbus = prom_searchsiblings(this_sbus, "sbus"); } else if(sparc_cpu_model == sun4d) { iommund = prom_getsibling(iommund); if(!iommund) break; iommund = prom_searchsiblings(iommund, "io-unit"); if(!iommund) break; this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi"); } else { this_sbus = prom_getsibling(this_sbus); if(!this_sbus) break; this_sbus = prom_searchsiblings(this_sbus, "sbus"); } if(this_sbus) { sbus->next = kmalloc(sizeof(struct linux_sbus), GFP_ATOMIC); sbus = sbus->next; sbus->next = 0; } else { break; } } /* while(this_sbus) */ if (sparc_cpu_model == sun4d) { extern void sun4d_init_sbi_irq(void); sun4d_init_sbi_irq(); } #ifdef CONFIG_SUN_OPENPROMIO openprom_init(); #endif #ifdef CONFIG_SUN_BPP bpp_init(); #endif #ifdef CONFIG_SUN_AUXIO if (sparc_cpu_model == sun4u) auxio_probe (); #endif #ifdef CONFIG_OBP_FLASH flash_init(); #endif #ifdef __sparc_v9__ if (sparc_cpu_model == sun4u) { extern void clock_probe(void); clock_probe(); } #endif }