Module Name:    src
Committed By:   pgoyette
Date:           Tue Sep 27 03:33:33 UTC 2016

Modified Files:
        src/sys/dev: ld.c
        src/sys/dev/ata: ata_raid.c ld_ataraid.c
        src/sys/dev/eisa: cac_eisa.c mlx_eisa.c
        src/sys/dev/ic: aac.c aacvar.h cac.c cacvar.h ld_aac.c ld_cac.c
            ld_icp.c ld_mlx.c ld_nvme.c mlx.c mlxvar.h nvme.c nvmevar.h
        src/sys/dev/pci: aac_pci.c amr.c cac_pci.c icp_pci.c if_vioif.c
            ld_amr.c ld_twa.c ld_twe.c ld_virtio.c mlx_pci.c nvme_pci.c twa.c
            twe.c viomb.c virtio.c virtiovar.h
        src/sys/dev/sdmmc: ld_sdmmc.c

Log Message:
Modularize the ld driver and all of its attachments.  Ensure that all
parents are capable of rescan (or otherwise provide a means of attaching
children post-initialization).


To generate a diff of this commit:
cvs rdiff -u -r1.96 -r1.97 src/sys/dev/ld.c
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/ata/ata_raid.c
cvs rdiff -u -r1.42 -r1.43 src/sys/dev/ata/ld_ataraid.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/eisa/cac_eisa.c
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/eisa/mlx_eisa.c
cvs rdiff -u -r1.44 -r1.45 src/sys/dev/ic/aac.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/ic/aacvar.h
cvs rdiff -u -r1.56 -r1.57 src/sys/dev/ic/cac.c
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/ic/cacvar.h
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/ic/ld_aac.c src/sys/dev/ic/ld_cac.c
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/ic/ld_icp.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/ic/ld_mlx.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/ic/ld_nvme.c
cvs rdiff -u -r1.64 -r1.65 src/sys/dev/ic/mlx.c
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/ic/mlxvar.h
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/ic/nvme.c
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/ic/nvmevar.h
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/pci/aac_pci.c
cvs rdiff -u -r1.61 -r1.62 src/sys/dev/pci/amr.c
cvs rdiff -u -r1.34 -r1.35 src/sys/dev/pci/cac_pci.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/pci/icp_pci.c
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/pci/if_vioif.c \
    src/sys/dev/pci/mlx_pci.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/pci/ld_amr.c
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/pci/ld_twa.c
cvs rdiff -u -r1.38 -r1.39 src/sys/dev/pci/ld_twe.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/pci/ld_virtio.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/pci/nvme_pci.c
cvs rdiff -u -r1.53 -r1.54 src/sys/dev/pci/twa.c
cvs rdiff -u -r1.105 -r1.106 src/sys/dev/pci/twe.c
cvs rdiff -u -r1.6 -r1.7 src/sys/dev/pci/viomb.c
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/pci/virtio.c
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/pci/virtiovar.h
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/sdmmc/ld_sdmmc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ld.c
diff -u src/sys/dev/ld.c:1.96 src/sys/dev/ld.c:1.97
--- src/sys/dev/ld.c:1.96	Mon Sep 19 23:32:30 2016
+++ src/sys/dev/ld.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld.c,v 1.96 2016/09/19 23:32:30 jdolecek Exp $	*/
+/*	$NetBSD: ld.c,v 1.97 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.96 2016/09/19 23:32:30 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.97 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -54,11 +54,10 @@ __KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.96 
 #include <sys/vnode.h>
 #include <sys/syslog.h>
 #include <sys/mutex.h>
+#include <sys/module.h>
 
 #include <dev/ldvar.h>
 
-#include <prop/proplib.h>
-
 static void	ldminphys(struct buf *bp);
 static bool	ld_suspend(device_t, const pmf_qual_t *);
 static bool	ld_shutdown(device_t, int);
@@ -590,3 +589,42 @@ lddiscard(dev_t dev, off_t pos, off_t le
 
 	return dk_discard(dksc, dev, pos, len);
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld, "dk_subr");
+
+#ifdef _MODULE
+CFDRIVER_DECL(ld, DV_DISK, NULL);
+#endif
+
+static int
+ld_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	devmajor_t bmajor, cmajor;
+#endif
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		bmajor = cmajor = -1;
+		error = devsw_attach(ld_cd.cd_name, &ld_bdevsw, &bmajor,
+		    &ld_cdevsw, &cmajor);
+		if (error)
+			break;
+		error = config_cfdriver_attach(&ld_cd);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_cfdriver_detach(&ld_cd);
+		if (error)
+			break;
+		devsw_detach(&ld_bdevsw, &ld_cdevsw);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/ata/ata_raid.c
diff -u src/sys/dev/ata/ata_raid.c:1.37 src/sys/dev/ata/ata_raid.c:1.38
--- src/sys/dev/ata/ata_raid.c:1.37	Thu Jul 14 10:19:05 2016
+++ src/sys/dev/ata/ata_raid.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_raid.c,v 1.37 2016/07/14 10:19:05 msaitoh Exp $	*/
+/*	$NetBSD: ata_raid.c,v 1.38 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid.c,v 1.37 2016/07/14 10:19:05 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid.c,v 1.38 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: ata_raid.c,v
 #include <sys/malloc.h>
 #include <sys/vnode.h>
 #include <sys/proc.h>
+#include <sys/module.h>
 
 #include <miscfs/specfs/specdev.h>
 
@@ -74,16 +75,19 @@ __KERNEL_RCSID(0, "$NetBSD: ata_raid.c,v
 
 static int	ataraid_match(device_t, cfdata_t, void *);
 static void	ataraid_attach(device_t, device_t, void *);
+static int	ataraid_rescan(device_t, const char *, const int *);
 static int	ataraid_print(void *, const char *);
 
 static int	ata_raid_finalize(device_t);
 
+static int	finalize_done;
+
 ataraid_array_info_list_t ataraid_array_info_list =
     TAILQ_HEAD_INITIALIZER(ataraid_array_info_list);
 u_int ataraid_array_info_count;
 
-CFATTACH_DECL_NEW(ataraid, 0,
-    ataraid_match, ataraid_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(ataraid, 0,
+    ataraid_match, ataraid_attach, NULL, NULL, ataraid_rescan, NULL, 0);
 
 /*
  * ataraidattach:
@@ -98,12 +102,29 @@ ataraidattach(int count)
 	 * Register a finalizer which will be used to actually configure
 	 * the logical disks configured by ataraid.
 	 */
+	finalize_done = 0;
 	if (config_finalize_register(NULL, ata_raid_finalize) != 0)
 		aprint_normal("WARNING: "
 		    "unable to register ATA RAID finalizer\n");
 }
 
 /*
+ * Use the config_finalizer to rescan for new devices, since the
+ * ld_ataraid driver might not be immediately available.
+ */
+
+/* ARGSUSED */
+static int
+ataraid_rescan(device_t self, const char *attr, const int *flags)
+{
+
+	finalize_done = 0;
+	(void)ata_raid_finalize(self);
+
+	return 0;
+}
+
+/*
  * ata_raid_type_name:
  *
  *	Return the type of ATA RAID.
@@ -140,34 +161,23 @@ ata_raid_finalize(device_t self)
 		.cf_unit = 0,
 		.cf_fstate = FSTATE_STAR,
 	};
-	extern struct cfdriver ataraid_cd;
-	static int done_once;
-	int error;
 
 	/*
-	 * Since we only handle real hardware, we only need to be
-	 * called once.
+	 * Only run once for each instantiation
 	 */
-	if (done_once)
-		return (0);
-	done_once = 1;
+	if (finalize_done)
+		return 0;
+	finalize_done = 1;
 
 	if (TAILQ_EMPTY(&ataraid_array_info_list))
 		goto out;
 
-	error = config_cfattach_attach(ataraid_cd.cd_name, &ataraid_ca);
-	if (error) {
-		printf("%s: unable to register cfattach, error = %d\n",
-		    ataraid_cd.cd_name, error);
-		(void) config_cfdriver_detach(&ataraid_cd);
-		goto out;
-	}
-
 	if (config_attach_pseudo(&ataraid_cfdata) == NULL)
 		printf("%s: unable to attach an instance\n",
 		    ataraid_cd.cd_name);
 
  out:
+printf("%s: exit\n", __func__);
 	return (1);
 }
 
@@ -311,3 +321,58 @@ ata_raid_config_block_rw(struct vnode *v
 	putiobuf(bp);
 	return (error);
 }
+
+MODULE(MODULE_CLASS_DRIVER, ataraid, "");
+ 
+#ifdef _MODULE
+CFDRIVER_DECL(ataraid, DV_DISK, NULL);
+#endif
+ 
+static int
+ataraid_modcmd(modcmd_t cmd, void *arg)
+{
+        int error = 0; 
+   
+        switch (cmd) {
+        case MODULE_CMD_INIT:
+#ifdef _MODULE
+		error = config_cfdriver_attach(&ataraid_cd);
+		if (error) 
+			break;
+
+		error = config_cfattach_attach(ataraid_cd.cd_name, &ataraid_ca);
+		if (error) {
+			config_cfdriver_detach(&ataraid_cd);
+			aprint_error("%s: unable to register cfattach for \n"
+			    "%s, error %d", __func__, ataraid_cd.cd_name,
+			    error);
+			break;
+		}
+#endif
+		break;
+	case MODULE_CMD_FINI:
+#ifdef _MODULE
+
+		error = config_cfattach_detach(ataraid_cd.cd_name, &ataraid_ca);
+		if (error) {
+			aprint_error("%s: failed to detach %s cfattach, "
+			    "error %d\n", __func__, ataraid_cd.cd_name, error);
+			break;
+		}
+		error = config_cfdriver_detach(&ataraid_cd);
+		if (error) {
+			(void)config_cfattach_attach(ataraid_cd.cd_name,
+			    &ataraid_ca);
+			aprint_error("%s: failed to detach %s cfdriver, "
+			    "error %d\n", __func__, ataraid_cd.cd_name, error);
+			break;
+		}
+#endif
+		break;
+	case MODULE_CMD_STAT:
+	default:
+		error = ENOTTY;
+	}
+
+	return error;
+}

Index: src/sys/dev/ata/ld_ataraid.c
diff -u src/sys/dev/ata/ld_ataraid.c:1.42 src/sys/dev/ata/ld_ataraid.c:1.43
--- src/sys/dev/ata/ld_ataraid.c:1.42	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/ata/ld_ataraid.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_ataraid.c,v 1.42 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_ataraid.c,v 1.43 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -47,10 +47,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.42 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.43 2016/09/27 03:33:32 pgoyette Exp $");
 
+#if defined(_KERNEL_OPT)
 #include "bio.h"
-
+#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -66,6 +67,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c
 #include <sys/malloc.h>
 #include <sys/vnode.h>
 #include <sys/kauth.h>
+#include <sys/module.h>
 #if NBIO > 0
 #include <dev/ata/atavar.h>
 #include <dev/ata/atareg.h>
