Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / newsmips / dev / hb.c
bloba1330d4ef3c21965e831d9e727ec648ff48935a9
1 /* $NetBSD: hb.c,v 1.17 2005/12/11 12:18:24 christos Exp $ */
3 #include <sys/cdefs.h>
4 __KERNEL_RCSID(0, "$NetBSD: hb.c,v 1.17 2005/12/11 12:18:24 christos Exp $");
6 #include <sys/param.h>
7 #include <sys/systm.h>
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>
16 #include "ioconf.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);
26 #define NLEVEL 4
27 static struct newsmips_intr hbintr_tab[NLEVEL];
29 static int
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)
35 return 0;
37 return 1;
40 static void
41 hb_attach(device_t parent, device_t self, void *aux)
43 struct hb_attach_args ha;
44 struct newsmips_intr *ip;
45 int i;
47 aprint_normal("\n");
49 memset(&ha, 0, sizeof(ha));
50 for (i = 0; i < NLEVEL; i++) {
51 ip = &hbintr_tab[i];
52 LIST_INIT(&ip->intr_q);
55 config_search_ia(hb_search, self, "hb", &ha);
58 static int
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);
70 return 0;
74 * Print out the confargs. The (parent) name is non-NULL
75 * when there was no match found by config_found().
77 static int
78 hb_print(void *args, const char *name)
80 struct hb_attach_args *ha = args;
82 /* Be quiet about empty HB locations. */
83 if (name)
84 return QUIET;
86 if (ha->ha_addr != -1)
87 aprint_normal(" addr 0x%x", ha->ha_addr);
89 return UNCONF;
92 void *
93 hb_intr_establish(int level, int mask, int priority, int (*func)(void *),
94 void *arg)
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);
102 if (ih == NULL)
103 panic("%s: malloc failed", __func__);
105 ih->ih_func = func;
106 ih->ih_arg = arg;
107 ih->ih_level = level;
108 ih->ih_mask = mask;
109 ih->ih_priority = priority;
111 if (LIST_EMPTY(&ip->intr_q)) {
112 LIST_INSERT_HEAD(&ip->intr_q, ih, ih_q);
113 goto done;
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);
121 goto done;
125 LIST_INSERT_AFTER(curih, ih, ih_q);
127 done:
128 return ih;
131 void
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);