ia64/xen-unstable

changeset 17779:5c38568d90df

stubdom: Add console reading support

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 03 09:32:50 2008 +0100 (2008-06-03)
parents fe60bf79d96f
children 420db89188ca
files extras/mini-os/console/console.c extras/mini-os/console/xencons_ring.c extras/mini-os/include/console.h extras/mini-os/lib/sys.c
line diff
     1.1 --- a/extras/mini-os/console/console.c	Mon Jun 02 16:05:07 2008 +0100
     1.2 +++ b/extras/mini-os/console/console.c	Tue Jun 03 09:32:50 2008 +0100
     1.3 @@ -49,17 +49,13 @@
     1.4     of standard dom0 handled console */
     1.5  #define USE_XEN_CONSOLE
     1.6  
     1.7 -/* Low level functions defined in xencons_ring.c */
     1.8 -extern int xencons_ring_init(void);
     1.9 -extern int xencons_ring_send(const char *data, unsigned len);
    1.10 -extern int xencons_ring_send_no_notify(const char *data, unsigned len);
    1.11 -
    1.12  
    1.13  /* If console not initialised the printk will be sent to xen serial line 
    1.14     NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
    1.15  static int console_initialised = 0;
    1.16  
    1.17  
    1.18 +#ifndef HAVE_LIBC
    1.19  void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
    1.20  {
    1.21      if(len > 0)
    1.22 @@ -77,6 +73,7 @@ void xencons_tx(void)
    1.23  {
    1.24      /* Do nothing, handled by _rx */
    1.25  }
    1.26 +#endif
    1.27  
    1.28  
    1.29  void console_print(char *data, int length)
     2.1 --- a/extras/mini-os/console/xencons_ring.c	Mon Jun 02 16:05:07 2008 +0100
     2.2 +++ b/extras/mini-os/console/xencons_ring.c	Tue Jun 03 09:32:50 2008 +0100
     2.3 @@ -8,6 +8,7 @@
     2.4  #include <xenbus.h>
     2.5  #include <xen/io/console.h>
     2.6  
     2.7 +DECLARE_WAIT_QUEUE_HEAD(console_queue);
     2.8  
     2.9  static inline struct xencons_interface *xencons_interface(void)
    2.10  {
    2.11 @@ -52,6 +53,9 @@ int xencons_ring_send(const char *data, 
    2.12  
    2.13  static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
    2.14  {
    2.15 +#ifdef HAVE_LIBC
    2.16 +        wake_up(&console_queue);
    2.17 +#else
    2.18  	struct xencons_interface *intf = xencons_interface();
    2.19  	XENCONS_RING_IDX cons, prod;
    2.20  
    2.21 @@ -71,8 +75,48 @@ static void handle_input(evtchn_port_t p
    2.22  	notify_daemon();
    2.23  
    2.24  	xencons_tx();
    2.25 +#endif
    2.26  }
    2.27  
    2.28 +#ifdef HAVE_LIBC
    2.29 +int xencons_ring_avail(void)
    2.30 +{
    2.31 +	struct xencons_interface *intf = xencons_interface();
    2.32 +	XENCONS_RING_IDX cons, prod;
    2.33 +
    2.34 +	cons = intf->in_cons;
    2.35 +	prod = intf->in_prod;
    2.36 +	mb();
    2.37 +	BUG_ON((prod - cons) > sizeof(intf->in));
    2.38 +
    2.39 +        return prod - cons;
    2.40 +}
    2.41 +
    2.42 +int xencons_ring_recv(char *data, unsigned len)
    2.43 +{
    2.44 +	struct xencons_interface *intf = xencons_interface();
    2.45 +	XENCONS_RING_IDX cons, prod;
    2.46 +        unsigned filled = 0;
    2.47 +
    2.48 +	cons = intf->in_cons;
    2.49 +	prod = intf->in_prod;
    2.50 +	mb();
    2.51 +	BUG_ON((prod - cons) > sizeof(intf->in));
    2.52 +
    2.53 +        while (filled < len && cons + filled != prod) {
    2.54 +                data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in));
    2.55 +                filled++;
    2.56 +	}
    2.57 +
    2.58 +	mb();
    2.59 +        intf->in_cons = cons + filled;
    2.60 +
    2.61 +	notify_daemon();
    2.62 +
    2.63 +        return filled;
    2.64 +}
    2.65 +#endif
    2.66 +
    2.67  int xencons_ring_init(void)
    2.68  {
    2.69  	int err;
     3.1 --- a/extras/mini-os/include/console.h	Mon Jun 02 16:05:07 2008 +0100
     3.2 +++ b/extras/mini-os/include/console.h	Tue Jun 03 09:32:50 2008 +0100
     3.3 @@ -52,4 +52,13 @@ void xencons_tx(void);
     3.4  void init_console(void);
     3.5  void console_print(char *data, int length);
     3.6  
     3.7 +/* Low level functions defined in xencons_ring.c */
     3.8 +extern struct wait_queue_head console_queue;
     3.9 +int xencons_ring_init(void);
    3.10 +int xencons_ring_send(const char *data, unsigned len);
    3.11 +int xencons_ring_send_no_notify(const char *data, unsigned len);
    3.12 +int xencons_ring_avail(void);
    3.13 +int xencons_ring_recv(char *data, unsigned len);
    3.14 +
    3.15 +
    3.16  #endif /* _LIB_CONSOLE_H_ */
     4.1 --- a/extras/mini-os/lib/sys.c	Mon Jun 02 16:05:07 2008 +0100
     4.2 +++ b/extras/mini-os/lib/sys.c	Tue Jun 03 09:32:50 2008 +0100
     4.3 @@ -213,8 +213,19 @@ int isatty(int fd)
     4.4  int read(int fd, void *buf, size_t nbytes)
     4.5  {
     4.6      switch (files[fd].type) {
     4.7 -	case FTYPE_CONSOLE:
     4.8 -	    return 0;
     4.9 +	case FTYPE_CONSOLE: {
    4.10 +	    int ret;
    4.11 +            DEFINE_WAIT(w);
    4.12 +            while(1) {
    4.13 +                add_waiter(w, console_queue);
    4.14 +                ret = xencons_ring_recv(buf, nbytes);
    4.15 +                if (ret)
    4.16 +                    break;
    4.17 +                schedule();
    4.18 +            }
    4.19 +            remove_waiter(w);
    4.20 +            return ret;
    4.21 +        }
    4.22  	case FTYPE_FILE: {
    4.23  	    ssize_t ret;
    4.24  	    if (nbytes > PAGE_SIZE)
    4.25 @@ -707,7 +718,12 @@ static int select_poll(int nfds, fd_set 
    4.26  	    FD_CLR(i, exceptfds);
    4.27  	    break;
    4.28  	case FTYPE_CONSOLE:
    4.29 -	    FD_CLR(i, readfds);
    4.30 +	    if (FD_ISSET(i, writefds)) {
    4.31 +                if (xencons_ring_avail())
    4.32 +		    n++;
    4.33 +		else
    4.34 +		    FD_CLR(i, readfds);
    4.35 +            }
    4.36  	    if (FD_ISSET(i, writefds))
    4.37                  n++;
    4.38  	    FD_CLR(i, exceptfds);
    4.39 @@ -809,6 +825,7 @@ int select(int nfds, fd_set *readfds, fd
    4.40      DEFINE_WAIT(w3);
    4.41      DEFINE_WAIT(w4);
    4.42      DEFINE_WAIT(w5);
    4.43 +    DEFINE_WAIT(w6);
    4.44  
    4.45      assert(thread == main_thread);
    4.46  
    4.47 @@ -830,6 +847,7 @@ int select(int nfds, fd_set *readfds, fd
    4.48      add_waiter(w3, blkfront_queue);
    4.49      add_waiter(w4, xenbus_watch_queue);
    4.50      add_waiter(w5, kbdfront_queue);
    4.51 +    add_waiter(w6, console_queue);
    4.52  
    4.53      if (readfds)
    4.54          myread = *readfds;
    4.55 @@ -916,6 +934,7 @@ out:
    4.56      remove_waiter(w3);
    4.57      remove_waiter(w4);
    4.58      remove_waiter(w5);
    4.59 +    remove_waiter(w6);
    4.60      return ret;
    4.61  }
    4.62