@@ -80,6 +82,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c
 
 #include <dev/ata/ata_raidvar.h>
 
+#include "ioconf.h"
+
 struct ld_ataraid_softc {
 	struct ld_softc sc_ld;
 
@@ -711,3 +715,47 @@ ld_ataraid_biodisk(struct ld_ataraid_sof
 	return 0;
 }
 #endif /* NBIO > 0 */
+
+MODULE(MODULE_CLASS_DRIVER, ld_ataraid, "ld,ataraid");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_ataraid"
+ * XXX it will be defined in the common-code module
+ */     
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif 
+  
+static int
+ld_ataraid_modcmd(modcmd_t cmd, void *opaque)
+{ 
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_ataraid, cfdata_ioconf_ld_ataraid);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_ataraid, cfdata_ioconf_ld_ataraid);
+		break;
+	default:
+		error = ENOTTY;
+	break;
+	}
+printf("%s: return %d\n", __func__, error);
+#endif
+
+	return error;
+}

Index: src/sys/dev/eisa/cac_eisa.c
diff -u src/sys/dev/eisa/cac_eisa.c:1.24 src/sys/dev/eisa/cac_eisa.c:1.25
--- src/sys/dev/eisa/cac_eisa.c:1.24	Thu Jul 14 10:19:06 2016
+++ src/sys/dev/eisa/cac_eisa.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: cac_eisa.c,v 1.24 2016/07/14 10:19:06 msaitoh Exp $	*/
+/*	$NetBSD: cac_eisa.c,v 1.25 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -61,12 +61,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cac_eisa.c,v 1.24 2016/07/14 10:19:06 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cac_eisa.c,v 1.25 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
-
+#include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/intr.h>
 
@@ -76,6 +76,8 @@ __KERNEL_RCSID(0, "$NetBSD: cac_eisa.c,v
 #include <dev/ic/cacreg.h>
 #include <dev/ic/cacvar.h>
 
+#include "ioconf.h"
+
 #define CAC_EISA_SLOT_OFFSET		0x0c88
 #define CAC_EISA_IOSIZE			0x0017
 #define CAC_EISA_IOCONF			0x38
@@ -89,8 +91,8 @@ static void	cac_eisa_l0_intr_enable(stru
 static int	cac_eisa_l0_intr_pending(struct cac_softc *);
 static void	cac_eisa_l0_submit(struct cac_softc *, struct cac_ccb *);
 
-CFATTACH_DECL_NEW(cac_eisa, sizeof(struct cac_softc),
-    cac_eisa_match, cac_eisa_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(cac_eisa, sizeof(struct cac_softc),
+    cac_eisa_match, cac_eisa_attach, NULL, NULL, cac_rescan, NULL, 0);
 
 static const struct cac_linkage cac_eisa_l0 = {
 	cac_eisa_l0_completed,
@@ -293,3 +295,44 @@ cac_eisa_l0_intr_enable(struct cac_softc
 	} else
 		cac_outb(sc, CAC_EISAREG_SYSTEM_MASK, CAC_INTR_DISABLE);
 }
+
+MODULE(MODULE_CLASS_DRIVER, cac_eisa, "cac");	/* No eisa module yet! */
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver cac_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+ 
+static int
+cac_eisa_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		/* 
+		 * We skip over the first entry in cfdriver[] array
+		 * since the cfdriver is attached by the common
+		 * (non-attachment-specific) code.
+		 */
+		error = config_init_component(&cfdriver_ioconf_cac_eisa[1],
+		    cfattach_ioconf_cac_eisa, cfdata_ioconf_cac_eisa);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(&cfdriver_ioconf_cac_eisa[1],  
+		    cfattach_ioconf_cac_eisa, cfdata_ioconf_cac_eisa);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/eisa/mlx_eisa.c
diff -u src/sys/dev/eisa/mlx_eisa.c:1.25 src/sys/dev/eisa/mlx_eisa.c:1.26
--- src/sys/dev/eisa/mlx_eisa.c:1.25	Thu Jul 14 10:19:06 2016
+++ src/sys/dev/eisa/mlx_eisa.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mlx_eisa.c,v 1.25 2016/07/14 10:19:06 msaitoh Exp $	*/
+/*	$NetBSD: mlx_eisa.c,v 1.26 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -34,12 +34,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mlx_eisa.c,v 1.25 2016/07/14 10:19:06 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mlx_eisa.c,v 1.26 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
-
+#include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/intr.h>
 
@@ -50,6 +50,8 @@ __KERNEL_RCSID(0, "$NetBSD: mlx_eisa.c,v
 #include <dev/ic/mlxio.h>
 #include <dev/ic/mlxvar.h>
 
+#include "ioconf.h"
+
 #define	MLX_EISA_SLOT_OFFSET		0x0c80
 #define	MLX_EISA_IOSIZE			(0x0ce0 - MLX_EISA_SLOT_OFFSET)
 #define	MLX_EISA_CFG01			(0x0cc0 - MLX_EISA_SLOT_OFFSET)
@@ -65,6 +67,7 @@ __KERNEL_RCSID(0, "$NetBSD: mlx_eisa.c,v
 
 static void	mlx_eisa_attach(device_t, device_t, void *);
 static int	mlx_eisa_match(device_t, cfdata_t, void *);
+static int	mlx_eisa_rescan(device_t, const char *, const int *);
 
 static int	mlx_v1_submit(struct mlx_softc *, struct mlx_ccb *);
 static int	mlx_v1_findcomplete(struct mlx_softc *, u_int *, u_int *);
@@ -74,8 +77,8 @@ static int	mlx_v1_fw_handshake(struct ml
 static int	mlx_v1_reset(struct mlx_softc *);
 #endif
 
-CFATTACH_DECL_NEW(mlx_eisa, sizeof(struct mlx_softc),
-    mlx_eisa_match, mlx_eisa_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(mlx_eisa, sizeof(struct mlx_softc),
+    mlx_eisa_match, mlx_eisa_attach, NULL, NULL, mlx_eisa_rescan, NULL, 0);
 
 static struct mlx_eisa_prod {
 	const char	*mp_idstr;
@@ -195,6 +198,13 @@ mlx_eisa_attach(device_t parent, device_
 	mlx_init(mlx, intrstr);
 }
 
+static int
+mlx_eisa_rescan(device_t self, const char *attr, const int *flag)
+{
+
+	return mlx_configure(device_private(self), 1);
+}
+
 /*
  * ================= V1 interface linkage =================
  */
@@ -353,3 +363,44 @@ mlx_v1_reset(struct mlx_softc *mlx)
 	return (0);
 }
 #endif	/* MLX_RESET */
+
+MODULE(MODULE_CLASS_DRIVER, mlx_eisa, "mlx");   /* No eisa module yet! */
+            
+#ifdef _MODULE
+/*              
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver cac_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif 
+
+static int
+mlx_eisa_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		/*
+		 * We skip over the first entry in cfdriver[] array
+		 * since the cfdriver is attached by the common
+		 * (non-attachment-specific) code.
+		 */
+		error = config_init_component(&cfdriver_ioconf_mlx_eisa[1],
+		    cfattach_ioconf_mlx_eisa, cfdata_ioconf_mlx_eisa);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(&cfdriver_ioconf_mlx_eisa[1],
+		    cfattach_ioconf_mlx_eisa, cfdata_ioconf_mlx_eisa);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/ic/aac.c
diff -u src/sys/dev/ic/aac.c:1.44 src/sys/dev/ic/aac.c:1.45
--- src/sys/dev/ic/aac.c:1.44	Sat Oct 27 17:18:18 2012
+++ src/sys/dev/ic/aac.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: aac.c,v 1.44 2012/10/27 17:18:18 chs Exp $	*/
+/*	$NetBSD: aac.c,v 1.45 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.44 2012/10/27 17:18:18 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.45 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -79,6 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.44
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/module.h>
 
 #include <sys/bus.h>
 
@@ -88,6 +89,8 @@ __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.44
 
 #include "locators.h"
 
+#include "ioconf.h"
+
 static int	aac_new_intr(void *);
 static int	aac_alloc_commands(struct aac_softc *);
 #ifdef notyet
@@ -147,9 +150,7 @@ extern struct	cfdriver aac_cd;
 int
 aac_attach(struct aac_softc *sc)
 {
-	struct aac_attach_args aaca;
-	int i, rv;
-	int locs[AACCF_NLOCS];
+	int rv;
 
 	SIMPLEQ_INIT(&sc->sc_ccb_free);
 	SIMPLEQ_INIT(&sc->sc_ccb_queue);
@@ -183,8 +184,27 @@ aac_attach(struct aac_softc *sc)
 	aac_describe_controller(sc);
 
 	/*
-	 * Attach devices.
+	 * Attach devices
+	 */
+	aac_devscan(sc);
+
+	/*
+	 * Enable interrupts, and register our shutdown hook.
 	 */
+	sc->sc_flags |= AAC_ONLINE;
+	AAC_UNMASK_INTERRUPTS(sc);
+	if (aac_sdh != NULL)
+		shutdownhook_establish(aac_shutdown, NULL);
+	return (0);
+}
+
+int
+aac_devscan(struct aac_softc *sc)
+{
+	struct aac_attach_args aaca;
+	int i;
+	int locs[AACCF_NLOCS];
+
 	for (i = 0; i < AAC_MAX_CONTAINERS; i++) {
 		if (!sc->sc_hdr[i].hd_present)
 			continue;
@@ -195,15 +215,7 @@ aac_attach(struct aac_softc *sc)
 		config_found_sm_loc(sc->sc_dv, "aac", locs, &aaca,
 				    aac_print, config_stdsubmatch);
 	}
-
-	/*
-	 * Enable interrupts, and register our shutdown hook.
-	 */
-	sc->sc_flags |= AAC_ONLINE;
-	AAC_UNMASK_INTERRUPTS(sc);
-	if (aac_sdh != NULL)
-		shutdownhook_establish(aac_shutdown, NULL);
-	return (0);
+	return 0;
 }
 
 static int
@@ -1750,3 +1762,33 @@ aac_print_fib(struct aac_softc *sc, stru
 	}
 }
 #endif /* AAC_DEBUG */
