ia64/xen-unstable

changeset 155:ba73696088e6

bitkeeper revision 1.22.5.1 (3e4cd9d8YCTcjulpz_EEkfSag8qJRg)

IDE code works in basic fashion; still ugly but functional.
Also better keyhandler debug support. Huzzah.
author smh22@boulderdash.cl.cam.ac.uk
date Fri Feb 14 11:58:16 2003 +0000 (2003-02-14)
parents 0834a70d2e19
children 01e412fb646d
files .rootkeys BitKeeper/etc/ignore xen-2.4.16/arch/i386/setup.c xen-2.4.16/common/keyhandler.c xen-2.4.16/drivers/block/ll_rw_blk.c xen-2.4.16/drivers/block/xen_block.c xen-2.4.16/drivers/char/xen_kbd.c xen-2.4.16/drivers/char/xen_serial.c xen-2.4.16/drivers/ide/ide-xeno.c xen-2.4.16/include/hypervisor-ifs/block.h xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h xen-2.4.16/include/xeno/keyhandler.h xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c xenolinux-2.4.16-sparse/include/linux/blk.h xenolinux-2.4.16-sparse/init/main.c
line diff
     1.1 --- a/.rootkeys	Thu Feb 13 14:51:10 2003 +0000
     1.2 +++ b/.rootkeys	Fri Feb 14 11:58:16 2003 +0000
     1.3 @@ -42,6 +42,7 @@ 3ddb79bdYO5D8Av12NHqPeSviav7cg xen-2.4.1
     1.4  3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen-2.4.16/common/domain_page.c
     1.5  3ddb79bdeyutmaXEfpQvvxj7eQ0fCw xen-2.4.16/common/event.c
     1.6  3ddb79bd9drcFPVxd4w2GPOIjLlXpA xen-2.4.16/common/kernel.c
     1.7 +3e4cd9d8LAAghUY0hNIK72uc2ch_Nw xen-2.4.16/common/keyhandler.c
     1.8  3ddb79bduhSEZI8xa7IbGQCpap5y2A xen-2.4.16/common/lib.c
     1.9  3ddb79bdS39UXxUtZnaScie83-7VTQ xen-2.4.16/common/memory.c
    1.10  3ddb79bdN51qpRC-6bOH-v5hl_AK6A xen-2.4.16/common/network.c
    1.11 @@ -231,6 +232,7 @@ 3ddb79c2qAxCOABlkKtD8Txohe-qEw xen-2.4.1
    1.12  3ddb79c2b3qe-6Ann09FqZBF4IrJaQ xen-2.4.16/include/xeno/irq_cpustat.h
    1.13  3ddb79c11w_O7z7YZJnzuDSxaK5LlA xen-2.4.16/include/xeno/kdev_t.h
    1.14  3e4540ccPHqIIv2pvnQ1gV8LUnoHIg xen-2.4.16/include/xeno/kernel.h
    1.15 +3e4cd9d8elj_7EgAs9Of56RQ2Yq_4g xen-2.4.16/include/xeno/keyhandler.h
    1.16  3ddb79c1NfYlOrWNqgZkj9EwtFfJow xen-2.4.16/include/xeno/lib.h
    1.17  3ddb79c18Ajy7micDGQQfJ0zWgEHtA xen-2.4.16/include/xeno/list.h
    1.18  3ddb79c0_s2_wgV0cA6tztEaeyy1NA xen-2.4.16/include/xeno/major.h
     2.1 --- a/BitKeeper/etc/ignore	Thu Feb 13 14:51:10 2003 +0000
     2.2 +++ b/BitKeeper/etc/ignore	Fri Feb 14 11:58:16 2003 +0000
     2.3 @@ -19,3 +19,4 @@ xen-2.4.16/include/xeno/sched.h.orig
     2.4  xenolinux-2.4.16-sparse/arch/xeno/drivers/block/Makefile.orig
     2.5  xenolinux-2.4.16-sparse/arch/xeno/drivers/block/block.c.orig
     2.6  xenolinux-2.4.16-sparse/scripts/kconfig.tk
     2.7 +xen-2.4.16/foo
     3.1 --- a/xen-2.4.16/arch/i386/setup.c	Thu Feb 13 14:51:10 2003 +0000
     3.2 +++ b/xen-2.4.16/arch/i386/setup.c	Fri Feb 14 11:58:16 2003 +0000
     3.3 @@ -283,6 +283,7 @@ void __init start_of_day(void)
     3.4      extern int  setup_network_devices(void);
     3.5      extern void net_init(void);
     3.6      extern void initialize_block_io(void);
     3.7 +    extern void initialize_keytable(); 
     3.8      extern void initialize_serial(void);
     3.9      extern void initialize_keyboard(void);
    3.10  
    3.11 @@ -337,8 +338,9 @@ void __init start_of_day(void)
    3.12  #endif
    3.13      do_initcalls();
    3.14  
    3.15 +    initialize_keytable(); /* call back handling for key codes      */
    3.16      initialize_serial();   /* setup serial 'driver' (for debugging) */
    3.17 -    initialize_keyboard(); /* setup keyboard (also for debugging) */
    3.18 +    initialize_keyboard(); /* setup keyboard (also for debugging)   */
    3.19  
    3.20      if ( !setup_network_devices() )
    3.21          panic("Must have a network device!\n");
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen-2.4.16/common/keyhandler.c	Fri Feb 14 11:58:16 2003 +0000
     4.3 @@ -0,0 +1,125 @@
     4.4 +#include <xeno/keyhandler.h> 
     4.5 +#include <xeno/reboot.h>
     4.6 +
     4.7 +#define KEY_MAX 256
     4.8 +#define STR_MAX  64
     4.9 +
    4.10 +typedef struct _key_te { 
    4.11 +    key_handler *handler; 
    4.12 +    char         desc[STR_MAX]; 
    4.13 +} key_te_t; 
    4.14 +
    4.15 +static key_te_t key_table[KEY_MAX]; 
    4.16 +    
    4.17 +void add_key_handler(u_char key, key_handler *handler, char *desc) 
    4.18 +{
    4.19 +    int i; 
    4.20 +    char *str; 
    4.21 +
    4.22 +    if(key_table[key].handler != NULL) 
    4.23 +	printk("Warning: overwriting handler for key 0x%x\n", key); 
    4.24 +
    4.25 +    key_table[key].handler = handler; 
    4.26 +
    4.27 +    str = key_table[key].desc; 
    4.28 +    for(i = 0; i < STR_MAX; i++) {
    4.29 +	if(*desc) 
    4.30 +	    *str++ = *desc++; 
    4.31 +	else break; 
    4.32 +    }
    4.33 +    if (i == STR_MAX) 
    4.34 +	key_table[key].desc[STR_MAX-1] = '\0'; 
    4.35 +
    4.36 +    return; 
    4.37 +}
    4.38 +
    4.39 +key_handler *get_key_handler(u_char key)
    4.40 +{
    4.41 +    return key_table[key].handler; 
    4.42 +}
    4.43 +
    4.44 +
    4.45 +void show_handlers(u_char key, void *dev_id, struct pt_regs *regs) 
    4.46 +{
    4.47 +    int i; 
    4.48 +
    4.49 +    printk("'%c' pressed -> showing installed handlers\n", key); 
    4.50 +    for(i=0; i < KEY_MAX; i++) 
    4.51 +	if(key_table[i].handler) 
    4.52 +	    printk("ASCII '%02x' => %s\n", i, key_table[i].desc);
    4.53 +    return; 
    4.54 +}
    4.55 +
    4.56 +
    4.57 +void dump_registers(u_char key, void *dev_id, struct pt_regs *regs) 
    4.58 +{
    4.59 +    extern void show_registers(struct pt_regs *regs); 
    4.60 +
    4.61 +    printk("'%c' pressed -> dumping registers\n", key); 
    4.62 +    show_registers(regs); 
    4.63 +    return; 
    4.64 +}
    4.65 +
    4.66 +void halt_machine(u_char key, void *dev_id, struct pt_regs *regs) 
    4.67 +{
    4.68 +    printk("'%c' pressed -> rebooting machine\n", key); 
    4.69 +    machine_restart(NULL); 
    4.70 +    return; 
    4.71 +}
    4.72 +
    4.73 +
    4.74 +
    4.75 +/* XXX SMH: this is keir's fault */
    4.76 +static char *task_states[] = 
    4.77 +{ 
    4.78 +    "Running", 
    4.79 +    "Interruptible Sleep", 
    4.80 +    "Uninterruptible Sleep", 
    4.81 +    NULL, "Stopped", 
    4.82 +    NULL, NULL, NULL, "Dying", 
    4.83 +}; 
    4.84 +
    4.85 +void do_task_queues(u_char key, void *dev_id, struct pt_regs *regs) 
    4.86 +{
    4.87 +    u_long flags; 
    4.88 +    struct task_struct *p; 
    4.89 +    shared_info_t *s; 
    4.90 +
    4.91 +    printk("'%c' pressed -> dumping task queues\n", key); 
    4.92 +    read_lock_irqsave(&tasklist_lock, flags); 
    4.93 +    p = &idle0_task;
    4.94 +    do {
    4.95 +        printk("Xen: DOM %d, CPU %d [has=%c], state = %s, "
    4.96 +	       "hyp_events = %08x\n", 
    4.97 +	       p->domain, p->processor, p->has_cpu ? 'T':'F', 
    4.98 +	       task_states[p->state], p->hyp_events); 
    4.99 +	s = p->shared_info; 
   4.100 +	if(!is_idle_task(p)) {
   4.101 +	    printk("Guest: events = %08lx, event_enable = %08lx\n", 
   4.102 +		   s->events, s->events_enable); 
   4.103 +	    printk("Notifying guest...\n"); 
   4.104 +	    set_bit(_EVENT_DEBUG, &s->events); 
   4.105 +	}
   4.106 +    }
   4.107 +
   4.108 +    while ( (p = p->next_task) != &idle0_task );
   4.109 +    read_unlock_irqrestore(&tasklist_lock, flags); 
   4.110 +}
   4.111 +
   4.112 +
   4.113 +void initialize_keytable() 
   4.114 +{
   4.115 +    int i; 
   4.116 +
   4.117 +    /* first initialize key handler table */
   4.118 +    for(i = 0; i < KEY_MAX; i++) 
   4.119 +	key_table[i].handler = (key_handler *)NULL; 
   4.120 +	
   4.121 +    /* setup own handlers */
   4.122 +    add_key_handler('d', dump_registers, "dump registers"); 
   4.123 +    add_key_handler('h', show_handlers, "show this message");
   4.124 +    add_key_handler('q', do_task_queues, "dump task queues + guest state");
   4.125 +    add_key_handler('r', halt_machine, "reboot machine ungracefully"); 
   4.126 +    
   4.127 +    return; 
   4.128 +}
     5.1 --- a/xen-2.4.16/drivers/block/ll_rw_blk.c	Thu Feb 13 14:51:10 2003 +0000
     5.2 +++ b/xen-2.4.16/drivers/block/ll_rw_blk.c	Fri Feb 14 11:58:16 2003 +0000
     5.3 @@ -31,6 +31,9 @@
     5.4  #include <xeno/slab.h>
     5.5  #include <xeno/module.h>
     5.6  
     5.7 +/* XXX SMH: temporarily we just dive at xen_block completion handler */
     5.8 +extern void end_block_io_op(struct buffer_head *bh); 
     5.9 +
    5.10  static void end_buffer_dummy(struct buffer_head *bh, int uptodate)
    5.11  {
    5.12    /* do nothing */
    5.13 @@ -1030,6 +1033,8 @@ out:
    5.14  	return 0;
    5.15  end_io:
    5.16  	bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
    5.17 +	/* XXX SMH: do we need this every time? */
    5.18 +	end_block_io_op(bh);
    5.19  	return 0;
    5.20  }
    5.21  
    5.22 @@ -1101,6 +1106,8 @@ void generic_make_request (int rw, struc
    5.23  
    5.24  			/* Yecch again */
    5.25  			bh->b_end_io(bh, 0);
    5.26 +			/* XXX SMH */ 
    5.27 +			end_block_io_op(bh);
    5.28  			return;
    5.29  		}
    5.30  	}
    5.31 @@ -1142,10 +1149,6 @@ void generic_make_request (int rw, struc
    5.32   */
    5.33  void submit_bh(int rw, struct buffer_head * bh)
    5.34  {
    5.35 -	int count = bh->b_size >> 9;
    5.36 -
    5.37 -	/* 	printk(KERN_ALERT "submit_bh\n"); */
    5.38 -
    5.39  	if (!test_bit(BH_Lock, &bh->b_state))
    5.40  		BUG();
    5.41  
    5.42 @@ -1160,17 +1163,6 @@ void submit_bh(int rw, struct buffer_hea
    5.43  	/*	bh->b_rsector = bh->b_blocknr * count; */
    5.44  
    5.45  	generic_make_request(rw, bh);
    5.46 -
    5.47 -#if 0
    5.48 -	switch (rw) {
    5.49 -		case WRITE:
    5.50 -			kstat.pgpgout += count;
    5.51 -			break;
    5.52 -		default:
    5.53 -			kstat.pgpgin += count;
    5.54 -			break;
    5.55 -	}
    5.56 -#endif
    5.57  }
    5.58  
    5.59  /**
    5.60 @@ -1267,6 +1259,8 @@ void ll_rw_block(int rw, int nr, struct 
    5.61  			BUG();
    5.62  	end_io:
    5.63  			bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
    5.64 +			/* XXX SMH */
    5.65 +			end_block_io_op(bh);
    5.66  			continue;
    5.67  		}
    5.68  
    5.69 @@ -1275,6 +1269,7 @@ void ll_rw_block(int rw, int nr, struct 
    5.70  	return;
    5.71  
    5.72  sorry:
    5.73 +	printk("~~~");
    5.74  	/* Make sure we don't get infinite dirty retries.. */
    5.75  	for (i = 0; i < nr; i++)
    5.76  		mark_buffer_clean(bhs[i]);
     6.1 --- a/xen-2.4.16/drivers/block/xen_block.c	Thu Feb 13 14:51:10 2003 +0000
     6.2 +++ b/xen-2.4.16/drivers/block/xen_block.c	Fri Feb 14 11:58:16 2003 +0000
     6.3 @@ -15,6 +15,8 @@
     6.4  #include <asm-i386/io.h>
     6.5  #include <asm/spinlock.h>
     6.6  
     6.7 +#include <xeno/keyhandler.h>
     6.8 +
     6.9  #define XEN_BLK_DEBUG 0
    6.10  #define XEN_BLK_DEBUG_LEVEL KERN_ALERT
    6.11  
    6.12 @@ -28,10 +30,12 @@ typedef struct blk_request
    6.13    struct task_struct *domain;                           /* requesting domain */
    6.14  } blk_request_t;
    6.15  
    6.16 -static int pending_work;                  /* which domains have work for us? */
    6.17 +static int pending_work;              /* which domains have work for us? */
    6.18 +
    6.19  blk_request_t blk_request_list[XEN_BLK_REQUEST_LIST_SIZE];
    6.20 -struct list_head free_queue;                              /* unused requests */
    6.21 -struct list_head pending_queue;                      /* waiting for hardware */
    6.22 +
    6.23 +struct list_head free_queue;          /* unused requests */
    6.24 +struct list_head pending_queue;       /* waiting for hardware */
    6.25  struct list_head io_done_queue;       /* request completed. send to guest os */
    6.26  spinlock_t free_queue_lock;
    6.27  spinlock_t pending_queue_lock;
    6.28 @@ -49,61 +53,46 @@ int dispatch_debug_block_io (int index);
    6.29   * end_block_io_op
    6.30   *
    6.31   * IO has completed.  Need to notify the guest operating system.
    6.32 - * Called from hardware interrupt.
    6.33 + * Called from ll_rw_block -- currently /DIRECTLY/ -- XXX FIXME 
    6.34 + * (e.g. hook into proper end processing of ll_rw) 
    6.35   */
    6.36  
    6.37  void end_block_io_op(struct buffer_head * bh)
    6.38  {
    6.39 -  unsigned long cpu_mask;
    6.40 -  /* struct list_head *list;*/
    6.41 -  blk_request_t *blk_request = NULL;
    6.42 -  unsigned long flags;                                           /* irq save */
    6.43 -
    6.44 -#if 0
    6.45 -  printk("{E}"); 
    6.46 -#endif
    6.47 -  if (XEN_BLK_DEBUG)  printk(XEN_BLK_DEBUG_LEVEL
    6.48 -			     "XEN end_block_io_op,  bh: %lx\n",
    6.49 -			     (unsigned long)bh);
    6.50 -
    6.51 -  {
    6.52 -    char temp[100];
    6.53 -    sprintf(temp, "endio  bh: 0x%p, blkno: 0x%lx",
    6.54 -	    bh, bh->b_blocknr);
    6.55 -    printx(temp);
    6.56 -  }
    6.57 -
    6.58 -  spin_lock_irqsave(&pending_queue_lock, flags);
    6.59 -  /*
    6.60 -  list_for_each (list, &pending_queue)
    6.61 -  {
    6.62 -    blk_request = list_entry(list, blk_request_t, queue);
    6.63 -    if (blk_request->bh == bh)      
    6.64 -    {
    6.65 -      break;
    6.66 +    unsigned long cpu_mask;
    6.67 +    /* struct list_head *list;*/
    6.68 +    blk_request_t *blk_request = NULL;
    6.69 +    unsigned long flags; /* irq save */
    6.70 +    
    6.71 +    if (XEN_BLK_DEBUG)  
    6.72 +	printk(XEN_BLK_DEBUG_LEVEL "XEN end_block_io_op,  bh: %lx\n",
    6.73 +	       (unsigned long)bh);
    6.74 +    
    6.75 +    spin_lock_irqsave(&pending_queue_lock, flags);
    6.76 +    blk_request = (blk_request_t *)bh->b_xen_request;
    6.77 +    
    6.78 +    if (blk_request == NULL) {
    6.79 +	printk (KERN_ALERT
    6.80 +		"   block io interrupt received for unknown buffer [0x%lx]\n",
    6.81 +		(unsigned long) bh);
    6.82 +	spin_unlock_irqrestore(&pending_queue_lock, flags);
    6.83 +	BUG();
    6.84 +	return;
    6.85      }
    6.86 -  }
    6.87 -  */
    6.88 -  blk_request = (blk_request_t *)bh->b_xen_request;
    6.89 -  if (blk_request == NULL)
    6.90 -  {
    6.91 -    printk (KERN_ALERT
    6.92 -	    "   block io interrupt received for unknown buffer [0x%lx]\n",
    6.93 -	    (unsigned long) bh);
    6.94 +    
    6.95 +    list_del(&blk_request->queue);
    6.96      spin_unlock_irqrestore(&pending_queue_lock, flags);
    6.97 +    
    6.98 +    spin_lock_irqsave(&io_done_queue_lock, flags);
    6.99 +    list_add_tail(&blk_request->queue, &io_done_queue);
   6.100 +    
   6.101 +    /* enqueue work for 'flush_blk_queue' handler */
   6.102 +    cpu_mask = mark_hyp_event(blk_request->domain, _HYP_EVENT_BLK_RX);
   6.103 +    spin_unlock_irqrestore(&io_done_queue_lock, flags);
   6.104 +    
   6.105 +    /* now kick the hypervisor */
   6.106 +    hyp_event_notify(cpu_mask); 
   6.107      return;
   6.108 -  }
   6.109 -  list_del(&blk_request->queue);
   6.110 -  spin_unlock_irqrestore(&pending_queue_lock, flags);
   6.111 -
   6.112 -  spin_lock_irqsave(&io_done_queue_lock, flags);
   6.113 -  list_add_tail(&blk_request->queue, &io_done_queue);
   6.114 -  spin_unlock_irqrestore(&io_done_queue_lock, flags);
   6.115 -
   6.116 -  /* enqueue work */
   6.117 -  cpu_mask = mark_hyp_event(blk_request->domain, _HYP_EVENT_BLK_RX);
   6.118 -
   6.119 -  return;
   6.120  }
   6.121  
   6.122  /*
   6.123 @@ -115,125 +104,81 @@ void end_block_io_op(struct buffer_head 
   6.124  
   6.125  void flush_blk_queue(void)
   6.126  {
   6.127 -  blk_request_t *blk_request;
   6.128 -  int position = 0;
   6.129 -  blk_ring_t *blk_ring;
   6.130 -  unsigned long flags;
   6.131 -  int loop;
   6.132 +    blk_request_t *blk_request;
   6.133 +    int position = 0;
   6.134 +    blk_ring_t *blk_ring;
   6.135 +    unsigned long flags;
   6.136 +    int loop;
   6.137 +    
   6.138 +    spin_lock_irqsave(&io_done_queue_lock, flags);
   6.139 +    clear_bit(_HYP_EVENT_BLK_RX, &current->hyp_events);
   6.140 +    
   6.141 +    while (!list_empty(&io_done_queue)) {
   6.142 +
   6.143 +	blk_request = list_entry(io_done_queue.next, blk_request_t, queue);
   6.144 +	list_del (&blk_request->queue);
   6.145 +	spin_unlock_irqrestore(&io_done_queue_lock, flags);
   6.146 +	
   6.147 +	/* place on ring for guest os */ 
   6.148 +	blk_ring = blk_request->domain->blk_ring_base;
   6.149 +	position = blk_ring->brx_prod;
   6.150  
   6.151 -#if 0
   6.152 -  printk("{F}"); 
   6.153 -#endif
   6.154 -  /*
   6.155 -  if (XEN_BLK_DEBUG)  printk(XEN_BLK_DEBUG_LEVEL
   6.156 -			     "XEN flush_blk_queue\n");
   6.157 -  */
   6.158 +	if (XEN_BLK_DEBUG)  
   6.159 +	    printk(XEN_BLK_DEBUG_LEVEL "XEN flush_blk_queue [%d]\n", position);
   6.160 +
   6.161 +	memcpy(&blk_ring->brx_ring[position], &blk_request->request,
   6.162 +	       sizeof(blk_ring_entry_t));
   6.163 +	blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod);
   6.164  
   6.165 -  clear_bit(_HYP_EVENT_BLK_RX, &current->hyp_events);
   6.166 +	/* notify appropriate guest os */
   6.167 +	set_bit(_EVENT_BLK_RX, &blk_request->domain->shared_info->events);
   6.168 +	
   6.169 +	/* free the buffer header allocated in do_block_io_op */
   6.170 +	if (blk_request->bh)
   6.171 +	    kfree(blk_request->bh); 
   6.172  
   6.173 -  /* NEED LOCK? */
   6.174 -  spin_lock_irqsave(&io_done_queue_lock, flags);
   6.175 -  while (!list_empty(&io_done_queue))
   6.176 -  {
   6.177 -    blk_request = list_entry(io_done_queue.next, blk_request_t, queue);
   6.178 -    list_del (&blk_request->queue);
   6.179 +	spin_lock_irqsave(&free_queue_lock, flags);
   6.180 +	list_add_tail(&blk_request->queue, &free_queue);
   6.181 +	spin_unlock_irqrestore(&free_queue_lock, flags);
   6.182 +
   6.183 +	spin_lock_irqsave(&io_done_queue_lock, flags);
   6.184 +    }
   6.185      spin_unlock_irqrestore(&io_done_queue_lock, flags);
   6.186  
   6.187 -    /* place on ring for guest os */ 
   6.188 -    blk_ring = blk_request->domain->blk_ring_base;
   6.189 -    position = blk_ring->rx_prod;
   6.190 -
   6.191 -    if (XEN_BLK_DEBUG)  printk(XEN_BLK_DEBUG_LEVEL
   6.192 -			       "XEN flush_blk_queue [%d]\n", position);
   6.193 -
   6.194 -    memcpy(&blk_ring->rx_ring[position], &blk_request->request,
   6.195 -	   sizeof(blk_ring_entry_t));
   6.196 -    blk_ring->rx_prod = BLK_RX_RING_INC(blk_ring->rx_prod);
   6.197 -
   6.198 -    /* notify appropriate guest os */
   6.199 -    set_bit(_EVENT_BLK_RX,
   6.200 -	    &blk_request->domain->shared_info->events);
   6.201  
   6.202 -    if (0)
   6.203 -    {
   6.204 -      int temp;
   6.205 -      struct buffer_head *bh = blk_request->bh;
   6.206 -      char * vbuffer = bh->b_data;
   6.207 -
   6.208 -      printk (KERN_ALERT "XEN return block 0x%lx\n", bh->b_blocknr);
   6.209 +    /* XXX SMH: below is ugly and dangerous -- fix */
   6.210 +    /*
   6.211 +     * now check if there is any pending work from any domain
   6.212 +     * that we were previously unable to process.
   6.213 +     *
   6.214 +     * NOTE: the current algorithm will check _every_ domain
   6.215 +     * and wake up _every_ domain that has pending work.
   6.216 +     * In the future, we should stop waking up domains once
   6.217 +     * there isn't any space for their requests any more
   6.218 +     * ALSO, we need to maintain a counter of the last domain
   6.219 +     * that we woke up for fairness... we shouldn't restart
   6.220 +     * at domain 0 every time (although we might want to special
   6.221 +     * case domain 0);
   6.222 +     */
   6.223 +    for (loop = 0; loop < XEN_BLOCK_MAX_DOMAINS; loop++) {
   6.224  
   6.225 -      for (temp = 0; temp < bh->b_size; temp++)
   6.226 -      {
   6.227 -	if (temp % 16 == 0)       printk ("[%04x]  ", temp);
   6.228 -	else if (temp % 4 == 0)   printk (" ");
   6.229 -	                          printk ("%02x",
   6.230 -					  vbuffer[temp] & 255);
   6.231 -	if ((temp + 1) % 16 == 0) printk ("\n");
   6.232 -      }
   6.233 -      printk ("\n\n");
   6.234 +	int domain = pending_work & (1 << loop);
   6.235 +
   6.236 +	if (domain) {
   6.237 +
   6.238 +	    struct task_struct *mytask = current;
   6.239 +
   6.240 +	    while (mytask->domain != loop)
   6.241 +		mytask = mytask->next_task;
   6.242 +
   6.243 +	    pending_work = pending_work & !(1 << loop);
   6.244 +	    do_block_io_op_domain(mytask);
   6.245 +	}
   6.246      }
   6.247  
   6.248 -    /* free the buffer header allocated in do_block_io_op */
   6.249 -    if (blk_request->bh)
   6.250 -    {
   6.251 -      kfree(blk_request->bh);                     /* alloc in do_block_io_op */
   6.252 -    }
   6.253 -
   6.254 -    spin_lock_irqsave(&free_queue_lock, flags);
   6.255 -    list_add_tail(&blk_request->queue, &free_queue);
   6.256 -    spin_unlock_irqrestore(&free_queue_lock, flags);
   6.257 -
   6.258 -    spin_lock_irqsave(&io_done_queue_lock, flags);
   6.259 -  }
   6.260 -  spin_unlock_irqrestore(&io_done_queue_lock, flags);
   6.261 -
   6.262 -  /*
   6.263 -   * now check if there is any pending work from any domain
   6.264 -   * that we were previously unable to process.
   6.265 -   *
   6.266 -   * NOTE: the current algorithm will check _every_ domain
   6.267 -   * and wake up _every_ domain that has pending work.
   6.268 -   * In the future, we should stop waking up domains once
   6.269 -   * there isn't any space for their requests any more
   6.270 -   * ALSO, we need to maintain a counter of the last domain
   6.271 -   * that we woke up for fairness... we shouldn't restart
   6.272 -   * at domain 0 every time (although we might want to special
   6.273 -   * case domain 0);
   6.274 -   */
   6.275 -  for (loop = 0; loop < XEN_BLOCK_MAX_DOMAINS; loop++)
   6.276 -  {
   6.277 -    int domain = pending_work & (1 << loop);
   6.278 +    return; 
   6.279 +}
   6.280  
   6.281 -    if (domain)
   6.282 -    {
   6.283 -      struct task_struct *mytask = current;
   6.284 -
   6.285 -      /*
   6.286 -      printk (KERN_ALERT 
   6.287 -	      "flush_blk_queue  pending_work: %x  domain: %d  loop: %d\n",
   6.288 -	      pending_work, domain, loop);
   6.289 -      */
   6.290 -      /* IS THERE A BETTER WAY OF FINDING THE TASK STRUCT FOR A 
   6.291 -       * PARTICULAR DOMAIN? 
   6.292 -       *
   6.293 -       * WHAT IF THE TASK GOES AWAY BEFORE WE HAVE A CHANCE TO
   6.294 -       * FINISH PROCESSING ALL OF ITS REQUESTS?
   6.295 -       */
   6.296 -      while (mytask->domain != loop)
   6.297 -      {
   6.298 -	mytask = mytask->next_task;
   6.299 -      }
   6.300 -      do_block_io_op_domain(mytask);
   6.301 -
   6.302 -      pending_work = pending_work & !(1 << loop);
   6.303 -      /*
   6.304 -      printk (KERN_ALERT 
   6.305 -	      "                 pending_work: %x  domain: %d  loop: %d\n",
   6.306 -	      pending_work, domain, loop);
   6.307 -      */
   6.308 -    }
   6.309 -  }
   6.310 -}
   6.311  
   6.312  /*
   6.313   * do_block_io_op
   6.314 @@ -244,186 +189,132 @@ void flush_blk_queue(void)
   6.315  
   6.316  long do_block_io_op (void)
   6.317  {
   6.318 -  return do_block_io_op_domain(current);
   6.319 +    return do_block_io_op_domain(current);
   6.320  }
   6.321  
   6.322 +
   6.323  /*
   6.324   * do_block_io_op
   6.325   *
   6.326   * handle the requests for a particular domain
   6.327   */
   6.328 -
   6.329  long do_block_io_op_domain (struct task_struct* task)
   6.330  {
   6.331 -  blk_ring_t *blk_ring = task->blk_ring_base;
   6.332 -  int loop;
   6.333 +    blk_ring_t *blk_ring = task->blk_ring_base;
   6.334 +    int loop, status;
   6.335 +
   6.336 +    if (XEN_BLK_DEBUG)  
   6.337 +	printk(XEN_BLK_DEBUG_LEVEL "XEN do_block_io_op %d %d\n",
   6.338 +	       blk_ring->btx_cons, blk_ring->btx_prod);
   6.339  
   6.340 -#if 0
   6.341 -  printk("{%d}", current->domain); 
   6.342 -#endif
   6.343 -  if (XEN_BLK_DEBUG)  printk(XEN_BLK_DEBUG_LEVEL
   6.344 -			     "XEN do_block_io_op %d %d\n",
   6.345 -			     blk_ring->tx_cons, blk_ring->tx_prod);
   6.346 +    for (loop = blk_ring->btx_cons; 
   6.347 +	 loop != blk_ring->btx_prod; 
   6.348 +	 loop = BLK_TX_RING_INC(loop)) {
   6.349 +
   6.350 +	status = 1;
   6.351  
   6.352 -  for (loop = blk_ring->tx_cons;
   6.353 -       loop != blk_ring->tx_prod;
   6.354 -       loop = BLK_TX_RING_INC(loop))
   6.355 -  {
   6.356 -    int status = 1;
   6.357 +	switch (blk_ring->btx_ring[loop].operation) {
   6.358 +
   6.359 +	case XEN_BLOCK_READ:
   6.360 +	case XEN_BLOCK_WRITE:
   6.361 +	    status = dispatch_rw_block_io(loop);
   6.362 +	    break;
   6.363  
   6.364 -    switch (blk_ring->tx_ring[loop].operation)
   6.365 -    {
   6.366 -      case XEN_BLOCK_READ :
   6.367 -      case XEN_BLOCK_WRITE :
   6.368 -      {
   6.369 -	status = dispatch_rw_block_io(loop);
   6.370 -	break;
   6.371 -      }
   6.372 -      case XEN_BLOCK_PROBE :
   6.373 -      {
   6.374 -	status = dispatch_probe_block_io(loop);
   6.375 -	break;
   6.376 -      }
   6.377 -      case XEN_BLOCK_DEBUG :
   6.378 -      {
   6.379 -	status = dispatch_debug_block_io(loop);
   6.380 -	break;
   6.381 -      }
   6.382 -      default :
   6.383 -      {
   6.384 -	printk (KERN_ALERT "error: unknown block io operation [%d]\n",
   6.385 -		blk_ring->tx_ring[loop].operation);
   6.386 -	BUG();
   6.387 -      }
   6.388 +	case XEN_BLOCK_PROBE:
   6.389 +	    status = dispatch_probe_block_io(loop);
   6.390 +	    break;
   6.391 +
   6.392 +	case XEN_BLOCK_DEBUG:
   6.393 +	    status = dispatch_debug_block_io(loop);
   6.394 +	    break;
   6.395 +
   6.396 +	default:
   6.397 +	    printk (KERN_ALERT "error: unknown block io operation [%d]\n",
   6.398 +		    blk_ring->btx_ring[loop].operation);
   6.399 +	    BUG();
   6.400 +	}
   6.401 +
   6.402 +
   6.403 +	if (status) {
   6.404 +	    /* 
   6.405 +	    ** Unable to successfully issue / complete command, maybe because
   6.406 +	    ** another resource (e.g. disk request buffers) is unavailable.
   6.407 +	    ** stop removing items from the communications ring and try later 
   6.408 +	    */
   6.409 +	    pending_work = pending_work | (1 << task->domain);
   6.410 +	    break;
   6.411 +	}
   6.412      }
   6.413  
   6.414 -    if (status)
   6.415 -    {
   6.416 -      /* unable to successfully issue / complete command, maybe because
   6.417 -       * another resource (e.g. disk request buffers) is unavailable.
   6.418 -       * stop removing items from the communications ring and try 
   6.419 -       * again later 
   6.420 -       */
   6.421 +    blk_ring->btx_cons = loop;
   6.422 +    return 0L;
   6.423 +}
   6.424  
   6.425 -      /*
   6.426 -      printk ("do_block_io_op_domain  domain:%d, pending_work: %x\n",
   6.427 -	      task->domain, pending_work);
   6.428 -      */
   6.429 -      pending_work = pending_work | (1 << task->domain);
   6.430 -      /*
   6.431 -      printk ("do_block_io_op_domain  domain:%d, pending_work: %x\n",
   6.432 -	      task->domain, pending_work);
   6.433 -      */
   6.434 -      break;
   6.435 -    }
   6.436 -  }
   6.437 -
   6.438 -  blk_ring->tx_cons = loop;
   6.439 -
   6.440 -  return 0L;
   6.441 -}
   6.442  
   6.443  int dispatch_debug_block_io (int index)
   6.444  {
   6.445 -  struct task_struct *task;
   6.446 -  blk_ring_t *blk_ring = current->blk_ring_base;
   6.447 -  char * buffer;
   6.448 -  char output[1000];
   6.449 -
   6.450 -  int foobar = (unsigned long)blk_ring->tx_ring[index].block_number;
   6.451 -
   6.452 -  printk (KERN_ALERT "dispatch_debug_block_io %d\n", foobar);
   6.453 -
   6.454 -  buffer = phys_to_virt(blk_ring->tx_ring[index].buffer);
   6.455 -  strcpy (buffer, "DEBUG\n");
   6.456 -
   6.457 -  task = current;
   6.458 -  sprintf (buffer, "current %d\n", current->domain);
   6.459 -  sprintf (buffer, "%s  tx: prod: %d, cons: %d, size: %d\n", buffer,
   6.460 -	   blk_ring->tx_prod, blk_ring->tx_cons, blk_ring->tx_ring_size);
   6.461 -  sprintf (buffer, "%s  rx: prod: %d, cons: %d, size: %d\n", buffer,
   6.462 -	   blk_ring->rx_prod, blk_ring->rx_cons, blk_ring->rx_ring_size);
   6.463 +    printk (KERN_ALERT "dispatch_debug_block_io: UNIMPL\n"); 
   6.464 +    return 1; 
   6.465 +}
   6.466  
   6.467 -  task = task->next_task;
   6.468 -  while (task != current)
   6.469 -  {
   6.470 -    blk_ring = task->blk_ring_base;
   6.471 -    sprintf (buffer, "%stask %d\n", buffer, task->domain);
   6.472 -    if (blk_ring != NULL)
   6.473 -    {
   6.474 -      sprintf (buffer, "%s  tx: prod: %d, cons: %d, size: %d\n",
   6.475 -	       buffer, blk_ring->tx_prod, blk_ring->tx_cons, 
   6.476 -	       blk_ring->tx_ring_size);
   6.477 -      sprintf (buffer, "%s  rx: prod: %d, cons: %d, size: %d\n",
   6.478 -	       buffer, blk_ring->rx_prod, blk_ring->rx_cons, 
   6.479 -	       blk_ring->rx_ring_size);
   6.480 -    }
   6.481 -    task = task->next_task;
   6.482 -  }
   6.483 -  dumpx(output, foobar);
   6.484 -  sprintf (buffer, "%s%s\n", buffer, output);
   6.485 -
   6.486 -  return 0;
   6.487 -}
   6.488 +extern void ide_probe_devices(xen_disk_info_t *xdi);
   6.489  
   6.490  int dispatch_probe_block_io (int index)
   6.491  {
   6.492 -  blk_ring_t *blk_ring = current->blk_ring_base;
   6.493 -  xen_disk_info_t *xdi;
   6.494 -
   6.495 -  xdi = phys_to_virt(blk_ring->tx_ring[index].buffer);
   6.496 +    blk_ring_t *blk_ring = current->blk_ring_base;
   6.497 +    xen_disk_info_t *xdi;
   6.498 +    
   6.499 +    xdi = phys_to_virt((unsigned long)blk_ring->btx_ring[index].buffer);
   6.500 +    
   6.501 +    ide_probe_devices(xdi);
   6.502 +    
   6.503 +    memcpy(&blk_ring->brx_ring[blk_ring->brx_prod], 
   6.504 +	   &blk_ring->btx_ring[index], 
   6.505 +	   sizeof(blk_ring_entry_t));
   6.506 +    blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod);
   6.507 +    
   6.508 +    return 0;
   6.509 +}
   6.510  
   6.511 -  ide_probe_devices(xdi);
   6.512 -
   6.513 -  return 0;
   6.514 -}
   6.515 +extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
   6.516  
   6.517  int dispatch_rw_block_io (int index)
   6.518  {
   6.519 -  blk_ring_t *blk_ring = current->blk_ring_base;
   6.520 -  struct buffer_head *bh;
   6.521 -  struct request_queue *rq;
   6.522 -  int operation;
   6.523 -  blk_request_t *blk_request;
   6.524 -  unsigned long flags;
   6.525 -
   6.526 +    blk_ring_t *blk_ring = current->blk_ring_base;
   6.527 +    struct buffer_head *bh;
   6.528 +    struct request_queue *rq;
   6.529 +    int operation;
   6.530 +    blk_request_t *blk_request;
   6.531 +    unsigned long flags;
   6.532 +    
   6.533      /*
   6.534       * check to make sure that the block request seems at least
   6.535       * a bit legitimate
   6.536       */
   6.537 -    if ((blk_ring->tx_ring[index].block_size & (0x200 - 1)) != 0)
   6.538 -    {
   6.539 -      printk(KERN_ALERT
   6.540 -	     "    error: dodgy block size: %d\n", 
   6.541 -	     blk_ring->tx_ring[index].block_size);
   6.542 -      BUG();
   6.543 +    if ((blk_ring->btx_ring[index].block_size & (0x200 - 1)) != 0) {
   6.544 +	printk(KERN_ALERT "    error: dodgy block size: %d\n", 
   6.545 +	       blk_ring->btx_ring[index].block_size);
   6.546 +	BUG();
   6.547      }
   6.548 +    
   6.549  
   6.550 -    if (XEN_BLK_DEBUG) 
   6.551 -    {
   6.552 -    printk(XEN_BLK_DEBUG_LEVEL
   6.553 -	   "    tx_cons: %d  tx_prod %d  index: %d     op: %s, pri: %s\n",
   6.554 -	   blk_ring->tx_cons, blk_ring->tx_prod, index,
   6.555 -	   (blk_ring->tx_ring[index].operation == XEN_BLOCK_READ ? "read" : "write"),
   6.556 -	   (blk_ring->tx_ring[index].priority == XEN_BLOCK_SYNC ? "sync" : "async"));
   6.557 -    }
   6.558 -
   6.559 -    {
   6.560 -      char temp[100];
   6.561 -      sprintf(temp, "issue  buf: 0x%p, bh: 0x%p, blkno: 0x%lx",
   6.562 -	      blk_ring->tx_ring[index].buffer, bh,
   6.563 -	      (unsigned long)blk_ring->tx_ring[index].block_number);
   6.564 -      printx(temp);
   6.565 +    if (XEN_BLK_DEBUG) {
   6.566 +	printk(XEN_BLK_DEBUG_LEVEL "    btx_cons: %d  btx_prod %d  index: %d "
   6.567 +	       "op: %s, pri: %s\n", blk_ring->btx_cons, blk_ring->btx_prod, 
   6.568 +	       index, 
   6.569 +	       (blk_ring->btx_ring[index].operation == XEN_BLOCK_READ ? 
   6.570 +		"read" : "write"), 
   6.571 +	       (blk_ring->btx_ring[index].priority == XEN_BLOCK_SYNC ? 
   6.572 +		"sync" : "async"));
   6.573      }
   6.574  
   6.575      /* find an empty request slot */
   6.576      spin_lock_irqsave(&free_queue_lock, flags);
   6.577 -    if (list_empty(&free_queue))
   6.578 -    {
   6.579 -      /*      printk (KERN_ALERT "dispatch_rw_block_io EMPTY FREE LIST!! %d\n", index); */
   6.580 -      spin_unlock_irqrestore(&free_queue_lock, flags);
   6.581 -      return 1;
   6.582 +    if (list_empty(&free_queue)) {
   6.583 +	spin_unlock_irqrestore(&free_queue_lock, flags);
   6.584 +	return 1;
   6.585      }
   6.586 +
   6.587      blk_request = list_entry(free_queue.next, blk_request_t, queue);
   6.588      list_del(&blk_request->queue);
   6.589      spin_unlock_irqrestore(&free_queue_lock, flags);
   6.590 @@ -432,60 +323,109 @@ int dispatch_rw_block_io (int index)
   6.591      spin_lock_irqsave(&pending_queue_lock, flags);
   6.592      list_add_tail(&blk_request->queue, &pending_queue);
   6.593      spin_unlock_irqrestore(&pending_queue_lock, flags);
   6.594 -
   6.595 +    
   6.596      /* we'll be doing this frequently, would a cache be appropriate? */
   6.597      /* free in flush_blk_queue */
   6.598      bh = (struct buffer_head *) kmalloc(sizeof(struct buffer_head), 
   6.599  					GFP_KERNEL);
   6.600 -    if (!bh)
   6.601 -    {
   6.602 -      printk(KERN_ALERT "ERROR: bh is null\n");
   6.603 -      BUG();
   6.604 +    if (!bh) {
   6.605 +	printk(KERN_ALERT "ERROR: bh is null\n");
   6.606 +	BUG();
   6.607      }
   6.608  
   6.609      /* set just the important bits of the buffer header */
   6.610      memset (bh, 0, sizeof (struct buffer_head));
   6.611 -
   6.612 -    bh->b_blocknr = blk_ring->tx_ring[index].block_number;   /* block number */
   6.613 -    bh->b_size = blk_ring->tx_ring[index].block_size;          /* block size */
   6.614 -    bh->b_dev = blk_ring->tx_ring[index].device;   /* device (B_FREE = free) */
   6.615 -    bh->b_rsector = blk_ring->tx_ring[index].sector_number; /* sector number */
   6.616 -                                                    
   6.617 -    bh->b_data = phys_to_virt(blk_ring->tx_ring[index].buffer);
   6.618 -                                                          /* ptr to data blk */
   6.619 -    bh->b_count.counter = 1;                       /* users using this block */
   6.620 -    bh->b_xen_request = (void *)blk_request;           /* save block request */
   6.621      
   6.622 -
   6.623 -    if (blk_ring->tx_ring[index].operation == XEN_BLOCK_WRITE)
   6.624 -    {
   6.625 -      bh->b_state = ((1 << BH_JBD) |                  /* buffer state bitmap */
   6.626 -		     (1 << BH_Mapped) |
   6.627 -		     (1 << BH_Req) |
   6.628 -		     (1 << BH_Dirty) |
   6.629 -		     (1 << BH_Uptodate));
   6.630 -      operation = WRITE;
   6.631 -    }
   6.632 -    else
   6.633 -    {
   6.634 -      bh->b_state = (1 << BH_Mapped);                 /* buffer state bitmap */
   6.635 -      operation = READ;
   6.636 +    bh->b_blocknr       = blk_ring->btx_ring[index].block_number;
   6.637 +    bh->b_size          = blk_ring->btx_ring[index].block_size; 
   6.638 +    bh->b_dev           = blk_ring->btx_ring[index].device; 
   6.639 +    bh->b_rsector       = blk_ring->btx_ring[index].sector_number;
   6.640 +    bh->b_data          = phys_to_virt((unsigned long)
   6.641 +				       blk_ring->btx_ring[index].buffer);
   6.642 +    bh->b_count.counter = 1;
   6.643 +    bh->b_xen_request   = (void *)blk_request;  
   6.644 +    
   6.645 +    if (blk_ring->btx_ring[index].operation == XEN_BLOCK_WRITE) {
   6.646 +	bh->b_state = ((1 << BH_JBD) | (1 << BH_Mapped) | (1 << BH_Req) |
   6.647 +		       (1 << BH_Dirty) | (1 << BH_Uptodate));
   6.648 +	operation = WRITE;
   6.649 +    } else {
   6.650 +	bh->b_state = (1 << BH_Mapped);
   6.651 +	operation = READ;
   6.652      }
   6.653  
   6.654 -    /* save meta data about request */
   6.655 -    memcpy(&blk_request->request,                    /* NEED COPY_FROM_USER? */
   6.656 -	   &blk_ring->tx_ring[index], sizeof(blk_ring_entry_t));
   6.657 -    blk_request->bh = bh;
   6.658 -    blk_request->domain = current;                    /* save current domain */
   6.659 -
   6.660 +    /* save meta data about request XXX SMH: should copy_from_user() */
   6.661 +    memcpy(&blk_request->request,
   6.662 +	   &blk_ring->btx_ring[index], sizeof(blk_ring_entry_t));
   6.663 +    blk_request->bh     = bh;
   6.664 +    blk_request->domain = current; 
   6.665 +    
   6.666      /* dispatch single block request */
   6.667 -    ll_rw_block(operation, 1, &bh);                        /* linux top half */
   6.668 +    ll_rw_block(operation, 1, &bh);       /* linux top half */
   6.669      rq = blk_get_queue(bh->b_rdev);                         
   6.670 -    generic_unplug_device(rq);                          /* linux bottom half */
   6.671 +    generic_unplug_device(rq);            /* linux bottom half */
   6.672  
   6.673      return 0;
   6.674  }
   6.675  
   6.676 +
   6.677 +/*
   6.678 + * debug dump_queue
   6.679 + * arguments: queue head, name of queue
   6.680 + */
   6.681 +void dump_queue(struct list_head *queue, char *name)
   6.682 +{
   6.683 +    struct list_head *list;
   6.684 +    int loop = 0;
   6.685 +    
   6.686 +    printk ("QUEUE %s %lx   n: %lx, p: %lx\n", name,  (unsigned long)queue,
   6.687 +	    (unsigned long) queue->next, (unsigned long) queue->prev);
   6.688 +    list_for_each (list, queue) {
   6.689 +	printk ("  %s %d : %lx   n: %lx, p: %lx\n", name, loop++, 
   6.690 +		(unsigned long)list,
   6.691 +		(unsigned long)list->next, (unsigned long)list->prev);
   6.692 +    }
   6.693 +    return; 
   6.694 +}
   6.695 +
   6.696 +void dump_queue_head(struct list_head *queue, char *name)
   6.697 +{
   6.698 +    struct list_head *list;
   6.699 +    int loop = 0;
   6.700 +    
   6.701 +    printk ("QUEUE %s %lx   n: %lx, p: %lx\n", name,  (unsigned long)queue,
   6.702 +	    (unsigned long) queue->next, (unsigned long) queue->prev);
   6.703 +    list_for_each (list, queue) {
   6.704 +	printk ("      %d : %lx   n: %lx, p: %lx\n", loop++, 
   6.705 +		(unsigned long)list,
   6.706 +		(unsigned long)list->next, (unsigned long)list->prev);
   6.707 +	if (loop >= 5) return;
   6.708 +    }
   6.709 +}
   6.710 +
   6.711 +static void dump_blockq(u_char key, void *dev_id, struct pt_regs *regs) 
   6.712 +{
   6.713 +    u_long flags; 
   6.714 +
   6.715 +    printk("Dumping block queues:\n"); 
   6.716 +
   6.717 +    spin_lock_irqsave(&free_queue_lock, flags);
   6.718 +    dump_queue(&free_queue, "FREE QUEUE"); 
   6.719 +    spin_unlock_irqrestore(&free_queue_lock, flags);
   6.720 +
   6.721 +    spin_lock_irqsave(&pending_queue_lock, flags);
   6.722 +    dump_queue(&pending_queue, "PENDING QUEUE"); 
   6.723 +    spin_unlock_irqrestore(&pending_queue_lock, flags);
   6.724 +
   6.725 +    spin_lock_irqsave(&io_done_queue_lock, flags);
   6.726 +    dump_queue(&io_done_queue, "IO DONE QUEUE"); 
   6.727 +    spin_unlock_irqrestore(&io_done_queue_lock, flags);
   6.728 +
   6.729 +    return; 
   6.730 +}
   6.731 +
   6.732 +
   6.733 +
   6.734  /*
   6.735   * initialize_block_io
   6.736   *
   6.737 @@ -493,128 +433,33 @@ int dispatch_rw_block_io (int index)
   6.738   * called from arch/i386/setup.c::start_of_day
   6.739   */
   6.740  
   6.741 -void initialize_block_io ()
   6.742 -{
   6.743 -  int loop;
   6.744 -
   6.745 -  INIT_LIST_HEAD(&free_queue);
   6.746 -  INIT_LIST_HEAD(&pending_queue);
   6.747 -  INIT_LIST_HEAD(&io_done_queue);
   6.748 -  
   6.749 -  spin_lock_init(&free_queue_lock);
   6.750 -  spin_lock_init(&pending_queue_lock);
   6.751 -  spin_lock_init(&io_done_queue_lock);
   6.752 +void initialize_block_io (){
   6.753  
   6.754 -  for (loop = 0; loop < XEN_BLK_REQUEST_LIST_SIZE; loop++)
   6.755 -  {
   6.756 -    list_add_tail(&blk_request_list[loop].queue, &free_queue);
   6.757 -  }
   6.758 -
   6.759 -  /*
   6.760 -   * if bit i is true then domain i has work for us to do.
   6.761 -   */
   6.762 -  pending_work = 0;
   6.763 -
   6.764 -  return;
   6.765 +    int loop;
   6.766 +    
   6.767 +    INIT_LIST_HEAD(&free_queue);
   6.768 +    INIT_LIST_HEAD(&pending_queue);
   6.769 +    INIT_LIST_HEAD(&io_done_queue);
   6.770 +    
   6.771 +    spin_lock_init(&free_queue_lock);
   6.772 +    spin_lock_init(&pending_queue_lock);
   6.773 +    spin_lock_init(&io_done_queue_lock);
   6.774 +    
   6.775 +    for (loop = 0; loop < XEN_BLK_REQUEST_LIST_SIZE; loop++)
   6.776 +    {
   6.777 +	list_add_tail(&blk_request_list[loop].queue, &free_queue);
   6.778 +    }
   6.779 +    
   6.780 +    
   6.781 +    add_key_handler('b', dump_blockq, "dump xen ide block queues"); 
   6.782 +    
   6.783 +    /*
   6.784 +     * if bit i is true then domain i has work for us to do.
   6.785 +     */
   6.786 +    pending_work = 0;
   6.787 +    
   6.788 +    return;
   6.789  }
   6.790  
   6.791  
   6.792 -#ifdef DEBUG
   6.793  
   6.794 -/*
   6.795 - * debug dump_queue
   6.796 - * arguments: queue head, name of queue
   6.797 - */
   6.798 -void dump_queue(struct list_head *queue, char *name)
   6.799 -{
   6.800 -  struct list_head *list;
   6.801 -  int loop = 0;
   6.802 -
   6.803 -  printk ("QUEUE %s %lx   n: %lx, p: %lx\n", name,  (unsigned long)queue,
   6.804 -	  (unsigned long) queue->next, (unsigned long) queue->prev);
   6.805 -  list_for_each (list, queue)
   6.806 -  {
   6.807 -    printk ("  %s %d : %lx   n: %lx, p: %lx\n", name, loop++, 
   6.808 -	    (unsigned long)list,
   6.809 -	    (unsigned long)list->next, (unsigned long)list->prev);
   6.810 -  }
   6.811 -}
   6.812 -
   6.813 -void dump_queue_head(struct list_head *queue, char *name)
   6.814 -{
   6.815 -  struct list_head *list;
   6.816 -  int loop = 0;
   6.817 -
   6.818 -  printk ("QUEUE %s %lx   n: %lx, p: %lx\n", name,  (unsigned long)queue,
   6.819 -	  (unsigned long) queue->next, (unsigned long) queue->prev);
   6.820 -  list_for_each (list, queue)
   6.821 -  {
   6.822 -    printk ("      %d : %lx   n: %lx, p: %lx\n", loop++, 
   6.823 -	    (unsigned long)list,
   6.824 -	    (unsigned long)list->next, (unsigned long)list->prev);
   6.825 -    if (loop >= 5) return;
   6.826 -  }
   6.827 -}
   6.828 -
   6.829 -#endif /* DEBUG */
   6.830 -
   6.831 -
   6.832 -#define debug_block_size 200000
   6.833 -#define debug_output_size 10
   6.834 -
   6.835 -static int    countx = 0;
   6.836 -static char * arrayx[debug_block_size];
   6.837 -static int    outputx = 0;
   6.838 -
   6.839 -void
   6.840 -printx (char * string)
   6.841 -{
   6.842 -  char * s;
   6.843 -
   6.844 -  s = (char *) kmalloc(strlen(string), GFP_KERNEL);
   6.845 -  strcpy (s, string);
   6.846 -  arrayx[countx++] = s;
   6.847 -
   6.848 -  if (countx >= debug_block_size)
   6.849 -  {
   6.850 -    countx = 0;
   6.851 -    printk (KERN_ALERT "printx wrap\n");
   6.852 -  }
   6.853 -
   6.854 -}
   6.855 -
   6.856 -void
   6.857 -dumpx (char *buffer, int count)
   6.858 -{
   6.859 -  int loop;
   6.860 -  int start;
   6.861 -
   6.862 -  sprintf (buffer, "debug dump\n");
   6.863 -
   6.864 -  /*
   6.865 -  for (loop = outputx;
   6.866 -       loop < outputx + debug_output_size && loop < countx; 
   6.867 -       loop ++)
   6.868 -  {
   6.869 -    sprintf (buffer, "%s%02d:%s\n", buffer, loop, arrayx[loop]);
   6.870 -  }
   6.871 -  outputx = loop;
   6.872 -  */
   6.873 -  
   6.874 -  if (count == 0 || count > countx)
   6.875 -  {
   6.876 -    start = 0;
   6.877 -  }
   6.878 -  else
   6.879 -  {
   6.880 -    start = countx - count;
   6.881 -  }
   6.882 -
   6.883 -  printk (KERN_ALERT "DUMPX BUFFER\n");
   6.884 -  for (loop = start; loop < countx; loop++)
   6.885 -  {
   6.886 -    printk (KERN_ALERT "%4d %s\n", loop, arrayx[loop]);
   6.887 -  }
   6.888 -  printk (KERN_ALERT "DUMPX bye bye\n");
   6.889 -}
   6.890 -
     7.1 --- a/xen-2.4.16/drivers/char/xen_kbd.c	Thu Feb 13 14:51:10 2003 +0000
     7.2 +++ b/xen-2.4.16/drivers/char/xen_kbd.c	Fri Feb 14 11:58:16 2003 +0000
     7.3 @@ -1,5 +1,6 @@
     7.4  #include <asm-i386/io.h>
     7.5  #include <xeno/sched.h>    /* this has request_irq() proto for some reason */
     7.6 +#include <xeno/keyhandler.h>  
     7.7  
     7.8  #define KEYBOARD_IRQ 1
     7.9  
    7.10 @@ -22,74 +23,148 @@
    7.11  #define kbd_read_status() inb(KBD_STATUS_REG)
    7.12  
    7.13  
    7.14 +static int keyboard_shift = 0;
    7.15 +static int keyboard_control = 0;
    7.16  
    7.17 -static void
    7.18 -dispatch_scancode (unsigned char scancode)
    7.19 +/* the following is pretty gross... 
    7.20 + * stop reading if you don't want to throw up!
    7.21 + */
    7.22 +
    7.23 +static unsigned char keymap_normal[] =
    7.24  {
    7.25 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.26 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.27 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.28 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.29 +
    7.30 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.31 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.32 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.33 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.34 +
    7.35 +   0 , 0 ,'1','2', '3','4','5','6',    '7','8','9','0', '-','=','\b','\t',
    7.36 +  'q','w','e','r', 't','y','u','i',    'o','p','[',']','\r', 0 ,'a','s',
    7.37 +  'd','f','g','h', 'j','k','l',';',   '\'','`', 0 ,'#', 'z','x','c','v',
    7.38 +  'b','n','m',',', '.','/', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.39 +
    7.40 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.41 +   0 , 0 , 0 , 0 ,  0 , 0 ,'\\', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.42 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.43 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
    7.44 +};
    7.45 +
    7.46 +static unsigned char keymap_shift[] =
    7.47 +{
    7.48 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.49 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.50 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.51 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.52 +
    7.53 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.54 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.55 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.56 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.57  
    7.58 -    /*
    7.59 -     * we could be a bit more clever here, but why?
    7.60 -     * just add a jump to your debug routine for the appropriate character.
    7.61 -     */
    7.62 -    switch (scancode)
    7.63 -    {
    7.64 -    case 0x01 :                                                       /* esc */
    7.65 -	printk ("<esc>");
    7.66 -	break;
    7.67 -    case 0x9e :                                                         /* a */
    7.68 -	printk ("a");
    7.69 -	break;
    7.70 -    case 0x9f :                                                         /* s */
    7.71 -	printk ("s");
    7.72 +   0 , 0 ,'!','"', '#','$','%','^',    '&','*','(',')', '_','+','\b','\t',
    7.73 +  'Q','W','E','R', 'T','Y','U','I',    'O','P','{','}','\r', 0 ,'A','S',
    7.74 +  'D','F','G','H', 'J','K','L',':',    '@', 0 , 0 ,'~', 'Z','X','C','V',
    7.75 +  'B','N','M','<', '>','?', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.76 +
    7.77 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.78 +   0 , 0 , 0 , 0 ,  0 , 0 ,'|', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.79 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.80 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
    7.81 +};
    7.82 +
    7.83 +
    7.84 +static unsigned char keymap_control[] =
    7.85 +{ /* same as normal, except for a-z -> 1 to 26 */
    7.86 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.87 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.88 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.89 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.90 +
    7.91 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.92 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.93 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.94 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
    7.95 +
    7.96 +   0 , 0 ,'1','2', '3','4','5','6',    '7','8','9','0', '-','=','\b','\t',
    7.97 +   17, 23, 5 , 18,  20, 25, 21, 9 ,     15, 16,'[',']','\r', 0 , 1 , 19,
    7.98 +   4 , 6 , 7 , 8 ,  10, 11, 12,';',   '\'','`', 0 ,'#', 26, 24, 3 , 22,
    7.99 +   2 , 14, 13,',', '.','/', 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
   7.100 +
   7.101 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
   7.102 +   0 , 0 , 0 , 0 ,  0 , 0 ,'\\', 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
   7.103 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,
   7.104 +   0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 ,     0 , 0 , 0 , 0 ,  0 , 0 , 0 , 0 
   7.105 +};
   7.106 +
   7.107 +
   7.108 +static unsigned char convert_scancode (unsigned char scancode)
   7.109 +{
   7.110 +    unsigned char value = 0;
   7.111 +
   7.112 +    switch (scancode) {
   7.113 +
   7.114 +    case 0xba: /* caps lock UP */
   7.115 +    case 0x9d: /* ctrl (left) UP */
   7.116 +	keyboard_control = 0;
   7.117  	break;
   7.118 -    case 0xae :                                                         /* c */
   7.119 -	printk ("c");
   7.120 -	break;
   7.121 -    case 0xb0 :                                                         /* b */
   7.122 -	printk ("b");
   7.123 +
   7.124 +    case 0x3a: /* caps lock DOWN */
   7.125 +    case 0x1d: /* ctrl (left) DOWN */
   7.126 +	keyboard_control = 1;
   7.127  	break;
   7.128 -    case 0xbb :                                                        /* f1 */
   7.129 -	printk ("<f1>");
   7.130 -	break;
   7.131 -    case 0xbc :                                                        /* f2 */
   7.132 -	printk ("<f2>");
   7.133 +
   7.134 +    case 0xaa: /* shift (left) UP */
   7.135 +    case 0xb6: /* shift (right) UP */
   7.136 +	keyboard_shift = 0;
   7.137  	break;
   7.138 -    case 0xbd :                                                        /* f3 */
   7.139 -	printk ("<f3>");
   7.140 -	break;
   7.141 -    case 0xbe :                                                        /* f4 */
   7.142 -	printk ("<f4>");
   7.143 +
   7.144 +    case 0x2a: /* shift (left) DOWN */
   7.145 +    case 0x36: /* shift (right) DOWN */
   7.146 +	keyboard_shift = 1;
   7.147  	break;
   7.148 -    case 0xbf :                                                        /* f5 */
   7.149 -	/* xen_block_dump_state(); */
   7.150 -	break;
   7.151 -    default :
   7.152 -	/* printk ("%x ", scancode); */
   7.153 +
   7.154 +    default:   /* normal keys */
   7.155 +	if (keyboard_control)
   7.156 +	    value = keymap_control[scancode];
   7.157 +	else if (keyboard_shift)
   7.158 +	    value = keymap_shift[scancode];
   7.159 +	else
   7.160 +	    value = keymap_normal[scancode];
   7.161 +
   7.162      }
   7.163  
   7.164 -    return; 
   7.165 +    if (value) printk ("%c", value);
   7.166 +
   7.167 +    return value;
   7.168  }
   7.169  
   7.170 -
   7.171 -/* regs should be struct pt_regs */
   7.172 -
   7.173 -static void keyboard_interrupt(int irq, void *dev_id, void *regs)
   7.174 +static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   7.175  {
   7.176      unsigned char status = kbd_read_status();
   7.177      unsigned int work = 10000;
   7.178 -    
   7.179 +
   7.180      while ((--work > 0) && (status & KBD_STAT_OBF))
   7.181      {
   7.182  	unsigned char scancode;
   7.183 -	
   7.184  	scancode = kbd_read_input();
   7.185  	
   7.186  	if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
   7.187  	{
   7.188  	    if (status & KBD_STAT_MOUSE_OBF)
   7.189  		/* mouse event, ignore */;
   7.190 -	    else
   7.191 -		dispatch_scancode (scancode);
   7.192 +	    else {
   7.193 +		unsigned char key; 
   7.194 +		key_handler *handler; 
   7.195 +		
   7.196 +		if((key = convert_scancode (scancode)) && 
   7.197 +		   (handler = get_key_handler(key))) 
   7.198 +		    (*handler)(key, dev_id, regs); 
   7.199 +		
   7.200 +	    }
   7.201  	}
   7.202  	status = kbd_read_status();
   7.203      }
     8.1 --- a/xen-2.4.16/drivers/char/xen_serial.c	Thu Feb 13 14:51:10 2003 +0000
     8.2 +++ b/xen-2.4.16/drivers/char/xen_serial.c	Fri Feb 14 11:58:16 2003 +0000
     8.3 @@ -1,6 +1,7 @@
     8.4  #include <asm-i386/io.h>
     8.5  #include <xeno/sched.h>    /* this has request_irq() proto for some reason */
     8.6 -
     8.7 +#include <xeno/keyhandler.h> 
     8.8 +#include <xeno/reboot.h>
     8.9  
    8.10  /* Register offsets */
    8.11  #define NS16550_RBR	0x00	/* receive buffer	*/
    8.12 @@ -43,51 +44,20 @@
    8.13  
    8.14  
    8.15  
    8.16 -/* 
    8.17 -** We keep an array of 'handlers' for each key code between 0 and 255; 
    8.18 -** this is intended to allow very simple debugging routines (toggle 
    8.19 -** debug flag, dump registers, reboot, etc) to be hooked in in a slightly
    8.20 -** nicer fashion than just editing this file :-) 
    8.21 -*/
    8.22 -
    8.23 -#define KEY_MAX 256
    8.24 -typedef void key_handler(u_char key); 
    8.25 -
    8.26 -static key_handler *key_table[KEY_MAX]; 
    8.27 -    
    8.28 -void add_key_handler(u_char key, key_handler *handler) 
    8.29 -{
    8.30 -    if(key_table[key] != NULL) 
    8.31 -	printk("Warning: overwriting handler for key 0x%x\n", key); 
    8.32 -
    8.33 -    key_table[key] = handler; 
    8.34 -    return; 
    8.35 -}
    8.36 -
    8.37 -
    8.38 -
    8.39  static int serial_echo = 0;   /* default is not to echo; change with 'e' */
    8.40  
    8.41 -void toggle_echo(u_char key) 
    8.42 +void toggle_echo(u_char key, void *dev_id, struct pt_regs *regs) 
    8.43  {
    8.44      serial_echo = !serial_echo; 
    8.45      return; 
    8.46  }
    8.47  
    8.48  
    8.49 -void halt_machine(u_char key) 
    8.50 -{
    8.51 -    /* This is 'debug me please' => just dump info and halt machine */
    8.52 -    printk("serial_rx_int: got EOT => halting machine.\n"); 
    8.53 -    printk("<not actually halting for now>\n"); 
    8.54 -    return; 
    8.55 -}
    8.56 -
    8.57 -
    8.58  
    8.59  static void serial_rx_int(int irq, void *dev_id, struct pt_regs *regs)
    8.60  {
    8.61      u_char c; 
    8.62 +    key_handler *handler; 
    8.63  
    8.64      /* XXX SMH: should probably check this is an RX interrupt :-) */
    8.65  
    8.66 @@ -95,8 +65,8 @@ static void serial_rx_int(int irq, void 
    8.67      c = inb(SERIAL_BASE + NS16550_RBR );
    8.68  
    8.69      /* if there's a handler, call it: we trust it won't screw us too badly */
    8.70 -    if(key_table[c]) 
    8.71 -	(*key_table[c])(c); 
    8.72 +    if((handler = get_key_handler(c)) != NULL) 
    8.73 +	(*handler)(c, dev_id, regs); 
    8.74  
    8.75      if(serial_echo) 
    8.76  	printk("%c", c); 
    8.77 @@ -104,19 +74,12 @@ static void serial_rx_int(int irq, void 
    8.78      return; 
    8.79  }
    8.80  
    8.81 -
    8.82  void initialize_serial() 
    8.83  {
    8.84 -    int i, fifo, rc; 
    8.85 -
    8.86 -    /* first initialize key handler table */
    8.87 -    for(i = 0; i < KEY_MAX; i++) 
    8.88 -	key_table[i] = (key_handler *)NULL; 
    8.89 -
    8.90 -    /* setup own handlers */
    8.91 -    add_key_handler(0x01, toggle_echo);    /* <esc> to toggle echo */
    8.92 -    add_key_handler(0x04, halt_machine);   /* CTRL-D to 'halt' */
    8.93 -
    8.94 +    int fifo, rc; 
    8.95 +    
    8.96 +    /* setup key handler */
    8.97 +    add_key_handler('~', toggle_echo, "toggle serial echo");
    8.98      
    8.99      /* Should detect this, but must be a ns16550a at least, surely? */
   8.100      fifo = 1;  
     9.1 --- a/xen-2.4.16/drivers/ide/ide-xeno.c	Thu Feb 13 14:51:10 2003 +0000
     9.2 +++ b/xen-2.4.16/drivers/ide/ide-xeno.c	Fri Feb 14 11:58:16 2003 +0000
     9.3 @@ -5,42 +5,37 @@
     9.4  #include <hypervisor-ifs/block.h>
     9.5  
     9.6  
     9.7 -void
     9.8 -ide_probe_devices (xen_disk_info_t* xdi)
     9.9 +void ide_probe_devices (xen_disk_info_t* xdi)
    9.10  {
    9.11 -  int loop;
    9.12 +    int loop;
    9.13 +    
    9.14 +    for (loop = 0; loop < MAX_HWIFS; ++loop) {
    9.15  
    9.16 -  for (loop = 0; loop < MAX_HWIFS; ++loop)
    9.17 -  {
    9.18 -    ide_hwif_t *hwif = &ide_hwifs[loop];
    9.19 -    if (hwif->present)
    9.20 -    {
    9.21 -      struct gendisk *gd = hwif->gd;
    9.22 -      unsigned int unit;
    9.23 +	ide_hwif_t *hwif = &ide_hwifs[loop];
    9.24 +	if (hwif->present) {
    9.25  
    9.26 -      for (unit = 0; unit < MAX_DRIVES; ++unit)
    9.27 -      {
    9.28 -	unsigned long capacity;
    9.29 +	    struct gendisk *gd = hwif->gd;
    9.30 +	    unsigned int unit;
    9.31 +
    9.32 +	    for (unit = 0; unit < MAX_DRIVES; ++unit) {
    9.33 +		unsigned long capacity;
    9.34 +		ide_drive_t *drive = &hwif->drives[unit];
    9.35  
    9.36 -	ide_drive_t *drive = &hwif->drives[unit];
    9.37 -
    9.38 -	if (drive->present)
    9.39 -	{
    9.40 -	  capacity = current_capacity (drive);
    9.41 -
    9.42 -	  xdi->disks[xdi->count].type = XEN_DISK_IDE;
    9.43 -	  xdi->disks[xdi->count].capacity = capacity;
    9.44 -	  xdi->count++;
    9.45 +		if (drive->present) {
    9.46 +		    capacity = current_capacity (drive);
    9.47 +		    xdi->disks[xdi->count].type = XEN_DISK_IDE;
    9.48 +		    xdi->disks[xdi->count].capacity = capacity;
    9.49 +		    xdi->count++;
    9.50  
    9.51 -	  printk (KERN_ALERT "IDE-XENO %d\n", xdi->count);
    9.52 -	  printk (KERN_ALERT "  capacity  0x%x\n", capacity);
    9.53 -	  printk (KERN_ALERT "  head      0x%x\n", drive->bios_head);
    9.54 -	  printk (KERN_ALERT "  sector    0x%x\n", drive->bios_sect);
    9.55 -	  printk (KERN_ALERT "  cylinder  0x%x\n", drive->bios_cyl);
    9.56 +		    printk (KERN_ALERT "IDE-XENO %d\n", xdi->count);
    9.57 +		    printk (KERN_ALERT "  capacity  0x%x\n", capacity);
    9.58 +		    printk (KERN_ALERT "  head      0x%x\n", drive->bios_head);
    9.59 +		    printk (KERN_ALERT "  sector    0x%x\n", drive->bios_sect);
    9.60 +		    printk (KERN_ALERT "  cylinder  0x%x\n", drive->bios_cyl);
    9.61 +		}
    9.62 +	    }
    9.63  	}
    9.64 -      }
    9.65      }
    9.66 -  }
    9.67  
    9.68    return;
    9.69  }
    10.1 --- a/xen-2.4.16/include/hypervisor-ifs/block.h	Thu Feb 13 14:51:10 2003 +0000
    10.2 +++ b/xen-2.4.16/include/hypervisor-ifs/block.h	Fri Feb 14 11:58:16 2003 +0000
    10.3 @@ -51,13 +51,13 @@ typedef struct blk_ring_entry
    10.4  
    10.5  typedef struct blk_ring_st 
    10.6  {
    10.7 -  blk_ring_entry_t *tx_ring;
    10.8 -  unsigned int      tx_prod, tx_cons;
    10.9 -  unsigned int 	    tx_ring_size;
   10.10 +  blk_ring_entry_t *btx_ring;
   10.11 +  unsigned int      btx_prod, btx_cons;
   10.12 +  unsigned int 	    btx_ring_size;
   10.13  
   10.14 -  blk_ring_entry_t *rx_ring;
   10.15 -  unsigned int      rx_prod, rx_cons;
   10.16 -  unsigned int	    rx_ring_size;
   10.17 +  blk_ring_entry_t *brx_ring;
   10.18 +  unsigned int      brx_prod, brx_cons;
   10.19 +  unsigned int	    brx_ring_size;
   10.20  } blk_ring_t;
   10.21  
   10.22  #define MAX_XEN_DISK_COUNT 100
    11.1 --- a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h	Thu Feb 13 14:51:10 2003 +0000
    11.2 +++ b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h	Fri Feb 14 11:58:16 2003 +0000
    11.3 @@ -107,10 +107,9 @@ typedef struct
    11.4  #define EVENT_BLK_RX   0x02 /* empty buffers for receive. */
    11.5  #define EVENT_TIMER    0x04 /* a timeout has been updated. */
    11.6  #define EVENT_DIE      0x08 /* OS is about to be killed. Clean up please! */
    11.7 -#define EVENT_NET_TX   0x10 /* packets for transmission. */
    11.8 -#define EVENT_NET_RX   0x20 /* empty buffers for receive. */
    11.9 -#define EVENT_NET2_TX  0x40 /* packets for transmission. */
   11.10 -#define EVENT_NET2_RX  0x80 /* empty buffers for receive. */
   11.11 +#define EVENT_DEBUG    0x10 /* request guest to dump debug info (gross!) */
   11.12 +#define EVENT_NET_TX   0x20 /* packets for transmission. */
   11.13 +#define EVENT_NET_RX   0x40 /* empty buffers for receive. */
   11.14  
   11.15  /* should these macros and the ones below test for range violation? */
   11.16  #define EVENT_NET_TX_FOR_VIF(x)    (EVENT_NET_TX << (2 * x))
   11.17 @@ -124,12 +123,12 @@ typedef struct
   11.18  #define _EVENT_DIE     3
   11.19  #define _EVENT_NET_TX  4
   11.20  #define _EVENT_NET_RX  5
   11.21 -#define _EVENT_NET2_TX 6
   11.22 -#define _EVENT_NET2_RX 7
   11.23 +#define _EVENT_DEBUG   6
   11.24  
   11.25  #define _EVENT_NET_TX_FOR_VIF(x)    (_EVENT_NET_TX + (2 * x))
   11.26  #define _EVENT_NET_RX_FOR_VIF(x)    (_EVENT_NET_RX + (2 * x))
   11.27  
   11.28 +
   11.29  /*
   11.30   * NB. We expect that this struct is smaller than a page.
   11.31   */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/xen-2.4.16/include/xeno/keyhandler.h	Fri Feb 14 11:58:16 2003 +0000
    12.3 @@ -0,0 +1,16 @@
    12.4 +/* 
    12.5 +** We keep an array of 'handlers' for each key code between 0 and 255; 
    12.6 +** this is intended to allow very simple debugging routines (toggle 
    12.7 +** debug flag, dump registers, reboot, etc) to be hooked in in a slightly
    12.8 +** nicer fashion than just editing the serial/keyboard drivers. 
    12.9 +*/
   12.10 +#include <xeno/sched.h>
   12.11 +
   12.12 +typedef void key_handler(unsigned char key, void *dev_id, 
   12.13 +			 struct pt_regs *regs); 
   12.14 +
   12.15 +extern void add_key_handler(unsigned char key, 
   12.16 +			    key_handler *handler, char *desc); 
   12.17 +
   12.18 +extern key_handler *get_key_handler(unsigned char key); 
   12.19 +
    13.1 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c	Thu Feb 13 14:51:10 2003 +0000
    13.2 +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c	Fri Feb 14 11:58:16 2003 +0000
    13.3 @@ -30,19 +30,21 @@ typedef unsigned char	byte;
    13.4  
    13.5  void xlblk_ide_register_disk(int, unsigned long);
    13.6  
    13.7 -#define XLBLK_MAX 2                                        /* very arbitrary */
    13.8 -#define XLBLK_MAJOR_NAME "blk"
    13.9 +#define XLBLK_MAX 2                                /* very arbitrary */
   13.10 +#define XLBLK_MAJOR_NAME "xhd"
   13.11  #define IDE_PARTN_BITS 6                           /* from ide.h::PARTN_BITS */
   13.12  #define IDE_PARTN_MASK ((1<<IDE_PARTN_BITS)-1)     /* from ide.h::PARTN_MASK */
   13.13  static int xlblk_blk_size[XLBLK_MAX];
   13.14  static int xlblk_blksize_size[XLBLK_MAX];
   13.15 +static int xlblk_read_ahead; 
   13.16  static int xlblk_hardsect_size[XLBLK_MAX];
   13.17 -static int xlblk_read_ahead[XLBLK_MAX];
   13.18  static int xlblk_max_sectors[XLBLK_MAX];
   13.19  
   13.20  #define XLBLK_RX_IRQ _EVENT_BLK_RX
   13.21  #define XLBLK_TX_IRQ _EVENT_BLK_TX
   13.22  
   13.23 +#define DEBUG_IRQ    _EVENT_DEBUG 
   13.24 +
   13.25  typedef struct xlblk_device
   13.26  {
   13.27    struct buffer_head *bh;
   13.28 @@ -51,11 +53,6 @@ typedef struct xlblk_device
   13.29  
   13.30  xlblk_device_t xlblk_device;
   13.31  
   13.32 -/* USE_REQUEST_QUEUE = 1  use (multiple) request queues
   13.33 - *                   = 0  don't use IO request queue 
   13.34 - */
   13.35 -#define USE_REQUEST_QUEUE 1
   13.36 -
   13.37  #define XLBLK_DEBUG       0
   13.38  #define XLBLK_DEBUG_IOCTL 0
   13.39  
   13.40 @@ -80,130 +77,106 @@ void hypervisor_request(void *         i
   13.41  
   13.42  static int xenolinux_block_open(struct inode *inode, struct file *filep)
   13.43  {
   13.44 -  if (XLBLK_DEBUG) {
   13.45 -    printk (KERN_ALERT "xenolinux_block_open\n"); }
   13.46 -  return 0;
   13.47 +    if (XLBLK_DEBUG)
   13.48 +	printk (KERN_ALERT "xenolinux_block_open\n"); 
   13.49 +
   13.50 +    return 0;
   13.51  }
   13.52  
   13.53  static int xenolinux_block_release(struct inode *inode, struct file *filep)
   13.54  {
   13.55 -  if (XLBLK_DEBUG) {
   13.56 -    printk (KERN_ALERT "xenolinux_block_release\n"); }
   13.57 -  return 0;
   13.58 +    if (XLBLK_DEBUG)
   13.59 +	printk (KERN_ALERT "xenolinux_block_release\n");
   13.60 +
   13.61 +    return 0;
   13.62  }
   13.63  
   13.64  static int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
   13.65  			  unsigned command, unsigned long argument)
   13.66  {
   13.67 -  int minor_dev;
   13.68 +    int minor_dev;
   13.69 +    struct hd_geometry *geo = (struct hd_geometry *)argument;
   13.70  
   13.71 -  if (XLBLK_DEBUG_IOCTL)
   13.72 -  {
   13.73 -    printk (KERN_ALERT "xenolinux_block_ioctl\n"); 
   13.74 -  }
   13.75 +    if (XLBLK_DEBUG_IOCTL)
   13.76 +	printk (KERN_ALERT "xenolinux_block_ioctl\n"); 
   13.77  
   13.78 -  /* check permissions */
   13.79 -  if (!capable(CAP_SYS_ADMIN)) return -EPERM;
   13.80 -  if (!inode)                  return -EINVAL;
   13.81 -  minor_dev = MINOR(inode->i_rdev);
   13.82 -  if (minor_dev >= XLBLK_MAX)  return -ENODEV;
   13.83 -
   13.84 -  if (XLBLK_DEBUG_IOCTL)
   13.85 -  {
   13.86 -    printk (KERN_ALERT  
   13.87 -	    "   command: 0x%x, argument: 0x%lx, minor: 0x%x\n",
   13.88 -	    command, (long) argument, minor_dev); 
   13.89 -  }
   13.90 +    /* check permissions */
   13.91 +    if (!capable(CAP_SYS_ADMIN)) return -EPERM;
   13.92 +    if (!inode)                  return -EINVAL;
   13.93 +    minor_dev = MINOR(inode->i_rdev);
   13.94 +    if (minor_dev >= XLBLK_MAX)  return -ENODEV;
   13.95 +    
   13.96 +    if (XLBLK_DEBUG_IOCTL)
   13.97 +	printk (KERN_ALERT "   command: 0x%x, argument: 0x%lx, minor: 0x%x\n",
   13.98 +		command, (long) argument, minor_dev); 
   13.99    
  13.100 -  switch (command)
  13.101 -  {
  13.102 -    case BLKGETSIZE :
  13.103 -    {
  13.104 -      if (XLBLK_DEBUG_IOCTL)
  13.105 -      {
  13.106 -	printk (KERN_ALERT
  13.107 -		"   BLKGETSIZE: %x %lx\n", BLKGETSIZE, 
  13.108 -		(long) xen_disk_info.disks[0].capacity); 
  13.109 -      }
  13.110 -      return put_user(xen_disk_info.disks[0].capacity, 
  13.111 -		      (unsigned long *) argument);
  13.112 -    }
  13.113 -    case BLKRRPART :
  13.114 -    {
  13.115 -      if (XLBLK_DEBUG_IOCTL) {
  13.116 -	printk (KERN_ALERT "   BLKRRPART: %x\n", BLKRRPART); }
  13.117 -      break;
  13.118 -    }
  13.119 -    case BLKSSZGET :
  13.120 -    {
  13.121 -      if (XLBLK_DEBUG_IOCTL) {
  13.122 -	printk (KERN_ALERT "   BLKSSZGET: %x 0x%x\n", BLKSSZGET,
  13.123 -		xlblk_hardsect_size[minor_dev]); }
  13.124 -      return xlblk_hardsect_size[minor_dev]; 
  13.125 +    switch (command) {
  13.126 +
  13.127 +    case BLKGETSIZE:
  13.128 +	if (XLBLK_DEBUG_IOCTL) 
  13.129 +	    printk (KERN_ALERT
  13.130 +		    "   BLKGETSIZE: %x %lx\n", BLKGETSIZE, 
  13.131 +		    (long) xen_disk_info.disks[0].capacity); 
  13.132 +	return put_user(xen_disk_info.disks[0].capacity, 
  13.133 +			(unsigned long *) argument);
  13.134 +
  13.135 +    case BLKRRPART:
  13.136 +	if (XLBLK_DEBUG_IOCTL)
  13.137 +	    printk (KERN_ALERT "   BLKRRPART: %x\n", BLKRRPART); 
  13.138 +	break;
  13.139 +
  13.140 +    case BLKSSZGET:
  13.141 +	if (XLBLK_DEBUG_IOCTL)
  13.142 +	    printk (KERN_ALERT "   BLKSSZGET: %x 0x%x\n", BLKSSZGET,
  13.143 +		    xlblk_hardsect_size[minor_dev]);
  13.144 +	return xlblk_hardsect_size[minor_dev]; 
  13.145 +
  13.146 +    case HDIO_GETGEO:
  13.147 +
  13.148 +	if (XLBLK_DEBUG_IOCTL)
  13.149 +	    printk (KERN_ALERT "   HDIO_GETGEO: %x\n", HDIO_GETGEO);
  13.150 +
  13.151 +	if (!argument) return -EINVAL;
  13.152 +	if (put_user(0x00,  (unsigned long *) &geo->start)) return -EFAULT;
  13.153 +	if (put_user(0xff,  (byte *)&geo->heads)) return -EFAULT;
  13.154 +	if (put_user(0x3f,  (byte *)&geo->sectors)) return -EFAULT;
  13.155 +	if (put_user(0x106, (unsigned short *)&geo->cylinders)) return -EFAULT;
  13.156 +	return 0;
  13.157 +
  13.158 +    case HDIO_GETGEO_BIG: 
  13.159 +
  13.160 +	if (XLBLK_DEBUG_IOCTL) 
  13.161 +	    printk (KERN_ALERT "   HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG);
  13.162 +
  13.163 +	if (!argument) return -EINVAL;
  13.164 +	if (put_user(0x00,  (unsigned long *) &geo->start))  return -EFAULT;
  13.165 +	if (put_user(0xff,  (byte *)&geo->heads))   return -EFAULT;
  13.166 +	if (put_user(0x3f,  (byte *)&geo->sectors)) return -EFAULT;
  13.167 +	if (put_user(0x106, (unsigned int *) &geo->cylinders)) return -EFAULT;
  13.168 +
  13.169 +	return 0;
  13.170 +
  13.171 +    default:
  13.172 +	if (XLBLK_DEBUG_IOCTL) 
  13.173 +	    printk (KERN_ALERT "   eh? unknown ioctl\n");
  13.174 +	break;
  13.175      }
  13.176 -    case HDIO_GETGEO :
  13.177 -    {
  13.178 -      struct hd_geometry *geo = (struct hd_geometry *)argument;
  13.179 -
  13.180 -      if (XLBLK_DEBUG_IOCTL) {
  13.181 -	printk (KERN_ALERT "   HDIO_GETGEO: %x\n", HDIO_GETGEO); }
  13.182 -
  13.183 -      if (!argument) return -EINVAL;
  13.184 -      /*
  13.185 -      if (put_user(0x80,  (byte *)&geo->heads)) return -EFAULT;
  13.186 -      if (put_user(0x3f,  (byte *)&geo->sectors)) return -EFAULT;
  13.187 -      if (put_user(0x20b, (unsigned short *) &geo->cylinders)) return -EFAULT;
  13.188 -      */
  13.189 -      if (put_user(0x00,  (unsigned long *) &geo->start)) return -EFAULT;
  13.190 -      if (put_user(0xff,  (byte *)&geo->heads)) return -EFAULT;
  13.191 -      if (put_user(0x3f,  (byte *)&geo->sectors)) return -EFAULT;
  13.192 -      if (put_user(0x106, (unsigned short *) &geo->cylinders)) return -EFAULT;
  13.193 -
  13.194 -      return 0;
  13.195 -    }
  13.196 -    case HDIO_GETGEO_BIG :
  13.197 -    {
  13.198 -      struct hd_big_geometry *geo = (struct hd_big_geometry *) argument;
  13.199 -
  13.200 -      if (XLBLK_DEBUG_IOCTL) {
  13.201 -	printk (KERN_ALERT "   HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG); }
  13.202 -
  13.203 -      if (!argument) return -EINVAL;
  13.204 -      /*
  13.205 -      if (put_user(0x80,  (byte *)&geo->heads))   return -EFAULT;
  13.206 -      if (put_user(0x3f,  (byte *)&geo->sectors)) return -EFAULT;
  13.207 -      if (put_user(0x20b, (unsigned int *) &geo->cylinders)) return -EFAULT;
  13.208 -      */
  13.209 -      if (put_user(0x00,  (unsigned long *) &geo->start))  return -EFAULT;
  13.210 -      if (put_user(0xff,  (byte *)&geo->heads))   return -EFAULT;
  13.211 -      if (put_user(0x3f,  (byte *)&geo->sectors)) return -EFAULT;
  13.212 -      if (put_user(0x106, (unsigned int *) &geo->cylinders)) return -EFAULT;
  13.213 -
  13.214 -      return 0;
  13.215 -    }
  13.216 -    default :
  13.217 -    {
  13.218 -      if (XLBLK_DEBUG_IOCTL) {
  13.219 -	printk (KERN_ALERT "   eh? unknown ioctl\n"); }
  13.220 -      break;
  13.221 -    }
  13.222 -  }
  13.223 -
  13.224 -  return 0;
  13.225 +    
  13.226 +    return 0;
  13.227  }
  13.228  
  13.229  static int xenolinux_block_check(kdev_t dev)
  13.230  {
  13.231 -  if (XLBLK_DEBUG) {
  13.232 -    printk (KERN_ALERT "xenolinux_block_check\n"); }
  13.233 -  return 0;
  13.234 +    if (XLBLK_DEBUG) 
  13.235 +      printk (KERN_ALERT "xenolinux_block_check\n");
  13.236 +    return 0;
  13.237  }
  13.238  
  13.239  static int xenolinux_block_revalidate(kdev_t dev)
  13.240  {
  13.241 -  if (XLBLK_DEBUG) {
  13.242 -    printk (KERN_ALERT "xenolinux_block_revalidate\n"); }
  13.243 -  return 0;
  13.244 +    if (XLBLK_DEBUG) 
  13.245 +	printk (KERN_ALERT "xenolinux_block_revalidate\n"); 
  13.246 +    return 0;
  13.247  }
  13.248  
  13.249  /*
  13.250 @@ -230,110 +203,88 @@ void hypervisor_request(void *         i
  13.251  			kdev_t         device,
  13.252  			int            mode)
  13.253  {
  13.254 -  blk_ring_t *blk_ring = start_info.blk_ring;
  13.255 -  int position;
  13.256 -  void *buffer_pa, *buffer_ma; 
  13.257 -  kdev_t phys_device = (kdev_t) 0;
  13.258 -  unsigned long sector_number = 0;
  13.259 +    blk_ring_t *blk_ring = start_info.blk_ring;
  13.260 +    int position;
  13.261 +    void *buffer_pa, *buffer_ma; 
  13.262 +    kdev_t phys_device = (kdev_t) 0;
  13.263 +    unsigned long sector_number = 0;
  13.264 +    struct gendisk *gd; 
  13.265 +    
  13.266  
  13.267 -#if 0
  13.268 -  printk(KERN_ALERT "[%x]", id); 
  13.269 -  printk (KERN_ALERT
  13.270 -	  "xlblk_req: id:%p op:%d, bf:%p, blk:%lu, sz:%u, dev:%x\n",
  13.271 -	  id, operation, buffer, block_number, block_size, device);
  13.272 -#endif
  13.273 +    buffer_pa = (void *)virt_to_phys(buffer); 
  13.274 +    buffer_ma = (void *)phys_to_machine((unsigned long)buffer_pa); 
  13.275  
  13.276 -  /* XXX SMH: now need to convert guest virtual address to machine address */
  13.277 -  buffer_pa = (void *)virt_to_phys((unsigned long)buffer); 
  13.278 -  buffer_ma = (void *)phys_to_machine((unsigned long)buffer_pa); 
  13.279 +    if (operation == XEN_BLOCK_PROBE) {
  13.280 +	phys_device = (kdev_t) 0;
  13.281 +	sector_number = 0;
  13.282  
  13.283 -#if 0
  13.284 -  printk(KERN_ALERT "va %p => pa %p => ma %p\n", buffer, buffer_pa, buffer_ma);
  13.285 -#endif
  13.286 +    } else if (operation == XEN_BLOCK_READ || operation == XEN_BLOCK_WRITE) {
  13.287  
  13.288 -  if (operation == XEN_BLOCK_PROBE)
  13.289 -  {
  13.290 -    phys_device = (kdev_t) 0;
  13.291 -    sector_number = 0;
  13.292 -  }
  13.293 -  else if (operation == XEN_BLOCK_READ || operation == XEN_BLOCK_WRITE)
  13.294 -  {
  13.295 -    /*
  13.296 -     * map logial major device to the physical device number 
  13.297 -     *
  13.298 -     *           XLBLK_MAJOR -> IDE0_MAJOR  (123 -> 3)
  13.299 -     */
  13.300 -    if (MAJOR(device) == XLBLK_MAJOR)
  13.301 -    {
  13.302 -      phys_device = MKDEV(IDE0_MAJOR, 0);
  13.303 -    }
  13.304 -    else
  13.305 -    {
  13.306 -      printk (KERN_ALERT
  13.307 -	      "error: xl_block::hypervisor_request: unknown device [0x%x]\n", 
  13.308 -	      device);
  13.309 -      BUG();
  13.310 -    }
  13.311 -  
  13.312 -    /*
  13.313 -     * compute real buffer location on disk
  13.314 -     * (from ll_rw_block.c::submit_bh)
  13.315 -     */
  13.316 -    {
  13.317 -      int idx = 0;
  13.318 +	/*
  13.319 +	 * map logial major device to the physical device number 
  13.320 +	 *
  13.321 +	 *           XLBLK_MAJOR -> IDE0_MAJOR  (123 -> 3)
  13.322 +	 */
  13.323 +	if (MAJOR(device) == XLBLK_MAJOR) 
  13.324 +	    phys_device = MKDEV(IDE0_MAJOR, 0);
  13.325 +	else {
  13.326 +	    printk (KERN_ALERT "error: xl_block::hypervisor_request: "
  13.327 +		    "unknown device [0x%x]\n", device);
  13.328 +	    BUG();
  13.329 +	}
  13.330 +
  13.331 +	/*
  13.332 +	 * compute real buffer location on disk
  13.333 +	 * (from ll_rw_block.c::submit_bh)
  13.334 +	 */
  13.335 +
  13.336 +
  13.337 +	sector_number = block_number /* * block_size >> 9 */;
  13.338  
  13.339 -      struct gendisk *gd = (struct gendisk *) xen_disk_info.disks[idx].gendisk;
  13.340 -      unsigned int minor = MINOR(device);
  13.341 +	if((gd = (struct gendisk *)xen_disk_info.disks[0].gendisk) != NULL)
  13.342 +	    sector_number += gd->part[MINOR(device)&IDE_PARTN_MASK].start_sect;
  13.343 +    }
  13.344  
  13.345 -      sector_number = block_number /* * block_size >> 9 */;
  13.346  
  13.347 -      if (gd != NULL)                     /* if we have a partition table... */
  13.348 -      {
  13.349 -	sector_number += gd->part[minor & IDE_PARTN_MASK].start_sect;
  13.350 -      }
  13.351 +    if (BLK_TX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons) {
  13.352 +	printk (KERN_ALERT "hypervisor_request: btx_cons: %d, btx_prod:%d",
  13.353 +		blk_ring->btx_cons, blk_ring->btx_prod);
  13.354 +	BUG(); 
  13.355      }
  13.356 -  }
  13.357 -
  13.358 -  /*
  13.359 -   * CHECK TO SEE IF THERE IS SPACE IN THE RING
  13.360 -   */
  13.361 -  if (BLK_TX_RING_INC(blk_ring->tx_prod) == blk_ring->tx_cons)
  13.362 -  {
  13.363 -    printk (KERN_ALERT "hypervisor_request: tx_cons: %d, tx_prod:%d",
  13.364 -	    blk_ring->tx_cons, blk_ring->tx_prod);
  13.365 -  }
  13.366 +    
  13.367 +    /* Fill out a communications ring structure & trap to the hypervisor */
  13.368 +    position = blk_ring->btx_prod;
  13.369 +    blk_ring->btx_ring[position].id            = id;
  13.370 +    blk_ring->btx_ring[position].priority      = mode;
  13.371 +    blk_ring->btx_ring[position].operation     = operation;
  13.372 +    blk_ring->btx_ring[position].buffer        = buffer_ma;
  13.373 +    blk_ring->btx_ring[position].block_number  = block_number;
  13.374 +    blk_ring->btx_ring[position].block_size    = block_size;
  13.375 +    blk_ring->btx_ring[position].device        = phys_device;
  13.376 +    blk_ring->btx_ring[position].sector_number = sector_number;
  13.377  
  13.378 -  /* fill out a communications ring structure 
  13.379 -     and then trap into the hypervisor */
  13.380 -  position = blk_ring->tx_prod;
  13.381 -  blk_ring->tx_ring[position].id            = id;
  13.382 -  blk_ring->tx_ring[position].priority      = mode;
  13.383 -  blk_ring->tx_ring[position].operation     = operation;
  13.384 -  blk_ring->tx_ring[position].buffer        = buffer_ma;
  13.385 -  blk_ring->tx_ring[position].block_number  = block_number;
  13.386 -  blk_ring->tx_ring[position].block_size    = block_size;
  13.387 -  blk_ring->tx_ring[position].device        = phys_device;
  13.388 -  blk_ring->tx_ring[position].sector_number = sector_number;
  13.389 +    blk_ring->btx_prod = BLK_TX_RING_INC(blk_ring->btx_prod);
  13.390 +
  13.391 +    switch(mode) { 
  13.392  
  13.393 -  blk_ring->tx_prod = BLK_TX_RING_INC(blk_ring->tx_prod);
  13.394 +    case XEN_BLOCK_SYNC:  
  13.395 +	/* trap into hypervisor */
  13.396 +	HYPERVISOR_block_io_op();
  13.397 +	break; 
  13.398  
  13.399 -  if (mode == XEN_BLOCK_SYNC)
  13.400 -  {
  13.401 -    /* trap into hypervisor */
  13.402 -    HYPERVISOR_block_io_op();
  13.403 -  }
  13.404 -  else if (mode == XEN_BLOCK_ASYNC)
  13.405 -  {
  13.406 -    /* for now, do nothing.  the request will go in the ring and
  13.407 -       the next sync request will trigger the hypervisor to act */
  13.408 -  }
  13.409 -  else
  13.410 -  {
  13.411 -    /* ummm, unknown mode. */
  13.412 -    BUG();
  13.413 -  }
  13.414 +    case XEN_BLOCK_ASYNC:
  13.415 +	/* for now, do nothing.  the request will go in the ring and
  13.416 +	   the next sync request will trigger the hypervisor to act */
  13.417 +	printk("Oh dear-- ASYNC xen block of doom!\n"); 
  13.418 +	break; 
  13.419  
  13.420 -  return;
  13.421 +    default: 
  13.422 +	/* ummm, unknown mode. */
  13.423 +	printk("xl_block thingy: unknown mode %d\n", mode); 
  13.424 +	BUG();
  13.425 +    }
  13.426 +
  13.427 +    return;
  13.428  }
  13.429  
  13.430  
  13.431 @@ -345,138 +296,82 @@ void hypervisor_request(void *         i
  13.432   * TO DO: should probably release the io_request_lock and then re-acquire
  13.433   *        (see LDD p. 338)
  13.434   */
  13.435 -
  13.436  static void do_xlblk_request (request_queue_t *rq)
  13.437  {
  13.438 -  struct request *req;
  13.439 -
  13.440 -  if (XLBLK_DEBUG)
  13.441 -  {
  13.442 -    printk (KERN_ALERT "xlblk.c::do_xlblk_request for '%s'\n", DEVICE_NAME); 
  13.443 -  }
  13.444 -
  13.445 -  while (!QUEUE_EMPTY)
  13.446 -  {
  13.447 -    struct buffer_head *bh;
  13.448 -    unsigned long offset;
  13.449 -    unsigned long length;
  13.450 -    int rw;
  13.451 -
  13.452 -    req = CURRENT;
  13.453 -
  13.454 +    struct request *req;
  13.455 +    
  13.456      if (XLBLK_DEBUG)
  13.457 +	printk (KERN_ALERT "xlblk.c::do_xlblk_request for '%s'\n", 
  13.458 +		DEVICE_NAME); 
  13.459 +    
  13.460 +    while (!QUEUE_EMPTY)
  13.461      {
  13.462 -      printk (KERN_ALERT
  13.463 -	      "do_xlblk_request %p: cmd %i, sec %lx, (%li) bh:%p\n",
  13.464 -	      req, req->cmd, req->sector,
  13.465 -	      req->current_nr_sectors, req->bh);
  13.466 -    }
  13.467 +	struct buffer_head *bh;
  13.468 +	unsigned long offset;
  13.469 +	unsigned long length;
  13.470 +	int rw;
  13.471 +	
  13.472 +	if(rq->plugged) 
  13.473 +	    return ; 
  13.474 +	
  13.475 +	req = CURRENT;
  13.476 +	
  13.477 +	if (XLBLK_DEBUG) 
  13.478 +	    printk (KERN_ALERT
  13.479 +		    "do_xlblk_request %p: cmd %i, sec %lx, (%li) bh:%p\n",
  13.480 +		    req, req->cmd, req->sector,
  13.481 +		    req->current_nr_sectors, req->bh);
  13.482 +	
  13.483 +	/* is there space in the tx ring for this request?
  13.484 +	 * if the ring is full, then leave the request in the queue
  13.485 +	 *
  13.486 +	 * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING BTX_CONS
  13.487 +	 * AT THE SAME TIME
  13.488 +	 */
  13.489 +	{
  13.490 +	    blk_ring_t *blk_ring = start_info.blk_ring;
  13.491 +	    
  13.492 +	    if (BLK_RX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons)
  13.493 +	    {
  13.494 +		printk (KERN_ALERT "OOPS, TX LOOKS FULL  cons: %d  prod: %d\n",
  13.495 +			blk_ring->btx_cons, blk_ring->btx_prod);
  13.496 +		BUG(); 
  13.497 +		break;
  13.498 +	    }
  13.499 +	}
  13.500 +	
  13.501 +	req->errors = 0;
  13.502 +	blkdev_dequeue_request(req);
  13.503 +	
  13.504 +	bh = req->bh;
  13.505 +	
  13.506 +	while (bh)
  13.507 +	{
  13.508 +	    offset = bh->b_rsector << 9;
  13.509 +	    length = bh->b_size;
  13.510 +	    
  13.511 +	    rw = req->cmd;
  13.512 +	    if (rw == READA)  rw= READ;
  13.513 +	    if ((rw != READ) && (rw != WRITE)) {
  13.514 +		printk (KERN_ALERT
  13.515 +			"XenoLinux Virtual Block Device: bad cmd: %d\n", rw);
  13.516 +		BUG();
  13.517 +	    }
  13.518  
  13.519 -    /* is there space in the tx ring for this request?
  13.520 -     * if the ring is full, then leave the request in the queue
  13.521 -     *
  13.522 -     * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING TX_CONS
  13.523 -     * AT THE SAME TIME
  13.524 -     */
  13.525 -    {
  13.526 -      blk_ring_t *blk_ring = start_info.blk_ring;
  13.527 -      
  13.528 -      if (BLK_RX_RING_INC(blk_ring->tx_prod) == blk_ring->tx_cons)
  13.529 -      {
  13.530 -	printk (KERN_ALERT "OOPS, TX LOOKS FULL  cons: %d  prod: %d\n",
  13.531 -		blk_ring->tx_cons, blk_ring->tx_prod);
  13.532 -	break;
  13.533 -      }
  13.534 -    }
  13.535 +	    hypervisor_request (req, rw == READ ? 
  13.536 +				XEN_BLOCK_READ : XEN_BLOCK_WRITE, 
  13.537 +				bh->b_data, bh->b_rsector, bh->b_size, 
  13.538 +				bh->b_dev, XEN_BLOCK_SYNC);
  13.539 +	    bh = bh->b_reqnext;
  13.540 +	}
  13.541  
  13.542 -    req->errors = 0;
  13.543 -    blkdev_dequeue_request(req);
  13.544 -
  13.545 -    bh = req->bh;
  13.546 -
  13.547 -    while (bh)
  13.548 -    {
  13.549 +	blkdev_dequeue_request(req);
  13.550  
  13.551 -    offset = bh->b_rsector << 9;
  13.552 -    length = bh->b_size;
  13.553 -    
  13.554 -    rw = req->cmd;
  13.555 -    if (rw == READA)  rw= READ;
  13.556 -    if ((rw != READ) && (rw != WRITE))
  13.557 -    {
  13.558 -      printk (KERN_ALERT
  13.559 -	      "XenoLinux Virtual Block Device: bad command: %d\n", rw);
  13.560 -      BUG();
  13.561      }
  13.562  
  13.563 -    /*
  13.564 -    if (XLBLK_DEBUG)
  13.565 -    {
  13.566 -      printk (KERN_ALERT "xlblk.c::do_xlblk_request\n");
  13.567 -      printk (KERN_ALERT "  b_blocknr: 0x%lx %ld\n", 
  13.568 -                         bh->b_blocknr, bh->b_blocknr);
  13.569 -      printk (KERN_ALERT "  b_size:    0x%x  %d\n", bh->b_size, bh->b_size);
  13.570 -      printk (KERN_ALERT "  b_dev:     0x%x  %d\n", bh->b_dev, bh->b_dev);
  13.571 -      printk (KERN_ALERT "  b_rsector: 0x%lx %ld\n", 
  13.572 -                         bh->b_rsector, bh->b_rsector);
  13.573 -    }
  13.574 -    */
  13.575 -
  13.576 -    hypervisor_request (req, rw == READ ? XEN_BLOCK_READ : XEN_BLOCK_WRITE, 
  13.577 -			bh->b_data, bh->b_rsector, bh->b_size, 
  13.578 -			bh->b_dev, XEN_BLOCK_SYNC);
  13.579 -
  13.580 -      bh = bh->b_reqnext;
  13.581 -    }
  13.582 -  }
  13.583 -
  13.584 -  return;
  13.585 +    return;
  13.586  }
  13.587  
  13.588 -/*
  13.589 - * xenolinux_block_request
  13.590 - *
  13.591 - * read a block without using a request queue
  13.592 - */
  13.593 -
  13.594 -static int xenolinux_block_request(request_queue_t *rq,
  13.595 -				   int rw,
  13.596 -				   struct buffer_head *bh)
  13.597 -{
  13.598 -  unsigned int minor;
  13.599 -  unsigned long offset;
  13.600 -  unsigned long length;
  13.601 -
  13.602 -  if (XLBLK_DEBUG) {
  13.603 -    printk (KERN_ALERT "xlblk.c::xenolinux_block_request: %lx %d %lx\n",
  13.604 -	    (unsigned long) rq, rw, (unsigned long) bh); }
  13.605 -  /*
  13.606 -  printk (KERN_ALERT "xlblk.c::xlblk_request: op:%d bh:%p sect:%lu sz:%u\n",
  13.607 -	  rw,  bh, bh->b_rsector, bh->b_size);
  13.608 -  */
  13.609 -
  13.610 -  minor = MINOR(bh->b_rdev);
  13.611 -
  13.612 -  offset = bh->b_rsector << 9;
  13.613 -  length = bh->b_size;
  13.614 -
  13.615 -  if (rw == READA)  rw= READ;
  13.616 -  if ((rw != READ) && (rw != WRITE))
  13.617 -  {
  13.618 -    printk (KERN_ALERT 
  13.619 -	    "XenoLinux Virtual Block Device: bad command: %d\n", rw);
  13.620 -    goto fail;
  13.621 -  }
  13.622 -
  13.623 -  hypervisor_request (bh, rw == READ ? XEN_BLOCK_READ : XEN_BLOCK_WRITE, 
  13.624 -		      bh->b_data, bh->b_rsector, bh->b_size, 
  13.625 -		      bh->b_dev, XEN_BLOCK_SYNC);
  13.626 -
  13.627 -  return 0;
  13.628 -
  13.629 - fail:
  13.630 -  return 0;
  13.631 -}
  13.632  
  13.633  static struct block_device_operations xenolinux_block_fops = 
  13.634  {
  13.635 @@ -489,335 +384,208 @@ static struct block_device_operations xe
  13.636  
  13.637  static void xlblk_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
  13.638  {
  13.639 -  xlblk_device_t *dev = (xlblk_device_t *)dev_id;
  13.640 -  blk_ring_t *blk_ring = start_info.blk_ring;
  13.641 -  struct buffer_head *bh;
  13.642 -  struct request *req;
  13.643 -  int loop;
  13.644 -
  13.645 -  for (loop = blk_ring->rx_cons;
  13.646 -       loop != blk_ring->rx_prod;
  13.647 -       loop = BLK_RX_RING_INC(loop))
  13.648 -  {
  13.649 -    blk_ring_entry_t *bret = &blk_ring->rx_ring[loop];
  13.650 -    void *buffer_pa, *buffer_va; 
  13.651 -
  13.652 -    buffer_pa = machine_to_phys((unsigned long)bret->buffer); 
  13.653 -    buffer_va = phys_to_virt((unsigned long)buffer_pa); 
  13.654 +    blk_ring_t *blk_ring = start_info.blk_ring;
  13.655 +    struct request *req;
  13.656 +    int loop;
  13.657 +    u_long flags; 
  13.658      
  13.659 -#if 0
  13.660 -    printk(KERN_ALERT "xlblk_rx_int: buffer ma %p => pa %p => va %p\n", 
  13.661 -	   bret->buffer, buffer_pa, buffer_va); 
  13.662 -
  13.663 -
  13.664 -    if (XLBLK_DEBUG)
  13.665 -    {
  13.666 -      printk (KERN_ALERT 
  13.667 -	      "xlblock::xlblk_rx_int [%s]\n",
  13.668 -	      (bret->operation == XEN_BLOCK_READ) ? "read" : "write");
  13.669 -      printk (KERN_ALERT 
  13.670 -	      "   vbuf: %lx, pbuf: %lx, blockno: %lx, size: %x, device %x\n",
  13.671 -	      (unsigned long) buffer_va, (unsigned long) bret->buffer,
  13.672 -	      bret->block_number, bret->block_size, bret->device);
  13.673 -      printk (KERN_ALERT "   bret: %p  bh: %p\n", bret, bret->id); 
  13.674 -    }
  13.675 -
  13.676 -    /*
  13.677 -    printk (KERN_ALERT
  13.678 -	    "xlblk_rx: id:%p op:%d, bf:%p, blk:%lu, sz:%u, dev:%x\n",
  13.679 -	    bret->id, bret->operation, bret->buffer, bret->block_number,
  13.680 -	    bret->block_size, bret->device);
  13.681 -    */
  13.682 -#endif
  13.683 -
  13.684 -    if (USE_REQUEST_QUEUE)
  13.685 -    {
  13.686 -      req = (struct request *)bret->id;
  13.687 -      printk(KERN_ALERT "|%x|", req); 
  13.688 -
  13.689 -      if (!end_that_request_first(req, 1, "NAME"))
  13.690 -      {
  13.691 -	blkdev_dequeue_request(req);
  13.692 -
  13.693 -	/* should be end_that_request_last(req)
  13.694 -	   to wake up waiting processes (with complete) */
  13.695 -	blkdev_release_request(req);
  13.696 -      }
  13.697 +    for (loop = blk_ring->brx_cons;
  13.698 +	 loop != blk_ring->brx_prod;
  13.699 +	 loop = BLK_RX_RING_INC(loop)) {
  13.700  
  13.701 -      /*
  13.702 -	if (XLBLK_DEBUG)
  13.703 -	{
  13.704 -	  int temp;
  13.705 -	  printk(KERN_ALERT 
  13.706 -		 "buff: 0x%p, blkno: 0x%lx, size: 0x%x, device 0x%x [%p]\n",
  13.707 -		 vbuffer, bret->block_number, bret->block_size, bret->device,
  13.708 -		 bh->b_end_io); 
  13.709 +	blk_ring_entry_t *bret = &blk_ring->brx_ring[loop];
  13.710 +	
  13.711 +	if(bret->operation == XEN_BLOCK_PROBE)
  13.712 +	    continue; 
  13.713  
  13.714 -	  for (temp = 0; temp < bret->block_size; temp++)
  13.715 -	  {
  13.716 -	    if (temp % 16 == 0)       printk ("[%4x]  ", temp);
  13.717 -	    else if (temp % 4 == 0)   printk (" ");
  13.718 -	                              printk ("%02x",
  13.719 -					      vbuffer[temp] & 255);
  13.720 -            if ((temp + 1) % 16 == 0) printk ("\n");
  13.721 -	  }
  13.722 -	  printk ("\n\n");
  13.723 -	}
  13.724 -      */
  13.725 -
  13.726 -#ifdef BOGUS
  13.727 -      req = (struct request *)bret->id;
  13.728 -      while ((bh = req->bh) != NULL)
  13.729 -      {
  13.730 -	req->bh = bh->b_reqnext;
  13.731 -	bh->b_reqnext = NULL;
  13.732 -	bh->b_end_io(bh,1);
  13.733 -      }
  13.734 -      blkdev_release_request(req);
  13.735 -#endif /* BOGUS  */
  13.736 +	spin_lock_irqsave(&io_request_lock, flags);
  13.737 +	req = (struct request *)bret->id;
  13.738 +	    
  13.739 +	if (!end_that_request_first(req, 1, "XenBlk"))
  13.740 +	    end_that_request_last(req);
  13.741 +	spin_unlock_irqrestore(&io_request_lock, flags);
  13.742 +	
  13.743      }
  13.744 -    else
  13.745 -    {
  13.746 -      bh = (struct buffer_head *)bret->id;
  13.747 -      bh->b_end_io(bh,1);
  13.748 -
  13.749 -      /*
  13.750 -	if (XLBLK_DEBUG)
  13.751 -	{
  13.752 -	  int temp;
  13.753 -#if 0
  13.754 -	  printk(KERN_ALERT 
  13.755 -		 "buff: 0x%p, blkno: 0x%lx, size: 0x%x, device 0x%x [%p]\n",
  13.756 -		 vbuffer, bret->block_number, bret->block_size, bret->device,
  13.757 -		 bh->b_end_io); 
  13.758 -#endif
  13.759 -
  13.760 -	  for (temp = 0; temp < bret->block_size; temp++)
  13.761 -	  {
  13.762 -	    if (temp % 16 == 0)       printk ("[%4x]  ", temp);
  13.763 -	    else if (temp % 4 == 0)   printk (" ");
  13.764 -	                              printk ("%02x",
  13.765 -					      vbuffer[temp] & 255);
  13.766 -            if ((temp + 1) % 16 == 0) printk ("\n");
  13.767 -	  }
  13.768 -	  printk ("\n\n");
  13.769 -	}
  13.770 -      */    
  13.771 -    }
  13.772 -  }
  13.773 -
  13.774 -  blk_ring->rx_cons = loop;
  13.775 +    
  13.776 +    blk_ring->brx_cons = loop;
  13.777  }
  13.778  
  13.779  static void xlblk_tx_int(int irq, void *dev_id, struct pt_regs *ptregs)
  13.780  {
  13.781 -  if (XLBLK_DEBUG) {
  13.782 -    printk (KERN_ALERT "--- xlblock::xlblk_tx_int\n"); }
  13.783 +    if (XLBLK_DEBUG) 
  13.784 +	printk (KERN_ALERT "--- xlblock::xlblk_tx_int\n"); 
  13.785  }
  13.786  
  13.787  int __init xlblk_init(void)
  13.788  {
  13.789 -  blk_ring_t *blk_ring = start_info.blk_ring;
  13.790 -  int loop, error, result;
  13.791 -
  13.792 -  /*
  13.793 -   * initialize memory rings to communicate with hypervisor 
  13.794 -   */
  13.795 +    blk_ring_t *blk_ring = start_info.blk_ring;
  13.796 +    int loop, error, result;
  13.797  
  13.798 -  if ( blk_ring == NULL ) return -ENOMEM;
  13.799 -
  13.800 -  blk_ring->tx_prod = blk_ring->tx_cons = 0;
  13.801 -  blk_ring->rx_prod = blk_ring->rx_cons = 0;
  13.802 -  blk_ring->tx_ring = NULL;
  13.803 -  blk_ring->rx_ring = NULL;
  13.804 +    /* initialize memory rings to communicate with hypervisor */
  13.805 +    if ( blk_ring == NULL ) return -ENOMEM;
  13.806  
  13.807 -  blk_ring->tx_ring = kmalloc(BLK_TX_RING_SIZE * sizeof(blk_ring_entry_t),
  13.808 -			      GFP_KERNEL);
  13.809 -  blk_ring->rx_ring = kmalloc(BLK_RX_RING_SIZE * sizeof(blk_ring_entry_t),
  13.810 -			      GFP_KERNEL);
  13.811 -
  13.812 -  if ((blk_ring->tx_ring == NULL) ||
  13.813 -      (blk_ring->rx_ring == NULL))
  13.814 -  {
  13.815 -    printk (KERN_ALERT 
  13.816 -	    "error, could not allocate ring memory for block device\n");
  13.817 -    error = -ENOBUFS;
  13.818 -    goto fail;
  13.819 -  }
  13.820 +    blk_ring->btx_prod = blk_ring->btx_cons = 0;
  13.821 +    blk_ring->brx_prod = blk_ring->brx_cons = 0;
  13.822 +    blk_ring->btx_ring = NULL;
  13.823 +    blk_ring->brx_ring = NULL;
  13.824 +    
  13.825 +    blk_ring->btx_ring = kmalloc(BLK_TX_RING_SIZE * sizeof(blk_ring_entry_t),
  13.826 +				 GFP_KERNEL);
  13.827 +    blk_ring->brx_ring = kmalloc(BLK_RX_RING_SIZE * sizeof(blk_ring_entry_t),
  13.828 +				 GFP_KERNEL);
  13.829  
  13.830 -  /*
  13.831 -   * setup soft interrupts to communicate with hypervisor
  13.832 -   */
  13.833 -
  13.834 -  error = request_irq(XLBLK_RX_IRQ, xlblk_rx_int, 0, "xlblk-rx", 
  13.835 -		      &xlblk_device);
  13.836 -  if (error)
  13.837 -  {
  13.838 -    printk(KERN_ALERT "Could not allocate receive interrupt\n");
  13.839 -    goto fail;
  13.840 -  }
  13.841 +    if ((blk_ring->btx_ring == NULL) || (blk_ring->brx_ring == NULL)) {
  13.842 +	printk (KERN_ALERT "could not alloc ring memory for block device\n");
  13.843 +	error = -ENOBUFS;
  13.844 +	goto fail;
  13.845 +    }
  13.846 +    
  13.847 +    error = request_irq(XLBLK_RX_IRQ, xlblk_rx_int, 0, 
  13.848 +			"xlblk-rx", &xlblk_device);
  13.849 +    if (error) {
  13.850 +	printk(KERN_ALERT "Could not allocate receive interrupt\n");
  13.851 +	goto fail;
  13.852 +    }
  13.853  
  13.854 -  error = request_irq(XLBLK_TX_IRQ, xlblk_tx_int, 0, "xlblk-tx", 
  13.855 -		      &xlblk_device);
  13.856 -  if (error)
  13.857 -  {
  13.858 -    printk(KERN_ALERT "Could not allocate transmit interrupt\n");
  13.859 -    free_irq(XLBLK_RX_IRQ, &xlblk_device);
  13.860 -    goto fail;
  13.861 -  }
  13.862 +    error = request_irq(XLBLK_TX_IRQ, xlblk_tx_int, 0, 
  13.863 +			"xlblk-tx", &xlblk_device);
  13.864 +    if (error) {
  13.865 +	printk(KERN_ALERT "Could not allocate transmit interrupt\n");
  13.866 +	free_irq(XLBLK_RX_IRQ, &xlblk_device);
  13.867 +	goto fail;
  13.868 +    }
  13.869  
  13.870 -  /*
  13.871 -   * get information about physical drives
  13.872 -   *
  13.873 -   */
  13.874 -  {
  13.875 -    /* NOTE: this should only occur in domain 0 */
  13.876      memset (&xen_disk_info, 0, sizeof(xen_disk_info));
  13.877      xen_disk_info.count = 0;
  13.878  
  13.879      hypervisor_request(NULL, XEN_BLOCK_PROBE, (char *) &xen_disk_info,
  13.880  		       0, 0, (kdev_t) 0, XEN_BLOCK_SYNC);
  13.881 -
  13.882 -    {
  13.883 -      int loop;
  13.884 -      for (loop = 0; loop < xen_disk_info.count; loop++)
  13.885 -      {
  13.886 +    for (loop = 0; loop < xen_disk_info.count; loop++) 
  13.887  	printk (KERN_ALERT "  %2d: type: %d, capacity: %ld\n",
  13.888  		loop, xen_disk_info.disks[loop].type, 
  13.889  		xen_disk_info.disks[loop].capacity);
  13.890 -      }
  13.891 -    }
  13.892 -  }
  13.893 -
  13.894 -  /*
  13.895 -   * initialize device driver
  13.896 -   */
  13.897  
  13.898 -  SET_MODULE_OWNER(&xenolinux_block_fops);
  13.899 +    
  13.900 +    SET_MODULE_OWNER(&xenolinux_block_fops);
  13.901 +    result = register_blkdev(xlblk_major, "block", &xenolinux_block_fops);
  13.902 +    if (result < 0) {
  13.903 +	printk (KERN_ALERT "xenolinux block: can't get major %d\n",
  13.904 +		xlblk_major);
  13.905 +	return result;
  13.906 +    }
  13.907  
  13.908 -  result = register_blkdev(xlblk_major, "block", &xenolinux_block_fops);
  13.909 -  if (result < 0)
  13.910 -  {
  13.911 -    printk (KERN_ALERT "xenolinux block: can't get major %d\n", xlblk_major);
  13.912 -    return result;
  13.913 -  }
  13.914 +    /* initialize global arrays in drivers/block/ll_rw_block.c */
  13.915 +    for (loop = 0; loop < XLBLK_MAX; loop++) {
  13.916 +	xlblk_blk_size[loop]      = xen_disk_info.disks[0].capacity;
  13.917 +	xlblk_blksize_size[loop]  = 512;
  13.918 +	xlblk_hardsect_size[loop] = 512;
  13.919 +	xlblk_max_sectors[loop]   = 128;
  13.920 +    }
  13.921 +    xlblk_read_ahead  = 8; 
  13.922  
  13.923 -  /* initialize global arrays in drivers/block/ll_rw_block.c */
  13.924 -  blk_size[xlblk_major] = xlblk_blk_size;
  13.925 -  blksize_size[xlblk_major] = xlblk_blksize_size;
  13.926 -  hardsect_size[xlblk_major] = xlblk_hardsect_size;
  13.927 -  read_ahead[xlblk_major] = xlblk_read_ahead;
  13.928 -  max_sectors[xlblk_major] = xlblk_max_sectors;
  13.929 -  for (loop = 0; loop < XLBLK_MAX; loop++)
  13.930 -  {
  13.931 -    xlblk_blk_size[loop] = xen_disk_info.disks[0].capacity;
  13.932 -    xlblk_blksize_size[loop] = 512;
  13.933 -    xlblk_hardsect_size[loop] = 512;
  13.934 -    xlblk_read_ahead[loop] = 8; 
  13.935 -    xlblk_max_sectors[loop] = 128;
  13.936 -  }
  13.937 +    blk_size[xlblk_major]      = xlblk_blk_size;
  13.938 +    blksize_size[xlblk_major]  = xlblk_blksize_size;
  13.939 +    hardsect_size[xlblk_major] = xlblk_hardsect_size;
  13.940 +    read_ahead[xlblk_major]    = xlblk_read_ahead; 
  13.941 +    max_sectors[xlblk_major]   = xlblk_max_sectors;
  13.942  
  13.943 -  if (USE_REQUEST_QUEUE)
  13.944 -  {
  13.945 -    /* NEED TO MODIFY THIS TO HANDLE MULTIPLE QUEUES
  13.946 -     * also, should replace do_xlblk_request with blk.h::DEVICE_REQUEST
  13.947 -     */
  13.948      blk_init_queue(BLK_DEFAULT_QUEUE(xlblk_major), do_xlblk_request);
  13.949 +    /* 
  13.950 +    ** XXX SMH: we don't leave req on queue => are happy for evelator
  13.951 +    ** to reorder things including it. (main reason for this decision
  13.952 +    ** is that it works while 'standard' case doesn't. Ho hum). 
  13.953 +    */
  13.954      blk_queue_headactive(BLK_DEFAULT_QUEUE(xlblk_major), 0);
  13.955 -  }
  13.956 -  else
  13.957 -  {
  13.958 -    /* we don't use __make_request in ll_rw_blk */
  13.959 -    blk_queue_make_request(BLK_DEFAULT_QUEUE(xlblk_major), 
  13.960 -			   xenolinux_block_request);
  13.961 -  }
  13.962 -  xlblk_ide_register_disk(0, xen_disk_info.disks[0].capacity);
  13.963 +
  13.964 +    xlblk_ide_register_disk(0, xen_disk_info.disks[0].capacity);
  13.965  
  13.966 -  /*
  13.967 -   * completion 
  13.968 -   */
  13.969 -  printk(KERN_ALERT 
  13.970 -	 "XenoLinux Virtual Block Device Driver installed [device: %d]\n",
  13.971 -	 xlblk_major);
  13.972 -  return 0;
  13.973 +    printk(KERN_ALERT 
  13.974 +	   "XenoLinux Virtual Block Device Driver installed [device: %d]\n",
  13.975 +	   xlblk_major);
  13.976 +    return 0;
  13.977  
  13.978   fail:
  13.979 -  if (blk_ring->tx_ring) kfree(blk_ring->tx_ring);
  13.980 -  if (blk_ring->rx_ring) kfree(blk_ring->rx_ring);
  13.981 -  return error;
  13.982 +    if (blk_ring->btx_ring) kfree(blk_ring->btx_ring);
  13.983 +    if (blk_ring->brx_ring) kfree(blk_ring->brx_ring);
  13.984 +    return error;
  13.985  }
  13.986  
  13.987  void xlblk_ide_register_disk(int idx, unsigned long capacity)
  13.988  {
  13.989 -  int units;
  13.990 -  int minors;
  13.991 -  struct gendisk *gd;
  13.992 -
  13.993 -  /* plagarized from ide-probe.c::init_gendisk */
  13.994 +    int units;
  13.995 +    int minors;
  13.996 +    struct gendisk *gd;
  13.997  
  13.998 -  units = 2;                                       /* from ide.h::MAX_DRIVES */
  13.999 -
 13.1000 -  minors    = units * (1<<IDE_PARTN_BITS);
 13.1001 -  gd        = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
 13.1002 -  gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
 13.1003 -  gd->part  = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
 13.1004 -  memset(gd->part, 0, minors * sizeof(struct hd_struct));
 13.1005 +    /* plagarized from ide-probe.c::init_gendisk */
 13.1006 +    
 13.1007 +    units = 2; /* from ide.h::MAX_DRIVES */
 13.1008  
 13.1009 -  gd->major       = xlblk_major;                  /* our major device number */
 13.1010 -  gd->major_name  = XLBLK_MAJOR_NAME;          /* treated special in genhd.c */
 13.1011 -  gd->minor_shift = IDE_PARTN_BITS;               /* num bits for partitions */
 13.1012 -  gd->max_p	  = 1<<IDE_PARTN_BITS;         /* 1 + max partitions / drive */
 13.1013 -  gd->nr_real	  = units;                        /* current num real drives */
 13.1014 -  gd->real_devices= NULL;                /* ptr to internal data (was: hwif) */
 13.1015 -  gd->next	  = NULL;                       /* linked list of major devs */
 13.1016 -  gd->fops        = &xenolinux_block_fops;                /* file operations */
 13.1017 -  gd->de_arr      = kmalloc (sizeof *gd->de_arr * units, GFP_KERNEL);
 13.1018 -  gd->flags	  = kmalloc (sizeof *gd->flags * units, GFP_KERNEL);
 13.1019 -  if (gd->de_arr)   memset (gd->de_arr, 0, sizeof *gd->de_arr * units);
 13.1020 -  if (gd->flags)    memset (gd->flags, 0, sizeof *gd->flags * units);
 13.1021 -  add_gendisk(gd);
 13.1022 +    minors    = units * (1<<IDE_PARTN_BITS);
 13.1023 +    gd        = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
 13.1024 +    gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
 13.1025 +    gd->part  = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
 13.1026 +    memset(gd->part, 0, minors * sizeof(struct hd_struct));
 13.1027 +    
 13.1028 +    gd->major        = xlblk_major;  
 13.1029 +    gd->major_name   = XLBLK_MAJOR_NAME;
 13.1030 +    gd->minor_shift  = IDE_PARTN_BITS; 
 13.1031 +    gd->max_p	     = 1<<IDE_PARTN_BITS;
 13.1032 +    gd->nr_real	     = units;           
 13.1033 +    gd->real_devices = NULL;          
 13.1034 +    gd->next	     = NULL;            
 13.1035 +    gd->fops         = &xenolinux_block_fops;
 13.1036 +    gd->de_arr       = kmalloc (sizeof *gd->de_arr * units, GFP_KERNEL);
 13.1037 +    gd->flags	     = kmalloc (sizeof *gd->flags * units, GFP_KERNEL);
 13.1038  
 13.1039 -  xen_disk_info.disks[idx].gendisk = gd;
 13.1040 +    if (gd->de_arr)  
 13.1041 +	memset (gd->de_arr, 0, sizeof *gd->de_arr * units);
 13.1042 +
 13.1043 +    if (gd->flags) 
 13.1044 +	memset (gd->flags, 0, sizeof *gd->flags * units);
 13.1045 +
 13.1046 +    add_gendisk(gd);
 13.1047 +
 13.1048 +    xen_disk_info.disks[idx].gendisk = gd;
 13.1049  
 13.1050 -  /* default disk size is just a big number.  in the future, we
 13.1051 -     need a message to probe the devices to determine the actual size */
 13.1052 -  register_disk(gd, MKDEV(xlblk_major, 0), 1<<IDE_PARTN_BITS,
 13.1053 -		&xenolinux_block_fops, capacity);
 13.1054 +    /* default disk size is just a big number.  in the future, we
 13.1055 +       need a message to probe the devices to determine the actual size */
 13.1056 +    register_disk(gd, MKDEV(xlblk_major, 0), 1<<IDE_PARTN_BITS,
 13.1057 +		  &xenolinux_block_fops, capacity);
 13.1058  
 13.1059 -  return;
 13.1060 +    return;
 13.1061  }
 13.1062  
 13.1063 +
 13.1064 +
 13.1065  static void __exit xlblk_cleanup(void)
 13.1066  {
 13.1067 -  /* CHANGE FOR MULTIQUEUE */
 13.1068 -  blk_cleanup_queue(BLK_DEFAULT_QUEUE(xlblk_major));
 13.1069 +    /* CHANGE FOR MULTIQUEUE */
 13.1070 +    blk_cleanup_queue(BLK_DEFAULT_QUEUE(xlblk_major));
 13.1071 +
 13.1072 +    /* clean up global arrays */
 13.1073 +    read_ahead[xlblk_major] = 0;
 13.1074  
 13.1075 -  /* clean up global arrays */
 13.1076 -  read_ahead[xlblk_major] = 0;
 13.1077 -  if (blk_size[xlblk_major]) kfree(blk_size[xlblk_major]);
 13.1078 -  blk_size[xlblk_major] = NULL;
 13.1079 -  if (blksize_size[xlblk_major]) kfree(blksize_size[xlblk_major]);
 13.1080 -  blksize_size[xlblk_major] = NULL;
 13.1081 -  if (hardsect_size[xlblk_major]) kfree(hardsect_size[xlblk_major]);
 13.1082 -  hardsect_size[xlblk_major] = NULL;
 13.1083 +    if (blk_size[xlblk_major]) 
 13.1084 +	kfree(blk_size[xlblk_major]);
 13.1085 +    blk_size[xlblk_major] = NULL;
 13.1086 +
 13.1087 +    if (blksize_size[xlblk_major]) 
 13.1088 +	kfree(blksize_size[xlblk_major]);
 13.1089 +    blksize_size[xlblk_major] = NULL;
 13.1090  
 13.1091 -  /*
 13.1092 -   *
 13.1093 -   * TODO: FOR EACH GENDISK, FREE 
 13.1094 -   *
 13.1095 -   */
 13.1096 +    if (hardsect_size[xlblk_major]) 
 13.1097 +	kfree(hardsect_size[xlblk_major]);
 13.1098 +    hardsect_size[xlblk_major] = NULL;
 13.1099 +    
 13.1100 +    /* XXX: free each gendisk */
 13.1101 +    if (unregister_blkdev(xlblk_major, "block"))
 13.1102 +	printk(KERN_ALERT
 13.1103 +	       "XenoLinux Virtual Block Device Driver uninstalled w/ errs\n");
 13.1104 +    else
 13.1105 +	printk(KERN_ALERT 
 13.1106 +	       "XenoLinux Virtual Block Device Driver uninstalled\n");
 13.1107  
 13.1108 -  if (unregister_blkdev(xlblk_major, "block"))
 13.1109 -  {
 13.1110 -    printk(KERN_ALERT
 13.1111 -	   "XenoLinux Virtual Block Device Driver uninstalled with errors\n");
 13.1112 -  }
 13.1113 -  else
 13.1114 -  {
 13.1115 -    printk(KERN_ALERT "XenoLinux Virtual Block Device Driver uninstalled\n");
 13.1116 -  }
 13.1117 -
 13.1118 -  return;
 13.1119 +    return;
 13.1120  }
 13.1121  
 13.1122  
    14.1 --- a/xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c	Thu Feb 13 14:51:10 2003 +0000
    14.2 +++ b/xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c	Fri Feb 14 11:58:16 2003 +0000
    14.3 @@ -533,6 +533,8 @@ static inline void add_request(request_q
    14.4  
    14.5  	if (!q->plugged && q->head_active && insert_here == &q->queue_head) {
    14.6  		spin_unlock_irq(&io_request_lock);
    14.7 +		printk("list_empty(&q->queue_head) is %d\n", 
    14.8 +		       list_empty(&q->queue_head)); 
    14.9  		BUG();
   14.10  	}
   14.11  
   14.12 @@ -771,6 +773,7 @@ get_rq:
   14.13  	req->bhtail = bh;
   14.14  	req->rq_dev = bh->b_rdev;
   14.15  	blk_started_io(count);
   14.16 +
   14.17  	add_request(q, req, insert_here);
   14.18  out:
   14.19  	if (freereq)
    15.1 --- a/xenolinux-2.4.16-sparse/include/linux/blk.h	Thu Feb 13 14:51:10 2003 +0000
    15.2 +++ b/xenolinux-2.4.16-sparse/include/linux/blk.h	Fri Feb 14 11:58:16 2003 +0000
    15.3 @@ -326,7 +326,7 @@ static void floppy_off(unsigned int nr);
    15.4  
    15.5  #elif (MAJOR_NR == XLBLK_MAJOR)
    15.6  
    15.7 -#define DEVICE_NAME "blk"
    15.8 +#define DEVICE_NAME "xeno disk"
    15.9  #define DEVICE_REQUEST do_xlblk_request
   15.10  /* #define DEVICE_INTR */
   15.11  #define DEVICE_NR(device) (MINOR(device))
    16.1 --- a/xenolinux-2.4.16-sparse/init/main.c	Thu Feb 13 14:51:10 2003 +0000
    16.2 +++ b/xenolinux-2.4.16-sparse/init/main.c	Fri Feb 14 11:58:16 2003 +0000
    16.3 @@ -149,7 +149,7 @@ static struct dev_name_struct {
    16.4  	const int num;
    16.5  } root_dev_names[] __initdata = {
    16.6  	{ "nfs",     0x00ff },
    16.7 -        { "blk",     0x7b00 },
    16.8 +    { "xhda",    0x7b00 },
    16.9  	{ "hda",     0x0300 },
   16.10  	{ "hdb",     0x0340 },
   16.11  	{ "loop",    0x0700 },