]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/ofed/include/linux/device.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / ofed / include / linux / device.h
1 /*-
2  * Copyright (c) 2010 Isilon Systems, Inc.
3  * Copyright (c) 2010 iX Systems, Inc.
4  * Copyright (c) 2010 Panasas, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
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.
16  *
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.
27  */
28 #ifndef _LINUX_DEVICE_H_
29 #define _LINUX_DEVICE_H_
30
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>
41
42 #include <sys/bus.h>
43
44 enum irqreturn  { IRQ_NONE = 0, IRQ_HANDLED, IRQ_WAKE_THREAD, };
45 typedef enum irqreturn  irqreturn_t;
46
47 struct class {
48         const char      *name;
49         struct module   *owner;
50         struct kobject  kobj;
51         devclass_t      bsdclass;
52         void            (*class_release)(struct class *class);
53         void            (*dev_release)(struct device *dev);
54 };
55
56 struct device {
57         struct device   *parent;
58         struct list_head irqents;
59         device_t        bsddev;
60         dev_t           devt;
61         struct class    *class;
62         void            (*release)(struct device *dev);
63         struct kobject  kobj;
64         uint64_t        *dma_mask;
65         void            *driver_data;
66         unsigned int    irq;
67         unsigned int    msix;
68         unsigned int    msix_max;
69 };
70
71 extern struct device linux_rootdev;
72 extern struct kobject class_root;
73
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);
78 };
79 #define CLASS_ATTR(_name, _mode, _show, _store)                         \
80         struct class_attribute class_attr_##_name =                     \
81             { { #_name, NULL, _mode }, _show, _store }
82
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 *,
89                                     size_t);
90 };
91
92 #define DEVICE_ATTR(_name, _mode, _show, _store)                        \
93         struct device_attribute dev_attr_##_name =                      \
94             { { #_name, NULL, _mode }, _show, _store }
95
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__)
101
102 static inline void *
103 dev_get_drvdata(struct device *dev)
104 {
105
106         return dev->driver_data;
107 }
108
109 static inline void
110 dev_set_drvdata(struct device *dev, void *data)
111 {
112
113         dev->driver_data = data;
114 }
115
116 static inline struct device *
117 get_device(struct device *dev)
118 {
119
120         if (dev)
121                 kobject_get(&dev->kobj);
122
123         return (dev);
124 }
125
126 static inline char *
127 dev_name(const struct device *dev)
128 {
129
130         return kobject_name(&dev->kobj);
131 }
132
133 #define dev_set_name(_dev, _fmt, ...)                                   \
134         kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__)
135
136 static inline void
137 put_device(struct device *dev)
138 {
139
140         if (dev)
141                 kobject_put(&dev->kobj);
142 }
143
144 static inline ssize_t
145 class_show(struct kobject *kobj, struct attribute *attr, char *buf)
146 {
147         struct class_attribute *dattr;
148         ssize_t error;
149
150         dattr = container_of(attr, struct class_attribute, attr);
151         error = -EIO;
152         if (dattr->show)
153                 error = dattr->show(container_of(kobj, struct class, kobj),
154                     buf);
155         return (error);
156 }
157
158 static inline ssize_t
159 class_store(struct kobject *kobj, struct attribute *attr, const char *buf,
160     size_t count)
161 {
162         struct class_attribute *dattr;
163         ssize_t error;
164
165         dattr = container_of(attr, struct class_attribute, attr);
166         error = -EIO;
167         if (dattr->store)
168                 error = dattr->store(container_of(kobj, struct class, kobj),
169                     buf, count);
170         return (error);
171 }
172
173 static inline void
174 class_release(struct kobject *kobj)
175 {
176         struct class *class;
177
178         class = container_of(kobj, struct class, kobj);
179         if (class->class_release)
180                 class->class_release(class);
181 }
182
183 static struct sysfs_ops class_sysfs = {
184         .show  = class_show,
185         .store = class_store,
186 };
187 static struct kobj_type class_ktype = {
188         .release = class_release,
189         .sysfs_ops = &class_sysfs
190 };
191
192 static inline int
193 class_register(struct class *class)
194 {
195
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);
200
201         return (0);
202 }
203
204 static inline void
205 class_unregister(struct class *class)
206 {
207
208         kobject_put(&class->kobj);
209 }
210
211 static inline void
212 device_release(struct kobject *kobj)
213 {
214         struct device *dev;
215
216         dev = container_of(kobj, struct device, kobj);
217         /* This is the precedence defined by linux. */
218         if (dev->release)
219                 dev->release(dev);
220         else if (dev->class && dev->class->dev_release)
221                 dev->class->dev_release(dev);
222 }
223
224 static inline ssize_t
225 dev_show(struct kobject *kobj, struct attribute *attr, char *buf)
226 {
227         struct device_attribute *dattr;
228         ssize_t error;
229
230         dattr = container_of(attr, struct device_attribute, attr);
231         error = -EIO;
232         if (dattr->show)
233                 error = dattr->show(container_of(kobj, struct device, kobj),
234                     dattr, buf);
235         return (error);
236 }
237
238 static inline ssize_t
239 dev_store(struct kobject *kobj, struct attribute *attr, const char *buf,
240     size_t count)
241 {
242         struct device_attribute *dattr;
243         ssize_t error;
244
245         dattr = container_of(attr, struct device_attribute, attr);
246         error = -EIO;
247         if (dattr->store)
248                 error = dattr->store(container_of(kobj, struct device, kobj),
249                     dattr, buf, count);
250         return (error);
251 }
252
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
257 };
258
259 /*
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.
263  */
264 static inline int
265 device_register(struct device *dev)
266 {
267         device_t bsddev;
268         int unit;
269
270         bsddev = NULL;
271         if (dev->devt) {
272                 unit = MINOR(dev->devt);
273                 bsddev = devclass_get_device(dev->class->bsdclass, unit);
274         } else
275                 unit = -1;
276         if (bsddev == NULL)
277                 bsddev = device_add_child(dev->parent->bsddev,
278                     dev->class->kobj.name, unit);
279         if (bsddev) {
280                 if (dev->devt == 0)
281                         dev->devt = makedev(0, device_get_unit(bsddev));
282                 device_set_softc(bsddev, dev);
283         }
284         dev->bsddev = bsddev;
285         kobject_init(&dev->kobj, &dev_ktype);
286         kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
287
288         return (0);
289 }
290
291 static inline void
292 device_unregister(struct device *dev)
293 {
294         device_t bsddev;
295
296         bsddev = dev->bsddev;
297         mtx_lock(&Giant);
298         if (bsddev)
299                 device_delete_child(device_get_parent(bsddev), bsddev);
300         mtx_unlock(&Giant);
301         put_device(dev);
302 }
303
304 struct device *device_create(struct class *class, struct device *parent,
305             dev_t devt, void *drvdata, const char *fmt, ...);
306
307 static inline void
308 device_destroy(struct class *class, dev_t devt)
309 {
310         device_t bsddev;
311         int unit;
312
313         unit = MINOR(devt);
314         bsddev = devclass_get_device(class->bsdclass, unit);
315         if (bsddev)
316                 device_unregister(device_get_softc(bsddev));
317 }
318
319 static inline void
320 class_kfree(struct class *class)
321 {
322
323         kfree(class);
324 }
325
326 static inline struct class *
327 class_create(struct module *owner, const char *name)
328 {
329         struct class *class;
330         int error;
331
332         class = kzalloc(sizeof(*class), M_WAITOK);
333         class->owner = owner;
334         class->name= name;
335         class->class_release = class_kfree;
336         error = class_register(class);
337         if (error) {
338                 kfree(class);
339                 return (NULL);
340         }
341
342         return (class);
343 }
344
345 static inline void
346 class_destroy(struct class *class)
347 {
348
349         if (class == NULL)
350                 return;
351         class_unregister(class);
352 }
353
354 static inline int
355 device_create_file(struct device *dev, const struct device_attribute *attr)
356 {
357
358         if (dev)
359                 return sysfs_create_file(&dev->kobj, &attr->attr);
360         return -EINVAL;
361 }
362
363 static inline void
364 device_remove_file(struct device *dev, const struct device_attribute *attr)
365 {
366
367         if (dev)
368                 sysfs_remove_file(&dev->kobj, &attr->attr);
369 }
370
371 static inline int
372 class_create_file(struct class *class, const struct class_attribute *attr)
373 {
374
375         if (class)
376                 return sysfs_create_file(&class->kobj, &attr->attr);
377         return -EINVAL;
378 }
379
380 static inline void
381 class_remove_file(struct class *class, const struct class_attribute *attr)
382 {
383
384         if (class)
385                 sysfs_remove_file(&class->kobj, &attr->attr);
386 }
387
388 static inline int dev_to_node(struct device *dev)
389 {
390                 return -1;
391 }
392
393
394 #endif  /* _LINUX_DEVICE_H_ */