16c2e3ddeSDoug Rabson /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3fe267a55SPedro F. Giffuni *
46c2e3ddeSDoug Rabson * Copyright (c) 1999 Doug Rabson
56c2e3ddeSDoug Rabson * All rights reserved.
66c2e3ddeSDoug Rabson *
76c2e3ddeSDoug Rabson * Redistribution and use in source and binary forms, with or without
86c2e3ddeSDoug Rabson * modification, are permitted provided that the following conditions
96c2e3ddeSDoug Rabson * are met:
106c2e3ddeSDoug Rabson * 1. Redistributions of source code must retain the above copyright
116c2e3ddeSDoug Rabson * notice, this list of conditions and the following disclaimer.
126c2e3ddeSDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright
136c2e3ddeSDoug Rabson * notice, this list of conditions and the following disclaimer in the
146c2e3ddeSDoug Rabson * documentation and/or other materials provided with the distribution.
156c2e3ddeSDoug Rabson *
166c2e3ddeSDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
176c2e3ddeSDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
186c2e3ddeSDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
196c2e3ddeSDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
206c2e3ddeSDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
216c2e3ddeSDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
226c2e3ddeSDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
236c2e3ddeSDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
246c2e3ddeSDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
256c2e3ddeSDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
266c2e3ddeSDoug Rabson * SUCH DAMAGE.
276c2e3ddeSDoug Rabson */
286c2e3ddeSDoug Rabson
296c2e3ddeSDoug Rabson #include <sys/param.h>
306c2e3ddeSDoug Rabson #include <sys/systm.h>
316c2e3ddeSDoug Rabson #include <sys/kernel.h>
326c2e3ddeSDoug Rabson #include <sys/bus.h>
336c2e3ddeSDoug Rabson #include <sys/module.h>
346c2e3ddeSDoug Rabson #include <isa/isavar.h>
350d484d24SJohn Baldwin #include <isa/isa_common.h>
36a3be63b3SDoug Rabson #include <machine/resource.h>
376c2e3ddeSDoug Rabson
380d484d24SJohn Baldwin void
isa_hinted_child(device_t parent,const char * name,int unit)390d484d24SJohn Baldwin isa_hinted_child(device_t parent, const char *name, int unit)
406c2e3ddeSDoug Rabson {
416c2e3ddeSDoug Rabson device_t child;
42e5979322SNate Lawson int sensitive, start, count;
43bea6af4dSDoug Rabson int order;
446c2e3ddeSDoug Rabson
456c2e3ddeSDoug Rabson /* device-specific flag overrides any wildcard */
466c2e3ddeSDoug Rabson sensitive = 0;
476c2e3ddeSDoug Rabson if (resource_int_value(name, unit, "sensitive", &sensitive) != 0)
486c2e3ddeSDoug Rabson resource_int_value(name, -1, "sensitive", &sensitive);
496c2e3ddeSDoug Rabson
506c2e3ddeSDoug Rabson if (sensitive)
51bea6af4dSDoug Rabson order = ISA_ORDER_SENSITIVE;
526c2e3ddeSDoug Rabson else
53bea6af4dSDoug Rabson order = ISA_ORDER_SPECULATIVE;
54bea6af4dSDoug Rabson
55bea6af4dSDoug Rabson child = BUS_ADD_CHILD(parent, order, name, unit);
566c2e3ddeSDoug Rabson if (child == 0)
576c2e3ddeSDoug Rabson return;
586c2e3ddeSDoug Rabson
59a3be63b3SDoug Rabson start = 0;
60a3be63b3SDoug Rabson count = 0;
610197892dSYoshihiro Takahashi resource_int_value(name, unit, "port", &start);
620197892dSYoshihiro Takahashi resource_int_value(name, unit, "portsize", &count);
630197892dSYoshihiro Takahashi if (start > 0 || count > 0)
6425afb89bSDoug Rabson bus_set_resource(child, SYS_RES_IOPORT, 0, start, count);
656c2e3ddeSDoug Rabson
66a3be63b3SDoug Rabson start = 0;
67a3be63b3SDoug Rabson count = 0;
680197892dSYoshihiro Takahashi resource_int_value(name, unit, "maddr", &start);
690197892dSYoshihiro Takahashi resource_int_value(name, unit, "msize", &count);
700197892dSYoshihiro Takahashi if (start > 0 || count > 0)
7125afb89bSDoug Rabson bus_set_resource(child, SYS_RES_MEMORY, 0, start, count);
726c2e3ddeSDoug Rabson
73828cb040SKazutaka YOKOTA if (resource_int_value(name, unit, "irq", &start) == 0 && start > 0)
7425afb89bSDoug Rabson bus_set_resource(child, SYS_RES_IRQ, 0, start, 1);
756c2e3ddeSDoug Rabson
760e7e521cSAndrew Gallatin if (resource_int_value(name, unit, "drq", &start) == 0 && start >= 0)
7725afb89bSDoug Rabson bus_set_resource(child, SYS_RES_DRQ, 0, start, 1);
786c2e3ddeSDoug Rabson
798a9bc9c0SJohn Baldwin if (resource_disabled(name, unit))
806c2e3ddeSDoug Rabson device_disable(child);
812ca94fcaSMatthew N. Dodd
822ca94fcaSMatthew N. Dodd isa_set_configattr(child, (isa_get_configattr(child)|ISACFGATTR_HINTS));
836c2e3ddeSDoug Rabson }
846c2e3ddeSDoug Rabson
850d484d24SJohn Baldwin static int
isa_match_resource_hint(device_t dev,int type,long value)860d484d24SJohn Baldwin isa_match_resource_hint(device_t dev, int type, long value)
876c2e3ddeSDoug Rabson {
880d484d24SJohn Baldwin struct isa_device* idev = DEVTOISA(dev);
890d484d24SJohn Baldwin struct resource_list *rl = &idev->id_resources;
900d484d24SJohn Baldwin struct resource_list_entry *rle;
916c2e3ddeSDoug Rabson
920d484d24SJohn Baldwin STAILQ_FOREACH(rle, rl, link) {
930d484d24SJohn Baldwin if (rle->type != type)
940d484d24SJohn Baldwin continue;
950d484d24SJohn Baldwin if (rle->start <= value && rle->end >= value)
960d484d24SJohn Baldwin return (1);
970d484d24SJohn Baldwin }
980d484d24SJohn Baldwin return (0);
996c2e3ddeSDoug Rabson }
1006c2e3ddeSDoug Rabson
1010d484d24SJohn Baldwin void
isa_hint_device_unit(device_t bus,device_t child,const char * name,int * unitp)1020d484d24SJohn Baldwin isa_hint_device_unit(device_t bus, device_t child, const char *name, int *unitp)
1030d484d24SJohn Baldwin {
1040d484d24SJohn Baldwin const char *s;
1050d484d24SJohn Baldwin long value;
1060d484d24SJohn Baldwin int line, matches, unit;
1076c2e3ddeSDoug Rabson
1080d484d24SJohn Baldwin line = 0;
1090d484d24SJohn Baldwin for (;;) {
1100d484d24SJohn Baldwin if (resource_find_dev(&line, name, &unit, "at", NULL) != 0)
1110d484d24SJohn Baldwin break;
1126c2e3ddeSDoug Rabson
1130d484d24SJohn Baldwin /* Must have an "at" for isa. */
1140d484d24SJohn Baldwin resource_string_value(name, unit, "at", &s);
1150d484d24SJohn Baldwin if (!(strcmp(s, device_get_nameunit(bus)) == 0 ||
1160d484d24SJohn Baldwin strcmp(s, device_get_name(bus)) == 0))
1170d484d24SJohn Baldwin continue;
1186c2e3ddeSDoug Rabson
1190d484d24SJohn Baldwin /*
1202fcd493cSJohn Baldwin * Check for matching resources. We must have at
1212fcd493cSJohn Baldwin * least one match. Since I/O and memory resources
1222fcd493cSJohn Baldwin * cannot be shared, if we get a match on either of
1232fcd493cSJohn Baldwin * those, ignore any mismatches in IRQs or DRQs.
1240d484d24SJohn Baldwin *
1252fcd493cSJohn Baldwin * XXX: We may want to revisit this to be more lenient
1262fcd493cSJohn Baldwin * and wire as long as it gets one match.
1270d484d24SJohn Baldwin */
1280d484d24SJohn Baldwin matches = 0;
1290d484d24SJohn Baldwin if (resource_long_value(name, unit, "port", &value) == 0) {
1302fcd493cSJohn Baldwin /*
1312fcd493cSJohn Baldwin * Floppy drive controllers are notorious for
1322fcd493cSJohn Baldwin * having a wide variety of resources not all
1332fcd493cSJohn Baldwin * of which include the first port that is
1342fcd493cSJohn Baldwin * specified by the hint (typically 0x3f0)
1352fcd493cSJohn Baldwin * (see the comment above
1362fcd493cSJohn Baldwin * fdc_isa_alloc_resources() in fdc_isa.c).
1372fcd493cSJohn Baldwin * However, they do all seem to include port +
1382fcd493cSJohn Baldwin * 2 (e.g. 0x3f2) so for a floppy device, look
1392fcd493cSJohn Baldwin * for 'value + 2' in the port resources
1402fcd493cSJohn Baldwin * instead of the hint value.
1412fcd493cSJohn Baldwin */
1422fcd493cSJohn Baldwin if (strcmp(name, "fdc") == 0)
1432fcd493cSJohn Baldwin value += 2;
1440d484d24SJohn Baldwin if (isa_match_resource_hint(child, SYS_RES_IOPORT,
1450d484d24SJohn Baldwin value))
1460d484d24SJohn Baldwin matches++;
1470d484d24SJohn Baldwin else
1480d484d24SJohn Baldwin continue;
1490d484d24SJohn Baldwin }
1500d484d24SJohn Baldwin if (resource_long_value(name, unit, "maddr", &value) == 0) {
1510d484d24SJohn Baldwin if (isa_match_resource_hint(child, SYS_RES_MEMORY,
1520d484d24SJohn Baldwin value))
1530d484d24SJohn Baldwin matches++;
1540d484d24SJohn Baldwin else
1550d484d24SJohn Baldwin continue;
1560d484d24SJohn Baldwin }
1572fcd493cSJohn Baldwin if (matches > 0)
1582fcd493cSJohn Baldwin goto matched;
1590d484d24SJohn Baldwin if (resource_long_value(name, unit, "irq", &value) == 0) {
1600d484d24SJohn Baldwin if (isa_match_resource_hint(child, SYS_RES_IRQ, value))
1610d484d24SJohn Baldwin matches++;
1620d484d24SJohn Baldwin else
1630d484d24SJohn Baldwin continue;
1640d484d24SJohn Baldwin }
1650d484d24SJohn Baldwin if (resource_long_value(name, unit, "drq", &value) == 0) {
1660d484d24SJohn Baldwin if (isa_match_resource_hint(child, SYS_RES_DRQ, value))
1670d484d24SJohn Baldwin matches++;
1680d484d24SJohn Baldwin else
1690d484d24SJohn Baldwin continue;
1700d484d24SJohn Baldwin }
1716c2e3ddeSDoug Rabson
1722fcd493cSJohn Baldwin matched:
1730d484d24SJohn Baldwin if (matches > 0) {
1740d484d24SJohn Baldwin /* We have a winner! */
1750d484d24SJohn Baldwin *unitp = unit;
1760d484d24SJohn Baldwin break;
1770d484d24SJohn Baldwin }
1780d484d24SJohn Baldwin }
1790d484d24SJohn Baldwin }
180