+
+MODULE(MODULE_CLASS_DRIVER, aac, "pci");
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+aac_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_aac,
+		    cfattach_ioconf_aac, cfdata_ioconf_aac);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(cfdriver_ioconf_aac,
+		    cfattach_ioconf_aac, cfdata_ioconf_aac);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/ic/aacvar.h
diff -u src/sys/dev/ic/aacvar.h:1.14 src/sys/dev/ic/aacvar.h:1.15
--- src/sys/dev/ic/aacvar.h:1.14	Sat Oct 27 17:18:18 2012
+++ src/sys/dev/ic/aacvar.h	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: aacvar.h,v 1.14 2012/10/27 17:18:18 chs Exp $	*/
+/*	$NetBSD: aacvar.h,v 1.15 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -347,6 +347,7 @@ struct aac_attach_args {
 };
 
 int	aac_attach(struct aac_softc *);
+int	aac_devscan(struct aac_softc *);
 void	aac_ccb_enqueue(struct aac_softc *, struct aac_ccb *);
 void	aac_ccb_free(struct aac_softc *, struct aac_ccb *);
 struct aac_ccb *aac_ccb_alloc(struct aac_softc *, int);

Index: src/sys/dev/ic/cac.c
diff -u src/sys/dev/ic/cac.c:1.56 src/sys/dev/ic/cac.c:1.57
--- src/sys/dev/ic/cac.c:1.56	Thu Jul  7 06:55:41 2016
+++ src/sys/dev/ic/cac.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: cac.c,v 1.56 2016/07/07 06:55:41 msaitoh Exp $	*/
+/*	$NetBSD: cac.c,v 1.57 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2006, 2007 The NetBSD Foundation, Inc.
@@ -34,9 +34,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cac.c,v 1.56 2016/07/07 06:55:41 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cac.c,v 1.57 2016/09/27 03:33:32 pgoyette Exp $");
 
+#if defined(_KERNEL_OPT)
 #include "bio.h"
+#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,7 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: cac.c,v 1.56
 #include <sys/endian.h>
 #include <sys/malloc.h>
 #include <sys/pool.h>
-
+#include <sys/module.h>
 #include <sys/bswap.h>
 #include <sys/bus.h>
 
@@ -99,11 +101,9 @@ int
 cac_init(struct cac_softc *sc, const char *intrstr, int startfw)
 {
 	struct cac_controller_info cinfo;
-	struct cac_attach_args caca;
 	int error, rseg, size, i;
 	bus_dma_segment_t seg;
 	struct cac_ccb *ccb;
-	int locs[CACCF_NLOCS];
 	char firm[8];
 
 	if (intrstr != NULL)
@@ -186,15 +186,14 @@ cac_init(struct cac_softc *sc, const cha
 	printf("%s: %d channels, firmware <%s>\n", device_xname(sc->sc_dev),
 	    cinfo.scsi_chips, firm);
 
+	/* Limit number of units to size of our sc_unitmask */
 	sc->sc_nunits = cinfo.num_drvs;
-	for (i = 0; i < cinfo.num_drvs; i++) {
-		caca.caca_unit = i;
+	if (sc->sc_nunits > sizeof(sc->sc_unitmask) * NBBY)
+		sc->sc_nunits = sizeof(sc->sc_unitmask) * NBBY;
 
-		locs[CACCF_UNIT] = i;
-
-		config_found_sm_loc(sc->sc_dev, "cac", locs, &caca,
-		    cac_print, config_stdsubmatch);
-	}
+	/* Attach our units */
+	sc->sc_unitmask = 0;
+	cac_rescan(sc->sc_dev, "cac", 0);
 
 	/* Set our `shutdownhook' before we start any device activity. */
 	if (cac_sdh == NULL)
@@ -216,6 +215,29 @@ cac_init(struct cac_softc *sc, const cha
 	return (0);
 }
 
+int
+cac_rescan(device_t self, const char *attr, const int *flags)
+{
+	struct cac_softc *sc;
+	struct cac_attach_args caca;
+	int locs[CACCF_NLOCS];
+	int i;
+
+	sc = device_private(self);
+	for (i = 0; i < sc->sc_nunits; i++) {
+		if (sc->sc_unitmask & (1 << i))
+			continue;
+		caca.caca_unit = i;
+
+		locs[CACCF_UNIT] = i;
+
+		if (config_found_sm_loc(self, attr, locs, &caca, cac_print,
+			    config_stdsubmatch))
+			sc->sc_unitmask |= 1 << i;
+	}
+	return 0;
+}
+
 /*
  * Shut down all `cac' controllers.
  */
@@ -729,3 +751,30 @@ cac_sensor_refresh(struct sysmon_envsys 
 	bio_vol_to_envsys(edata, &bv);
 }
 #endif /* NBIO > 0 */
+
+MODULE(MODULE_CLASS_DRIVER, cac, NULL);
+
+#ifdef _MODULE
+CFDRIVER_DECL(cac, DV_DISK, NULL);
+#endif
+
+static int
+cac_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_cfdriver_attach(&cac_cd);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_cfdriver_detach(&cac_cd);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+	return error;
+}

Index: src/sys/dev/ic/cacvar.h
diff -u src/sys/dev/ic/cacvar.h:1.20 src/sys/dev/ic/cacvar.h:1.21
--- src/sys/dev/ic/cacvar.h:1.20	Sat Oct 27 17:18:19 2012
+++ src/sys/dev/ic/cacvar.h	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: cacvar.h,v 1.20 2012/10/27 17:18:19 chs Exp $	*/
+/*	$NetBSD: cacvar.h,v 1.21 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -111,6 +111,7 @@ struct cac_softc {
 	bus_dma_tag_t		sc_dmat;
 	bus_dmamap_t		sc_dmamap;
 	int			sc_nunits;
+	uint64_t		sc_unitmask;
 	void			*sc_ih;
 	void *			sc_ccbs;
 	paddr_t			sc_ccbs_paddr;
@@ -138,6 +139,7 @@ struct cac_attach_args {
 int	cac_cmd(struct cac_softc *, int, void *, int, int, int, int,
 		struct cac_context *);
 int	cac_init(struct cac_softc *, const char *, int);
+int	cac_rescan(device_t, const char *, const int *);
 int	cac_intr(void *);
 
 extern const struct	cac_linkage cac_l0;

Index: src/sys/dev/ic/ld_aac.c
diff -u src/sys/dev/ic/ld_aac.c:1.29 src/sys/dev/ic/ld_aac.c:1.30
--- src/sys/dev/ic/ld_aac.c:1.29	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/ic/ld_aac.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_aac.c,v 1.29 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_aac.c,v 1.30 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_aac.c,v 1.29 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_aac.c,v 1.30 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_aac.c,v 1
 #include <sys/endian.h>
 #include <sys/dkio.h>
 #include <sys/disk.h>
+#include <sys/module.h>
 
 #include <sys/bus.h>
 
@@ -49,6 +50,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_aac.c,v 1
 #include <dev/ic/aacreg.h>
 #include <dev/ic/aacvar.h>
 
+#include "ioconf.h"
+
 struct ld_aac_softc {
 	struct	ld_softc sc_ld;
 	int	sc_hwunit;
@@ -360,3 +363,47 @@ ld_aac_dump(struct ld_softc *ld, void *d
 	return (ld_aac_dobio((struct ld_aac_softc *)ld, data,
 	    blkcnt * ld->sc_secsize, blkno, 1, NULL));
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_aac, "ld,aac");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c" 
+#endif
+
+static int
+ld_aac_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_aac, cfdata_ioconf_ld_aac);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_aac, cfdata_ioconf_ld_aac);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}
+
Index: src/sys/dev/ic/ld_cac.c
diff -u src/sys/dev/ic/ld_cac.c:1.29 src/sys/dev/ic/ld_cac.c:1.30
--- src/sys/dev/ic/ld_cac.c:1.29	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/ic/ld_cac.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_cac.c,v 1.29 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_cac.c,v 1.30 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2006 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1.29 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1.30 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -45,7 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1
 #include <sys/endian.h>
 #include <sys/dkio.h>
 #include <sys/disk.h>
-
+#include <sys/module.h>
 #include <sys/bus.h>
 
 #include <dev/ldvar.h>
@@ -53,6 +53,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1
 #include <dev/ic/cacreg.h>
 #include <dev/ic/cacvar.h>
 
+#include "ioconf.h"
+
 struct ld_cac_softc {
 	struct	ld_softc sc_ld;
 	kmutex_t *sc_mutex;
@@ -215,3 +217,46 @@ ld_cac_done(device_t dv, void *context, 
 	lddone(&sc->sc_ld, bp);
 	mutex_enter(sc->sc_mutex);
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_cac, "ld,cac");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+        
+static int
+ld_cac_modcmd(modcmd_t cmd, void *opaque)
+{               
+	int error = 0;
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_cac, cfdata_ioconf_ld_cac);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_cac, cfdata_ioconf_ld_cac);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/ic/ld_icp.c
diff -u src/sys/dev/ic/ld_icp.c:1.28 src/sys/dev/ic/ld_icp.c:1.29
--- src/sys/dev/ic/ld_icp.c:1.28	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/ic/ld_icp.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_icp.c,v 1.28 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_icp.c,v 1.29 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_icp.c,v 1.28 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_icp.c,v 1.29 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -45,7 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_icp.c,v 1
 #include <sys/endian.h>
 #include <sys/dkio.h>
 #include <sys/disk.h>
-
+#include <sys/module.h>
 #include <sys/bus.h>
 
 #include <dev/ldvar.h>
@@ -53,6 +53,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_icp.c,v 1
 #include <dev/ic/icpreg.h>
 #include <dev/ic/icpvar.h>
 
+#include "ioconf.h"
+
 struct ld_icp_softc {
 	struct	ld_softc sc_ld;
 	int	sc_hwunit;
@@ -325,3 +327,46 @@ ld_icp_adjqparam(device_t dv, int openin
 
 	ldadjqparam((struct ld_softc *) dv, openings);
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_icp, "ld");	/* no icp module yet */
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */     
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+        
+static int
+ld_icp_modcmd(modcmd_t cmd, void *opaque)
+{       
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+        
+#ifdef _MODULE 
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_icp, cfdata_ioconf_ld_icp);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_icp, cfdata_ioconf_ld_icp);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/ic/ld_mlx.c
diff -u src/sys/dev/ic/ld_mlx.c:1.22 src/sys/dev/ic/ld_mlx.c:1.23
--- src/sys/dev/ic/ld_mlx.c:1.22	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/ic/ld_mlx.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_mlx.c,v 1.22 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_mlx.c,v 1.23 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_mlx.c,v 1.22 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_mlx.c,v 1.23 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -45,7 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_mlx.c,v 1
 #include <sys/endian.h>
 #include <sys/dkio.h>
 #include <sys/disk.h>
-
+#include <sys/module.h>
 #include <machine/vmparam.h>
 #include <sys/bus.h>
 
@@ -55,6 +55,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_mlx.c,v 1
 #include <dev/ic/mlxio.h>
 #include <dev/ic/mlxvar.h>
 
