static int __init ts102_uctrl_init(void) { struct uctrl_driver *driver = &drv; int len, i; struct linux_prom_irqs tmp_irq[2]; unsigned int vaddr[2] = { 0, 0 }; int tmpnode, uctrlnode = prom_getchild(prom_root_node); tmpnode = prom_searchsiblings(uctrlnode, "obio"); if (tmpnode) uctrlnode = prom_getchild(tmpnode); uctrlnode = prom_searchsiblings(uctrlnode, "uctrl"); if (!uctrlnode) return -ENODEV; /* the prom mapped it for us */ len = prom_getproperty(uctrlnode, "address", (void *) vaddr, sizeof(vaddr)); driver->regs = (struct uctrl_regs *)vaddr[0]; len = prom_getproperty(uctrlnode, "intr", (char *) tmp_irq, sizeof(tmp_irq)); /* Flush device */ READUCTLDATA(len); if(!driver->irq) driver->irq = tmp_irq[0].pri; request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver); enable_irq(driver->irq); if (misc_register(&uctrl_dev)) { printk("%s: unable to get misc minor %d\n", __FUNCTION__, uctrl_dev.minor); disable_irq(driver->irq); free_irq(driver->irq, driver); return -ENODEV; } driver->regs->uctrl_intr = UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK; printk("uctrl: 0x%x (irq %s)\n", driver->regs, __irq_itoa(driver->irq)); uctrl_get_event_status(); uctrl_get_external_status(); return 0; }
int init_one_port(struct linux_ebus_device *dev) { struct parport tmpport, *p; unsigned long base; unsigned long config; int irq, dma; /* Pointer to NS87303 Configuration Registers */ config = dev->base_address[1]; /* Setup temporary access to Device operations */ tmpport.base = dev->base_address[0]; tmpport.ops = &parport_ax_ops; /* Configure IRQ to Push Pull, Level Low */ /* Enable ECP mode, set bit 2 of the CTR first */ tmpport.ops->write_control(&tmpport, 0x04); ns87303_modify(config, PCR, PCR_EPP_ENABLE | PCR_IRQ_ODRAIN, PCR_ECP_ENABLE | PCR_ECP_CLK_ENA | PCR_IRQ_POLAR); /* LPT CTR bit 5 controls direction of parallel port */ ns87303_modify(config, PTR, 0, PTR_LPT_REG_DIR); /* * Now continue initializing the port */ base = dev->base_address[0]; irq = dev->irqs[0]; dma = PARPORT_DMA_AUTO; if (!(p = parport_register_port(base, irq, dma, &parport_ax_ops))) return 0; /* Save away pointer to our EBus DMA */ p->private_data = (void *)dev->base_address[2]; p->modes = PARPORT_MODE_PCSPP | parport_PS2_supported(p); if (!check_region(p->base + 0x400, 3)) { p->modes |= parport_ECR_present(p); p->modes |= parport_ECP_supported(p); p->modes |= parport_ECPPS2_supported(p); } p->size = 3; if (p->dma == PARPORT_DMA_AUTO) p->dma = (p->modes & PARPORT_MODE_PCECP) ? 0 : PARPORT_DMA_NONE; printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); if (p->irq != PARPORT_IRQ_NONE) printk(", irq %s", __irq_itoa(p->irq)); if (p->dma != PARPORT_DMA_NONE) printk(", dma %d", p->dma); printk(" ["); { int f = 0; printmode(SPP); printmode(PS2); printmode(ECP); printmode(ECPPS2); } printk("]\n"); parport_proc_register(p); p->flags |= PARPORT_FLAG_COMA; p->ops->write_control(p, 0x0c); p->ops->write_data(p, 0); if (parport_probe_hook) (*parport_probe_hook)(p); return 1; }
__initfunc(void fill_ebus_child(int node, struct linux_prom_registers *preg, struct linux_ebus_child *dev)) { 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); 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) { 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]]; } len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); if ((len == -1) || (len == 0)) { dev->num_irqs = 0; /* * Oh, well, some PROMs don't export interrupts * property to children of EBus devices... * * Be smart about PS/2 keyboard and mouse. */ if (!strcmp(dev->parent->prom_name, "8042")) { if (!strcmp(dev->prom_name, "kb_ps2")) { dev->num_irqs = 1; dev->irqs[0] = dev->parent->irqs[0]; } else { dev->num_irqs = 1; dev->irqs[0] = dev->parent->irqs[1]; } } } else { dev->num_irqs = len / sizeof(irqs[0]); for (i = 0; i < dev->num_irqs; i++) { ebus_intmap_match(dev->bus, preg, &irqs[i]); dev->irqs[i] = psycho_irq_build(dev->bus->parent, dev->bus->self, irqs[i]); } } #ifdef DEBUG_FILL_EBUS_DEV dprintf("child '%s': address%s\n", dev->prom_name, dev->num_addrs > 1 ? "es" : ""); for (i = 0; i < dev->num_addrs; i++) dprintf(" %016lx\n", dev->base_address[i]); 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 }
__initfunc(void fill_ebus_device(int node, struct linux_ebus_device *dev)) { 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); 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__); } 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->base_address[n]; dev->base_address[i] += (unsigned long)regs[i].phys_addr; } len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); if ((len == -1) || (len == 0)) { dev->num_irqs = 0; } else { dev->num_irqs = len / sizeof(irqs[0]); for (i = 0; i < dev->num_irqs; i++) { ebus_intmap_match(dev->bus, ®s[0], &irqs[i]); dev->irqs[i] = psycho_irq_build(dev->bus->parent, dev->bus->self, irqs[i]); } } #ifdef DEBUG_FILL_EBUS_DEV dprintf("'%s': address%s\n", dev->prom_name, dev->num_addrs > 1 ? "es" : ""); for (i = 0; i < dev->num_addrs; i++) dprintf(" %016lx\n", dev->base_address[i]); 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)); child = dev->children; child->next = 0; child->parent = dev; child->bus = dev->bus; 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 = child->next; child->next = 0; child->parent = dev; child->bus = dev->bus; fill_ebus_child(node, ®s[0], child); } } }
/** * usb_hcd_pci_probe - initialize PCI-based HCDs * @dev: USB Host Controller being probed * @id: pci hotplug id connecting controller to HCD framework * Context: !in_interrupt() * * Allocates basic PCI resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * * Store this function in the HCD's struct pci_driver as probe(). */ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) { struct hc_driver *driver; unsigned long resource, len; void __iomem *base; struct usb_hcd *hcd; int retval, region; char buf [8], *bufp = buf; if (usb_disabled()) return -ENODEV; if (!id || !(driver = (struct hc_driver *) id->driver_data)) return -EINVAL; if (pci_enable_device (dev) < 0) return -ENODEV; dev->current_state = 0; dev->dev.power.power_state = 0; if (!dev->irq) { dev_err (&dev->dev, "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", pci_name(dev)); retval = -ENODEV; goto done; } if (driver->flags & HCD_MEMORY) { // EHCI, OHCI region = 0; resource = pci_resource_start (dev, 0); len = pci_resource_len (dev, 0); if (!request_mem_region (resource, len, driver->description)) { dev_dbg (&dev->dev, "controller already in use\n"); retval = -EBUSY; goto done; } base = ioremap_nocache (resource, len); if (base == NULL) { dev_dbg (&dev->dev, "error mapping memory\n"); retval = -EFAULT; clean_1: release_mem_region (resource, len); dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); goto done; } } else { // UHCI resource = len = 0; for (region = 0; region < PCI_ROM_RESOURCE; region++) { if (!(pci_resource_flags (dev, region) & IORESOURCE_IO)) continue; resource = pci_resource_start (dev, region); len = pci_resource_len (dev, region); if (request_region (resource, len, driver->description)) break; } if (region == PCI_ROM_RESOURCE) { dev_dbg (&dev->dev, "no i/o regions available\n"); retval = -EBUSY; goto done; } base = (void __iomem *) resource; } // driver->reset(), later on, will transfer device from // control by SMM/BIOS to control by Linux (if needed) hcd = driver->hcd_alloc (); if (hcd == NULL) { dev_dbg (&dev->dev, "hcd alloc fail\n"); retval = -ENOMEM; clean_2: if (driver->flags & HCD_MEMORY) { iounmap (base); goto clean_1; } else { release_region (resource, len); dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); goto done; } } // hcd zeroed everything hcd->regs = base; hcd->region = region; pci_set_drvdata (dev, hcd); hcd->driver = driver; hcd->description = driver->description; hcd->self.bus_name = pci_name(dev); #ifdef CONFIG_PCI_NAMES hcd->product_desc = dev->pretty_name; #else if (hcd->product_desc == NULL) hcd->product_desc = "USB Host Controller"; #endif hcd->self.controller = &dev->dev; if ((retval = hcd_buffer_create (hcd)) != 0) { clean_3: kfree (hcd); goto clean_2; } dev_info (hcd->self.controller, "%s\n", hcd->product_desc); /* till now HC has been in an indeterminate state ... */ if (driver->reset && (retval = driver->reset (hcd)) < 0) { dev_err (hcd->self.controller, "can't reset\n"); goto clean_3; } hcd->state = USB_STATE_HALT; pci_set_master (dev); #ifndef __sparc__ sprintf (buf, "%d", dev->irq); #else bufp = __irq_itoa(dev->irq); #endif retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd); if (retval != 0) { dev_err (hcd->self.controller, "request interrupt %s failed\n", bufp); goto clean_3; } hcd->irq = dev->irq; dev_info (hcd->self.controller, "irq %s, %s 0x%lx\n", bufp, (driver->flags & HCD_MEMORY) ? "pci mem" : "io base", resource); usb_bus_init (&hcd->self); hcd->self.op = &usb_hcd_operations; hcd->self.release = &usb_hcd_release; hcd->self.hcpriv = (void *) hcd; init_timer (&hcd->rh_timer); INIT_LIST_HEAD (&hcd->dev_list); usb_register_bus (&hcd->self); if ((retval = driver->start (hcd)) < 0) { dev_err (hcd->self.controller, "init error %d\n", retval); usb_hcd_pci_remove (dev); } done: if (retval != 0) pci_disable_device (dev); return retval; }
int usb_hcd_amba_probe (struct amba_device *dev, void *vid) { int retval = 0; char buf [8], *bufp = buf; struct usb_bus *bus = NULL; struct usb_hcd *hcd = NULL; void *device_base = NULL; struct amba_id *id = (struct amba_id *)vid; struct hc_driver *driver = (struct hc_driver *)id->data; #if defined (CONFIG_USB_EHCI_PNX0106) && defined (GPIO_USB_POWER_FAULT) init_timer (&timer_check_usb_power_fault); timer_check_usb_power_fault.function = check_usb_power_fault_func; timer_check_usb_power_fault.data = 0; #endif proc_vbus_init(); usb2ip_init (dev); if (driver->flags & HCD_MEMORY) { // EHCI, OHCI /* map the address (already requested by amba_device) */ device_base = ioremap_nocache( dev->res.start, dev->res.end - dev->res.start + 1 ) ; if ( !device_base ) { printk( KERN_ERR "%s: failed to remap the amba registers\n", __FUNCTION__) ; return -1 ; } } else { printk (KERN_ERR "%s: tried to allocate i/o memory for UHCI\n", __FUNCTION__); } hcd = driver->hcd_alloc (); if (hcd == NULL) { printk(KERN_DEBUG "%s: hcd alloc fail\n", __FUNCTION__); retval = -ENOMEM; clean_1: if (driver->flags & HCD_MEMORY) { iounmap (device_base); device_base = 0; } printk(KERN_DEBUG "hcd-amba::init usb_amba fail, %d\n", retval); goto done; } // hcd zeroed everything hcd->regs = device_base; //amba_set_drvdata (dev, hcd); hcd->pdev = dev; hcd->driver = driver; hcd->description = driver->description; if (hcd->product_desc == NULL) hcd->product_desc = "USB EHCI 1.0 Host Controller (amba)"; hcd->state = USB_STATE_HALT; #ifndef __sparc__ sprintf (buf, "%d", dev->irq[0]); #else bufp = __irq_itoa(dev->irq[0]); #endif /* request the irq (there should be one) */ retval = request_irq (dev->irq[0], hcd_irq, 0/*SA_SHIRQ*/, "usb_ehci", hcd); if (retval) { printk(KERN_ERR "hcd-amba.c :: request interrupt %s failed\n", bufp); retval = -EBUSY; goto clean_1; } hcd->irq = dev->irq[0]; bus = usb_alloc_bus (&hcd_operations); if (bus == NULL) { printk(KERN_ERR "usb_alloc_bus fail\n"); retval = -ENOMEM; free_irq (dev->irq, hcd); goto clean_1; } hcd->bus = bus; strcpy(dev->slot_name, "1"); bus->bus_name = dev->slot_name; bus->hcpriv = (void *) hcd; INIT_LIST_HEAD (&hcd->dev_list); INIT_LIST_HEAD (&hcd->hcd_list); down (&hcd_list_lock); list_add (&hcd->hcd_list, &hcd_list); up (&hcd_list_lock); usb_register_bus (bus); if ((retval = driver->start (hcd)) < 0) usb_hcd_amba_remove (dev); done: return retval; }
/** * usb_hcd_pci_probe - initialize PCI-based HCDs * @dev: USB Host Controller being probed * @id: pci hotplug id connecting controller to HCD framework * Context: !in_interrupt() * * Allocates basic PCI resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * * Store this function in the HCD's struct pci_driver as probe(). */ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) { struct hc_driver *driver; unsigned long resource, len; void *base; struct usb_hcd *hcd; int retval, region; char buf [8], *bufp = buf; if (usb_disabled()) return -ENODEV; if (!id || !(driver = (struct hc_driver *) id->driver_data)) return -EINVAL; if (pci_enable_device (dev) < 0) return -ENODEV; if (!dev->irq) { err ("Found HC with no IRQ. Check BIOS/PCI %s setup!", dev->slot_name); return -ENODEV; } if (driver->flags & HCD_MEMORY) { // EHCI, OHCI region = 0; resource = pci_resource_start (dev, 0); len = pci_resource_len (dev, 0); if (!request_mem_region (resource, len, driver->description)) { dbg ("controller already in use"); return -EBUSY; } base = ioremap_nocache (resource, len); if (base == NULL) { dbg ("error mapping memory"); retval = -EFAULT; clean_1: release_mem_region (resource, len); err ("init %s fail, %d", dev->slot_name, retval); return retval; } } else { // UHCI resource = len = 0; for (region = 0; region < PCI_ROM_RESOURCE; region++) { if (!(pci_resource_flags (dev, region) & IORESOURCE_IO)) continue; resource = pci_resource_start (dev, region); len = pci_resource_len (dev, region); if (request_region (resource, len, driver->description)) break; } if (region == PCI_ROM_RESOURCE) { dbg ("no i/o regions available"); return -EBUSY; } base = (void *) resource; } // driver->start(), later on, will transfer device from // control by SMM/BIOS to control by Linux (if needed) pci_set_master (dev); hcd = driver->hcd_alloc (); if (hcd == NULL){ dbg ("hcd alloc fail"); retval = -ENOMEM; clean_2: if (driver->flags & HCD_MEMORY) { iounmap (base); goto clean_1; } else { release_region (resource, len); err ("init %s fail, %d", dev->slot_name, retval); return retval; } } pci_set_drvdata (dev, hcd); hcd->driver = driver; hcd->description = driver->description; hcd->pdev = dev; hcd->self.bus_name = dev->slot_name; hcd->product_desc = dev->dev.name; hcd->self.controller = &dev->dev; hcd->controller = hcd->self.controller; if ((retval = hcd_buffer_create (hcd)) != 0) { clean_3: driver->hcd_free (hcd); goto clean_2; } dev_info (hcd->controller, "%s\n", hcd->product_desc); #ifndef __sparc__ sprintf (buf, "%d", dev->irq); #else bufp = __irq_itoa(dev->irq); #endif if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd) != 0) { dev_err (hcd->controller, "request interrupt %s failed\n", bufp); retval = -EBUSY; goto clean_3; } hcd->irq = dev->irq; hcd->regs = base; hcd->region = region; dev_info (hcd->controller, "irq %s, %s %p\n", bufp, (driver->flags & HCD_MEMORY) ? "pci mem" : "io base", base); usb_bus_init (&hcd->self); hcd->self.op = &usb_hcd_operations; hcd->self.hcpriv = (void *) hcd; INIT_LIST_HEAD (&hcd->dev_list); usb_register_bus (&hcd->self); if ((retval = driver->start (hcd)) < 0) usb_hcd_pci_remove (dev); return retval; }
static int __devinit hc_found_ohci (struct pci_dev *dev, int irq, void *mem_base, const struct pci_device_id *id) { ohci_t * ohci; char buf[8], *bufp = buf; int ret; #ifndef __sparc__ sprintf(buf, "%d", irq); #else bufp = __irq_itoa(irq); #endif printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n", (unsigned long) mem_base, bufp); printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name); ohci = hc_alloc_ohci (dev, mem_base); if (!ohci) { return -ENOMEM; } if ((ret = ohci_mem_init (ohci)) < 0) { hc_release_ohci (ohci); return ret; } ohci->flags = id->driver_data; /* Check for NSC87560. We have to look at the bridge (fn1) to identify the USB (fn2). This quirk might apply to more or even all NSC stuff I don't know.. */ if(dev->vendor == PCI_VENDOR_ID_NS) { struct pci_dev *fn1 = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1)); if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO) ohci->flags |= OHCI_QUIRK_SUCKYIO; } if (ohci->flags & OHCI_QUIRK_SUCKYIO) printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n"); if (ohci->flags & OHCI_QUIRK_AMD756) printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n"); if (hc_reset (ohci) < 0) { hc_release_ohci (ohci); return -ENODEV; } /* FIXME this is a second HC reset; why?? */ writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); wait_ms (10); usb_register_bus (ohci->bus); if (request_irq (irq, hc_interrupt, SA_SHIRQ, ohci_pci_driver.name, ohci) != 0) { err ("request interrupt %s failed", bufp); hc_release_ohci (ohci); return -EBUSY; } ohci->irq = irq; if (hc_start (ohci) < 0) { err ("can't start usb-%s", dev->slot_name); hc_release_ohci (ohci); return -EBUSY; } #ifdef DEBUG ohci_dump (ohci, 1); #endif return 0; }
__initfunc(static void fill_sbus_device(int nd, struct linux_sbus_device *sbus_dev)) { int grrr, len; unsigned long dev_base_addr, base; sbus_dev->prom_node = nd; prom_getstring(nd, "name", lbuf, sizeof(lbuf)); strcpy(sbus_dev->prom_name, lbuf); dev_base_addr = prom_getint(nd, "address"); if(dev_base_addr != -1) sbus_dev->sbus_addr = dev_base_addr; len = prom_getproperty(nd, "reg", (void *) sbus_dev->reg_addrs, sizeof(sbus_dev->reg_addrs)); if(len == -1) goto no_regs; if(len%sizeof(struct linux_prom_registers)) { prom_printf("WHOOPS: proplen for %s was %d, need multiple of %d\n", sbus_dev->prom_name, len, (int) sizeof(struct linux_prom_registers)); panic("fill_sbus_device"); } sbus_dev->num_registers = (len/sizeof(struct linux_prom_registers)); sbus_dev->ranges_applied = 0; base = (unsigned long) sbus_dev->reg_addrs[0].phys_addr; if(base>=SUN_SBUS_BVADDR || (sparc_cpu_model != sun4c && sparc_cpu_model != sun4)) { /* Ahh, we can determine the slot and offset */ if(sparc_cpu_model == sun4u) { /* A bit tricky on the SYSIO. */ sbus_dev->slot = sbus_dev->reg_addrs[0].which_io; sbus_dev->offset = sbus_dev_offset(base); } else if (sparc_cpu_model == sun4d) { sbus_dev->slot = sbus_dev->reg_addrs[0].which_io; sbus_dev->offset = base; } else { sbus_dev->slot = sbus_dev_slot(base); sbus_dev->offset = sbus_dev_offset(base); } } else { /* Grrr, gotta do calculations to fix things up */ sbus_dev->slot = sbus_dev->reg_addrs[0].which_io; sbus_dev->offset = base; sbus_dev->reg_addrs[0].phys_addr = sbus_devaddr(sbus_dev->slot, base); for(grrr=1; grrr<sbus_dev->num_registers; grrr++) { base = (unsigned long) sbus_dev->reg_addrs[grrr].phys_addr; sbus_dev->reg_addrs[grrr].phys_addr = sbus_devaddr(sbus_dev->slot, base); } /* That surely sucked */ } sbus_dev->sbus_addr = (unsigned long) sbus_dev->reg_addrs[0].phys_addr; if(len>(sizeof(struct linux_prom_registers)*PROMREG_MAX)) { prom_printf("WHOOPS: I got too many register addresses for %s len=%d\n", sbus_dev->prom_name, len); panic("sbus device register overflow"); } no_regs: len = prom_getproperty(nd, "address", (void *) sbus_dev->sbus_vaddrs, sizeof(sbus_dev->sbus_vaddrs)); if(len == -1) len=0; if(len&3) { prom_printf("Grrr, I didn't get a multiple of 4 proplen " "for device %s got %d\n", sbus_dev->prom_name, len); len=0; } sbus_dev->num_vaddrs = (len/4); #ifdef __sparc_v9__ len = prom_getproperty(nd, "interrupts", (void *)irqs, sizeof(irqs)); if((len == -1) || (len == 0)) { sbus_dev->irqs[0] = 0; sbus_dev->num_irqs = 0; } else { sbus_dev->num_irqs = 1; if (irqs[0].pri < 0x20) sbus_dev->irqs[0] = sbus_build_irq(sbus_dev->my_bus, irqs[0].pri + (sbus_dev->slot * 8)); else sbus_dev->irqs[0] = sbus_build_irq(sbus_dev->my_bus, irqs[0].pri); } #else len = prom_getproperty(nd, "intr", (void *)irqs, sizeof(irqs)); if (len == -1) len=0; if (len&7) { prom_printf("Grrr, I didn't get a multiple of 8 proplen for " "device %s got %d\n", sbus_dev->prom_name, len); len=0; } if (len > 4 * 8) { prom_printf("Device %s has more than 4 interrupts\n", sbus_dev->prom_name); len = 4 * 8; } sbus_dev->num_irqs=(len/8); if(sbus_dev->num_irqs == 0) sbus_dev->irqs[0]=0; else if (sparc_cpu_model != sun4d) for (len = 0; len < sbus_dev->num_irqs; len++) sbus_dev->irqs[len] = irqs[len].pri; else { extern unsigned int sun4d_build_irq(struct linux_sbus_device *sdev, int irq); for (len = 0; len < sbus_dev->num_irqs; len++) sbus_dev->irqs[len] = sun4d_build_irq(sbus_dev, irqs[len].pri); } #endif #ifdef DEBUG_FILL #ifdef __sparc_v9__ prom_printf("Found %s at SBUS slot %x offset %016lx ", sbus_dev->prom_name, sbus_dev->slot, sbus_dev->offset); if (sbus_dev->irqs[0]) prom_printf("irq %s\n", __irq_itoa(sbus_dev->irqs[0])); else prom_printf("\n"); prom_printf("Base address %016lx\n", sbus_dev->sbus_addr); #else prom_printf("Found %s at SBUS slot %x offset %08lx irq-level %d\n", sbus_dev->prom_name, sbus_dev->slot, sbus_dev->offset, sbus_dev->irqs[0]); prom_printf("Base address %08lx\n", sbus_dev->sbus_addr); #endif prom_printf("REGISTERS: Probed %d register(s)\n", sbus_dev->num_registers); for(len=0; len<sbus_dev->num_registers; len++) #ifdef __sparc_v9__ prom_printf("Regs<%d> at address<%08lx> IO-space<%d> size<%d " "bytes, %d words>\n", (int) len, (unsigned long) sbus_dev->reg_addrs[len].phys_addr, sbus_dev->reg_addrs[len].which_io, sbus_dev->reg_addrs[len].reg_size, (sbus_dev->reg_addrs[len].reg_size/4)); #else prom_printf("Regs<%d> at address<%016lx> IO-space<%d> size<%d " "bytes, %d words>\n", (int) len, (unsigned long) sbus_dev->reg_addrs[len].phys_addr, sbus_dev->reg_addrs[len].which_io, sbus_dev->reg_addrs[len].reg_size, (sbus_dev->reg_addrs[len].reg_size/4)); #endif #endif }