static void aha_isa_identify(driver_t *driver, device_t parent) { int i; bus_addr_t ioport; struct aha_softc aha; int rid; struct resource *res; device_t child; /* Attempt to find an adapter */ for (i = 0; i < sizeof(aha_board_ports) / sizeof(aha_board_ports[0]); i++) { bzero(&aha, sizeof(aha)); ioport = aha_board_ports[i]; /* * XXX Check to see if we have a hard-wired aha device at * XXX this port, if so, skip. This should also cover the * XXX case where we are run multiple times due to, eg, * XXX kldload/kldunload. */ rid = 0; res = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid, ioport, ioport, AHA_NREGS, RF_ACTIVE); if (res == NULL) continue; aha_alloc(&aha, -1, rman_get_bustag(res), rman_get_bushandle(res)); /* See if there is really a card present */ if (aha_probe(&aha) || aha_fetch_adapter_info(&aha)) goto not_this_one; child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "aha", -1); bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, AHA_NREGS); /* * Could query the board and set IRQ/DRQ, but probe does * that. */ not_this_one:; bus_release_resource(parent, SYS_RES_IOPORT, rid, res); aha_free(&aha); } }
/* * Check if the device can be found at the port given */ static int aha_isa_probe(device_t dev) { /* * find unit and check we have that many defined */ struct aha_softc *aha = device_get_softc(dev); int error; u_long port_start; int port_rid; int drq; int irq; config_data_t config_data; aha->dev = dev; /* Check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, aha_ids) == ENXIO) return (ENXIO); port_rid = 0; aha->port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &port_rid, AHA_NREGS, RF_ACTIVE); if (aha->port == NULL) return (ENXIO); port_start = rman_get_start(aha->port); aha_alloc(aha); /* See if there is really a card present */ if (aha_probe(aha) || aha_fetch_adapter_info(aha)) { aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); return (ENXIO); } /* * Determine our IRQ, and DMA settings and * export them to the configuration system. */ error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, (uint8_t*)&config_data, sizeof(config_data), DEFAULT_CMD_TIMEOUT); if (error != 0) { device_printf(dev, "Could not determine IRQ or DMA " "settings for adapter at %#jx. Failing probe\n", (uintmax_t)port_start); aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); return (ENXIO); } bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); aha->port = NULL; switch (config_data.dma_chan) { case DMA_CHAN_5: drq = 5; break; case DMA_CHAN_6: drq = 6; break; case DMA_CHAN_7: drq = 7; break; default: device_printf(dev, "Invalid DMA setting for adapter at %#jx.", (uintmax_t)port_start); return (ENXIO); } error = bus_set_resource(dev, SYS_RES_DRQ, 0, drq, 1); if (error) return error; irq = ffs(config_data.irq) + 8; error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); return (error); }
/* * 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 aha_isa_probe(device_t dev) { /* * find unit and check we have that many defined */ struct aha_softc **sc = device_get_softc(dev); struct aha_softc *aha; int port_index; int max_port_index; int error; u_long port_start, port_count; struct resource *port_res; int port_rid; int drq; int irq; aha = NULL; /* Check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, aha_ids) == ENXIO) return (ENXIO); error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port_start, &port_count); if (error != 0) port_start = 0; /* * Bound our board search if the user has * specified an exact port. */ aha_find_probe_range(port_start, &port_index, &max_port_index); if (port_index < 0) return ENXIO; /* Attempt to find an adapter */ for (;port_index <= max_port_index; port_index++) { config_data_t config_data; u_int ioport; int error; ioport = aha_iop_from_bio(port_index); error = bus_set_resource(dev, SYS_RES_IOPORT, 0, ioport, AHA_NREGS); if (error) return error; port_rid = 0; port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, 0, ~0, AHA_NREGS, RF_ACTIVE); if (!port_res) continue; /* Allocate a softc for use during probing */ aha = aha_alloc(device_get_unit(dev), rman_get_bustag(port_res), rman_get_bushandle(port_res)); if (aha == NULL) { bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); break; } /* See if there is really a card present */ if (aha_probe(aha) || aha_fetch_adapter_info(aha)) { aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); continue; } /* * Determine our IRQ, and DMA settings and * export them to the configuration system. */ error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, (u_int8_t*)&config_data, sizeof(config_data), DEFAULT_CMD_TIMEOUT); if (error != 0) { printf("aha_isa_probe: Could not determine IRQ or DMA " "settings for adapter at 0x%x. Failing probe\n", ioport); aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); continue; } bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); switch (config_data.dma_chan) { case DMA_CHAN_5: drq = 5; break; case DMA_CHAN_6: drq = 6; break; case DMA_CHAN_7: drq = 7; break; default: printf("aha_isa_probe: Invalid DMA setting " "detected for adapter at 0x%x. " "Failing probe\n", ioport); return (ENXIO); } error = bus_set_resource(dev, SYS_RES_DRQ, 0, drq, 1); if (error) return error; irq = ffs(config_data.irq) + 8; error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); if (error) return error; *sc = aha; aha_unit++; return (0); } return (ENXIO); }