1 /*- 2 * Copyright (c) 2010 Isilon Systems, Inc. 3 * Copyright (c) 2010 iX Systems, Inc. 4 * Copyright (c) 2010 Panasas, Inc. 5 * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice unmodified, this list of conditions, and the following 13 * disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #ifndef _LINUXKPI_LINUX_KOBJECT_H_ 30 #define _LINUXKPI_LINUX_KOBJECT_H_ 31 32 #include <sys/stdarg.h> 33 34 #include <linux/kernel.h> 35 #include <linux/kref.h> 36 #include <linux/list.h> 37 #include <linux/slab.h> 38 #include <linux/spinlock.h> 39 #include <linux/wait.h> 40 #include <linux/workqueue.h> 41 42 struct kobject; 43 struct kset; 44 struct sysctl_oid; 45 46 #define KOBJ_CHANGE 0x01 47 48 struct kobj_type { 49 void (*release)(struct kobject *kobj); 50 const struct sysfs_ops *sysfs_ops; 51 struct attribute **default_attrs; 52 const struct attribute_group **default_groups; 53 }; 54 55 extern const struct kobj_type linux_kfree_type; 56 57 struct kobject { 58 struct kobject *parent; 59 char *name; 60 struct kref kref; 61 const struct kobj_type *ktype; 62 struct list_head entry; 63 union { 64 struct sysctl_oid *oidp; 65 66 /* 67 * On Linux, a `struct kernfs_node *` pointer, representing a 68 * directory in sysfs, is kept in the `sd` struct field. 69 * 70 * We don't have that on FreeBSD because we use sysctls 71 * instead. Let's alias the sysctl OID pointer to `sd`. This 72 * pointer is checked by the DRM drivers using: 73 * if (var->kobj.sd) { 74 * ... 75 * } 76 */ 77 void *sd; 78 }; 79 struct kset *kset; 80 }; 81 82 extern struct kobject *mm_kobj; 83 84 struct attribute { 85 const char *name; 86 struct module *owner; 87 mode_t mode; 88 }; 89 90 extern const struct sysfs_ops kobj_sysfs_ops; 91 92 struct kobj_attribute { 93 struct attribute attr; 94 ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, 95 char *buf); 96 ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, 97 const char *buf, size_t count); 98 }; 99 100 struct kset_uevent_ops { 101 /* TODO */ 102 }; 103 104 struct kset { 105 struct list_head list; 106 spinlock_t list_lock; 107 struct kobject kobj; 108 const struct kset_uevent_ops *uevent_ops; 109 }; 110 111 static inline void 112 kobject_init(struct kobject *kobj, const struct kobj_type *ktype) 113 { 114 115 kref_init(&kobj->kref); 116 INIT_LIST_HEAD(&kobj->entry); 117 kobj->ktype = ktype; 118 kobj->oidp = NULL; 119 } 120 121 void linux_kobject_release(struct kref *kref); 122 123 static inline void 124 kobject_put(struct kobject *kobj) 125 { 126 127 if (kobj) 128 kref_put(&kobj->kref, linux_kobject_release); 129 } 130 131 static inline struct kobject * 132 kobject_get(struct kobject *kobj) 133 { 134 135 if (kobj) 136 kref_get(&kobj->kref); 137 return kobj; 138 } 139 140 struct kobject *kobject_create(void); 141 int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list); 142 int kobject_add(struct kobject *kobj, struct kobject *parent, 143 const char *fmt, ...); 144 145 static inline struct kobject * 146 kobject_create_and_add(const char *name, struct kobject *parent) 147 { 148 struct kobject *kobj; 149 150 kobj = kobject_create(); 151 if (kobj == NULL) 152 return (NULL); 153 if (kobject_add(kobj, parent, "%s", name) == 0) 154 return (kobj); 155 kobject_put(kobj); 156 157 return (NULL); 158 } 159 160 static inline void 161 kobject_del(struct kobject *kobj __unused) 162 { 163 } 164 165 static inline char * 166 kobject_name(const struct kobject *kobj) 167 { 168 169 return kobj->name; 170 } 171 172 int kobject_set_name(struct kobject *kobj, const char *fmt, ...); 173 int kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype, 174 struct kobject *parent, const char *fmt, ...); 175 176 static __inline int 177 kobject_uevent_env(struct kobject *kobj, int action, char *envp[]) 178 { 179 180 /* 181 * iwlwifi(4) sends an INACCESSIBLE event when it detects that the card 182 * (pice endpoint) is gone and it attempts a removal cleanup. 183 * Not sure if we do anything related to udev/sysfs at the moment or 184 * need a shortcut or simply ignore it (for now). 185 */ 186 187 return (0); 188 } 189 190 void kset_init(struct kset *kset); 191 int kset_register(struct kset *kset); 192 void kset_unregister(struct kset *kset); 193 struct kset * kset_create_and_add(const char *name, 194 const struct kset_uevent_ops *u, struct kobject *parent_kobj); 195 196 static inline struct kset * 197 to_kset(struct kobject *kobj) 198 { 199 if (kobj != NULL) 200 return container_of(kobj, struct kset, kobj); 201 else 202 return NULL; 203 } 204 205 static inline struct kset * 206 kset_get(struct kset *kset) 207 { 208 if (kset != NULL) { 209 struct kobject *kobj; 210 211 kobj = kobject_get(&kset->kobj); 212 return to_kset(kobj); 213 } else { 214 return NULL; 215 } 216 } 217 218 static inline void 219 kset_put(struct kset *kset) 220 { 221 if (kset != NULL) 222 kobject_put(&kset->kobj); 223 } 224 225 void linux_kobject_kfree_name(struct kobject *kobj); 226 227 #endif /* _LINUXKPI_LINUX_KOBJECT_H_ */ 228