Lines Matching +full:- +full:u

4  * Driver for receiving and demuxing event-channel signals.
6 * Copyright (c) 2004-2005, K A Fraser
7 * Multi-process extensions Copyright (c) 2004, Steven Smith
58 #include <xen/xen-os.h>
64 MALLOC_DEFINE(M_EVTCHN, "evtchn_dev", "Xen event channel user-space device");
78 #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
116 /*------------------------- Red-black tree helpers ---------------------------*/
121 return (u1->port - u2->port); in evtchn_cmp()
125 find_evtchn(struct per_user_data *u, evtchn_port_t port) in find_evtchn() argument
131 return (RB_FIND(evtchn_tree, &u->evtchns, &tmp)); in find_evtchn()
134 /*--------------------------- Interrupt handlers -----------------------------*/
142 if (!evtchn->enabled && bootverbose) { in evtchn_filter()
145 evtchn->port); in evtchn_filter()
148 evtchn_mask_port(evtchn->port); in evtchn_filter()
149 evtchn->enabled = false; in evtchn_filter()
158 struct per_user_data *u; in evtchn_interrupt() local
161 u = evtchn->user; in evtchn_interrupt()
167 mtx_lock(&u->ring_prod_mutex); in evtchn_interrupt()
168 if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) { in evtchn_interrupt()
169 u->ring[EVTCHN_RING_MASK(u->ring_prod)] = evtchn->port; in evtchn_interrupt()
171 if (u->ring_cons == u->ring_prod++) { in evtchn_interrupt()
172 wakeup(u); in evtchn_interrupt()
173 selwakeup(&u->ev_rsel); in evtchn_interrupt()
176 u->ring_overflow = 1; in evtchn_interrupt()
177 mtx_unlock(&u->ring_prod_mutex); in evtchn_interrupt()
180 /*------------------------- Character device methods -------------------------*/
184 struct per_user_data *u; in evtchn_open() local
187 u = malloc(sizeof(*u), M_EVTCHN, M_WAITOK | M_ZERO); in evtchn_open()
188 u->ring = malloc(PAGE_SIZE, M_EVTCHN, M_WAITOK | M_ZERO); in evtchn_open()
191 mtx_init(&u->bind_mutex, "evtchn_bind_mutex", NULL, MTX_DEF); in evtchn_open()
192 sx_init(&u->ring_cons_mutex, "evtchn_ringc_sx"); in evtchn_open()
193 mtx_init(&u->ring_prod_mutex, "evtchn_ringp_mutex", NULL, MTX_DEF); in evtchn_open()
195 /* Initialize red-black tree. */ in evtchn_open()
196 RB_INIT(&u->evtchns); in evtchn_open()
199 error = devfs_set_cdevpriv(u, evtchn_release); in evtchn_open()
201 mtx_destroy(&u->bind_mutex); in evtchn_open()
202 mtx_destroy(&u->ring_prod_mutex); in evtchn_open()
203 sx_destroy(&u->ring_cons_mutex); in evtchn_open()
204 free(u->ring, M_EVTCHN); in evtchn_open()
205 free(u, M_EVTCHN); in evtchn_open()
214 struct per_user_data *u; in evtchn_release() local
217 u = arg; in evtchn_release()
219 seldrain(&u->ev_rsel); in evtchn_release()
221 RB_FOREACH_SAFE(evtchn, evtchn_tree, &u->evtchns, tmp) { in evtchn_release()
222 xen_intr_unbind(&evtchn->handle); in evtchn_release()
224 RB_REMOVE(evtchn_tree, &u->evtchns, evtchn); in evtchn_release()
228 mtx_destroy(&u->bind_mutex); in evtchn_release()
229 mtx_destroy(&u->ring_prod_mutex); in evtchn_release()
230 sx_destroy(&u->ring_cons_mutex); in evtchn_release()
231 free(u->ring, M_EVTCHN); in evtchn_release()
232 free(u, M_EVTCHN); in evtchn_release()
240 struct per_user_data *u; in evtchn_read() local
242 error = devfs_get_cdevpriv((void **)&u); in evtchn_read()
247 count = uio->uio_resid; in evtchn_read()
248 count &= ~(sizeof(evtchn_port_t)-1); in evtchn_read()
256 sx_xlock(&u->ring_cons_mutex); in evtchn_read()
258 if (u->ring_overflow) { in evtchn_read()
263 c = u->ring_cons; in evtchn_read()
264 p = u->ring_prod; in evtchn_read()
273 error = sx_sleep(u, &u->ring_cons_mutex, PCATCH, "evtchw", 0); in evtchn_read()
280 bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * in evtchn_read()
284 bytes1 = (p - c) * sizeof(evtchn_port_t); in evtchn_read()
293 bytes2 = count - bytes1; in evtchn_read()
299 if (uiomove(&u->ring[EVTCHN_RING_MASK(c)], bytes1, uio) || in evtchn_read()
300 ((bytes2 != 0) && uiomove(&u->ring[0], bytes2, uio))) in evtchn_read()
303 u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t); in evtchn_read()
307 sx_xunlock(&u->ring_cons_mutex); in evtchn_read()
316 struct per_user_data *u; in evtchn_write() local
318 error = devfs_get_cdevpriv((void **)&u); in evtchn_write()
324 count = uio->uio_resid; in evtchn_write()
326 count &= ~(sizeof(evtchn_port_t)-1); in evtchn_write()
339 mtx_lock(&u->bind_mutex); in evtchn_write()
345 evtchn = find_evtchn(u, port); in evtchn_write()
346 if (evtchn && !evtchn->enabled) { in evtchn_write()
347 evtchn->enabled = true; in evtchn_write()
348 evtchn_unmask_port(evtchn->port); in evtchn_write()
352 mtx_unlock(&u->bind_mutex); in evtchn_write()
361 evtchn_bind_user_port(struct per_user_data *u, struct user_evtchn *evtchn) in evtchn_bind_user_port() argument
365 evtchn->port = xen_intr_port(evtchn->handle); in evtchn_bind_user_port()
366 evtchn->user = u; in evtchn_bind_user_port()
367 evtchn->enabled = true; in evtchn_bind_user_port()
368 mtx_lock(&u->bind_mutex); in evtchn_bind_user_port()
369 RB_INSERT(evtchn_tree, &u->evtchns, evtchn); in evtchn_bind_user_port()
370 mtx_unlock(&u->bind_mutex); in evtchn_bind_user_port()
373 INTR_TYPE_MISC | INTR_MPSAFE, evtchn->handle); in evtchn_bind_user_port()
375 xen_intr_unbind(&evtchn->handle); in evtchn_bind_user_port()
376 mtx_lock(&u->bind_mutex); in evtchn_bind_user_port()
377 RB_REMOVE(evtchn_tree, &u->evtchns, evtchn); in evtchn_bind_user_port()
378 mtx_unlock(&u->bind_mutex); in evtchn_bind_user_port()
388 struct per_user_data *u; in evtchn_ioctl() local
391 error = devfs_get_cdevpriv((void **)&u); in evtchn_ioctl()
404 error = xen_intr_bind_virq(evtchn_dev, bind->virq, 0, in evtchn_ioctl()
405 NULL, NULL, NULL, 0, &evtchn->handle); in evtchn_ioctl()
410 error = evtchn_bind_user_port(u, evtchn); in evtchn_ioctl()
413 bind->port = evtchn->port; in evtchn_ioctl()
426 bind->remote_domain, bind->remote_port, NULL, in evtchn_ioctl()
427 NULL, NULL, 0, &evtchn->handle); in evtchn_ioctl()
432 error = evtchn_bind_user_port(u, evtchn); in evtchn_ioctl()
435 bind->port = evtchn->port; in evtchn_ioctl()
448 bind->remote_domain, NULL, NULL, NULL, 0, &evtchn->handle); in evtchn_ioctl()
453 error = evtchn_bind_user_port(u, evtchn); in evtchn_ioctl()
456 bind->port = evtchn->port; in evtchn_ioctl()
466 mtx_lock(&u->bind_mutex); in evtchn_ioctl()
467 evtchn = find_evtchn(u, unbind->port); in evtchn_ioctl()
472 RB_REMOVE(evtchn_tree, &u->evtchns, evtchn); in evtchn_ioctl()
473 mtx_unlock(&u->bind_mutex); in evtchn_ioctl()
475 xen_intr_unbind(&evtchn->handle); in evtchn_ioctl()
487 mtx_lock(&u->bind_mutex); in evtchn_ioctl()
488 evtchn = find_evtchn(u, notify->port); in evtchn_ioctl()
494 xen_intr_signal(evtchn->handle); in evtchn_ioctl()
495 mtx_unlock(&u->bind_mutex); in evtchn_ioctl()
502 sx_xlock(&u->ring_cons_mutex); in evtchn_ioctl()
503 mtx_lock(&u->ring_prod_mutex); in evtchn_ioctl()
504 u->ring_cons = u->ring_prod = u->ring_overflow = 0; in evtchn_ioctl()
505 mtx_unlock(&u->ring_prod_mutex); in evtchn_ioctl()
506 sx_xunlock(&u->ring_cons_mutex); in evtchn_ioctl()
528 struct per_user_data *u; in evtchn_poll() local
531 error = devfs_get_cdevpriv((void **)&u); in evtchn_poll()
538 mtx_lock(&u->ring_prod_mutex); in evtchn_poll()
540 if (u->ring_cons != u->ring_prod) { in evtchn_poll()
544 selrecord(td, &u->ev_rsel); in evtchn_poll()
547 mtx_unlock(&u->ring_prod_mutex); in evtchn_poll()
552 /*------------------ Private Device Attachment Functions --------------------*/
562 panic("unable to attach evtchn user-space device"); in evtchn_identify()
569 device_set_desc(dev, "Xen event channel user-space device"); in evtchn_probe()
582 /*-------------------- Private Device Attachment Data -----------------------*/