Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/src/linux_compat.c
Show First 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
panic_cmp(struct rb_node *one, struct rb_node *two) | panic_cmp(struct rb_node *one, struct rb_node *two) | ||||
{ | { | ||||
panic("no cmp"); | panic("no cmp"); | ||||
} | } | ||||
RB_GENERATE(linux_root, rb_node, __entry, panic_cmp); | 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 | static void | ||||
linux_device_release(struct device *dev) | linux_device_release(struct device *dev) | ||||
{ | { | ||||
pr_debug("linux_device_release: %s\n", dev_name(dev)); | pr_debug("linux_device_release: %s\n", dev_name(dev)); | ||||
kfree(dev); | kfree(dev); | ||||
} | } | ||||
static ssize_t | static ssize_t | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | |||||
va_start(args, fmt); | va_start(args, fmt); | ||||
kobject_set_name_vargs(&dev->kobj, fmt, args); | kobject_set_name_vargs(&dev->kobj, fmt, args); | ||||
va_end(args); | va_end(args); | ||||
device_register(dev); | device_register(dev); | ||||
return (dev); | 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 | static void | ||||
linux_kq_lock(void *arg) | linux_kq_lock(void *arg) | ||||
{ | { | ||||
spinlock_t *s = arg; | spinlock_t *s = arg; | ||||
spin_lock(s); | spin_lock(s); | ||||
} | } | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 1,982 Lines • ▼ Show 20 Lines | |||||
init_waitqueue_head(&linux_bit_waitq); | init_waitqueue_head(&linux_bit_waitq); | ||||
init_waitqueue_head(&linux_var_waitq); | init_waitqueue_head(&linux_var_waitq); | ||||
} | } | ||||
SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL); | SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL); | ||||
static void | static void | ||||
linux_compat_uninit(void *arg) | linux_compat_uninit(void *arg) | ||||
{ | { | ||||
linux_kobject_kfree_name(&linux_class_root); | kobject_kfree_name(&linux_class_root); | ||||
linux_kobject_kfree_name(&linux_root_device.kobj); | kobject_kfree_name(&linux_root_device.kobj); | ||||
linux_kobject_kfree_name(&linux_class_misc.kobj); | kobject_kfree_name(&linux_class_misc.kobj); | ||||
bz: Can we internally please keep the prefix even if it changed and can them by their proper name… | |||||
mtx_destroy(&vmmaplock); | mtx_destroy(&vmmaplock); | ||||
spin_lock_destroy(&pci_lock); | spin_lock_destroy(&pci_lock); | ||||
rw_destroy(&linux_vma_lock); | rw_destroy(&linux_vma_lock); | ||||
} | } | ||||
SYSUNINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_uninit, NULL); | SYSUNINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_uninit, NULL); | ||||
/* | /* | ||||
* NOTE: Linux frequently uses "unsigned long" for pointer to integer | * NOTE: Linux frequently uses "unsigned long" for pointer to integer | ||||
* conversion and vice versa, where in FreeBSD "uintptr_t" would be | * conversion and vice versa, where in FreeBSD "uintptr_t" would be | ||||
* used. Assert these types have the same size, else some parts of the | * used. Assert these types have the same size, else some parts of the | ||||
* LinuxKPI may not work like expected: | * LinuxKPI may not work like expected: | ||||
*/ | */ | ||||
CTASSERT(sizeof(unsigned long) == sizeof(uintptr_t)); | CTASSERT(sizeof(unsigned long) == sizeof(uintptr_t)); | ||||
Context not available. |
Can we internally please keep the prefix even if it changed and can them by their proper name with the lkpi_ prefix?