xref: /openbsd-src/sys/dev/bio.c (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
1 /*	$OpenBSD: bio.c,v 1.2 2003/06/03 20:49:28 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 2002 Niklas Hallqvist.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /* A device controller ioctl tunnelling device.  */
28 
29 #include <sys/param.h>
30 #include <sys/device.h>
31 #include <sys/ioctl.h>
32 #include <sys/malloc.h>
33 #include <sys/queue.h>
34 #include <sys/systm.h>
35 
36 #include <dev/biovar.h>
37 
38 struct bio_mapping {
39 	LIST_ENTRY(bio_mapping) bm_link;
40 	struct device *bm_dev;
41 	int (*bm_ioctl)(struct device *, u_long, caddr_t);
42 };
43 
44 LIST_HEAD(, bio_mapping) bios = LIST_HEAD_INITIALIZER(bios);
45 
46 struct bio_softc {
47 	struct device	 sc_dev;
48 };
49 
50 void	bioattach(int);
51 int	bioclose(dev_t, int, int, struct proc *);
52 int	bioioctl(dev_t, u_long, caddr_t, int, struct proc *);
53 int	bioopen(dev_t, int, int, struct proc *);;
54 
55 int	bio_delegate_ioctl(struct bio_mapping *, u_long, caddr_t);
56 struct bio_mapping *bio_lookup(char *);
57 int	bio_validate(void *);
58 
59 void
60 bioattach(nunits)
61 	int nunits;
62 {
63 }
64 
65 int
66 bioopen(dev, flags, mode, p)
67 	dev_t dev;
68 	int flags, mode;
69 	struct proc *p;
70 {
71 	return (0);
72 }
73 
74 int
75 bioclose(dev, flags, mode, p)
76 	dev_t dev;
77 	int flags, mode;
78 	struct proc *p;
79 {
80 	return (0);
81 }
82 
83 int
84 bioioctl(dev, cmd, addr, flag, p)
85 	dev_t dev;
86 	u_long cmd;
87 	caddr_t addr;
88 	int flag;
89 	struct proc *p;
90 {
91 	char name[16];
92 	int len, error;
93 	struct bio_locate *locate;
94 	struct bio_common *common;
95 
96 	switch (cmd) {
97 	case BIOCLOCATE:
98 		locate = (struct bio_locate *)addr;
99 		error = copyinstr(locate->name, name, 16, &len);
100 		if (error != 0)
101 			return (error);
102 		locate->cookie = bio_lookup(name);
103 		if (locate->cookie == NULL)
104 			return (ENOENT);
105 		break;
106 
107 	default:
108 		common = (struct bio_common *)addr;
109 		if (!bio_validate(common->cookie))
110 			return (ENOENT);
111 		return (bio_delegate_ioctl(
112 		    (struct bio_mapping *)common->cookie, cmd, addr));
113 	}
114 	return (0);
115 }
116 
117 int
118 bio_register(dev, ioctl)
119 	struct device *dev;
120 	int (*ioctl)(struct device *, u_long, caddr_t);
121 {
122 	struct bio_mapping *bm;
123 
124 	MALLOC(bm, struct bio_mapping *, sizeof *bm, M_DEVBUF, M_NOWAIT);
125 	if (bm == NULL)
126 		return (ENOMEM);
127 	bm->bm_dev = dev;
128 	bm->bm_ioctl = ioctl;
129 	LIST_INSERT_HEAD(&bios, bm, bm_link);
130 	return (0);
131 }
132 
133 struct bio_mapping *
134 bio_lookup(name)
135 	char *name;
136 {
137 	struct bio_mapping *bm;
138 
139 	for (bm = LIST_FIRST(&bios); bm != NULL; bm = LIST_NEXT(bm, bm_link))
140 		if (strcmp(name, bm->bm_dev->dv_xname) == 0)
141 			return (bm);
142 	return (NULL);
143 }
144 
145 int
146 bio_validate(cookie)
147 	void *cookie;
148 {
149 	struct bio_mapping *bm;
150 
151 	for (bm = LIST_FIRST(&bios); bm != NULL; bm = LIST_NEXT(bm, bm_link))
152 		if (bm == cookie)
153 			return (1);
154 	return (0);
155 }
156 
157 int
158 bio_delegate_ioctl(bm, cmd, addr)
159 	struct bio_mapping *bm;
160 	u_long cmd;
161 	caddr_t addr;
162 {
163 	return (bm->bm_ioctl(bm->bm_dev, cmd, addr));
164 }
165