Index: sys/compat/linuxkpi/common/include/linux/kobject.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/kobject.h +++ sys/compat/linuxkpi/common/include/linux/kobject.h @@ -74,6 +74,31 @@ const char *buf, size_t count); }; +int lkpi_kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list); +int lkpi_kobject_add(struct kobject *kobj, struct kobject *parent, + const char *fmt, ...); +int lkpi_kobject_set_name(struct kobject *kobj, const char *fmt, ...); +int lkpi_kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype, + struct kobject *parent, const char *fmt, ...); +void lkpi_kobject_kfree_name(struct kobject *kobj); +int lkpi_kobject_add_complete(struct kobject *kobj, struct kobject *parent); +void lkpi_kobject_release(struct kref *kref); + +#define kobject_set_name_vargs(kobj, fmt, va) \ + lkpi_kobject_set_name_vargs(kobj, fmt, va) +#define kobject_add(kobj, parent, fmt, ...) \ + lkpi_kobject_add(kobj, parent, fmt, ##__VA_ARGS__) +#define kobject_set_name(kobj, fmt, ...) \ + lkpi_kobject_set_name(kobj, fmt, ##__VA_ARGS__) +#define kobject_init_and_add(kobj, ktype, parent, fmt, ...) \ + lkpi_kobject_init_and_add(kobj, ktype, parent, fmt, ##__VA_ARGS__) +#define kobject_kfree_name(kobj) \ + lkpi_kobject_kfree_name(kobj) +#define kobject_add_complete(kobj, parent) \ + lkpi_kobject_add_complete(kobj, parent) +#define kobject_release(kobj) \ + lkpi_kobject_release(kobj) + static inline void kobject_init(struct kobject *kobj, const struct kobj_type *ktype) { @@ -84,14 +109,12 @@ kobj->oidp = NULL; } -void linux_kobject_release(struct kref *kref); - static inline void kobject_put(struct kobject *kobj) { if (kobj) - kref_put(&kobj->kref, linux_kobject_release); + kref_put(&kobj->kref, lkpi_kobject_release); } static inline struct kobject * @@ -103,10 +126,6 @@ return kobj; } -int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list); -int kobject_add(struct kobject *kobj, struct kobject *parent, - const char *fmt, ...); - static inline struct kobject * kobject_create(void) { @@ -147,8 +166,4 @@ return kobj->name; } -int kobject_set_name(struct kobject *kobj, const char *fmt, ...); -int kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype, - struct kobject *parent, const char *fmt, ...); - #endif /* _LINUX_KOBJECT_H_ */ Index: sys/compat/linuxkpi/common/include/linux/miscdevice.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/miscdevice.h +++ sys/compat/linuxkpi/common/include/linux/miscdevice.h @@ -33,6 +33,7 @@ #define MISC_DYNAMIC_MINOR -1 +#include #include #include Index: sys/compat/linuxkpi/common/src/linux_compat.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_compat.c +++ sys/compat/linuxkpi/common/src/linux_compat.c @@ -131,132 +131,6 @@ RB_GENERATE(linux_root, rb_node, __entry, panic_cmp); -int -kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list args) -{ - va_list tmp_va; - int len; - char *old; - char *name; - char dummy; - - old = kobj->name; - - if (old && fmt == NULL) - return (0); - - /* compute length of string */ - va_copy(tmp_va, args); - len = vsnprintf(&dummy, 0, fmt, tmp_va); - va_end(tmp_va); - - /* account for zero termination */ - len++; - - /* check for error */ - if (len < 1) - return (-EINVAL); - - /* allocate memory for string */ - name = kzalloc(len, GFP_KERNEL); - if (name == NULL) - return (-ENOMEM); - vsnprintf(name, len, fmt, args); - kobj->name = name; - - /* free old string */ - kfree(old); - - /* filter new string */ - for (; *name != '\0'; name++) - if (*name == '/') - *name = '!'; - return (0); -} - -int -kobject_set_name(struct kobject *kobj, const char *fmt, ...) -{ - va_list args; - int error; - - va_start(args, fmt); - error = kobject_set_name_vargs(kobj, fmt, args); - va_end(args); - - return (error); -} - -static int -kobject_add_complete(struct kobject *kobj, struct kobject *parent) -{ - const struct kobj_type *t; - int error; - - kobj->parent = parent; - error = sysfs_create_dir(kobj); - if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) { - struct attribute **attr; - t = kobj->ktype; - - for (attr = t->default_attrs; *attr != NULL; attr++) { - error = sysfs_create_file(kobj, *attr); - if (error) - break; - } - if (error) - sysfs_remove_dir(kobj); - } - return (error); -} - -int -kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...) -{ - va_list args; - int error; - - va_start(args, fmt); - error = kobject_set_name_vargs(kobj, fmt, args); - va_end(args); - if (error) - return (error); - - return kobject_add_complete(kobj, parent); -} - -void -linux_kobject_release(struct kref *kref) -{ - struct kobject *kobj; - char *name; - - kobj = container_of(kref, struct kobject, kref); - sysfs_remove_dir(kobj); - name = kobj->name; - if (kobj->ktype && kobj->ktype->release) - kobj->ktype->release(kobj); - kfree(name); -} - -static void -linux_kobject_kfree(struct kobject *kobj) -{ - kfree(kobj); -} - -static void -linux_kobject_kfree_name(struct kobject *kobj) -{ - if (kobj) { - kfree(kobj->name); - } -} - -const struct kobj_type linux_kfree_type = { - .release = linux_kobject_kfree -}; - static void linux_device_release(struct device *dev) { @@ -386,26 +260,6 @@ return (dev); } -int -kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype, - struct kobject *parent, const char *fmt, ...) -{ - va_list args; - int error; - - kobject_init(kobj, ktype); - kobj->ktype = ktype; - kobj->parent = parent; - kobj->name = NULL; - - va_start(args, fmt); - error = kobject_set_name_vargs(kobj, fmt, args); - va_end(args); - if (error) - return (error); - return kobject_add_complete(kobj, parent); -} - static void linux_kq_lock(void *arg) { @@ -2532,9 +2386,9 @@ static void linux_compat_uninit(void *arg) { - linux_kobject_kfree_name(&linux_class_root); - linux_kobject_kfree_name(&linux_root_device.kobj); - linux_kobject_kfree_name(&linux_class_misc.kobj); + kobject_kfree_name(&linux_class_root); + kobject_kfree_name(&linux_root_device.kobj); + kobject_kfree_name(&linux_class_misc.kobj); mtx_destroy(&vmmaplock); spin_lock_destroy(&pci_lock); Index: sys/compat/linuxkpi/common/src/linux_kobject.c =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/src/linux_kobject.c @@ -0,0 +1,180 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * Copyright (c) 2013-2018 Mellanox Technologies, Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +int +lkpi_kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list args) +{ + va_list tmp_va; + int len; + char *old; + char *name; + char dummy; + + old = kobj->name; + + if (old && fmt == NULL) + return (0); + + /* compute length of string */ + va_copy(tmp_va, args); + len = vsnprintf(&dummy, 0, fmt, tmp_va); + va_end(tmp_va); + + /* account for zero termination */ + len++; + + /* check for error */ + if (len < 1) + return (-EINVAL); + + /* allocate memory for string */ + name = kzalloc(len, GFP_KERNEL); + if (name == NULL) + return (-ENOMEM); + vsnprintf(name, len, fmt, args); + kobj->name = name; + + /* free old string */ + kfree(old); + + /* filter new string */ + for (; *name != '\0'; name++) + if (*name == '/') + *name = '!'; + return (0); +} + +int +lkpi_kobject_set_name(struct kobject *kobj, const char *fmt, ...) +{ + va_list args; + int error; + + va_start(args, fmt); + error = kobject_set_name_vargs(kobj, fmt, args); + va_end(args); + + return (error); +} + +int +lkpi_kobject_add_complete(struct kobject *kobj, struct kobject *parent) +{ + const struct kobj_type *t; + int error; + + kobj->parent = parent; + error = sysfs_create_dir(kobj); + if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) { + struct attribute **attr; + t = kobj->ktype; + + for (attr = t->default_attrs; *attr != NULL; attr++) { + error = sysfs_create_file(kobj, *attr); + if (error) + break; + } + if (error) + sysfs_remove_dir(kobj); + } + return (error); +} + +int +lkpi_kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...) +{ + va_list args; + int error; + + va_start(args, fmt); + error = kobject_set_name_vargs(kobj, fmt, args); + va_end(args); + if (error) + return (error); + + return kobject_add_complete(kobj, parent); +} + +int +lkpi_kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype, + struct kobject *parent, const char *fmt, ...) +{ + va_list args; + int error; + + kobject_init(kobj, ktype); + kobj->ktype = ktype; + kobj->parent = parent; + kobj->name = NULL; + + va_start(args, fmt); + error = kobject_set_name_vargs(kobj, fmt, args); + va_end(args); + if (error) + return (error); + return kobject_add_complete(kobj, parent); +} + +void +lkpi_kobject_release(struct kref *kref) +{ + struct kobject *kobj; + char *name; + + kobj = container_of(kref, struct kobject, kref); + sysfs_remove_dir(kobj); + name = kobj->name; + if (kobj->ktype && kobj->ktype->release) + kobj->ktype->release(kobj); + kfree(name); +} + +static void +lkpi_kobject_kfree(struct kobject *kobj) +{ + kfree(kobj); +} + +void +lkpi_kobject_kfree_name(struct kobject *kobj) +{ + if (kobj) { + kfree(kobj->name); + } +} + +const struct kobj_type linux_kfree_type = { + .release = lkpi_kobject_kfree +}; Index: sys/modules/linuxkpi/Makefile =================================================================== --- sys/modules/linuxkpi/Makefile +++ sys/modules/linuxkpi/Makefile @@ -9,6 +9,7 @@ linux_idr.c \ linux_kmod.c \ linux_kthread.c \ + linux_kobject.c \ linux_lock.c \ linux_page.c \ linux_pci.c \