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