static int pckbdprobe(device_t dev) { struct resource *res; int error, rid; /* Check isapnp ids */ if (isa_get_vendorid(dev)) return (ENXIO); device_set_desc(dev, "PC-98 Keyboard"); rid = 0; res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2, RF_ACTIVE); if (res == NULL) return ENXIO; isa_load_resourcev(res, pckbd_iat, 2); error = pckbd_probe_unit(dev, isa_get_port(dev), (1 << isa_get_irq(dev)), device_get_flags(dev)); bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return (error); }
static int pckbdattach(device_t dev) { keyboard_t *kbd; void *ih; struct resource *res; int error, rid; rid = 0; res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2, RF_ACTIVE); if (res == NULL) return ENXIO; isa_load_resourcev(res, pckbd_iat, 2); error = pckbd_attach_unit(dev, &kbd, isa_get_port(dev), (1 << isa_get_irq(dev)), device_get_flags(dev)); rid = 0; res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (res == NULL) return ENXIO; bus_setup_intr(dev, res, INTR_TYPE_TTY, NULL, pckbd_isa_intr, kbd, &ih); return 0; }
static int ct_isa_match(device_t dev) { struct bshw *hw; struct resource *port_res, *mem_res; struct ct_bus_access_handle ch; int rv; if (ISA_PNP_PROBE(device_get_parent(dev), dev, ct_pnp_ids) == ENXIO) return ENXIO; switch (isa_get_logicalid(dev)) { case 0x0100e7b1: /* LHA-301 */ case 0x110154dc: /* SC-98III */ case 0x4120acb4: /* IFC-NN */ /* XXX - force to SMIT mode */ device_set_flags(dev, device_get_flags(dev) | 0x40000); break; } if (isa_get_port(dev) == -1) bus_set_resource(dev, SYS_RES_IOPORT, 0, BSHW_IOBASE, BSHW_IOSZ); if ((hw = ct_find_hw(dev)) == NULL) return ENXIO; if (ct_space_map(dev, hw, &port_res, &mem_res) != 0) return ENXIO; bzero(&ch, sizeof(ch)); ch.ch_iot = rman_get_bustag(port_res); ch.ch_ioh = rman_get_bushandle(port_res), ch.ch_bus_weight = ct_isa_bus_access_weight; rv = ctprobesubr(&ch, 0, BSHW_DEFAULT_HOSTID, BSHW_DEFAULT_CHIPCLK, NULL); if (rv != 0) { struct bshw_softc bshw_tab; struct bshw_softc *bs = &bshw_tab; memset(bs, 0, sizeof(*bs)); bshw_read_settings(&ch, bs); bus_set_resource(dev, SYS_RES_IRQ, 0, bs->sc_irq, 1); bus_set_resource(dev, SYS_RES_DRQ, 0, bs->sc_drq, 1); } bus_release_resource(dev, SYS_RES_IOPORT, 0, port_res); if (mem_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, mem_res); if (rv != 0) return 0; return ENXIO; }
static int pckbdprobe(device_t dev) { /* Check isapnp ids */ if (isa_get_vendorid(dev)) return (ENXIO); device_set_desc(dev, "PC-98 Keyboard"); return pckbd_probe_unit(device_get_unit(dev), isa_get_port(dev), (1 << isa_get_irq(dev)), device_get_flags(dev)); }
static int aps_probe(struct device *dev) { struct resource *iores; int iorid = 0; u_int8_t cr; unsigned char iobuf[16]; #if defined(APSDEBUG) || defined(KLD_MODULE) device_printf(dev, "%s: port 0x%x\n", __func__, isa_get_port(dev)); #endif if (device_get_unit(dev) != 0) return ENXIO; iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &iorid, RF_ACTIVE); if (iores == NULL) { DPRINTF(("aps: can't map i/o space\n")); return ENXIO; } /* See if this machine has APS */ /* get APS mode */ iobuf[APS_CMD] = 0x13; if (aps_do_io(iores, iobuf, APS_WRITE_0, APS_READ_1)) { bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores); return ENXIO; } /* * Observed values from Linux driver: * 0x01: T42 * 0x02: chip already initialised * 0x03: T41 * 0x05: T61 */ cr = iobuf[APS_ARG1]; bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores); DPRINTF(("aps: state register 0x%x\n", cr)); if (iobuf[APS_RET] != 0 || cr < 1 || cr > 5) { DPRINTF(("aps: unsupported state %d\n", cr)); return ENXIO; } device_set_desc(dev, "ThinkPad Active Protection System"); return 0; }
static int aic_isa_probe(device_t dev) { struct aic_isa_softc *sc = device_get_softc(dev); struct aic_softc *aic = &sc->sc_aic; int numports, i; u_int port, *ports; u_int8_t porta; if (ISA_PNP_PROBE(device_get_parent(dev), dev, aic_ids) == ENXIO) return (ENXIO); port = isa_get_port(dev); if (port != -1) { ports = &port; numports = 1; } else { ports = aic_isa_ports; numports = AIC_ISA_NUMPORTS; } for (i = 0; i < numports; i++) { if (bus_set_resource(dev, SYS_RES_IOPORT, 0, ports[i], AIC_ISA_PORTSIZE, -1)) continue; if (aic_isa_alloc_resources(dev)) continue; if (!aic_probe(aic)) { aic_isa_release_resources(dev); break; } aic_isa_release_resources(dev); } if (i == numports) return (ENXIO); porta = aic_inb(aic, PORTA); if (isa_get_irq(dev) == -1) { int irq = PORTA_IRQ(porta); bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1, machintr_intr_cpuid(irq)); } if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1) bus_set_resource(dev, SYS_RES_DRQ, 0, PORTA_DRQ(porta), 1, -1); device_set_desc(dev, "Adaptec 6260/6360 SCSI controller"); return (0); }
static int pckbdattach(device_t dev) { keyboard_t *kbd; void *ih; struct resource *res; int zero = 0; pckbd_attach_unit(device_get_unit(dev), &kbd, isa_get_port(dev), (1 << isa_get_irq(dev)), device_get_flags(dev)); res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, 0ul, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE); BUS_SETUP_INTR(device_get_parent(dev), dev, res, INTR_TYPE_TTY, pckbd_isa_intr, kbd, &ih); return (0); }
static void aps_identify(driver_t *driver, struct device *parent) { struct device *child; child = device_find_child(parent, driver->name, -1); if (child != NULL) { if (isa_get_portsize(child) == 0) { // aps(4) must have been compiled into the kernel if (bootverbose) kprintf("%s: will specify the port\n", __func__); } else if (isa_get_port(child) != APS_ADDR_BASE) kprintf("%s: will overwrite specified port\n", __func__); else { if (isa_get_portsize(child) == APS_ADDR_SIZE) { // aps.ko must have been reloaded kprintf("%s: already have been invoked\n", __func__); return; } else kprintf("%s: will amend the portsize\n", __func__); } } else { // first invocation of `kldload aps.ko` kprintf("%s: creating a new %s\n", __func__, driver->name); child = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, driver->name, -1); if (child == NULL) { kprintf("%s: cannot add child\n", __func__); return; } } if (bus_set_resource(child, SYS_RES_IOPORT, 0, APS_ADDR_BASE, APS_ADDR_SIZE, -1)) kprintf("%s: cannot set resource\n", __func__); }
int lpt_probe(device_t dev) { #define PC98_OLD_LPT 0x40 #define PC98_IEEE_1284_FUNCTION 0x149 int rid; struct resource *res; /* Check isapnp ids */ if (isa_get_vendorid(dev)) return ENXIO; rid = 0; res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, lpt_iat, 4, RF_ACTIVE); if (res == NULL) return ENXIO; isa_load_resourcev(res, lpt_iat, 4); if (isa_get_port(dev) == PC98_OLD_LPT) { unsigned int pc98_ieee_mode, tmp; tmp = inb(PC98_IEEE_1284_FUNCTION); pc98_ieee_mode = tmp; if ((tmp & 0x10) == 0x10) { outb(PC98_IEEE_1284_FUNCTION, tmp & ~0x10); tmp = inb(PC98_IEEE_1284_FUNCTION); if ((tmp & 0x10) != 0x10) { outb(PC98_IEEE_1284_FUNCTION, pc98_ieee_mode); bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return ENXIO; } } } bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return 0; }
/* * Check if the device can be found at the port given * and if so, set it up ready for further work * as an argument, takes the isa_device structure from * autoconf.c */ static int bt_isa_probe(device_t dev) { /* * find unit and check we have that many defined */ int port_index; int max_port_index; /* No pnp support */ if (isa_get_vendorid(dev)) return (ENXIO); port_index = 0; max_port_index = BT_NUM_ISAPORTS - 1; /* * Bound our board search if the user has * specified an exact port. */ bt_find_probe_range(isa_get_port(dev), &port_index, &max_port_index); if (port_index < 0) return (ENXIO); /* Attempt to find an adapter */ for (;port_index <= max_port_index; port_index++) { struct bt_probe_info info; u_int ioport; ioport = bt_iop_from_bio(port_index); /* * Ensure this port has not already been claimed already * by a PCI, EISA or ISA adapter. */ if (bt_check_probed_iop(ioport) != 0) continue; /* Initialise the softc for use during probing */ if (bt_isa_alloc_resources(dev, ioport, ioport + BT_NREGS -1) != 0) continue; /* We're going to attempt to probe it now, so mark it probed */ bt_mark_probed_bio(port_index); if (bt_port_probe(dev, &info) != 0) { if (bootverbose) kprintf("bt_isa_probe: Probe failed at 0x%x\n", ioport); bt_isa_release_resources(dev); continue; } bt_isa_release_resources(dev); bus_set_resource(dev, SYS_RES_DRQ, 0, info.drq, 1, -1); bus_set_resource(dev, SYS_RES_IRQ, 0, info.irq, 1, machintr_legacy_intr_cpuid(info.irq)); return (0); } return (ENXIO); }
static int alloc_resource(sc_p scp) { int i, base, lid, flags; device_t dev; flags = 0; if (isa_get_vendorid(scp->dev)) lid = isa_get_logicalid(scp->dev); else { lid = LOGICALID_NOPNP; flags = device_get_flags(scp->dev); } switch(lid) { case LOGICALID_PCM: case LOGICALID_NOPNP: /* XXX Non-PnP */ if (lid == LOGICALID_NOPNP) base = isa_get_port(scp->dev); else base = 0; for (i = 0 ; i < sizeof(scp->io) / sizeof(*scp->io) ; i++) { if (scp->io[i] == NULL) { scp->io_rid[i] = i; if (base == 0) scp->io[i] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[i], 0, ~0, io_range[i], RF_ACTIVE); else scp->io[i] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[i], base + io_offset[i], base + io_offset[i] + io_range[i] - 1 , io_range[i], RF_ACTIVE); if (scp->io[i] == NULL) return (1); scp->io_alloced[i] = 0; } } if (scp->irq == NULL) { scp->irq_rid = 0; scp->irq = bus_alloc_resource_any(scp->dev, SYS_RES_IRQ, &scp->irq_rid, RF_ACTIVE|RF_SHAREABLE); if (scp->irq == NULL) return (1); scp->irq_alloced = 0; } for (i = 0 ; i < sizeof(scp->drq) / sizeof(*scp->drq) ; i++) { if (scp->drq[i] == NULL) { scp->drq_rid[i] = i; if (base == 0 || i == 0) scp->drq[i] = bus_alloc_resource_any( scp->dev, SYS_RES_DRQ, &scp->drq_rid[i], RF_ACTIVE); else if ((flags & DV_F_DUAL_DMA) != 0) /* XXX The secondary drq is specified in the flag. */ scp->drq[i] = bus_alloc_resource(scp->dev, SYS_RES_DRQ, &scp->drq_rid[i], flags & DV_F_DRQ_MASK, flags & DV_F_DRQ_MASK, 1, RF_ACTIVE); if (scp->drq[i] == NULL) return (1); scp->drq_alloced[i] = 0; } } break; case LOGICALID_OPL: if (scp->io[0] == NULL) { scp->io_rid[0] = 0; scp->io[0] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[0], 0, ~0, io_range[0], RF_ACTIVE); if (scp->io[0] == NULL) return (1); scp->io_alloced[0] = 0; } break; case LOGICALID_MIDI: if (scp->io[0] == NULL) { scp->io_rid[0] = 0; scp->io[0] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[0], 0, ~0, io_range[0], RF_ACTIVE); if (scp->io[0] == NULL) return (1); scp->io_alloced[0] = 0; } if (scp->irq == NULL) { /* The irq is shared with pcm audio. */ dev = find_masterdev(scp); if (dev == NULL) return (1); scp->irq_rid = 0; scp->irq = BUS_ALLOC_RESOURCE(dev, NULL, SYS_RES_IRQ, &scp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); if (scp->irq == NULL) return (1); scp->irq_alloced = 0; } break; } return (0); }
static int gusisa_probe(device_t dev) { device_t child; struct resource *res, *res2; int base, rid, rid2, s, flags; unsigned char val; base = isa_get_port(dev); flags = device_get_flags(dev); rid = 1; res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, base + 0x100, base + 0x107, 8, RF_ACTIVE); if (res == NULL) return ENXIO; res2 = NULL; /* * Check for the presence of some GUS card. Reset the card, * then see if we can access the memory on it. */ port_wr(res, 3, 0x4c); port_wr(res, 5, 0); DELAY(30 * 1000); port_wr(res, 3, 0x4c); port_wr(res, 5, 1); DELAY(30 * 1000); s = splhigh(); /* Write to DRAM. */ port_wr(res, 3, 0x43); /* Register select */ port_wr(res, 4, 0); /* Low addr */ port_wr(res, 5, 0); /* Med addr */ port_wr(res, 3, 0x44); /* Register select */ port_wr(res, 4, 0); /* High addr */ port_wr(res, 7, 0x55); /* DRAM */ /* Read from DRAM. */ port_wr(res, 3, 0x43); /* Register select */ port_wr(res, 4, 0); /* Low addr */ port_wr(res, 5, 0); /* Med addr */ port_wr(res, 3, 0x44); /* Register select */ port_wr(res, 4, 0); /* High addr */ val = port_rd(res, 7); /* DRAM */ splx(s); if (val != 0x55) goto fail; rid2 = 0; res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid2, base, base, 1, RF_ACTIVE); if (res2 == NULL) goto fail; s = splhigh(); port_wr(res2, 0x0f, 0x20); val = port_rd(res2, 0x0f); splx(s); if (val == 0xff || (val & 0x06) == 0) val = 0; else { val = port_rd(res2, 0x506); /* XXX Out of range. */ if (val == 0xff) val = 0; } bus_release_resource(dev, SYS_RES_IOPORT, rid2, res2); bus_release_resource(dev, SYS_RES_IOPORT, rid, res); if (val >= 10) { struct sndcard_func *func; /* Looks like a GUS MAX. Set the rest of the resources. */ bus_set_resource(dev, SYS_RES_IOPORT, 2, base + 0x10c, 8); if (flags & DV_F_DUAL_DMA) bus_set_resource(dev, SYS_RES_DRQ, 1, flags & DV_F_DRQ_MASK, 1); /* We can support the CS4231 and MIDI devices. */ func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); if (func == NULL) return ENOMEM; func->func = SCF_MIDI; child = device_add_child(dev, "midi", -1); device_set_ivars(child, func); func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); if (func == NULL) printf("xxx: gus pcm not attached, out of memory\n"); else { func->func = SCF_PCM; child = device_add_child(dev, "pcm", -1); device_set_ivars(child, func); } device_set_desc(dev, "Gravis UltraSound MAX"); return 0; } else { /* * TODO: Support even older GUS cards. MIDI should work on * all models. */ return ENXIO; } fail: bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return ENXIO; }
static int pmc_isa_probe(device_t dev) { struct pmc_isa_softc *sc = device_get_softc(dev); u_int port; u_int16_t save, tmp; #if 0 if (isa_get_vendorid(dev)) { return ENXIO; } if (device_get_unit(dev) > 0) { printf("pmc: Only one PMC driver supported.\n"); return ENXIO; } #endif port = isa_get_port(dev); if (port == -1) { port = PMC_ISA_PORT; } if (bootverbose) { device_printf(dev, "port = 0x%x\n", port); } if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port, PMC_ISA_PORTSIZE)) { if (bootverbose) { device_printf(dev, "bus_set_resource failed\n"); } return ENXIO; } if (pmc_isa_alloc_resources(dev)) { if (bootverbose) { device_printf(dev, "pmc_isa_alloc_resources failed\n"); } return ENXIO; } /* Check the existence of PMC */ sc_outw(sc, 0, 0x0052); save = sc_inw(sc, 2); tmp = save & ~0x3f; sc_outw(sc, 2, tmp); if (sc_inw(sc, 2) != tmp) { if (bootverbose) { device_printf(dev, "failed to clear index(0x0052)\n"); } pmc_isa_release_resources(dev); return ENXIO; } tmp |= 0x3e; sc_outw(sc, 2, tmp); if (sc_inw(sc, 2) != tmp) { if (bootverbose) { device_printf(dev, "failed to set index(0x0052)\n"); } pmc_isa_release_resources(dev); return ENXIO; } sc_outw(sc, 2, save); pmc_isa_release_resources(dev); device_set_desc(dev, "Power Management Controller"); return 0; }
int lpt_probe(device_t dev) { #ifdef PC98 #define PC98_OLD_LPT 0x40 #define PC98_IEEE_1284_FUNCTION 0x149 int rid; struct resource *res; /* Check isapnp ids */ if (isa_get_vendorid(dev)) return ENXIO; rid = 0; res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, lpt_iat, 4, RF_ACTIVE); if (res == NULL) return ENXIO; isa_load_resourcev(res, lpt_iat, 4); if (isa_get_port(dev) == PC98_OLD_LPT) { unsigned int pc98_ieee_mode, tmp; tmp = inb(PC98_IEEE_1284_FUNCTION); pc98_ieee_mode = tmp; if ((tmp & 0x10) == 0x10) { outb(PC98_IEEE_1284_FUNCTION, tmp & ~0x10); tmp = inb(PC98_IEEE_1284_FUNCTION); if ((tmp & 0x10) != 0x10) { outb(PC98_IEEE_1284_FUNCTION, pc98_ieee_mode); bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return ENXIO; } } } bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return 0; #else int port; static short next_bios_lpt = 0; int status; static u_char testbyte[18] = { 0x55, /* alternating zeros */ 0xaa, /* alternating ones */ 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f, /* walking zero */ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 /* walking one */ }; int i; /* * Make sure there is some way for lptopen to see that * the port is not configured * This 0 will remain if the port isn't attached */ (lpt_sc + dvp->id_unit)->sc_port = 0; status = IO_LPTSIZE; /* If port not specified, use bios list */ if(dvp->id_iobase < 0) { /* port? */ if((next_bios_lpt < BIOS_MAX_LPT) && (*(BIOS_PORTS+next_bios_lpt) != 0) ) { dvp->id_iobase = *(BIOS_PORTS+next_bios_lpt++); goto end_probe; } else return (0); } /* Port was explicitly specified */ /* This allows probing of ports unknown to the BIOS */ port = dvp->id_iobase + lpt_data; for (i = 0; i < 18; i++) { if (!lpt_port_test(port, testbyte[i], 0xff)) { status = 0; goto end_probe; } } end_probe: /* write 0's to control and data ports */ outb(dvp->id_iobase+lpt_data, 0); outb(dvp->id_iobase+lpt_control, 0); return (status); #endif }