> 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"

Reply via email to