続々 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;
 }