device.h revision 289624
1128345Stjr/* $FreeBSD: head/sys/ofed/include/linux/device.h 289624 2015-10-20 11:40:04Z hselasky $ */ 2128345Stjr/*- 3128345Stjr * Copyright (c) 2010 Isilon Systems, Inc. 460786Sps * Copyright (c) 2010 iX Systems, Inc. 560786Sps * Copyright (c) 2010 Panasas, Inc. 660786Sps * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. 760786Sps * All rights reserved. 860786Sps * 960786Sps * Redistribution and use in source and binary forms, with or without 1060786Sps * modification, are permitted provided that the following conditions 1160786Sps * are met: 1260786Sps * 1. Redistributions of source code must retain the above copyright 1360786Sps * notice unmodified, this list of conditions, and the following 1460786Sps * disclaimer. 15128345Stjr * 2. Redistributions in binary form must reproduce the above copyright 1660786Sps * notice, this list of conditions and the following disclaimer in the 1760786Sps * documentation and/or other materials provided with the distribution. 1860786Sps * 1960786Sps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2060786Sps * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21161475Sdelphij * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2260786Sps * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23161475Sdelphij * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2460786Sps * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2560786Sps * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2660786Sps * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2760786Sps * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2860786Sps * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2960786Sps */ 3060786Sps#ifndef _LINUX_DEVICE_H_ 3160786Sps#define _LINUX_DEVICE_H_ 3260786Sps 3360786Sps#include <linux/types.h> 3460786Sps#include <linux/kobject.h> 3560786Sps#include <linux/list.h> 3660786Sps#include <linux/compiler.h> 3760786Sps#include <linux/types.h> 3860786Sps#include <linux/module.h> 3960786Sps#include <linux/workqueue.h> 4060786Sps#include <linux/sysfs.h> 4160786Sps#include <linux/kdev_t.h> 4260786Sps#include <asm/atomic.h> 4360786Sps 4460786Sps#include <sys/bus.h> 4560786Sps 4660786Spsenum irqreturn { IRQ_NONE = 0, IRQ_HANDLED, IRQ_WAKE_THREAD, }; 4760786Spstypedef enum irqreturn irqreturn_t; 4860786Sps 4960786Spsstruct class { 5060786Sps const char *name; 5160786Sps struct module *owner; 5260786Sps struct kobject kobj; 5360786Sps devclass_t bsdclass; 5460786Sps void (*class_release)(struct class *class); 5560786Sps void (*dev_release)(struct device *dev); 5660786Sps char * (*devnode)(struct device *dev, umode_t *mode); 5760786Sps}; 5860786Sps 5960786Spsstruct device { 6060786Sps struct device *parent; 6160786Sps struct list_head irqents; 6260786Sps device_t bsddev; 6360786Sps dev_t devt; 6460786Sps struct class *class; 6560786Sps void (*release)(struct device *dev); 6660786Sps struct kobject kobj; 6760786Sps uint64_t *dma_mask; 6860786Sps void *driver_data; 6960786Sps unsigned int irq; 7060786Sps unsigned int msix; 7160786Sps unsigned int msix_max; 7260786Sps}; 7360786Sps 7460786Spsextern struct device linux_rootdev; 7560786Spsextern struct kobject class_root; 7660786Sps 7760786Spsstruct class_attribute { 7860786Sps struct attribute attr; 7960786Sps ssize_t (*show)(struct class *, struct class_attribute *, char *); 8060786Sps ssize_t (*store)(struct class *, struct class_attribute *, const char *, size_t); 8160786Sps const void *(*namespace)(struct class *, const struct class_attribute *); 8260786Sps}; 8360786Sps 8460786Sps#define CLASS_ATTR(_name, _mode, _show, _store) \ 8560786Sps struct class_attribute class_attr_##_name = \ 8660786Sps { { #_name, NULL, _mode }, _show, _store } 8760786Sps 8860786Spsstruct device_attribute { 8960786Sps struct attribute attr; 9060786Sps ssize_t (*show)(struct device *, 9160786Sps struct device_attribute *, char *); 9260786Sps ssize_t (*store)(struct device *, 9360786Sps struct device_attribute *, const char *, 9460786Sps size_t); 9560786Sps}; 9660786Sps 9760786Sps#define DEVICE_ATTR(_name, _mode, _show, _store) \ 9860786Sps struct device_attribute dev_attr_##_name = \ 9960786Sps { { #_name, NULL, _mode }, _show, _store } 10060786Sps 10160786Sps/* Simple class attribute that is just a static string */ 10260786Spsstruct class_attribute_string { 10360786Sps struct class_attribute attr; 10460786Sps char *str; 10560786Sps}; 10660786Sps 10760786Spsstatic inline ssize_t 10860786Spsshow_class_attr_string(struct class *class, 109161475Sdelphij struct class_attribute *attr, char *buf) 110161475Sdelphij{ 11160786Sps struct class_attribute_string *cs; 11260786Sps cs = container_of(attr, struct class_attribute_string, attr); 11389019Sps return snprintf(buf, PAGE_SIZE, "%s\n", cs->str); 11460786Sps} 115161475Sdelphij 11660786Sps/* Currently read-only only */ 117128345Stjr#define _CLASS_ATTR_STRING(_name, _mode, _str) \ 11860786Sps { __ATTR(_name, _mode, show_class_attr_string, NULL), _str } 11960786Sps#define CLASS_ATTR_STRING(_name, _mode, _str) \ 12060786Sps struct class_attribute_string class_attr_##_name = \ 12160786Sps _CLASS_ATTR_STRING(_name, _mode, _str) 12260786Sps 12360786Sps#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 12460786Sps#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 12560786Sps#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 12660786Sps#define dev_printk(lvl, dev, fmt, ...) \ 12760786Sps device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 12860786Sps 12960786Spsstatic inline void * 13060786Spsdev_get_drvdata(struct device *dev) 13160786Sps{ 13260786Sps 13360786Sps return dev->driver_data; 13460786Sps} 13560786Sps 13660786Spsstatic inline void 13760786Spsdev_set_drvdata(struct device *dev, void *data) 13860786Sps{ 13960786Sps 14060786Sps dev->driver_data = data; 14160786Sps} 14260786Sps 14360786Spsstatic inline struct device * 14460786Spsget_device(struct device *dev) 14560786Sps{ 14660786Sps 14760786Sps if (dev) 14860786Sps kobject_get(&dev->kobj); 14960786Sps 15060786Sps return (dev); 15160786Sps} 15260786Sps 15360786Spsstatic inline char * 15460786Spsdev_name(const struct device *dev) 15560786Sps{ 15660786Sps 15760786Sps return kobject_name(&dev->kobj); 15860786Sps} 159161475Sdelphij 16060786Sps#define dev_set_name(_dev, _fmt, ...) \ 16160786Sps kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__) 16260786Sps 16360786Spsstatic inline void 16460786Spsput_device(struct device *dev) 16560786Sps{ 16660786Sps 16760786Sps if (dev) 16860786Sps kobject_put(&dev->kobj); 16960786Sps} 17060786Sps 17160786Spsstatic inline ssize_t 17260786Spsclass_show(struct kobject *kobj, struct attribute *attr, char *buf) 17360786Sps{ 17460786Sps struct class_attribute *dattr; 17560786Sps ssize_t error; 17660786Sps 17760786Sps dattr = container_of(attr, struct class_attribute, attr); 17889019Sps error = -EIO; 179128345Stjr if (dattr->show) 18060786Sps error = dattr->show(container_of(kobj, struct class, kobj), 18160786Sps dattr, buf); 18260786Sps return (error); 183128345Stjr} 184128345Stjr 18560786Spsstatic inline ssize_t 186128345Stjrclass_store(struct kobject *kobj, struct attribute *attr, const char *buf, 187128345Stjr size_t count) 18860786Sps{ 189128345Stjr struct class_attribute *dattr; 190128345Stjr ssize_t error; 19160786Sps 192128345Stjr dattr = container_of(attr, struct class_attribute, attr); 193128345Stjr error = -EIO; 19460786Sps if (dattr->store) 195128345Stjr error = dattr->store(container_of(kobj, struct class, kobj), 196128345Stjr dattr, buf, count); 19760786Sps return (error); 198161475Sdelphij} 199161475Sdelphij 200161475Sdelphijstatic inline void 201128345Stjrclass_release(struct kobject *kobj) 202128345Stjr{ 20360786Sps struct class *class; 20460786Sps 20560786Sps class = container_of(kobj, struct class, kobj); 20660786Sps if (class->class_release) 207128345Stjr class->class_release(class); 208128345Stjr} 20960786Sps 210128345Stjrstatic struct sysfs_ops class_sysfs = { 211128345Stjr .show = class_show, 21260786Sps .store = class_store, 213128345Stjr}; 214128345Stjrstatic struct kobj_type class_ktype = { 21560786Sps .release = class_release, 216128345Stjr .sysfs_ops = &class_sysfs 217128345Stjr}; 218128345Stjr 219128345Stjrstatic inline int 220128345Stjrclass_register(struct class *class) 221128345Stjr{ 222128345Stjr 223128345Stjr class->bsdclass = devclass_create(class->name); 224128345Stjr kobject_init(&class->kobj, &class_ktype); 22560786Sps kobject_set_name(&class->kobj, class->name); 22660786Sps kobject_add(&class->kobj, &class_root, class->name); 22760786Sps 228128345Stjr return (0); 229128345Stjr} 23060786Sps 231128345Stjrstatic inline void 232128345Stjrclass_unregister(struct class *class) 23360786Sps{ 234128345Stjr 235128345Stjr kobject_put(&class->kobj); 23663128Sps} 237128345Stjr 238128345Stjrstatic inline void 23963128Spsdevice_release(struct kobject *kobj) 240128345Stjr{ 241128345Stjr struct device *dev; 24260786Sps 243128345Stjr dev = container_of(kobj, struct device, kobj); 244128345Stjr /* This is the precedence defined by linux. */ 24560786Sps if (dev->release) 246128345Stjr dev->release(dev); 247128345Stjr else if (dev->class && dev->class->dev_release) 24889019Sps dev->class->dev_release(dev); 249128345Stjr} 250128345Stjr 25160786Spsstatic inline ssize_t 252128345Stjrdev_show(struct kobject *kobj, struct attribute *attr, char *buf) 253128345Stjr{ 25460786Sps struct device_attribute *dattr; 255128345Stjr ssize_t error; 256128345Stjr 257128345Stjr dattr = container_of(attr, struct device_attribute, attr); 258128345Stjr error = -EIO; 25963128Sps if (dattr->show) 26063128Sps error = dattr->show(container_of(kobj, struct device, kobj), 261128345Stjr dattr, buf); 26260786Sps return (error); 26360786Sps} 264128345Stjr 265128345Stjrstatic inline ssize_t 266128345Stjrdev_store(struct kobject *kobj, struct attribute *attr, const char *buf, 267161475Sdelphij size_t count) 268161475Sdelphij{ 269161475Sdelphij struct device_attribute *dattr; 270128345Stjr ssize_t error; 27160786Sps 27260786Sps dattr = container_of(attr, struct device_attribute, attr); 273128345Stjr error = -EIO; 274128345Stjr if (dattr->store) 27560786Sps error = dattr->store(container_of(kobj, struct device, kobj), 276128345Stjr dattr, buf, count); 277128345Stjr return (error); 27860786Sps} 279128345Stjr 280128345Stjrstatic struct sysfs_ops dev_sysfs = { .show = dev_show, .store = dev_store, }; 28160786Spsstatic struct kobj_type dev_ktype = { 282128345Stjr .release = device_release, 283128345Stjr .sysfs_ops = &dev_sysfs 28460786Sps}; 285128345Stjr 286128345Stjr/* 28760786Sps * Devices are registered and created for exporting to sysfs. create 288128345Stjr * implies register and register assumes the device fields have been 289128345Stjr * setup appropriately before being called. 29060786Sps */ 291128345Stjrstatic inline int 292128345Stjrdevice_register(struct device *dev) 29360786Sps{ 294128345Stjr device_t bsddev; 295128345Stjr int unit; 29660786Sps 297128345Stjr bsddev = NULL; 298128345Stjr if (dev->devt) { 29960786Sps unit = MINOR(dev->devt); 300128345Stjr bsddev = devclass_get_device(dev->class->bsdclass, unit); 301128345Stjr } else 30260786Sps unit = -1; 303128345Stjr if (bsddev == NULL) 30460786Sps bsddev = device_add_child(dev->parent->bsddev, 30560786Sps dev->class->kobj.name, unit); 306128345Stjr if (bsddev) { 30760786Sps if (dev->devt == 0) 30860786Sps dev->devt = makedev(0, device_get_unit(bsddev)); 309128345Stjr device_set_softc(bsddev, dev); 310128345Stjr } 311128345Stjr dev->bsddev = bsddev; 312128345Stjr kobject_init(&dev->kobj, &dev_ktype); 31360786Sps kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev)); 31460786Sps 315128345Stjr return (0); 316128345Stjr} 317128345Stjr 318128345Stjrstatic inline void 31960786Spsdevice_unregister(struct device *dev) 32060786Sps{ 321128345Stjr device_t bsddev; 322128345Stjr 32360786Sps bsddev = dev->bsddev; 324128345Stjr mtx_lock(&Giant); 32560786Sps if (bsddev) 32660786Sps device_delete_child(device_get_parent(bsddev), bsddev); 327128345Stjr mtx_unlock(&Giant); 328128345Stjr put_device(dev); 329128345Stjr} 330128345Stjr 33160786Spsstruct device *device_create(struct class *class, struct device *parent, 33260786Sps dev_t devt, void *drvdata, const char *fmt, ...); 333128345Stjr 334128345Stjrstatic inline void 335128345Stjrdevice_destroy(struct class *class, dev_t devt) 336128345Stjr{ 33760786Sps device_t bsddev; 33860786Sps int unit; 339128345Stjr 340128345Stjr unit = MINOR(devt); 341128345Stjr bsddev = devclass_get_device(class->bsdclass, unit); 342128345Stjr if (bsddev) 343128345Stjr device_unregister(device_get_softc(bsddev)); 344128345Stjr} 345128345Stjr 34660786Spsstatic inline void 34760786Spsclass_kfree(struct class *class) 348128345Stjr{ 349128345Stjr 35060786Sps kfree(class); 351128345Stjr} 352128345Stjr 35360786Spsstatic inline struct class * 354128345Stjrclass_create(struct module *owner, const char *name) 355128345Stjr{ 356128345Stjr struct class *class; 357128345Stjr int error; 358128345Stjr 359128345Stjr class = kzalloc(sizeof(*class), M_WAITOK); 360128345Stjr class->owner = owner; 361128345Stjr class->name= name; 362128345Stjr class->class_release = class_kfree; 363128345Stjr error = class_register(class); 364128345Stjr if (error) { 365128345Stjr kfree(class); 366128345Stjr return (NULL); 367128345Stjr } 368128345Stjr 369128345Stjr return (class); 370128345Stjr} 371128345Stjr 372128345Stjrstatic inline void 373128345Stjrclass_destroy(struct class *class) 374128345Stjr{ 375128345Stjr 376128345Stjr if (class == NULL) 377128345Stjr return; 378128345Stjr class_unregister(class); 379128345Stjr} 380128345Stjr 381128345Stjrstatic inline int 382128345Stjrdevice_create_file(struct device *dev, const struct device_attribute *attr) 383161475Sdelphij{ 384161475Sdelphij 385161475Sdelphij if (dev) 386128345Stjr return sysfs_create_file(&dev->kobj, &attr->attr); 387128345Stjr return -EINVAL; 388128345Stjr} 389128345Stjr 390128345Stjrstatic inline void 391128345Stjrdevice_remove_file(struct device *dev, const struct device_attribute *attr) 392128345Stjr{ 393128345Stjr 394128345Stjr if (dev) 395128345Stjr sysfs_remove_file(&dev->kobj, &attr->attr); 396128345Stjr} 397128345Stjr 398128345Stjrstatic inline int 399128345Stjrclass_create_file(struct class *class, const struct class_attribute *attr) 400128345Stjr{ 401128345Stjr 402128345Stjr if (class) 403128345Stjr return sysfs_create_file(&class->kobj, &attr->attr); 404128345Stjr return -EINVAL; 405128345Stjr} 406128345Stjr 407128345Stjrstatic inline void 408128345Stjrclass_remove_file(struct class *class, const struct class_attribute *attr) 409{ 410 411 if (class) 412 sysfs_remove_file(&class->kobj, &attr->attr); 413} 414 415static inline int dev_to_node(struct device *dev) 416{ 417 return -1; 418} 419 420char *kvasprintf(gfp_t, const char *, va_list); 421char *kasprintf(gfp_t, const char *, ...); 422 423#endif /* _LINUX_DEVICE_H_ */ 424