1219820Sjeff/*-
2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc.
3219820Sjeff * Copyright (c) 2010 iX Systems, Inc.
4219820Sjeff * Copyright (c) 2010 Panasas, Inc.
5219820Sjeff * All rights reserved.
6219820Sjeff *
7219820Sjeff * Redistribution and use in source and binary forms, with or without
8219820Sjeff * modification, are permitted provided that the following conditions
9219820Sjeff * are met:
10219820Sjeff * 1. Redistributions of source code must retain the above copyright
11219820Sjeff *    notice unmodified, this list of conditions, and the following
12219820Sjeff *    disclaimer.
13219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
14219820Sjeff *    notice, this list of conditions and the following disclaimer in the
15219820Sjeff *    documentation and/or other materials provided with the distribution.
16219820Sjeff *
17219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27219820Sjeff */
28219820Sjeff
29219820Sjeff#ifndef	_LINUX_CDEV_H_
30219820Sjeff#define	_LINUX_CDEV_H_
31219820Sjeff
32219820Sjeff#include <linux/kobject.h>
33219820Sjeff#include <linux/kdev_t.h>
34219820Sjeff#include <linux/list.h>
35219820Sjeff
36219820Sjeffstruct file_operations;
37219820Sjeffstruct inode;
38219820Sjeffstruct module;
39219820Sjeff
40219820Sjeffextern struct cdevsw linuxcdevsw;
41219820Sjeff
42219820Sjeffstruct linux_cdev {
43219820Sjeff	struct kobject	kobj;
44219820Sjeff	struct module	*owner;
45219820Sjeff	struct cdev	*cdev;
46219820Sjeff	dev_t		dev;
47219820Sjeff	const struct file_operations *ops;
48219820Sjeff};
49219820Sjeff
50219820Sjeffstatic inline void
51219820Sjeffcdev_release(struct kobject *kobj)
52219820Sjeff{
53219820Sjeff	struct linux_cdev *cdev;
54219820Sjeff
55219820Sjeff	cdev = container_of(kobj, struct linux_cdev, kobj);
56219820Sjeff	if (cdev->cdev)
57219820Sjeff		destroy_dev(cdev->cdev);
58219820Sjeff	kfree(cdev);
59219820Sjeff}
60219820Sjeff
61219820Sjeffstatic inline void
62219820Sjeffcdev_static_release(struct kobject *kobj)
63219820Sjeff{
64219820Sjeff	struct linux_cdev *cdev;
65219820Sjeff
66219820Sjeff	cdev = container_of(kobj, struct linux_cdev, kobj);
67219820Sjeff	if (cdev->cdev)
68219820Sjeff		destroy_dev(cdev->cdev);
69219820Sjeff}
70219820Sjeff
71219820Sjeffstatic struct kobj_type cdev_ktype = {
72219820Sjeff	.release = cdev_release,
73219820Sjeff};
74219820Sjeff
75219820Sjeffstatic struct kobj_type cdev_static_ktype = {
76219820Sjeff	.release = cdev_static_release,
77219820Sjeff};
78219820Sjeff
79219820Sjeffstatic inline void
80219820Sjeffcdev_init(struct linux_cdev *cdev, const struct file_operations *ops)
81219820Sjeff{
82219820Sjeff
83219820Sjeff	kobject_init(&cdev->kobj, &cdev_static_ktype);
84219820Sjeff	cdev->ops = ops;
85219820Sjeff}
86219820Sjeff
87219820Sjeffstatic inline struct linux_cdev *
88219820Sjeffcdev_alloc(void)
89219820Sjeff{
90219820Sjeff	struct linux_cdev *cdev;
91219820Sjeff
92219820Sjeff	cdev = kzalloc(sizeof(struct linux_cdev), M_WAITOK);
93219820Sjeff	if (cdev)
94219820Sjeff		kobject_init(&cdev->kobj, &cdev_ktype);
95219820Sjeff	return (cdev);
96219820Sjeff}
97219820Sjeff
98219820Sjeffstatic inline void
99219820Sjeffcdev_put(struct linux_cdev *p)
100219820Sjeff{
101219820Sjeff	kobject_put(&p->kobj);
102219820Sjeff}
103219820Sjeff
104219820Sjeffstatic inline int
105219820Sjeffcdev_add(struct linux_cdev *cdev, dev_t dev, unsigned count)
106219820Sjeff{
107219820Sjeff	if (count != 1)
108219820Sjeff		panic("cdev_add: Unsupported count: %d", count);
109219820Sjeff	cdev->cdev = make_dev(&linuxcdevsw, MINOR(dev), 0, 0, 0700,
110243814Sdelphij	    "%s", kobject_name(&cdev->kobj));
111219820Sjeff	cdev->dev = dev;
112219820Sjeff	cdev->cdev->si_drv1 = cdev;
113219820Sjeff
114219820Sjeff	return (0);
115219820Sjeff}
116219820Sjeff
117219820Sjeffstatic inline void
118219820Sjeffcdev_del(struct linux_cdev *cdev)
119219820Sjeff{
120219820Sjeff	if (cdev->cdev) {
121219820Sjeff		destroy_dev(cdev->cdev);
122219820Sjeff		cdev->cdev = NULL;
123219820Sjeff	}
124219820Sjeff	kobject_put(&cdev->kobj);
125219820Sjeff}
126219820Sjeff
127219820Sjeff#define	cdev	linux_cdev
128219820Sjeff
129219820Sjeff#endif	/* _LINUX_CDEV_H_ */
130