static int pxauart_match(device_t parent, cfdata_t cf, void *aux) { struct pxaip_attach_args *pxa = aux; bus_space_tag_t bt = &pxa2x0_a4x_bs_tag; /* XXX: This sucks */ bus_space_handle_t bh; struct pxa2x0_gpioconf *gpioconf; u_int gpio; int rv, i; switch (pxa->pxa_addr) { case PXA2X0_FFUART_BASE: if (pxa->pxa_intr != PXA2X0_INT_FFUART) return (0); gpioconf = CPU_IS_PXA250 ? pxa25x_com_ffuart_gpioconf : pxa27x_com_ffuart_gpioconf; break; case PXA2X0_STUART_BASE: if (pxa->pxa_intr != PXA2X0_INT_STUART) return (0); gpioconf = CPU_IS_PXA250 ? pxa25x_com_stuart_gpioconf : pxa27x_com_stuart_gpioconf; break; case PXA2X0_BTUART_BASE: /* XXX: Config file option ... */ if (pxa->pxa_intr != PXA2X0_INT_BTUART) return (0); gpioconf = CPU_IS_PXA250 ? pxa25x_com_btuart_gpioconf : pxa27x_com_btuart_gpioconf; break; case PXA2X0_HWUART_BASE: if (pxa->pxa_intr != PXA2X0_INT_HWUART) return (0); if (CPU_IS_PXA270) return (0); gpioconf = pxa25x_com_hwuart_gpioconf; break; default: return (0); } for (i = 0; gpioconf[i].pin != -1; i++) { gpio = pxa2x0_gpio_get_function(gpioconf[i].pin); if (GPIO_FN(gpio) != GPIO_FN(gpioconf[i].value) || GPIO_FN_IS_OUT(gpio) != GPIO_FN_IS_OUT(gpioconf[i].value)) return (0); } pxa->pxa_size = 0x20; if (com_is_console(bt, pxa->pxa_addr, NULL)) return (1); if (bus_space_map(bt, pxa->pxa_addr, pxa->pxa_size, 0, &bh)) return (0); /* Make sure the UART is enabled */ bus_space_write_1(bt, bh, com_ier, IER_EUART); rv = comprobe1(bt, bh); bus_space_unmap(bt, bh, pxa->pxa_size); return (rv); }
/* * ae_attach: * * Attach an ae interface to the system. */ void ae_attach(device_t parent, device_t self, void *aux) { const uint8_t *enaddr; prop_data_t ea; struct ae_softc *sc = device_private(self); struct arbus_attach_args *aa = aux; struct ifnet *ifp = &sc->sc_ethercom.ec_if; int i, error; sc->sc_dev = self; callout_init(&sc->sc_tick_callout, 0); printf(": Atheros AR531X 10/100 Ethernet\n"); /* * Try to get MAC address. */ ea = prop_dictionary_get(device_properties(sc->sc_dev), "mac-address"); if (ea == NULL) { printf("%s: unable to get mac-addr property\n", device_xname(sc->sc_dev)); return; } KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); enaddr = prop_data_data_nocopy(ea); /* Announce ourselves. */ printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev), ether_sprintf(enaddr)); sc->sc_cirq = aa->aa_cirq; sc->sc_mirq = aa->aa_mirq; sc->sc_st = aa->aa_bst; sc->sc_dmat = aa->aa_dmat; SIMPLEQ_INIT(&sc->sc_txfreeq); SIMPLEQ_INIT(&sc->sc_txdirtyq); /* * Map registers. */ sc->sc_size = aa->aa_size; if ((error = bus_space_map(sc->sc_st, aa->aa_addr, sc->sc_size, 0, &sc->sc_sh)) != 0) { printf("%s: unable to map registers, error = %d\n", device_xname(sc->sc_dev), error); goto fail_0; } /* * Allocate the control data structures, and create and load the * DMA map for it. */ if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct ae_control_data), PAGE_SIZE, 0, &sc->sc_cdseg, 1, &sc->sc_cdnseg, 0)) != 0) { printf("%s: unable to allocate control data, error = %d\n", device_xname(sc->sc_dev), error); goto fail_1; } if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg, sizeof(struct ae_control_data), (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) { printf("%s: unable to map control data, error = %d\n", device_xname(sc->sc_dev), error); goto fail_2; } if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct ae_control_data), 1, sizeof(struct ae_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { printf("%s: unable to create control data DMA map, " "error = %d\n", device_xname(sc->sc_dev), error); goto fail_3; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, sc->sc_control_data, sizeof(struct ae_control_data), NULL, 0)) != 0) { printf("%s: unable to load control data DMA map, error = %d\n", device_xname(sc->sc_dev), error); goto fail_4; } /* * Create the transmit buffer DMA maps. */ for (i = 0; i < AE_TXQUEUELEN; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, AE_NTXSEGS, MCLBYTES, 0, 0, &sc->sc_txsoft[i].txs_dmamap)) != 0) { printf("%s: unable to create tx DMA map %d, " "error = %d\n", device_xname(sc->sc_dev), i, error); goto fail_5; } } /* * Create the receive buffer DMA maps. */ for (i = 0; i < AE_NRXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) { printf("%s: unable to create rx DMA map %d, " "error = %d\n", device_xname(sc->sc_dev), i, error); goto fail_6; } sc->sc_rxsoft[i].rxs_mbuf = NULL; } /* * Reset the chip to a known state. */ ae_reset(sc); /* * From this point forward, the attachment cannot fail. A failure * before this point releases all resources that may have been * allocated. */ sc->sc_flags |= AE_ATTACHED; /* * Initialize our media structures. This may probe the MII, if * present. */ sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = ae_mii_readreg; sc->sc_mii.mii_writereg = ae_mii_writereg; sc->sc_mii.mii_statchg = ae_mii_statchg; sc->sc_ethercom.ec_mii = &sc->sc_mii; ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); sc->sc_tick = ae_mii_tick; strcpy(ifp->if_xname, device_xname(sc->sc_dev)); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; sc->sc_if_flags = ifp->if_flags; ifp->if_ioctl = ae_ioctl; ifp->if_start = ae_start; ifp->if_watchdog = ae_watchdog; ifp->if_init = ae_init; ifp->if_stop = ae_stop; IFQ_SET_READY(&ifp->if_snd); /* * We can support 802.1Q VLAN-sized frames. */ sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; /* * Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, enaddr); ether_set_ifflags_cb(&sc->sc_ethercom, ae_ifflags_cb); rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); /* * Make sure the interface is shutdown during reboot. */ sc->sc_sdhook = shutdownhook_establish(ae_shutdown, sc); if (sc->sc_sdhook == NULL) printf("%s: WARNING: unable to establish shutdown hook\n", device_xname(sc->sc_dev)); /* * Add a suspend hook to make sure we come back up after a * resume. */ sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev), ae_power, sc); if (sc->sc_powerhook == NULL) printf("%s: WARNING: unable to establish power hook\n", device_xname(sc->sc_dev)); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ fail_6: for (i = 0; i < AE_NRXDESC; i++) { if (sc->sc_rxsoft[i].rxs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].rxs_dmamap); } fail_5: for (i = 0; i < AE_TXQUEUELEN; i++) { if (sc->sc_txsoft[i].txs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); fail_4: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); fail_3: bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, sizeof(struct ae_control_data)); fail_2: bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg); fail_1: bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size); fail_0: return; }
static int fdc_isa_probe(device_t parent, cfdata_t match, void *aux) { struct isa_attach_args *ia = aux; bus_space_tag_t iot; bus_space_handle_t ioh, ctl_ioh, base_ioh; int rv, iobase; iot = ia->ia_iot; rv = 0; if (ia->ia_nio < 1) return (0); if (ia->ia_nirq < 1) return (0); if (ia->ia_ndrq < 1) return (0); if (ISA_DIRECT_CONFIG(ia)) return (0); /* Disallow wildcarded I/O addresses. */ if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) return (0); /* Don't allow wildcarded IRQ/DRQ. */ if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) return (0); if (ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ) return (0); /* Map the I/O space. */ iobase = ia->ia_io[0].ir_addr; if (bus_space_map(iot, iobase, 6 /* FDC_NPORT */, 0, &base_ioh)) return (0); if (bus_space_subregion(iot, base_ioh, 2, 4, &ioh)) { bus_space_unmap(iot, base_ioh, 6); return (0); } if (bus_space_map(iot, iobase + fdctl + 2, 1, 0, &ctl_ioh)) { bus_space_unmap(iot, base_ioh, 6); return (0); } /* Not needed for the rest of the probe. */ bus_space_unmap(iot, ctl_ioh, 1); /* reset */ bus_space_write_1(iot, ioh, fdout, 0); delay(100); bus_space_write_1(iot, ioh, fdout, FDO_FRST); /* see if it can handle a command */ if (out_fdc(iot, ioh, NE7CMD_SPECIFY) < 0) goto out; out_fdc(iot, ioh, 0xdf); out_fdc(iot, ioh, 2); rv = 1; ia->ia_nio = 1; ia->ia_io[0].ir_size = FDC_NPORT; ia->ia_nirq = 1; ia->ia_ndrq = 1; ia->ia_niomem = 0; out: bus_space_unmap(iot, base_ioh, 6 /* FDC_NPORT */); return (rv); }
static int smu_attach(device_t dev) { struct smu_softc *sc; phandle_t node, child; uint8_t data[12]; sc = device_get_softc(dev); mtx_init(&sc->sc_mtx, "smu", NULL, MTX_DEF); sc->sc_cur_cmd = NULL; sc->sc_doorbellirqid = -1; sc->sc_u3 = 0; if (OF_finddevice("/u3") != -1) sc->sc_u3 = 1; /* * Map the mailbox area. This should be determined from firmware, * but I have not found a simple way to do that. */ bus_dma_tag_create(NULL, 16, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, PAGE_SIZE, 1, PAGE_SIZE, 0, NULL, NULL, &(sc->sc_dmatag)); sc->sc_bt = &bs_le_tag; bus_space_map(sc->sc_bt, SMU_MAILBOX, 4, 0, &sc->sc_mailbox); /* * Allocate the command buffer. This can be anywhere in the low 4 GB * of memory. */ bus_dmamem_alloc(sc->sc_dmatag, (void **)&sc->sc_cmd, BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->sc_cmd_dmamap); bus_dmamap_load(sc->sc_dmatag, sc->sc_cmd_dmamap, sc->sc_cmd, PAGE_SIZE, smu_phys_callback, sc, 0); STAILQ_INIT(&sc->sc_cmdq); /* * Set up handlers to change CPU voltage when CPU frequency is changed. */ EVENTHANDLER_REGISTER(cpufreq_pre_change, smu_cpufreq_pre_change, dev, EVENTHANDLER_PRI_ANY); EVENTHANDLER_REGISTER(cpufreq_post_change, smu_cpufreq_post_change, dev, EVENTHANDLER_PRI_ANY); /* * Detect and attach child devices. */ node = ofw_bus_get_node(dev); for (child = OF_child(node); child != 0; child = OF_peer(child)) { char name[32]; memset(name, 0, sizeof(name)); OF_getprop(child, "name", name, sizeof(name)); if (strncmp(name, "rpm-fans", 9) == 0 || strncmp(name, "fans", 5) == 0) smu_attach_fans(dev, child); if (strncmp(name, "sensors", 8) == 0) smu_attach_sensors(dev, child); if (strncmp(name, "smu-i2c-control", 15) == 0) smu_attach_i2c(dev, child); } /* Some SMUs have the I2C children directly under the bus. */ smu_attach_i2c(dev, node); /* * Collect calibration constants. */ smu_get_datablock(dev, SMU_CPUTEMP_CAL, data, sizeof(data)); sc->sc_cpu_diode_scale = (data[4] << 8) + data[5]; sc->sc_cpu_diode_offset = (data[6] << 8) + data[7]; smu_get_datablock(dev, SMU_CPUVOLT_CAL, data, sizeof(data)); sc->sc_cpu_volt_scale = (data[4] << 8) + data[5]; sc->sc_cpu_volt_offset = (data[6] << 8) + data[7]; sc->sc_cpu_curr_scale = (data[8] << 8) + data[9]; sc->sc_cpu_curr_offset = (data[10] << 8) + data[11]; smu_get_datablock(dev, SMU_SLOTPW_CAL, data, sizeof(data)); sc->sc_slots_pow_scale = (data[4] << 8) + data[5]; sc->sc_slots_pow_offset = (data[6] << 8) + data[7]; /* * Set up LED interface */ sc->sc_leddev = led_create(smu_set_sleepled, dev, "sleepled"); /* * Reset on power loss behavior */ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "server_mode", CTLTYPE_INT | CTLFLAG_RW, dev, 0, smu_server_mode, "I", "Enable reboot after power failure"); /* * Set up doorbell interrupt. */ sc->sc_doorbellirqid = 0; sc->sc_doorbellirq = bus_alloc_resource_any(smu_doorbell, SYS_RES_IRQ, &sc->sc_doorbellirqid, RF_ACTIVE); bus_setup_intr(smu_doorbell, sc->sc_doorbellirq, INTR_TYPE_MISC | INTR_MPSAFE, NULL, smu_doorbell_intr, dev, &sc->sc_doorbellirqcookie); powerpc_config_intr(rman_get_start(sc->sc_doorbellirq), INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); /* * Connect RTC interface. */ clock_register(dev, 1000); /* * Learn about shutdown events */ EVENTHANDLER_REGISTER(shutdown_final, smu_shutdown, dev, SHUTDOWN_PRI_LAST); return (bus_generic_attach(dev)); }
/* * This routine is called after all the ISA devices are configured, * to avoid conflict. */ static void yds_configure_legacy(device_t self) #define FLEXIBLE (sc->sc_flags & YDS_CAP_LEGACY_FLEXIBLE) #define SELECTABLE (sc->sc_flags & YDS_CAP_LEGACY_SELECTABLE) { static const bus_addr_t opl_addrs[] = {0x388, 0x398, 0x3A0, 0x3A8}; static const bus_addr_t mpu_addrs[] = {0x330, 0x300, 0x332, 0x334}; struct yds_softc *sc; pcireg_t reg; device_t dev; int i; sc = device_private(self); if (!FLEXIBLE && !SELECTABLE) return; reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY); reg &= ~0x8133c03f; /* these bits are out of interest */ reg |= ((YDS_PCI_EX_LEGACY_IMOD) | (YDS_PCI_LEGACY_FMEN | YDS_PCI_LEGACY_MEN /*| YDS_PCI_LEGACY_MIEN*/)); reg |= YDS_PCI_EX_LEGACY_SMOD_DISABLE; if (FLEXIBLE) { pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg); delay(100*1000); } /* Look for OPL */ dev = 0; for (i = 0; i < sizeof(opl_addrs) / sizeof(bus_addr_t); i++) { if (SELECTABLE) { pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg | (i << (0+16))); delay(100*1000); /* wait 100ms */ } else pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_FM_BA, opl_addrs[i]); if (bus_space_map(sc->sc_opl_iot, opl_addrs[i], 4, 0, &sc->sc_opl_ioh) == 0) { struct audio_attach_args aa; aa.type = AUDIODEV_TYPE_OPL; aa.hwif = aa.hdl = NULL; dev = config_found(self, &aa, audioprint); if (dev == 0) bus_space_unmap(sc->sc_opl_iot, sc->sc_opl_ioh, 4); else { if (SELECTABLE) reg |= (i << (0+16)); break; } } } if (dev == 0) { reg &= ~YDS_PCI_LEGACY_FMEN; pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg); } else { /* Max. volume */ YWRITE4(sc, YDS_LEGACY_OUT_VOLUME, 0x3fff3fff); YWRITE4(sc, YDS_LEGACY_REC_VOLUME, 0x3fff3fff); } /* Look for MPU */ dev = NULL; for (i = 0; i < sizeof(mpu_addrs) / sizeof(bus_addr_t); i++) { if (SELECTABLE) pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg | (i << (4+16))); else pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_MPU_BA, mpu_addrs[i]); if (bus_space_map(sc->sc_mpu_iot, mpu_addrs[i], 2, 0, &sc->sc_mpu_ioh) == 0) { struct audio_attach_args aa; aa.type = AUDIODEV_TYPE_MPU; aa.hwif = aa.hdl = NULL; dev = config_found(self, &aa, audioprint); if (dev == 0) bus_space_unmap(sc->sc_mpu_iot, sc->sc_mpu_ioh, 2); else { if (SELECTABLE) reg |= (i << (4+16)); break; } } } if (dev == 0) { reg &= ~(YDS_PCI_LEGACY_MEN | YDS_PCI_LEGACY_MIEN); pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg); } sc->sc_mpu = dev; }
void ohci_aubus_attach(struct device *parent, struct device *self, void *aux) { ohci_softc_t *sc = (ohci_softc_t *)self; void *ih; usbd_status r; uint32_t x, tmp; struct aubus_attach_args *aa = aux; r = 0; sc->sc_size = USBH_SIZE; sc->iot = aa->aa_st; sc->sc_bus.dmatag = (bus_dma_tag_t)aa->aa_dt; if (bus_space_map(sc->iot, USBH_BASE, USBH_SIZE, 0, &sc->ioh)) { printf("%s: Unable to map USBH registers\n", sc->sc_bus.bdev.dv_xname); return; } /* * Enable the USB Host controller here. * As per 7.2 in the Au1500 manual: * * (1) Set CE bit to enable clocks. * (2) Set E to enable OHCI * (3) Clear HCFS in OHCI_CONTROL. * (4) Wait for RD bit to be set. */ x = bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE); x |= UE_CE; bus_space_write_4(sc->iot, sc->ioh, USBH_ENABLE, x); delay(10); x |= UE_E; #ifdef __MIPSEB__ x |= UE_BE; #endif bus_space_write_4(sc->iot, sc->ioh, USBH_ENABLE, x); delay(10); x = bus_space_read_4(sc->iot, sc->ioh, OHCI_CONTROL); x &= ~(OHCI_HCFS_MASK); bus_space_write_4(sc->iot, sc->ioh, OHCI_CONTROL, x); delay(10); /* Need to read USBH_ENABLE twice in succession according to * au1500 Errata #7. */ for (x = 100; x; x--) { bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE); tmp = bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE); if (tmp&UE_RD) break; delay(1000); } printf(": Au1X00 OHCI\n"); /* Disable OHCI interrupts */ bus_space_write_4(sc->iot, sc->ioh, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); /* hook interrupt */ ih = au_intr_establish(aa->aa_irq[0], 0, IPL_USB, IST_LEVEL_LOW, ohci_intr, sc); if (ih == NULL) { printf("%s: couldn't establish interrupt\n", sc->sc_bus.bdev.dv_xname); } if (x) r = ohci_init(sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", sc->sc_bus.bdev.dv_xname, r); au_intr_disestablish(ih); return; } /* Attach USB device */ sc->sc_child = config_found((void *)sc, &sc->sc_bus, usbctlprint); }
void macfb_obio_attach(struct device *parent, struct device *self, void *aux) { struct obio_attach_args *oa = (struct obio_attach_args *) aux; struct macfb_softc *sc = (struct macfb_softc *)self; u_long length; u_int32_t vbase1, vbase2; struct macfb_devconfig *dc; sc->card_id = 0; sc->sc_tag = oa->oa_tag; dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK); bzero(dc, sizeof(*dc)); switch (current_mac_model->class) { case MACH_CLASSQ2: if (current_mac_model->machineid != MACH_MACLC575) { sc->sc_basepa = VALKYRIE_BASE; length = 0x00100000; /* 1MB */ if (sc->sc_basepa <= mac68k_vidphys && mac68k_vidphys < (sc->sc_basepa + length)) sc->sc_fbofs = mac68k_vidphys - sc->sc_basepa; else sc->sc_fbofs = 0; #ifdef DEBUG printf(" @ %lx", sc->sc_basepa + sc->sc_fbofs); #endif if (bus_space_map(sc->sc_tag, VALKYRIE_CONTROL_BASE, 0x40, 0, &sc->sc_regh) != 0) { printf(": can't map Valkyrie registers\n"); free(dc, M_DEVBUF); return; } /* Disable interrupts */ bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x18, 0x1); bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x40); printf(": Valkyrie\n"); break; } /* * Note: the only system in this class that does not have * the Valkyrie chip -- at least, that we know of -- is * the Performa/LC 57x series. This system has a version * of the DAFB controller, instead. * * If this assumption proves false, we'll have to be more * intelligent here. */ /*FALLTHROUGH*/ case MACH_CLASSQ: if (bus_space_map(sc->sc_tag, DAFB_CONTROL_BASE, 0x120, 0, &sc->sc_regh)) { printf(": can't map DAFB registers\n"); free(dc, M_DEVBUF); return; } sc->sc_basepa = DAFB_BASE; length = 0x00100000; /* 1MB */ /* Compute the current frame buffer offset */ vbase1 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x0) & 0xfff; /* * XXX The following exists because the DAFB v7 in these * systems doesn't return reasonable values to use for fbofs. * Ken'ichi Ishizaka gets credit for this hack. (sar 19990426) * (Does this get us the correct result for _all_ DAFB- * equipped systems and monitor combinations? It seems * possible, if not likely...) */ switch (current_mac_model->machineid) { case MACH_MACLC475: case MACH_MACLC475_33: case MACH_MACLC575: case MACH_MACQ605: case MACH_MACQ605_33: vbase1 &= 0x3f; break; } vbase2 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x4) & 0xf; sc->sc_fbofs = (vbase1 << 9) | (vbase2 << 5); #ifdef DEBUG printf(" @ %lx", sc->sc_basepa + sc->sc_fbofs); #endif /* Disable interrupts */ bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x104, 0); /* Clear any pending interrupts */ bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x10C, 0); bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x110, 0); bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x114, 0); printf(": DAFB, monitor sense %x\n", (bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x1c) & 0x7)); bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x120); if (bus_space_map(sc->sc_tag, DAFB_CMAP_BASE, 0x20, 0, &sc->sc_regh) == 0) { dc->dc_cmapregs = (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_regh); dc->dc_setcolor = dafb_setcolor; } break; case MACH_CLASSAV: sc->sc_basepa = CIVIC_BASE; length = 0x00200000; /* 2MB */ if (sc->sc_basepa <= mac68k_vidphys && mac68k_vidphys < (sc->sc_basepa + length)) sc->sc_fbofs = mac68k_vidphys - sc->sc_basepa; else sc->sc_fbofs = 0; #ifdef DEBUG printf(" @ %lx", sc->sc_basepa + sc->sc_fbofs); #endif if (bus_space_map(sc->sc_tag, CIVIC_CONTROL_BASE, PAGE_SIZE, 0, &sc->sc_regh) != 0) { printf(": can't map Civic registers\n"); free(dc, M_DEVBUF); return; } /* Disable interrupts */ bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x120, 0); bus_space_unmap(sc->sc_tag, sc->sc_regh, PAGE_SIZE); printf(": Civic\n"); break; case MACH_CLASSIIci: case MACH_CLASSIIsi: sc->sc_basepa = trunc_page(mac68k_vidphys); sc->sc_fbofs = m68k_page_offset(mac68k_vidphys); length = mac68k_vidlen + sc->sc_fbofs; #ifdef DEBUG printf(" @ %lx: RBV", sc->sc_basepa + sc->sc_fbofs); switch (via2_reg(rMonitor) & RBVMonitorMask) { case RBVMonIDBWP: printf(", 15\" monochrome portrait"); break; case RBVMonIDRGB12: printf(", 12\" color"); break; case RBVMonIDRGB15: printf(", 15\" color"); break; case RBVMonIDStd: printf(", Macintosh II"); break; default: printf(", unrecognized"); break; } printf(" display\n"); #else printf(": RBV\n"); #endif break; default: sc->sc_basepa = trunc_page(mac68k_vidphys); sc->sc_fbofs = m68k_page_offset(mac68k_vidphys); length = mac68k_vidlen + sc->sc_fbofs; #ifdef DEBUG printf(" @ %lx:", sc->sc_basepa + sc->sc_fbofs); #endif printf(": On-board video\n"); break; } if (bus_space_map(sc->sc_tag, sc->sc_basepa, length, 0, &sc->sc_handle)) { printf("%s: failed to map video RAM\n", sc->sc_dev.dv_xname); free(dc, M_DEVBUF); return; } if (sc->sc_basepa <= mac68k_vidphys && mac68k_vidphys < (sc->sc_basepa + length)) videoaddr = (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle) + sc->sc_fbofs; dc->dc_vaddr = (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle); dc->dc_paddr = sc->sc_basepa; dc->dc_offset = sc->sc_fbofs; dc->dc_wid = videosize & 0xffff; dc->dc_ht = (videosize >> 16) & 0xffff; dc->dc_depth = videobitdepth; dc->dc_rowbytes = videorowbytes; dc->dc_size = dc->dc_ht * dc->dc_rowbytes; /* Perform common video attachment. */ macfb_attach_common(sc, dc); }
/* * Attach this instance, and then all the sub-devices */ static void asc_vsbus_attach(struct device *parent, struct device *self, void *aux) { struct vsbus_attach_args *va = aux; struct asc_vsbus_softc *asc = (void *)self; struct ncr53c9x_softc *sc = &asc->sc_ncr53c9x; int error; asc_attached = 1; /* * Set up glue for MI code early; we use some of it here. */ sc->sc_glue = &asc_vsbus_glue; asc->sc_bst = va->va_iot; asc->sc_dmat = va->va_dmat; error = bus_space_map(asc->sc_bst, va->va_paddr - ASC_REG_NCR, ASC_REG_END, 0, &asc->sc_bsh); if (error) { printf(": failed to map registers: error=%d\n", error); return; } error = bus_space_subregion(asc->sc_bst, asc->sc_bsh, ASC_REG_NCR, ASC_REG_END - ASC_REG_NCR, &asc->sc_ncrh); if (error) { printf(": failed to map ncr registers: error=%d\n", error); return; } if (vax_boardtype == VAX_BTYP_46 || vax_boardtype == VAX_BTYP_48) { error = bus_space_subregion(asc->sc_bst, asc->sc_bsh, ASC_REG_KA46_ADR, sizeof(u_int32_t), &asc->sc_adrh); if (error) { printf(": failed to map adr register: error=%d\n", error); return; } error = bus_space_subregion(asc->sc_bst, asc->sc_bsh, ASC_REG_KA46_DIR, sizeof(u_int32_t), &asc->sc_dirh); if (error) { printf(": failed to map dir register: error=%d\n", error); return; } } else { /* This is a gross and disgusting kludge but it'll * save a bunch of ugly code. Unlike the VS4000/60, * the SCSI Address and direction registers are not * near the SCSI NCR registers and are inside the * block of general VAXstation registers. So we grab * them from there and knowing the internals of the * bus_space implementation, we cast to bus_space_handles. */ struct vsbus_softc *vsc = (struct vsbus_softc *) parent; asc->sc_adrh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_ADR); asc->sc_dirh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_DIR); #if 0 printf("\n%s: adrh=0x%08lx dirh=0x%08lx", self->dv_xname, asc->sc_adrh, asc->sc_dirh); ncr53c9x_debug = NCR_SHOWDMA|NCR_SHOWINTS|NCR_SHOWCMDS|NCR_SHOWPHASE|NCR_SHOWSTART|NCR_SHOWMSGS; #endif } error = bus_dmamap_create(asc->sc_dmat, ASC_MAXXFERSIZE, 1, ASC_MAXXFERSIZE, 0, BUS_DMA_NOWAIT, &asc->sc_dmamap); switch (vax_boardtype) { #if defined(VAX46) case VAX_BTYP_46: sc->sc_id = (clk_page[0xbc/2] >> clk_tweak) & 7; break; #endif default: sc->sc_id = 6; /* XXX need to get this from VMB */ break; } sc->sc_freq = ASC_FREQUENCY; /* gimme MHz */ sc->sc_freq /= 1000000; scb_vecalloc(va->va_cvec, (void (*)(void *)) ncr53c9x_intr, &asc->sc_ncr53c9x, SCB_ISTACK, &asc->sc_intrcnt); asc->sc_cvec = va->va_cvec; evcount_attach(&asc->sc_intrcnt, self->dv_xname, (void *)&asc->sc_cvec, &evcount_intr); /* * XXX More of this should be in ncr53c9x_attach(), but * XXX should we really poke around the chip that much in * XXX the MI code? Think about this more... */ /* * Set up static configuration info. */ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; sc->sc_cfg2 = NCRCFG2_SCSI2; sc->sc_cfg3 = 0; sc->sc_rev = NCR_VARIANT_NCR53C94; /* * XXX minsync and maxxfer _should_ be set up in MI code, * XXX but it appears to have some dependency on what sort * XXX of DMA we're hooked up to, etc. */ /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = (1000 / sc->sc_freq); sc->sc_maxxfer = 64 * 1024; /* Do the common parts of attachment. */ ncr53c9x_attach(sc, &asc_vsbus_ops, &asc_vsbus_dev); }
int acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa) { struct aml_value res; bus_size_t ec_sc, ec_data; int dtype, ctype; char *buf; int size, ret; int64_t gpe; struct acpi_ecdt *ecdt = aa->aaa_table; extern struct aml_node aml_root; /* Check if this is ECDT initialization */ if (ecdt) { /* Get GPE, Data and Control segments */ sc->sc_gpe = ecdt->gpe_bit; ctype = ecdt->ec_control.address_space_id; ec_sc = ecdt->ec_control.address; dtype = ecdt->ec_data.address_space_id; ec_data = ecdt->ec_data.address; /* Get devnode from header */ sc->sc_devnode = aml_searchname(&aml_root, ecdt->ec_id); goto ecdtdone; } if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &gpe)) { dnprintf(10, "%s: no _GPE\n", DEVNAME(sc)); return (1); } sc->sc_gpe = gpe; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) { dnprintf(10, "%s: no _CRS\n", DEVNAME(sc)); return (1); } /* Parse CRS to get control and data registers */ if (res.type != AML_OBJTYPE_BUFFER) { dnprintf(10, "%s: unknown _CRS type %d\n", DEVNAME(sc), res.type); aml_freevalue(&res); return (1); } size = res.length; buf = res.v_buffer; ret = acpiec_getregister(buf, size, &dtype, &ec_data); if (ret <= 0) { dnprintf(10, "%s: failed to read DATA from _CRS\n", DEVNAME(sc)); aml_freevalue(&res); return (1); } buf += ret; size -= ret; ret = acpiec_getregister(buf, size, &ctype, &ec_sc); if (ret <= 0) { dnprintf(10, "%s: failed to read S/C from _CRS\n", DEVNAME(sc)); aml_freevalue(&res); return (1); } buf += ret; size -= ret; if (size != 2 || *buf != RES_TYPE_ENDTAG) { dnprintf(10, "%s: no _CRS end tag\n", DEVNAME(sc)); aml_freevalue(&res); return (1); } aml_freevalue(&res); /* XXX: todo - validate _CRS checksum? */ ecdtdone: dnprintf(10, "%s: Data: 0x%x, S/C: 0x%x\n", DEVNAME(sc), ec_data, ec_sc); if (ctype == GAS_SYSTEM_IOSPACE) sc->sc_cmd_bt = aa->aaa_iot; else sc->sc_cmd_bt = aa->aaa_memt; if (bus_space_map(sc->sc_cmd_bt, ec_sc, 1, 0, &sc->sc_cmd_bh)) { dnprintf(10, "%s: failed to map S/C reg.\n", DEVNAME(sc)); return (1); } if (dtype == GAS_SYSTEM_IOSPACE) sc->sc_data_bt = aa->aaa_iot; else sc->sc_data_bt = aa->aaa_memt; if (bus_space_map(sc->sc_data_bt, ec_data, 1, 0, &sc->sc_data_bh)) { dnprintf(10, "%s: failed to map DATA reg.\n", DEVNAME(sc)); bus_space_unmap(sc->sc_cmd_bt, sc->sc_cmd_bh, 1); return (1); } return (0); }
void cpi_nubus_attach(device_t parent, device_t self, void *aux) { struct cpi_softc *sc; struct nubus_attach_args *na; int err, ii; sc = device_private(self); sc->sc_options = (device_cfdata(self)->cf_flags & CPI_OPTIONS_MASK); na = aux; sc->sc_bst = na->na_tag; memcpy(&sc->sc_slot, na->fmt, sizeof(nubus_slot)); sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot); /* * The CIO sits eight bit wide on the top byte lane of * Nubus, so map 16 byte. */ if (TRACE_CONFIG) { printf("\n"); printf("\tcpi_nubus_attach() mapping 8536 CIO at 0x%lx.\n", sc->sc_basepa + CIO_BASE_OFFSET); } err = bus_space_map(sc->sc_bst, sc->sc_basepa + CIO_BASE_OFFSET, (Z8536_IOSIZE << 4), 0, &sc->sc_bsh); if (err) { aprint_normal(": failed to map memory space.\n"); return; } sc->sc_lpstate = LP_INITIAL; sc->sc_intcount = 0; sc->sc_bytestoport = 0; if (TRACE_CONFIG) printf("\tcpi_nubus_attach() about to set up 8536 CIO.\n"); for (ii = 0; ii < sizeof(cio_reset); ii += 2) z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_reset[ii], cio_reset[ii + 1]); delay(1000); /* Give the CIO time to set itself up */ for (ii = 0; ii < sizeof(cio_init); ii += 2) { z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_init[ii], cio_init[ii + 1]); } if (TRACE_CONFIG) printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n"); /* XXX Get information strings from the card ROM */ aprint_normal(": CSI Hurdler II Centronics\n"); /* Attach CIO timers 1+2 as timecounter */ if (sc->sc_options & CPI_CTC12_IS_TIMECOUNTER) { cpi_tc_initclock(sc); } callout_init(&sc->sc_wakeupchan, 0); /* XXX */ /* make sure interrupts are vectored to us */ add_nubus_intr(na->slot, cpi_nubus_intr, sc); }
/* * gtmpsc_hackinit - hacks required to supprt GTMPSC console */ STATIC int gtmpsc_hackinit(struct gtmpsc_softc *sc, bus_space_tag_t iot, bus_dma_tag_t dmat, bus_addr_t base, int unit, int brg, int baudrate, tcflag_t tcflag) { gtmpsc_poll_sdma_t *cn_dmapage = (gtmpsc_poll_sdma_t *)gtmpsc_cn_dmapage; int error; DPRINTF(("hackinit\n")); memset(sc, 0, sizeof(struct gtmpsc_softc)); error = bus_space_map(iot, base + GTMPSC_BASE(unit), GTMPSC_SIZE, 0, &sc->sc_mpsch); if (error != 0) goto fail0; error = bus_space_map(iot, base + GTSDMA_BASE(unit), GTSDMA_SIZE, 0, &sc->sc_sdmah); if (error != 0) goto fail1; error = bus_dmamap_create(dmat, sizeof(gtmpsc_polltx_t), 1, sizeof(gtmpsc_polltx_t), 0, BUS_DMA_NOWAIT, &sc->sc_txdma_map); if (error != 0) goto fail2; error = bus_dmamap_load(dmat, sc->sc_txdma_map, cn_dmapage->tx, sizeof(gtmpsc_polltx_t), NULL, BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE); if (error != 0) goto fail3; error = bus_dmamap_create(dmat, sizeof(gtmpsc_pollrx_t), 1, sizeof(gtmpsc_pollrx_t), 0, BUS_DMA_NOWAIT, &sc->sc_rxdma_map); if (error != 0) goto fail4; error = bus_dmamap_load(dmat, sc->sc_rxdma_map, cn_dmapage->rx, sizeof(gtmpsc_pollrx_t), NULL, BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE); if (error != 0) goto fail5; sc->sc_iot = iot; sc->sc_dmat = dmat; sc->sc_poll_sdmapage = cn_dmapage; sc->sc_brg = brg; sc->sc_baudrate = baudrate; sc->sc_cflag = tcflag; gtmpsc_txdesc_init(sc); gtmpsc_rxdesc_init(sc); return 0; fail5: bus_dmamap_destroy(dmat, sc->sc_rxdma_map); fail4: bus_dmamap_unload(dmat, sc->sc_txdma_map); fail3: bus_dmamap_destroy(dmat, sc->sc_txdma_map); fail2: bus_space_unmap(iot, sc->sc_sdmah, GTSDMA_SIZE); fail1: bus_space_unmap(iot, sc->sc_mpsch, GTMPSC_SIZE); fail0: return error; }
static void piixpm_attach(device_t parent, device_t self, void *aux) { struct piixpm_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct i2cbus_attach_args iba; pcireg_t base, conf; pcireg_t pmmisc; pci_intr_handle_t ih; const char *intrstr = NULL; int i, numbusses = 1; sc->sc_dev = self; sc->sc_iot = pa->pa_iot; sc->sc_id = pa->pa_id; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; pci_aprint_devinfo(pa, NULL); if (!pmf_device_register(self, piixpm_suspend, piixpm_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Read configuration */ conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); DPRINTF(("%s: conf 0x%x\n", device_xname(self), conf)); if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) || (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC)) goto nopowermanagement; /* check whether I/O access to PM regs is enabled */ pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC); if (!(pmmisc & 1)) goto nopowermanagement; /* Map I/O space */ base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE); if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base), PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) { aprint_error_dev(self, "can't map power management I/O space\n"); goto nopowermanagement; } /* * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 * in the "Specification update" (document #297738). */ acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 ); nopowermanagement: /* SB800 rev 0x40+ needs special initialization */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_SMB && PCI_REVISION(pa->pa_class) >= 0x40) { if (piixpm_sb800_init(sc) == 0) { numbusses = 4; goto attach_i2c; } aprint_normal_dev(self, "SMBus disabled\n"); return; } if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { aprint_normal_dev(self, "SMBus disabled\n"); return; } /* Map I/O space */ base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff; if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base), PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { aprint_error_dev(self, "can't map smbus I/O space\n"); return; } sc->sc_poll = 1; aprint_normal_dev(self, ""); if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) { /* No PCI IRQ */ aprint_normal("interrupting at SMI, "); } else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) { /* Install interrupt handler */ if (pci_intr_map(pa, &ih) == 0) { intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, piixpm_intr, sc); if (sc->sc_smb_ih != NULL) { aprint_normal("interrupting at %s", intrstr); sc->sc_poll = 0; } } } if (sc->sc_poll) aprint_normal("polling"); aprint_normal("\n"); attach_i2c: /* Attach I2C bus */ mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE); for (i = 0; i < numbusses; i++) { sc->sc_busses[i].sda = i; sc->sc_busses[i].softc = sc; sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i]; sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus; sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus; sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec; memset(&iba, 0, sizeof(iba)); iba.iba_type = I2C_TYPE_SMBUS; iba.iba_tag = &sc->sc_i2c_tags[i]; config_found_ia(self, "i2cbus", &iba, iicbus_print); } }
void ixp425_attach(device_t self) { struct ixp425_softc *sc = device_private(self); #if NPCI > 0 struct pcibus_attach_args pba; #endif sc->sc_dev = self; sc->sc_iot = &ixp425_bs_tag; ixp425_softc = sc; printf("\n"); /* * Mapping for GPIO Registers */ if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE, 0, &sc->sc_gpio_ioh)) panic("%s: unable to map GPIO registers", device_xname(self)); if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE, 0, &sc->sc_exp_ioh)) panic("%s: unable to map Expansion Bus registers", device_xname(self)); #if NPCI > 0 /* * Mapping for PCI CSR */ if (bus_space_map(sc->sc_iot, IXP425_PCI_HWBASE, IXP425_PCI_SIZE, 0, &sc->sc_pci_ioh)) panic("%s: unable to map PCI registers", device_xname(self)); /* * Invoke the board-specific PCI initialization code */ ixp425_md_pci_init(sc); /* * Generic initialization of the PCI chipset. */ ixp425_pci_init(sc); /* * Initialize the DMA tags. */ ixp425_pci_dma_init(sc); /* * Attach the PCI bus. */ pba.pba_pc = &sc->ia_pci_chipset; pba.pba_iot = &sc->sc_pci_iot; pba.pba_memt = &sc->sc_pci_memt; pba.pba_dmat = &sc->ia_pci_dmat; pba.pba_bus = 0; /* bus number = 0 */ pba.pba_bridgetag = NULL; pba.pba_intrswiz = 0; /* XXX */ pba.pba_intrtag = 0; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; (void) config_found_ia(self, "pcibus", &pba, pcibusprint); #endif }
int nouveau_fifo_channel_create_(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, int bar, u32 addr, u32 size, u32 pushbuf, u64 engmask, int len, void **ptr) { struct nouveau_device *device = nv_device(engine); struct nouveau_fifo *priv = (void *)engine; struct nouveau_fifo_chan *chan; struct nouveau_dmaeng *dmaeng; unsigned long flags; int ret; /* create base object class */ ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL, engmask, len, ptr); chan = *ptr; if (ret) return ret; /* validate dma object representing push buffer */ chan->pushdma = (void *)nouveau_handle_ref(parent, pushbuf); if (!chan->pushdma) return -ENOENT; dmaeng = (void *)chan->pushdma->base.engine; switch (chan->pushdma->base.oclass->handle) { case NV_DMA_FROM_MEMORY_CLASS: case NV_DMA_IN_MEMORY_CLASS: break; default: return -EINVAL; } ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu); if (ret) return ret; /* find a free fifo channel */ spin_lock_irqsave(&priv->lock, flags); for (chan->chid = priv->min; chan->chid < priv->max; chan->chid++) { if (!priv->channel[chan->chid]) { priv->channel[chan->chid] = nv_object(chan); break; } } spin_unlock_irqrestore(&priv->lock, flags); if (chan->chid == priv->max) { nv_error(priv, "no free channels\n"); return -ENOSPC; } /* map fifo control registers */ #ifdef __NetBSD__ chan->bst = nv_device_resource_tag(device, bar); /* XXX errno NetBSD->Linux */ ret = -bus_space_map(chan->bst, nv_device_resource_start(device, bar) + addr + (chan->chid * size), size, 0, &chan->bsh); if (ret) return ret; chan->mapped = true; #else chan->user = ioremap(nv_device_resource_start(device, bar) + addr + (chan->chid * size), size); if (!chan->user) return -EFAULT; #endif nouveau_event_trigger(priv->cevent, 0); chan->size = size; return 0; }
void pchbattach(struct device *parent, struct device *self, void *aux) { struct pchb_softc *sc = (struct pchb_softc *)self; struct pci_attach_args *pa = aux; int has_agp = 0, i, r; switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_AMD: printf("\n"); switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_AMD_AMD64_0F_HT: case PCI_PRODUCT_AMD_AMD64_10_HT: case PCI_PRODUCT_AMD_AMD64_11_HT: for (i = 0; i < AMD64HT_NUM_LDT; i++) pchb_amd64ht_attach(self, pa, i); break; } break; case PCI_VENDOR_INTEL: switch (PCI_PRODUCT(pa->pa_id)) { /* * As for Intel AGP, the host bridge is either in GFX mode * (internal graphics) or in AGP mode. In GFX mode, we pretend * to have AGP because the graphics memory access is very * similar and the AGP GATT code will deal with this. In the * latter case, the pci_get_capability(PCI_CAP_AGP) test below * will fire, so we do no harm by already setting the flag. */ /* AGP only */ case PCI_PRODUCT_INTEL_82915GM_HB: case PCI_PRODUCT_INTEL_82945GM_HB: case PCI_PRODUCT_INTEL_82945GME_HB: case PCI_PRODUCT_INTEL_82G965_HB: case PCI_PRODUCT_INTEL_82Q965_HB: case PCI_PRODUCT_INTEL_82GM965_HB: case PCI_PRODUCT_INTEL_82G33_HB: case PCI_PRODUCT_INTEL_82G35_HB: has_agp = 1; break; /* AGP + RNG */ case PCI_PRODUCT_INTEL_82915G_HB: case PCI_PRODUCT_INTEL_82945G_HB: has_agp = 1; /* FALLTHROUGH */ case PCI_PRODUCT_INTEL_82925X_HB: case PCI_PRODUCT_INTEL_82955X_HB: sc->sc_bt = pa->pa_memt; if (bus_space_map(sc->sc_bt, I82802_IOBASE, I82802_IOSIZE, 0, &sc->sc_bh)) break; /* probe and init rng */ if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST) & I82802_RNG_HWST_PRESENT)) break; /* enable RNG */ bus_space_write_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST, bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST) | I82802_RNG_HWST_ENABLE); /* see if we can read anything */ for (i = 1000; i-- && !(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV); ) DELAY(10); if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV)) break; r = bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_DATA); timeout_set(&sc->sc_rng_to, pchb_rnd, sc); sc->sc_rng_i = 4; pchb_rnd(sc); break; } printf("\n"); break; default: printf("\n"); break; } #if NAGP > 0 /* * If we haven't detected AGP yet (via a product ID), * then check for AGP capability on the device. */ if (has_agp || pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL) != 0) { agp_set_pchb(pa); } #endif }
/* * Probe routine. * * See if the card is there and at the right place. * (XXX - cgd -- needs help) */ int elprobe(device_t parent, cfdata_t match, void *aux) { struct isa_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_iot; bus_space_handle_t ioh; int iobase; u_int8_t station_addr[ETHER_ADDR_LEN]; u_int8_t i; int rval; rval = 0; if (ia->ia_nio < 1) return (0); if (ia->ia_nirq < 1) return (0); if (ISA_DIRECT_CONFIG(ia)) return (0); iobase = ia->ia_io[0].ir_addr; if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) return (0); if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) return (0); /* First check the base. */ if (iobase < 0x200 || iobase > 0x3f0) return 0; /* Map i/o space. */ if (bus_space_map(iot, iobase, 16, 0, &ioh)) return 0; /* * Now attempt to grab the station address from the PROM and see if it * contains the 3com vendor code. */ DPRINTF(("Probing 3c501 at 0x%x...\n", iobase)); /* Reset the board. */ DPRINTF(("Resetting board...\n")); bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET); delay(5); bus_space_write_1(iot, ioh, EL_AC, 0); /* Now read the address. */ DPRINTF(("Reading station address...\n")); for (i = 0; i < ETHER_ADDR_LEN; i++) { bus_space_write_1(iot, ioh, EL_GPBL, i); station_addr[i] = bus_space_read_1(iot, ioh, EL_EAW); } DPRINTF(("Address is %s\n", ether_sprintf(station_addr))); /* * If the vendor code is ok, return a 1. We'll assume that whoever * configured this system is right about the IRQ. */ if (station_addr[0] != 0x02 || station_addr[1] != 0x60 || station_addr[2] != 0x8c) { DPRINTF(("Bad vendor code.\n")); goto out; } DPRINTF(("Vendor code ok.\n")); ia->ia_nio = 1; ia->ia_io[0].ir_size = 16; ia->ia_nirq = 1; ia->ia_niomem = 0; ia->ia_ndrq = 0; rval = 1; out: bus_space_unmap(iot, ioh, 16); return rval; }
void platform_mp_start_ap(void) { bus_space_handle_t scu; bus_space_handle_t src; uint32_t val; int i; if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0) panic("Couldn't map the SCU\n"); if (bus_space_map(fdtbus_bs_tag, SRC_PHYSBASE, SRC_SIZE, 0, &src) != 0) panic("Couldn't map the system reset controller (SRC)\n"); /* * Invalidate SCU cache tags. The 0x0000ffff constant invalidates all * ways on all cores 0-3. Per the ARM docs, it's harmless to write to * the bits for cores that are not present. */ bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff); /* * Erratum ARM/MP: 764369 (problems with cache maintenance). * Setting the "disable-migratory bit" in the undocumented SCU * Diagnostic Control Register helps work around the problem. */ val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL); bus_space_write_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL, val | SCU_DIAG_DISABLE_MIGBIT); /* * Enable the SCU, then clean the cache on this core. After these two * operations the cache tag ram in the SCU is coherent with the contents * of the cache on this core. The other cores aren't running yet so * their caches can't contain valid data yet, but we've initialized * their SCU tag ram above, so they will be coherent from startup. */ val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG); bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG, val | SCU_CONTROL_ENABLE); cpu_idcache_wbinv_all(); /* * For each AP core, set the entry point address and argument registers, * and set the core-enable and core-reset bits in the control register. */ val = bus_space_read_4(fdtbus_bs_tag, src, SRC_CONTROL_REG); for (i=1; i < mp_ncpus; i++) { bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR0_C1FUNC + 8*i, pmap_kextract((vm_offset_t)mpentry)); bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR1_C1ARG + 8*i, 0); val |= ((1 << (SRC_CONTROL_C1ENA_SHIFT - 1 + i )) | ( 1 << (SRC_CONTROL_C1RST_SHIFT - 1 + i))); } bus_space_write_4(fdtbus_bs_tag, src, SRC_CONTROL_REG, val); armv7_sev(); bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE); bus_space_unmap(fdtbus_bs_tag, src, SRC_SIZE); }
/* * Attach the interface to the kernel data structures. By the time this is * called, we know that the card exists at the given I/O address. We still * assume that the IRQ given is correct. */ void elattach(device_t parent, device_t self, void *aux) { struct el_softc *sc = device_private(self); struct isa_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_iot; bus_space_handle_t ioh; struct ifnet *ifp = &sc->sc_ethercom.ec_if; u_int8_t myaddr[ETHER_ADDR_LEN]; u_int8_t i; sc->sc_dev = self; printf("\n"); DPRINTF(("Attaching %s...\n", device_xname(sc->sc_dev))); /* Map i/o space. */ if (bus_space_map(iot, ia->ia_io[0].ir_addr, 16, 0, &ioh)) { aprint_error_dev(self, "can't map i/o space\n"); return; } sc->sc_iot = iot; sc->sc_ioh = ioh; /* Reset the board. */ bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET); delay(5); bus_space_write_1(iot, ioh, EL_AC, 0); /* Now read the address. */ for (i = 0; i < ETHER_ADDR_LEN; i++) { bus_space_write_1(iot, ioh, EL_GPBL, i); myaddr[i] = bus_space_read_1(iot, ioh, EL_EAW); } /* Stop the board. */ elstop(sc); /* Initialize ifnet structure. */ strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_softc = sc; ifp->if_start = elstart; ifp->if_ioctl = elioctl; ifp->if_watchdog = elwatchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; IFQ_SET_READY(&ifp->if_snd); /* Now we can attach the interface. */ DPRINTF(("Attaching interface...\n")); if_attach(ifp); ether_ifattach(ifp, myaddr); /* Print out some information for the user. */ printf("%s: address %s\n", device_xname(self), ether_sprintf(myaddr)); sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_EDGE, IPL_NET, elintr, sc); DPRINTF(("Attaching to random...\n")); rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); DPRINTF(("elattach() finished.\n")); }
void imxpcibr_attach(struct device *parent, struct device *self, void *args) { struct armv7_attach_args *aa = args; struct imxpcibr_softc *sc = (struct imxpcibr_softc *) self; struct pcibus_attach_args pba; sc->sc_iot = aa->aa_iot; sc->sc_dma_tag = aa->aa_dmat; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("imxpcibr_attach: bus_space_map failed!"); printf("\n"); return; imxiomuxc_enable_pcie(); imxiomuxc_pcie_test_powerdown(0); clk_enable(clk_get("pcie_axi")); clk_enable(clk_get("pcie_ref_125m")); imxiomuxc_pcie_test_powerdown(1); HSET4(sc, PCIE_RC_COMMAND, PCIE_RC_COMMAND_IO_SPACE | PCIE_RC_COMMAND_MEMORY_SPACE | PCIE_RC_COMMAND_BUS_MASTER); HSET4(sc, PCIE_RC_REVID, PCI_CLASS_BRIDGE_PCI << 16); snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name), "%s pciio", sc->sc_dev.dv_xname); sc->sc_ioex = extent_create(sc->sc_ioex_name, 0x00000000, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name), "%s pcimem", sc->sc_dev.dv_xname); sc->sc_memex = extent_create(sc->sc_memex_name, 0x00000000, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); sc->sc_pc.pc_conf_v = sc; sc->sc_pc.pc_attach_hook = imxpcibr_attach_hook; sc->sc_pc.pc_bus_maxdevs = imxpcibr_bus_maxdevs; sc->sc_pc.pc_make_tag = imxpcibr_make_tag; sc->sc_pc.pc_decompose_tag = imxpcibr_decompose_tag; sc->sc_pc.pc_conf_size = imxpcibr_conf_size; sc->sc_pc.pc_conf_read = imxpcibr_conf_read; sc->sc_pc.pc_conf_write = imxpcibr_conf_write; sc->sc_pc.pc_intr_v = sc; sc->sc_pc.pc_intr_map = imxpcibr_intr_map; sc->sc_pc.pc_intr_string = imxpcibr_intr_string; sc->sc_pc.pc_intr_establish = imxpcibr_intr_establish; sc->sc_pc.pc_intr_disestablish = imxpcibr_intr_disestablish; bzero(&pba, sizeof(pba)); pba.pba_dmat = sc->sc_dma_tag; pba.pba_busname = "pci"; pba.pba_iot = sc->sc_iot; pba.pba_memt = sc->sc_iot; pba.pba_ioex = sc->sc_ioex; pba.pba_memex = sc->sc_memex; pba.pba_pc = &sc->sc_pc; pba.pba_domain = pci_ndomains++; pba.pba_bus = 0; imxpcibr_sc = sc; config_found(self, &pba, NULL); }
int sti_sgc_probe(struct device *parent, struct cfdata *cf, void *aux) { struct confargs *ca = aux; bus_space_handle_t romh; paddr_t rom; u_int32_t id, romend; u_char devtype; int rv = 0, romunmapped = 0; if (ca->ca_type.iodc_type != HPPA_TYPE_FIO) return (0); /* these need futher checking for the graphics id */ if (ca->ca_type.iodc_sv_model != HPPA_FIO_GSGC && ca->ca_type.iodc_sv_model != HPPA_FIO_SGC) return 0; rom = sti_sgc_getrom(ca); #ifdef STIDEBUG printf ("sti: hpa=%x, rom=%x\n", (uint)ca->ca_hpa, (uint)rom); #endif /* if it does not map, probably part of the lasi space */ if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &romh))) { #ifdef STIDEBUG printf ("sti: cannot map rom space (%d)\n", rv); #endif if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) { romh = rom; romunmapped++; } else { /* in this case nobody has no freaking idea */ return 0; } } devtype = bus_space_read_1(ca->ca_iot, romh, 3); #ifdef STIDEBUG printf("sti: devtype=%d\n", devtype); #endif rv = 1; switch (devtype) { case STI_DEVTYPE4: id = bus_space_read_4(ca->ca_iot, romh, STI_DEV4_DD_GRID); romend = bus_space_read_4(ca->ca_iot, romh, STI_DEV4_DD_ROMEND); break; case STI_DEVTYPE1: id = (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID + 3) << 24) | (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID + 7) << 16) | (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID + 11) << 8) | (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID + 15)); romend = (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND + 3) << 24) | (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND + 7) << 16) | (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND + 11) << 8) | (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND + 15)); break; default: #ifdef STIDEBUG printf("sti: unknown type (%x)\n", devtype); #endif rv = 0; romend = 0; } if (rv && ca->ca_type.iodc_sv_model == HPPA_FIO_SGC && id == STI_ID_FDDI) { #ifdef STIDEBUG printf("sti: not a graphics device\n"); #endif rv = 0; } if (ca->ca_naddrs >= sizeof(ca->ca_addrs) / sizeof(ca->ca_addrs[0])) { printf("sti: address list overflow\n"); return (0); } ca->ca_addrs[ca->ca_naddrs].addr = rom; ca->ca_addrs[ca->ca_naddrs].size = round_page(romend); ca->ca_naddrs++; if (!romunmapped) bus_space_unmap(ca->ca_iot, romh, STI_ROMSIZE); return (rv); }
void aupciattach(struct device *parent, struct device *self, void *aux) { struct aupci_softc *sc = (struct aupci_softc *)self; struct aubus_attach_args *aa = (struct aubus_attach_args *)aux; uint32_t cfg; #if NPCI > 0 uint32_t mbar, mask; bus_addr_t mstart; struct pcibus_attach_args pba; #endif aupci_found = 1; sc->sc_bust = aa->aa_st; if (bus_space_map(sc->sc_bust, aa->aa_addrs[0], 512, 0, &sc->sc_bush) != 0) { printf("\n%s: unable to map PCI registers\n", sc->sc_dev.dv_xname); return; } #if NPCI > 0 /* * These physical addresses are locked in on the CPUs we have * seen. Perhaps these should be passed in via locators, thru * the configuration file. */ sc->sc_cfgbase = PCI_CONFIG_BASE; sc->sc_membase = PCI_MEM_BASE; sc->sc_iobase = PCI_IO_BASE; #endif /* * Configure byte swapping, as YAMON doesn't do it. YAMON does take * care of most of the rest of the details (clocking, etc.), however. */ #if _BYTE_ORDER == _BIG_ENDIAN /* * N.B.: This still doesn't do the DMA thing properly. I have * not yet figured out how to get DMA access to work properly * without having bytes swapped while the processor is in * big-endian mode. I'm not even sure that the Alchemy part * can do it without swapping the bytes (which would be a * bummer, since then only parts which had hardware detection * and swapping support would work without special hacks in * their drivers.) */ cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H | AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN | AUPCI_CONFIG_SM | AUPCI_CONFIG_ST | AUPCI_CONFIG_SIC_DATA; #else cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H | AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN; #endif bus_space_write_4(sc->sc_bust, sc->sc_bush, AUPCI_CONFIG, cfg); cfg = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_COMMAND_STATUS); printf(": Alchemy Host-PCI Bridge"); if (cfg & PCI_STATUS_66MHZ_SUPPORT) printf(", 66MHz"); else printf(", 33MHz"); printf("\n"); #if NPCI > 0 /* * PCI configuration space. Address in this bus are * orthogonal to other spaces. We need to make the entire * 32-bit address space available. */ sc->sc_cfgt = &sc->sc_cfg_space; au_himem_space_init(sc->sc_cfgt, "pcicfg", sc->sc_cfgbase, 0x00000000, 0xffffffff, AU_HIMEM_SPACE_IO); /* * Virtual PCI memory. Configured so that we don't overlap * with PCI memory space. */ mask = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MWMASK); mask >>= AUPCI_MWMASK_SHIFT; mask <<= AUPCI_MWMASK_SHIFT; mbar = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MBAR); mstart = (mbar & mask) + (~mask + 1); sc->sc_memt = &sc->sc_mem_space; au_himem_space_init(sc->sc_memt, "pcimem", sc->sc_membase, mstart, 0xffffffff, AU_HIMEM_SPACE_LITTLE_ENDIAN); /* * IO space. Address in this bus are orthogonal to other spaces. * 16 MB should be plenty. We don't start from zero to avoid * potential device bugs. */ sc->sc_iot = &sc->sc_io_space; au_himem_space_init(sc->sc_iot, "pciio", sc->sc_iobase, AUPCI_IO_START, AUPCI_IO_END, AU_HIMEM_SPACE_LITTLE_ENDIAN | AU_HIMEM_SPACE_IO); sc->sc_pc.pc_conf_v = sc; sc->sc_pc.pc_attach_hook = aupci_attach_hook; sc->sc_pc.pc_bus_maxdevs = aupci_bus_maxdevs; sc->sc_pc.pc_make_tag = aupci_make_tag; sc->sc_pc.pc_decompose_tag = aupci_decompose_tag; sc->sc_pc.pc_conf_read = aupci_conf_read; sc->sc_pc.pc_conf_write = aupci_conf_write; sc->sc_pc.pc_intr_v = sc; sc->sc_pc.pc_intr_map = aupci_intr_map; sc->sc_pc.pc_intr_string = aupci_intr_string; sc->sc_pc.pc_intr_establish = aupci_intr_establish; sc->sc_pc.pc_intr_disestablish = aupci_intr_disestablish; sc->sc_pc.pc_conf_interrupt = aupci_conf_interrupt; #ifdef PCI_NETBSD_CONFIGURE mem_ex = extent_create("pcimem", mstart, 0xffffffff, M_DEVBUF, NULL, 0, EX_WAITOK); io_ex = extent_create("pciio", AUPCI_IO_START, AUPCI_IO_END, M_DEVBUF, NULL, 0, EX_WAITOK); pci_configure_bus(&sc->sc_pc, io_ex, mem_ex, NULL, 0, mips_dcache_align); extent_destroy(mem_ex); extent_destroy(io_ex); #endif pba.pba_iot = sc->sc_iot; pba.pba_memt = sc->sc_memt; /* XXX: review dma tag logic */ pba.pba_dmat = aa->aa_dt; pba.pba_dmat64 = NULL; pba.pba_pc = &sc->sc_pc; pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; pba.pba_bus = 0; pba.pba_bridgetag = NULL; config_found_ia(self, "pcibus", &pba, pcibusprint); #endif /* NPCI > 0 */ }
static void atppc_acpi_attach(device_t parent, device_t self, void *aux) { struct atppc_softc *sc = device_private(self); struct atppc_acpi_softc *asc = device_private(self); struct acpi_attach_args *aa = aux; struct acpi_resources res; struct acpi_io *io; struct acpi_irq *irq; struct acpi_drq *drq; ACPI_STATUS rv; int nirq; sc->sc_dev_ok = ATPPC_NOATTACH; sc->sc_dev = self; /* parse resources */ rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS", &res, &acpi_resource_parse_ops_default); if (ACPI_FAILURE(rv)) return; /* find our i/o registers */ io = acpi_res_io(&res, 0); if (io == NULL) { aprint_error_dev(sc->sc_dev, "unable to find i/o register resource\n"); goto out; } /* find our IRQ */ irq = acpi_res_irq(&res, 0); if (irq == NULL) { aprint_error_dev(sc->sc_dev, "unable to find irq resource\n"); goto out; } nirq = irq->ar_irq; /* find our DRQ */ drq = acpi_res_drq(&res, 0); if (drq == NULL) { aprint_error_dev(sc->sc_dev, "unable to find drq resource\n"); goto out; } asc->sc_drq = drq->ar_drq; /* Attach */ sc->sc_iot = aa->aa_iot; sc->sc_has = 0; asc->sc_ic = aa->aa_ic; sc->sc_dev_ok = ATPPC_ATTACHED; if (bus_space_map(sc->sc_iot, io->ar_base, io->ar_length, 0, &sc->sc_ioh) != 0) { aprint_error_dev(self, "attempt to map bus space failed, device not " "properly attached.\n"); goto out; } sc->sc_ieh = isa_intr_establish(aa->aa_ic, nirq, (irq->ar_type == ACPI_EDGE_SENSITIVE) ? IST_EDGE : IST_LEVEL, IPL_TTY, atppcintr, sc->sc_dev); /* setup DMA hooks */ if (atppc_isadma_setup(sc, asc->sc_ic, asc->sc_drq) == 0) { sc->sc_has |= ATPPC_HAS_DMA; sc->sc_dma_start = atppc_acpi_dma_start; sc->sc_dma_finish = atppc_acpi_dma_finish; sc->sc_dma_abort = atppc_acpi_dma_abort; sc->sc_dma_malloc = atppc_acpi_dma_malloc; sc->sc_dma_free = atppc_acpi_dma_free; } sc->sc_has |= ATPPC_HAS_INTR; /* Run soft configuration attach */ atppc_sc_attach(sc); out: acpi_resource_cleanup(&res); }
static void itesio_isa_attach(device_t parent, device_t self, void *aux) { struct itesio_softc *sc = device_private(self); struct isa_attach_args *ia = aux; int i; uint8_t cr; sc->sc_iot = ia->ia_iot; if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0, &sc->sc_ioh)) { aprint_error(": can't map i/o space\n"); return; } aprint_naive("\n"); /* * Enter to the Super I/O MB PNP mode. */ itesio_enter(sc->sc_iot, sc->sc_ioh); /* * Get info from the Super I/O Global Configuration Registers: * Chip IDs and Device Revision. */ sc->sc_chipid = (itesio_readreg(sc->sc_iot, sc->sc_ioh, ITESIO_CHIPID1) << 8); sc->sc_chipid |= itesio_readreg(sc->sc_iot, sc->sc_ioh, ITESIO_CHIPID2); sc->sc_devrev = (itesio_readreg(sc->sc_iot, sc->sc_ioh, ITESIO_DEVREV) & 0x0f); /* * Select the EC LDN to get the Base Address. */ itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_LDNSEL, ITESIO_EC_LDN); sc->sc_hwmon_baseaddr = (itesio_readreg(sc->sc_iot, sc->sc_ioh, ITESIO_EC_MSB) << 8); sc->sc_hwmon_baseaddr |= itesio_readreg(sc->sc_iot, sc->sc_ioh, ITESIO_EC_LSB); /* * We are done, exit MB PNP mode. */ itesio_exit(sc->sc_iot, sc->sc_ioh); aprint_normal(": iTE IT%4xF Super I/O (rev %d)\n", sc->sc_chipid, sc->sc_devrev); aprint_normal_dev(self, "Hardware Monitor registers at 0x%x\n", sc->sc_hwmon_baseaddr); if (bus_space_map(sc->sc_ec_iot, sc->sc_hwmon_baseaddr, 8, 0, &sc->sc_ec_ioh)) { aprint_error_dev(self, "cannot map hwmon i/o space\n"); goto out2; } sc->sc_hwmon_mapped = true; /* Activate monitoring */ cr = itesio_ecreadreg(sc, ITESIO_EC_CONFIG); SET(cr, 0x01); itesio_ecwritereg(sc, ITESIO_EC_CONFIG, cr); #ifdef notyet /* Enable beep alarms */ cr = itesio_ecreadreg(sc, ITESIO_EC_BEEPEER); SET(cr, 0x02); /* Voltage exceeds limit */ SET(cr, 0x04); /* Temperature exceeds limit */ itesio_ecwritereg(sc, ITESIO_EC_BEEPEER, cr); #endif /* * Initialize and attach sensors. */ itesio_setup_sensors(sc); sc->sc_sme = sysmon_envsys_create(); for (i = 0; i < IT_NUM_SENSORS; i++) { if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i])) { sysmon_envsys_destroy(sc->sc_sme); goto out; } } /* * Hook into the system monitor. */ sc->sc_sme->sme_name = device_xname(self); sc->sc_sme->sme_cookie = sc; sc->sc_sme->sme_refresh = itesio_refresh; if ((i = sysmon_envsys_register(sc->sc_sme))) { aprint_error_dev(self, "unable to register with sysmon (%d)\n", i); sysmon_envsys_destroy(sc->sc_sme); goto out; } sc->sc_hwmon_enabled = true; if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); /* The IT8705 doesn't support the WDT */ if (sc->sc_chipid == ITESIO_ID8705) goto out2; /* * Initialize the watchdog timer. */ sc->sc_smw.smw_name = device_xname(self); sc->sc_smw.smw_cookie = sc; sc->sc_smw.smw_setmode = itesio_wdt_setmode; sc->sc_smw.smw_tickle = itesio_wdt_tickle; sc->sc_smw.smw_period = 60; if (sysmon_wdog_register(&sc->sc_smw)) { aprint_error_dev(self, "unable to register watchdog timer\n"); goto out2; } sc->sc_wdt_enabled = true; aprint_normal_dev(self, "Watchdog Timer present\n"); return; out: bus_space_unmap(sc->sc_ec_iot, sc->sc_ec_ioh, 8); out2: bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2); }
static void obioohci_attach(struct device *parent, struct device *self, void *aux) { struct obioohci_softc *sc = (struct obioohci_softc *)self; struct obio_attach_args *obio = aux; usbd_status r; sc->sc.sc_size = 0; sc->sc_ih = NULL; sc->sc.sc_bus.dmatag = 0; /* Map I/O space */ if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0, &sc->sc.ioh)) { aprint_error(": couldn't map memory space\n"); return; } sc->sc.iot = obio->obio_iot; sc->sc_addr = obio->obio_addr; sc->sc.sc_size = obio->obio_size; sc->sc.sc_bus.dmatag = obio->obio_dmac; /* XXX copied from ohci_pci.c. needed? */ bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); /* start the usb clock */ #ifdef NOTYET pxa2x0_clkman_config(CKEN_USBHC, 1); #endif obioohci_enable(sc); /* Disable interrupts, so we don't get any spurious ones. */ bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_MIE); #ifdef NOTYET sc->sc_ih = obio_intr_establish(obio->obio_intr, IPL_USB, sc->sc.sc_bus.bdev.dv_xname, ohci_intr, &sc->sc); if (sc->sc_ih == NULL) { aprint_error(": unable to establish interrupt\n"); goto free_map; } #else sc->sc_ih = obioohci_fake_intr_establish(ohci_intr, &sc->sc); #endif strlcpy(sc->sc.sc_vendor, "OMAP2", sizeof(sc->sc.sc_vendor)); r = ohci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { aprint_error("%s: init failed, error=%d\n", sc->sc.sc_bus.bdev.dv_xname, r); goto free_intr; } sc->sc.sc_powerhook = powerhook_establish(sc->sc.sc_bus.bdev.dv_xname, obioohci_power, sc); if (sc->sc.sc_powerhook == NULL) { aprint_error("%s: cannot establish powerhook\n", sc->sc.sc_bus.bdev.dv_xname); } sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus, usbctlprint); return; free_intr: #ifdef NOTYET obio_gpio_intr_disestablish(sc->sc_ih); #endif sc->sc_ih = NULL; #ifdef NOTYET free_map: #endif obioohci_disable(sc); #ifdef NOTYET pxa2x0_clkman_config(CKEN_USBHC, 0); #endif bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); sc->sc.sc_size = 0; }
void j720sspattach(struct device *parent, struct device *self, void *aux) { struct j720ssp_softc *sc = (void *)self; struct sa11x0_softc *psc = (void *)parent; struct sa11x0_attach_args *sa = aux; struct wskbddev_attach_args a; printf("\n"); sc->sc_iot = psc->sc_iot; sc->sc_gpioh = psc->sc_gpioh; if (bus_space_map(sc->sc_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ssph)) { printf("%s: unable to map SSP registers\n", sc->sc_dev.dv_xname); return; } sc->sc_si = softintr_establish(IPL_SOFTCLOCK, j720kbdsoft, sc); sc->sc_enabled = 0; a.console = 0; a.keymap = &j720kbd_keymapdata; a.accessops = &j720kbd_accessops; a.accesscookie = sc; /* Do console initialization */ if (! (bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) { j720kbdcons_sc = *sc; a.console = 1; wskbd_cnattach(&j720kbd_consops, NULL, &j720kbd_keymapdata); j720kbdcons_initstate = 1; } /* * Attach the wskbd, saving a handle to it. * XXX XXX XXX */ sc->sc_wskbddev = config_found(self, &a, wskbddevprint); #ifdef DEBUG /* Zero the stat counters */ j720sspwaitcnt = 0; j720sspwaittime = 0; #endif if (j720kbdcons_initstate == 1) j720kbd_enable(sc, 1); /* LCD control is on the same bus */ config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, CONFIG_HOOK_SHARE, j720lcdparam, sc); config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS, CONFIG_HOOK_SHARE, j720lcdparam, sc); config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS_MAX, CONFIG_HOOK_SHARE, j720lcdparam, sc); config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, CONFIG_HOOK_SHARE, j720lcdparam, sc); config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST, CONFIG_HOOK_SHARE, j720lcdparam, sc); config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST_MAX, CONFIG_HOOK_SHARE, j720lcdparam, sc); }
static void sdhc_attach(device_t parent, device_t self, void *aux) { struct sdhc_axi_softc *sc = device_private(self); struct axi_attach_args *aa = aux; bus_space_tag_t iot = aa->aa_iot; bus_space_handle_t ioh; u_int perclk = 0, v; sc->sc_sdhc.sc_dev = self; sc->sc_sdhc.sc_dmat = aa->aa_dmat; if (bus_space_map(iot, aa->aa_addr, AIPS2_USDHC_SIZE, 0, &ioh)) { aprint_error_dev(self, "can't map\n"); return; } aprint_normal(": Ultra Secured Digial Host Controller\n"); aprint_naive("\n"); sc->sc_sdhc.sc_host = sc->sc_hosts; switch (aa->aa_addr) { case IMX6_AIPS2_BASE + AIPS2_USDHC1_BASE: v = imx6_ccm_read(CCM_CCGR6); imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC1_CLK_ENABLE(3)); perclk = imx6_get_clock(IMX6CLK_USDHC1_CLK_ROOT); break; case IMX6_AIPS2_BASE + AIPS2_USDHC2_BASE: v = imx6_ccm_read(CCM_CCGR6); imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC2_CLK_ENABLE(3)); perclk = imx6_get_clock(IMX6CLK_USDHC2_CLK_ROOT); break; case IMX6_AIPS2_BASE + AIPS2_USDHC3_BASE: v = imx6_ccm_read(CCM_CCGR6); imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC3_CLK_ENABLE(3)); perclk = imx6_get_clock(IMX6CLK_USDHC3_CLK_ROOT); break; case IMX6_AIPS2_BASE + AIPS2_USDHC4_BASE: v = imx6_ccm_read(CCM_CCGR6); imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC4_CLK_ENABLE(3)); perclk = imx6_get_clock(IMX6CLK_USDHC4_CLK_ROOT); break; } sc->sc_sdhc.sc_clkbase = perclk / 1000; sc->sc_sdhc.sc_flags |= SDHC_FLAG_USDHC | SDHC_FLAG_NO_PWR0 | SDHC_FLAG_HAVE_DVS | SDHC_FLAG_32BIT_ACCESS | SDHC_FLAG_ENHANCED; sc->sc_ih = intr_establish(aa->aa_irq, IPL_SDMMC, IST_LEVEL, sdhc_intr, &sc->sc_sdhc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "can't establish interrupt\n"); return; } if (sdhc_host_found(&sc->sc_sdhc, iot, ioh, AIPS2_USDHC_SIZE)) { aprint_error_dev(self, "can't initialize host\n"); return; } if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume, sdhc_shutdown)) { aprint_error_dev(self, "can't establish power hook\n"); } }
int nouveau_fifo_channel_create_(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, int bar, u32 addr, u32 size, u32 pushbuf, u64 engmask, int len, void **ptr) { struct nouveau_device *device = nv_device(engine); struct nouveau_fifo *priv = (void *)engine; struct nouveau_fifo_chan *chan; struct nouveau_dmaeng *dmaeng; unsigned long flags; int ret; /* create base object class */ ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL, engmask, len, ptr); chan = *ptr; if (ret) return ret; /* validate dma object representing push buffer */ chan->pushdma = (void *)nouveau_handle_ref(parent, pushbuf); if (!chan->pushdma) return -ENOENT; dmaeng = (void *)chan->pushdma->base.engine; switch (chan->pushdma->base.oclass->handle) { case NV_DMA_FROM_MEMORY_CLASS: case NV_DMA_IN_MEMORY_CLASS: break; default: return -EINVAL; } ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu); if (ret) return ret; /* find a free fifo channel */ spin_lock_irqsave(&priv->lock, flags); for (chan->chid = priv->min; chan->chid < priv->max; chan->chid++) { if (!priv->channel[chan->chid]) { priv->channel[chan->chid] = nv_object(chan); break; } } spin_unlock_irqrestore(&priv->lock, flags); if (chan->chid == priv->max) { nv_error(priv, "no free channels\n"); return -ENOSPC; } /* map fifo control registers */ #ifdef __NetBSD__ if (bar == 0) { /* * We already map BAR 0 in the engine device base, so * grab a subregion of that. */ bus_space_tag_t mmiot = nv_subdev(device)->mmiot; bus_space_handle_t mmioh = nv_subdev(device)->mmioh; bus_size_t mmiosz = nv_subdev(device)->mmiosz; /* Check whether it lies inside the region. */ if (mmiosz < addr || mmiosz - addr < chan->chid*size || mmiosz - addr - chan->chid*size < size) { ret = EIO; nv_error(priv, "fifo channel out of range:" " addr 0x%"PRIxMAX " chid 0x%"PRIxMAX" size 0x%"PRIxMAX " mmiosz 0x%"PRIxMAX"\n", (uintmax_t)addr, (uintmax_t)chan->chid, (uintmax_t)size, (uintmax_t)mmiosz); return ret; } /* Grab a subregion. */ /* XXX errno NetBSD->Linux */ ret = -bus_space_subregion(mmiot, mmioh, (addr + chan->chid*size), size, &chan->bsh); if (ret) { nv_error(priv, "bus_space_subregion failed: %d\n", ret); return ret; } /* Success! No need to unmap a subregion. */ chan->mapped = false; chan->bst = mmiot; } else { chan->bst = nv_device_resource_tag(device, bar); /* XXX errno NetBSD->Linux */ ret = -bus_space_map(chan->bst, (nv_device_resource_start(device, bar) + addr + (chan->chid * size)), size, 0, &chan->bsh); if (ret) { nv_error(priv, "failed to map fifo channel:" " bar %d addr %"PRIxMAX" + %"PRIxMAX " + (%"PRIxMAX" * %"PRIxMAX") = %"PRIxMAX " size %"PRIxMAX": %d\n", bar, (uintmax_t)nv_device_resource_start(device, bar), (uintmax_t)addr, (uintmax_t)chan->chid, (uintmax_t)size, (uintmax_t)(nv_device_resource_start(device, bar) + addr + (chan->chid * size)), (uintmax_t)size, ret); return ret; } chan->mapped = true; } #else chan->user = ioremap(nv_device_resource_start(device, bar) + addr + (chan->chid * size), size); if (!chan->user) return -EFAULT; #endif nouveau_event_trigger(priv->cevent, 0); chan->size = size; return 0; }
void amdpm_attach(struct device *parent, struct device *self, void *aux) { struct amdpm_softc *sc = (struct amdpm_softc *) self; struct pci_attach_args *pa = aux; struct timeval tv1, tv2; pcireg_t reg; int i; sc->sc_pc = pa->pa_pc; sc->sc_tag = pa->pa_tag; sc->sc_iot = pa->pa_iot; reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_CONFREG); if ((reg & AMDPM_PMIOEN) == 0) { printf(": PMxx space isn't enabled\n"); return; } reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_PMPTR); if (bus_space_map(sc->sc_iot, AMDPM_PMBASE(reg), AMDPM_PMSIZE, 0, &sc->sc_ioh)) { printf(": failed to map PMxx space\n"); return; } reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_CONFREG); if (reg & AMDPM_RNGEN) { /* Check to see if we can read data from the RNG. */ (void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, AMDPM_RNGDATA); /* benchmark the RNG */ microtime(&tv1); for (i = 2 * 1024; i--; ) { while(!(bus_space_read_1(sc->sc_iot, sc->sc_ioh, AMDPM_RNGSTAT) & AMDPM_RNGDONE)) ; (void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, AMDPM_RNGDATA); } microtime(&tv2); timersub(&tv2, &tv1, &tv1); if (tv1.tv_sec) tv1.tv_usec += 1000000 * tv1.tv_sec; printf(": rng active, %dKb/sec", 8 * 1000000 / tv1.tv_usec); #ifdef AMDPM_RND_COUNTERS evcnt_attach_dynamic(&sc->sc_rnd_hits, EVCNT_TYPE_MISC, NULL, sc->sc_dev.dv_xname, "rnd hits"); evcnt_attach_dynamic(&sc->sc_rnd_miss, EVCNT_TYPE_MISC, NULL, sc->sc_dev.dv_xname, "rnd miss"); for (i = 0; i < 256; i++) { evcnt_attach_dynamic(&sc->sc_rnd_data[i], EVCNT_TYPE_MISC, NULL, sc->sc_dev.dv_xname, "rnd data"); } #endif timeout_set(&sc->sc_rnd_ch, amdpm_rnd_callout, sc); amdpm_rnd_callout(sc); } }
static void omapl1xohci_attach (struct device *parent, struct device *self, void *aux) { struct omapl1xohci_softc *sc = device_private(self); struct tipb_attach_args *tipb = aux; usbd_status r; /* Map OHCI registers */ if (bus_space_map(tipb->tipb_iot, tipb->tipb_addr, tipb->tipb_size, 0, &sc->sc.ioh)) { aprint_error_dev(self, "can't map ohci mem space\n"); return; } /* Enable the usb lpsc modules */ if (omapl1x_lpsc_enable(PSC1_USB20_MODULE) != 0) { aprint_error_dev(self, "can't enable usb2.0 module\n"); return; } if (omapl1x_lpsc_enable(PSC1_USB11_MODULE) != 0) { aprint_error_dev(self, "can't enable usb1.1 module\n"); return; } syscfg0.syscfg_iot = tipb->tipb_iot; syscfg0.syscfg_addr = OMAPL1X_SYSCFG0_ADDR; syscfg0.syscfg_size = OMAPL1X_SYSCFG0_SIZE; /* Map syscfg registers. We want to use it for configuring cfgchip2 */ if (bus_space_map(syscfg0.syscfg_iot, syscfg0.syscfg_addr, syscfg0.syscfg_size, 0, &syscfg0.syscfg_ioh)) { aprint_error_dev(self, "can't map syscfg0 mem space\n"); return; } sc->sc.sc_dev = self; sc->sc.sc_bus.hci_private = sc; sc->sc_intr = tipb->tipb_intr; sc->sc.iot = tipb->tipb_iot; sc->sc.sc_addr = tipb->tipb_addr; sc->sc.sc_size = tipb->tipb_size; sc->sc.sc_bus.dmatag = tipb->tipb_dmac; /* Disable interrupts, so we don't get any spurious ones. */ bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); /* provide clock to USB block */ if (!omapl1x_usbclk_enable(&syscfg0)) { aprint_error_dev(self, "phy init failed\n"); return; } /* establish the interrupt. */ sc->sc_ih = intr_establish(sc->sc_intr, IPL_USB, IST_LEVEL_HIGH, ohci_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt\n"); return; } strlcpy(sc->sc.sc_vendor, "OMAPL1X", sizeof sc->sc.sc_vendor); r = ohci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { aprint_error_dev(self, "init failed, error=%d\n", r); return; } /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); /* Done accessing the syscfg0 registers */ bus_space_unmap(syscfg0.syscfg_iot, syscfg0.syscfg_ioh, syscfg0.syscfg_size); }
void sbbc_attach(struct device *parent, struct device *self, void *aux) { struct sbbc_softc *sc = (void *)self; struct pci_attach_args *pa = aux; struct sbbc_sram_toc *toc; bus_addr_t base; bus_size_t size; pci_intr_handle_t ih; int chosen, iosram; int i; /* XXX Don't byteswap. */ sc->sc_bbt = *pa->pa_memt; sc->sc_bbt.sasi = ASI_PRIMARY; sc->sc_iot = &sc->sc_bbt; if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, SBBC_PCI_BAR, PCI_MAPREG_TYPE_MEM, &base, &size, NULL)) { printf(": can't find register space\n"); return; } if (bus_space_map(sc->sc_iot, base + SBBC_REGS_OFFSET, SBBC_REGS_SIZE, 0, &sc->sc_regs_ioh)) { printf(": can't map register space\n"); return; } if (bus_space_map(sc->sc_iot, base + SBBC_EPLD_OFFSET, SBBC_EPLD_SIZE, 0, &sc->sc_epld_ioh)) { printf(": can't map EPLD registers\n"); goto unmap_regs; } if (bus_space_map(sc->sc_iot, base + SBBC_SRAM_OFFSET, SBBC_SRAM_SIZE, 0, &sc->sc_sram_ioh)) { printf(": can't map SRAM\n"); goto unmap_epld; } if (pci_intr_map(pa, &ih)) { printf(": unable to map interrupt\n"); goto unmap_sram; } printf(": %s\n", pci_intr_string(pa->pa_pc, ih)); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY, sbbc_intr, sc, sc->sc_dv.dv_xname); if (sc->sc_ih == NULL) { printf("%s: unable to establish interrupt\n", sc->sc_dv.dv_xname); goto unmap_sram; } bus_space_write_4(sc->sc_iot, sc->sc_regs_ioh, SBBC_PCI_INT_ENABLE, SBBC_PCI_ENABLE_INT_A); /* Check if we are the chosen one. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "iosram", &iosram, sizeof(iosram)) <= 0 || PCITAG_NODE(pa->pa_tag) != iosram) return; /* SRAM TOC offset defaults to 0. */ if (OF_getprop(chosen, "iosram-toc", &sc->sc_sram_toc, sizeof(sc->sc_sram_toc)) <= 0) sc->sc_sram_toc = 0; sc->sc_sram = bus_space_vaddr(sc->sc_iot, sc->sc_sram_ioh); toc = (struct sbbc_sram_toc *)(sc->sc_sram + sc->sc_sram_toc); for (i = 0; i < toc->toc_ntags; i++) { if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIE") == 0) sc->sc_sram_solscie = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIR") == 0) sc->sc_sram_solscir = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIE") == 0) sc->sc_sram_scsolie = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIR") == 0) sc->sc_sram_scsolir = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); } for (i = 0; i < toc->toc_ntags; i++) { if (strcmp(toc->toc_tag[i].tag_key, "TODDATA") == 0) sbbc_attach_tod(sc, toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SOLCONS") == 0) sbbc_attach_cons(sc, toc->toc_tag[i].tag_offset); } return; unmap_sram: bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_SRAM_SIZE); unmap_epld: bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_EPLD_SIZE); unmap_regs: bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_REGS_SIZE); }