xref: /netbsd/sys/dev/isapnp/isapnpdebug.c (revision bf9ec67e)
1 /*	$NetBSD: isapnpdebug.c,v 1.6 2001/11/13 07:56:41 lukem 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.6 2001/11/13 07:56:41 lukem 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_WRITEABLE) ?
70 		"writeable," : "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