isapnpdebug.c revision 1.8 1 /* $NetBSD: isapnpdebug.c,v 1.8 2005/02/27 00:27:21 perry Exp $ */
2
3 /*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: isapnpdebug.c,v 1.8 2005/02/27 00:27:21 perry Exp $");
41
42 #ifdef DEBUG_ISAPNP
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/device.h>
47
48 #include <machine/bus.h>
49
50 #include <dev/isa/isavar.h>
51
52 #include <dev/isapnp/isapnpreg.h>
53 #include <dev/isapnp/isapnpvar.h>
54
55 /* isapnp_print_mem():
56 * Print a memory tag
57 */
58 void
59 isapnp_print_mem(str, mem)
60 const char *str;
61 const struct isapnp_region *mem;
62 {
63 printf("%sMemory: %s,%sshadowable,decode-%s,%scacheable,%s", str,
64 (mem->flags & ISAPNP_MEMATTR_ROM) ? "ROM," : "RAM,",
65 (mem->flags & ISAPNP_MEMATTR_SHADOWABLE) ? "" : "non-",
66 (mem->flags & ISAPNP_MEMATTR_HIGH_ADDR) ?
67 "high-addr," : "range-len,",
68 (mem->flags & ISAPNP_MEMATTR_CACHEABLE) ? "" : "non-",
69 (mem->flags & ISAPNP_MEMATTR_WRITABLE) ?
70 "writable," : "read-only,");
71
72 switch (mem->flags & ISAPNP_MEMWIDTH_MASK) {
73 case ISAPNP_MEMWIDTH_8:
74 printf("8-bit ");
75 break;
76 case ISAPNP_MEMWIDTH_16:
77 printf("16-bit ");
78 break;
79 case ISAPNP_MEMWIDTH_8_16:
80 printf("8/16-bit ");
81 break;
82 case ISAPNP_MEMWIDTH_32:
83 printf("32-bit ");
84 break;
85 }
86
87 printf("min 0x%x, max 0x%x, ", mem->minbase, mem->maxbase);
88 printf("align 0x%x, length 0x%x\n", mem->align, mem->length);
89 }
90
91
92 /* isapnp_print_io():
93 * Print an io tag
94 */
95 void
96 isapnp_print_io(str, io)
97 const char *str;
98 const struct isapnp_region *io;
99 {
100 printf("%d %sIO Ports: %d address bits, alignment %d ",
101 io->length, str, (io->flags & ISAPNP_IOFLAGS_16) ? 16 : 10,
102 io->align);
103
104 printf("min 0x%x, max 0x%x\n", io->minbase, io->maxbase);
105 }
106
107
108 /* isapnp_print_irq():
109 * Print an irq tag
110 */
111 void
112 isapnp_print_irq(str, irq)
113 const char *str;
114 const struct isapnp_pin *irq;
115 {
116 int i;
117
118 printf("%sIRQ's supported: ", str);
119 for (i = 0; i < 16; i++)
120 if (irq->bits & (1 << i))
121 printf("%d ", i);
122
123 if (irq->flags & ISAPNP_IRQTYPE_EDGE_PLUS)
124 printf("E+");
125 if (irq->flags & ISAPNP_IRQTYPE_EDGE_MINUS)
126 printf("E-");
127 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_PLUS)
128 printf("L+");
129 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_MINUS)
130 printf("L-");
131 printf("\n");
132 }
133
134 /* isapnp_print_drq():
135 * Print a drq tag
136 */
137 void
138 isapnp_print_drq(str, drq)
139 const char *str;
140 const struct isapnp_pin *drq;
141 {
142 int i;
143 u_char flags = drq->flags;
144
145 printf("%sDRQ's supported: ", str);
146 for (i = 0; i < 8; i++)
147 if (drq->bits & (1 << i))
148 printf("%d ", i);
149
150 printf("Width: ");
151 switch (flags & ISAPNP_DMAWIDTH_MASK) {
152 case ISAPNP_DMAWIDTH_8:
153 printf("8-bit ");
154 break;
155 case ISAPNP_DMAWIDTH_8_16:
156 printf("8/16-bit ");
157 break;
158 case ISAPNP_DMAWIDTH_16:
159 printf("16-bit ");
160 break;
161 case ISAPNP_DMAWIDTH_RESERVED:
162 printf("Reserved ");
163 break;
164 }
165
166 printf("Speed: ");
167 switch (flags & ISAPNP_DMASPEED_MASK) {
168 case ISAPNP_DMASPEED_COMPAT:
169 printf("compat ");
170 break;
171 case ISAPNP_DMASPEED_A:
172 printf("A ");
173 break;
174 case ISAPNP_DMASPEED_B:
175 printf("B ");
176 break;
177 case ISAPNP_DMASPEED_F:
178 printf("F ");
179 break;
180 }
181
182 if (flags & ISAPNP_DMAATTR_MASK)
183 printf("Attributes: %s%s%s",
184 (flags & ISAPNP_DMAATTR_BUS_MASTER) ? "bus master " : "",
185 (flags & ISAPNP_DMAATTR_INCR_8) ? "incr 8 " : "",
186 (flags & ISAPNP_DMAATTR_INCR_16) ? "incr 16 " : "");
187 printf("\n");
188 }
189
190
191 /* isapnp_print_dep_start():
192 * Print a start dependencies tag
193 */
194 void
195 isapnp_print_dep_start(str, pref)
196 const char *str;
197 const u_char pref;
198 {
199
200 printf("%sconfig: ", str);
201 switch (pref) {
202 case ISAPNP_DEP_PREFERRED:
203 printf("preferred\n");
204 break;
205
206 case ISAPNP_DEP_ACCEPTABLE:
207 printf("acceptable\n");
208 break;
209
210 case ISAPNP_DEP_FUNCTIONAL:
211 printf("functional\n");
212 break;
213
214 case ISAPNP_DEP_UNSET: /* Used internally */
215 printf("unset\n");
216 break;
217
218 case ISAPNP_DEP_CONFLICTING: /* Used internally */
219 printf("conflicting\n");
220 break;
221
222 default:
223 printf("invalid\n");
224 break;
225 }
226 }
227
228 void
229 isapnp_print_attach(pa)
230 const struct isapnp_attach_args *pa;
231 {
232 int i;
233
234 printf("Found <%s, %s, %s, %s> ", pa->ipa_devident,
235 pa->ipa_devlogic, pa->ipa_devcompat, pa->ipa_devclass);
236 isapnp_print_dep_start("", pa->ipa_pref);
237
238 for (i = 0; i < pa->ipa_nio; i++)
239 isapnp_print_io("", &pa->ipa_io[i]);
240
241 for (i = 0; i < pa->ipa_nmem; i++)
242 isapnp_print_mem("", &pa->ipa_mem[i]);
243
244 for (i = 0; i < pa->ipa_nirq; i++)
245 isapnp_print_irq("", &pa->ipa_irq[i]);
246
247 for (i = 0; i < pa->ipa_ndrq; i++)
248 isapnp_print_drq("", &pa->ipa_drq[i]);
249
250 for (i = 0; i < pa->ipa_nmem32; i++)
251 isapnp_print_mem("", &pa->ipa_mem32[i]);
252 }
253
254
255 /* isapnp_get_config():
256 * Get the current configuration of the card
257 */
258 void
259 isapnp_get_config(sc, pa)
260 struct isapnp_softc *sc;
261 struct isapnp_attach_args *pa;
262 {
263 int i;
264 u_char v0, v1, v2, v3;
265 static u_char isapnp_mem_range[] = ISAPNP_MEM_DESC;
266 static u_char isapnp_io_range[] = ISAPNP_IO_DESC;
267 static u_char isapnp_irq_range[] = ISAPNP_IRQ_DESC;
268 static u_char isapnp_drq_range[] = ISAPNP_DRQ_DESC;
269 static u_char isapnp_mem32_range[] = ISAPNP_MEM32_DESC;
270 struct isapnp_region *r;
271 struct isapnp_pin *p;
272
273 memset(pa, 0, sizeof(*pa));
274
275 for (i = 0; i < sizeof(isapnp_io_range); i++) {
276 r = &pa->ipa_io[i];
277 v0 = isapnp_read_reg(sc,
278 isapnp_io_range[i] + ISAPNP_IO_BASE_15_8);
279 v1 = isapnp_read_reg(sc,
280 isapnp_io_range[i] + ISAPNP_IO_BASE_7_0);
281 r->base = (v0 << 8) | v1;
282 if (r->base == 0)
283 break;
284 }
285 pa->ipa_nio = i;
286
287 for (i = 0; i < sizeof(isapnp_mem_range); i++) {
288 r = &pa->ipa_mem[i];
289 v0 = isapnp_read_reg(sc,
290 isapnp_mem_range[i] + ISAPNP_MEM_BASE_23_16);
291 v1 = isapnp_read_reg(sc,
292 isapnp_mem_range[i] + ISAPNP_MEM_BASE_15_8);
293 r->base = (v0 << 16) | (v1 << 8);
294 if (r->base == 0)
295 break;
296
297 v0 = isapnp_read_reg(sc,
298 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_23_16);
299 v1 = isapnp_read_reg(sc,
300 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_15_8);
301 r->length = (v0 << 16) | (v1 << 8);
302 v0 = isapnp_read_reg(sc,
303 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL);
304 r->flags = 0;
305 if (v0 & ISAPNP_MEM_CONTROL_LIMIT)
306 r->flags |= ISAPNP_MEMATTR_HIGH_ADDR;
307 if (v0 & ISAPNP_MEM_CONTROL_16)
308 r->flags |= ISAPNP_MEMWIDTH_16;
309 }
310 pa->ipa_nmem = i;
311
312 for (i = 0; i < sizeof(isapnp_irq_range); i++) {
313 v0 = isapnp_read_reg(sc,
314 isapnp_irq_range[i] + ISAPNP_IRQ_NUMBER);
315 p = &pa->ipa_irq[i];
316 p->num = v0 & 0xf;
317 if (p->num == 0)
318 break;
319
320 switch (v0 & (ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH)) {
321 case ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH:
322 p->flags = ISAPNP_IRQTYPE_LEVEL_PLUS;
323 break;
324 case ISAPNP_IRQ_HIGH:
325 p->flags = ISAPNP_IRQTYPE_EDGE_PLUS;
326 break;
327 case ISAPNP_IRQ_LEVEL:
328 p->flags = ISAPNP_IRQTYPE_LEVEL_MINUS;
329 break;
330 default:
331 p->flags = ISAPNP_IRQTYPE_EDGE_MINUS;
332 break;
333 }
334 }
335 pa->ipa_nirq = i;
336
337 for (i = 0; i < sizeof(isapnp_drq_range); i++) {
338 v0 = isapnp_read_reg(sc, isapnp_drq_range[i]);
339 p = &pa->ipa_drq[i];
340 p->num = v0 & 0xf;
341 if (p->num == 4)
342 break;
343 }
344 pa->ipa_ndrq = i;
345
346 for (i = 0; i < sizeof(isapnp_mem32_range); i++) {
347 r = &pa->ipa_mem32[i];
348 v0 = isapnp_read_reg(sc,
349 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_31_24);
350 v1 = isapnp_read_reg(sc,
351 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_23_16);
352 v2 = isapnp_read_reg(sc,
353 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_15_8);
354 v3 = isapnp_read_reg(sc,
355 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_7_0);
356 r->base = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
357 if (r->base == 0)
358 break;
359
360 v0 = isapnp_read_reg(sc,
361 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_31_24);
362 v1 = isapnp_read_reg(sc,
363 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_23_16);
364 v2 = isapnp_read_reg(sc,
365 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_15_8);
366 v3 = isapnp_read_reg(sc,
367 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_7_0);
368 r->length = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
369 v0 = isapnp_read_reg(sc,
370 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL);
371 r->flags = v0;
372 }
373 pa->ipa_nmem32 = i;
374 }
375
376
377 /* isapnp_print_config():
378 * Print the current configuration of the card
379 */
380 void
381 isapnp_print_config(pa)
382 const struct isapnp_attach_args *pa;
383 {
384 int i;
385 const struct isapnp_region *r;
386 const struct isapnp_pin *p;
387
388 printf("Register configuration:\n");
389 if (pa->ipa_nio)
390 for (i = 0; i < pa->ipa_nio; i++) {
391 r = &pa->ipa_io[i];
392 printf("io[%d]: 0x%x/%d\n", i, r->base, r->length);
393 }
394
395 if (pa->ipa_nmem)
396 for (i = 0; i < pa->ipa_nmem; i++) {
397 r = &pa->ipa_mem[i];
398 printf("mem[%d]: 0x%x/%d\n", i, r->base, r->length);
399 }
400
401 if (pa->ipa_nirq)
402 for (i = 0; i < pa->ipa_nirq; i++) {
403 p = &pa->ipa_irq[i];
404 printf("irq[%d]: %d\n", i, p->num);
405 }
406
407 if (pa->ipa_ndrq)
408 for (i = 0; i < pa->ipa_ndrq; i++) {
409 p = &pa->ipa_drq[i];
410 printf("drq[%d]: %d\n", i, p->num);
411 }
412
413 if (pa->ipa_nmem32)
414 for (i = 0; i < pa->ipa_nmem32; i++) {
415 r = &pa->ipa_mem32[i];
416 printf("mem32[%d]: 0x%x/%d\n", i, r->base, r->length);
417 }
418 }
419
420 #endif
421