> On May 16, 2016, at 02:56, Hans Petter Selasky <hsela...@freebsd.org> wrote: > > 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)
Dumb question — couldn’t we run the check without locking Giant, then delete the child, e.g. if (bsddev != NULL) { mtx_lock(&Giant); device_delete_child(device_get_parent(bsddev), bsddev); mtx_unlock(&Giant); } put_device(dev); > 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, > _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"