+#include "ioconf.h"
+
 struct ld_mlx_softc {
 	struct	ld_softc sc_ld;
 	int	sc_hwunit;
@@ -248,3 +250,46 @@ ld_mlx_dump(struct ld_softc *ld, void *d
 	return (ld_mlx_dobio((struct ld_mlx_softc *)ld, data,
 	    blkcnt * ld->sc_secsize, blkno, 1, NULL));
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_mlx, "ld");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif   
+        
+static int  
+ld_mlx_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_mlx, cfdata_ioconf_ld_mlx);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_mlx, cfdata_ioconf_ld_mlx);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/ic/ld_nvme.c
diff -u src/sys/dev/ic/ld_nvme.c:1.7 src/sys/dev/ic/ld_nvme.c:1.8
--- src/sys/dev/ic/ld_nvme.c:1.7	Tue Sep 20 21:18:08 2016
+++ src/sys/dev/ic/ld_nvme.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_nvme.c,v 1.7 2016/09/20 21:18:08 jdolecek Exp $	*/
+/*	$NetBSD: ld_nvme.c,v 1.8 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (C) 2016 NONAKA Kimihiro <non...@netbsd.org>
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.7 2016/09/20 21:18:08 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.8 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -36,11 +36,14 @@ __KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 
 #include <sys/bufq.h>
 #include <sys/disk.h>
 #include <sys/kmem.h>
+#include <sys/module.h>
 
 #include <dev/ldvar.h>
 #include <dev/ic/nvmereg.h>
 #include <dev/ic/nvmevar.h>
 
+#include "ioconf.h"
+
 struct ld_nvme_softc {
 	struct ld_softc		sc_ld;
 	struct nvme_softc	*sc_nvme;
@@ -191,3 +194,46 @@ ld_nvme_syncdone(void *xc, struct buf *b
 {
 	/* nothing to do */
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_nvme, "ld,nvme");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef	CFDRIVER_DECL
+#define	CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+
+static int
+ld_nvme_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_nvme, cfdata_ioconf_ld_nvme);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_nvme, cfdata_ioconf_ld_nvme);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/ic/mlx.c
diff -u src/sys/dev/ic/mlx.c:1.64 src/sys/dev/ic/mlx.c:1.65
--- src/sys/dev/ic/mlx.c:1.64	Thu Jul 14 10:19:06 2016
+++ src/sys/dev/ic/mlx.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mlx.c,v 1.64 2016/07/14 10:19:06 msaitoh Exp $	*/
+/*	$NetBSD: mlx.c,v 1.65 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -67,9 +67,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mlx.c,v 1.64 2016/07/14 10:19:06 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mlx.c,v 1.65 2016/09/27 03:33:32 pgoyette Exp $");
 
+#if defined(_KERNEL_OPT)
 #include "ld.h"
+#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -85,7 +87,7 @@ __KERNEL_RCSID(0, "$NetBSD: mlx.c,v 1.64
 #include <sys/kthread.h>
 #include <sys/disk.h>
 #include <sys/kauth.h>
-
+#include <sys/module.h>
 #include <machine/vmparam.h>
 #include <sys/bus.h>
 
@@ -108,7 +110,6 @@ __KERNEL_RCSID(0, "$NetBSD: mlx.c,v 1.64
 static void	mlx_adjqparam(struct mlx_softc *, int, int);
 static int	mlx_ccb_submit(struct mlx_softc *, struct mlx_ccb *);
 static int	mlx_check(struct mlx_softc *, int);
-static void	mlx_configure(struct mlx_softc *, int);
 static void	mlx_describe(struct mlx_softc *);
 static void	*mlx_enquire(struct mlx_softc *, int, size_t,
 			     void (*)(struct mlx_ccb *), int);
@@ -551,7 +552,7 @@ mlx_describe(struct mlx_softc *mlx)
 /*
  * Locate disk resources and attach children to them.
  */
-static void
+int
 mlx_configure(struct mlx_softc *mlx, int waitok)
 {
 	struct mlx_enquiry *me;
@@ -638,6 +639,8 @@ mlx_configure(struct mlx_softc *mlx, int
 		    mlx->mlx_max_queuecnt % nunits);
  out:
  	mlx->mlx_flags &= ~MLXF_RESCANNING;
+
+	return 0;
 }
 
 /*
@@ -1687,11 +1690,12 @@ mlx_rebuild(struct mlx_softc *mlx, int c
 		goto out;
 
 	/* Command completed OK? */
-	aprint_normal_dev(mlx->mlx_dv, "");
 	if (mc->mc_status != 0)
-		printf("REBUILD ASYNC failed - %s\n", mlx_ccb_diagnose(mc));
+		aprint_normal_dev(mlx->mlx_dv, "REBUILD ASYNC failed - %s\n",
+		    mlx_ccb_diagnose(mc));
 	else
-		printf("rebuild started for %d:%d\n", channel, target);
+		aprint_normal_dev(mlx->mlx_dv, "rebuild started for %d:%d\n",
+		    channel, target);
 
 	error = mc->mc_status;
 
@@ -2210,9 +2214,35 @@ mlx_fw_message(struct mlx_softc *mlx, in
 		return (0);
 	}
 
-	aprint_normal_dev(mlx->mlx_dv, "");
-	aprint_normal(fmt, param2, param1);
+	aprint_normal_dev(mlx->mlx_dv, fmt, param2, param1);
 	aprint_normal("\n");
 
 	return (0);
 }
+
+MODULE(MODULE_CLASS_DRIVER, mlx, NULL);
+                
+#ifdef _MODULE
+CFDRIVER_DECL(cac, DV_DISK, NULL);
+#endif  
+        
+static int
+mlx_modcmd(modcmd_t cmd, void *opaque)
+{       
+	int error = 0;
+                
+#ifdef _MODULE      
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_cfdriver_attach(&mlx_cd);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_cfdriver_detach(&mlx_cd);
+		break;      
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+	return error;
+}

Index: src/sys/dev/ic/mlxvar.h
diff -u src/sys/dev/ic/mlxvar.h:1.15 src/sys/dev/ic/mlxvar.h:1.16
--- src/sys/dev/ic/mlxvar.h:1.15	Sat Oct 27 17:18:22 2012
+++ src/sys/dev/ic/mlxvar.h	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mlxvar.h,v 1.15 2012/10/27 17:18:22 chs Exp $	*/
+/*	$NetBSD: mlxvar.h,v 1.16 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -177,6 +177,7 @@ struct mlx_attach_args {
 int	mlx_flush(struct mlx_softc *, int);
 void	mlx_init(struct mlx_softc *, const char *);
 int	mlx_intr(void *);
+int	mlx_configure(struct mlx_softc *, int);
 
 int	mlx_ccb_alloc(struct mlx_softc *, struct mlx_ccb **, int);
 const char *mlx_ccb_diagnose(struct mlx_ccb *);

Index: src/sys/dev/ic/nvme.c
diff -u src/sys/dev/ic/nvme.c:1.13 src/sys/dev/ic/nvme.c:1.14
--- src/sys/dev/ic/nvme.c:1.13	Tue Sep 20 21:18:08 2016
+++ src/sys/dev/ic/nvme.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvme.c,v 1.13 2016/09/20 21:18:08 jdolecek Exp $	*/
+/*	$NetBSD: nvme.c,v 1.14 2016/09/27 03:33:32 pgoyette Exp $	*/
 /*	$OpenBSD: nvme.c,v 1.49 2016/04/18 05:59:50 dlg Exp $ */
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.13 2016/09/20 21:18:08 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.14 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -331,7 +331,6 @@ nvme_disable(struct nvme_softc *sc)
 int
 nvme_attach(struct nvme_softc *sc)
 {
-	struct nvme_attach_args naa;
 	uint64_t cap;
 	uint32_t reg;
 	u_int dstrd;
@@ -424,13 +423,7 @@ nvme_attach(struct nvme_softc *sc)
 	    KM_SLEEP);
 	if (sc->sc_namespaces == NULL)
 		goto free_q;
-	for (i = 0; i < sc->sc_nn; i++) {
-		memset(&naa, 0, sizeof(naa));
-		naa.naa_nsid = i + 1;
-		naa.naa_qentries = ioq_entries;
-		sc->sc_namespaces[i].dev = config_found(sc->sc_dev, &naa,
-		    nvme_print);
-	}
+	nvme_rescan(sc->sc_dev, "nvme", &i);
 
 	return 0;
 
@@ -449,6 +442,25 @@ free_admin_q:
 	return 1;
 }
 
