static int cy_isa_probe(device_t dev) { struct resource *mem_res; cy_addr iobase; int mem_rid; if (isa_get_logicalid(dev) != 0) /* skip PnP probes */ return (ENXIO); mem_rid = 0; mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid, 0ul, ~0ul, 0ul, RF_ACTIVE); if (mem_res == NULL) { device_printf(dev, "ioport resource allocation failed\n"); return (ENXIO); } iobase = rman_get_virtual(mem_res); /* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */ cy_inb(iobase, CY16_RESET, 0); /* XXX? */ DELAY(500); /* wait for the board to get its act together */ /* this is needed to get the board out of reset */ cy_outb(iobase, CY_CLEAR_INTR, 0, 0); DELAY(500); bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res); return (cy_units(iobase, 0) == 0 ? ENXIO : 0); }
static int uart_isa_probe(device_t dev) { struct uart_softc *sc; device_t parent; parent = device_get_parent(dev); sc = device_get_softc(dev); /* Check PnP IDs */ if (ISA_PNP_PROBE(parent, dev, isa_ns8250_ids) == ENXIO) return (ENXIO); /* Probe PnP _and_ non-PnP ns8250 here. */ #ifdef PC98 if (isa_get_logicalid(dev)) sc->sc_class = &uart_ns8250_class; else sc->sc_class = uart_pc98_getdev(bus_get_resource_start(dev, SYS_RES_IOPORT, 0)); #else sc->sc_class = &uart_ns8250_class; #endif return (uart_bus_probe(dev, 0, 0, 0, 0)); }
static int sbc_probe(device_t dev) { char *s = NULL; u_int32_t lid, vid; lid = isa_get_logicalid(dev); vid = isa_get_vendorid(dev); if (lid) { if (lid == 0x01000000 && vid != 0x01009305) /* ALS0001 */ return ENXIO; /* Check pnp ids */ return ISA_PNP_PROBE(device_get_parent(dev), dev, sbc_ids); } else { int rid = 0, ver; struct resource *io; #ifdef PC98 io = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pcm_iat, 16, RF_ACTIVE); #else io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 16, RF_ACTIVE); #endif if (!io) goto bad; #ifdef PC98 isa_load_resourcev(io, pcm_iat, 16); #endif if (sb_reset_dsp(io)) goto bad2; ver = sb_identify_board(io); if (ver == 0) goto bad2; switch ((ver & 0x00000f00) >> 8) { case 1: device_set_desc(dev, "SoundBlaster 1.0 (not supported)"); s = NULL; break; case 2: s = "SoundBlaster 2.0"; break; case 3: s = (ver & 0x0000f000)? "ESS 488" : "SoundBlaster Pro"; break; case 4: s = "SoundBlaster 16"; break; case 5: s = (ver & 0x00000008)? "ESS 688" : "ESS 1688"; break; } if (s) device_set_desc(dev, s); bad2: bus_release_resource(dev, SYS_RES_IOPORT, rid, io); bad: return s? 0 : ENXIO; } }
static int gusc_probe(device_t dev) { device_t child; u_int32_t logical_id; char *s; struct sndcard_func *func; int ret; logical_id = isa_get_logicalid(dev); s = NULL; /* Check isapnp ids */ if (logical_id != 0 && (ret = ISA_PNP_PROBE(device_get_parent(dev), dev, gusc_ids)) != 0) return (ret); else { if (logical_id == 0) return gusisa_probe(dev); } switch (logical_id) { case LOGICALID_PCM: s = "Gravis UltraSound Plug & Play PCM"; func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); if (func == NULL) return (ENOMEM); func->func = SCF_PCM; child = device_add_child(dev, "pcm", -1); device_set_ivars(child, func); break; case LOGICALID_OPL: s = "Gravis UltraSound Plug & Play OPL"; func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); if (func == NULL) return (ENOMEM); func->func = SCF_SYNTH; child = device_add_child(dev, "midi", -1); device_set_ivars(child, func); break; case LOGICALID_MIDI: s = "Gravis UltraSound Plug & Play MIDI"; 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); break; } if (s != NULL) { device_set_desc(dev, s); return (0); } return (ENXIO); }
static int sn_isa_probe (device_t dev) { if (isa_get_logicalid(dev)) /* skip PnP probes */ return (ENXIO); if (sn_probe(dev) != 0) return (ENXIO); return (0); }
static int ichwd_probe(device_t dev) { /* Do not claim some ISA PnP device by accident. */ if (isa_get_logicalid(dev) != 0) return (ENXIO); return (0); }
static int release_resource(sc_p scp) { int i, 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 */ for (i = 0 ; i < NELEM(scp->io) ; i++) { if (scp->io[i] != NULL) { bus_release_resource(scp->dev, SYS_RES_IOPORT, scp->io_rid[i], scp->io[i]); scp->io[i] = NULL; } } if (scp->irq != NULL) { bus_release_resource(scp->dev, SYS_RES_IRQ, scp->irq_rid, scp->irq); scp->irq = NULL; } for (i = 0 ; i < NELEM(scp->drq) ; i++) { if (scp->drq[i] != NULL) { bus_release_resource(scp->dev, SYS_RES_DRQ, scp->drq_rid[i], scp->drq[i]); scp->drq[i] = NULL; } } break; case LOGICALID_OPL: if (scp->io[0] != NULL) { bus_release_resource(scp->dev, SYS_RES_IOPORT, scp->io_rid[0], scp->io[0]); scp->io[0] = NULL; } break; case LOGICALID_MIDI: if (scp->io[0] != NULL) { bus_release_resource(scp->dev, SYS_RES_IOPORT, scp->io_rid[0], scp->io[0]); scp->io[0] = NULL; } if (scp->irq != NULL) { /* The irq is shared with pcm audio. */ dev = find_masterdev(scp); if (dev == NULL) return (1); BUS_RELEASE_RESOURCE(dev, NULL, SYS_RES_IOPORT, scp->irq_rid, scp->irq); scp->irq = NULL; } break; } 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 amdsbwd_probe(device_t dev) { struct resource *res; device_t smb_dev; uint32_t addr; int rid; int rc; /* Do not claim some ISA PnP device by accident. */ if (isa_get_logicalid(dev) != 0) return (ENXIO); rc = bus_set_resource(dev, SYS_RES_IOPORT, 0, AMDSB_PMIO_INDEX, AMDSB_PMIO_WIDTH); if (rc != 0) { device_printf(dev, "bus_set_resource for IO failed\n"); return (ENXIO); } rid = 0; res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul, AMDSB_PMIO_WIDTH, RF_ACTIVE | RF_SHAREABLE); if (res == NULL) { device_printf(dev, "bus_alloc_resource for IO failed\n"); return (ENXIO); } smb_dev = pci_find_bsf(0, 20, 0); KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n")); if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID) amdsbwd_probe_sb7xx(dev, res, &addr); else amdsbwd_probe_sb8xx(dev, res, &addr); bus_release_resource(dev, SYS_RES_IOPORT, rid, res); bus_delete_resource(dev, SYS_RES_IOPORT, rid); amdsbwd_verbose_printf(dev, "memory base address = %#010x\n", addr); rc = bus_set_resource(dev, SYS_RES_MEMORY, 0, addr + AMDSB_WD_CTRL, AMDSB_WDIO_REG_WIDTH); if (rc != 0) { device_printf(dev, "bus_set_resource for control failed\n"); return (ENXIO); } rc = bus_set_resource(dev, SYS_RES_MEMORY, 1, addr + AMDSB_WD_COUNT, AMDSB_WDIO_REG_WIDTH); if (rc != 0) { device_printf(dev, "bus_set_resource for count failed\n"); return (ENXIO); } return (0); }
static int aic_isa_alloc_resources(device_t dev) { struct aic_isa_softc *sc = device_get_softc(dev); int rid; bus_addr_t *bs_iat; if ((isa_get_logicalid(dev) == 0xa180a3b8) || (AIC_TYPE98(device_get_flags(dev)) == AIC98_NEC100)) bs_iat = aicport_100; else bs_iat = aicport_generic; sc->sc_port = sc->sc_irq = sc->sc_drq = NULL; rid = 0; sc->sc_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, bs_iat, AIC_ISA_PORTSIZE, RF_ACTIVE); if (!sc->sc_port) { device_printf(dev, "I/O port allocation failed\n"); return (ENOMEM); } isa_load_resourcev(sc->sc_port, bs_iat, AIC_ISA_PORTSIZE); mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF); if (isa_get_irq(dev) != -1) { rid = 0; sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!sc->sc_irq) { device_printf(dev, "IRQ allocation failed\n"); aic_isa_release_resources(dev); return (ENOMEM); } } if (isa_get_drq(dev) != -1) { rid = 0; sc->sc_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid, RF_ACTIVE); if (!sc->sc_drq) { device_printf(dev, "DRQ allocation failed\n"); aic_isa_release_resources(dev); return (ENOMEM); } } sc->sc_aic.dev = dev; sc->sc_aic.res = sc->sc_port; return (0); }
static int mecia_probe(device_t dev) { int validslots = 0; /* Check isapnp ids */ if (isa_get_logicalid(dev)) /* skip PnP probes */ return (ENXIO); if (inb(MECIA_REG0) != 0xff) { validslots++; /* XXX need to allocated the port resources */ device_set_desc(dev, "MECIA PC98 Original PCMCIA Controller"); } return (validslots ? 0 : ENXIO); }
static device_t find_masterdev(sc_p scp) { int i, units; devclass_t devclass; device_t dev; devclass = device_get_devclass(scp->dev); units = devclass_get_maxunit(devclass); dev = NULL; for (i = 0 ; i < units ; i++) { dev = devclass_get_device(devclass, i); if (isa_get_vendorid(dev) == isa_get_vendorid(scp->dev) && isa_get_logicalid(dev) == LOGICALID_PCM && isa_get_serial(dev) == isa_get_serial(scp->dev)) break; } if (i == units) return (NULL); return (dev); }
static int pcf_isa_probe(device_t dev) { u_long start, count; u_int rid = 0, port, error; /* skip PnP probes */ if (isa_get_logicalid(dev)) return (ENXIO); /* The port address must be explicitly specified */ bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count); if ((error = resource_int_value(PCF_NAME, 0, "port", &port) != 0)) return (error); /* Probe is only successfull for the specified base io */ if (port != (u_int)start) return (ENXIO); device_set_desc(dev, "PCF8584 I2C bus controller"); return (0); }
void pnp_parse_resources(device_t dev, u_char *resources, int len, int ldn) { struct isa_config *configs; struct isa_config *config; device_t parent; int priorities[1 + MAXDEP]; u_char *start; u_char *p; u_char tag; u_int32_t id; int ncfgs; int l; int i; parent = device_get_parent(dev); id = isa_get_logicalid(dev); configs = (struct isa_config *)malloc(sizeof(*configs)*(1 + MAXDEP), M_DEVBUF, M_NOWAIT | M_ZERO); if (configs == NULL) { device_printf(parent, "No memory to parse PNP data\n"); return; } config = &configs[0]; priorities[0] = 0; ncfgs = 1; p = resources; start = NULL; while (len > 0) { tag = *p++; len--; if (PNP_RES_TYPE(tag) == 0) { /* Small resource */ l = PNP_SRES_LEN(tag); if (len < l) { len = 0; continue; } len -= l; switch (PNP_SRES_NUM(tag)) { case PNP_TAG_START_DEPENDANT: if (start != NULL) { /* * Copy the common resources first, * then parse the "dependent" resources. */ pnp_merge_resources(dev, &configs[0], config); pnp_parse_dependant(dev, start, p - start - 1, config, ldn); } start = p + l; if (ncfgs > MAXDEP) { device_printf(parent, "too many dependant configs (%d)\n", MAXDEP); len = 0; break; } config = &configs[ncfgs]; /* * If the priority is not specified, * then use the default of 'acceptable' */ if (l > 0) priorities[ncfgs] = p[0]; else priorities[ncfgs] = 1; if (bootverbose) pnp_printf(id, "start dependent (%d)\n", priorities[ncfgs]); ncfgs++; break; case PNP_TAG_END_DEPENDANT: if (start == NULL) { device_printf(parent, "malformed resources\n"); len = 0; break; } /* * Copy the common resources first, * then parse the "dependent" resources. */ pnp_merge_resources(dev, &configs[0], config); pnp_parse_dependant(dev, start, p - start - 1, config, ldn); start = NULL; if (bootverbose) pnp_printf(id, "end dependent\n"); /* * Back to the common part; clear it * as its contents has already been copied * to each dependant. */ config = &configs[0]; bzero(config, sizeof(*config)); break; case PNP_TAG_END: if (start != NULL) { device_printf(parent, "malformed resources\n"); } len = 0; break; default: if (start != NULL) /* defer parsing a dependent section */ break; if (pnp_parse_desc(dev, tag, p, l, config, ldn)) len = 0; break; } p += l; } else { /* Large resource */ if (len < 2) { len = 0; break; } l = I16(p); p += 2; len -= 2; if (len < l) { len = 0; break; } len -= l; if (start == NULL && pnp_parse_desc(dev, tag, p, l, config, ldn)) { len = 0; break; } p += l; } } if (ncfgs == 1) { /* Single config without dependants */ ISA_ADD_CONFIG(parent, dev, priorities[0], &configs[0]); free(configs, M_DEVBUF); return; } for (i = 1; i < ncfgs; i++) { /* * Merge the remaining part of the common resources, * if any. Strictly speaking, there shouldn't be common/main * resources after the END_DEPENDENT tag. */ pnp_merge_resources(dev, &configs[0], &configs[i]); ISA_ADD_CONFIG(parent, dev, priorities[i], &configs[i]); } free(configs, M_DEVBUF); }
static int adv_isa_probe(device_t dev) { int port_index; int max_port_index; u_long iobase, iocount, irq; int user_iobase = 0; int rid = 0; void *ih; struct resource *iores, *irqres; /* * We don't know of any PnP ID's for these cards. */ if (isa_get_logicalid(dev) != 0) return (ENXIO); /* * Default to scanning all possible device locations. */ port_index = 0; max_port_index = MAX_ISA_IOPORT_INDEX; if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, &iocount) == 0) { user_iobase = 1; for (;port_index <= max_port_index; port_index++) if (iobase <= adv_isa_ioports[port_index]) break; if ((port_index > max_port_index) || (iobase != adv_isa_ioports[port_index])) { if (bootverbose) printf("adv%d: Invalid baseport of 0x%lx specified. " "Nearest valid baseport is 0x%x. Failing " "probe.\n", device_get_unit(dev), iobase, (port_index <= max_port_index) ? adv_isa_ioports[port_index] : adv_isa_ioports[max_port_index]); return ENXIO; } max_port_index = port_index; } /* Perform the actual probing */ adv_set_isapnp_wait_for_key(); for (;port_index <= max_port_index; port_index++) { u_int16_t port_addr = adv_isa_ioports[port_index]; bus_size_t maxsegsz; bus_size_t maxsize; bus_addr_t lowaddr; int error; struct adv_softc *adv; if (port_addr == 0) /* Already been attached */ continue; if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port_addr, 1)) continue; /* XXX what is the real portsize? */ iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (iores == NULL) continue; if (adv_find_signature(rman_get_bustag(iores), rman_get_bushandle(iores)) == 0) { bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); continue; } /* * Got one. Now allocate our softc * and see if we can initialize the card. */ adv = adv_alloc(dev, rman_get_bustag(iores), rman_get_bushandle(iores)); if (adv == NULL) { bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); break; } /* * Stop the chip. */ ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); ADV_OUTW(adv, ADV_CHIP_STATUS, 0); /* * Determine the chip version. */ adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION); if ((adv->chip_version >= ADV_CHIP_MIN_VER_VL) && (adv->chip_version <= ADV_CHIP_MAX_VER_VL)) { adv->type = ADV_VL; maxsegsz = ADV_VL_MAX_DMA_COUNT; maxsize = BUS_SPACE_MAXSIZE_32BIT; lowaddr = ADV_VL_MAX_DMA_ADDR; bus_delete_resource(dev, SYS_RES_DRQ, 0); } else if ((adv->chip_version >= ADV_CHIP_MIN_VER_ISA) && (adv->chip_version <= ADV_CHIP_MAX_VER_ISA)) { if (adv->chip_version >= ADV_CHIP_MIN_VER_ISA_PNP) { adv->type = ADV_ISAPNP; ADV_OUTB(adv, ADV_REG_IFC, ADV_IFC_INIT_DEFAULT); } else { adv->type = ADV_ISA; } maxsegsz = ADV_ISA_MAX_DMA_COUNT; maxsize = BUS_SPACE_MAXSIZE_24BIT; lowaddr = ADV_ISA_MAX_DMA_ADDR; adv->isa_dma_speed = ADV_DEF_ISA_DMA_SPEED; adv->isa_dma_channel = adv_get_isa_dma_channel(adv); bus_set_resource(dev, SYS_RES_DRQ, 0, adv->isa_dma_channel, 1); } else { panic("advisaprobe: Unknown card revision\n"); } /* * Allocate a parent dmatag for all tags created * by the MI portions of the advansys driver */ error = bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), /* alignemnt */ 1, /* boundary */ 0, /* lowaddr */ lowaddr, /* highaddr */ BUS_SPACE_MAXADDR, /* filter */ NULL, /* filterarg */ NULL, /* maxsize */ maxsize, /* nsegments */ ~0, /* maxsegsz */ maxsegsz, /* flags */ 0, /* lockfunc */ busdma_lock_mutex, /* lockarg */ &Giant, &adv->parent_dmat); if (error != 0) { printf("%s: Could not allocate DMA tag - error %d\n", adv_name(adv), error); adv_free(adv); bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); break; } adv->init_level += 2; if (overrun_buf == NULL) { /* Need to allocate our overrun buffer */ if (bus_dma_tag_create( /* parent */ adv->parent_dmat, /* alignment */ 8, /* boundary */ 0, /* lowaddr */ ADV_ISA_MAX_DMA_ADDR, /* highaddr */ BUS_SPACE_MAXADDR, /* filter */ NULL, /* filterarg */ NULL, /* maxsize */ ADV_OVERRUN_BSIZE, /* nsegments */ 1, /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, /* flags */ 0, /* lockfunc */ NULL, /* lockarg */ NULL, &overrun_dmat) != 0) { adv_free(adv); bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); break; } if (bus_dmamem_alloc(overrun_dmat, (void **)&overrun_buf, BUS_DMA_NOWAIT, &overrun_dmamap) != 0) { bus_dma_tag_destroy(overrun_dmat); adv_free(adv); bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); break; } /* And permanently map it in */ bus_dmamap_load(overrun_dmat, overrun_dmamap, overrun_buf, ADV_OVERRUN_BSIZE, adv_map, &overrun_physbase, /*flags*/0); } adv->overrun_physbase = overrun_physbase; if (adv_init(adv) != 0) { bus_dmamap_unload(overrun_dmat, overrun_dmamap); bus_dmamem_free(overrun_dmat, overrun_buf, overrun_dmamap); bus_dma_tag_destroy(overrun_dmat); adv_free(adv); bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); break; } switch (adv->type) { case ADV_ISAPNP: if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG) { adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN; adv->fix_asyn_xfer = ~0; } /* Fall Through */ case ADV_ISA: adv->max_dma_count = ADV_ISA_MAX_DMA_COUNT; adv->max_dma_addr = ADV_ISA_MAX_DMA_ADDR; adv_set_isa_dma_settings(adv); break; case ADV_VL: adv->max_dma_count = ADV_VL_MAX_DMA_COUNT; adv->max_dma_addr = ADV_VL_MAX_DMA_ADDR; break; default: panic("advisaprobe: Invalid card type\n"); } /* Determine our IRQ */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL)) bus_set_resource(dev, SYS_RES_IRQ, 0, adv_get_chip_irq(adv), 1); else adv_set_chip_irq(adv, irq); irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (irqres == NULL || bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY, NULL, adv_intr, adv, &ih)) { bus_dmamap_unload(overrun_dmat, overrun_dmamap); bus_dmamem_free(overrun_dmat, overrun_buf, overrun_dmamap); bus_dma_tag_destroy(overrun_dmat); adv_free(adv); bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); break; } /* Mark as probed */ adv_isa_ioports[port_index] = 0; return 0; } if (user_iobase) bus_set_resource(dev, SYS_RES_IOPORT, 0, iobase, iocount); else bus_delete_resource(dev, SYS_RES_IOPORT, 0); return ENXIO; }
/* * On standard ISA, we don't just use an 8 port range * (e.g. 0x3f0-0x3f7) since that covers an IDE control register at * 0x3f6. So, on older hardware, we use 0x3f0-0x3f5 and 0x3f7. * However, some BIOSs omit the control port, while others start at * 0x3f2. Of the latter, sometimes we have two resources, other times * we have one. We have to deal with the following cases: * * 1: 0x3f0-0x3f5 # very rare * 2: 0x3f0 # hints -> 0x3f0-0x3f5,0x3f7 * 3: 0x3f0-0x3f5,0x3f7 # Most common * 4: 0x3f2-0x3f5,0x3f7 # Second most common * 5: 0x3f2-0x3f5 # implies 0x3f7 too. * 6: 0x3f2-0x3f3,0x3f4-0x3f5,0x3f7 # becoming common * 7: 0x3f2-0x3f3,0x3f4-0x3f5 # rare * 8: 0x3f0-0x3f1,0x3f2-0x3f3,0x3f4-0x3f5,0x3f7 * 9: 0x3f0-0x3f3,0x3f4-0x3f5,0x3f7 * * The following code is generic for any value of 0x3fx. It is also * generic for all the above cases, as well as cases where things are * even weirder. */ int fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc) { struct resource *res; int i, j, rid, newrid, nport; u_long port; fdc->fdc_dev = dev; rid = 0; for (i = 0; i < FDC_MAXREG; i++) fdc->resio[i] = NULL; nport = isa_get_logicalid(dev) ? 1 : 6; for (rid = 0; ; rid++) { newrid = rid; res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid, 0ul, ~0ul, rid == 0 ? nport : 1, RF_ACTIVE); if (res == NULL) break; /* * Mask off the upper bits of the register, and sanity * check resource ranges. */ i = rman_get_start(res) & 0x7; if (i + rman_get_size(res) - 1 > FDC_MAXREG) { bus_release_resource(dev, SYS_RES_IOPORT, newrid, res); return (ENXIO); } for (j = 0; j < rman_get_size(res); j++) { fdc->resio[i + j] = res; fdc->ridio[i + j] = newrid; fdc->ioff[i + j] = j; fdc->ioh[i + j] = rman_get_bushandle(res); } } if (fdc->resio[2] == NULL) { device_printf(dev, "No FDOUT register!\n"); return (ENXIO); } fdc->iot = rman_get_bustag(fdc->resio[2]); if (fdc->resio[7] == NULL) { port = (rman_get_start(fdc->resio[2]) & ~0x7) + 7; newrid = rid; res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid, port, port, 1, RF_ACTIVE); if (res == NULL) { device_printf(dev, "Faking up FDCTL\n"); fdc->resio[7] = fdc->resio[2]; fdc->ridio[7] = fdc->ridio[2]; fdc->ioff[7] = fdc->ioff[2] + 5; fdc->ioh[7] = fdc->ioh[2]; } else { fdc->resio[7] = res; fdc->ridio[7] = newrid; fdc->ioff[7] = rman_get_start(res) & 7; fdc->ioh[7] = rman_get_bushandle(res); } } fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq, RF_ACTIVE | RF_SHAREABLE); if (fdc->res_irq == NULL) { device_printf(dev, "cannot reserve interrupt line\n"); return (ENXIO); } if ((fdc->flags & FDC_NODMA) == 0) { fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &fdc->rid_drq, RF_ACTIVE | RF_SHAREABLE); if (fdc->res_drq == NULL) { device_printf(dev, "cannot reserve DMA request line\n"); /* This is broken and doesn't work for ISA case */ fdc->flags |= FDC_NODMA; } else fdc->dmachan = rman_get_start(fdc->res_drq); } return (0); }
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 sbc_attach(device_t dev) { char *err = NULL; struct sbc_softc *scp; struct sndcard_func *func; u_int32_t logical_id = isa_get_logicalid(dev); int flags = device_get_flags(dev); int f, dh, dl, x, irq, i; if (!logical_id && (flags & DV_F_DUAL_DMA)) { bus_set_resource(dev, SYS_RES_DRQ, 1, flags & DV_F_DRQ_MASK, 1); } scp = device_get_softc(dev); bzero(scp, sizeof(*scp)); scp->dev = dev; sbc_lockinit(scp); err = "alloc_resource"; if (alloc_resource(scp)) goto bad; err = "sb_reset_dsp"; if (sb_reset_dsp(scp->io[0])) goto bad; err = "sb_identify_board"; scp->bd_ver = sb_identify_board(scp->io[0]) & 0x00000fff; if (scp->bd_ver == 0) goto bad; f = 0; if (logical_id == 0x01200000 && scp->bd_ver < 0x0400) scp->bd_ver = 0x0499; switch ((scp->bd_ver & 0x0f00) >> 8) { case 1: /* old sound blaster has nothing... */ break; case 2: f |= BD_F_DUP_MIDI; if (scp->bd_ver > 0x200) f |= BD_F_MIX_CT1335; break; case 5: f |= BD_F_ESS; scp->bd_ver = 0x0301; case 3: f |= BD_F_DUP_MIDI | BD_F_MIX_CT1345; break; case 4: f |= BD_F_SB16 | BD_F_MIX_CT1745; if (scp->drq[0]) dl = rman_get_start(scp->drq[0]); else dl = -1; if (scp->drq[1]) dh = rman_get_start(scp->drq[1]); else dh = dl; if (!logical_id && (dh < dl)) { struct resource *r; r = scp->drq[0]; scp->drq[0] = scp->drq[1]; scp->drq[1] = r; dl = rman_get_start(scp->drq[0]); dh = rman_get_start(scp->drq[1]); } /* soft irq/dma configuration */ x = -1; irq = rman_get_start(scp->irq[0]); #ifdef PC98 /* SB16 in PC98 use different IRQ table */ if (irq == 3) x = 1; else if (irq == 5) x = 8; else if (irq == 10) x = 2; else if (irq == 12) x = 4; if (x == -1) { err = "bad irq (3/5/10/12 valid)"; goto bad; } else sb_setmixer(scp->io[0], IRQ_NR, x); /* SB16 in PC98 use different dma setting */ sb_setmixer(scp->io[0], DMA_NR, dh == 0 ? 1 : 2); #else if (irq == 5) x = 2; else if (irq == 7) x = 4; else if (irq == 9) x = 1; else if (irq == 10) x = 8; if (x == -1) { err = "bad irq (5/7/9/10 valid)"; goto bad; } else sb_setmixer(scp->io[0], IRQ_NR, x); sb_setmixer(scp->io[0], DMA_NR, (1 << dh) | (1 << dl)); #endif if (bootverbose) { device_printf(dev, "setting card to irq %d, drq %d", irq, dl); if (dl != dh) printf(", %d", dh); printf("\n"); } break; } switch (logical_id) { case 0x43008c0e: /* CTL0043 */ case 0x01200000: case 0x01000000: f |= BD_F_SB16X; break; } scp->bd_ver |= f << 16; err = "setup_intr"; for (i = 0; i < IRQ_MAX; i++) { scp->ihl[i].parent = scp; if (snd_setup_intr(dev, scp->irq[i], 0, sbc_intr, &scp->ihl[i], &scp->ih[i])) goto bad; } /* PCM Audio */ func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); if (func == NULL) goto bad; func->func = SCF_PCM; scp->child_pcm = device_add_child(dev, "pcm", -1); device_set_ivars(scp->child_pcm, func); /* Midi Interface */ func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); if (func == NULL) goto bad; func->func = SCF_MIDI; scp->child_midi1 = device_add_child(dev, "midi", -1); device_set_ivars(scp->child_midi1, func); /* OPL FM Synthesizer */ func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); if (func == NULL) goto bad; func->func = SCF_SYNTH; scp->child_midi2 = device_add_child(dev, "midi", -1); device_set_ivars(scp->child_midi2, func); /* probe/attach kids */ bus_generic_attach(dev); return (0); bad: if (err) device_printf(dev, "%s\n", err); release_resource(scp); return (ENXIO); }
static int pnp_parse_desc(device_t dev, u_char tag, u_char *res, int len, struct isa_config *config, int ldn) { char buf[100]; u_int32_t id; u_int32_t compat_id; int temp; id = isa_get_logicalid(dev); if (PNP_RES_TYPE(tag) == 0) { /* Small resource */ switch (PNP_SRES_NUM(tag)) { case PNP_TAG_VERSION: case PNP_TAG_VENDOR: /* these descriptors are quietly ignored */ break; case PNP_TAG_LOGICAL_DEVICE: case PNP_TAG_START_DEPENDANT: case PNP_TAG_END_DEPENDANT: if (bootverbose) pnp_printf(id, "unexpected small tag %d\n", PNP_SRES_NUM(tag)); /* shouldn't happen; quit now */ return (1); case PNP_TAG_COMPAT_DEVICE: /* * Got a compatible device id resource. * Should keep a list of compat ids in the device. */ bcopy(res, &compat_id, 4); if (isa_get_compatid(dev) == 0) isa_set_compatid(dev, compat_id); break; case PNP_TAG_IRQ_FORMAT: if (config->ic_nirq == ISA_NIRQ) { pnp_printf(id, "too many irqs\n"); return (1); } if (I16(res) == 0) { /* a null descriptor */ config->ic_irqmask[config->ic_nirq] = 0; config->ic_nirq++; break; } if (bootverbose) pnp_printf(id, "adding irq mask %#02x\n", I16(res)); config->ic_irqmask[config->ic_nirq] = I16(res); config->ic_nirq++; break; case PNP_TAG_DMA_FORMAT: if (config->ic_ndrq == ISA_NDRQ) { pnp_printf(id, "too many drqs\n"); return (1); } if (res[0] == 0) { /* a null descriptor */ config->ic_drqmask[config->ic_ndrq] = 0; config->ic_ndrq++; break; } if (bootverbose) pnp_printf(id, "adding dma mask %#02x\n", res[0]); config->ic_drqmask[config->ic_ndrq] = res[0]; config->ic_ndrq++; break; case PNP_TAG_IO_RANGE: if (config->ic_nport == ISA_NPORT) { pnp_printf(id, "too many ports\n"); return (1); } if (res[6] == 0) { /* a null descriptor */ config->ic_port[config->ic_nport].ir_start = 0; config->ic_port[config->ic_nport].ir_end = 0; config->ic_port[config->ic_nport].ir_size = 0; config->ic_port[config->ic_nport].ir_align = 0; config->ic_nport++; break; } if (bootverbose) { pnp_printf(id, "adding io range " "%#x-%#x, size=%#x, " "align=%#x\n", I16(res + 1), I16(res + 3) + res[6]-1, res[6], res[5]); } config->ic_port[config->ic_nport].ir_start = I16(res + 1); config->ic_port[config->ic_nport].ir_end = I16(res + 3) + res[6] - 1; config->ic_port[config->ic_nport].ir_size = res[6]; if (res[5] == 0) { /* Make sure align is at least one */ res[5] = 1; } config->ic_port[config->ic_nport].ir_align = res[5]; config->ic_nport++; pnp_check_quirks(isa_get_vendorid(dev), isa_get_logicalid(dev), ldn, config); break; case PNP_TAG_IO_FIXED: if (config->ic_nport == ISA_NPORT) { pnp_printf(id, "too many ports\n"); return (1); } if (res[2] == 0) { /* a null descriptor */ config->ic_port[config->ic_nport].ir_start = 0; config->ic_port[config->ic_nport].ir_end = 0; config->ic_port[config->ic_nport].ir_size = 0; config->ic_port[config->ic_nport].ir_align = 0; config->ic_nport++; break; } if (bootverbose) { pnp_printf(id, "adding fixed io range " "%#x-%#x, size=%#x, " "align=%#x\n", I16(res), I16(res) + res[2] - 1, res[2], 1); } config->ic_port[config->ic_nport].ir_start = I16(res); config->ic_port[config->ic_nport].ir_end = I16(res) + res[2] - 1; config->ic_port[config->ic_nport].ir_size = res[2]; config->ic_port[config->ic_nport].ir_align = 1; config->ic_nport++; break; case PNP_TAG_END: if (bootverbose) pnp_printf(id, "end config\n"); return (1); default: /* Skip this resource */ pnp_printf(id, "unexpected small tag %d\n", PNP_SRES_NUM(tag)); break; } } else { /* Large resource */ switch (PNP_LRES_NUM(tag)) { case PNP_TAG_ID_UNICODE: case PNP_TAG_LARGE_VENDOR: /* these descriptors are quietly ignored */ break; case PNP_TAG_ID_ANSI: if (len > sizeof(buf) - 1) len = sizeof(buf) - 1; bcopy(res, buf, len); /* * Trim trailing spaces and garbage. */ while (len > 0 && buf[len - 1] <= ' ') len--; buf[len] = '\0'; device_set_desc_copy(dev, buf); break; case PNP_TAG_MEMORY_RANGE: if (config->ic_nmem == ISA_NMEM) { pnp_printf(id, "too many memory ranges\n"); return (1); } if (I16(res + 7) == 0) { /* a null descriptor */ config->ic_mem[config->ic_nmem].ir_start = 0; config->ic_mem[config->ic_nmem].ir_end = 0; config->ic_mem[config->ic_nmem].ir_size = 0; config->ic_mem[config->ic_nmem].ir_align = 0; config->ic_nmem++; break; } if (bootverbose) { temp = I16(res + 7) << 8; pnp_printf(id, "adding memory range " "%#x-%#x, size=%#x, " "align=%#x\n", I16(res + 1) << 8, (I16(res + 3) << 8) + temp - 1, temp, I16(res + 5)); } config->ic_mem[config->ic_nmem].ir_start = I16(res + 1) << 8; config->ic_mem[config->ic_nmem].ir_end = (I16(res + 3) << 8) + (I16(res + 7) << 8) - 1; config->ic_mem[config->ic_nmem].ir_size = I16(res + 7) << 8; config->ic_mem[config->ic_nmem].ir_align = I16(res + 5); if (!config->ic_mem[config->ic_nmem].ir_align) config->ic_mem[config->ic_nmem].ir_align = 0x10000; config->ic_nmem++; break; case PNP_TAG_MEMORY32_RANGE: if (config->ic_nmem == ISA_NMEM) { pnp_printf(id, "too many memory ranges\n"); return (1); } if (I32(res + 13) == 0) { /* a null descriptor */ config->ic_mem[config->ic_nmem].ir_start = 0; config->ic_mem[config->ic_nmem].ir_end = 0; config->ic_mem[config->ic_nmem].ir_size = 0; config->ic_mem[config->ic_nmem].ir_align = 0; config->ic_nmem++; break; } if (bootverbose) { pnp_printf(id, "adding memory32 range " "%#x-%#x, size=%#x, " "align=%#x\n", I32(res + 1), I32(res + 5) + I32(res + 13) - 1, I32(res + 13), I32(res + 9)); } config->ic_mem[config->ic_nmem].ir_start = I32(res + 1); config->ic_mem[config->ic_nmem].ir_end = I32(res + 5) + I32(res + 13) - 1; config->ic_mem[config->ic_nmem].ir_size = I32(res + 13); config->ic_mem[config->ic_nmem].ir_align = I32(res + 9); config->ic_nmem++; break; case PNP_TAG_MEMORY32_FIXED: if (config->ic_nmem == ISA_NMEM) { pnp_printf(id, "too many memory ranges\n"); return (1); } if (I32(res + 5) == 0) { /* a null descriptor */ config->ic_mem[config->ic_nmem].ir_start = 0; config->ic_mem[config->ic_nmem].ir_end = 0; config->ic_mem[config->ic_nmem].ir_size = 0; config->ic_mem[config->ic_nmem].ir_align = 0; break; } if (bootverbose) { pnp_printf(id, "adding fixed memory32 range " "%#x-%#x, size=%#x\n", I32(res + 1), I32(res + 1) + I32(res + 5) - 1, I32(res + 5)); } config->ic_mem[config->ic_nmem].ir_start = I32(res + 1); config->ic_mem[config->ic_nmem].ir_end = I32(res + 1) + I32(res + 5) - 1; config->ic_mem[config->ic_nmem].ir_size = I32(res + 5); config->ic_mem[config->ic_nmem].ir_align = 1; config->ic_nmem++; break; default: /* Skip this resource */ pnp_printf(id, "unexpected large tag %d\n", PNP_SRES_NUM(tag)); break; } } return (0); }
static int ahc_isa_probe(device_t dev) { struct aic7770_identity *entry; bus_space_tag_t tag; bus_space_handle_t bsh; struct resource *regs; struct resource *irq; uint32_t iobase; u_int intdef; u_int hcntrl; int irq_num; int error; int zero; error = ENXIO; zero = 0; regs = NULL; irq = NULL; /* Skip probes for ISA PnP devices */ if (isa_get_logicalid(dev) != 0) return (error); regs = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &zero, RF_ACTIVE); if (regs == NULL) { device_printf(dev, "No resources allocated.\n"); return (ENOMEM); } iobase = rman_get_start(regs); tag = rman_get_bustag(regs); bsh = rman_get_bushandle(regs); entry = ahc_isa_find_device(tag, bsh); if (entry == NULL) goto cleanup; /* Pause the card preseving the IRQ type */ hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS; bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE); while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0) ; /* Make sure we have a valid interrupt vector */ intdef = bus_space_read_1(tag, bsh, INTDEF); irq_num = intdef & VECTOR; switch (irq_num) { case 9: case 10: case 11: case 12: case 14: case 15: break; default: device_printf(dev, "@0x%x: illegal irq setting %d\n", iobase, irq_num); goto cleanup; } if (bus_set_resource(dev, SYS_RES_IRQ, zero, irq_num, 1) != 0) goto cleanup; /* * The 284X only supports edge triggered interrupts, * so do not claim RF_SHAREABLE. */ irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &zero, 0 /*!(RF_ACTIVE|RF_SHAREABLE)*/); if (irq != NULL) { error = 0; device_set_desc(dev, entry->name); } else device_printf(dev, "@0x%x: irq %d allocation failed\n", iobase, irq_num); cleanup: if (regs != NULL) { bus_release_resource(dev, SYS_RES_IOPORT, zero, regs); regs = NULL; } if (irq != NULL) { bus_release_resource(dev, SYS_RES_IRQ, zero, irq); irq = NULL; } return (error); }
static int rp_probe(device_t dev) { int unit; CONTROLLER_t *controller; int num_aiops; CONTROLLER_t *ctlp; int retval; /* * We have no PnP RocketPort cards. * (At least according to LINT) */ if (isa_get_logicalid(dev) != 0) return (ENXIO); /* We need IO port resource to configure an ISA device. */ if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0) return (ENXIO); unit = device_get_unit(dev); if (unit >= 4) { device_printf(dev, "rpprobe: unit number %d invalid.\n", unit); return (ENXIO); } device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit); ctlp = device_get_softc(dev); bzero(ctlp, sizeof(*ctlp)); ctlp->dev = dev; ctlp->aiop2rid = rp_isa_aiop2rid; ctlp->aiop2off = rp_isa_aiop2off; ctlp->ctlmask = rp_isa_ctlmask; /* The IO ports of AIOPs for an ISA controller are discrete. */ ctlp->io_num = 1; ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); if (ctlp->io_rid == NULL || ctlp->io == NULL) { device_printf(dev, "rp_attach: Out of memory.\n"); retval = ENOMEM; goto nogo; } ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT | M_ZERO); if (ctlp->bus_ctlp == NULL) { device_printf(dev, "rp_attach: Out of memory.\n"); retval = ENOMEM; goto nogo; } ctlp->io_rid[0] = 0; if (rp_controller != NULL) { controller = rp_controller; ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x40, RF_ACTIVE); } else { controller = rp_controller = ctlp; ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x44, RF_ACTIVE); } if (ctlp->io[0] == NULL) { device_printf(dev, "rp_attach: Resource not available.\n"); retval = ENXIO; goto nogo; } num_aiops = sInitController(ctlp, controller, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0); if (num_aiops <= 0) { device_printf(dev, "board%d init failed.\n", unit); retval = ENXIO; goto nogo; } if (rp_controller == NULL) rp_controller = controller; rp_nisadevs++; device_set_desc(dev, "RocketPort ISA"); return (0); nogo: rp_isareleaseresource(ctlp); return (retval); }
/* Probe routine. See if the card is there and at the right place. */ static int el_probe(device_t dev) { struct el_softc *sc; u_short base; /* Just for convenience */ u_char station_addr[ETHER_ADDR_LEN]; int i, rid; /* Grab some info for our structure */ sc = device_get_softc(dev); if (isa_get_logicalid(dev)) /* skip PnP probes */ return (ENXIO); if ((base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0) return (ENXIO); /* First check the base */ if((base < 0x280) || (base > 0x3f0)) { device_printf(dev, "ioaddr must be between 0x280 and 0x3f0\n"); return(ENXIO); } /* Temporarily map the resources. */ rid = 0; sc->el_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, EL_IOSIZ, RF_ACTIVE); if (sc->el_res == NULL) return(ENXIO); sc->el_btag = rman_get_bustag(sc->el_res); sc->el_bhandle = rman_get_bushandle(sc->el_res); mtx_init(&sc->el_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); EL_LOCK(sc); /* 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",base)); /* Reset the board */ dprintf(("Resetting board...\n")); CSR_WRITE_1(sc,EL_AC,EL_AC_RESET); DELAY(5); CSR_WRITE_1(sc,EL_AC,0); dprintf(("Reading station address...\n")); /* Now read the address */ for(i=0;i<ETHER_ADDR_LEN;i++) { CSR_WRITE_1(sc,EL_GPBL,i); station_addr[i] = CSR_READ_1(sc,EL_EAW); } /* Now release resources */ bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->el_res); EL_UNLOCK(sc); mtx_destroy(&sc->el_mtx); dprintf(("Address is %6D\n",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")); return(ENXIO); } else { dprintf(("Vendor code ok.\n")); /* Copy the station address into the arpcom structure */ bcopy(station_addr,sc->arpcom.ac_enaddr,ETHER_ADDR_LEN); } device_set_desc(dev, "3Com 3c501 Ethernet"); return(0); }