From 71edba1fe8111c3b2712adad69006a78ad614595 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 10 Nov 2003 02:47:11 +0000 Subject: [PATCH] Move 'guessing' code from the probe into the identify routine where it more properly belongs. --- sys/dev/aha/aha.c | 66 -------------- sys/dev/aha/aha_isa.c | 200 ++++++++++++++++++++++-------------------- 2 files changed, 106 insertions(+), 160 deletions(-) diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c index 7b2b2469a74..f1040649795 100644 --- a/sys/dev/aha/aha.c +++ b/sys/dev/aha/aha.c @@ -166,37 +166,6 @@ static void ahapoll(struct cam_sim *sim); /* Our timeout handler */ static timeout_t ahatimeout; -u_long aha_unit = 0; - -/* - * Do our own re-probe protection until a configuration - * manager can do it for us. This ensures that we don't - * reprobe a card already found by the EISA or PCI probes. - */ -static struct aha_isa_port aha_isa_ports[] = -{ - { 0x130, 4 }, - { 0x134, 5 }, - { 0x230, 2 }, - { 0x234, 3 }, - { 0x330, 0 }, - { 0x334, 1 } -}; - -/* - * I/O ports listed in the order enumerated by the - * card for certain op codes. - */ -static uint16_t aha_board_ports[] = -{ - 0x330, - 0x334, - 0x230, - 0x234, - 0x130, - 0x134 -}; - /* Exported functions */ void aha_alloc(struct aha_softc *aha, int unit, bus_space_tag_t tag, @@ -664,41 +633,6 @@ aha_name(struct aha_softc *aha) return (name); } -void -aha_find_probe_range(int ioport, int *port_index, int *max_port_index) -{ - if (ioport > 0) { - int i; - - for (i = 0;i < AHA_NUM_ISAPORTS; i++) - if (ioport <= aha_isa_ports[i].addr) - break; - if (i >= AHA_NUM_ISAPORTS || ioport != aha_isa_ports[i].addr) { - printf("\n" -"aha_isa_probe: Invalid baseport of 0x%x specified.\n" -"aha_isa_probe: Nearest valid baseport is 0x%x.\n" -"aha_isa_probe: Failing probe.\n", - ioport, - i < AHA_NUM_ISAPORTS ? aha_isa_ports[i].addr - : aha_isa_ports[AHA_NUM_ISAPORTS - 1].addr); - *port_index = *max_port_index = -1; - return; - } - *port_index = *max_port_index = aha_isa_ports[i].bio; - } else { - *port_index = 0; - *max_port_index = AHA_NUM_ISAPORTS - 1; - } -} - -int -aha_iop_from_bio(isa_compat_io_t bio_index) -{ - if (bio_index >= 0 && bio_index < AHA_NUM_ISAPORTS) - return (aha_board_ports[bio_index]); - return (-1); -} - static void ahaallocccbs(struct aha_softc *aha) { diff --git a/sys/dev/aha/aha_isa.c b/sys/dev/aha/aha_isa.c index 7167e12eadf..ad46f6d1cc5 100644 --- a/sys/dev/aha/aha_isa.c +++ b/sys/dev/aha/aha_isa.c @@ -77,18 +77,28 @@ __FBSDID("$FreeBSD$"); static struct isa_pnp_id aha_ids[] = { {ADP0100_PNP, "Adaptec 1540/1542 ISA SCSI"}, /* ADP0100 */ - {AHA1540_PNP, "Adaptec 1540/aha-1640/aha-1535"},/* ADP1542 */ + {AHA1540_PNP, "Adaptec 1540/aha-1640/aha-1535"},/* ADP1540 */ {AHA1542_PNP, "Adaptec 1542/aha-1535"}, /* ADP1542 */ {AHA1542_PNPCOMPAT, "Adaptec 1542 compatible"}, /* PNP00A0 */ {ICU0091_PNP, "Adaptec AHA-1540/1542 SCSI"}, /* ICU0091 */ {0} }; +/* + * I/O ports listed in the order enumerated by the card for certain op codes. + */ +static bus_addr_t aha_board_ports[] = +{ + 0x330, + 0x334, + 0x230, + 0x234, + 0x130, + 0x134 +}; + /* * 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) @@ -97,113 +107,77 @@ aha_isa_probe(device_t dev) * find unit and check we have that many defined */ struct aha_softc *aha = device_get_softc(dev); - int port_index; - int max_port_index; int error; - u_long port_start, port_count; + u_long port_start; struct resource *port_res; int port_rid; int drq; int irq; + config_data_t config_data; /* 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; + port_rid = 0; + port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, + 0, ~0, AHA_NREGS, RF_ACTIVE); - /* 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_alloc(aha, device_get_unit(dev), rman_get_bustag(port_res), - rman_get_bushandle(port_res)); - - /* 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; - } + if (port_res == NULL) + 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) { - 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; - } + port_start = rman_get_start(port_res); + aha_alloc(aha, device_get_unit(dev), rman_get_bustag(port_res), + rman_get_bushandle(port_res)); + /* 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); + return (ENXIO); + } - 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; - - return (0); + /* + * 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, + port_res); + return (ENXIO); + } + + 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: + 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; - return (ENXIO); + irq = ffs(config_data.irq) + 8; + error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); + return (error); } /* @@ -339,6 +313,44 @@ aha_isa_detach(device_t dev) 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); + } } static device_method_t aha_isa_methods[] = { -- 2.45.2