続々 attach
workqueue(9) を使うとこんな感じですかね。
カードが刺さっている間はカーネルスレッドが増えてしまうのが気になるところ。
Index: ld_sdmmc.c =================================================================== RCS file: /cvs/cvsroot/src/sys/dev/sdmmc/ld_sdmmc.c,v retrieving revision 1.2 diff -u -r1.2 ld_sdmmc.c --- ld_sdmmc.c 6 May 2009 08:20:49 -0000 1.2 +++ ld_sdmmc.c 27 May 2009 10:59:37 -0000 @@ -43,6 +43,7 @@ #include <sys/endian.h> #include <sys/dkio.h> #include <sys/disk.h> +#include <sys/workqueue.h> #if NRND > 0 #include <sys/rnd.h> #endif @@ -75,6 +76,9 @@ struct sdmmc_function *sc_sf; struct ld_sdmmc_task sc_task; + + struct workqueue *sc_wkq; + struct work sc_wk; }; static int ld_sdmmc_match(device_t, cfdata_t, void *); @@ -84,6 +88,7 @@ static int ld_sdmmc_dump(struct ld_softc *, void *, int, int); static int ld_sdmmc_start(struct ld_softc *, struct buf *); +static void ld_sdmmc_doattach(struct work *, void *); static void ld_sdmmc_dobio(void *); static void ld_sdmmc_timeout(void *); @@ -109,6 +114,7 @@ struct ld_sdmmc_softc *sc = device_private(self); struct sdmmc_attach_args *sa = aux; struct ld_softc *ld = &sc->sc_ld; + int error; ld->sc_dv = self; @@ -128,6 +134,26 @@ ld->sc_dump = ld_sdmmc_dump; ld->sc_start = ld_sdmmc_start; + /* + * It is avoided that the error occurs when the card attaches it, + * when wedge is supported. + */ + error = workqueue_create(&sc->sc_wkq, "ldattach", + ld_sdmmc_doattach, sc, PRI_NONE, IPL_NONE, 0); + if (error) { + aprint_error_dev(self, "couldn't create workqueue\n"); + return; + } + workqueue_enqueue(sc->sc_wkq, &sc->sc_wk, NULL); +} + +/*ARGSUSED*/ +static void +ld_sdmmc_doattach(struct work *wk, void *arg) +{ + struct ld_sdmmc_softc *sc = (struct ld_sdmmc_softc *)arg; + struct ld_softc *ld = &sc->sc_ld; + ldattach(ld); } @@ -141,6 +167,7 @@ if ((rv = ldbegindetach(ld, flags)) != 0) return rv; ldenddetach(ld); + workqueue_destroy(sc->sc_wkq); return 0; }