summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2019-03-17 16:27:17 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2019-03-17 16:27:17 +0000
commit94e2856c1e2c94d8464f0bff229466806f99299d (patch)
treedfaf457607ab74c4140ffa3aba4f684ff2018ddd /sys
parent6b807b1fe6e8462341690c03d4bcefa2c7759e98 (diff)
Replace a hand-rolled linked list with SLIST.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/octeon/dev/octciu.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/sys/arch/octeon/dev/octciu.c b/sys/arch/octeon/dev/octciu.c
index 2a0104c79a6..7e422ac9053 100644
--- a/sys/arch/octeon/dev/octciu.c
+++ b/sys/arch/octeon/dev/octciu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: octciu.c,v 1.14 2019/03/17 05:25:06 visa Exp $ */
+/* $OpenBSD: octciu.c,v 1.15 2019/03/17 16:27:16 visa Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -71,7 +71,8 @@ struct intrbank {
#define IS_WORKQ_IRQ(x) ((unsigned int)(x) < 16)
struct octciu_intrhand {
- struct octciu_intrhand *ih_next;
+ SLIST_ENTRY(octciu_intrhand)
+ ih_list;
int (*ih_fun)(void *);
void *ih_arg;
int ih_level;
@@ -95,7 +96,8 @@ struct octciu_softc {
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
struct octciu_cpu sc_cpu[MAXCPUS];
- struct octciu_intrhand *sc_intrhand[OCTCIU_NINTS];
+ SLIST_HEAD(, octciu_intrhand)
+ sc_intrhand[OCTCIU_NINTS];
unsigned int sc_nbanks;
int (*sc_ipi_handler)(void *);
@@ -148,6 +150,7 @@ octciu_attach(struct device *parent, struct device *self, void *aux)
{
struct fdt_attach_args *faa = aux;
struct octciu_softc *sc = (struct octciu_softc *)self;
+ int i;
if (faa->fa_nreg != 1) {
printf(": expected one IO space, got %d\n", faa->fa_nreg);
@@ -166,6 +169,9 @@ octciu_attach(struct device *parent, struct device *self, void *aux)
else
sc->sc_nbanks = 2;
+ for (i = 0; i < OCTCIU_NINTS; i++)
+ SLIST_INIT(&sc->sc_intrhand[i]);
+
printf("\n");
sc->sc_ic.ic_cookie = sc;
@@ -235,7 +241,7 @@ octciu_intr_establish(int irq, int level, int (*ih_fun)(void *),
void *ih_arg, const char *ih_what)
{
struct octciu_softc *sc = octciu_sc;
- struct octciu_intrhand **p, *q, *ih;
+ struct octciu_intrhand *ih, *last, *tmp;
int cpuid = cpu_number();
int flags;
int s;
@@ -258,7 +264,6 @@ octciu_intr_establish(int irq, int level, int (*ih_fun)(void *),
if (ih == NULL)
return NULL;
- ih->ih_next = NULL;
ih->ih_fun = ih_fun;
ih->ih_arg = ih_arg;
ih->ih_level = level;
@@ -269,14 +274,14 @@ octciu_intr_establish(int irq, int level, int (*ih_fun)(void *),
s = splhigh();
- /*
- * Figure out where to put the handler.
- * This is O(N^2), but we want to preserve the order, and N is
- * generally small.
- */
- for (p = &sc->sc_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
- continue;
- *p = ih;
+ if (SLIST_EMPTY(&sc->sc_intrhand[irq])) {
+ SLIST_INSERT_HEAD(&sc->sc_intrhand[irq], ih, ih_list);
+ } else {
+ last = NULL;
+ SLIST_FOREACH(tmp, &sc->sc_intrhand[irq], ih_list)
+ last = tmp;
+ SLIST_INSERT_AFTER(last, ih, ih_list);
+ }
sc->sc_cpu[cpuid].scpu_intem[IRQ_TO_BANK(irq)] |=
1UL << IRQ_TO_BIT(irq);
@@ -315,10 +320,11 @@ void
octciu_intr_disestablish(void *_ih)
{
struct octciu_intrhand *ih = _ih;
- struct octciu_intrhand *p;
+ struct octciu_intrhand *tmp;
struct octciu_softc *sc = octciu_sc;
unsigned int irq = ih->ih_irq;
int cpuid = cpu_number();
+ int found = 0;
int s;
KASSERT(irq < sc->sc_nbanks * BANK_SIZE);
@@ -326,27 +332,26 @@ octciu_intr_disestablish(void *_ih)
s = splhigh();
- if (ih == sc->sc_intrhand[irq]) {
- sc->sc_intrhand[irq] = ih->ih_next;
-
- if (sc->sc_intrhand[irq] == NULL)
- sc->sc_cpu[cpuid].scpu_intem[IRQ_TO_BANK(irq)] &=
- ~(1UL << IRQ_TO_BIT(irq));
- } else {
- for (p = sc->sc_intrhand[irq]; p != NULL; p = p->ih_next) {
- if (p->ih_next == ih) {
- p->ih_next = ih->ih_next;
- break;
- }
+ SLIST_FOREACH(tmp, &sc->sc_intrhand[irq], ih_list) {
+ if (tmp == ih) {
+ found = 1;
+ break;
}
- if (p == NULL)
- panic("%s: intrhand %p has not been registered",
- __func__, ih);
}
- free(ih, M_DEVBUF, sizeof(*ih));
+ if (found == 0)
+ panic("%s: intrhand %p not registered", __func__, ih);
+
+ SLIST_REMOVE(&sc->sc_intrhand[irq], ih, octciu_intrhand, ih_list);
+
+ if (SLIST_EMPTY(&sc->sc_intrhand[irq])) {
+ sc->sc_cpu[cpuid].scpu_intem[IRQ_TO_BANK(irq)] &=
+ ~(1UL << IRQ_TO_BIT(irq));
+ }
octciu_intr_makemasks(sc);
splx(s); /* causes hw mask update */
+
+ free(ih, M_DEVBUF, sizeof(*ih));
}
void
@@ -378,7 +383,7 @@ octciu_intr_makemasks(struct octciu_softc *sc)
/* First, figure out which levels each IRQ uses. */
for (irq = 0; irq < OCTCIU_NINTS; irq++) {
uint levels = 0;
- for (q = sc->sc_intrhand[irq]; q != NULL; q = q->ih_next) {
+ SLIST_FOREACH(q, &sc->sc_intrhand[irq], ih_list) {
if (q->ih_cpuid == cpuid)
levels |= 1 << q->ih_level;
}
@@ -498,7 +503,7 @@ octciu_intr_bank(struct octciu_softc *sc, struct intrbank *bank,
while ((irq = octciu_next_irq(&isr)) >= 0) {
irq += bank->id * BANK_SIZE;
handled = 0;
- for (ih = sc->sc_intrhand[irq]; ih != NULL; ih = ih->ih_next) {
+ SLIST_FOREACH(ih, &sc->sc_intrhand[irq], ih_list) {
splraise(ih->ih_level);
#ifdef MULTIPROCESSOR
if (ih->ih_level < IPL_IPI) {