static paddr_t xel_addr(device_t parent, cfdata_t match, struct intio_attach_args *ia) { paddr_t addr = 0; if (match->cf_addr == INTIOCF_ADDR_DEFAULT) { int i; for (i = 0; i < sizeof(xel_addrs)/sizeof(xel_addrs[0]); i++) { if (xel_probe(xel_addrs[i])) { addr = xel_addrs[i]; break; } } } else { if (xel_probe((paddr_t) match->cf_addr)) addr = (paddr_t) match->cf_addr; } if (addr) { /* found! */ ia->ia_addr = (int) addr; ia->ia_size = 0x4000; if (intio_map_allocate_region(parent, ia, INTIO_MAP_TESTONLY) < 0) return 0; else return addr; } return 0; }
static void dmac_attach(device_t parent, device_t self, void *aux) { struct dmac_softc *sc = device_private(self); struct intio_attach_args *ia = aux; struct intio_softc *intio; int r __diagused; sc->sc_dev = self; dmac_attached = 1; ia->ia_size = DMAC_CHAN_SIZE * DMAC_NCHAN; r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE); #ifdef DIAGNOSTIC if (r) panic("IO map for DMAC corruption??"); #endif intio = device_private(parent); intio->sc_dmac = self; sc->sc_bst = ia->ia_bst; bus_space_map(sc->sc_bst, ia->ia_addr, ia->ia_size, 0, &sc->sc_bht); dmac_init_channels(sc); aprint_normal(": HD63450 DMAC\n"); aprint_normal_dev(self, "4 channels available.\n"); }
static void rtc_attach(device_t parent, device_t self, void *aux) { struct rtc_softc *sc = device_private(self); struct intio_attach_args *ia = aux; int r; rtc_attached = 1; ia->ia_size = 0x20; r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE); #ifdef DIAGNOSTIC if (r) panic("IO map for RTC corruption??"); #endif sc->sc_bst = ia->ia_bst; bus_space_map(sc->sc_bst, ia->ia_addr, 0x2000, 0, &sc->sc_bht); sc->sc_todr.cookie = sc; sc->sc_todr.todr_gettime_ymdhms = rtgettod; sc->sc_todr.todr_settime_ymdhms = rtsettod; todr_attach(&sc->sc_todr); aprint_normal(": RP5C15\n"); }
/* * Is the zs chip present? */ static int zs_match(device_t parent, cfdata_t cf, void *aux) { struct intio_attach_args *ia = aux; struct zsdevice *zsaddr = (void *)ia->ia_addr; int i; if (strcmp(ia->ia_name, "zsc") != 0) return 0; for (i = 0; i < ZS_MAXDEV; i++) if (zsaddr == (void *)zs_physaddr[i]) /* XXX */ break; ia->ia_size = 8; if (intio_map_allocate_region(parent, ia, INTIO_MAP_TESTONLY)) return 0; if (zsaddr != (void *)zs_physaddr[i]) return 0; if (badaddr((void *)IIOV(zsaddr))) return 0; return (1); }
static void spc_intio_attach(device_t parent, device_t self, void *aux) { struct spc_softc *sc = device_private(self); struct intio_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_bst; bus_space_handle_t ioh; sc->sc_dev = self; intio_map_allocate_region(device_parent(parent), ia, INTIO_MAP_ALLOCATE); if (bus_space_map(iot, ia->ia_addr, 0x20, BUS_SPACE_MAP_SHIFTED, &ioh)) { aprint_error(": can't map i/o space\n"); return; } aprint_normal("\n"); sc->sc_iot = iot; sc->sc_ioh = ioh; sc->sc_initiator = IODEVbase->io_sram[0x70] & 0x7; /* XXX */ if (intio_intr_establish(ia->ia_intr, "spc", spc_intr, sc)) panic("spcattach: interrupt vector busy"); spc_attach(sc); }
static void xel_attach(device_t parent, device_t self, void *aux) { struct xel_softc *sc = device_private(self); struct intio_attach_args *ia = aux; cfdata_t cf = device_cfdata(self); paddr_t addr; int r __diagused; addr = xel_addr(parent, cf, aux); sc->sc_bst = ia->ia_bst; ia->ia_addr = (int) addr; ia->ia_size = 0x4000; r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE); #ifdef DIAGNOSTIC if (r) panic("IO map for Xellent30 corruption??"); #endif aprint_normal(": Xellent30 MPU Accelerator.\n"); return; }
static void mfp_attach(device_t parent, device_t self, void *aux) { struct mfp_softc *sc = device_private(self); struct intio_attach_args *ia = aux; int r; aprint_normal("\n"); mfp_attached = 1; /* mfp_init() is already called via early config_console() */ sc->sc_bst = ia->ia_bst; sc->sc_intr = ia->ia_intr; ia->ia_size = 0x30; r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE); #ifdef DIAGNOSTIC if (r) panic("IO map for MFP corruption??"); #endif bus_space_map(ia->ia_bst, ia->ia_addr, 0x2000, 0, &sc->sc_bht); config_search_ia(mfp_search, self, "mfp", NULL); }
static int spc_intio_match(device_t parent, cfdata_t cf, void *aux) { struct intio_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_bst; bus_space_handle_t ioh; ia->ia_size = 0x20; if (intio_map_allocate_region(device_parent(parent), ia, INTIO_MAP_TESTONLY) < 0) return 0; if (bus_space_map(iot, ia->ia_addr, 0x20, BUS_SPACE_MAP_SHIFTED, &ioh) < 0) return 0; if (badaddr(INTIO_ADDR(ia->ia_addr + BDID))) return 0; bus_space_unmap(iot, ioh, 0x20); return 1; }
void parattach(device_t pdp, device_t dp, void *aux) { struct par_softc *sc = device_private(dp); struct intio_attach_args *ia = aux; int r; par_attached = 1; sc->sc_dev = dp; sc->sc_flags = PARF_ALIVE; aprint_normal(": parallel port (write only, interrupt)\n"); ia->ia_size = 0x2000; r = intio_map_allocate_region(pdp, ia, INTIO_MAP_ALLOCATE); #ifdef DIAGNOSTIC if (r) panic("IO map for PAR corruption??"); #endif sc->sc_bst = ia->ia_bst; r = bus_space_map(sc->sc_bst, ia->ia_addr, ia->ia_size, BUS_SPACE_MAP_SHIFTED, &sc->sc_bsh); #ifdef DIAGNOSTIC if (r) panic("Cannot map IO space for PAR."); #endif intio_set_sicilian_intr(intio_get_sicilian_intr() & ~SICILIAN_INTR_PAR); intio_intr_establish(ia->ia_intr, "par", (intio_intr_handler_t)parintr, (void *)1); callout_init(&sc->sc_timo_ch, 0); callout_init(&sc->sc_start_ch, 0); callout_init(&intr_callout, 0); }
int parmatch(device_t pdp, cfdata_t cfp, void *aux) { struct intio_attach_args *ia = aux; /* X680x0 has only one parallel port */ if (strcmp(ia->ia_name, "par") || par_attached) return 0; if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) ia->ia_addr = 0xe8c000; ia->ia_size = 0x2000; if (intio_map_allocate_region(pdp, ia, INTIO_MAP_TESTONLY)) return 0; if (ia->ia_intr == INTIOCF_INTR_DEFAULT) ia->ia_intr = 99; #if DIAGNOSTIC if (ia->ia_intr != 99) return 0; #endif return 1; }
/* * Attach a found zs. */ static void zs_attach(device_t parent, device_t self, void *aux) { struct zsc_softc *zsc = device_private(self); struct intio_attach_args *ia = aux; struct zsc_attach_args zsc_args; volatile struct zschan *zc; struct zs_chanstate *cs; int r, s, zs_unit, channel; zsc->zsc_dev = self; aprint_normal("\n"); zs_unit = device_unit(self); zsc->zsc_addr = (void *)ia->ia_addr; ia->ia_size = 8; r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE); #ifdef DIAGNOSTIC if (r) panic("zs: intio IO map corruption"); #endif /* * Initialize software state for each channel. */ for (channel = 0; channel < 2; channel++) { device_t child; zsc_args.channel = channel; zsc_args.hwflags = 0; cs = &zsc->zsc_cs_store[channel]; zsc->zsc_cs[channel] = cs; zs_lock_init(cs); cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; cs->cs_brg_clk = PCLK / 16; if (channel == 0) zc = (volatile void *)IIOV(&zsc->zsc_addr->zs_chan_a); else zc = (volatile void *)IIOV(&zsc->zsc_addr->zs_chan_b); cs->cs_reg_csr = &zc->zc_csr; cs->cs_reg_data = &zc->zc_data; zs_init_reg[2] = ia->ia_intr; memcpy(cs->cs_creg, zs_init_reg, 16); memcpy(cs->cs_preg, zs_init_reg, 16); if (zc == conschan) { zsc_args.hwflags |= ZS_HWFLAG_CONSOLE; cs->cs_defspeed = zs_get_speed(cs); cs->cs_defcflag = zscn_def_cflag; } else { cs->cs_defspeed = 9600; cs->cs_defcflag = zs_def_cflag; } /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; cs->cs_rr0_cts = 0; cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; cs->cs_wr5_rts = 0; /* * Clear the master interrupt enable. * The INTENA is common to both channels, * so just do it on the A channel. */ if (channel == 0) { s = splzs(); zs_write_reg(cs, 9, 0); splx(s); } /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ child = config_found(self, (void *)&zsc_args, zs_print); #if ZSTTY > 0 if (zc == conschan && ((child && strcmp(device_xname(child), "zstty0")) || child == NULL)) /* XXX */ panic("%s: console device mismatch", __func__); #endif if (child == NULL) { /* No sub-driver. Just reset it. */ uint8_t reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; s = splzs(); zs_write_reg(cs, 9, reset); splx(s); } } /* * Now safe to install interrupt handlers. */ if (intio_intr_establish(ia->ia_intr, "zs", zshard, zsc)) panic("%s: interrupt vector busy", __func__); zsc->zsc_softintr_cookie = softint_establish(SOFTINT_SERIAL, (void (*)(void *))zsc_intr_soft, zsc); /* XXX; evcnt_attach() ? */ /* * Set the master interrupt enable and interrupt vector. * (common to both channels, do it on A) */ cs = zsc->zsc_cs[0]; s = splzs(); /* interrupt vector */ zs_write_reg(cs, 2, ia->ia_intr); /* master interrupt control (enable) */ zs_write_reg(cs, 9, zs_init_reg[9]); splx(s); }