+int
+nvme_rescan(device_t self, const char *attr, const int *flags)
+{
+	int i;
+	struct nvme_softc *sc = device_private(self);
+	struct nvme_attach_args naa;
+
+	for (i = 0; i < sc->sc_nn; i++) {
+		if (sc->sc_namespaces[i].dev)
+			continue;
+		memset(&naa, 0, sizeof(naa));
+		naa.naa_nsid = i + 1;
+		naa.naa_qentries = nvme_ioq_size;
+		sc->sc_namespaces[i].dev = config_found(sc->sc_dev, &naa,
+		    nvme_print);
+	}
+	return 0;
+}
+
 static int
 nvme_print(void *aux, const char *pnp)
 {

Index: src/sys/dev/ic/nvmevar.h
diff -u src/sys/dev/ic/nvmevar.h:1.5 src/sys/dev/ic/nvmevar.h:1.6
--- src/sys/dev/ic/nvmevar.h:1.5	Mon Sep 19 22:11:41 2016
+++ src/sys/dev/ic/nvmevar.h	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmevar.h,v 1.5 2016/09/19 22:11:41 jdolecek Exp $	*/
+/*	$NetBSD: nvmevar.h,v 1.6 2016/09/27 03:33:32 pgoyette Exp $	*/
 /*	$OpenBSD: nvmevar.h,v 1.8 2016/04/14 11:18:32 dlg Exp $ */
 
 /*
@@ -148,6 +148,7 @@ struct nvme_attach_args {
 
 int	nvme_attach(struct nvme_softc *);
 int	nvme_detach(struct nvme_softc *, int flags);
+int	nvme_rescan(device_t, const char *, const int *);
 void	nvme_childdet(device_t, device_t);
 int	nvme_intr(void *);
 int	nvme_intr_msi(void *);

Index: src/sys/dev/pci/aac_pci.c
diff -u src/sys/dev/pci/aac_pci.c:1.37 src/sys/dev/pci/aac_pci.c:1.38
--- src/sys/dev/pci/aac_pci.c:1.37	Thu Jul  7 06:55:41 2016
+++ src/sys/dev/pci/aac_pci.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: aac_pci.c,v 1.37 2016/07/07 06:55:41 msaitoh Exp $	*/
+/*	$NetBSD: aac_pci.c,v 1.38 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: aac_pci.c,v 1.37 2016/07/07 06:55:41 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: aac_pci.c,v 1.38 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -598,8 +598,16 @@ aac_pci_attach(device_t parent, device_t
 		bus_space_unmap(sc->sc_memt, sc->sc_memh, memsize);
 }
 
-CFATTACH_DECL_NEW(aac_pci, sizeof(struct aac_pci_softc),
-    aac_pci_match, aac_pci_attach, NULL, NULL);
+/* ARGSUSED */
+static int
+aac_pci_rescan(device_t self, const char *attr, const int *flags)
+{
+
+	return aac_devscan(device_private(self));
+}
+
+CFATTACH_DECL3_NEW(aac_pci, sizeof(struct aac_pci_softc),
+    aac_pci_match, aac_pci_attach, NULL, NULL, aac_pci_rescan, NULL, 0);
 
 /*
  * Read the current firmware status word.

Index: src/sys/dev/pci/amr.c
diff -u src/sys/dev/pci/amr.c:1.61 src/sys/dev/pci/amr.c:1.62
--- src/sys/dev/pci/amr.c:1.61	Thu Jul 14 04:19:27 2016
+++ src/sys/dev/pci/amr.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: amr.c,v 1.61 2016/07/14 04:19:27 msaitoh Exp $	*/
+/*	$NetBSD: amr.c,v 1.62 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amr.c,v 1.61 2016/07/14 04:19:27 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amr.c,v 1.62 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -79,6 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: amr.c,v 1.61
 #include <sys/kauth.h>
 #include <sys/mutex.h>
 #include <sys/condvar.h>
+#include <sys/module.h>
 
 #include <machine/endian.h>
 #include <sys/bus.h>
@@ -91,6 +92,8 @@ __KERNEL_RCSID(0, "$NetBSD: amr.c,v 1.61
 
 #include "locators.h"
 
+#include "ioconf.h"
+
 static void	amr_attach(device_t, device_t, void *);
 static void	amr_ccb_dump(struct amr_softc *, struct amr_ccb *);
 static void	*amr_enquire(struct amr_softc *, u_int8_t, u_int8_t, u_int8_t,
@@ -99,6 +102,7 @@ static int	amr_init(struct amr_softc *, 
 			 struct pci_attach_args *pa);
 static int	amr_intr(void *);
 static int	amr_match(device_t, cfdata_t, void *);
+static int	amr_rescan(device_t, const char *, const int *);
 static int	amr_print(void *, const char *);
 static void	amr_shutdown(void *);
 static void	amr_teardown(struct amr_softc *);
@@ -115,8 +119,8 @@ static dev_type_open(amropen);
 static dev_type_close(amrclose);
 static dev_type_ioctl(amrioctl);
 
-CFATTACH_DECL_NEW(amr, sizeof(struct amr_softc),
-    amr_match, amr_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(amr, sizeof(struct amr_softc),
+    amr_match, amr_attach, NULL, NULL, amr_rescan, NULL, 0);
 
 const struct cdevsw amr_cdevsw = {
 	.d_open = amropen,
@@ -268,16 +272,14 @@ static void
 amr_attach(device_t parent, device_t self, void *aux)
 {
 	struct pci_attach_args *pa;
-	struct amr_attach_args amra;
 	const struct amr_pci_type *apt;
 	struct amr_softc *amr;
 	pci_chipset_tag_t pc;
 	pci_intr_handle_t ih;
 	const char *intrstr;
 	pcireg_t reg;
-	int rseg, i, j, size, rv, memreg, ioreg;
+	int rseg, i, size, rv, memreg, ioreg;
 	struct amr_ccb *ac;
-	int locs[AMRCF_NLOCS];
 	char intrbuf[PCI_INTRSTR_LEN];
 
 	aprint_naive(": RAID controller\n");
@@ -484,16 +486,7 @@ amr_attach(device_t parent, device_t sel
 		amr_sdh = shutdownhook_establish(amr_shutdown, NULL);
 
 	/* Attach sub-devices. */
-	for (j = 0; j < amr->amr_numdrives; j++) {
-		if (amr->amr_drive[j].al_size == 0)
-			continue;
-		amra.amra_unit = j;
-
-		locs[AMRCF_UNIT] = j;
-
-		amr->amr_drive[j].al_dv = config_found_sm_loc(amr->amr_dv,
-			"amr", locs, &amra, amr_print, config_stdsubmatch);
-	}
+	amr_rescan(self, "amr", 0);
 
 	SIMPLEQ_INIT(&amr->amr_ccb_queue);
 
@@ -516,6 +509,30 @@ amr_attach(device_t parent, device_t sel
  		amr->amr_flags |= AMRF_THREAD;
 }
 
+static int
+amr_rescan(device_t self, const char *attr, const int *flags)
+{
+	int j;
+	int locs[AMRCF_NLOCS];
+	struct amr_attach_args amra;
+	struct amr_softc *amr;
+
+	amr = device_private(self);
+	for (j = 0; j < amr->amr_numdrives; j++) {
+		if (amr->amr_drive[j].al_dv)
+			continue;
+		if (amr->amr_drive[j].al_size == 0)
+			continue;
+		amra.amra_unit = j;
+
+		locs[AMRCF_UNIT] = j;
+
+		amr->amr_drive[j].al_dv = config_found_sm_loc(amr->amr_dv,
+			attr, locs, &amra, amr_print, config_stdsubmatch);
+	}
+	return 0;
+}
+
 /*
  * Free up resources.
  */
@@ -1535,3 +1552,34 @@ out:
 	free(dp, M_DEVBUF);
 	return (error);
 }
+
+MODULE(MODULE_CLASS_DRIVER, amr, "pci");
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+amr_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_amr,
+		    cfattach_ioconf_amr, cfdata_ioconf_amr);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(cfdriver_ioconf_amr,
+		    cfattach_ioconf_amr, cfdata_ioconf_amr);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}
+

Index: src/sys/dev/pci/cac_pci.c
diff -u src/sys/dev/pci/cac_pci.c:1.34 src/sys/dev/pci/cac_pci.c:1.35
--- src/sys/dev/pci/cac_pci.c:1.34	Sat Mar 29 19:28:24 2014
+++ src/sys/dev/pci/cac_pci.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: cac_pci.c,v 1.34 2014/03/29 19:28:24 christos Exp $	*/
+/*	$NetBSD: cac_pci.c,v 1.35 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -34,13 +34,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cac_pci.c,v 1.34 2014/03/29 19:28:24 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cac_pci.c,v 1.35 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/device.h>
 #include <sys/queue.h>
+#include <sys/module.h>
 
 #include <machine/endian.h>
 #include <sys/bus.h>
@@ -51,6 +52,8 @@ __KERNEL_RCSID(0, "$NetBSD: cac_pci.c,v 
 #include <dev/ic/cacreg.h>
 #include <dev/ic/cacvar.h>
 
+#include "ioconf.h"
+
 static struct	cac_ccb *cac_pci_l0_completed(struct cac_softc *);
 static int	cac_pci_l0_fifo_full(struct cac_softc *);
 static void	cac_pci_l0_intr_enable(struct cac_softc *, int);
@@ -220,8 +223,8 @@ cac_pci_attach(device_t parent, device_t
 	cac_init(sc, intrstr, (ct->ct_flags & CT_STARTFW) != 0);
 }
 
-CFATTACH_DECL_NEW(cac_pci, sizeof(struct cac_softc),
-    cac_pci_match, cac_pci_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(cac_pci, sizeof(struct cac_softc),
+    cac_pci_match, cac_pci_attach, NULL, NULL, cac_rescan, NULL, 0);
 
 static void
 cac_pci_l0_submit(struct cac_softc *sc, struct cac_ccb *ccb)
@@ -280,3 +283,44 @@ cac_pci_l0_fifo_full(struct cac_softc *s
 
 	return (cac_inl(sc, CAC_42REG_CMD_FIFO) != 0);
 }
+
+MODULE(MODULE_CLASS_DRIVER, cac_pci, "cac,pci");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+ 
+static int
+cac_pci_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		/* 
+		 * We skip over the first entry in cfdriver[] array
+		 * since the cfdriver is attached by the common
+		 * (non-attachment-specific) code.
+		 */
+		error = config_init_component(&cfdriver_ioconf_cac_pci[1],
+		    cfattach_ioconf_cac_pci, cfdata_ioconf_cac_pci);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(&cfdriver_ioconf_cac_pci[1],  
+		    cfattach_ioconf_cac_pci, cfdata_ioconf_cac_pci);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/pci/icp_pci.c
diff -u src/sys/dev/pci/icp_pci.c:1.22 src/sys/dev/pci/icp_pci.c:1.23
--- src/sys/dev/pci/icp_pci.c:1.22	Sat Mar 29 19:28:24 2014
+++ src/sys/dev/pci/icp_pci.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: icp_pci.c,v 1.22 2014/03/29 19:28:24 christos Exp $	*/
+/*	$NetBSD: icp_pci.c,v 1.23 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icp_pci.c,v 1.22 2014/03/29 19:28:24 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icp_pci.c,v 1.23 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -157,6 +157,7 @@ __KERNEL_RCSID(0, "$NetBSD: icp_pci.c,v 
 
 int	icp_pci_match(device_t, cfdata_t, void *);
 void	icp_pci_attach(device_t, device_t, void *);
+int	icp_pci_rescan(device_t, const char *, const int *);
 void	icp_pci_enable_intr(struct icp_softc *);
 int	icp_pci_find_class(struct pci_attach_args *);
 
@@ -181,8 +182,8 @@ void	icp_mpr_release_event(struct icp_so
 void	icp_mpr_set_sema0(struct icp_softc *);
 int	icp_mpr_test_busy(struct icp_softc *);
 
-CFATTACH_DECL_NEW(icp_pci, sizeof(struct icp_softc),
-    icp_pci_match, icp_pci_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(icp_pci, sizeof(struct icp_softc),
+    icp_pci_match, icp_pci_attach, NULL, NULL, icp_pci_rescan, NULL, 0);
 
 struct icp_pci_ident {
 	u_short	gpi_vendor;
@@ -587,6 +588,14 @@ icp_pci_attach(device_t parent, device_t
 		pci_intr_disestablish(pa->pa_pc, icp->icp_ih);
 }
 
+int
+icp_pci_rescan(device_t self, const char *attr, const int *flags)
+{
+
+	icp_rescan_all(device_private(self));
+	return 0;
+}
+
 /*
  * Enable interrupts.
  */

