Module Name:    src
Committed By:   haad
Date:           Sun Jan  3 22:22:23 UTC 2010

Modified Files:
        src/sys/dev/dm: device-mapper.c dm_ioctl.c files.dm

Log Message:
Hook device-mapper to autoconf framework. Add dm_attach, dm_match and dm_detach
routines used by autoconf users. Change dm_dev_remove_ioctl to call dm_detach.

This should be primary used by kernel to disable devices during shutdown of
system with nested disk devices.

Requested by dyo...@.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/dm/device-mapper.c
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/dm/dm_ioctl.c
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/dm/files.dm

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/dm/device-mapper.c
diff -u src/sys/dev/dm/device-mapper.c:1.11 src/sys/dev/dm/device-mapper.c:1.12
--- src/sys/dev/dm/device-mapper.c:1.11	Tue Dec 29 23:37:47 2009
+++ src/sys/dev/dm/device-mapper.c	Sun Jan  3 22:22:23 2010
@@ -1,4 +1,4 @@
-/*        $NetBSD: device-mapper.c,v 1.11 2009/12/29 23:37:47 haad Exp $ */
+/*        $NetBSD: device-mapper.c,v 1.12 2010/01/03 22:22:23 haad Exp $ */
 
 /*
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -38,6 +38,7 @@
 
 #include <sys/buf.h>
 #include <sys/conf.h>
+#include <sys/device.h>
 #include <sys/dkio.h>
 #include <sys/disk.h>
 #include <sys/disklabel.h>
@@ -58,14 +59,19 @@
 static dev_type_size(dmsize);
 
 /* attach and detach routines */
-int dmattach(void);
-int dmdestroy(void);
+static int dmattach(void);
+static int dmdestroy(void);
 
 static int dm_cmd_to_fun(prop_dictionary_t);
 static int disk_ioctl_switch(dev_t, u_long, void *);
 static int dm_ioctl_switch(u_long);
 static void dmminphys(struct buf *);
 
+/* CF attach/detach functions used for power management */
+static int dm_detach(device_t, int);
+static void dm_attach(device_t, device_t, void *);
+static int dm_match(device_t, cfdata_t, void *);
+
 /* ***Variable-definitions*** */
 const struct bdevsw dm_bdevsw = {
 	.d_open = dmopen,
@@ -95,6 +101,14 @@
 	.d_strategy = dmstrategy
 };
 
