Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/isa/isahint.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 1999 Doug Rabson
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/param.h>
30
#include <sys/systm.h>
31
#include <sys/kernel.h>
32
#include <sys/bus.h>
33
#include <sys/module.h>
34
#include <isa/isavar.h>
35
#include <isa/isa_common.h>
36
#include <machine/resource.h>
37
38
void
39
isa_hinted_child(device_t parent, const char *name, int unit)
40
{
41
device_t child;
42
int sensitive, start, count;
43
int order;
44
45
/* device-specific flag overrides any wildcard */
46
sensitive = 0;
47
if (resource_int_value(name, unit, "sensitive", &sensitive) != 0)
48
resource_int_value(name, DEVICE_UNIT_ANY, "sensitive",
49
&sensitive);
50
51
if (sensitive)
52
order = ISA_ORDER_SENSITIVE;
53
else
54
order = ISA_ORDER_SPECULATIVE;
55
56
child = BUS_ADD_CHILD(parent, order, name, unit);
57
if (child == 0)
58
return;
59
60
start = 0;
61
count = 0;
62
resource_int_value(name, unit, "port", &start);
63
resource_int_value(name, unit, "portsize", &count);
64
if (start > 0 || count > 0)
65
bus_set_resource(child, SYS_RES_IOPORT, 0, start, count);
66
67
start = 0;
68
count = 0;
69
resource_int_value(name, unit, "maddr", &start);
70
resource_int_value(name, unit, "msize", &count);
71
if (start > 0 || count > 0)
72
bus_set_resource(child, SYS_RES_MEMORY, 0, start, count);
73
74
if (resource_int_value(name, unit, "irq", &start) == 0 && start > 0)
75
bus_set_resource(child, SYS_RES_IRQ, 0, start, 1);
76
77
if (resource_int_value(name, unit, "drq", &start) == 0 && start >= 0)
78
bus_set_resource(child, SYS_RES_DRQ, 0, start, 1);
79
80
if (resource_disabled(name, unit))
81
device_disable(child);
82
83
isa_set_configattr(child, (isa_get_configattr(child)|ISACFGATTR_HINTS));
84
}
85
86
static int
87
isa_match_resource_hint(device_t dev, int type, long value)
88
{
89
struct isa_device* idev = DEVTOISA(dev);
90
struct resource_list *rl = &idev->id_resources;
91
struct resource_list_entry *rle;
92
93
STAILQ_FOREACH(rle, rl, link) {
94
if (rle->type != type)
95
continue;
96
if (rle->start <= value && rle->end >= value)
97
return (1);
98
}
99
return (0);
100
}
101
102
void
103
isa_hint_device_unit(device_t bus, device_t child, const char *name, int *unitp)
104
{
105
const char *s;
106
long value;
107
int line, matches, unit;
108
109
line = 0;
110
for (;;) {
111
if (resource_find_dev(&line, name, &unit, "at", NULL) != 0)
112
break;
113
114
/* Must have an "at" for isa. */
115
resource_string_value(name, unit, "at", &s);
116
if (!(strcmp(s, device_get_nameunit(bus)) == 0 ||
117
strcmp(s, device_get_name(bus)) == 0))
118
continue;
119
120
/*
121
* Check for matching resources. We must have at
122
* least one match. Since I/O and memory resources
123
* cannot be shared, if we get a match on either of
124
* those, ignore any mismatches in IRQs or DRQs.
125
*
126
* XXX: We may want to revisit this to be more lenient
127
* and wire as long as it gets one match.
128
*/
129
matches = 0;
130
if (resource_long_value(name, unit, "port", &value) == 0) {
131
/*
132
* Floppy drive controllers are notorious for
133
* having a wide variety of resources not all
134
* of which include the first port that is
135
* specified by the hint (typically 0x3f0)
136
* (see the comment above
137
* fdc_isa_alloc_resources() in fdc_isa.c).
138
* However, they do all seem to include port +
139
* 2 (e.g. 0x3f2) so for a floppy device, look
140
* for 'value + 2' in the port resources
141
* instead of the hint value.
142
*/
143
if (strcmp(name, "fdc") == 0)
144
value += 2;
145
if (isa_match_resource_hint(child, SYS_RES_IOPORT,
146
value))
147
matches++;
148
else
149
continue;
150
}
151
if (resource_long_value(name, unit, "maddr", &value) == 0) {
152
if (isa_match_resource_hint(child, SYS_RES_MEMORY,
153
value))
154
matches++;
155
else
156
continue;
157
}
158
if (matches > 0)
159
goto matched;
160
if (resource_long_value(name, unit, "irq", &value) == 0) {
161
if (isa_match_resource_hint(child, SYS_RES_IRQ, value))
162
matches++;
163
else
164
continue;
165
}
166
if (resource_long_value(name, unit, "drq", &value) == 0) {
167
if (isa_match_resource_hint(child, SYS_RES_DRQ, value))
168
matches++;
169
else
170
continue;
171
}
172
173
matched:
174
if (matches > 0) {
175
/* We have a winner! */
176
*unitp = unit;
177
break;
178
}
179
}
180
}
181
182