ia64/xen-unstable

changeset 19773:11d8ca329b54

minios: support secondary guest consoles.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jun 17 07:22:18 2009 +0100 (2009-06-17)
parents aaab04808ee7
children 74911141ce79
files extras/mini-os/console/console.c extras/mini-os/console/xencons_ring.c extras/mini-os/include/console.h extras/mini-os/include/lib.h extras/mini-os/kernel.c extras/mini-os/lib/sys.c stubdom/grub/mini-os.c
line diff
     1.1 --- a/extras/mini-os/console/console.c	Wed Jun 17 07:21:03 2009 +0100
     1.2 +++ b/extras/mini-os/console/console.c	Wed Jun 17 07:22:18 2009 +0100
     1.3 @@ -76,11 +76,11 @@ void xencons_tx(void)
     1.4  #endif
     1.5  
     1.6  
     1.7 -void console_print(char *data, int length)
     1.8 +void console_print(struct consfront_dev *dev, char *data, int length)
     1.9  {
    1.10      char *curr_char, saved_char;
    1.11      int part_len;
    1.12 -    int (*ring_send_fn)(const char *data, unsigned length);
    1.13 +    int (*ring_send_fn)(struct consfront_dev *dev, const char *data, unsigned length);
    1.14  
    1.15      if(!console_initialised)
    1.16          ring_send_fn = xencons_ring_send_no_notify;
    1.17 @@ -94,17 +94,17 @@ void console_print(char *data, int lengt
    1.18              saved_char = *(curr_char+1);
    1.19              *(curr_char+1) = '\r';
    1.20              part_len = curr_char - data + 2;
    1.21 -            ring_send_fn(data, part_len);
    1.22 +            ring_send_fn(dev, data, part_len);
    1.23              *(curr_char+1) = saved_char;
    1.24              data = curr_char+1;
    1.25              length -= part_len - 1;
    1.26          }
    1.27      }
    1.28      
    1.29 -    ring_send_fn(data, length);
    1.30 +    ring_send_fn(dev, data, length);
    1.31      
    1.32      if(data[length-1] == '\n')
    1.33 -        ring_send_fn("\r", 1);
    1.34 +        ring_send_fn(dev, "\r", 1);
    1.35  }
    1.36  
    1.37  void print(int direct, const char *fmt, va_list args)
    1.38 @@ -123,7 +123,7 @@ void print(int direct, const char *fmt, 
    1.39  #endif    
    1.40              (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
    1.41          
    1.42 -        console_print(buf, strlen(buf));
    1.43 +        console_print(NULL, buf, strlen(buf));
    1.44      }
    1.45  }
    1.46  
    1.47 @@ -151,7 +151,7 @@ void init_console(void)
    1.48      printk("done.\n");
    1.49  }
    1.50  
    1.51 -void fini_console(void)
    1.52 +void fini_console(struct consfront_dev *dev)
    1.53  {
    1.54 -    /* Destruct the console and get the parameters of the restarted one */
    1.55 +    if (dev) free_consfront(dev);
    1.56  }
     2.1 --- a/extras/mini-os/console/xencons_ring.c	Wed Jun 17 07:21:03 2009 +0100
     2.2 +++ b/extras/mini-os/console/xencons_ring.c	Wed Jun 17 07:22:18 2009 +0100
     2.3 @@ -7,25 +7,38 @@
     2.4  #include <lib.h>
     2.5  #include <xenbus.h>
     2.6  #include <xen/io/console.h>
     2.7 +#include <xen/io/protocols.h>
     2.8 +#include <xen/io/ring.h>
     2.9 +#include <xmalloc.h>
    2.10 +#include <gnttab.h>
    2.11  
    2.12  DECLARE_WAIT_QUEUE_HEAD(console_queue);
    2.13  
    2.14 +static inline void notify_daemon(struct consfront_dev *dev)
    2.15 +{
    2.16 +    /* Use evtchn: this is called early, before irq is set up. */
    2.17 +    if (!dev)
    2.18 +        notify_remote_via_evtchn(start_info.console.domU.evtchn);
    2.19 +    else
    2.20 +        notify_remote_via_evtchn(dev->evtchn);
    2.21 +}
    2.22 +
    2.23  static inline struct xencons_interface *xencons_interface(void)
    2.24  {
    2.25      return mfn_to_virt(start_info.console.domU.mfn);
    2.26 -}
    2.27 -
    2.28 -static inline void notify_daemon(void)
    2.29 -{
    2.30 -    /* Use evtchn: this is called early, before irq is set up. */
    2.31 -    notify_remote_via_evtchn(start_info.console.domU.evtchn);
    2.32 -}
    2.33 -
    2.34 -int xencons_ring_send_no_notify(const char *data, unsigned len)
    2.35 +} 
    2.36 + 
    2.37 +int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, unsigned len)
    2.38  {	
    2.39      int sent = 0;
    2.40 -	struct xencons_interface *intf = xencons_interface();
    2.41 +	struct xencons_interface *intf;
    2.42  	XENCONS_RING_IDX cons, prod;
    2.43 +
    2.44 +	if (!dev)
    2.45 +            intf = xencons_interface();
    2.46 +        else
    2.47 +            intf = dev->ring;
    2.48 +
    2.49  	cons = intf->out_cons;
    2.50  	prod = intf->out_prod;
    2.51  	mb();
    2.52 @@ -40,20 +53,27 @@ int xencons_ring_send_no_notify(const ch
    2.53      return sent;
    2.54  }
    2.55  
    2.56 -int xencons_ring_send(const char *data, unsigned len)
    2.57 +int xencons_ring_send(struct consfront_dev *dev, const char *data, unsigned len)
    2.58  {
    2.59      int sent;
    2.60 -    sent = xencons_ring_send_no_notify(data, len);
    2.61 -	notify_daemon();
    2.62  
    2.63 -	return sent;
    2.64 +    sent = xencons_ring_send_no_notify(dev, data, len);
    2.65 +    notify_daemon(dev);
    2.66 +
    2.67 +    return sent;
    2.68  }	
    2.69  
    2.70  
    2.71  
    2.72 -static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
    2.73 +static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *data)
    2.74  {
    2.75  #ifdef HAVE_LIBC
    2.76 +	struct consfront_dev *dev = (struct consfront_dev *) data;
    2.77 +        int fd = dev ? dev->fd : -1;
    2.78 +
    2.79 +        if (fd != -1)
    2.80 +            files[fd].read = 1;
    2.81 +
    2.82          wake_up(&console_queue);
    2.83  #else
    2.84  	struct xencons_interface *intf = xencons_interface();
    2.85 @@ -72,18 +92,23 @@ static void handle_input(evtchn_port_t p
    2.86  	mb();
    2.87  	intf->in_cons = cons;
    2.88  
    2.89 -	notify_daemon();
    2.90 +	notify_daemon(dev);
    2.91  
    2.92  	xencons_tx();
    2.93  #endif
    2.94  }
    2.95  
    2.96  #ifdef HAVE_LIBC
    2.97 -int xencons_ring_avail(void)
    2.98 +int xencons_ring_avail(struct consfront_dev *dev)
    2.99  {
   2.100 -	struct xencons_interface *intf = xencons_interface();
   2.101 +	struct xencons_interface *intf;
   2.102  	XENCONS_RING_IDX cons, prod;
   2.103  
   2.104 +        if (!dev)
   2.105 +            intf = xencons_interface();
   2.106 +        else
   2.107 +            intf = dev->ring;
   2.108 +
   2.109  	cons = intf->in_cons;
   2.110  	prod = intf->in_prod;
   2.111  	mb();
   2.112 @@ -92,12 +117,17 @@ int xencons_ring_avail(void)
   2.113          return prod - cons;
   2.114  }
   2.115  
   2.116 -int xencons_ring_recv(char *data, unsigned len)
   2.117 +int xencons_ring_recv(struct consfront_dev *dev, char *data, unsigned len)
   2.118  {
   2.119 -	struct xencons_interface *intf = xencons_interface();
   2.120 +	struct xencons_interface *intf;
   2.121  	XENCONS_RING_IDX cons, prod;
   2.122          unsigned filled = 0;
   2.123  
   2.124 +        if (!dev)
   2.125 +            intf = xencons_interface();
   2.126 +        else
   2.127 +            intf = dev->ring;
   2.128 +
   2.129  	cons = intf->in_cons;
   2.130  	prod = intf->in_prod;
   2.131  	mb();
   2.132 @@ -111,31 +141,190 @@ int xencons_ring_recv(char *data, unsign
   2.133  	mb();
   2.134          intf->in_cons = cons + filled;
   2.135  
   2.136 -	notify_daemon();
   2.137 +	notify_daemon(dev);
   2.138  
   2.139          return filled;
   2.140  }
   2.141  #endif
   2.142  
   2.143 -int xencons_ring_init(void)
   2.144 +struct consfront_dev *xencons_ring_init(void)
   2.145  {
   2.146  	int err;
   2.147 +	struct consfront_dev *dev;
   2.148  
   2.149  	if (!start_info.console.domU.evtchn)
   2.150  		return 0;
   2.151  
   2.152 -	err = bind_evtchn(start_info.console.domU.evtchn, handle_input,
   2.153 -			  NULL);
   2.154 +	dev = malloc(sizeof(struct consfront_dev));
   2.155 +	memset(dev, 0, sizeof(struct consfront_dev));
   2.156 +	dev->nodename = "device/console";
   2.157 +	dev->dom = 0;
   2.158 +	dev->backend = 0;
   2.159 +	dev->ring_ref = 0;
   2.160 +
   2.161 +#ifdef HAVE_LIBC
   2.162 +	dev->fd = -1;
   2.163 +#endif
   2.164 +	dev->evtchn = start_info.console.domU.evtchn;
   2.165 +	dev->ring = (struct xencons_interface *) mfn_to_virt(start_info.console.domU.mfn);
   2.166 +
   2.167 +	err = bind_evtchn(dev->evtchn, handle_input, dev);
   2.168  	if (err <= 0) {
   2.169  		printk("XEN console request chn bind failed %i\n", err);
   2.170 -		return err;
   2.171 +                free(dev);
   2.172 +		return NULL;
   2.173  	}
   2.174 -        unmask_evtchn(start_info.console.domU.evtchn);
   2.175 +        unmask_evtchn(dev->evtchn);
   2.176  
   2.177  	/* In case we have in-flight data after save/restore... */
   2.178 -	notify_daemon();
   2.179 +	notify_daemon(dev);
   2.180  
   2.181 -	return 0;
   2.182 +	return dev;
   2.183 +}
   2.184 +
   2.185 +void free_consfront(struct consfront_dev *dev)
   2.186 +{
   2.187 +    mask_evtchn(dev->evtchn);
   2.188 +
   2.189 +    free(dev->backend);
   2.190 +
   2.191 +    gnttab_end_access(dev->ring_ref);
   2.192 +    free_page(dev->ring);
   2.193 +
   2.194 +    unbind_evtchn(dev->evtchn);
   2.195 +
   2.196 +    free(dev->nodename);
   2.197 +    free(dev);
   2.198 +}
   2.199 +
   2.200 +struct consfront_dev *init_consfront(char *_nodename)
   2.201 +{
   2.202 +    xenbus_transaction_t xbt;
   2.203 +    char* err;
   2.204 +    char* message=NULL;
   2.205 +    int retry=0;
   2.206 +    char* msg;
   2.207 +    char nodename[256];
   2.208 +    char path[256];
   2.209 +    static int consfrontends = 1;
   2.210 +    struct consfront_dev *dev;
   2.211 +    int res;
   2.212 +
   2.213 +    if (!_nodename)
   2.214 +        snprintf(nodename, sizeof(nodename), "device/console/%d", consfrontends);
   2.215 +    else
   2.216 +        strncpy(nodename, _nodename, sizeof(nodename));
   2.217 +
   2.218 +    printk("******************* CONSFRONT for %s **********\n\n\n", nodename);
   2.219 +
   2.220 +    consfrontends++;
   2.221 +    dev = malloc(sizeof(*dev));
   2.222 +    memset(dev, 0, sizeof(*dev));
   2.223 +    dev->nodename = strdup(nodename);
   2.224 +#ifdef HAVE_LIBC
   2.225 +    dev->fd = -1;
   2.226 +#endif
   2.227 +
   2.228 +    snprintf(path, sizeof(path), "%s/backend-id", nodename);
   2.229 +    if ((res = xenbus_read_integer(path)) < 0) 
   2.230 +        return NULL;
   2.231 +    else
   2.232 +        dev->dom = res;
   2.233 +    evtchn_alloc_unbound(dev->dom, handle_input, dev, &dev->evtchn);
   2.234 +
   2.235 +    dev->ring = (struct xencons_interface *) alloc_page();
   2.236 +    memset(dev->ring, 0, PAGE_SIZE);
   2.237 +    dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_mfn(dev->ring), 0);
   2.238 +
   2.239 +    dev->events = NULL;
   2.240 +
   2.241 +again:
   2.242 +    err = xenbus_transaction_start(&xbt);
   2.243 +    if (err) {
   2.244 +        printk("starting transaction\n");
   2.245 +    }
   2.246 +
   2.247 +    err = xenbus_printf(xbt, nodename, "ring-ref","%u",
   2.248 +                dev->ring_ref);
   2.249 +    if (err) {
   2.250 +        message = "writing ring-ref";
   2.251 +        goto abort_transaction;
   2.252 +    }
   2.253 +    err = xenbus_printf(xbt, nodename,
   2.254 +                "port", "%u", dev->evtchn);
   2.255 +    if (err) {
   2.256 +        message = "writing event-channel";
   2.257 +        goto abort_transaction;
   2.258 +    }
   2.259 +    err = xenbus_printf(xbt, nodename,
   2.260 +                "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
   2.261 +    if (err) {
   2.262 +        message = "writing protocol";
   2.263 +        goto abort_transaction;
   2.264 +    }
   2.265 +
   2.266 +    err = xenbus_printf(xbt, nodename, "type", "%s", "ioemu");
   2.267 +    if (err) {
   2.268 +        message = "writing type";
   2.269 +        goto abort_transaction;
   2.270 +    }
   2.271 +
   2.272 +    snprintf(path, sizeof(path), "%s/state", nodename);
   2.273 +    err = xenbus_switch_state(xbt, path, XenbusStateConnected);
   2.274 +    if (err) {
   2.275 +        message = "switching state";
   2.276 +        goto abort_transaction;
   2.277 +    }
   2.278 +
   2.279 +
   2.280 +    err = xenbus_transaction_end(xbt, 0, &retry);
   2.281 +    if (retry) {
   2.282 +            goto again;
   2.283 +        printk("completing transaction\n");
   2.284 +    }
   2.285 +
   2.286 +    goto done;
   2.287 +
   2.288 +abort_transaction:
   2.289 +    xenbus_transaction_end(xbt, 1, &retry);
   2.290 +    goto error;
   2.291 +
   2.292 +done:
   2.293 +
   2.294 +    snprintf(path, sizeof(path), "%s/backend", nodename);
   2.295 +    msg = xenbus_read(XBT_NIL, path, &dev->backend);
   2.296 +    if (msg) {
   2.297 +        printk("Error %s when reading the backend path %s\n", msg, path);
   2.298 +        goto error;
   2.299 +    }
   2.300 +
   2.301 +    printk("backend at %s\n", dev->backend);
   2.302 +
   2.303 +    {
   2.304 +        XenbusState state;
   2.305 +        char path[strlen(dev->backend) + 1 + 19 + 1];
   2.306 +        snprintf(path, sizeof(path), "%s/state", dev->backend);
   2.307 +        
   2.308 +	xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
   2.309 +        msg = NULL;
   2.310 +        state = xenbus_read_integer(path);
   2.311 +        while (msg == NULL && state < XenbusStateConnected)
   2.312 +            msg = xenbus_wait_for_state_change(path, &state, &dev->events);
   2.313 +        if (msg != NULL || state != XenbusStateConnected) {
   2.314 +            printk("backend not available, state=%d\n", state);
   2.315 +            xenbus_unwatch_path(XBT_NIL, path);
   2.316 +            goto error;
   2.317 +        }
   2.318 +    }
   2.319 +    unmask_evtchn(dev->evtchn);
   2.320 +
   2.321 +    printk("**************************\n");
   2.322 +
   2.323 +    return dev;
   2.324 +
   2.325 +error:
   2.326 +    free_consfront(dev);
   2.327 +    return NULL;
   2.328  }
   2.329  
   2.330  void xencons_resume(void)
     3.1 --- a/extras/mini-os/include/console.h	Wed Jun 17 07:21:03 2009 +0100
     3.2 +++ b/extras/mini-os/include/console.h	Wed Jun 17 07:22:18 2009 +0100
     3.3 @@ -36,9 +36,32 @@
     3.4  #ifndef _LIB_CONSOLE_H_
     3.5  #define _LIB_CONSOLE_H_
     3.6  
     3.7 -#include<mini-os/os.h>
     3.8 -#include<mini-os/traps.h>
     3.9 -#include<stdarg.h>
    3.10 +#include <mini-os/os.h>
    3.11 +#include <mini-os/traps.h>
    3.12 +#include <mini-os/types.h>
    3.13 +#include <xen/grant_table.h>
    3.14 +#include <xenbus.h>
    3.15 +#include <xen/io/console.h>
    3.16 +#include <stdarg.h>
    3.17 +
    3.18 +struct consfront_dev {
    3.19 +    domid_t dom;
    3.20 +
    3.21 +    struct xencons_interface *ring;
    3.22 +    grant_ref_t ring_ref;
    3.23 +    evtchn_port_t evtchn;
    3.24 +
    3.25 +    char *nodename;
    3.26 +    char *backend;
    3.27 +
    3.28 +    xenbus_event_queue events;
    3.29 +
    3.30 +#ifdef HAVE_LIBC
    3.31 +    int fd;
    3.32 +#endif
    3.33 +};
    3.34 +
    3.35 +
    3.36  
    3.37  void print(int direct, const char *fmt, va_list args);
    3.38  void printk(const char *fmt, ...);
    3.39 @@ -50,16 +73,17 @@ void xencons_rx(char *buf, unsigned len,
    3.40  void xencons_tx(void);
    3.41  
    3.42  void init_console(void);
    3.43 -void console_print(char *data, int length);
    3.44 -void fini_console(void);
    3.45 +void console_print(struct consfront_dev *dev, char *data, int length);
    3.46 +void fini_console(struct consfront_dev *dev);
    3.47  
    3.48  /* Low level functions defined in xencons_ring.c */
    3.49  extern struct wait_queue_head console_queue;
    3.50 -int xencons_ring_init(void);
    3.51 -int xencons_ring_send(const char *data, unsigned len);
    3.52 -int xencons_ring_send_no_notify(const char *data, unsigned len);
    3.53 -int xencons_ring_avail(void);
    3.54 -int xencons_ring_recv(char *data, unsigned len);
    3.55 -
    3.56 +struct consfront_dev *xencons_ring_init(void);
    3.57 +struct consfront_dev *init_consfront(char *_nodename);
    3.58 +int xencons_ring_send(struct consfront_dev *dev, const char *data, unsigned len);
    3.59 +int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, unsigned len);
    3.60 +int xencons_ring_avail(struct consfront_dev *dev);
    3.61 +int xencons_ring_recv(struct consfront_dev *dev, char *data, unsigned len);
    3.62 +void free_consfront(struct consfront_dev *dev);
    3.63  
    3.64  #endif /* _LIB_CONSOLE_H_ */
     4.1 --- a/extras/mini-os/include/lib.h	Wed Jun 17 07:21:03 2009 +0100
     4.2 +++ b/extras/mini-os/include/lib.h	Wed Jun 17 07:22:18 2009 +0100
     4.3 @@ -101,6 +101,7 @@ char * strcat(char * dest, const char * 
     4.4  char  *strdup(const char *s);
     4.5  #endif
     4.6  #include <mini-os/console.h>
     4.7 +int openpty(void);
     4.8  
     4.9  #define RAND_MIX 2654435769U
    4.10  
    4.11 @@ -183,6 +184,9 @@ extern struct file {
    4.12  	struct {
    4.13  	    struct fbfront_dev *dev;
    4.14  	} fb;
    4.15 +	struct {
    4.16 +	    struct consfront_dev *dev;
    4.17 +	} cons;
    4.18          struct {
    4.19              /* To each xenbus FD is associated a queue of watch events for this
    4.20               * FD.  */
     5.1 --- a/extras/mini-os/kernel.c	Wed Jun 17 07:21:03 2009 +0100
     5.2 +++ b/extras/mini-os/kernel.c	Wed Jun 17 07:22:18 2009 +0100
     5.3 @@ -562,7 +562,7 @@ void stop_kernel(void)
     5.4      fini_gnttab();
     5.5  
     5.6      /* Reset the console driver. */
     5.7 -    fini_console();
     5.8 +    fini_console(NULL);
     5.9      /* TODO: record new ring mfn & event in start_info */
    5.10  
    5.11      /* Reset XenBus */
     6.1 --- a/extras/mini-os/lib/sys.c	Wed Jun 17 07:21:03 2009 +0100
     6.2 +++ b/extras/mini-os/lib/sys.c	Wed Jun 17 07:22:18 2009 +0100
     6.3 @@ -167,6 +167,18 @@ int mkdir(const char *pathname, mode_t m
     6.4      return 0;
     6.5  }
     6.6  
     6.7 +int openpty(void)
     6.8 +{
     6.9 +    struct consfront_dev *dev;
    6.10 +
    6.11 +    dev = init_consfront(NULL);
    6.12 +    dev->fd = alloc_fd(FTYPE_CONSOLE);
    6.13 +    files[dev->fd].cons.dev = dev;
    6.14 +
    6.15 +    printk("fd(%d) = openpty\n", dev->fd);
    6.16 +    return(dev->fd);
    6.17 +}
    6.18 +
    6.19  int open(const char *pathname, int flags, ...)
    6.20  {
    6.21      int fs_fd, fd;
    6.22 @@ -219,7 +231,7 @@ int read(int fd, void *buf, size_t nbyte
    6.23              DEFINE_WAIT(w);
    6.24              while(1) {
    6.25                  add_waiter(w, console_queue);
    6.26 -                ret = xencons_ring_recv(buf, nbytes);
    6.27 +                ret = xencons_ring_recv(files[fd].cons.dev, buf, nbytes);
    6.28                  if (ret)
    6.29                      break;
    6.30                  schedule();
    6.31 @@ -286,7 +298,7 @@ int write(int fd, const void *buf, size_
    6.32  {
    6.33      switch (files[fd].type) {
    6.34  	case FTYPE_CONSOLE:
    6.35 -	    console_print((char *)buf, nbytes);
    6.36 +	    console_print(files[fd].cons.dev, (char *)buf, nbytes);
    6.37  	    return nbytes;
    6.38  	case FTYPE_FILE: {
    6.39  	    ssize_t ret;
    6.40 @@ -416,6 +428,10 @@ int close(int fd)
    6.41              shutdown_fbfront(files[fd].fb.dev);
    6.42              files[fd].type = FTYPE_NONE;
    6.43              return 0;
    6.44 +        case FTYPE_CONSOLE:
    6.45 +            fini_console(files[fd].cons.dev);
    6.46 +            files[fd].type = FTYPE_NONE;
    6.47 +            return 0;
    6.48  	case FTYPE_NONE:
    6.49  	    break;
    6.50      }
    6.51 @@ -735,7 +751,7 @@ static int select_poll(int nfds, fd_set 
    6.52  	    break;
    6.53  	case FTYPE_CONSOLE:
    6.54  	    if (FD_ISSET(i, readfds)) {
    6.55 -                if (xencons_ring_avail())
    6.56 +                if (xencons_ring_avail(files[i].cons.dev))
    6.57  		    n++;
    6.58  		else
    6.59  		    FD_CLR(i, readfds);
     7.1 --- a/stubdom/grub/mini-os.c	Wed Jun 17 07:21:03 2009 +0100
     7.2 +++ b/stubdom/grub/mini-os.c	Wed Jun 17 07:22:18 2009 +0100
     7.3 @@ -329,7 +329,7 @@ void
     7.4  serial_hw_put (int _c)
     7.5  {
     7.6    char c = _c;
     7.7 -  console_print(&c, 1);
     7.8 +  console_print(NULL, &c, 1);
     7.9  }
    7.10  
    7.11  int
    7.12 @@ -337,7 +337,7 @@ serial_hw_fetch (void)
    7.13  {
    7.14      char key;
    7.15  
    7.16 -    if (!xencons_ring_avail())
    7.17 +    if (!xencons_ring_avail(NULL))
    7.18          return -1;
    7.19  
    7.20      read(STDIN_FILENO, &key, 1);