Annotation of src/sys/arch/x68k/dev/event.c, Revision 1.12.20.1
1.12.20.1! matt 1: /* event.c,v 1.12 2007/03/04 06:01:05 christos Exp */
1.1 oki 2:
3: /*
4: * Copyright (c) 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This software was developed by the Computer Systems Engineering group
8: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9: * contributed to Berkeley.
10: *
11: * All advertising materials mentioning features or use of this software
12: * must display the following acknowledgement:
13: * This product includes software developed by the University of
14: * California, Lawrence Berkeley Laboratory.
15: *
16: * Redistribution and use in source and binary forms, with or without
17: * modification, are permitted provided that the following conditions
18: * are met:
19: * 1. Redistributions of source code must retain the above copyright
20: * notice, this list of conditions and the following disclaimer.
21: * 2. Redistributions in binary form must reproduce the above copyright
22: * notice, this list of conditions and the following disclaimer in the
23: * documentation and/or other materials provided with the distribution.
1.9 agc 24: * 3. Neither the name of the University nor the names of its contributors
1.1 oki 25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: *
40: * @(#)event.c 8.1 (Berkeley) 6/11/93
41: */
42:
43: /*
44: * Internal `Firm_event' interface for the keyboard and mouse drivers.
45: */
1.8 lukem 46:
47: #include <sys/cdefs.h>
1.12.20.1! matt 48: __KERNEL_RCSID(0, "event.c,v 1.12 2007/03/04 06:01:05 christos Exp");
1.1 oki 49:
50: #include <sys/param.h>
51: #include <sys/fcntl.h>
52: #include <sys/malloc.h>
53: #include <sys/proc.h>
54: #include <sys/systm.h>
55: #include <sys/vnode.h>
1.3 oki 56: #include <sys/select.h>
57: #include <sys/poll.h>
1.1 oki 58:
59: #include <machine/vuid_event.h>
60: #include <x68k/dev/event_var.h>
61:
62: /*
63: * Initialize a firm_event queue.
64: */
65: void
1.10 chs 66: ev_init(struct evvar *ev)
1.1 oki 67: {
68:
69: ev->ev_get = ev->ev_put = 0;
70: ev->ev_q = malloc((u_long)EV_QSIZE * sizeof(struct firm_event),
1.12.20.1! matt 71: M_DEVBUF, M_WAITOK|M_ZERO);
! 72: selinit(&ev->ev_sel);
1.1 oki 73: }
74:
75: /*
76: * Tear down a firm_event queue.
77: */
78: void
1.10 chs 79: ev_fini(struct evvar *ev)
1.1 oki 80: {
81:
1.12.20.1! matt 82: seldestroy(&ev->ev_sel);
1.1 oki 83: free(ev->ev_q, M_DEVBUF);
84: }
85:
86: /*
87: * User-level interface: read, select.
88: * (User cannot write an event queue.)
89: */
90: int
1.10 chs 91: ev_read(struct evvar *ev, struct uio *uio, int flags)
1.1 oki 92: {
93: int s, n, cnt, error;
94:
95: /*
96: * Make sure we can return at least 1.
97: */
98: if (uio->uio_resid < sizeof(struct firm_event))
99: return (EMSGSIZE); /* ??? */
100: s = splev();
101: while (ev->ev_get == ev->ev_put) {
102: if (flags & IO_NDELAY) {
103: splx(s);
104: return (EWOULDBLOCK);
105: }
106: ev->ev_wanted = 1;
1.12 christos 107: error = tsleep((void *)ev, PEVENT | PCATCH, "firm_event", 0);
1.1 oki 108: if (error) {
109: splx(s);
110: return (error);
111: }
112: }
113: /*
114: * Move firm_events from tail end of queue (there is at least one
115: * there).
116: */
117: if (ev->ev_put < ev->ev_get)
118: cnt = EV_QSIZE - ev->ev_get; /* events in [get..QSIZE) */
119: else
120: cnt = ev->ev_put - ev->ev_get; /* events in [get..put) */
121: splx(s);
122: n = howmany(uio->uio_resid, sizeof(struct firm_event));
123: if (cnt > n)
124: cnt = n;
1.12 christos 125: error = uiomove((void *)&ev->ev_q[ev->ev_get],
1.1 oki 126: cnt * sizeof(struct firm_event), uio);
127: n -= cnt;
128: /*
129: * If we do not wrap to 0, used up all our space, or had an error,
130: * stop. Otherwise move from front of queue to put index, if there
131: * is anything there to move.
132: */
133: if ((ev->ev_get = (ev->ev_get + cnt) % EV_QSIZE) != 0 ||
134: n == 0 || error || (cnt = ev->ev_put) == 0)
135: return (error);
136: if (cnt > n)
137: cnt = n;
1.12 christos 138: error = uiomove((void *)&ev->ev_q[0],
1.1 oki 139: cnt * sizeof(struct firm_event), uio);
140: ev->ev_get = cnt;
141: return (error);
142: }
143:
144: int
1.11 christos 145: ev_poll(struct evvar *ev, int events, struct lwp *l)
1.1 oki 146: {
1.10 chs 147: int s, revents = 0;
1.1 oki 148:
1.10 chs 149: s = splev();
1.3 oki 150: if (events & (POLLIN | POLLRDNORM)) {
151: if (ev->ev_get == ev->ev_put)
1.11 christos 152: selrecord(l, &ev->ev_sel);
1.3 oki 153: else
154: revents |= events & (POLLIN | POLLRDNORM);
155: }
156: revents |= events & (POLLOUT | POLLWRNORM);
1.1 oki 157: splx(s);
1.3 oki 158: return (revents);
1.6 jdolecek 159: }
160:
161: static void
162: filt_evrdetach(struct knote *kn)
163: {
164: struct evvar *ev = kn->kn_hook;
165: int s;
166:
167: s = splev();
1.7 christos 168: SLIST_REMOVE(&ev->ev_sel.sel_klist, kn, knote, kn_selnext);
1.6 jdolecek 169: splx(s);
170: }
171:
172: static int
173: filt_evread(struct knote *kn, long hint)
174: {
175: struct evvar *ev = kn->kn_hook;
176:
177: if (ev->ev_get == ev->ev_put)
178: return (0);
179:
180: if (ev->ev_get < ev->ev_put)
181: kn->kn_data = ev->ev_put - ev->ev_get;
182: else
183: kn->kn_data = (EV_QSIZE - ev->ev_get) +
184: ev->ev_put;
185:
186: kn->kn_data *= sizeof(struct firm_event);
187:
188: return (1);
189: }
190:
191: static const struct filterops ev_filtops =
192: { 1, NULL, filt_evrdetach, filt_evread };
193:
194: int
195: ev_kqfilter(struct evvar *ev, struct knote *kn)
196: {
197: struct klist *klist;
198: int s;
199:
200: switch (kn->kn_filter) {
201: case EVFILT_READ:
1.7 christos 202: klist = &ev->ev_sel.sel_klist;
1.6 jdolecek 203: kn->kn_fop = &ev_filtops;
204: break;
205:
206: default:
207: return (1);
208: }
209:
210: kn->kn_hook = ev;
211:
212: s = splev();
213: SLIST_INSERT_HEAD(klist, kn, kn_selnext);
214: splx(s);
215:
216: return (0);
1.1 oki 217: }
CVSweb <webmaster@jp.NetBSD.org>