? sys/dev/mscp/.mscp.c.swp
? sys/dev/mscp/.mscp_subr.c.swp
? sys/dev/mscp/.mscpvar.h.swp
Index: sys/dev/mscp/mscp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mscp/mscp.c,v
retrieving revision 1.29
diff -u -r1.29 mscp.c
--- sys/dev/mscp/mscp.c	8 Apr 2008 20:10:44 -0000	1.29
+++ sys/dev/mscp/mscp.c	11 Jan 2009 01:02:27 -0000
@@ -86,6 +86,7 @@
 #include <sys/device.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
+#include <sys/kmem.h>
 
 #include <sys/bus.h>
 
@@ -95,6 +96,13 @@
 
 #define PCMD	PSWP		/* priority for command packet waits */
 
+/* An mscp workqueue item */
+struct mscp_work {
+	struct work mw_work;
+	struct mscp_softc *mw_mi;
+	struct mscp mw_mp;
+};
+
 /*
  * Get a command packet.  Second argument is true iff we are
  * to wait if necessary.  Return NULL if none are available and
@@ -297,11 +305,19 @@
 			break;
 
 		if (drive == 0) {
-			struct	drive_attach_args da;
+			struct mscp_work *mw;
+
+			mw = kmem_zalloc(sizeof(*mw), KM_NOSLEEP);
+			if (mw == NULL) {
+				aprint_error_dev(&mi->mi_dev,
+					"out of memory, cannot attach\n");
+				return;
+			}
 
-			da.da_mp = (struct mscp *)mp;
-			da.da_typ = mi->mi_type;
-			config_found(&mi->mi_dev, (void *)&da, mscp_print);
+			mw->mw_mi = mi;
+			mw->mw_mp = *mp;
+
+			workqueue_enqueue(mi->mi_wq, (struct work *)mw, NULL);
 		} else
 			/* Hack to avoid complaints */
 			if (!(((mp->mscp_event & M_ST_MASK) == M_ST_AVAILABLE)
@@ -469,3 +485,16 @@
 	panic("mscp_requeue");
 }
 
+void
+mscp_worker(struct work *wk, void *dummy)
+{
+	struct mscp_work *mw = (struct mscp_work *)wk;
+	struct drive_attach_args da;
+
+	da.da_mp = &mw->mw_mp;
+	da.da_typ = mw->mw_mi->mi_type;
+
+	config_found(&mw->mw_mi->mi_dev, (void *)&da, mscp_print);
+
+	kmem_free(mw, sizeof(*mw));
+}
Index: sys/dev/mscp/mscp_subr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mscp/mscp_subr.c,v
retrieving revision 1.35
diff -u -r1.35 mscp_subr.c
--- sys/dev/mscp/mscp_subr.c	8 Apr 2008 20:10:44 -0000	1.35
+++ sys/dev/mscp/mscp_subr.c	11 Jan 2009 01:02:28 -0000
@@ -226,6 +226,11 @@
 		mi->mi_me = &mt_device;
 	}
 #endif
+
+	if (workqueue_create(&mi->mi_wq, "mscp_wq", mscp_worker, NULL,
+	    PRI_NONE, IPL_NONE, 0) != 0)
+		panic("%s: could not create workqueue", __func__);
+
 	/*
 	 * Go out and search for sub-units on this MSCP bus,
 	 * and call config_found for each found.
Index: sys/dev/mscp/mscpvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/mscp/mscpvar.h,v
retrieving revision 1.15
diff -u -r1.15 mscpvar.h
--- sys/dev/mscp/mscpvar.h	4 Mar 2007 06:02:14 -0000	1.15
+++ sys/dev/mscp/mscpvar.h	11 Jan 2009 01:02:28 -0000
@@ -70,6 +70,8 @@
  *	@(#)mscpvar.h	7.3 (Berkeley) 6/28/90
  */
 
+#include <sys/workqueue.h>
+
 /*
  * MSCP generic driver configuration
  */
@@ -224,6 +226,7 @@
 	bus_space_handle_t mi_sah;	/* status & address (read part) */
 	bus_space_handle_t mi_swh;	/* status & address (write part) */
 	struct bufq_state *mi_resq;	/* While waiting for packets */
+	struct workqueue *mi_wq;	/* Workqueue for autoconf work */
 };
 
 /* mi_flags */
@@ -280,3 +283,4 @@
 int	mscp_waitstep(struct mscp_softc *, int, int);
 void	mscp_dgo(struct mscp_softc *, struct mscp_xi *);
 void	mscp_intr(struct mscp_softc *);
+void	mscp_worker(struct work *, void *);
