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