summaryrefslogtreecommitdiffstats
path: root/sys/dev/aha
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2003-11-10 02:47:11 +0000
committerimp <imp@FreeBSD.org>2003-11-10 02:47:11 +0000
commit0139b2158b48ea2fa48e215b6266b501b62da914 (patch)
treedf99a8893d1f43ced00d0aeb0e281f73ffb94f02 /sys/dev/aha
parentfa4ea5d2f2c4f2808206b802fa09b5ee6ffb7631 (diff)
downloadFreeBSD-src-0139b2158b48ea2fa48e215b6266b501b62da914.zip
FreeBSD-src-0139b2158b48ea2fa48e215b6266b501b62da914.tar.gz
Move 'guessing' code from the probe into the identify routine where it more
properly belongs.
Diffstat (limited to 'sys/dev/aha')
-rw-r--r--sys/dev/aha/aha.c66
-rw-r--r--sys/dev/aha/aha_isa.c200
2 files changed, 106 insertions, 160 deletions
diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c
index 7b2b246..f104064 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 7167e12..ad46f6d 100644
--- a/sys/dev/aha/aha_isa.c
+++ b/sys/dev/aha/aha_isa.c
@@ -77,7 +77,7 @@ __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 */
@@ -85,10 +85,20 @@ static struct isa_pnp_id aha_ids[] = {
};
/*
+ * 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[] = {
OpenPOWER on IntegriCloud