ia64/xen-unstable

changeset 645:3212022b1d8d

bitkeeper revision 1.362 (3f170be1KkQ_xBzWAe6JSR2i5ZRyAg)

config.h, xen_kbd.c:
Cleaned up Xen keyboard/mouse virtualisation and fixed an infinite-loop bug in the interrupt handler.
author kaf24@scramble.cl.cam.ac.uk
date Thu Jul 17 20:49:37 2003 +0000 (2003-07-17)
parents 7fb9fbf0919c
children 6650ca532761
files xen/drivers/char/xen_kbd.c xen/include/xeno/config.h
line diff
     1.1 --- a/xen/drivers/char/xen_kbd.c	Thu Jul 17 16:31:05 2003 +0000
     1.2 +++ b/xen/drivers/char/xen_kbd.c	Thu Jul 17 20:49:37 2003 +0000
     1.3 @@ -1,9 +1,10 @@
     1.4  #include <asm-i386/io.h>
     1.5  #include <asm-i386/irq.h>
     1.6 -#include <xeno/sched.h>    /* this has request_irq() proto for some reason */
     1.7 +#include <xeno/sched.h>
     1.8  #include <xeno/keyhandler.h>  
     1.9  #include <hypervisor-ifs/kbd.h>
    1.10  #include <xeno/event.h>
    1.11 +#include <xeno/console.h>
    1.12  
    1.13  /* Hash-defines torn from <linux/pc_keyb.h> and <asm/keyboard.h> */
    1.14  
    1.15 @@ -25,92 +26,55 @@
    1.16  #define kbd_read_input() inb(KBD_DATA_REG)
    1.17  #define kbd_read_status() inb(KBD_STATUS_REG)
    1.18  
    1.19 -#define KEYBOARD_IRQ 1
    1.20 +#define KEYBOARD_IRQ  1
    1.21 +#define AUX_IRQ      12
    1.22 +
    1.23  #define kbd_write_output(val) outb(val, KBD_DATA_REG)
    1.24  #define kbd_write_command(val) outb(val, KBD_CNTL_REG)
    1.25  
    1.26 -#define AUX_IRQ 12
    1.27 -
    1.28 -#undef KBD_DEBUG
    1.29 -
    1.30 -/* THIS SECTION DEALS WITH CONFIG_XEN_ATTENTION_KEY */
    1.31 -
    1.32 -// always set for now.  potentially moved to a central config later.
    1.33 -// this should really affect common/keyhandler.c too
    1.34 -#define CONFIG_XEN_ATTENTION_KEY
    1.35 -
    1.36  #ifdef CONFIG_XEN_ATTENTION_KEY
    1.37  
    1.38  static int xen_attention_key_down = 0;
    1.39 -#define XEN_ATTENTION_KEY 0x46 // scroll lock
    1.40 +#define XEN_ATTENTION_KEY 0x46 /* Scroll Lock */
    1.41  #define KBD_SCANCODE_KEYUP_MASK 0x80
    1.42  
    1.43 -/* naive scancode -> key mappings for internal xen use */
    1.44 +/* Simple scancode-to-key mappings for internal Xen use. */
    1.45  
    1.46  static unsigned char keymap_normal[] =
    1.47  {
    1.48 -   0 , 0 ,'1','2', '3','4','5','6',    '7','8','9','0', '-','=','\b','\t',
    1.49 -  'q','w','e','r', 't','y','u','i',    'o','p','[',']','\r', 0 ,'a','s',
    1.50 -  'd','f','g','h', 'j','k','l',';',   '\'','`', 0 ,'#', 'z','x','c','v',
    1.51 -  'b','n','m',',', '.','/', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.52 +    0 , 0 ,'1','2', '3','4','5','6',    '7','8','9','0', '-','=','\b','\t',
    1.53 +    'q','w','e','r', 't','y','u','i',    'o','p','[',']','\r', 0 ,'a','s',
    1.54 +    'd','f','g','h', 'j','k','l',';',   '\'','`', 0 ,'#', 'z','x','c','v',
    1.55 +    'b','n','m',',', '.','/', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.56  
    1.57 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.58 -   0 , 0 , 0 , 0 ,  0 , 0 ,'\\', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.59 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.60 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
    1.61 +    0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.62 +    0 , 0 , 0 , 0 ,  0 , 0 ,'\\', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.63 +    0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.64 +    0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
    1.65  };
    1.66  
    1.67  static unsigned char keymap_shift[] =
    1.68  {
    1.69 -   0 , 0 ,'!','"', '#','$','%','^',    '&','*','(',')', '_','+','\b','\t',
    1.70 -  'Q','W','E','R', 'T','Y','U','I',    'O','P','{','}','\r', 0 ,'A','S',
    1.71 -  'D','F','G','H', 'J','K','L',':',    '@', 0 , 0 ,'~', 'Z','X','C','V',
    1.72 -  'B','N','M','<', '>','?', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.73 -
    1.74 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.75 -   0 , 0 , 0 , 0 ,  0 , 0 ,'|', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.76 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.77 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
    1.78 -};
    1.79 +    0 , 0 ,'!','"', '#','$','%','^',    '&','*','(',')', '_','+','\b','\t',
    1.80 +    'Q','W','E','R', 'T','Y','U','I',    'O','P','{','}','\r', 0 ,'A','S',
    1.81 +    'D','F','G','H', 'J','K','L',':',    '@', 0 , 0 ,'~', 'Z','X','C','V',
    1.82 +    'B','N','M','<', '>','?', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.83  
    1.84 -
    1.85 -static unsigned char keymap_control[] =
    1.86 -{ /* same as normal, except for a-z -> 1 to 26 */
    1.87 -   0 , 0 ,'1','2', '3','4','5','6',    '7','8','9','0', '-','=','\b','\t',
    1.88 -   17, 23, 5 , 18,  20, 25, 21, 9 ,     15, 16,'[',']','\r', 0 , 1 , 19,
    1.89 -   4 , 6 , 7 , 8 ,  10, 11, 12,';',   '\'','`', 0 ,'#', 26, 24, 3 , 22,
    1.90 -   2 , 14, 13,',', '.','/', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.91 -
    1.92 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.93 -   0 , 0 , 0 , 0 ,  0 , 0 ,'\\', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.94 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.95 -   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
    1.96 +    0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.97 +    0 , 0 , 0 , 0 ,  0 , 0 ,'|', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.98 +    0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    1.99 +    0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
   1.100  };
   1.101  
   1.102  
   1.103  static int keyboard_shift = 0;
   1.104 -static int keyboard_control = 0;
   1.105 -static int keyboard_echo = 0;
   1.106  
   1.107  static unsigned char convert_scancode (unsigned char scancode)
   1.108  {
   1.109      unsigned char value = 0;
   1.110  
   1.111 -    switch (scancode) {
   1.112 -
   1.113 -    case 0xbb: /* F1 */
   1.114 -	keyboard_echo = !keyboard_echo;
   1.115 -	break;
   1.116 -
   1.117 -    case 0xba: /* caps lock UP */
   1.118 -    case 0x9d: /* ctrl (left) UP */
   1.119 -	keyboard_control = 0;
   1.120 -	break;
   1.121 -
   1.122 -    case 0x3a: /* caps lock DOWN */
   1.123 -    case 0x1d: /* ctrl (left) DOWN */
   1.124 -	keyboard_control = 1;
   1.125 -	break;
   1.126 +    switch ( scancode ) 
   1.127 +    {
   1.128  
   1.129      case 0xaa: /* shift (left) UP */
   1.130      case 0xb6: /* shift (right) UP */
   1.131 @@ -122,151 +86,141 @@ static unsigned char convert_scancode (u
   1.132  	keyboard_shift = 1;
   1.133  	break;
   1.134  
   1.135 -    default:   /* normal keys */
   1.136 -        // dont process key-down events
   1.137 -        if(!(scancode & KBD_SCANCODE_KEYUP_MASK)) break; 
   1.138 -
   1.139 -	scancode = scancode & (~KBD_SCANCODE_KEYUP_MASK); 
   1.140 -	if (keyboard_control)
   1.141 -	    value = keymap_control[scancode];
   1.142 -	else if (keyboard_shift)
   1.143 +    default:
   1.144 +        /* Only process key-up events */
   1.145 +        if(!(scancode & KBD_SCANCODE_KEYUP_MASK)) 
   1.146 +            break; 
   1.147 +	scancode = scancode & ~KBD_SCANCODE_KEYUP_MASK; 
   1.148 +	if (keyboard_shift)
   1.149  	    value = keymap_shift[scancode];
   1.150  	else
   1.151  	    value = keymap_normal[scancode];
   1.152 -
   1.153 +        break;
   1.154      }
   1.155  
   1.156 -    if (value && keyboard_echo) printk ("%c", value);
   1.157 -
   1.158      return value;
   1.159  }
   1.160  
   1.161  #endif /* CONFIG_XEN_ATTENTION_KEY */
   1.162  
   1.163  
   1.164 -/* THIS SECTION DEALS WITH STORING A RING OF PENDING KBD EVENTS */
   1.165 -
   1.166 -// store kbd events waiting to be processed by guest os
   1.167 -#define KBD_RING_SIZE        64 
   1.168 +/* We store kbd events awaiting receive by a guest OS in a ring buffer. */
   1.169 +#define KBD_RING_SIZE 64 
   1.170  static int kbd_ring[KBD_RING_SIZE]; 
   1.171  static int kbd_ring_prod = 0;
   1.172  static int kbd_ring_cons = 0;
   1.173  
   1.174 -#define KBD_RING_INC(_i)     (((_i)+1) & (KBD_RING_SIZE-1))
   1.175 -#define KBD_RING_FULL (KBD_RING_INC(kbd_ring_prod)  == kbd_ring_cons)
   1.176 -#define KBD_RING_EMPTY (kbd_ring_prod == kbd_ring_cons)
   1.177 +#define KBD_RING_INC(_i) (((_i)+1) & (KBD_RING_SIZE-1))
   1.178 +#define KBD_RING_FULL    (KBD_RING_INC(kbd_ring_prod) == kbd_ring_cons)
   1.179 +#define KBD_RING_EMPTY   (kbd_ring_prod == kbd_ring_cons)
   1.180  
   1.181 -// these assume locking has already been taken care of
   1.182 -static void kbd_ring_push(unsigned char status, unsigned char scancode) {
   1.183 -  if(KBD_RING_FULL) return;
   1.184 -  kbd_ring[kbd_ring_prod] = KBD_CODE(scancode, status);
   1.185 -  kbd_ring_prod = KBD_RING_INC(kbd_ring_prod);
   1.186 +static void kbd_ring_push(unsigned char status, unsigned char scancode)
   1.187 +{
   1.188 +    if ( KBD_RING_FULL )
   1.189 +        return;
   1.190 +    
   1.191 +    kbd_ring[kbd_ring_prod] = KBD_CODE(scancode, status);
   1.192 +    kbd_ring_prod = KBD_RING_INC(kbd_ring_prod);
   1.193  }
   1.194  
   1.195 -static int kbd_ring_pop() {
   1.196 -  int ret;
   1.197 -  if(KBD_RING_EMPTY) {
   1.198 -    // read directly from controller - no events waiting in ring
   1.199 -    unsigned char status = kbd_read_status();
   1.200 -    unsigned char scancode = kbd_read_input(); 
   1.201 -    return KBD_CODE(scancode, status);
   1.202 -  }
   1.203 -  ret = kbd_ring[kbd_ring_cons];
   1.204 -  kbd_ring_cons = KBD_RING_INC(kbd_ring_cons);
   1.205 -  return ret;
   1.206 +static int kbd_ring_pop(void)
   1.207 +{
   1.208 +    int ret;
   1.209 +
   1.210 +    if ( KBD_RING_EMPTY )
   1.211 +    {
   1.212 +        /* Read directly from controller - no events waiting in ring. */
   1.213 +        unsigned char status = kbd_read_status();
   1.214 +        unsigned char scancode = kbd_read_input(); 
   1.215 +        ret = KBD_CODE(scancode, status);
   1.216 +    }
   1.217 +    else
   1.218 +    {
   1.219 +        ret = kbd_ring[kbd_ring_cons];
   1.220 +        kbd_ring_cons = KBD_RING_INC(kbd_ring_cons);
   1.221 +    }
   1.222 +
   1.223 +    return ret;
   1.224  }
   1.225  
   1.226  
   1.227 -/* THIS SECTION DEALS WITH COMMUNICATING PS2 EVENTS/CMDS WITH GUEST OS */
   1.228 -
   1.229 -#include <xeno/console.h>
   1.230 -
   1.231 -// need lock as there may be _two_ interrupts at play, keyboard and mouse, as well as guest os actions
   1.232 +/*
   1.233 + * NB. Lock is essential as there are two distinct interrupts (keyboard + aux).
   1.234 + * Also interrupts may disturb guest OS actions.
   1.235 + */
   1.236  static spinlock_t kbd_lock;
   1.237  
   1.238 -
   1.239  long do_kbd_op(unsigned char op, unsigned char val)
   1.240  {
   1.241 -  // check for domain 0
   1.242 -#ifdef KBD_DEBUG
   1.243 -  printk("do_kbd_op: op %2x, val %2x, prod %d, cons %d\n", op, val, kbd_ring_prod, kbd_ring_cons); 
   1.244 -#endif
   1.245 -
   1.246 -  if ( !CONSOLE_ISOWNER(current) ) return -EPERM;  
   1.247 +    unsigned long flags;
   1.248 +    long ret = -EINVAL;
   1.249  
   1.250 -  switch(op) {
   1.251 -  case KBD_OP_WRITEOUTPUT:
   1.252 -    kbd_write_output(val);
   1.253 -    return 0L;
   1.254 -  case KBD_OP_WRITECOMMAND:
   1.255 -    kbd_write_command(val);
   1.256 -    return 0L;
   1.257 -  case KBD_OP_READ: {
   1.258 -    unsigned long flags;
   1.259 -    unsigned long ret;
   1.260 +    if ( !CONSOLE_ISOWNER(current) ) 
   1.261 +        return -EPERM;  
   1.262 +
   1.263      spin_lock_irqsave(&kbd_lock, flags);
   1.264 -    ret = kbd_ring_pop();
   1.265 +
   1.266 +    switch ( op )
   1.267 +    {
   1.268 +    case KBD_OP_WRITEOUTPUT:
   1.269 +        kbd_write_output(val);
   1.270 +        ret = 0L;
   1.271 +        break;
   1.272 +    case KBD_OP_WRITECOMMAND:
   1.273 +        kbd_write_command(val);
   1.274 +        ret = 0L;
   1.275 +        break;
   1.276 +    case KBD_OP_READ:
   1.277 +        ret = kbd_ring_pop();
   1.278 +        break;
   1.279 +    }
   1.280 +
   1.281      spin_unlock_irqrestore(&kbd_lock, flags);
   1.282 +
   1.283      return ret;
   1.284 -  }
   1.285 -  }
   1.286 -
   1.287 -  return -EINVAL;
   1.288  }
   1.289  
   1.290  
   1.291  static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   1.292  {
   1.293 -  unsigned char status;
   1.294 -  unsigned int work = 1000;
   1.295 -  unsigned long cpu_mask;
   1.296 -  unsigned long flags;
   1.297 -  spin_lock_irqsave(&kbd_lock, flags);
   1.298 -  status = kbd_read_status();
   1.299 +    unsigned char status, scancode;
   1.300 +    unsigned int work = 1000;
   1.301 +    unsigned long cpu_mask, flags;
   1.302  
   1.303 -#ifdef KBD_DEBUG
   1.304 -    printk("keyboard_interrupt irq %d, status 0x%2x\n", irq, status);
   1.305 -#endif
   1.306 -    while ((--work > 0) && (status & KBD_STAT_OBF))
   1.307 +    spin_lock_irqsave(&kbd_lock, flags);
   1.308 +
   1.309 +    while ( (--work > 0) && ((status = kbd_read_status()) & KBD_STAT_OBF) )
   1.310      {      
   1.311 -      unsigned char scancode;
   1.312 -      scancode = kbd_read_input();
   1.313 -      //printk("scancode 0x%2x\n", scancode);
   1.314 +        scancode = kbd_read_input();
   1.315        
   1.316  #ifdef CONFIG_XEN_ATTENTION_KEY
   1.317 -      if(!(status & (KBD_STAT_GTO | KBD_STAT_PERR | KBD_STAT_MOUSE_OBF))) {
   1.318 -	if ((scancode & (~KBD_SCANCODE_KEYUP_MASK)) == XEN_ATTENTION_KEY) {
   1.319 -	  xen_attention_key_down = !(scancode & KBD_SCANCODE_KEYUP_MASK);
   1.320 -	  //printk("xen_attention_key_down %d\n", xen_attention_key_down);
   1.321 -	} else if (xen_attention_key_down) {
   1.322 -	  key_handler *handler; 
   1.323 -	  unsigned char key;
   1.324 -
   1.325 -	  spin_unlock_irqrestore(&kbd_lock, flags);
   1.326 -	  key = convert_scancode(scancode); 
   1.327 -	  if(key && (handler = get_key_handler(key))) 
   1.328 -	    (*handler)(key, dev_id, regs); 
   1.329 -	  
   1.330 -	  spin_lock_irqsave(&kbd_lock, flags);
   1.331 -	  status = kbd_read_status();
   1.332 -	  continue; // do not send key to guest os
   1.333 -	}
   1.334 -      }
   1.335 +        if ( !(status & (KBD_STAT_GTO | KBD_STAT_PERR | KBD_STAT_MOUSE_OBF)) )
   1.336 +        {
   1.337 +            if ( (scancode & (~KBD_SCANCODE_KEYUP_MASK)) == XEN_ATTENTION_KEY )
   1.338 +            {
   1.339 +                xen_attention_key_down = !(scancode & KBD_SCANCODE_KEYUP_MASK);
   1.340 +            } 
   1.341 +            else if ( xen_attention_key_down )
   1.342 +            {
   1.343 +                key_handler *handler; 
   1.344 +                unsigned char key;
   1.345 +                spin_unlock_irqrestore(&kbd_lock, flags);
   1.346 +                key = convert_scancode(scancode); 
   1.347 +                if ( key && (handler = get_key_handler(key)) )
   1.348 +                    (*handler)(key, dev_id, regs); 
   1.349 +                spin_lock_irqsave(&kbd_lock, flags);
   1.350 +                continue;
   1.351 +            }
   1.352 +        }
   1.353  #endif
   1.354        
   1.355 -      if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
   1.356 -	kbd_ring_push(status, scancode);
   1.357 -
   1.358 -	cpu_mask = mark_guest_event(CONSOLE_OWNER, _EVENT_KBD);
   1.359 +        kbd_ring_push(status, scancode);
   1.360 +        cpu_mask = mark_guest_event(CONSOLE_OWNER, _EVENT_KBD);
   1.361          guest_event_notify(cpu_mask);
   1.362 -
   1.363 -	status = kbd_read_status();
   1.364 -	//scancode = kbd_read_input();
   1.365 -      }
   1.366      }
   1.367      
   1.368 -    if (!work)
   1.369 -      printk(KERN_ERR "xen_keyb: controller jammed (0x%02X).\n", status);
   1.370 +    if ( !work )
   1.371 +        printk(KERN_ERR "xen_keyb: controller jammed (0x%02X).\n", status);
   1.372  
   1.373      spin_unlock_irqrestore(&kbd_lock, flags);
   1.374  }
   1.375 @@ -275,20 +229,20 @@ static void keyboard_interrupt(int irq, 
   1.376  
   1.377  void initialize_keyboard()
   1.378  {
   1.379 -  spin_lock_init(&kbd_lock);
   1.380 -
   1.381 -  if(request_irq(KEYBOARD_IRQ, keyboard_interrupt, SA_NOPROFILE, "keyboard", NULL)) {
   1.382 -    printk("initialize_keyboard: failed to alloc IRQ %d\n", KEYBOARD_IRQ); 
   1.383 -    return;
   1.384 -  }
   1.385 +    spin_lock_init(&kbd_lock);
   1.386  
   1.387 -  if(request_irq(AUX_IRQ, keyboard_interrupt, SA_NOPROFILE, "PS/2 Mouse", NULL)) {
   1.388 -    printk("initialize_keyboard: failed to alloc IRQ %d\n", AUX_IRQ); 
   1.389 -    return;
   1.390 -  }
   1.391 +    if( request_irq(KEYBOARD_IRQ, keyboard_interrupt, 
   1.392 +                    SA_NOPROFILE, "keyboard", NULL)) 
   1.393 +    {
   1.394 +        printk("initialize_keyboard: failed to alloc IRQ %d\n", KEYBOARD_IRQ); 
   1.395 +        return;
   1.396 +    }
   1.397  
   1.398 -#ifdef KBD_DEBUG
   1.399 -  printk("PS/2 keyboard and mouse interface ok");
   1.400 -#endif
   1.401 +    if ( request_irq(AUX_IRQ, keyboard_interrupt, 
   1.402 +                     SA_NOPROFILE, "PS/2 Mouse", NULL)) 
   1.403 +    {
   1.404 +        printk("initialize_keyboard: failed to alloc IRQ %d\n", AUX_IRQ); 
   1.405 +        return;
   1.406 +    }
   1.407  }
   1.408  
     2.1 --- a/xen/include/xeno/config.h	Thu Jul 17 16:31:05 2003 +0000
     2.2 +++ b/xen/include/xeno/config.h	Thu Jul 17 20:49:37 2003 +0000
     2.3 @@ -38,6 +38,8 @@
     2.4  #define CONFIG_SD_EXTRA_DEVS 40
     2.5  #define CONFIG_SCSI_MULTI_LUN 1
     2.6  
     2.7 +#define CONFIG_XEN_ATTENTION_KEY 1
     2.8 +
     2.9  #define HZ 100
    2.10  
    2.11  /*