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-2016 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 * $FreeBSD$ 30 */ 31 #ifndef _LINUX_DEVICE_H_ 32 #define _LINUX_DEVICE_H_ 33 34 #include <linux/err.h> 35 #include <linux/types.h> 36 #include <linux/kobject.h> 37 #include <linux/sysfs.h> 38 #include <linux/list.h> 39 #include <linux/compiler.h> 40 #include <linux/types.h> 41 #include <linux/module.h> 42 #include <linux/workqueue.h> 43 #include <linux/sysfs.h> 44 #include <linux/kdev_t.h> 45 #include <asm/atomic.h> 46 47 #include <sys/bus.h> 48 49 enum irqreturn { IRQ_NONE = 0, IRQ_HANDLED, IRQ_WAKE_THREAD, }; 50 typedef enum irqreturn irqreturn_t; 51 52 struct device; 53 54 struct class { 55 const char *name; 56 struct module *owner; 57 struct kobject kobj; 58 devclass_t bsdclass; 59 void (*class_release)(struct class *class); 60 void (*dev_release)(struct device *dev); 61 char * (*devnode)(struct device *dev, umode_t *mode); 62 }; 63 64 struct device { 65 struct device *parent; 66 struct list_head irqents; 67 device_t bsddev; 68 /* 69 * The following flag is used to determine if the LinuxKPI is 70 * responsible for detaching the BSD device or not. If the 71 * LinuxKPI got the BSD device using devclass_get_device(), it 72 * must not try to detach or delete it, because it's already 73 * done somewhere else. 74 */ 75 bool bsddev_attached_here; 76 dev_t devt; 77 struct class *class; 78 void (*release)(struct device *dev); 79 struct kobject kobj; 80 uint64_t *dma_mask; 81 void *driver_data; 82 unsigned int irq; 83 #define LINUX_IRQ_INVALID 65535 84 unsigned int msix; 85 unsigned int msix_max; 86 const struct attribute_group **groups; 87 }; 88 89 extern struct device linux_root_device; 90 extern struct kobject linux_class_root; 91 extern const struct kobj_type linux_dev_ktype; 92 extern const struct kobj_type linux_class_ktype; 93 94 struct class_attribute { 95 struct attribute attr; 96 ssize_t (*show)(struct class *, struct class_attribute *, char *); 97 ssize_t (*store)(struct class *, struct class_attribute *, const char *, size_t); 98 const void *(*namespace)(struct class *, const struct class_attribute *); 99 }; 100 101 #define CLASS_ATTR(_name, _mode, _show, _store) \ 102 struct class_attribute class_attr_##_name = \ 103 { { #_name, NULL, _mode }, _show, _store } 104 105 struct device_attribute { 106 struct attribute attr; 107 ssize_t (*show)(struct device *, 108 struct device_attribute *, char *); 109 ssize_t (*store)(struct device *, 110 struct device_attribute *, const char *, 111 size_t); 112 }; 113 114 #define DEVICE_ATTR(_name, _mode, _show, _store) \ 115 struct device_attribute dev_attr_##_name = \ 116 { { #_name, NULL, _mode }, _show, _store } 117 118 /* Simple class attribute that is just a static string */ 119 struct class_attribute_string { 120 struct class_attribute attr; 121 char *str; 122 }; 123 124 static inline ssize_t 125 show_class_attr_string(struct class *class, 126 struct class_attribute *attr, char *buf) 127 { 128 struct class_attribute_string *cs; 129 cs = container_of(attr, struct class_attribute_string, attr); 130 return snprintf(buf, PAGE_SIZE, "%s\n", cs->str); 131 } 132 133 /* Currently read-only only */ 134 #define _CLASS_ATTR_STRING(_name, _mode, _str) \ 135 { __ATTR(_name, _mode, show_class_attr_string, NULL), _str } 136 #define CLASS_ATTR_STRING(_name, _mode, _str) \ 137 struct class_attribute_string class_attr_##_name = \ 138 _CLASS_ATTR_STRING(_name, _mode, _str) 139 140 #define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 141 #define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 142 #define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 143 #define dev_notice(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 144 #define dev_printk(lvl, dev, fmt, ...) \ 145 device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 146 147 #define dev_err_ratelimited(dev, ...) do { \ 148 static linux_ratelimit_t __ratelimited; \ 149 if (linux_ratelimited(&__ratelimited)) \ 150 dev_err(dev, __VA_ARGS__); \ 151 } while (0) 152 153 #define dev_warn_ratelimited(dev, ...) do { \ 154 static linux_ratelimit_t __ratelimited; \ 155 if (linux_ratelimited(&__ratelimited)) \ 156 dev_warn(dev, __VA_ARGS__); \ 157 } while (0) 158 159 static inline void * 160 dev_get_drvdata(const struct device *dev) 161 { 162 163 return dev->driver_data; 164 } 165 166 static inline void 167 dev_set_drvdata(struct device *dev, void *data) 168 { 169 170 dev->driver_data = data; 171 } 172 173 static inline struct device * 174 get_device(struct device *dev) 175 { 176 177 if (dev) 178 kobject_get(&dev->kobj); 179 180 return (dev); 181 } 182 183 static inline char * 184 dev_name(const struct device *dev) 185 { 186 187 return kobject_name(&dev->kobj); 188 } 189 190 #define dev_set_name(_dev, _fmt, ...) \ 191 kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__) 192 193 static inline void 194 put_device(struct device *dev) 195 { 196 197 if (dev) 198 kobject_put(&dev->kobj); 199 } 200 201 static inline int 202 class_register(struct class *class) 203 { 204 205 class->bsdclass = devclass_create(class->name); 206 kobject_init(&class->kobj, &linux_class_ktype); 207 kobject_set_name(&class->kobj, class->name); 208 kobject_add(&class->kobj, &linux_class_root, class->name); 209 210 return (0); 211 } 212 213 static inline void 214 class_unregister(struct class *class) 215 { 216 217 kobject_put(&class->kobj); 218 } 219 220 static inline struct device *kobj_to_dev(struct kobject *kobj) 221 { 222 return container_of(kobj, struct device, kobj); 223 } 224 225 /* 226 * Devices are registered and created for exporting to sysfs. Create 227 * implies register and register assumes the device fields have been 228 * setup appropriately before being called. 229 */ 230 static inline void 231 device_initialize(struct device *dev) 232 { 233 device_t bsddev = NULL; 234 int unit = -1; 235 236 if (dev->devt) { 237 unit = MINOR(dev->devt); 238 bsddev = devclass_get_device(dev->class->bsdclass, unit); 239 dev->bsddev_attached_here = false; 240 } else if (dev->parent == NULL) { 241 bsddev = devclass_get_device(dev->class->bsdclass, 0); 242 dev->bsddev_attached_here = false; 243 } else { 244 dev->bsddev_attached_here = true; 245 } 246 247 if (bsddev == NULL && dev->parent != NULL) { 248 bsddev = device_add_child(dev->parent->bsddev, 249 dev->class->kobj.name, unit); 250 } 251 252 if (bsddev != NULL) 253 device_set_softc(bsddev, dev); 254 255 dev->bsddev = bsddev; 256 MPASS(dev->bsddev != NULL); 257 kobject_init(&dev->kobj, &linux_dev_ktype); 258 } 259 260 static inline int 261 device_add(struct device *dev) 262 { 263 if (dev->bsddev != NULL) { 264 if (dev->devt == 0) 265 dev->devt = makedev(0, device_get_unit(dev->bsddev)); 266 } 267 kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev)); 268 return (0); 269 } 270 271 static inline void 272 device_create_release(struct device *dev) 273 { 274 kfree(dev); 275 } 276 277 static inline struct device * 278 device_create_groups_vargs(struct class *class, struct device *parent, 279 dev_t devt, void *drvdata, const struct attribute_group **groups, 280 const char *fmt, va_list args) 281 { 282 struct device *dev = NULL; 283 int retval = -ENODEV; 284 285 if (class == NULL || IS_ERR(class)) 286 goto error; 287 288 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 289 if (!dev) { 290 retval = -ENOMEM; 291 goto error; 292 } 293 294 dev->devt = devt; 295 dev->class = class; 296 dev->parent = parent; 297 dev->groups = groups; 298 dev->release = device_create_release; 299 /* device_initialize() needs the class and parent to be set */ 300 device_initialize(dev); 301 dev_set_drvdata(dev, drvdata); 302 303 retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 304 if (retval) 305 goto error; 306 307 retval = device_add(dev); 308 if (retval) 309 goto error; 310 311 return dev; 312 313 error: 314 put_device(dev); 315 return ERR_PTR(retval); 316 } 317 318 static inline struct device * 319 device_create_with_groups(struct class *class, 320 struct device *parent, dev_t devt, void *drvdata, 321 const struct attribute_group **groups, const char *fmt, ...) 322 { 323 va_list vargs; 324 struct device *dev; 325 326 va_start(vargs, fmt); 327 dev = device_create_groups_vargs(class, parent, devt, drvdata, 328 groups, fmt, vargs); 329 va_end(vargs); 330 return dev; 331 } 332 333 static inline int 334 device_register(struct device *dev) 335 { 336 device_t bsddev = NULL; 337 int unit = -1; 338 339 if (dev->bsddev != NULL) 340 goto done; 341 342 if (dev->devt) { 343 unit = MINOR(dev->devt); 344 bsddev = devclass_get_device(dev->class->bsdclass, unit); 345 dev->bsddev_attached_here = false; 346 } else if (dev->parent == NULL) { 347 bsddev = devclass_get_device(dev->class->bsdclass, 0); 348 dev->bsddev_attached_here = false; 349 } else { 350 dev->bsddev_attached_here = true; 351 } 352 if (bsddev == NULL && dev->parent != NULL) { 353 bsddev = device_add_child(dev->parent->bsddev, 354 dev->class->kobj.name, unit); 355 } 356 if (bsddev != NULL) { 357 if (dev->devt == 0) 358 dev->devt = makedev(0, device_get_unit(bsddev)); 359 device_set_softc(bsddev, dev); 360 } 361 dev->bsddev = bsddev; 362 done: 363 kobject_init(&dev->kobj, &linux_dev_ktype); 364 kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev)); 365 366 return (0); 367 } 368 369 static inline void 370 device_unregister(struct device *dev) 371 { 372 device_t bsddev; 373 374 bsddev = dev->bsddev; 375 dev->bsddev = NULL; 376 377 if (bsddev != NULL && dev->bsddev_attached_here) { 378 mtx_lock(&Giant); 379 device_delete_child(device_get_parent(bsddev), bsddev); 380 mtx_unlock(&Giant); 381 } 382 put_device(dev); 383 } 384 385 static inline void 386 device_del(struct device *dev) 387 { 388 device_t bsddev; 389 390 bsddev = dev->bsddev; 391 dev->bsddev = NULL; 392 393 if (bsddev != NULL && dev->bsddev_attached_here) { 394 mtx_lock(&Giant); 395 device_delete_child(device_get_parent(bsddev), bsddev); 396 mtx_unlock(&Giant); 397 } 398 } 399 400 struct device *device_create(struct class *class, struct device *parent, 401 dev_t devt, void *drvdata, const char *fmt, ...); 402 403 static inline void 404 device_destroy(struct class *class, dev_t devt) 405 { 406 device_t bsddev; 407 int unit; 408 409 unit = MINOR(devt); 410 bsddev = devclass_get_device(class->bsdclass, unit); 411 if (bsddev != NULL) 412 device_unregister(device_get_softc(bsddev)); 413 } 414 415 static inline void 416 linux_class_kfree(struct class *class) 417 { 418 419 kfree(class); 420 } 421 422 static inline struct class * 423 class_create(struct module *owner, const char *name) 424 { 425 struct class *class; 426 int error; 427 428 class = kzalloc(sizeof(*class), M_WAITOK); 429 class->owner = owner; 430 class->name = name; 431 class->class_release = linux_class_kfree; 432 error = class_register(class); 433 if (error) { 434 kfree(class); 435 return (NULL); 436 } 437 438 return (class); 439 } 440 441 static inline void 442 class_destroy(struct class *class) 443 { 444 445 if (class == NULL) 446 return; 447 class_unregister(class); 448 } 449 450 static inline int 451 device_create_file(struct device *dev, const struct device_attribute *attr) 452 { 453 454 if (dev) 455 return sysfs_create_file(&dev->kobj, &attr->attr); 456 return -EINVAL; 457 } 458 459 static inline void 460 device_remove_file(struct device *dev, const struct device_attribute *attr) 461 { 462 463 if (dev) 464 sysfs_remove_file(&dev->kobj, &attr->attr); 465 } 466 467 static inline int 468 class_create_file(struct class *class, const struct class_attribute *attr) 469 { 470 471 if (class) 472 return sysfs_create_file(&class->kobj, &attr->attr); 473 return -EINVAL; 474 } 475 476 static inline void 477 class_remove_file(struct class *class, const struct class_attribute *attr) 478 { 479 480 if (class) 481 sysfs_remove_file(&class->kobj, &attr->attr); 482 } 483 484 static inline int 485 dev_to_node(struct device *dev) 486 { 487 return -1; 488 } 489 490 char *kvasprintf(gfp_t, const char *, va_list); 491 char *kasprintf(gfp_t, const char *, ...); 492 493 #endif /* _LINUX_DEVICE_H_ */ 494