aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>2008-11-13 21:43:30 +0000
committerbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>2008-11-13 21:43:30 +0000
commit6a1c3d418a94bd98ef47e6bedb15c85a31398d6f (patch)
treed5fb65f55471758784aaf53eda8f807cb8f6e963
parent5457aee1a3912396a8b63d4491724a51187c598c (diff)
* include/sys/sunddi.h, modules/spl/spl-module.c : Removed default
udev support from sunddi implementation because it uses GPL-only symbols. This support is optionally available for SPL consumers if they define HAVE_GPL_ONLY_SYMBOLS and license their module as GPL using the MODULE_LICENSE("GPL") macro. git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@179 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
-rw-r--r--ChangeLog8
-rw-r--r--autoconf/spl-build.m48
-rw-r--r--configure.ac1
-rw-r--r--include/sys/sunddi.h63
-rw-r--r--modules/spl/spl-module.c50
5 files changed, 83 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index cb231cb01..8d023992e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-11-13 Brian Behlendorf <[email protected]>
+
+ * include/sys/sunddi.h, modules/spl/spl-module.c : Removed default
+ udev support from sunddi implementation because it uses GPL-only
+ symbols. This support is optionally available for SPL consumers
+ if they define HAVE_GPL_ONLY_SYMBOLS and license their module as
+ GPL using the MODULE_LICENSE("GPL") macro.
+
2008-11-05 Brian Behlendorf <[email protected]>
* : Tag spl-0.3.4
diff --git a/autoconf/spl-build.m4 b/autoconf/spl-build.m4
index 0ac7ae8a6..c5c031977 100644
--- a/autoconf/spl-build.m4
+++ b/autoconf/spl-build.m4
@@ -30,7 +30,7 @@ AC_DEFUN([SPL_AC_KERNEL], [
AC_MSG_RESULT([Not found])
AC_MSG_ERROR([
*** Please specify the location of the kernel source
- *** with the '--with-kernel=PATH' option])
+ *** with the '--with-linux=PATH' option])
fi
fi
@@ -74,6 +74,12 @@ AC_DEFUN([SPL_AC_KERNEL], [
AC_SUBST(kmoduledir)
])
+AC_DEFUN([SPL_AC_LICENSE], [
+ AC_MSG_CHECKING([license])
+ AC_MSG_RESULT([GPL])
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DHAVE_GPL_ONLY_SYMBOLS"
+])
+
AC_DEFUN([SPL_AC_DEBUG], [
AC_MSG_CHECKING([whether debugging is enabled])
AC_ARG_ENABLE( [debug],
diff --git a/configure.ac b/configure.ac
index a50fe92e1..b3835d0e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,6 +38,7 @@ LINUX=
LINUX_OBJ=
SPL_AC_KERNEL
+SPL_AC_LICENSE
SPL_AC_DEBUG
SPL_AC_DEBUG_KMEM
SPL_AC_DEBUG_MUTEX
diff --git a/include/sys/sunddi.h b/include/sys/sunddi.h
index bbfd412da..dea09d171 100644
--- a/include/sys/sunddi.h
+++ b/include/sys/sunddi.h
@@ -87,6 +87,7 @@ typedef struct dev_info {
minor_t di_minor;
dev_t di_dev;
unsigned di_minors;
+ int di_flags;
struct list_head di_list;
} dev_info_t;
@@ -180,6 +181,11 @@ typedef struct modldrv {
#define DDI_PROP_DONTPASS 0x0001
#define DDI_PROP_CANSLEEP 0x0002
+#define GLOBAL_DEV 0x02
+#define NODEBOUND_DEV 0x04
+#define NODESPECIFIC_DEV 0x06
+#define ENUMERATED_DEV 0x08
+
#define ddi_prop_lookup_string(x1,x2,x3,x4,x5) (*x5 = NULL)
#define ddi_prop_free(x) (void)0
#define ddi_root_node() (void)0
@@ -189,7 +195,7 @@ typedef struct modldrv {
extern int __ddi_create_minor_node(dev_info_t *dip, char *name, int spec_type,
minor_t minor_num, char *node_type,
- int flag, struct module *mod);
+ int flags, struct module *mod);
extern void __ddi_remove_minor_node(dev_info_t *dip, char *name);
extern int __mod_install(struct modlinkage *modlp);
extern int __mod_remove(struct modlinkage *modlp);
@@ -197,19 +203,64 @@ extern int __mod_remove(struct modlinkage *modlp);
static __inline__ void ddi_report_dev(dev_info_t *d) { }
static __inline__ void ddi_prop_remove_all(dev_info_t *dip) { }
+static __inline__ void
+ddi_remove_minor_node(dev_info_t *di, char *name)
+{
+#ifdef HAVE_GPL_ONLY_SYMBOLS
+ /* Cleanup udev (GPL-only symbols required). This is performed as
+ * part of an inline function to ensure that these symbols are not
+ * linked against the SPL which is GPL'ed. But instead they are
+ * linked against the package building against the SPL to ensure
+ * its license allows linking with GPL-only symbols. */
+ if (di->di_class) {
+ spl_device_destroy(di->di_class, di->di_device, di->di_dev);
+ spl_class_destroy(di->di_class);
+ di->di_class = NULL;
+ di->di_dev = 0;
+ }
+#endif
+
+ __ddi_remove_minor_node(di, name);
+}
+
static __inline__ int
ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
- minor_t minor_num, char *node_type, int flag)
+ minor_t minor_num, char *node_type, int flags)
{
- return __ddi_create_minor_node(di, name, spec_type, minor_num,
- node_type, flag, THIS_MODULE);
-
+ int rc;
+
+ rc = __ddi_create_minor_node(di, name, spec_type, minor_num,
+ node_type, flags, THIS_MODULE);
+ if (rc)
+ return rc;
+
+#ifdef HAVE_GPL_ONLY_SYMBOLS
+ /* Setup udev (GPL-only symbols required). This is performed as
+ * part of an inline function to ensure that these symbols are not
+ * linked against the SPL which is GPL'ed. But instead they are
+ * linked against the package building against the SPL to ensure
+ * its license allows linking with GPL-only symbols. */
+ di->di_class = spl_class_create(THIS_MODULE, name);
+ if (IS_ERR(di->di_class)) {
+ rc = PTR_ERR(di->di_class);
+ di->di_class = NULL;
+ ddi_remove_minor_node(di, name);
+ CERROR("Error creating %s class, %d\n", name, rc);
+ RETURN(DDI_FAILURE);
+ }
+
+ /* Do not append a 0 to devices with minor nums of 0 */
+ di->di_device = spl_device_create(di->di_class, NULL, di->di_dev, NULL,
+ (di->di_minor == 0) ? "%s" : "%s%d",
+ name, di->di_minor);
+#endif
+
+ return rc;
}
#undef mod_install
#undef mod_remove
-#define ddi_remove_minor_node __ddi_remove_minor_node
#define mod_install __mod_install
#define mod_remove __mod_remove
diff --git a/modules/spl/spl-module.c b/modules/spl/spl-module.c
index 0dd4cfded..700c76182 100644
--- a/modules/spl/spl-module.c
+++ b/modules/spl/spl-module.c
@@ -58,7 +58,7 @@ mod_generic_ioctl(struct inode *ino, struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct dev_info *di;
- int rc, flag = 0, rvalp = 0;
+ int rc, flags = 0, rvalp = 0;
cred_t *cr = NULL;
di = get_dev_info(MKDEV(imajor(ino), iminor(ino)));
@@ -67,14 +67,14 @@ mod_generic_ioctl(struct inode *ino, struct file *filp,
rc = di->di_ops->devo_cb_ops->cb_ioctl(di->di_dev,
(int)cmd,(intptr_t)arg,
- flag, cr, &rvalp);
+ flags, cr, &rvalp);
return rc;
}
int
__ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
minor_t minor_num, char *node_type,
- int flag, struct module *mod)
+ int flags, struct module *mod)
{
struct cdev *cdev;
struct dev_ops *dev_ops;
@@ -86,7 +86,6 @@ __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
ASSERT(spec_type == S_IFCHR);
ASSERT(minor_num < di->di_minors);
ASSERT(!strcmp(node_type, DDI_PSEUDO));
- ASSERT(flag == 0);
fops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
if (fops == NULL)
@@ -141,8 +140,10 @@ __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
ASSERT(cb_ops->cb_aread == NULL);
ASSERT(cb_ops->cb_awrite == NULL);
+ di->di_cdev = cdev;
+ di->di_flags = flags;
di->di_minor = minor_num;
- di->di_dev = MKDEV(di->di_major, di->di_minor);
+ di->di_dev = MKDEV(di->di_major, di->di_minor);
rc = cdev_add(cdev, di->di_dev, 1);
if (rc) {
@@ -153,29 +154,6 @@ __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
RETURN(DDI_FAILURE);
}
- di->di_class = spl_class_create(THIS_MODULE, name);
- if (IS_ERR(di->di_class)) {
- rc = PTR_ERR(di->di_class);
- CERROR("Error creating %s class, %d\n", name, rc);
- kfree(fops);
- cdev_del(di->di_cdev);
- mutex_exit(&di->di_lock);
- RETURN(DDI_FAILURE);
- }
-
- /* Do not append a 0 to devices with minor nums of 0 */
- if (di->di_minor == 0) {
- di->di_device = spl_device_create(di->di_class, NULL,
- di->di_dev, NULL,
- "%s", name);
- } else {
- di->di_device = spl_device_create(di->di_class, NULL,
- di->di_dev, NULL,
- "%s%d", name, di->di_minor);
- }
-
- di->di_cdev = cdev;
-
spin_lock(&dev_info_lock);
list_add(&di->di_list, &dev_info_list);
spin_unlock(&dev_info_lock);
@@ -184,19 +162,11 @@ __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
RETURN(DDI_SUCCESS);
}
-EXPORT_SYMBOL_GPL(__ddi_create_minor_node);
+EXPORT_SYMBOL(__ddi_create_minor_node);
static void
__ddi_remove_minor_node_locked(dev_info_t *di, char *name)
{
- if (di->di_class) {
- spl_device_destroy(di->di_class, di->di_device, di->di_dev);
- spl_class_destroy(di->di_class);
-
- di->di_class = NULL;
- di->di_dev = 0;
- }
-
if (di->di_cdev) {
cdev_del(di->di_cdev);
di->di_cdev = NULL;
@@ -216,19 +186,19 @@ __ddi_remove_minor_node(dev_info_t *di, char *name)
mutex_exit(&di->di_lock);
EXIT;
}
-EXPORT_SYMBOL_GPL(ddi_remove_minor_node);
+EXPORT_SYMBOL(__ddi_remove_minor_node);
#if 0
static int
mod_generic_open(struct inode *, struct file *)
{
- open(dev_t *devp, int flag, int otyp, cred_t *credp);
+ open(dev_t *devp, int flags, int otyp, cred_t *credp);
}
static int
mod_generic_close(struct inode *, struct file *)
{
- close(dev_t dev, int flag, int otyp, cred_t *credp);
+ close(dev_t dev, int flags, int otyp, cred_t *credp);
}
static ssize_t