+/* Autoconf defines */
+CFDRIVER_DECL(dm, DV_DISK, NULL);
+CFATTACH_DECL3_NEW(dm, 0,
+     dm_match, dm_attach, dm_detach, NULL, NULL, NULL,
+     DVF_DETACH_SHUTDOWN);
+
+extern struct cfdriver dm_cd;
+
 extern uint64_t dev_counter;
 
 /*
@@ -134,11 +148,27 @@
 {
 #ifdef _MODULE
 	int bmajor = -1, cmajor = -1;
+	int error;
+
+	error = 0;
 
 	switch (cmd) {
 	case MODULE_CMD_INIT:
 		dmattach();
-		return devsw_attach("dm", &dm_bdevsw, &bmajor,
+
+		error = config_cfdriver_attach(&dm_cd);
+		if (error)
+			break;
+
+		error = config_cfattach_attach(dm_cd.cd_name, &dm_ca);
+		if (error) {
+			config_cfdriver_detach(&dm_cd);
+			aprint_error("Unable to register cfattach for dm driver\n");
+
+			break;
+		}
+
+		error =  devsw_attach("dm", &dm_bdevsw, &bmajor,
 		    &dm_cdevsw, &cmajor);
 		break;
 
@@ -152,7 +182,14 @@
 		if (dev_counter > 0)
 			return EBUSY;
 		dmdestroy();
-		return devsw_detach(&dm_bdevsw, &dm_cdevsw);
+
+		error = config_cfattach_detach(dm_cd.cd_name, &dm_ca);
+		if (error)
+			break;
+
+		config_cfdriver_detach(&dm_cd);
+
+		devsw_detach(&dm_bdevsw, &dm_cdevsw);
 		break;
 	case MODULE_CMD_STAT:
 		return ENOTTY;
@@ -161,7 +198,7 @@
 		return ENOTTY;
 	}
 
-	return 0;
+	return error;
 #else
 
 	if (cmd == MODULE_CMD_INIT)
@@ -172,10 +209,75 @@
 }
 
 
+/*
+ * dm_match:
+ *
+ *	Autoconfiguration match function for pseudo-device glue.
+ */
+static int
+dm_match(device_t parent, cfdata_t match,
+    void *aux)
+{
+
+	/* Pseudo-device; always present. */
+	return (1);
+}
+
+/*
+ * dm_attach:
+ *
+ *	Autoconfiguration attach function for pseudo-device glue.
+ */
+static void
+dm_attach(device_t parent, device_t self,
+    void *aux)
+{
+	return;
+}
+
+
+/*
+ * dm_detach:
+ *
+ *	Autoconfiguration detach function for pseudo-device glue.
+ * This routine is called by dm_ioctl::dm_dev_remove_ioctl and by autoconf to
+ * remove devices created in device-mapper. 
+ */
+static int
+dm_detach(device_t self, int flags)
+{
+	dm_dev_t *dmv;
+
+	/* Detach device from global device list */
+	if ((dmv = dm_dev_detach(self)) == NULL)
+		return ENOENT;
+
+	/* Destroy active table first.  */
+	dm_table_destroy(&dmv->table_head, DM_TABLE_ACTIVE);
+
+	/* Destroy inactive table if exits, too. */
+	dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
+	
+	dm_table_head_destroy(&dmv->table_head);
+
+	/* Destroy disk device structure */
+	disk_detach(dmv->diskp);
+	disk_destroy(dmv->diskp);
+
+	/* Destroy device */
+	(void)dm_dev_free(dmv);
+
+	/* Decrement device counter After removing device */
+	atomic_dec_64(&dev_counter);
+
+	return 0;
+}
+
 /* attach routine */
-int
+static int
 dmattach(void)
 {
+
 	dm_target_init();
 	dm_dev_init();
 	dm_pdev_init();
@@ -184,9 +286,10 @@
 }
 
 /* Destroy routine */
-int
+static int
 dmdestroy(void)
 {
+
 	dm_dev_destroy();
 	dm_pdev_destroy();
 	dm_target_destroy();
@@ -197,6 +300,7 @@
 static int
 dmopen(dev_t dev, int flags, int mode, struct lwp *l)
 {
+
 	aprint_debug("open routine called %" PRIu32 "\n", minor(dev));
 	return 0;
 }
@@ -204,8 +308,8 @@
 static int
 dmclose(dev_t dev, int flags, int mode, struct lwp *l)
 {
-	aprint_debug("CLOSE routine called\n");
 
+	aprint_debug("CLOSE routine called\n");
 	return 0;
 }
 

Index: src/sys/dev/dm/dm_ioctl.c
diff -u src/sys/dev/dm/dm_ioctl.c:1.18 src/sys/dev/dm/dm_ioctl.c:1.19
--- src/sys/dev/dm/dm_ioctl.c:1.18	Tue Dec 29 23:37:48 2009
+++ src/sys/dev/dm/dm_ioctl.c	Sun Jan  3 22:22:23 2010
@@ -1,5 +1,5 @@
 
-/*        $NetBSD: dm_ioctl.c,v 1.18 2009/12/29 23:37:48 haad Exp $      */
+/*        $NetBSD: dm_ioctl.c,v 1.19 2010/01/03 22:22:23 haad Exp $      */
 
 /*
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -82,6 +82,7 @@
 #include <sys/types.h>
 #include <sys/param.h>
 
+#include <sys/device.h>
 #include <sys/disk.h>
 #include <sys/disklabel.h>
 #include <sys/kmem.h>
@@ -97,6 +98,14 @@
 extern const struct dkdriver dmdkdriver;
 uint64_t dev_counter;
 
+/* Generic cf_data for device-mapper driver */
+static struct cfdata dm_cfdata = {
+	.cf_name = "dm",
+	.cf_atname = "dm",
+	.cf_fstate = FSTATE_STAR,
+	.cf_unit = 0
+};
+
 #define DM_REMOVE_FLAG(flag, name) do {					\
 		prop_dictionary_get_uint32(dm_dict,DM_IOCTL_FLAGS,&flag); \
 		flag &= ~name;						\
@@ -198,6 +207,7 @@
 	dm_dev_t *dmv;
 	const char *name, *uuid;
 	int r, flags;
+	device_t devt;
 	
 	r = 0;
 	flags = 0;
@@ -218,9 +228,14 @@
 		return EEXIST;
 	}
 
