hb.c revision 1.11 1 /* $NetBSD: hb.c,v 1.11 2003/05/09 13:36:40 tsutsui Exp $ */
2
3 #include <sys/param.h>
4 #include <sys/systm.h>
5 #include <sys/device.h>
6
7 #include <machine/autoconf.h>
8
9 #include <newsmips/dev/hbvar.h>
10
11 static int hb_match __P((struct device *, struct cfdata *, void *));
12 static void hb_attach __P((struct device *, struct device *, void *));
13 static int hb_search __P((struct device *, struct cfdata *, void *));
14 static int hb_print __P((void *, const char *));
15
16 CFATTACH_DECL(hb, sizeof(struct device),
17 hb_match, hb_attach, NULL, NULL);
18
19 extern struct cfdriver hb_cd;
20
21 struct intrhand {
22 int (*func) __P((void *));
23 void *arg;
24 };
25
26 #define NHBINTR 4
27 struct intrhand hb_intrhand[6][NHBINTR];
28
29 static int
30 hb_match(parent, cf, aux)
31 struct device *parent;
32 struct cfdata *cf;
33 void *aux;
34 {
35 struct confargs *ca = aux;
36
37 if (strcmp(ca->ca_name, hb_cd.cd_name) != 0)
38 return 0;
39
40 return 1;
41 }
42
43 static void
44 hb_attach(parent, self, aux)
45 struct device *parent;
46 struct device *self;
47 void *aux;
48 {
49 struct hb_attach_args ha;
50
51 printf("\n");
52 memset(&ha, 0, sizeof(ha));
53 config_search(hb_search, self, &ha);
54 }
55
56 static int
57 hb_search(parent, cf, aux)
58 struct device *parent;
59 struct cfdata *cf;
60 void *aux;
61 {
62 struct hb_attach_args *ha = aux;
63
64 ha->ha_name = cf->cf_name;
65 ha->ha_addr = cf->cf_addr;
66 ha->ha_level = cf->cf_level;
67
68 if (config_match(parent, cf, ha) > 0)
69 config_attach(parent, cf, ha, hb_print);
70
71 return 0;
72 }
73
74 /*
75 * Print out the confargs. The (parent) name is non-NULL
76 * when there was no match found by config_found().
77 */
78 static int
79 hb_print(args, name)
80 void *args;
81 const char *name;
82 {
83 struct hb_attach_args *ha = args;
84
85 /* Be quiet about empty HB locations. */
86 if (name)
87 return QUIET;
88
89 if (ha->ha_addr != -1)
90 aprint_normal(" addr 0x%x", ha->ha_addr);
91
92 return UNCONF;
93 }
94
95 void *
96 hb_intr_establish(irq, level, func, arg)
97 int irq, level;
98 int (*func) __P((void *));
99 void *arg;
100 {
101 struct intrhand *ih = hb_intrhand[irq];
102 int i;
103
104 for (i = NHBINTR; i > 0; i--) {
105 if (ih->func == NULL)
106 goto found;
107 ih++;
108 }
109 panic("hb_intr_establish: no room");
110
111 found:
112 ih->func = func;
113 ih->arg = arg;
114
115 #ifdef HB_DEBUG
116 for (irq = 0; irq <= 2; irq++) {
117 for (i = 0; i < NHBINTR; i++) {
118 printf("%p(%p) ",
119 hb_intrhand[irq][i].func,
120 hb_intrhand[irq][i].arg);
121 }
122 printf("\n");
123 }
124 #endif
125
126 return ih;
127 }
128
129 void
130 hb_intr_dispatch(irq)
131 int irq;
132 {
133 struct intrhand *ih;
134 int i;
135
136 ih = hb_intrhand[irq];
137 for (i = NHBINTR; i > 0; i--) {
138 if (ih->func)
139 (*ih->func)(ih->arg);
140 ih++;
141 }
142 }
143