Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 May 2016 09:56:48 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r299933 - in head/sys: compat/linuxkpi/common/include/linux sys
Message-ID:  <201605160956.u4G9umAT025380@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Mon May 16 09:56:48 2016
New Revision: 299933
URL: https://svnweb.freebsd.org/changeset/base/299933

Log:
  Implement more Linux device related functions in the LinuxKPI. While
  at it use NULL for some pointer checks.
  
  Bump the FreeBSD version to force recompilation of all kernel modules
  due to a structure size change.
  
  Obtained from:	kmacy @
  MFC after:	1 week
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/compat/linuxkpi/common/include/linux/device.h
  head/sys/sys/param.h

Modified: head/sys/compat/linuxkpi/common/include/linux/device.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/device.h	Mon May 16 09:31:44 2016	(r299932)
+++ head/sys/compat/linuxkpi/common/include/linux/device.h	Mon May 16 09:56:48 2016	(r299933)
@@ -31,6 +31,7 @@
 #ifndef	_LINUX_DEVICE_H_
 #define	_LINUX_DEVICE_H_
 
+#include <linux/err.h>
 #include <linux/types.h>
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
@@ -71,6 +72,7 @@ struct device {
 	unsigned int	irq;
 	unsigned int	msix;
 	unsigned int	msix_max;
+	const struct attribute_group **groups;
 };
 
 extern struct device linux_root_device;
@@ -127,11 +129,12 @@ show_class_attr_string(struct class *cla
 #define	dev_err(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
 #define	dev_warn(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
 #define	dev_info(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define	dev_notice(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
 #define	dev_printk(lvl, dev, fmt, ...)					\
 	    device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
 
 static inline void *
-dev_get_drvdata(struct device *dev)
+dev_get_drvdata(const struct device *dev)
 {
 
 	return dev->driver_data;
@@ -191,11 +194,106 @@ class_unregister(struct class *class)
 	kobject_put(&class->kobj);
 }
 
+static inline struct device *kobj_to_dev(struct kobject *kobj)
+{
+	return container_of(kobj, struct device, kobj);
+}
+
 /*
- * Devices are registered and created for exporting to sysfs.  create
+ * Devices are registered and created for exporting to sysfs. Create
  * implies register and register assumes the device fields have been
  * setup appropriately before being called.
  */
+static inline void
+device_initialize(struct device *dev)
+{
+	device_t bsddev;
+
+	bsddev = NULL;
+	if (dev->devt) {
+		int unit = MINOR(dev->devt);
+		bsddev = devclass_get_device(dev->class->bsdclass, unit);
+	}
+	if (bsddev != NULL)
+		device_set_softc(bsddev, dev);
+
+	dev->bsddev = bsddev;
+	kobject_init(&dev->kobj, &linux_dev_ktype);
+}
+
+static inline int
+device_add(struct device *dev)
+{	
+	if (dev->bsddev != NULL) {
+		if (dev->devt == 0)
+			dev->devt = makedev(0, device_get_unit(dev->bsddev));
+	}
+	kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
+	return (0);
+}
+
+static inline void
+device_create_release(struct device *dev)
+{
+	kfree(dev);
+}
+
+static inline struct device *
+device_create_groups_vargs(struct class *class, struct device *parent,
+    dev_t devt, void *drvdata, const struct attribute_group **groups,
+    const char *fmt, va_list args)
+{
+	struct device *dev = NULL;
+	int retval = -ENODEV;
+
+	if (class == NULL || IS_ERR(class))
+		goto error;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	device_initialize(dev);
+	dev->devt = devt;
+	dev->class = class;
+	dev->parent = parent;
+	dev->groups = groups;
+	dev->release = device_create_release;
+	dev->bsddev = devclass_get_device(dev->class->bsdclass, MINOR(devt));
+	dev_set_drvdata(dev, drvdata);
+
+	retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
+	if (retval)
+		goto error;
+
+	retval = device_add(dev);
+	if (retval)
+		goto error;
+
+	return dev;
+
+error:
+	put_device(dev);
+	return ERR_PTR(retval);
+}
+
+static inline struct device *
+device_create_with_groups(struct class *class,
+    struct device *parent, dev_t devt, void *drvdata,
+    const struct attribute_group **groups, const char *fmt, ...)
+{
+	va_list vargs;
+	struct device *dev;
+
+	va_start(vargs, fmt);
+	dev = device_create_groups_vargs(class, parent, devt, drvdata,
+	    groups, fmt, vargs);
+	va_end(vargs);
+	return dev;
+}
+
 static inline int
 device_register(struct device *dev)
 {
@@ -233,13 +331,29 @@ device_unregister(struct device *dev)
 	device_t bsddev;
 
 	bsddev = dev->bsddev;
+	dev->bsddev = NULL;
+
 	mtx_lock(&Giant);
-	if (bsddev)
+	if (bsddev != NULL)
 		device_delete_child(device_get_parent(bsddev), bsddev);
 	mtx_unlock(&Giant);
 	put_device(dev);
 }
 
+static inline void
+device_del(struct device *dev)
+{
+	device_t bsddev;
+
+	bsddev = dev->bsddev;
+	dev->bsddev = NULL;
+
+	mtx_lock(&Giant);
+	if (bsddev != NULL)
+		device_delete_child(device_get_parent(bsddev), bsddev);
+	mtx_unlock(&Giant);
+}
+
 struct device *device_create(struct class *class, struct device *parent,
 	    dev_t devt, void *drvdata, const char *fmt, ...);
 
@@ -251,7 +365,7 @@ device_destroy(struct class *class, dev_
 
 	unit = MINOR(devt);
 	bsddev = devclass_get_device(class->bsdclass, unit);
-	if (bsddev)
+	if (bsddev != NULL)
 		device_unregister(device_get_softc(bsddev));
 }
 

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h	Mon May 16 09:31:44 2016	(r299932)
+++ head/sys/sys/param.h	Mon May 16 09:56:48 2016	(r299933)
@@ -58,7 +58,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1100108	/* Master, propagated to newvers */
+#define __FreeBSD_version 1100109	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605160956.u4G9umAT025380>