Index: src/sys/dev/pci/if_vioif.c
diff -u src/sys/dev/pci/if_vioif.c:1.25 src/sys/dev/pci/if_vioif.c:1.26
--- src/sys/dev/pci/if_vioif.c:1.25	Mon Aug 29 04:21:25 2016
+++ src/sys/dev/pci/if_vioif.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vioif.c,v 1.25 2016/08/29 04:21:25 ozaki-r Exp $	*/
+/*	$NetBSD: if_vioif.c,v 1.26 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.25 2016/08/29 04:21:25 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.26 2016/09/27 03:33:32 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v
 #include <sys/mutex.h>
 #include <sys/sockio.h>
 #include <sys/cpu.h>
+#include <sys/module.h>
 
 #include <dev/pci/pcidevs.h>
 #include <dev/pci/pcireg.h>
@@ -57,6 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v
 
 #include <net/bpf.h>
 
+#include "ioconf.h"
 
 #ifdef NET_MPSAFE
 #define VIOIF_MPSAFE	1
@@ -1511,3 +1513,33 @@ vioif_updown(struct vioif_softc *sc, boo
 				     isup?VIRTIO_NET_S_LINK_UP:0);
 	return 0;
 }
+
+MODULE(MODULE_CLASS_DRIVER, if_vioif, "virtio");
+ 
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+ 
+static int 
+if_vioif_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_if_vioif, 
+		    cfattach_ioconf_if_vioif, cfdata_ioconf_if_vioif); 
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(cfdriver_ioconf_if_vioif,
+		    cfattach_ioconf_if_vioif, cfdata_ioconf_if_vioif);
+		break;
+	default:
+		error = ENOTTY;
+		break; 
+	}
+#endif
+   
+	return error;
+}
Index: src/sys/dev/pci/mlx_pci.c
diff -u src/sys/dev/pci/mlx_pci.c:1.25 src/sys/dev/pci/mlx_pci.c:1.26
--- src/sys/dev/pci/mlx_pci.c:1.25	Sat Mar 29 19:28:25 2014
+++ src/sys/dev/pci/mlx_pci.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mlx_pci.c,v 1.25 2014/03/29 19:28:25 christos Exp $	*/
+/*	$NetBSD: mlx_pci.c,v 1.26 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mlx_pci.c,v 1.25 2014/03/29 19:28:25 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mlx_pci.c,v 1.26 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -70,6 +70,7 @@ __KERNEL_RCSID(0, "$NetBSD: mlx_pci.c,v 
 #include <sys/device.h>
 #include <sys/queue.h>
 #include <sys/callout.h>
+#include <sys/module.h>
 
 #include <machine/endian.h>
 #include <sys/bus.h>
@@ -82,6 +83,8 @@ __KERNEL_RCSID(0, "$NetBSD: mlx_pci.c,v 
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcidevs.h>
 
+#include "ioconf.h"
+
 static void	mlx_pci_attach(device_t, device_t, void *);
 static int	mlx_pci_match(device_t, cfdata_t, void *);
 static const struct mlx_pci_ident *mlx_pci_findmpi(struct pci_attach_args *);
@@ -141,8 +144,15 @@ static struct mlx_pci_ident {
 	},
 };
 
-CFATTACH_DECL_NEW(mlx_pci, sizeof(struct mlx_softc),
-    mlx_pci_match, mlx_pci_attach, NULL, NULL);
+static int
+mlx_pci_rescan(device_t self, const char *attr, const int *flag)
+{
+
+	return mlx_configure(device_private(self), 1);
+}
+
+CFATTACH_DECL3_NEW(mlx_pci, sizeof(struct mlx_softc),
+    mlx_pci_match, mlx_pci_attach, NULL, NULL, mlx_pci_rescan, NULL, 0);
 
 /*
  * Try to find a `mlx_pci_ident' entry corresponding to this board.
@@ -671,3 +681,44 @@ mlx_v5_fw_handshake(struct mlx_softc *ml
 
 	return (2);
 }
+
+MODULE(MODULE_CLASS_DRIVER, mlx_pci, "mlx,pci");
+        
+#ifdef _MODULE
+/*      
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */     
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"  
+#endif  
+        
+static int
+mlx_pci_modcmd(modcmd_t cmd, void *opaque)
+{           
+	int error = 0;
+ 
+#ifdef _MODULE  
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		/*
+		 * We skip over the first entry in cfdriver[] array
+		 * since the cfdriver is attached by the common
+		 * (non-attachment-specific) code.
+		 */
+		error = config_init_component(&cfdriver_ioconf_mlx_pci[1],
+		    cfattach_ioconf_mlx_pci, cfdata_ioconf_mlx_pci);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(&cfdriver_ioconf_mlx_pci[1],
+		    cfattach_ioconf_mlx_pci, cfdata_ioconf_mlx_pci);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/pci/ld_amr.c
diff -u src/sys/dev/pci/ld_amr.c:1.24 src/sys/dev/pci/ld_amr.c:1.25
--- src/sys/dev/pci/ld_amr.c:1.24	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/pci/ld_amr.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_amr.c,v 1.24 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_amr.c,v 1.25 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_amr.c,v 1.24 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_amr.c,v 1.25 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_amr.c,v 1
 #include <sys/endian.h>
 #include <sys/dkio.h>
 #include <sys/disk.h>
+#include <sys/module.h>
 
 #include <sys/bus.h>
 
@@ -55,6 +56,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_amr.c,v 1
 #include <dev/pci/amrreg.h>
 #include <dev/pci/amrvar.h>
 
+#include "ioconf.h"
+
 struct ld_amr_softc {
 	struct	ld_softc sc_ld;
 	int	sc_hwunit;
@@ -201,3 +204,46 @@ ld_amr_dump(struct ld_softc *ld, void *d
 	return (ld_amr_dobio(sc, data, blkcnt * ld->sc_secsize, blkno, 1,
 	    NULL));
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_amr, "ld,amr");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+
+static int
+ld_amr_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_amr, cfdata_ioconf_ld_amr);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_amr, cfdata_ioconf_ld_amr);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/pci/ld_twa.c
diff -u src/sys/dev/pci/ld_twa.c:1.18 src/sys/dev/pci/ld_twa.c:1.19
--- src/sys/dev/pci/ld_twa.c:1.18	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/pci/ld_twa.c	Tue Sep 27 03:33:32 2016
@@ -1,5 +1,5 @@
 /*	$wasabi: ld_twa.c,v 1.9 2006/02/14 18:44:37 jordanr Exp $	*/
-/*	$NetBSD: ld_twa.c,v 1.18 2016/09/16 15:20:50 jdolecek Exp $ */
+/*	$NetBSD: ld_twa.c,v 1.19 2016/09/27 03:33:32 pgoyette Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001, 2002, 2003, 2004 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_twa.c,v 1.18 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_twa.c,v 1.19 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,7 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_twa.c,v 1
 #include <sys/dkio.h>
 #include <sys/disk.h>
 #include <sys/proc.h>
-
+#include <sys/module.h>
 #include <sys/bus.h>
 
 #include <dev/ldvar.h>
@@ -64,6 +64,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_twa.c,v 1
 #include <dev/pci/twareg.h>
 #include <dev/pci/twavar.h>
 
+#include "ioconf.h"
+
 struct ld_twa_softc {
 	struct	ld_softc sc_ld;
 	int	sc_hwunit;
@@ -306,3 +308,46 @@ ld_twa_scsicmd(struct ld_twa_softc *sc,
 
 	return (0);
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_twa, "ld,twa");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL 
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+
+static int
+ld_twa_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_twa, cfdata_ioconf_ld_twa);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_twa, cfdata_ioconf_ld_twa);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/pci/ld_twe.c
diff -u src/sys/dev/pci/ld_twe.c:1.38 src/sys/dev/pci/ld_twe.c:1.39
--- src/sys/dev/pci/ld_twe.c:1.38	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/pci/ld_twe.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_twe.c,v 1.38 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_twe.c,v 1.39 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1.38 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1.39 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,7 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1
 #include <sys/dkio.h>
 #include <sys/disk.h>
 #include <sys/proc.h>
-
+#include <sys/module.h>
 #include <sys/bus.h>
 
 #include <dev/ldvar.h>
@@ -54,6 +54,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1
 #include <dev/pci/twereg.h>
 #include <dev/pci/twevar.h>
 
+#include "ioconf.h"
+
 struct ld_twe_softc {
 	struct	ld_softc sc_ld;
 	int	sc_hwunit;
@@ -321,3 +323,46 @@ ld_twe_adjqparam(device_t self, int open
 
 	ldadjqparam(ld, openings);
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_twe, "ld,twe");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL 
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+
+static int
+ld_twe_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_twe, cfdata_ioconf_ld_twe);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_twe, cfdata_ioconf_ld_twe);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/pci/ld_virtio.c
diff -u src/sys/dev/pci/ld_virtio.c:1.11 src/sys/dev/pci/ld_virtio.c:1.12
--- src/sys/dev/pci/ld_virtio.c:1.11	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/pci/ld_virtio.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_virtio.c,v 1.11 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_virtio.c,v 1.12 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.11 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.12 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,
 #include <sys/device.h>
 #include <sys/disk.h>
 #include <sys/mutex.h>
+#include <sys/module.h>
 
 #include <dev/pci/pcidevs.h>
 #include <dev/pci/pcireg.h>
@@ -46,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,
 #include <dev/pci/virtioreg.h>
 #include <dev/pci/virtiovar.h>
 
+#include "ioconf.h"
+
 /*
  * ld_virtioreg:
  */
@@ -604,3 +607,46 @@ ld_virtio_detach(device_t self, int flag
 
 	return 0;
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_virtio, "ld,virtio");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"
+#endif
+ 
+static int
+ld_virtio_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_virtio, cfdata_ioconf_ld_virtio);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_virtio, cfdata_ioconf_ld_virtio);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Index: src/sys/dev/pci/nvme_pci.c
diff -u src/sys/dev/pci/nvme_pci.c:1.14 src/sys/dev/pci/nvme_pci.c:1.15
--- src/sys/dev/pci/nvme_pci.c:1.14	Sun Sep 18 21:19:39 2016
+++ src/sys/dev/pci/nvme_pci.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvme_pci.c,v 1.14 2016/09/18 21:19:39 jdolecek Exp $	*/
+/*	$NetBSD: nvme_pci.c,v 1.15 2016/09/27 03:33:32 pgoyette Exp $	*/
 /*	$OpenBSD: nvme_pci.c,v 1.3 2016/04/14 11:18:32 dlg Exp $ */
 
 /*
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvme_pci.c,v 1.14 2016/09/18 21:19:39 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvme_pci.c,v 1.15 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -87,9 +87,10 @@ struct nvme_pci_softc {
 static int	nvme_pci_match(device_t, cfdata_t, void *);
 static void	nvme_pci_attach(device_t, device_t, void *);
 static int	nvme_pci_detach(device_t, int);
+static int	nvme_pci_rescan(device_t, const char *, const int *);
 
 CFATTACH_DECL3_NEW(nvme_pci, sizeof(struct nvme_pci_softc),
-    nvme_pci_match, nvme_pci_attach, nvme_pci_detach, NULL, NULL,
+    nvme_pci_match, nvme_pci_attach, nvme_pci_detach, NULL, nvme_pci_rescan,
     nvme_childdet, DVF_DETACH_SHUTDOWN);
 
 static int	nvme_pci_intr_establish(struct nvme_softc *,
@@ -230,6 +231,13 @@ unmap:
 }
 
 static int
+nvme_pci_rescan(device_t self, const char *attr, const int *flags)
+{
+
+	return nvme_rescan(self, attr, flags);
+}
+
+static int
 nvme_pci_detach(device_t self, int flags)
 {
 	struct nvme_pci_softc *psc = device_private(self);
@@ -514,31 +522,17 @@ nvme_modcmd(modcmd_t cmd, void *opaque)
 {
 #ifdef _MODULE
 	devmajor_t cmajor, bmajor;
-	extern const struct bdevsw ld_bdevsw;
-	extern const struct cdevsw ld_cdevsw;
 	extern const struct cdevsw nvme_cdevsw;
 #endif
 	int error = 0;
 
+#ifdef _MODULE
 	switch (cmd) {
 	case MODULE_CMD_INIT:
-#ifdef _MODULE
-		/* devsw must be done before configuring the actual device,
-		 * otherwise ldattach() fails
-		 */
-		bmajor = cmajor = NODEVMAJOR;
-		error = devsw_attach(ld_cd.cd_name, &ld_bdevsw, &bmajor,
-		    &ld_cdevsw, &cmajor);
-		if (error) {
-			aprint_error("%s: unable to register devsw\n",
-			    ld_cd.cd_name);
-			return error;
-		}
-
 		error = config_init_component(cfdriver_ioconf_nvme_pci,
 		    cfattach_ioconf_nvme_pci, cfdata_ioconf_nvme_pci);
 		if (error)
