2 * Copyright (c) 2010 Isilon Systems, Inc.
3 * Copyright (c) 2010 iX Systems, Inc.
4 * Copyright (c) 2010 Panasas, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice unmodified, this list of conditions, and the following
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #ifndef _LINUX_DEVICE_H_
29 #define _LINUX_DEVICE_H_
31 #include <linux/types.h>
32 #include <linux/kobject.h>
33 #include <linux/list.h>
34 #include <linux/compiler.h>
35 #include <linux/types.h>
36 #include <linux/module.h>
37 #include <linux/workqueue.h>
38 #include <linux/sysfs.h>
39 #include <linux/kdev_t.h>
40 #include <asm/atomic.h>
44 enum irqreturn { IRQ_NONE = 0, IRQ_HANDLED, IRQ_WAKE_THREAD, };
45 typedef enum irqreturn irqreturn_t;
52 void (*class_release)(struct class *class);
53 void (*dev_release)(struct device *dev);
57 struct device *parent;
58 struct list_head irqents;
62 void (*release)(struct device *dev);
68 unsigned int msix_max;
71 extern struct device linux_rootdev;
72 extern struct kobject class_root;
74 struct class_attribute {
75 struct attribute attr;
76 ssize_t (*show)(struct class *, char *);
77 ssize_t (*store)(struct class *, const char *, size_t);
79 #define CLASS_ATTR(_name, _mode, _show, _store) \
80 struct class_attribute class_attr_##_name = \
81 { { #_name, NULL, _mode }, _show, _store }
83 struct device_attribute {
84 struct attribute attr;
85 ssize_t (*show)(struct device *,
86 struct device_attribute *, char *);
87 ssize_t (*store)(struct device *,
88 struct device_attribute *, const char *,
92 #define DEVICE_ATTR(_name, _mode, _show, _store) \
93 struct device_attribute dev_attr_##_name = \
94 { { #_name, NULL, _mode }, _show, _store }
96 #define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
97 #define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
98 #define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
99 #define dev_printk(lvl, dev, fmt, ...) \
100 device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
103 dev_get_drvdata(struct device *dev)
106 return dev->driver_data;
110 dev_set_drvdata(struct device *dev, void *data)
113 dev->driver_data = data;
116 static inline struct device *
117 get_device(struct device *dev)
121 kobject_get(&dev->kobj);
127 dev_name(const struct device *dev)
130 return kobject_name(&dev->kobj);
133 #define dev_set_name(_dev, _fmt, ...) \
134 kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__)
137 put_device(struct device *dev)
141 kobject_put(&dev->kobj);
144 static inline ssize_t
145 class_show(struct kobject *kobj, struct attribute *attr, char *buf)
147 struct class_attribute *dattr;
150 dattr = container_of(attr, struct class_attribute, attr);
153 error = dattr->show(container_of(kobj, struct class, kobj),
158 static inline ssize_t
159 class_store(struct kobject *kobj, struct attribute *attr, const char *buf,
162 struct class_attribute *dattr;
165 dattr = container_of(attr, struct class_attribute, attr);
168 error = dattr->store(container_of(kobj, struct class, kobj),
174 class_release(struct kobject *kobj)
178 class = container_of(kobj, struct class, kobj);
179 if (class->class_release)
180 class->class_release(class);
183 static struct sysfs_ops class_sysfs = {
185 .store = class_store,
187 static struct kobj_type class_ktype = {
188 .release = class_release,
189 .sysfs_ops = &class_sysfs
193 class_register(struct class *class)
196 class->bsdclass = devclass_create(class->name);
197 kobject_init(&class->kobj, &class_ktype);
198 kobject_set_name(&class->kobj, class->name);
199 kobject_add(&class->kobj, &class_root, class->name);
205 class_unregister(struct class *class)
208 kobject_put(&class->kobj);
212 device_release(struct kobject *kobj)
216 dev = container_of(kobj, struct device, kobj);
217 /* This is the precedence defined by linux. */
220 else if (dev->class && dev->class->dev_release)
221 dev->class->dev_release(dev);
224 static inline ssize_t
225 dev_show(struct kobject *kobj, struct attribute *attr, char *buf)
227 struct device_attribute *dattr;
230 dattr = container_of(attr, struct device_attribute, attr);
233 error = dattr->show(container_of(kobj, struct device, kobj),
238 static inline ssize_t
239 dev_store(struct kobject *kobj, struct attribute *attr, const char *buf,
242 struct device_attribute *dattr;
245 dattr = container_of(attr, struct device_attribute, attr);
248 error = dattr->store(container_of(kobj, struct device, kobj),
253 static struct sysfs_ops dev_sysfs = { .show = dev_show, .store = dev_store, };
254 static struct kobj_type dev_ktype = {
255 .release = device_release,
256 .sysfs_ops = &dev_sysfs
260 * Devices are registered and created for exporting to sysfs. create
261 * implies register and register assumes the device fields have been
262 * setup appropriately before being called.
265 device_register(struct device *dev)
272 unit = MINOR(dev->devt);
273 bsddev = devclass_get_device(dev->class->bsdclass, unit);
277 bsddev = device_add_child(dev->parent->bsddev,
278 dev->class->kobj.name, unit);
281 dev->devt = makedev(0, device_get_unit(bsddev));
282 device_set_softc(bsddev, dev);
284 dev->bsddev = bsddev;
285 kobject_init(&dev->kobj, &dev_ktype);
286 kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
292 device_unregister(struct device *dev)
296 bsddev = dev->bsddev;
299 device_delete_child(device_get_parent(bsddev), bsddev);
304 struct device *device_create(struct class *class, struct device *parent,
305 dev_t devt, void *drvdata, const char *fmt, ...);
308 device_destroy(struct class *class, dev_t devt)
314 bsddev = devclass_get_device(class->bsdclass, unit);
316 device_unregister(device_get_softc(bsddev));
320 class_kfree(struct class *class)
326 static inline struct class *
327 class_create(struct module *owner, const char *name)
332 class = kzalloc(sizeof(*class), M_WAITOK);
333 class->owner = owner;
335 class->class_release = class_kfree;
336 error = class_register(class);
346 class_destroy(struct class *class)
351 class_unregister(class);
355 device_create_file(struct device *dev, const struct device_attribute *attr)
359 return sysfs_create_file(&dev->kobj, &attr->attr);
364 device_remove_file(struct device *dev, const struct device_attribute *attr)
368 sysfs_remove_file(&dev->kobj, &attr->attr);
372 class_create_file(struct class *class, const struct class_attribute *attr)
376 return sysfs_create_file(&class->kobj, &attr->attr);
381 class_remove_file(struct class *class, const struct class_attribute *attr)
385 sysfs_remove_file(&class->kobj, &attr->attr);
388 static inline int dev_to_node(struct device *dev)
394 #endif /* _LINUX_DEVICE_H_ */