wsevent.c revision 1.1 1 /* $NetBSD: wsevent.c,v 1.1 1998/03/22 14:24:03 drochner Exp $ */
2
3 /*
4 * Copyright (c) 1996, 1997 Christopher G. Demetriou. 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 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Christopher G. Demetriou
17 * for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 static const char _copyright[] __attribute__ ((unused)) =
34 "Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
35 static const char _rcsid[] __attribute__ ((unused)) =
36 "$NetBSD: wsevent.c,v 1.1 1998/03/22 14:24:03 drochner Exp $";
37
38 /*
39 * Copyright (c) 1992, 1993
40 * The Regents of the University of California. All rights reserved.
41 *
42 * This software was developed by the Computer Systems Engineering group
43 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
44 * contributed to Berkeley.
45 *
46 * All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Lawrence Berkeley Laboratory.
50 *
51 * Redistribution and use in source and binary forms, with or without
52 * modification, are permitted provided that the following conditions
53 * are met:
54 * 1. Redistributions of source code must retain the above copyright
55 * notice, this list of conditions and the following disclaimer.
56 * 2. Redistributions in binary form must reproduce the above copyright
57 * notice, this list of conditions and the following disclaimer in the
58 * documentation and/or other materials provided with the distribution.
59 * 3. All advertising materials mentioning features or use of this software
60 * must display the following acknowledgement:
61 * This product includes software developed by the University of
62 * California, Berkeley and its contributors.
63 * 4. Neither the name of the University nor the names of its contributors
64 * may be used to endorse or promote products derived from this software
65 * without specific prior written permission.
66 *
67 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
68 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
69 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
70 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
71 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
72 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
73 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
74 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
75 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
76 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
77 * SUCH DAMAGE.
78 *
79 * @(#)event.c 8.1 (Berkeley) 6/11/93
80 */
81
82 /*
83 * Internal "wscons_event" queue interface for the keyboard and mouse drivers.
84 */
85
86 #include <sys/param.h>
87 #include <sys/fcntl.h>
88 #include <sys/malloc.h>
89 #include <sys/proc.h>
90 #include <sys/systm.h>
91 #include <sys/vnode.h>
92 #include <sys/select.h>
93 #include <sys/poll.h>
94
95 #include <dev/wscons/wsconsio.h>
96 #include <dev/wscons/wseventvar.h>
97
98 /*
99 * Initialize a wscons_event queue.
100 */
101 void
102 wsevent_init(ev)
103 register struct wseventvar *ev;
104 {
105
106 ev->get = ev->put = 0;
107 ev->q = malloc((u_long)WSEVENT_QSIZE * sizeof(struct wscons_event),
108 M_DEVBUF, M_WAITOK);
109 bzero((caddr_t)ev->q, WSEVENT_QSIZE * sizeof(struct wscons_event));
110 }
111
112 /*
113 * Tear down a wscons_event queue.
114 */
115 void
116 wsevent_fini(ev)
117 register struct wseventvar *ev;
118 {
119
120 free(ev->q, M_DEVBUF);
121 }
122
123 /*
124 * User-level interface: read, poll.
125 * (User cannot write an event queue.)
126 */
127 int
128 wsevent_read(ev, uio, flags)
129 register struct wseventvar *ev;
130 struct uio *uio;
131 int flags;
132 {
133 int s, n, cnt, error;
134
135 /*
136 * Make sure we can return at least 1.
137 */
138 if (uio->uio_resid < sizeof(struct wscons_event))
139 return (EMSGSIZE); /* ??? */
140 s = splwsevent();
141 while (ev->get == ev->put) {
142 if (flags & IO_NDELAY) {
143 splx(s);
144 return (EWOULDBLOCK);
145 }
146 ev->wanted = 1;
147 error = tsleep((caddr_t)ev, PWSEVENT | PCATCH,
148 "wsevent_read", 0);
149 if (error) {
150 splx(s);
151 return (error);
152 }
153 }
154 /*
155 * Move wscons_event from tail end of queue (there is at least one
156 * there).
157 */
158 if (ev->put < ev->get)
159 cnt = WSEVENT_QSIZE - ev->get; /* events in [get..QSIZE) */
160 else
161 cnt = ev->put - ev->get; /* events in [get..put) */
162 splx(s);
163 n = howmany(uio->uio_resid, sizeof(struct wscons_event));
164 if (cnt > n)
165 cnt = n;
166 error = uiomove((caddr_t)&ev->q[ev->get],
167 cnt * sizeof(struct wscons_event), uio);
168 n -= cnt;
169 /*
170 * If we do not wrap to 0, used up all our space, or had an error,
171 * stop. Otherwise move from front of queue to put index, if there
172 * is anything there to move.
173 */
174 if ((ev->get = (ev->get + cnt) % WSEVENT_QSIZE) != 0 ||
175 n == 0 || error || (cnt = ev->put) == 0)
176 return (error);
177 if (cnt > n)
178 cnt = n;
179 error = uiomove((caddr_t)&ev->q[0],
180 cnt * sizeof(struct wscons_event), uio);
181 ev->get = cnt;
182 return (error);
183 }
184
185 int
186 wsevent_poll(ev, events, p)
187 register struct wseventvar *ev;
188 int events;
189 struct proc *p;
190 {
191 int revents = 0;
192 int s = splwsevent();
193
194 if (events & (POLLIN | POLLRDNORM))
195 if (ev->get != ev->put)
196 revents |= events & (POLLIN | POLLRDNORM);
197 else
198 selrecord(p, &ev->sel);
199
200 splx(s);
201 return (revents);
202 }
203