-			return error;
+			break;
 
 		bmajor = cmajor = NODEVMAJOR;
 		error = devsw_attach(nvme_cd.cd_name, NULL, &bmajor,
@@ -548,21 +542,16 @@ nvme_modcmd(modcmd_t cmd, void *opaque)
 			    nvme_cd.cd_name);
 			/* do not abort, just /dev/nvme* will not work */
 		}
-#endif
-		return error;
+		break;
 	case MODULE_CMD_FINI:
-#ifdef _MODULE
 		devsw_detach(NULL, &nvme_cdevsw);
 
 		error = config_fini_component(cfdriver_ioconf_nvme_pci,
 		    cfattach_ioconf_nvme_pci, cfdata_ioconf_nvme_pci);
-		if (error)
-			return error;
-
-		devsw_detach(&ld_bdevsw, &ld_cdevsw);
-#endif
-		return error;
+		break;
 	default:
-		return ENOTTY;
+		break;
 	}
+#endif
+	return error;
 }

Index: src/sys/dev/pci/twa.c
diff -u src/sys/dev/pci/twa.c:1.53 src/sys/dev/pci/twa.c:1.54
--- src/sys/dev/pci/twa.c:1.53	Thu Jul  7 06:55:41 2016
+++ src/sys/dev/pci/twa.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: twa.c,v 1.53 2016/07/07 06:55:41 msaitoh Exp $ */
+/*	$NetBSD: twa.c,v 1.54 2016/09/27 03:33:32 pgoyette Exp $ */
 /*	$wasabi: twa.c,v 1.27 2006/07/28 18:17:21 wrstuden Exp $	*/
 
 /*-
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: twa.c,v 1.53 2016/07/07 06:55:41 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: twa.c,v 1.54 2016/09/27 03:33:32 pgoyette Exp $");
 
 //#define TWA_DEBUG
 
@@ -86,7 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: twa.c,v 1.53
 #include <sys/disk.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
-
+#include <sys/module.h>
 #include <sys/bus.h>
 
 #include <dev/pci/pcireg.h>
@@ -104,6 +104,7 @@ __KERNEL_RCSID(0, "$NetBSD: twa.c,v 1.53
 #include <dev/ldvar.h>
 
 #include "locators.h"
+#include "ioconf.h"
 
 #define	PCI_CBIO	0x10
 
@@ -114,6 +115,7 @@ static uint16_t	twa_enqueue_aen(struct t
 			struct twa_command_header *);
 
 static void	twa_attach(device_t, device_t, void *);
+static int	twa_request_bus_scan(device_t, const char *, const int *);
 static void	twa_shutdown(void *);
 static int	twa_init_connection(struct twa_softc *, uint16_t, uint32_t,
 					uint16_t, uint16_t, uint16_t, uint16_t,
@@ -140,8 +142,8 @@ extern struct	cfdriver twa_cd;
 extern uint32_t twa_fw_img_size;
 extern uint8_t	twa_fw_img[];
 
-CFATTACH_DECL_NEW(twa, sizeof(struct twa_softc),
-    twa_match, twa_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(twa, sizeof(struct twa_softc),
+    twa_match, twa_attach, NULL, NULL, twa_request_bus_scan, NULL, 0);
 
 /* FreeBSD driver revision for sysctl expected by the 3ware cli */
 const char twaver[] = "1.50.01.002";
@@ -970,9 +972,11 @@ twa_recompute_openings(struct twa_softc 
 	}
 }
 
+/* ARGSUSED */
 static int
-twa_request_bus_scan(struct twa_softc *sc)
+twa_request_bus_scan(device_t self, const char *attr, const int *flags)
 {
+	struct twa_softc *sc = device_private(self);
 	struct twa_drive *td;
 	struct twa_request *tr;
 	struct twa_attach_args twaa;
@@ -1013,7 +1017,7 @@ twa_request_bus_scan(struct twa_softc *s
 				locs[TWACF_UNIT] = unit;
 
 				sc->sc_units[unit].td_dev =
-				    config_found_sm_loc(sc->twa_dv, "twa",
+				    config_found_sm_loc(sc->twa_dv, attr,
 				    locs, &twaa, twa_print, config_stdsubmatch);
 			}
 		} else {
@@ -1437,12 +1441,15 @@ twa_init_ctlr(struct twa_softc *sc)
 }
 
 static int
-twa_setup(struct twa_softc *sc)
+twa_setup(device_t self)
 {
+	struct twa_softc *sc;
 	struct tw_cl_event_packet *aen_queue;
 	uint32_t		i = 0;
 	int			error = 0;
 
+	sc = device_private(self);
+
 	/* Initialize request queues. */
 	TAILQ_INIT(&sc->twa_free);
 	TAILQ_INIT(&sc->twa_busy);
@@ -1488,7 +1495,7 @@ twa_setup(struct twa_softc *sc)
 
 	twa_describe_controller(sc);
 
-	error = twa_request_bus_scan(sc);
+	error = twa_request_bus_scan(self, "twa", 0);
 
 	twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
 		TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT |
@@ -1607,7 +1614,7 @@ twa_attach(device_t parent, device_t sel
 	if (intrstr != NULL)
 		aprint_normal_dev(sc->twa_dv, "interrupting at %s\n", intrstr);
 
-	twa_setup(sc);
+	twa_setup(self);
 
 	if (twa_sdh == NULL)
 		twa_sdh = shutdownhook_establish(twa_shutdown, NULL);
@@ -2043,7 +2050,7 @@ fw_passthru_done:
 	}
 
 	case TW_OSL_IOCTL_SCAN_BUS:
-		twa_request_bus_scan(sc);
+		twa_request_bus_scan(sc->twa_dv, "twa", 0);
 		break;
 
 	case TW_CL_IOCTL_GET_FIRST_EVENT:
@@ -2748,11 +2755,11 @@ twa_aen_callback(struct twa_request *tr)
 		cmd_hdr->err_specific_desc[sizeof(cmd_hdr->err_specific_desc) - 1] = '\0';
 		for (i = 0; i < 18; i++)
 			printf("%x\t", tr->tr_command->cmd_hdr.sense_data[i]);
-
-		printf(""); /* print new line */
+		printf("\n"); /* print new line */
 
 		for (i = 0; i < 128; i++)
 			printf("%x\t", ((int8_t *)(tr->tr_data))[i]);
+		printf("\n"); /* print new line */
 	}
 	if (tr->tr_data)
 		free(tr->tr_data, M_DEVBUF);
@@ -3139,3 +3146,33 @@ twa_check_ctlr_state(struct twa_softc *s
 	}
 	return(result);
 }
+
+MODULE(MODULE_CLASS_DRIVER, twa, "pci");
+ 
+#ifdef _MODULE  
+#include "ioconf.c"
+#endif 
+
+static int      
+twa_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_twa,
+		    cfattach_ioconf_twa, cfdata_ioconf_twa);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(cfdriver_ioconf_twa,
+		    cfattach_ioconf_twa, cfdata_ioconf_twa);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif  
+        
+	return error;
+}

Index: src/sys/dev/pci/twe.c
diff -u src/sys/dev/pci/twe.c:1.105 src/sys/dev/pci/twe.c:1.106
--- src/sys/dev/pci/twe.c:1.105	Thu Jul 14 04:19:27 2016
+++ src/sys/dev/pci/twe.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: twe.c,v 1.105 2016/07/14 04:19:27 msaitoh Exp $	*/
+/*	$NetBSD: twe.c,v 1.106 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2001, 2002, 2003, 2004 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.105 2016/07/14 04:19:27 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.106 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -79,7 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.10
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
 #include <sys/kauth.h>
-
+#include <sys/module.h>
 #include <sys/bswap.h>
 #include <sys/bus.h>
 
@@ -91,6 +91,7 @@ __KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.10
 #include <dev/pci/tweio.h>
 
 #include "locators.h"
+#include "ioconf.h"
 
 #define	PCI_CBIO	0x10
 
@@ -100,6 +101,7 @@ static void	twe_aen_enqueue(struct twe_s
 static uint16_t	twe_aen_dequeue(struct twe_softc *);
 
 static void	twe_attach(device_t, device_t, void *);
+static int	twe_rescan(device_t, const char *, const int *);
 static int	twe_init_connection(struct twe_softc *);
 static int	twe_intr(void *);
 static int	twe_match(device_t, cfdata_t, void *);
@@ -122,8 +124,8 @@ static inline void twe_outl(struct twe_s
 
 extern struct	cfdriver twe_cd;
 
-CFATTACH_DECL_NEW(twe, sizeof(struct twe_softc),
-    twe_match, twe_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(twe, sizeof(struct twe_softc),
+    twe_match, twe_attach, NULL, NULL, twe_rescan, NULL, 0);
 
 /* FreeBSD driver revision for sysctl expected by the 3ware cli */
 const char twever[] = "1.50.01.002";
@@ -452,9 +454,7 @@ twe_attach(device_t parent, device_t sel
 	twe_describe_controller(sc);
 
 	/* Find and attach RAID array units. */
-	sc->sc_nunits = 0;
-	for (i = 0; i < TWE_MAX_UNITS; i++)
-		(void) twe_add_unit(sc, i);
+	twe_rescan(self, "twe", 0);
 
 	/* ...and finally, enable interrupts. */
 	twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR |
@@ -484,6 +484,20 @@ twe_attach(device_t parent, device_t sel
 	}
 }
 
+static int
+twe_rescan(device_t self, const char *attr, const int *flags)
+{
+	struct twe_softc *sc;
+	int i;
+
+	sc = device_private(self);
+	sc->sc_nunits = 0;
+	for (i = 0; i < TWE_MAX_UNITS; i++)
+		(void) twe_add_unit(sc, i);
+	return 0;
+}
+
+
 void
 twe_register_callbacks(struct twe_softc *sc, int unit,
     const struct twe_callbacks *tcb)
@@ -1991,3 +2005,33 @@ twe_describe_controller(struct twe_softc
 	}
 	free(p[0], M_DEVBUF);
 }
+
+MODULE(MODULE_CLASS_DRIVER, twe, "pci");
+ 
+#ifdef _MODULE  
+#include "ioconf.c"
+#endif 
+
+static int      
+twe_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_twe,
+		    cfattach_ioconf_twe, cfdata_ioconf_twe);
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(cfdriver_ioconf_twe,
+		    cfattach_ioconf_twe, cfdata_ioconf_twe);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif  
+        
+	return error;
+}

