xref: /netbsd-src/sys/dev/isapnp/isapnpdebug.c (revision 56a34939419542e88b386b2229be7565f4f45461)
1 /*	$NetBSD: isapnpdebug.c,v 1.11 2008/04/28 20:23:53 martin 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.11 2008/04/28 20:23:53 martin 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