1 /* $NetBSD: hb.c,v 1.17 2005/12/11 12:18:24 christos Exp $ */
4 __KERNEL_RCSID(0, "$NetBSD: hb.c,v 1.17 2005/12/11 12:18:24 christos Exp $");
8 #include <sys/device.h>
9 #include <sys/malloc.h>
11 #include <machine/autoconf.h>
12 #include <machine/intr.h>
14 #include <newsmips/dev/hbvar.h>
18 static int hb_match(device_t
, cfdata_t
, void *);
19 static void hb_attach(device_t
, device_t
, void *);
20 static int hb_search(device_t
, cfdata_t
, const int *, void *);
21 static int hb_print(void *, const char *);
23 CFATTACH_DECL_NEW(hb
, 0,
24 hb_match
, hb_attach
, NULL
, NULL
);
27 static struct newsmips_intr hbintr_tab
[NLEVEL
];
30 hb_match(device_t parent
, cfdata_t cf
, void *aux
)
32 struct confargs
*ca
= aux
;
34 if (strcmp(ca
->ca_name
, hb_cd
.cd_name
) != 0)
41 hb_attach(device_t parent
, device_t self
, void *aux
)
43 struct hb_attach_args ha
;
44 struct newsmips_intr
*ip
;
49 memset(&ha
, 0, sizeof(ha
));
50 for (i
= 0; i
< NLEVEL
; i
++) {
52 LIST_INIT(&ip
->intr_q
);
55 config_search_ia(hb_search
, self
, "hb", &ha
);
59 hb_search(device_t parent
, cfdata_t cf
, const int *ldesc
, void *aux
)
61 struct hb_attach_args
*ha
= aux
;
63 ha
->ha_name
= cf
->cf_name
;
64 ha
->ha_addr
= cf
->cf_addr
;
65 ha
->ha_level
= cf
->cf_level
;
67 if (config_match(parent
, cf
, ha
) > 0)
68 config_attach(parent
, cf
, ha
, hb_print
);
74 * Print out the confargs. The (parent) name is non-NULL
75 * when there was no match found by config_found().
78 hb_print(void *args
, const char *name
)
80 struct hb_attach_args
*ha
= args
;
82 /* Be quiet about empty HB locations. */
86 if (ha
->ha_addr
!= -1)
87 aprint_normal(" addr 0x%x", ha
->ha_addr
);
93 hb_intr_establish(int level
, int mask
, int priority
, int (*func
)(void *),
96 struct newsmips_intr
*ip
;
97 struct newsmips_intrhand
*ih
, *curih
;
99 ip
= &hbintr_tab
[level
];
101 ih
= malloc(sizeof(*ih
), M_DEVBUF
, M_NOWAIT
);
103 panic("%s: malloc failed", __func__
);
107 ih
->ih_level
= level
;
109 ih
->ih_priority
= priority
;
111 if (LIST_EMPTY(&ip
->intr_q
)) {
112 LIST_INSERT_HEAD(&ip
->intr_q
, ih
, ih_q
);
116 for (curih
= LIST_FIRST(&ip
->intr_q
);
117 LIST_NEXT(curih
, ih_q
) != NULL
;
118 curih
= LIST_NEXT(curih
, ih_q
)) {
119 if (ih
->ih_priority
> curih
->ih_priority
) {
120 LIST_INSERT_BEFORE(curih
, ih
, ih_q
);
125 LIST_INSERT_AFTER(curih
, ih
, ih_q
);
132 hb_intr_dispatch(int level
, int stat
)
134 struct newsmips_intr
*ip
;
135 struct newsmips_intrhand
*ih
;
137 ip
= &hbintr_tab
[level
];
139 LIST_FOREACH(ih
, &ip
->intr_q
, ih_q
) {
140 if (ih
->ih_mask
& stat
)
141 (*ih
->ih_func
)(ih
->ih_arg
);