Index: src/sys/dev/pci/viomb.c
diff -u src/sys/dev/pci/viomb.c:1.6 src/sys/dev/pci/viomb.c:1.7
--- src/sys/dev/pci/viomb.c:1.6	Thu Jul  7 06:55:41 2016
+++ src/sys/dev/pci/viomb.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: viomb.c,v 1.6 2016/07/07 06:55:41 msaitoh Exp $	*/
+/*	$NetBSD: viomb.c,v 1.7 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.6 2016/07/07 06:55:41 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.7 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.
 #include <sys/mutex.h>
 #include <sys/sysctl.h>
 #include <uvm/uvm_page.h>
+#include <sys/module.h>
 
 #include <dev/pci/pcidevs.h>
 #include <dev/pci/pcireg.h>
@@ -46,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.
 #include <dev/pci/virtioreg.h>
 #include <dev/pci/virtiovar.h>
 
+#include "ioconf.h"
+
 /* Configuration registers */
 #define VIRTIO_BALLOON_CONFIG_NUM_PAGES	0 /* 32bit */
 #define VIRTIO_BALLOON_CONFIG_ACTUAL	4 /* 32bit */
@@ -525,3 +528,33 @@ viomb_thread(void *arg)
 		mutex_exit(&sc->sc_waitlock);
 	}
 }
+
+MODULE(MODULE_CLASS_DRIVER, viomb, "virtio");
+ 
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+ 
+static int 
+viomb_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_viomb, 
+		    cfattach_ioconf_viomb, cfdata_ioconf_viomb); 
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(cfdriver_ioconf_viomb,
+		    cfattach_ioconf_viomb, cfdata_ioconf_viomb);
+		break;
+	default:
+		error = ENOTTY;
+		break; 
+	}
+#endif
+   
+	return error;
+}

Index: src/sys/dev/pci/virtio.c
diff -u src/sys/dev/pci/virtio.c:1.17 src/sys/dev/pci/virtio.c:1.18
--- src/sys/dev/pci/virtio.c:1.17	Sun Aug 14 07:47:15 2016
+++ src/sys/dev/pci/virtio.c	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: virtio.c,v 1.17 2016/08/14 07:47:15 tron Exp $	*/
+/*	$NetBSD: virtio.c,v 1.18 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.17 2016/08/14 07:47:15 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.18 2016/09/27 03:33:32 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -35,6 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/kmem.h>
+#include <sys/module.h>
 
 #include <dev/pci/pcidevs.h>
 #include <dev/pci/pcireg.h>
@@ -47,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1
 
 static int	virtio_match(device_t, cfdata_t, void *);
 static void	virtio_attach(device_t, device_t, void *);
+static int	virtio_rescan(device_t, const char *, const int *);
 static int	virtio_detach(device_t, int);
 static int	virtio_intr(void *arg);
 static int	virtio_msix_queue_intr(void *);
@@ -56,14 +58,13 @@ static int	virtio_setup_msix_interrupts(
 		    struct pci_attach_args *);
 static int	virtio_setup_intx_interrupt(struct virtio_softc *,
 		    struct pci_attach_args *);
-static int	virtio_setup_interrupts(struct virtio_softc *,
-		    struct pci_attach_args *);
+static int	virtio_setup_interrupts(struct virtio_softc *);
 static void	virtio_soft_intr(void *arg);
 static void	virtio_init_vq(struct virtio_softc *,
 		    struct virtqueue *, const bool);
 
 CFATTACH_DECL3_NEW(virtio, sizeof(struct virtio_softc),
-    virtio_match, virtio_attach, virtio_detach, NULL, NULL, NULL,
+    virtio_match, virtio_attach, virtio_detach, NULL, virtio_rescan, NULL,
     DVF_DETACH_SHUTDOWN);
 
 static void
@@ -233,16 +234,16 @@ virtio_setup_intx_interrupt(struct virti
 }
 
 static int
-virtio_setup_interrupts(struct virtio_softc *sc, struct pci_attach_args *pa)
+virtio_setup_interrupts(struct virtio_softc *sc)
 {
 	device_t self = sc->sc_dev;
-	pci_chipset_tag_t pc = pa->pa_pc;
+	pci_chipset_tag_t pc = sc->sc_pa.pa_pc;
 	int error;
 	int nmsix;
 	int counts[PCI_INTR_TYPE_SIZE];
 	pci_intr_type_t max_type;
 
-	nmsix = pci_msix_count(pa->pa_pc, pa->pa_tag);
+	nmsix = pci_msix_count(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag);
 	aprint_debug_dev(self, "pci_msix_count=%d\n", nmsix);
 
 	/* We need at least two: one for config and the other for queues */
@@ -259,7 +260,7 @@ virtio_setup_interrupts(struct virtio_so
 	}
 
  retry:
-	error = pci_intr_alloc(pa, &sc->sc_ihp, counts, max_type);
+	error = pci_intr_alloc(&sc->sc_pa, &sc->sc_ihp, counts, max_type);
 	if (error != 0) {
 		aprint_error_dev(self, "couldn't map interrupt\n");
 		return -1;
@@ -277,7 +278,7 @@ virtio_setup_interrupts(struct virtio_so
 			goto retry;
 		}
 
-		error = virtio_setup_msix_interrupts(sc, pa);
+		error = virtio_setup_msix_interrupts(sc, &sc->sc_pa);
 		if (error != 0) {
 			kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 2);
 			pci_intr_release(pc, sc->sc_ihp, 2);
@@ -298,7 +299,7 @@ virtio_setup_interrupts(struct virtio_so
 			return -1;
 		}
 
-		error = virtio_setup_intx_interrupt(sc, pa);
+		error = virtio_setup_intx_interrupt(sc, &sc->sc_pa);
 		if (error != 0) {
 			kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 1);
 			pci_intr_release(pc, sc->sc_ihp, 1);
@@ -321,7 +322,6 @@ virtio_attach(device_t parent, device_t 
 	pcitag_t tag = pa->pa_tag;
 	int revision;
 	pcireg_t id;
-	int r;
 
 	revision = PCI_REVISION(pa->pa_class);
 	if (revision != 0) {
@@ -362,24 +362,39 @@ virtio_attach(device_t parent, device_t 
 	/* XXX: use softc as aux... */
 	sc->sc_childdevid = PCI_SUBSYS_ID(id);
 	sc->sc_child = NULL;
-	config_found(self, sc, NULL);
+	sc->sc_pa = *pa;
+	virtio_rescan(self, "virtio", 0);
+	return;
+}
+
+/* ARGSUSED */
+static int
+virtio_rescan(device_t self, const char *attr, const int *scan_flags)
+{
+	struct virtio_softc *sc;
+	int r;
+
+	sc = device_private(self);
+	if (sc->sc_child)	/* Child already attached? */
+		return 0;
+	config_found_ia(self, attr, sc, NULL);
 	if (sc->sc_child == NULL) {
 		aprint_error_dev(self,
 				 "no matching child driver; not configured\n");
-		return;
+		return 0;
 	}
 	if (sc->sc_child == (void*)1) { /* this shows error */
 		aprint_error_dev(self,
 				 "virtio configuration failed\n");
 		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
-		return;
+		return 0;
 	}
 
-	r = virtio_setup_interrupts(sc, pa);
+	r = virtio_setup_interrupts(sc);
 	if (r != 0) {
 		aprint_error_dev(self, "failed to setup interrupts\n");
 		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
-		return;
+		return 0;
 	}
 
 	sc->sc_soft_ih = NULL;
@@ -395,7 +410,7 @@ virtio_attach(device_t parent, device_t 
 
 	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
 
-	return;
+	return 0;
 }
 
 static int
@@ -1282,3 +1297,33 @@ virtio_dequeue_commit(struct virtio_soft
 
 	return 0;
 }
+
+MODULE(MODULE_CLASS_DRIVER, virtio, "pci");
+ 
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+ 
+static int
+virtio_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_virtio, 
+		    cfattach_ioconf_virtio, cfdata_ioconf_virtio); 
+		break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(cfdriver_ioconf_virtio, 
+		    cfattach_ioconf_virtio, cfdata_ioconf_virtio);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+ 
+	return error; 
+}

Index: src/sys/dev/pci/virtiovar.h
diff -u src/sys/dev/pci/virtiovar.h:1.5 src/sys/dev/pci/virtiovar.h:1.6
--- src/sys/dev/pci/virtiovar.h:1.5	Mon Oct 26 01:44:48 2015
+++ src/sys/dev/pci/virtiovar.h	Tue Sep 27 03:33:32 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: virtiovar.h,v 1.5 2015/10/26 01:44:48 ozaki-r Exp $	*/
+/*	$NetBSD: virtiovar.h,v 1.6 2016/09/27 03:33:32 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -149,6 +149,7 @@ struct virtio_softc {
 					 /* set by child */
 	int			(*sc_intrhand)(struct virtio_softc*);
 					 /* set by child */
+	struct pci_attach_args	sc_pa;	/* need for rescan to set interrupts */
 };
 
 #define VIRTIO_F_PCI_INTR_MPSAFE	(1 << 0)

Index: src/sys/dev/sdmmc/ld_sdmmc.c
diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.22 src/sys/dev/sdmmc/ld_sdmmc.c:1.23
--- src/sys/dev/sdmmc/ld_sdmmc.c:1.22	Fri Sep 16 15:20:50 2016
+++ src/sys/dev/sdmmc/ld_sdmmc.c	Tue Sep 27 03:33:33 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld_sdmmc.c,v 1.22 2016/09/16 15:20:50 jdolecek Exp $	*/
+/*	$NetBSD: ld_sdmmc.c,v 1.23 2016/09/27 03:33:33 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.22 2016/09/16 15:20:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.23 2016/09/27 03:33:33 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -45,11 +45,14 @@ __KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v
 #include <sys/dkio.h>
 #include <sys/disk.h>
 #include <sys/kthread.h>
+#include <sys/module.h>
 
 #include <dev/ldvar.h>
 
 #include <dev/sdmmc/sdmmcvar.h>
 
+#include "ioconf.h"
+
 #ifdef LD_SDMMC_DEBUG
 #define DPRINTF(s)	printf s
 #else
@@ -244,3 +247,46 @@ ld_sdmmc_dump(struct ld_softc *ld, void 
 	return sdmmc_mem_write_block(sc->sc_sf, blkno, data,
 	    blkcnt * ld->sc_secsize);
 }
+
+MODULE(MODULE_CLASS_DRIVER, ld_sdmmc, "ld");
+
+#ifdef _MODULE
+/*
+ * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
+ * XXX it will be defined in the common-code module
+ */
+#undef  CFDRIVER_DECL
+#define CFDRIVER_DECL(name, class, attr)
+#include "ioconf.c"    
+#endif
+
+static int
+ld_sdmmc_modcmd(modcmd_t cmd, void *opaque)
+{
+#ifdef _MODULE
+	/*
+	 * We ignore the cfdriver_vec[] that ioconf provides, since
+	 * the cfdrivers are attached already.
+	 */
+	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
+#endif
+	int error = 0;
+ 
+#ifdef _MODULE
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_sdmmc, cfdata_ioconf_ld_sdmmc);
+        	break;
+	case MODULE_CMD_FINI:
+		error = config_fini_component(no_cfdriver_vec,
+		    cfattach_ioconf_ld_sdmmc, cfdata_ioconf_ld_sdmmc);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+#endif
+
+	return error;
+}

Reply via email to