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