FreeBSD/Linux Kernel Cross Reference
sys/chips/busses.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993-1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: busses.c,v $
29 * Revision 2.15 93/05/17 10:26:48 rvb
30 * Type casts, etc to quiet gcc 2.3.3 warnings
31 *
32 * Revision 2.14 93/05/10 22:25:04 rvb
33 * No more caddr_t.
34 * [93/04/09 af]
35 *
36 * Revision 2.13 93/01/14 17:15:09 danner
37 * Converted to boolean return values, prototyped.
38 * [93/01/14 danner]
39 *
40 * Revision 2.12 92/08/03 17:21:10 jfriedl
41 * removed silly prototypes
42 * [92/08/02 jfriedl]
43 *
44 * Revision 2.11 92/05/21 17:05:33 jfriedl
45 * Cleanup to quiet gcc warnings.
46 * [92/05/16 jfriedl]
47 *
48 * Revision 2.10 91/11/12 11:09:14 rvb
49 * Upgrade phys_address and address check
50 * [91/10/30 15:36:00 rvb]
51 *
52 * Revision 2.9 91/10/09 15:55:08 af
53 * Changed to never overwrite the *->address and *->phys_address
54 * fields in either master or device descriptors. This lets the
55 * probe routine use them as it pleases, and modify them if
56 * necessary.
57 * Also, if the device does have a phys address insist that we match.
58 * [91/09/03 af]
59 *
60 * Revision 2.8 91/08/24 11:51:24 af
61 * Wildcarding on adaptor no. works now.
62 *
63 * Revision 2.7 91/06/19 11:46:21 rvb
64 * File moved here from mips/PMAX since it tries to be generic;
65 * it is used on the PMAX and the Vax3100.
66 * [91/06/04 rvb]
67 *
68 * Added check in configure_bus_master for device's controller# to match
69 * the controller's unit#, if not wildcarded.
70 * Also, made device->ctlr correct *before* calling the slave function.
71 * [91/06/02 af]
72 *
73 * Revision 2.6 91/05/14 17:32:20 mrt
74 * Correcting copyright
75 *
76 * Revision 2.5 91/02/05 17:47:04 mrt
77 * Added author notices
78 * [91/02/04 11:21:01 mrt]
79 *
80 * Changed to use new Mach copyright
81 * [91/02/02 12:24:34 mrt]
82 *
83 * Revision 2.4 90/12/05 23:36:34 af
84 *
85 *
86 * Revision 2.3 90/12/05 20:49:29 af
87 * Fixed wrong wildcarding on controller rather than adaptor.
88 * Removed unused "metering" disk ID. Now the flag field is used for
89 * more meaningful purposes.
90 * [90/12/03 23:00:38 af]
91 *
92 * Revision 2.2 90/08/07 22:29:04 rpd
93 * Let the bus name be a parameter to the config functions.
94 * [90/08/07 15:26:10 af]
95 *
96 * Revision 2.1.1.1 90/05/20 14:10:14 af
97 * Created, putting in just the minimum functionality
98 * needed for the 3max TURBOchannel. Should extend to
99 * cope with VME properly.
100 * [90/04/18 af]
101 *
102 */
103
104 /*
105 * File: busses.c
106 * Author: Alessandro Forin, Carnegie Mellon University
107 * Date: 4/90
108 *
109 * Generic autoconfiguration functions,
110 * usable to probe and attach devices
111 * on any bus that suits the generic bus
112 * structure, such as VME, TURBOChannel,
113 * and all the VAX busses.
114 *
115 */
116
117 #include <mach/boolean.h>
118 #include <mach/std_types.h>
119 #include <chips/busses.h>
120
121
122
123
124 /*
125 * configure_bus_master
126 *
127 * Given the name of a bus_ctlr, look it up in the
128 * init table. If found, probe it. If there can be
129 * slaves attached, walk the device's init table
130 * for those that might be attached to this controller.
131 * Call the 'slave' function on each one to see if
132 * ok, then the 'attach' one.
133 *
134 * Returns 0 if the controller is not there.
135 *
136 */
137 boolean_t configure_bus_master(
138 char *name,
139 vm_offset_t virt,
140 vm_offset_t phys,
141 int adpt_no,
142 char *bus_name)
143 {
144 register struct bus_device *device;
145 register struct bus_ctlr *master;
146 register struct bus_driver *driver;
147
148 int found = 0;
149
150 /*
151 * Match the name in the table, then pick the entry that has the
152 * right adaptor number, or one that has it wildcarded. Entries
153 * already allocated are marked alive, skip them.
154 */
155 for (master = bus_master_init; master->driver; master++) {
156 if (master->alive)
157 continue;
158 if (((master->adaptor == adpt_no) || (master->adaptor == '?')) &&
159 (strcmp(master->name, name) == 0)) {
160 found = 1;
161 break;
162 }
163 }
164
165 if (!found)
166 return FALSE;
167
168 /*
169 * Found a match, probe it
170 */
171 driver = master->driver;
172 if ((*driver->probe) (virt, master) == 0)
173 return FALSE;
174
175 master->alive = 1;
176 master->adaptor = adpt_no;
177
178 /*
179 * Remember which controller this device is attached to
180 */
181 driver->minfo[master->unit] = master;
182
183 printf("%s%d: at %s%d\n", master->name, master->unit, bus_name, adpt_no);
184
185 /*
186 * Now walk all devices to check those that might be attached to this
187 * controller. We match the unallocated ones that have the right
188 * controller number, or that have a widcarded controller number.
189 */
190 for (device = bus_device_init; device->driver; device++) {
191 int ctlr;
192 if (device->alive || device->driver != driver ||
193 (device->adaptor != '?' && device->adaptor != adpt_no))
194 continue;
195 ctlr = device->ctlr;
196 if (ctlr == '?') device->ctlr = master->unit;
197 /*
198 * A matching entry. See if the slave-probing routine is
199 * happy.
200 */
201 if ((device->ctlr != master->unit) ||
202 ((*driver->slave) (device, virt) == 0)) {
203 device->ctlr = ctlr;
204 continue;
205 }
206
207 device->alive = 1;
208 device->adaptor = adpt_no;
209 device->ctlr = master->unit;
210
211 /*
212 * Save a backpointer to the controller
213 */
214 device->mi = master;
215
216 /*
217 * ..and to the device
218 */
219 driver->dinfo[device->unit] = device;
220
221 if (device->slave >= 0)
222 printf(" %s%d: at %s%d slave %d",
223 device->name, device->unit,
224 driver->mname, master->unit, device->slave);
225 else
226 printf(" %s%d: at %s%d",
227 device->name, device->unit,
228 driver->mname, master->unit);
229
230 /*
231 * Now attach this slave
232 */
233 (*driver->attach) (device);
234 printf("\n");
235 }
236 return TRUE;
237 }
238
239 /*
240 * configure_bus_device
241 *
242 * Given the name of a bus_device, look it up in the
243 * init table. If found, probe it. If it is present,
244 * call the driver's 'attach' function.
245 *
246 * Returns 0 if the device is not there.
247 *
248 */
249 boolean_t configure_bus_device(
250 char *name,
251 vm_offset_t virt,
252 vm_offset_t phys,
253 int adpt_no,
254 char *bus_name)
255 {
256 register struct bus_device *device;
257 register struct bus_driver *driver;
258
259 int found = 0;
260
261 /*
262 * Walk all devices to find one with the right name
263 * and adaptor number (or wildcard). The entry should
264 * be unallocated, and also the slave number should
265 * be wildcarded.
266 */
267 for (device = bus_device_init; device->driver; device++) {
268 if (device->alive)
269 continue;
270 if (((device->adaptor == adpt_no) || (device->adaptor == '?')) &&
271 (device->slave == -1) &&
272 ((!device->phys_address) ||
273 ((device->phys_address == phys) && (device->address == virt))) &&
274 (strcmp(device->name, name) == 0)) {
275 found = 1;
276 break;
277 }
278 }
279
280 if (!found)
281 return FALSE;
282
283 /*
284 * Found an entry, probe the device
285 */
286 driver = device->driver;
287 if ((*driver->probe) (virt, (struct bus_ctlr *)device) == 0)
288 return FALSE;
289
290 device->alive = 1;
291 device->adaptor = adpt_no;
292
293 printf("%s%d: at %s%d", device->name, device->unit, bus_name, adpt_no);
294
295 /*
296 * Remember which driver this device is attached to
297 */
298 driver->dinfo[device->unit] = device;
299
300 /*
301 * Attach the device
302 */
303 (*driver->attach) (device);
304 printf("\n");
305
306 return TRUE;
307 }
308
Cache object: 81fa5df6b059f978c54d14ffb52cf64f
|