summaryrefslogtreecommitdiff
path: root/sys/dev/cardbus/cardslot.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2008-11-24 15:50:45 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2008-11-24 15:50:45 +0000
commit12d0b513950a3e41089b1128b472689c689d4175 (patch)
treefaf8ef049f3ed448c1e95168fa91ad04a86af658 /sys/dev/cardbus/cardslot.c
parent22c7ad1354a2e9091ea23248b0fde52f6d9f37c3 (diff)
use workq instead of crafting our own kthread, since the tasks being done
are fairly small. tested by a few, and kettenis says he will test it sooner if it is commited...
Diffstat (limited to 'sys/dev/cardbus/cardslot.c')
-rw-r--r--sys/dev/cardbus/cardslot.c351
1 files changed, 162 insertions, 189 deletions
diff --git a/sys/dev/cardbus/cardslot.c b/sys/dev/cardbus/cardslot.c
index 101f3671223..38f57e9ec1a 100644
--- a/sys/dev/cardbus/cardslot.c
+++ b/sys/dev/cardbus/cardslot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cardslot.c,v 1.10 2007/12/21 17:36:52 kettenis Exp $ */
+/* $OpenBSD: cardslot.c,v 1.11 2008/11/24 15:50:44 deraadt Exp $ */
/* $NetBSD: cardslot.c,v 1.9 2000/03/22 09:35:06 haya Exp $ */
/*
@@ -40,6 +40,8 @@
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <sys/kthread.h>
+#include <sys/pool.h>
+#include <sys/workq.h>
#include <machine/bus.h>
@@ -64,8 +66,7 @@
STATIC void cardslotattach(struct device *, struct device *, void *);
STATIC int cardslotmatch(struct device *, void *, void *);
-STATIC void create_slot_manager(void *);
-STATIC void cardslot_event_thread(void *arg);
+STATIC void cardslot_event(void *arg1, void *arg2);
STATIC int cardslot_cb_print(void *aux, const char *pcic);
STATIC int cardslot_16_print(void *, const char *);
@@ -79,6 +80,8 @@ struct cfdriver cardslot_cd = {
NULL, "cardslot", DV_DULL
};
+struct pool cardsloteventpool;
+
STATIC int
cardslotmatch(struct device *parent, void *match, void *aux)
{
@@ -104,11 +107,14 @@ cardslotattach(struct device *parent, struct device *self, void *aux)
struct cardbus_softc *csc = NULL;
struct pcmcia_softc *psc = NULL;
+ if (cardsloteventpool.pr_align == 0)
+ pool_init(&cardsloteventpool, sizeof(cardslot_event), 0, 0, 0,
+ "cardslot", NULL);
+
sc->sc_slot = sc->sc_dev.dv_unit;
sc->sc_cb_softc = NULL;
sc->sc_16_softc = NULL;
SIMPLEQ_INIT(&sc->sc_events);
- sc->sc_th_enable = 0;
printf(" slot %d flags %x\n", sc->sc_slot,
sc->sc_dev.dv_cfdata->cf_flags);
@@ -137,9 +143,6 @@ cardslotattach(struct device *parent, struct device *self, void *aux)
}
}
- if (csc != NULL || psc != NULL)
- kthread_create_deferred(create_slot_manager, (void *)sc);
-
if (csc && (csc->sc_cf->cardbus_ctrl)(csc->sc_cc, CARDBUS_CD)) {
DPRINTF(("cardslotattach: CardBus card found\n"));
/* attach deferred */
@@ -187,21 +190,6 @@ cardslot_16_print(void *arg, const char *pnp)
return (UNCONF);
}
-STATIC void
-create_slot_manager(void *arg)
-{
- struct cardslot_softc *sc = (struct cardslot_softc *)arg;
-
- sc->sc_th_enable = 1;
-
- if (kthread_create(cardslot_event_thread, sc, &sc->sc_event_thread,
- "%s", sc->sc_dev.dv_xname)) {
- printf("%s: unable to create event thread for slot %d\n",
- sc->sc_dev.dv_xname, sc->sc_slot);
- panic("create_slot_manager");
- }
-}
-
/*
* void cardslot_event_throw(struct cardslot_softc *sc, int ev)
*
@@ -212,6 +200,7 @@ void
cardslot_event_throw(struct cardslot_softc *sc, int ev)
{
struct cardslot_event *ce;
+ int s;
DPRINTF(("cardslot_event_throw: an event %s comes\n",
ev == CARDSLOT_EVENT_INSERTION_CB ? "CardBus Card inserted" :
@@ -219,202 +208,186 @@ cardslot_event_throw(struct cardslot_softc *sc, int ev)
ev == CARDSLOT_EVENT_REMOVAL_CB ? "CardBus Card removed" :
ev == CARDSLOT_EVENT_REMOVAL_16 ? "16-bit Card removed" : "???"));
- if ((ce = (struct cardslot_event *)malloc(sizeof(struct cardslot_event),
- M_TEMP, M_NOWAIT)) == NULL) {
- panic("cardslot_event");
- }
-
+ ce = pool_get(&cardsloteventpool, PR_NOWAIT);
+ if (ce == NULL)
+ return;
ce->ce_type = ev;
- {
- int s = spltty();
- SIMPLEQ_INSERT_TAIL(&sc->sc_events, ce, ce_q);
- splx(s);
- }
+ s = spltty();
+ SIMPLEQ_INSERT_TAIL(&sc->sc_events, ce, ce_q);
+ splx(s);
- wakeup(&sc->sc_events);
+ workq_add_task(NULL, 0, cardslot_event, sc, NULL);
}
/*
- * STATIC void cardslot_event_thread(void *arg)
+ * STATIC void cardslot_event(void *arg)
*
* This function is the main routine handing cardslot events such as
* insertions and removals.
*
*/
STATIC void
-cardslot_event_thread(void *arg)
+cardslot_event(void *arg1, void *arg2)
{
- struct cardslot_softc *sc = arg;
+ struct cardslot_softc *sc = arg1;
struct cardslot_event *ce;
- int s;
- static int antonym_ev[4] = {
- CARDSLOT_EVENT_REMOVAL_16, CARDSLOT_EVENT_INSERTION_16,
- CARDSLOT_EVENT_REMOVAL_CB, CARDSLOT_EVENT_INSERTION_CB
- };
-
- while (sc->sc_th_enable) {
- s = spltty();
- if ((ce = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) {
- splx(s);
- (void) tsleep(&sc->sc_events, PWAIT, "cardslotev", 0);
- continue;
- }
- SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
- splx(s);
+ int s, ev;
- if (IS_CARDSLOT_INSERT_REMOVE_EV(ce->ce_type)) {
- /* Chattering suppression */
- s = spltty();
- while (1) {
- struct cardslot_event *ce1, *ce2;
-
- if ((ce1 = SIMPLEQ_FIRST(&sc->sc_events)) ==
- NULL)
- break;
- if (ce1->ce_type != antonym_ev[ce->ce_type])
- break;
- if ((ce2 = SIMPLEQ_NEXT(ce1, ce_q)) == NULL)
- break;
- if (ce2->ce_type == ce->ce_type) {
- SIMPLEQ_REMOVE_HEAD(&sc->sc_events,
- ce_q);
- free(ce1, M_TEMP);
- SIMPLEQ_REMOVE_HEAD(&sc->sc_events,
- ce_q);
- free(ce2, M_TEMP);
- }
+ s = spltty();
+ if ((ce = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) {
+ splx(s);
+ return;
+ }
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
+
+ if (IS_CARDSLOT_INSERT_REMOVE_EV(ce->ce_type)) {
+ /* Chattering suppression */
+ static int antonym_ev[4] = {
+ CARDSLOT_EVENT_REMOVAL_16,
+ CARDSLOT_EVENT_INSERTION_16,
+ CARDSLOT_EVENT_REMOVAL_CB,
+ CARDSLOT_EVENT_INSERTION_CB
+ };
+
+ while (1) {
+ struct cardslot_event *ce1, *ce2;
+
+ if ((ce1 = SIMPLEQ_FIRST(&sc->sc_events)) ==
+ NULL)
+ break;
+ if (ce1->ce_type != antonym_ev[ce->ce_type])
+ break;
+ if ((ce2 = SIMPLEQ_NEXT(ce1, ce_q)) == NULL)
+ break;
+ if (ce2->ce_type == ce->ce_type) {
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
+ pool_put(&cardsloteventpool, ce1);
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
+ pool_put(&cardsloteventpool, ce2);
}
- splx(s);
}
-
- switch (ce->ce_type) {
- case CARDSLOT_EVENT_INSERTION_CB:
- if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
- CARDSLOT_STATUS_CARD_CB) ||
- (CARDSLOT_CARDTYPE(sc->sc_status) ==
- CARDSLOT_STATUS_CARD_16)) {
- if (CARDSLOT_WORK(sc->sc_status) ==
- CARDSLOT_STATUS_WORKING) {
- /* A card has already been inserted
- * and works.
- */
- break;
- }
+ }
+ splx(s);
+
+ ev = ce->ce_type;
+ pool_put(&cardsloteventpool, ce);
+
+ switch (ev) {
+ case CARDSLOT_EVENT_INSERTION_CB:
+ if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
+ CARDSLOT_STATUS_CARD_CB) ||
+ (CARDSLOT_CARDTYPE(sc->sc_status) ==
+ CARDSLOT_STATUS_CARD_16)) {
+ if (CARDSLOT_WORK(sc->sc_status) ==
+ CARDSLOT_STATUS_WORKING) {
+ /* A card has already been inserted
+ * and works.
+ */
+ break;
}
+ }
- if (sc->sc_cb_softc) {
- CARDSLOT_SET_CARDTYPE(sc->sc_status,
- CARDSLOT_STATUS_CARD_CB);
- if (cardbus_attach_card(sc->sc_cb_softc) > 0) {
- /* At least one function works */
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_WORKING);
- } else {
- /* No functions work or this card is
- * not known
- */
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_NOTWORK);
- }
+ if (sc->sc_cb_softc) {
+ CARDSLOT_SET_CARDTYPE(sc->sc_status,
+ CARDSLOT_STATUS_CARD_CB);
+ if (cardbus_attach_card(sc->sc_cb_softc) > 0) {
+ /* At least one function works */
+ CARDSLOT_SET_WORK(sc->sc_status,
+ CARDSLOT_STATUS_WORKING);
} else {
- printf("%s: CardBus support disabled\n",
- sc->sc_dev.dv_xname);
+ /* No functions work or this card is
+ * not known
+ */
+ CARDSLOT_SET_WORK(sc->sc_status,
+ CARDSLOT_STATUS_NOTWORK);
}
-
- break;
-
- case CARDSLOT_EVENT_INSERTION_16:
- if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
- CARDSLOT_STATUS_CARD_CB) ||
- (CARDSLOT_CARDTYPE(sc->sc_status) ==
- CARDSLOT_STATUS_CARD_16)) {
- if (CARDSLOT_WORK(sc->sc_status) ==
- CARDSLOT_STATUS_WORKING) {
- /* A card has already been inserted
- * and works.
- */
- break;
- }
+ } else {
+ printf("%s: CardBus support disabled\n",
+ sc->sc_dev.dv_xname);
+ }
+ break;
+
+ case CARDSLOT_EVENT_INSERTION_16:
+ if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
+ CARDSLOT_STATUS_CARD_CB) ||
+ (CARDSLOT_CARDTYPE(sc->sc_status) ==
+ CARDSLOT_STATUS_CARD_16)) {
+ if (CARDSLOT_WORK(sc->sc_status) ==
+ CARDSLOT_STATUS_WORKING) {
+ /* A card has already been inserted
+ * and works.
+ */
+ break;
}
- if (sc->sc_16_softc) {
- CARDSLOT_SET_CARDTYPE(sc->sc_status,
- CARDSLOT_STATUS_CARD_16);
- if (pcmcia_card_attach(
- (struct device *)sc->sc_16_softc)) {
- /* Do not attach */
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_NOTWORK);
- } else {
- /* working */
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_WORKING);
- }
+ }
+ if (sc->sc_16_softc) {
+ CARDSLOT_SET_CARDTYPE(sc->sc_status,
+ CARDSLOT_STATUS_CARD_16);
+ if (pcmcia_card_attach(
+ (struct device *)sc->sc_16_softc)) {
+ /* Do not attach */
+ CARDSLOT_SET_WORK(sc->sc_status,
+ CARDSLOT_STATUS_NOTWORK);
} else {
- panic("no 16-bit pcmcia on %s",
- sc->sc_dev.dv_xname);
+ /* working */
+ CARDSLOT_SET_WORK(sc->sc_status,
+ CARDSLOT_STATUS_WORKING);
}
-
- break;
-
- case CARDSLOT_EVENT_REMOVAL_CB:
- if (CARDSLOT_CARDTYPE(sc->sc_status) ==
- CARDSLOT_STATUS_CARD_CB) {
- /* CardBus card has not been inserted. */
- if (CARDSLOT_WORK(sc->sc_status) ==
- CARDSLOT_STATUS_WORKING) {
- cardbus_detach_card(sc->sc_cb_softc);
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_NOTWORK);
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_CARD_NONE);
- }
- CARDSLOT_SET_CARDTYPE(sc->sc_status,
- CARDSLOT_STATUS_CARD_NONE);
- } else if (CARDSLOT_CARDTYPE(sc->sc_status) !=
- CARDSLOT_STATUS_CARD_16) {
- /* Unknown card... */
- CARDSLOT_SET_CARDTYPE(sc->sc_status,
+ } else {
+ panic("no 16-bit pcmcia on %s",
+ sc->sc_dev.dv_xname);
+ }
+ break;
+
+ case CARDSLOT_EVENT_REMOVAL_CB:
+ if (CARDSLOT_CARDTYPE(sc->sc_status) ==
+ CARDSLOT_STATUS_CARD_CB) {
+ /* CardBus card has not been inserted. */
+ if (CARDSLOT_WORK(sc->sc_status) ==
+ CARDSLOT_STATUS_WORKING) {
+ cardbus_detach_card(sc->sc_cb_softc);
+ CARDSLOT_SET_WORK(sc->sc_status,
+ CARDSLOT_STATUS_NOTWORK);
+ CARDSLOT_SET_WORK(sc->sc_status,
CARDSLOT_STATUS_CARD_NONE);
}
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_NOTWORK);
- break;
-
- case CARDSLOT_EVENT_REMOVAL_16:
- DPRINTF(("%s: removal event\n", sc->sc_dev.dv_xname));
- if (CARDSLOT_CARDTYPE(sc->sc_status) !=
- CARDSLOT_STATUS_CARD_16) {
- /* 16-bit card has not been inserted. */
- break;
- }
- if ((sc->sc_16_softc != NULL) &&
- (CARDSLOT_WORK(sc->sc_status) ==
- CARDSLOT_STATUS_WORKING)) {
- struct pcmcia_softc *psc = sc->sc_16_softc;
-
- pcmcia_card_deactivate((struct device *)psc);
- pcmcia_chip_socket_disable(psc->pct, psc->pch);
- pcmcia_card_detach((struct device *)psc,
- DETACH_FORCE);
- }
CARDSLOT_SET_CARDTYPE(sc->sc_status,
CARDSLOT_STATUS_CARD_NONE);
- CARDSLOT_SET_WORK(sc->sc_status,
- CARDSLOT_STATUS_NOTWORK);
+ } else if (CARDSLOT_CARDTYPE(sc->sc_status) !=
+ CARDSLOT_STATUS_CARD_16) {
+ /* Unknown card... */
+ CARDSLOT_SET_CARDTYPE(sc->sc_status,
+ CARDSLOT_STATUS_CARD_NONE);
+ }
+ CARDSLOT_SET_WORK(sc->sc_status,
+ CARDSLOT_STATUS_NOTWORK);
+ break;
+
+ case CARDSLOT_EVENT_REMOVAL_16:
+ DPRINTF(("%s: removal event\n", sc->sc_dev.dv_xname));
+ if (CARDSLOT_CARDTYPE(sc->sc_status) !=
+ CARDSLOT_STATUS_CARD_16) {
+ /* 16-bit card has not been inserted. */
break;
-
- default:
- panic("cardslot_event_thread: unknown event %d",
- ce->ce_type);
}
- free(ce, M_TEMP);
+ if ((sc->sc_16_softc != NULL) &&
+ (CARDSLOT_WORK(sc->sc_status) ==
+ CARDSLOT_STATUS_WORKING)) {
+ struct pcmcia_softc *psc = sc->sc_16_softc;
+
+ pcmcia_card_deactivate((struct device *)psc);
+ pcmcia_chip_socket_disable(psc->pct, psc->pch);
+ pcmcia_card_detach((struct device *)psc,
+ DETACH_FORCE);
+ }
+ CARDSLOT_SET_CARDTYPE(sc->sc_status,
+ CARDSLOT_STATUS_CARD_NONE);
+ CARDSLOT_SET_WORK(sc->sc_status,
+ CARDSLOT_STATUS_NOTWORK);
+ break;
+
+ default:
+ panic("cardslot_event_thread: unknown event %d", ev);
}
-
- sc->sc_event_thread = NULL;
-
- /* In case the parent device is waiting for us to exit. */
- wakeup(sc);
-
- kthread_exit(0);
}