1 /* $OpenBSD: bio.c,v 1.4 2005/04/01 20:02:27 marco 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
bioattach(nunits)60 bioattach(nunits)
61 int nunits;
62 {
63 }
64
65 int
bioopen(dev,flags,mode,p)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
bioclose(dev,flags,mode,p)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
bioioctl(dev,cmd,addr,flag,p)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 size_t len;
93 int error;
94 struct bio_locate *locate;
95 struct bio_common *common;
96
97 switch (cmd) {
98 case BIOCLOCATE:
99 locate = (struct bio_locate *)addr;
100 error = copyinstr(locate->name, name, 16, &len);
101 if (error != 0)
102 return (error);
103 locate->cookie = bio_lookup(name);
104 if (locate->cookie == NULL)
105 return (ENOENT);
106 break;
107
108 default:
109 common = (struct bio_common *)addr;
110 if (!bio_validate(common->cookie))
111 return (ENOENT);
112 return (bio_delegate_ioctl(
113 (struct bio_mapping *)common->cookie, cmd, addr));
114 }
115 return (0);
116 }
117
118 int
bio_register(dev,ioctl)119 bio_register(dev, ioctl)
120 struct device *dev;
121 int (*ioctl)(struct device *, u_long, caddr_t);
122 {
123 struct bio_mapping *bm;
124
125 MALLOC(bm, struct bio_mapping *, sizeof *bm, M_DEVBUF, M_NOWAIT);
126 if (bm == NULL)
127 return (ENOMEM);
128 bm->bm_dev = dev;
129 bm->bm_ioctl = ioctl;
130 LIST_INSERT_HEAD(&bios, bm, bm_link);
131 return (0);
132 }
133
134 struct bio_mapping *
bio_lookup(name)135 bio_lookup(name)
136 char *name;
137 {
138 struct bio_mapping *bm;
139
140 for (bm = LIST_FIRST(&bios); bm != NULL; bm = LIST_NEXT(bm, bm_link))
141 if (strcmp(name, bm->bm_dev->dv_xname) == 0)
142 return (bm);
143 return (NULL);
144 }
145
146 int
bio_validate(cookie)147 bio_validate(cookie)
148 void *cookie;
149 {
150 struct bio_mapping *bm;
151
152 for (bm = LIST_FIRST(&bios); bm != NULL; bm = LIST_NEXT(bm, bm_link))
153 if (bm == cookie)
154 return (1);
155 return (0);
156 }
157
158 int
bio_delegate_ioctl(bm,cmd,addr)159 bio_delegate_ioctl(bm, cmd, addr)
160 struct bio_mapping *bm;
161 u_long cmd;
162 caddr_t addr;
163 {
164 return (bm->bm_ioctl(bm->bm_dev, cmd, addr));
165 }
166