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