xencons_ring.c revision 181643
1#include <sys/cdefs.h> 2__FBSDID("$FreeBSD: head/sys/dev/xen/console/xencons_ring.c 181643 2008-08-12 20:01:57Z kmacy $"); 3 4#include <sys/param.h> 5#include <sys/module.h> 6#include <sys/systm.h> 7#include <sys/consio.h> 8#include <sys/proc.h> 9#include <sys/uio.h> 10#include <sys/tty.h> 11#include <sys/systm.h> 12#include <sys/taskqueue.h> 13#include <sys/conf.h> 14#include <sys/kernel.h> 15#include <sys/bus.h> 16#include <machine/stdarg.h> 17#include <machine/xen/xen-os.h> 18#include <machine/xen/hypervisor.h> 19#include <machine/xen/xen_intr.h> 20#include <sys/cons.h> 21 22 23#include <dev/xen/console/xencons_ring.h> 24#include <machine/xen/evtchn.h> 25#include <xen/interface/io/console.h> 26 27 28#define console_evtchn console.domU.evtchn 29extern char *console_page; 30 31static inline struct xencons_interface * 32xencons_interface(void) 33{ 34 return (struct xencons_interface *)console_page; 35} 36 37 38int 39xencons_has_input(void) 40{ 41 struct xencons_interface *intf; 42 43 intf = xencons_interface(); 44 45 return (intf->in_cons != intf->in_prod); 46} 47 48 49int 50xencons_ring_send(const char *data, unsigned len) 51{ 52 struct xencons_interface *intf; 53 XENCONS_RING_IDX cons, prod; 54 int sent; 55 56 intf = xencons_interface(); 57 cons = intf->out_cons; 58 prod = intf->out_prod; 59 sent = 0; 60 61 mb(); 62 PANIC_IF((prod - cons) > sizeof(intf->out)); 63 64 while ((sent < len) && ((prod - cons) < sizeof(intf->out))) 65 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; 66 67 wmb(); 68 intf->out_prod = prod; 69 70 notify_remote_via_evtchn(xen_start_info->console_evtchn); 71 72 return sent; 73 74} 75 76 77static xencons_receiver_func *xencons_receiver; 78 79void 80xencons_handle_input(void *unused) 81{ 82 struct xencons_interface *intf; 83 XENCONS_RING_IDX cons, prod; 84 85 intf = xencons_interface(); 86 87 cons = intf->in_cons; 88 prod = intf->in_prod; 89 90 /* XXX needs locking */ 91 while (cons != prod) { 92 xencons_rx(intf->in + MASK_XENCONS_IDX(cons, intf->in), 1); 93 cons++; 94 } 95 96 mb(); 97 intf->in_cons = cons; 98 99 notify_remote_via_evtchn(xen_start_info->console_evtchn); 100 101 xencons_tx(); 102} 103 104void 105xencons_ring_register_receiver(xencons_receiver_func *f) 106{ 107 xencons_receiver = f; 108} 109 110int 111xencons_ring_init(void) 112{ 113 int err; 114 115 if (!xen_start_info->console_evtchn) 116 return 0; 117 118 err = bind_caller_port_to_irqhandler(xen_start_info->console_evtchn, 119 "xencons", xencons_handle_input, NULL, 120 INTR_TYPE_MISC | INTR_MPSAFE, NULL); 121 if (err) { 122 XENPRINTF("XEN console request irq failed %i\n", err); 123 return err; 124 } 125 126 return 0; 127} 128#ifdef notyet 129void 130xencons_suspend(void) 131{ 132 133 if (!xen_start_info->console_evtchn) 134 return; 135 136 unbind_evtchn_from_irqhandler(xen_start_info->console_evtchn, NULL); 137} 138 139void 140xencons_resume(void) 141{ 142 143 (void)xencons_ring_init(); 144} 145#endif 146/* 147 * Local variables: 148 * mode: C 149 * c-set-style: "BSD" 150 * c-basic-offset: 8 151 * tab-width: 4 152 * indent-tabs-mode: t 153 * End: 154 */ 155