diff options
author | cl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk> | 2004-10-04 13:15:55 +0000 |
---|---|---|
committer | cl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk> | 2004-10-04 13:15:55 +0000 |
commit | e6521d710d81d983ed87a1f27be7f33a0ed8576d (patch) | |
tree | 67e6814f3551e2c4516ffbbc961fdd588e957f5b /netbsd-2.0-xen-sparse | |
parent | 5595355e81b907b1a496711dbfbc306d956642a5 (diff) | |
download | xen-e6521d710d81d983ed87a1f27be7f33a0ed8576d.tar.gz xen-e6521d710d81d983ed87a1f27be7f33a0ed8576d.tar.bz2 xen-e6521d710d81d983ed87a1f27be7f33a0ed8576d.zip |
bitkeeper revision 1.1159.99.1 (41614d0bCFm_w7iZTkZCC7k5oNSaqw)
Cleanup device initialization.
Add support for bidirectional virtual consoles.
Diffstat (limited to 'netbsd-2.0-xen-sparse')
8 files changed, 223 insertions, 80 deletions
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c index 82e998d3b6..241a8a9b83 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c @@ -127,8 +127,7 @@ stipending() hypervisor_acknowledge_irq(irq); ci->ci_ipending |= (1 << irq); if (ret == 0 && ci->ci_ilevel < - ci->ci_isources[irq]->is_handlers - ->ih_level) + ci->ci_isources[irq]->is_maxlevel) ret = 1; } #if 0 /* XXXcl dev/evtchn */ diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h b/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h index 32a774b1b6..5e84f5af86 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h @@ -81,6 +81,8 @@ struct xennet_softc { netif_tx_interface_t *sc_tx; netif_rx_interface_t *sc_rx; + struct vm_page *sc_pg_tx; + struct vm_page *sc_pg_rx; uint32_t sc_tx_entries; uint32_t sc_tx_resp_cons; @@ -102,6 +104,7 @@ struct xennet_attach_args { struct nfs_diskless; int xennet_scan(struct device *, struct xennet_attach_args *, cfprint_t); +void xennet_scan_finish(struct device *); void xennet_start(struct ifnet *); int xennet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); void xennet_watchdog(struct ifnet *ifp); diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h b/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h index 8c1c57c692..089d365a0d 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h @@ -52,5 +52,6 @@ struct xbd_attach_args { }; int xbd_scan(struct device *, struct xbd_attach_args *, cfprint_t); +void xbd_scan_finish(struct device *); #endif /* _XEN_XBDVAR_H_ */ diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c index 39b4febdd3..d81068b0a1 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c @@ -20,8 +20,9 @@ __KERNEL_RCSID(0, "$NetBSD$"); #include <machine/ctrl_if.h> #include <machine/evtchn.h> +void printk(char *, ...); #if 0 -#define DPRINTK(_f, _a...) printf("(file=%s, line=%d) " _f, \ +#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \ __FILE__ , __LINE__ , ## _a ) #else #define DPRINTK(_f, _a...) ((void)0) @@ -34,7 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD$"); */ int initdom_ctrlif_domcontroller_port = -1; -static int ctrl_if_evtchn; +/* static */ int ctrl_if_evtchn = -1; static int ctrl_if_irq; static struct simplelock ctrl_if_lock; @@ -148,9 +149,10 @@ static void __ctrl_if_rxmsg_deferred(void *unused) while ( ctrl_if_rxmsg_deferred_cons != dp ) { - msg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX( - ctrl_if_rxmsg_deferred_cons++)]; + msg = &ctrl_if_rxmsg_deferred[ + MASK_CONTROL_IDX(ctrl_if_rxmsg_deferred_cons)]; (*ctrl_if_rxmsg_handler[msg->type])(msg, 0); + ctrl_if_rxmsg_deferred_cons++; } } @@ -166,7 +168,7 @@ static void __ctrl_if_rx_tasklet(unsigned long data) while ( ctrl_if_rx_req_cons != rp ) { - pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons++)]; + pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons)]; memcpy(&msg, pmsg, offsetof(ctrl_msg_t, msg)); DPRINTK("Rx-Req %u/%u :: %d/%d\n", @@ -184,6 +186,8 @@ static void __ctrl_if_rx_tasklet(unsigned long data) &msg, offsetof(ctrl_msg_t, msg) + msg.length); else (*ctrl_if_rxmsg_handler[msg.type])(&msg, 0); + + ctrl_if_rx_req_cons++; } if ( dp != ctrl_if_rxmsg_deferred_prod ) @@ -206,11 +210,15 @@ static int ctrl_if_interrupt(void *arg) if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod || ctrl_if_rx_req_cons != ctrl_if->rx_req_prod ) { #if 0 +#if 0 wakeup(&ctrl_if_kthread); #else if (ctrl_if_softintr) softintr_schedule(ctrl_if_softintr); #endif +#else + ctrl_if_kthread((void *)1); +#endif } return 0; @@ -225,6 +233,7 @@ ctrl_if_send_message_noblock( control_if_t *ctrl_if = get_ctrl_if(); unsigned long flags; int i; + int s; save_and_cli(flags); simple_lock(&ctrl_if_lock); @@ -233,7 +242,11 @@ ctrl_if_send_message_noblock( { simple_unlock(&ctrl_if_lock); restore_flags(flags); - return -EAGAIN; + s = splhigh(); + if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod ) + __ctrl_if_tx_tasklet(0); + splx(s); + return EAGAIN; } msg->id = 0xFF; @@ -275,10 +288,13 @@ ctrl_if_send_message_block( while ((rc = ctrl_if_send_message_noblock(msg, hnd, id)) == EAGAIN) { /* XXXcl possible race -> add a lock and ltsleep */ +#if 1 +#else rc = tsleep((caddr_t) &ctrl_if_tx_wait, PUSER | PCATCH, "ctrl_if", 0); if (rc) break; +#endif } return rc; @@ -456,7 +472,6 @@ ctrl_if_kthread(void *arg) { control_if_t *ctrl_if = get_ctrl_if(); - // printf("ctrl_if_kthread starting\n"); for (;;) { if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod ) __ctrl_if_tx_tasklet(0); @@ -464,10 +479,6 @@ ctrl_if_kthread(void *arg) if ( ctrl_if_rx_req_cons != ctrl_if->rx_req_prod ) __ctrl_if_rx_tasklet(0); - if ( ctrl_if_rxmsg_deferred_cons != - ctrl_if_rxmsg_deferred_prod ) - __ctrl_if_rxmsg_deferred(NULL); - if (arg) { // printf("ctrl_if_kthread one-shot done\n"); return; @@ -479,13 +490,19 @@ ctrl_if_kthread(void *arg) } static void -ctrl_if_create_kthread(void *arg) +ctrl_if_softintr_handler(void *arg) { + static int in_handler = 0; - printf("ctrl_if_kthread creating\n"); - if (kthread_create1(ctrl_if_kthread, arg, NULL, "ctrl_if")) - printf("ctrl_if_kthread create failed\n"); - softintr_schedule(ctrl_if_softintr); + if (in_handler++ != 0) { + ctrl_if_evtchn = -1; + panic("recurse"); + } + + if ( ctrl_if_rxmsg_deferred_cons != ctrl_if_rxmsg_deferred_prod ) + __ctrl_if_rxmsg_deferred(NULL); + + in_handler--; } #ifdef notyet @@ -528,20 +545,29 @@ void ctrl_if_resume(void) hypervisor_enable_irq(ctrl_if_irq); } +void ctrl_if_early_init(void); +void ctrl_if_early_init(void) +{ + + simple_lock_init(&ctrl_if_lock); + + ctrl_if_evtchn = xen_start_info.domain_controller_evtchn; +} + void ctrl_if_init(void) { - int i; + int i; - for ( i = 0; i < 256; i++ ) - ctrl_if_rxmsg_handler[i] = ctrl_if_rxmsg_default_handler; + for ( i = 0; i < 256; i++ ) + ctrl_if_rxmsg_handler[i] = ctrl_if_rxmsg_default_handler; - simple_lock_init(&ctrl_if_lock); + if (ctrl_if_evtchn == -1) + ctrl_if_early_init(); - if (0) kthread_create(ctrl_if_create_kthread, NULL); - ctrl_if_softintr = - softintr_establish(IPL_SOFTNET, ctrl_if_kthread, (void *)1); + ctrl_if_softintr = softintr_establish(IPL_SOFTNET, + ctrl_if_softintr_handler, NULL); - ctrl_if_resume(); + ctrl_if_resume(); } diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c index 0f5a9fe788..294f79830a 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c @@ -133,6 +133,18 @@ hypervisor_match(parent, match, aux) return 0; } +static void +scan_finish(struct device *parent) +{ + +#if NXENNET > 0 + xennet_scan_finish(parent); +#endif +#if NXBD > 0 + xbd_scan_finish(parent); +#endif +} + /* * Attach the hypervisor. */ @@ -183,6 +195,9 @@ hypervisor_attach(parent, self, aux) xenvfr_init(); } #endif +#if NXENNET > 0 || NXBD > 0 + config_interrupts(self, scan_finish); +#endif } int diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c index a48f854f13..1670da4ea3 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c @@ -106,8 +106,9 @@ __KERNEL_RCSID(0, "$NetBSD: if_xennet.c,v 1.1.2.1 2004/05/22 15:58:29 he Exp $") #define XEDB_MBUF 0x08 #define XEDB_MEM 0x10 int xennet_debug = 0x0; -#define DPRINTF(x) if (xennet_debug) printf x; -#define DPRINTFN(n,x) if (xennet_debug & (n)) printf x; +void printk(char *, ...); +#define DPRINTF(x) if (xennet_debug) printk x; +#define DPRINTFN(n,x) if (xennet_debug & (n)) printk x; #else #define DPRINTF(x) #define DPRINTFN(n,x) @@ -174,13 +175,21 @@ static int nxennet_media = (sizeof(xennet_media)/sizeof(xennet_media[0])); #endif +static int +xennet_wait_for_interfaces(void) +{ + + while (netctrl.xc_interfaces != netctrl.xc_connected) + HYPERVISOR_yield(); + return 0; +} + int xennet_scan(struct device *self, struct xennet_attach_args *xneta, cfprint_t print) { ctrl_msg_t cmsg; netif_fe_driver_status_t st; - int err = 0; if ((xen_start_info.flags & SIF_INITDOMAIN) || (xen_start_info.flags & SIF_NET_BE_DOMAIN)) @@ -203,13 +212,17 @@ xennet_scan(struct device *self, struct xennet_attach_args *xneta, memcpy(cmsg.msg, &st, sizeof(st)); ctrl_if_send_message_block(&cmsg, NULL, 0, 0); -#if 0 + return 0; +} + +void +xennet_scan_finish(struct device *parent) +{ + int err; + err = xennet_wait_for_interfaces(); if (err) ctrl_if_unregister_receiver(CMSG_NETIF_FE, xennet_ctrlif_rx); -#endif - - return err; } int @@ -270,7 +283,7 @@ find_device(int handle) if (xs->sc_ifno == handle) break; } - return xs; + return dv ? xs : NULL; } static void @@ -278,6 +291,7 @@ xennet_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) { int respond = 1; + DPRINTFN(XEDB_EVENT, ("> ctrlif_rx=%d\n", msg->subtype)); switch (msg->subtype) { case CMSG_NETIF_FE_INTERFACE_STATUS: if (msg->length != sizeof(netif_fe_interface_status_t)) @@ -307,7 +321,8 @@ static void xennet_driver_status_change(netif_fe_driver_status_t *status) { - DPRINTFN(XEDB_EVENT, ("> status=%d\n", status->status)); + DPRINTFN(XEDB_EVENT, ("xennet_driver_status_change(%d)\n", + status->status)); netctrl.xc_up = status->status; xennet_driver_count_connected(); @@ -340,10 +355,9 @@ xennet_interface_status_change(netif_fe_interface_status_t *status) netif_fe_interface_connect_t up; struct xennet_softc *sc; struct ifnet *ifp; - struct vm_page *pg_tx, *pg_rx; struct xennet_attach_args xneta; - DPRINTFN(XEDB_EVENT, ("> status=%d handle=%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n", + DPRINTFN(XEDB_EVENT, ("xennet_interface_status_change(%d,%d,%02x:%02x:%02x:%02x:%02x:%02x)\n", status->status, status->handle, status->mac[0], status->mac[1], status->mac[2], @@ -363,6 +377,11 @@ xennet_interface_status_change(netif_fe_interface_status_t *status) } ifp = &sc->sc_ethercom.ec_if; + DPRINTFN(XEDB_EVENT, ("xennet_interface_status_change(%d,%p,%02x:%02x:%02x:%02x:%02x:%02x)\n", + status->handle, sc, + status->mac[0], status->mac[1], status->mac[2], + status->mac[3], status->mac[4], status->mac[5])); + switch (status->status) { case NETIF_INTERFACE_STATUS_CLOSED: printf("Unexpected netif-CLOSED message in state %d\n", @@ -411,28 +430,30 @@ xennet_interface_status_change(netif_fe_interface_status_t *status) } #endif - /* Move from CLOSED to DISCONNECTED state. */ - sc->sc_tx = (netif_tx_interface_t *) - uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE); - if (sc->sc_tx == NULL) - panic("netif: no tx va"); - sc->sc_rx = (netif_rx_interface_t *) - uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE); - if (sc->sc_rx == NULL) - panic("netif: no rx va"); - pg_tx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); - if (pg_tx == NULL) { - panic("netif: no tx pages"); - } - pmap_kenter_pa((vaddr_t)sc->sc_tx, VM_PAGE_TO_PHYS(pg_tx), - VM_PROT_READ | VM_PROT_WRITE); - pg_rx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); - if (pg_rx == NULL) { - panic("netif: no rx pages"); + if (sc->sc_backend_state == BEST_CLOSED) { + /* Move from CLOSED to DISCONNECTED state. */ + sc->sc_tx = (netif_tx_interface_t *) + uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE); + if (sc->sc_tx == NULL) + panic("netif: no tx va"); + sc->sc_rx = (netif_rx_interface_t *) + uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE); + if (sc->sc_rx == NULL) + panic("netif: no rx va"); + sc->sc_pg_tx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); + if (sc->sc_pg_tx == NULL) { + panic("netif: no tx pages"); + } + pmap_kenter_pa((vaddr_t)sc->sc_tx, VM_PAGE_TO_PHYS(sc->sc_pg_tx), + VM_PROT_READ | VM_PROT_WRITE); + sc->sc_pg_rx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); + if (sc->sc_pg_rx == NULL) { + panic("netif: no rx pages"); + } + pmap_kenter_pa((vaddr_t)sc->sc_rx, VM_PAGE_TO_PHYS(sc->sc_pg_rx), + VM_PROT_READ | VM_PROT_WRITE); + sc->sc_backend_state = BEST_DISCONNECTED; } - pmap_kenter_pa((vaddr_t)sc->sc_rx, VM_PAGE_TO_PHYS(pg_rx), - VM_PROT_READ | VM_PROT_WRITE); - sc->sc_backend_state = BEST_DISCONNECTED; /* Construct an interface-CONNECT message for the * domain controller. */ @@ -440,8 +461,8 @@ xennet_interface_status_change(netif_fe_interface_status_t *status) cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT; cmsg.length = sizeof(netif_fe_interface_connect_t); up.handle = status->handle; - up.tx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(pg_tx)) >> PAGE_SHIFT; - up.rx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(pg_rx)) >> PAGE_SHIFT; + up.tx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(sc->sc_pg_tx)) >> PAGE_SHIFT; + up.rx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(sc->sc_pg_rx)) >> PAGE_SHIFT; memcpy(cmsg.msg, &up, sizeof(up)); /* Tell the controller to bring up the interface. */ @@ -514,6 +535,7 @@ xennet_interface_status_change(netif_fe_interface_status_t *status) status->status); break; } + DPRINTFN(XEDB_EVENT, ("xennet_interface_status_change()\n")); } static void @@ -806,8 +828,6 @@ network_alloc_rx_buffers(struct xennet_softc *sc) int s; ringidx = sc->sc_rx->req_prod; - if (0) printf("network_alloc_rx_buffers prod %d cons %d\n", ringidx, - sc->sc_rx_resp_cons); if ((ringidx - sc->sc_rx_resp_cons) > (RX_MAX_ENTRIES / 2)) return; diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c index 9cfab063a9..a8034a2116 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c @@ -809,7 +809,7 @@ send_driver_status(int ok) .subtype = CMSG_BLKIF_FE_DRIVER_STATUS, .length = sizeof(blkif_fe_driver_status_t), }; - blkif_fe_driver_status_t *msg = (void*)cmsg.msg; + blkif_fe_driver_status_t *msg = (blkif_fe_driver_status_t *)cmsg.msg; msg->status = ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN; @@ -825,7 +825,8 @@ send_interface_connect(void) .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT, .length = sizeof(blkif_fe_interface_connect_t), }; - blkif_fe_interface_connect_t *msg = (void*)cmsg.msg; + blkif_fe_interface_connect_t *msg = + (blkif_fe_interface_connect_t *)cmsg.msg; paddr_t pa; pmap_extract(pmap_kernel(), (vaddr_t)blk_ring, &pa); @@ -866,6 +867,15 @@ setup_sysctl(void) diskcookies = pnode; } +static int +xbd_wait_for_interfaces(void) +{ + + while (state != STATE_CONNECTED) + HYPERVISOR_yield(); + return 0; +} + int xbd_scan(struct device *self, struct xbd_attach_args *mainbus_xbda, cfprint_t print) @@ -912,13 +922,19 @@ xbd_scan(struct device *self, struct xbd_attach_args *mainbus_xbda, send_driver_status(1); -#if 0 - enable_update_events(self); -#endif - return 0; } +void +xbd_scan_finish(struct device *parent) +{ + int err; + + err = xbd_wait_for_interfaces(); + if (err) + ctrl_if_unregister_receiver(CMSG_NETIF_FE, xbd_ctrlif_rx); +} + #if NXBD > 0 int xbd_match(struct device *parent, struct cfdata *match, void *aux) diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c index a151e3dd83..91fbccd9ed 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c @@ -46,6 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: xencons.c,v 1.1.2.1 2004/05/22 15:59:21 he Exp $"); #include <machine/stdarg.h> #include <machine/xen.h> #include <machine/hypervisor.h> +#include <machine/evtchn.h> +#include <machine/ctrl_if.h> #include <dev/cons.h> @@ -87,6 +89,7 @@ const struct cdevsw xencons_cdevsw = { }; +static void xencons_rx(ctrl_msg_t *, unsigned long); void xenconscn_attach(void); int xenconscn_getc(dev_t); void xenconscn_putc(dev_t, int); @@ -131,6 +134,8 @@ xencons_attach(struct device *parent, struct device *self, void *aux) /* Set db_max_line to avoid paging. */ db_max_line = 0x7fffffff; + + (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0); } } @@ -258,7 +263,6 @@ xencons_start(struct tty *tp) { struct clist *cl; int s, len; - u_char buf[XENCONS_BURST+1]; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) @@ -271,8 +275,22 @@ xencons_start(struct tty *tp) * expensive and we don't want our serial ports to overflow. */ cl = &tp->t_outq; - len = q_to_b(cl, buf, XENCONS_BURST); - (void)HYPERVISOR_console_io(CONSOLEIO_write, len, buf); + if (xen_start_info.flags & SIF_INITDOMAIN) { + u_char buf[XENCONS_BURST+1]; + + len = q_to_b(cl, buf, XENCONS_BURST); + (void)HYPERVISOR_console_io(CONSOLEIO_write, len, buf); + } else { + ctrl_msg_t msg; + + len = q_to_b(cl, msg.msg, sizeof(msg.msg)); + msg.type = CMSG_CONSOLE; + msg.subtype = CMSG_CONSOLE_DATA; + msg.length = len; + ctrl_if_send_message_noblock(&msg, NULL, 0); + /* XXX check return value and queue wait for space + * thread/softint */ + } s = spltty(); tp->t_state &= ~TS_BUSY; @@ -298,13 +316,47 @@ xencons_stop(struct tty *tp, int flag) } +/* Non-privileged receive callback. */ +static void +xencons_rx(ctrl_msg_t *msg, unsigned long id) +{ + int i; + int s; + // unsigned long flags; + struct xencons_softc *sc; + struct tty *tp; + + sc = device_lookup(&xencons_cd, XENCONS_UNIT(cn_tab->cn_dev)); + if (sc == NULL) + goto out; + + tp = sc->sc_tty; + if (tp == NULL) + goto out; + + s = spltty(); + // save_and_cli(flags); + // simple_lock(&xencons_lock); + for (i = 0; i < msg->length; i++) + (*tp->t_linesw->l_rint)(msg->msg[i], tp); + // simple_unlock(&xencons_lock); + // restore_flags(flags); + splx(s); + out: + msg->length = 0; + ctrl_if_send_response(msg); +} + +void ctrl_if_early_init(void); void xenconscn_attach() { cn_tab = &xencons; + ctrl_if_early_init(); + xencons_isconsole = 1; } @@ -316,18 +368,29 @@ xenconscn_getc(dev_t dev) for (;;); } -#define MAXLINELEN 1024 void xenconscn_putc(dev_t dev, int c) { - static char buf[1024+1]; - static int bufpos = 0; - - buf[bufpos++] = c; - if (c == '\n') { - buf[bufpos] = 0; - (void)HYPERVISOR_console_io(CONSOLEIO_write, bufpos, buf); - bufpos = 0; + extern int ctrl_if_evtchn; + + if (xen_start_info.flags & SIF_INITDOMAIN || + ctrl_if_evtchn == -1) { + u_char buf[1]; + + buf[0] = c; + (void)HYPERVISOR_console_io(CONSOLEIO_write, 1, buf); + } else { + ctrl_msg_t msg; + + msg.type = CMSG_CONSOLE; + msg.subtype = CMSG_CONSOLE_DATA; + msg.length = 1; + msg.msg[0] = c; + while (ctrl_if_send_message_noblock(&msg, NULL, 0) == EAGAIN) { + HYPERVISOR_yield(); + /* XXX check return value and queue wait for space + * thread/softint */ + } } } |