device.h revision 289644
1219820Sjeff/*- 2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc. 3219820Sjeff * Copyright (c) 2010 iX Systems, Inc. 4219820Sjeff * Copyright (c) 2010 Panasas, Inc. 5270710Shselasky * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. 6219820Sjeff * All rights reserved. 7219820Sjeff * 8219820Sjeff * Redistribution and use in source and binary forms, with or without 9219820Sjeff * modification, are permitted provided that the following conditions 10219820Sjeff * are met: 11219820Sjeff * 1. Redistributions of source code must retain the above copyright 12219820Sjeff * notice unmodified, this list of conditions, and the following 13219820Sjeff * disclaimer. 14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 15219820Sjeff * notice, this list of conditions and the following disclaimer in the 16219820Sjeff * documentation and/or other materials provided with the distribution. 17219820Sjeff * 18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28289644Shselasky * 29289644Shselasky * $FreeBSD: head/sys/ofed/include/linux/device.h 289644 2015-10-20 19:08:26Z hselasky $ 30219820Sjeff */ 31219820Sjeff#ifndef _LINUX_DEVICE_H_ 32219820Sjeff#define _LINUX_DEVICE_H_ 33219820Sjeff 34219820Sjeff#include <linux/types.h> 35219820Sjeff#include <linux/kobject.h> 36219820Sjeff#include <linux/list.h> 37219820Sjeff#include <linux/compiler.h> 38219820Sjeff#include <linux/types.h> 39219820Sjeff#include <linux/module.h> 40219820Sjeff#include <linux/workqueue.h> 41219820Sjeff#include <linux/sysfs.h> 42219820Sjeff#include <linux/kdev_t.h> 43219820Sjeff#include <asm/atomic.h> 44219820Sjeff 45219820Sjeff#include <sys/bus.h> 46219820Sjeff 47219820Sjeffenum irqreturn { IRQ_NONE = 0, IRQ_HANDLED, IRQ_WAKE_THREAD, }; 48219820Sjefftypedef enum irqreturn irqreturn_t; 49219820Sjeff 50219820Sjeffstruct class { 51219820Sjeff const char *name; 52219820Sjeff struct module *owner; 53219820Sjeff struct kobject kobj; 54219820Sjeff devclass_t bsdclass; 55219820Sjeff void (*class_release)(struct class *class); 56219820Sjeff void (*dev_release)(struct device *dev); 57270710Shselasky char * (*devnode)(struct device *dev, umode_t *mode); 58219820Sjeff}; 59219820Sjeff 60219820Sjeffstruct device { 61219820Sjeff struct device *parent; 62219820Sjeff struct list_head irqents; 63219820Sjeff device_t bsddev; 64219820Sjeff dev_t devt; 65219820Sjeff struct class *class; 66219820Sjeff void (*release)(struct device *dev); 67219820Sjeff struct kobject kobj; 68219820Sjeff uint64_t *dma_mask; 69219820Sjeff void *driver_data; 70219820Sjeff unsigned int irq; 71219820Sjeff unsigned int msix; 72219820Sjeff unsigned int msix_max; 73219820Sjeff}; 74219820Sjeff 75219820Sjeffextern struct device linux_rootdev; 76219820Sjeffextern struct kobject class_root; 77219820Sjeff 78219820Sjeffstruct class_attribute { 79270710Shselasky struct attribute attr; 80270710Shselasky ssize_t (*show)(struct class *, struct class_attribute *, char *); 81270710Shselasky ssize_t (*store)(struct class *, struct class_attribute *, const char *, size_t); 82270710Shselasky const void *(*namespace)(struct class *, const struct class_attribute *); 83219820Sjeff}; 84270710Shselasky 85219820Sjeff#define CLASS_ATTR(_name, _mode, _show, _store) \ 86219820Sjeff struct class_attribute class_attr_##_name = \ 87219820Sjeff { { #_name, NULL, _mode }, _show, _store } 88219820Sjeff 89219820Sjeffstruct device_attribute { 90219820Sjeff struct attribute attr; 91219820Sjeff ssize_t (*show)(struct device *, 92270710Shselasky struct device_attribute *, char *); 93219820Sjeff ssize_t (*store)(struct device *, 94270710Shselasky struct device_attribute *, const char *, 95270710Shselasky size_t); 96219820Sjeff}; 97219820Sjeff 98219820Sjeff#define DEVICE_ATTR(_name, _mode, _show, _store) \ 99219820Sjeff struct device_attribute dev_attr_##_name = \ 100219820Sjeff { { #_name, NULL, _mode }, _show, _store } 101219820Sjeff 102270710Shselasky/* Simple class attribute that is just a static string */ 103270710Shselaskystruct class_attribute_string { 104270710Shselasky struct class_attribute attr; 105270710Shselasky char *str; 106270710Shselasky}; 107270710Shselasky 108270710Shselaskystatic inline ssize_t 109270710Shselaskyshow_class_attr_string(struct class *class, 110270710Shselasky struct class_attribute *attr, char *buf) 111270710Shselasky{ 112270710Shselasky struct class_attribute_string *cs; 113270710Shselasky cs = container_of(attr, struct class_attribute_string, attr); 114270710Shselasky return snprintf(buf, PAGE_SIZE, "%s\n", cs->str); 115270710Shselasky} 116270710Shselasky 117270710Shselasky/* Currently read-only only */ 118270710Shselasky#define _CLASS_ATTR_STRING(_name, _mode, _str) \ 119270710Shselasky { __ATTR(_name, _mode, show_class_attr_string, NULL), _str } 120270710Shselasky#define CLASS_ATTR_STRING(_name, _mode, _str) \ 121270710Shselasky struct class_attribute_string class_attr_##_name = \ 122270710Shselasky _CLASS_ATTR_STRING(_name, _mode, _str) 123270710Shselasky 124219820Sjeff#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 125219820Sjeff#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 126219820Sjeff#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 127219820Sjeff#define dev_printk(lvl, dev, fmt, ...) \ 128219820Sjeff device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 129219820Sjeff 130219820Sjeffstatic inline void * 131219820Sjeffdev_get_drvdata(struct device *dev) 132219820Sjeff{ 133219820Sjeff 134219820Sjeff return dev->driver_data; 135219820Sjeff} 136219820Sjeff 137219820Sjeffstatic inline void 138219820Sjeffdev_set_drvdata(struct device *dev, void *data) 139219820Sjeff{ 140219820Sjeff 141219820Sjeff dev->driver_data = data; 142219820Sjeff} 143219820Sjeff 144219820Sjeffstatic inline struct device * 145219820Sjeffget_device(struct device *dev) 146219820Sjeff{ 147219820Sjeff 148219820Sjeff if (dev) 149219820Sjeff kobject_get(&dev->kobj); 150219820Sjeff 151219820Sjeff return (dev); 152219820Sjeff} 153219820Sjeff 154219820Sjeffstatic inline char * 155219820Sjeffdev_name(const struct device *dev) 156219820Sjeff{ 157219820Sjeff 158219820Sjeff return kobject_name(&dev->kobj); 159219820Sjeff} 160219820Sjeff 161219820Sjeff#define dev_set_name(_dev, _fmt, ...) \ 162219820Sjeff kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__) 163219820Sjeff 164219820Sjeffstatic inline void 165219820Sjeffput_device(struct device *dev) 166219820Sjeff{ 167219820Sjeff 168219820Sjeff if (dev) 169219820Sjeff kobject_put(&dev->kobj); 170219820Sjeff} 171219820Sjeff 172219820Sjeffstatic inline ssize_t 173219820Sjeffclass_show(struct kobject *kobj, struct attribute *attr, char *buf) 174219820Sjeff{ 175219820Sjeff struct class_attribute *dattr; 176219820Sjeff ssize_t error; 177219820Sjeff 178219820Sjeff dattr = container_of(attr, struct class_attribute, attr); 179219820Sjeff error = -EIO; 180219820Sjeff if (dattr->show) 181219820Sjeff error = dattr->show(container_of(kobj, struct class, kobj), 182270710Shselasky dattr, buf); 183219820Sjeff return (error); 184219820Sjeff} 185219820Sjeff 186219820Sjeffstatic inline ssize_t 187219820Sjeffclass_store(struct kobject *kobj, struct attribute *attr, const char *buf, 188219820Sjeff size_t count) 189219820Sjeff{ 190219820Sjeff struct class_attribute *dattr; 191219820Sjeff ssize_t error; 192219820Sjeff 193219820Sjeff dattr = container_of(attr, struct class_attribute, attr); 194219820Sjeff error = -EIO; 195219820Sjeff if (dattr->store) 196219820Sjeff error = dattr->store(container_of(kobj, struct class, kobj), 197270710Shselasky dattr, buf, count); 198219820Sjeff return (error); 199219820Sjeff} 200219820Sjeff 201219820Sjeffstatic inline void 202219820Sjeffclass_release(struct kobject *kobj) 203219820Sjeff{ 204219820Sjeff struct class *class; 205219820Sjeff 206219820Sjeff class = container_of(kobj, struct class, kobj); 207219820Sjeff if (class->class_release) 208219820Sjeff class->class_release(class); 209219820Sjeff} 210219820Sjeff 211219820Sjeffstatic struct sysfs_ops class_sysfs = { 212219820Sjeff .show = class_show, 213219820Sjeff .store = class_store, 214219820Sjeff}; 215219820Sjeffstatic struct kobj_type class_ktype = { 216219820Sjeff .release = class_release, 217219820Sjeff .sysfs_ops = &class_sysfs 218219820Sjeff}; 219219820Sjeff 220219820Sjeffstatic inline int 221219820Sjeffclass_register(struct class *class) 222219820Sjeff{ 223219820Sjeff 224219820Sjeff class->bsdclass = devclass_create(class->name); 225219820Sjeff kobject_init(&class->kobj, &class_ktype); 226219820Sjeff kobject_set_name(&class->kobj, class->name); 227219820Sjeff kobject_add(&class->kobj, &class_root, class->name); 228219820Sjeff 229219820Sjeff return (0); 230219820Sjeff} 231219820Sjeff 232219820Sjeffstatic inline void 233219820Sjeffclass_unregister(struct class *class) 234219820Sjeff{ 235219820Sjeff 236219820Sjeff kobject_put(&class->kobj); 237219820Sjeff} 238219820Sjeff 239219820Sjeffstatic inline void 240219820Sjeffdevice_release(struct kobject *kobj) 241219820Sjeff{ 242219820Sjeff struct device *dev; 243219820Sjeff 244219820Sjeff dev = container_of(kobj, struct device, kobj); 245219820Sjeff /* This is the precedence defined by linux. */ 246219820Sjeff if (dev->release) 247219820Sjeff dev->release(dev); 248219820Sjeff else if (dev->class && dev->class->dev_release) 249219820Sjeff dev->class->dev_release(dev); 250219820Sjeff} 251219820Sjeff 252219820Sjeffstatic inline ssize_t 253219820Sjeffdev_show(struct kobject *kobj, struct attribute *attr, char *buf) 254219820Sjeff{ 255219820Sjeff struct device_attribute *dattr; 256219820Sjeff ssize_t error; 257219820Sjeff 258219820Sjeff dattr = container_of(attr, struct device_attribute, attr); 259219820Sjeff error = -EIO; 260219820Sjeff if (dattr->show) 261219820Sjeff error = dattr->show(container_of(kobj, struct device, kobj), 262219820Sjeff dattr, buf); 263219820Sjeff return (error); 264219820Sjeff} 265219820Sjeff 266219820Sjeffstatic inline ssize_t 267219820Sjeffdev_store(struct kobject *kobj, struct attribute *attr, const char *buf, 268219820Sjeff size_t count) 269219820Sjeff{ 270219820Sjeff struct device_attribute *dattr; 271219820Sjeff ssize_t error; 272219820Sjeff 273219820Sjeff dattr = container_of(attr, struct device_attribute, attr); 274219820Sjeff error = -EIO; 275219820Sjeff if (dattr->store) 276219820Sjeff error = dattr->store(container_of(kobj, struct device, kobj), 277219820Sjeff dattr, buf, count); 278219820Sjeff return (error); 279219820Sjeff} 280219820Sjeff 281219820Sjeffstatic struct sysfs_ops dev_sysfs = { .show = dev_show, .store = dev_store, }; 282219820Sjeffstatic struct kobj_type dev_ktype = { 283219820Sjeff .release = device_release, 284219820Sjeff .sysfs_ops = &dev_sysfs 285219820Sjeff}; 286219820Sjeff 287219820Sjeff/* 288219820Sjeff * Devices are registered and created for exporting to sysfs. create 289219820Sjeff * implies register and register assumes the device fields have been 290219820Sjeff * setup appropriately before being called. 291219820Sjeff */ 292219820Sjeffstatic inline int 293219820Sjeffdevice_register(struct device *dev) 294219820Sjeff{ 295219820Sjeff device_t bsddev; 296219820Sjeff int unit; 297219820Sjeff 298219820Sjeff bsddev = NULL; 299219820Sjeff if (dev->devt) { 300219820Sjeff unit = MINOR(dev->devt); 301219820Sjeff bsddev = devclass_get_device(dev->class->bsdclass, unit); 302219820Sjeff } else 303219820Sjeff unit = -1; 304219820Sjeff if (bsddev == NULL) 305219820Sjeff bsddev = device_add_child(dev->parent->bsddev, 306219820Sjeff dev->class->kobj.name, unit); 307219820Sjeff if (bsddev) { 308219820Sjeff if (dev->devt == 0) 309219820Sjeff dev->devt = makedev(0, device_get_unit(bsddev)); 310219820Sjeff device_set_softc(bsddev, dev); 311219820Sjeff } 312219820Sjeff dev->bsddev = bsddev; 313219820Sjeff kobject_init(&dev->kobj, &dev_ktype); 314219820Sjeff kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev)); 315219820Sjeff 316219820Sjeff return (0); 317219820Sjeff} 318219820Sjeff 319219820Sjeffstatic inline void 320219820Sjeffdevice_unregister(struct device *dev) 321219820Sjeff{ 322219820Sjeff device_t bsddev; 323219820Sjeff 324219820Sjeff bsddev = dev->bsddev; 325219820Sjeff mtx_lock(&Giant); 326219820Sjeff if (bsddev) 327219820Sjeff device_delete_child(device_get_parent(bsddev), bsddev); 328219820Sjeff mtx_unlock(&Giant); 329219820Sjeff put_device(dev); 330219820Sjeff} 331219820Sjeff 332219820Sjeffstruct device *device_create(struct class *class, struct device *parent, 333219820Sjeff dev_t devt, void *drvdata, const char *fmt, ...); 334219820Sjeff 335219820Sjeffstatic inline void 336219820Sjeffdevice_destroy(struct class *class, dev_t devt) 337219820Sjeff{ 338219820Sjeff device_t bsddev; 339219820Sjeff int unit; 340219820Sjeff 341219820Sjeff unit = MINOR(devt); 342219820Sjeff bsddev = devclass_get_device(class->bsdclass, unit); 343219820Sjeff if (bsddev) 344219820Sjeff device_unregister(device_get_softc(bsddev)); 345219820Sjeff} 346219820Sjeff 347219820Sjeffstatic inline void 348219820Sjeffclass_kfree(struct class *class) 349219820Sjeff{ 350219820Sjeff 351219820Sjeff kfree(class); 352219820Sjeff} 353219820Sjeff 354219820Sjeffstatic inline struct class * 355219820Sjeffclass_create(struct module *owner, const char *name) 356219820Sjeff{ 357219820Sjeff struct class *class; 358219820Sjeff int error; 359219820Sjeff 360219820Sjeff class = kzalloc(sizeof(*class), M_WAITOK); 361219820Sjeff class->owner = owner; 362219820Sjeff class->name= name; 363219820Sjeff class->class_release = class_kfree; 364219820Sjeff error = class_register(class); 365219820Sjeff if (error) { 366219820Sjeff kfree(class); 367219820Sjeff return (NULL); 368219820Sjeff } 369219820Sjeff 370219820Sjeff return (class); 371219820Sjeff} 372219820Sjeff 373219820Sjeffstatic inline void 374219820Sjeffclass_destroy(struct class *class) 375219820Sjeff{ 376219820Sjeff 377219820Sjeff if (class == NULL) 378219820Sjeff return; 379219820Sjeff class_unregister(class); 380219820Sjeff} 381219820Sjeff 382219820Sjeffstatic inline int 383219820Sjeffdevice_create_file(struct device *dev, const struct device_attribute *attr) 384219820Sjeff{ 385219820Sjeff 386219820Sjeff if (dev) 387219820Sjeff return sysfs_create_file(&dev->kobj, &attr->attr); 388219820Sjeff return -EINVAL; 389219820Sjeff} 390219820Sjeff 391219820Sjeffstatic inline void 392219820Sjeffdevice_remove_file(struct device *dev, const struct device_attribute *attr) 393219820Sjeff{ 394219820Sjeff 395219820Sjeff if (dev) 396219820Sjeff sysfs_remove_file(&dev->kobj, &attr->attr); 397219820Sjeff} 398219820Sjeff 399219820Sjeffstatic inline int 400219820Sjeffclass_create_file(struct class *class, const struct class_attribute *attr) 401219820Sjeff{ 402219820Sjeff 403219820Sjeff if (class) 404219820Sjeff return sysfs_create_file(&class->kobj, &attr->attr); 405219820Sjeff return -EINVAL; 406219820Sjeff} 407219820Sjeff 408219820Sjeffstatic inline void 409219820Sjeffclass_remove_file(struct class *class, const struct class_attribute *attr) 410219820Sjeff{ 411219820Sjeff 412219820Sjeff if (class) 413219820Sjeff sysfs_remove_file(&class->kobj, &attr->attr); 414219820Sjeff} 415219820Sjeff 416255932Salfredstatic inline int dev_to_node(struct device *dev) 417255932Salfred{ 418255932Salfred return -1; 419255932Salfred} 420255932Salfred 421285088Shselaskychar *kvasprintf(gfp_t, const char *, va_list); 422278865Shselaskychar *kasprintf(gfp_t, const char *, ...); 423270710Shselasky 424219820Sjeff#endif /* _LINUX_DEVICE_H_ */ 425