+	if ((devt = config_attach_pseudo(&dm_cfdata)) == NULL) {
+		aprint_error("Unable to attach pseudo device dm/%s\n", name);
+		return (ENOMEM);
+	}
+	
 	if ((dmv = dm_dev_alloc()) == NULL)
 		return ENOMEM;
-		
+
 	if (uuid)
 		strncpy(dmv->uuid, uuid, DM_UUID_LEN);
 	else 
@@ -230,18 +245,18 @@
 		strlcpy(dmv->name, name, DM_NAME_LEN);
 
 	dmv->minor = atomic_inc_64_nv(&sc_minor_num);
-
 	dmv->flags = 0; /* device flags are set when needed */
 	dmv->ref_cnt = 0;
 	dmv->event_nr = 0;
 	dmv->dev_type = 0;
+	dmv->devt = devt;
 	
+	dm_table_head_init(&dmv->table_head);
+
 	mutex_init(&dmv->dev_mtx, MUTEX_DEFAULT, IPL_NONE);
 	mutex_init(&dmv->diskp_mtx, MUTEX_DEFAULT, IPL_NONE);
 	cv_init(&dmv->dev_cv, "dm_dev");
 
-	dm_table_head_init(&dmv->table_head);
-	
 	if (flags & DM_READONLY_FLAG)
 		dmv->flags |= DM_READONLY_FLAG;
 
@@ -371,6 +386,7 @@
 	dm_dev_t *dmv;
 	const char *name, *uuid;
 	uint32_t flags, minor;
+	device_t devt;
 	
 	flags = 0;
 	name = NULL;
@@ -383,32 +399,20 @@
 	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
 	
 	dm_dbg_print_flags(flags);
-	
-	/* Remove device from global device list */
-	if ((dmv = dm_dev_rem(name, uuid, minor)) == NULL){
+
+	/* This seems as hack to me, probably use routine dm_dev_get_devt to
+	   atomicaly get devt from device. */
+	if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
 		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
 		return ENOENT;
 	}
 
-	/* Destroy active table first.  */
-	dm_table_destroy(&dmv->table_head, DM_TABLE_ACTIVE);
-	
-	/* Destroy inactive table if exits, too. */
-	dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
-	
-	dm_table_head_destroy(&dmv->table_head);
-
-	/* Destroy disk device structure */
-	disk_detach(dmv->diskp);
-	disk_destroy(dmv->diskp);
-	
-	/* Destroy device */
-	(void)dm_dev_free(dmv);
+	devt = dmv->devt;
 
-	/* Decrement device counter After removing device */
-	atomic_dec_64(&dev_counter);
+	dm_dev_unbusy(dmv);
 	
-	return 0;
+	/* This will call dm_detach routine which will actually removes device. */
+	return config_detach(devt, DETACH_QUIET);
 }
 
 /*

Index: src/sys/dev/dm/files.dm
diff -u src/sys/dev/dm/files.dm:1.5 src/sys/dev/dm/files.dm:1.6
--- src/sys/dev/dm/files.dm:1.5	Sun Jun 28 22:05:07 2009
+++ src/sys/dev/dm/files.dm	Sun Jan  3 22:22:23 2010
@@ -1,4 +1,4 @@
-defpseudo   dm
+defpseudodev   dm
 file	    dev/dm/device-mapper.c      dm
 file        dev/dm/dm_dev.c   	        dm
 file        dev/dm/dm_ioctl.c           dm

Reply via email to