aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.rootkeys2
-rw-r--r--BitKeeper/etc/ignore1
-rw-r--r--xen-2.4.16/arch/i386/setup.c4
-rw-r--r--xen-2.4.16/common/keyhandler.c125
-rw-r--r--xen-2.4.16/drivers/block/ll_rw_blk.c25
-rw-r--r--xen-2.4.16/drivers/block/xen_block.c749
-rw-r--r--xen-2.4.16/drivers/char/xen_kbd.c165
-rw-r--r--xen-2.4.16/drivers/char/xen_serial.c57
-rw-r--r--xen-2.4.16/drivers/ide/ide-xeno.c61
-rw-r--r--xen-2.4.16/include/hypervisor-ifs/block.h12
-rw-r--r--xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h11
-rw-r--r--xen-2.4.16/include/xeno/keyhandler.h16
-rw-r--r--xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c1026
-rw-r--r--xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c3
-rw-r--r--xenolinux-2.4.16-sparse/include/linux/blk.h2
-rw-r--r--xenolinux-2.4.16-sparse/init/main.c2
16 files changed, 1025 insertions, 1236 deletions
diff --git a/.rootkeys b/.rootkeys
index cb463f80ba..90ea177d49 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -42,6 +42,7 @@
3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen-2.4.16/common/domain_page.c
3ddb79bdeyutmaXEfpQvvxj7eQ0fCw xen-2.4.16/common/event.c
3ddb79bd9drcFPVxd4w2GPOIjLlXpA xen-2.4.16/common/kernel.c
+3e4cd9d8LAAghUY0hNIK72uc2ch_Nw xen-2.4.16/common/keyhandler.c
3ddb79bduhSEZI8xa7IbGQCpap5y2A xen-2.4.16/common/lib.c
3ddb79bdS39UXxUtZnaScie83-7VTQ xen-2.4.16/common/memory.c
3ddb79bdN51qpRC-6bOH-v5hl_AK6A xen-2.4.16/common/network.c
@@ -231,6 +232,7 @@
3ddb79c2b3qe-6Ann09FqZBF4IrJaQ xen-2.4.16/include/xeno/irq_cpustat.h
3ddb79c11w_O7z7YZJnzuDSxaK5LlA xen-2.4.16/include/xeno/kdev_t.h
3e4540ccPHqIIv2pvnQ1gV8LUnoHIg xen-2.4.16/include/xeno/kernel.h
+3e4cd9d8elj_7EgAs9Of56RQ2Yq_4g xen-2.4.16/include/xeno/keyhandler.h
3ddb79c1NfYlOrWNqgZkj9EwtFfJow xen-2.4.16/include/xeno/lib.h
3ddb79c18Ajy7micDGQQfJ0zWgEHtA xen-2.4.16/include/xeno/list.h
3ddb79c0_s2_wgV0cA6tztEaeyy1NA xen-2.4.16/include/xeno/major.h
diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore
index e5be6b0ec8..47b60ce0af 100644
--- a/BitKeeper/etc/ignore
+++ b/BitKeeper/etc/ignore
@@ -19,3 +19,4 @@ xen-2.4.16/include/xeno/sched.h.orig
xenolinux-2.4.16-sparse/arch/xeno/drivers/block/Makefile.orig
xenolinux-2.4.16-sparse/arch/xeno/drivers/block/block.c.orig
xenolinux-2.4.16-sparse/scripts/kconfig.tk
+xen-2.4.16/foo
diff --git a/xen-2.4.16/arch/i386/setup.c b/xen-2.4.16/arch/i386/setup.c
index 57d3f93a7b..d67ec7af78 100644
--- a/xen-2.4.16/arch/i386/setup.c
+++ b/xen-2.4.16/arch/i386/setup.c
@@ -283,6 +283,7 @@ void __init start_of_day(void)
extern int setup_network_devices(void);
extern void net_init(void);
extern void initialize_block_io(void);
+ extern void initialize_keytable();
extern void initialize_serial(void);
extern void initialize_keyboard(void);
@@ -337,8 +338,9 @@ void __init start_of_day(void)
#endif
do_initcalls();
+ initialize_keytable(); /* call back handling for key codes */
initialize_serial(); /* setup serial 'driver' (for debugging) */
- initialize_keyboard(); /* setup keyboard (also for debugging) */
+ initialize_keyboard(); /* setup keyboard (also for debugging) */
if ( !setup_network_devices() )
panic("Must have a network device!\n");
diff --git a/xen-2.4.16/common/keyhandler.c b/xen-2.4.16/common/keyhandler.c
new file mode 100644
index 0000000000..bd99b7956f
--- /dev/null
+++ b/xen-2.4.16/common/keyhandler.c
@@ -0,0 +1,125 @@
+#include <xeno/keyhandler.h>
+#include <xeno/reboot.h>
+
+#define KEY_MAX 256
+#define STR_MAX 64
+
+typedef struct _key_te {
+ key_handler *handler;
+ char desc[STR_MAX];
+} key_te_t;
+
+static key_te_t key_table[KEY_MAX];
+
+void add_key_handler(u_char key, key_handler *handler, char *desc)
+{
+ int i;
+ char *str;
+
+ if(key_table[key].handler != NULL)
+ printk("Warning: overwriting handler for key 0x%x\n", key);
+
+ key_table[key].handler = handler;
+
+ str = key_table[key].desc;
+ for(i = 0; i < STR_MAX; i++) {
+ if(*desc)
+ *str++ = *desc++;
+ else break;
+ }
+ if (i == STR_MAX)
+ key_table[key].desc[STR_MAX-1] = '\0';
+
+ return;
+}
+
+key_handler *get_key_handler(u_char key)
+{
+ return key_table[key].handler;
+}
+
+
+void show_handlers(u_char key, void *dev_id, struct pt_regs *regs)
+{
+ int i;
+
+ printk("'%c' pressed -> showing installed handlers\n", key);
+ for(i=0; i < KEY_MAX; i++)
+ if(key_table[i].handler)
+ printk("ASCII '%02x' => %s\n", i, key_table[i].desc);
+ return;
+}
+
+
+void dump_registers(u_char key, void *dev_id, struct pt_regs *regs)
+{
+ extern void show_registers(struct pt_regs *regs);
+
+ printk("'%c' pressed -> dumping registers\n", key);
+ show_registers(regs);
+ return;
+}
+
+void halt_machine(u_char key, void *dev_id, struct pt_regs *regs)
+{
+ printk("'%c' pressed -> rebooting machine\n", key);
+ machine_restart(NULL);
+ return;
+}
+
+
+
+/* XXX SMH: this is keir's fault */
+static char *task_states[] =
+{
+ "Running",
+ "Interruptible Sleep",
+ "Uninterruptible Sleep",
+ NULL, "Stopped",
+ NULL, NULL, NULL, "Dying",
+};
+
+void do_task_queues(u_char key, void *dev_id, struct pt_regs *regs)
+{
+ u_long flags;
+ struct task_struct *p;
+ shared_info_t *s;
+
+ printk("'%c' pressed -> dumping task queues\n", key);
+ read_lock_irqsave(&tasklist_lock, flags);
+ p = &idle0_task;
+ do {
+ printk("Xen: DOM %d, CPU %d [has=%c], state = %s, "
+ "hyp_events = %08x\n",
+ p->domain, p->processor, p->has_cpu ? 'T':'F',
+ task_states[p->state], p->hyp_events);
+ s = p->shared_info;
+ if(!is_idle_task(p)) {
+ printk("Guest: events = %08lx, event_enable = %08lx\n",
+ s->events, s->events_enable);
+ printk("Notifying guest...\n");
+ set_bit(_EVENT_DEBUG, &s->events);
+ }
+ }
+
+ while ( (p = p->next_task) != &idle0_task );
+ read_unlock_irqrestore(&tasklist_lock, flags);
+}
+
+
+void initialize_keytable()
+{
+ int i;
+
+ /* first initialize key handler table */
+ for(i = 0; i < KEY_MAX; i++)
+ key_table[i].handler = (key_handler *)NULL;
+
+ /* setup own handlers */
+ add_key_handler('d', dump_registers, "dump registers");
+ add_key_handler('h', show_handlers, "show this message");
+ add_key_handler('q', do_task_queues, "dump task queues + guest state");
+ add_key_handler('r', halt_machine, "reboot machine ungracefully");
+
+ return;
+}
diff --git a/xen-2.4.16/drivers/block/ll_rw_blk.c b/xen-2.4.16/drivers/block/ll_rw_blk.c
index 06d9fb72e9..348b516c1d 100644
--- a/xen-2.4.16/drivers/block/ll_rw_blk.c
+++ b/xen-2.4.16/drivers/block/ll_rw_blk.c
@@ -31,6 +31,9 @@
#include <xeno/slab.h>
#include <xeno/module.h>
+/* XXX SMH: temporarily we just dive at xen_block completion handler */
+extern void end_block_io_op(struct buffer_head *bh);
+
static void end_buffer_dummy(struct buffer_head *bh, int uptodate)
{
/* do nothing */
@@ -1030,6 +1033,8 @@ out:
return 0;
end_io:
bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
+ /* XXX SMH: do we need this every time? */
+ end_block_io_op(bh);
return 0;
}
@@ -1101,6 +1106,8 @@ void generic_make_request (int rw, struct buffer_head * bh)
/* Yecch again */
bh->b_end_io(bh, 0);
+ /* XXX SMH */
+ end_block_io_op(bh);
return;
}
}
@@ -1142,10 +1149,6 @@ void generic_make_request (int rw, struct buffer_head * bh)
*/
void submit_bh(int rw, struct buffer_head * bh)
{
- int count = bh->b_size >> 9;
-
- /* printk(KERN_ALERT "submit_bh\n"); */
-
if (!test_bit(BH_Lock, &bh->b_state))
BUG();
@@ -1160,17 +1163,6 @@ void submit_bh(int rw, struct buffer_head * bh)
/* bh->b_rsector = bh->b_blocknr * count; */
generic_make_request(rw, bh);
-
-#if 0
- switch (rw) {
- case WRITE:
- kstat.pgpgout += count;
- break;
- default:
- kstat.pgpgin += count;
- break;
- }
-#endif
}
/**
@@ -1267,6 +1259,8 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])
BUG();
end_io:
bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
+ /* XXX SMH */
+ end_block_io_op(bh);
continue;
}
@@ -1275,6 +1269,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])
return;
sorry:
+ printk("~~~");
/* Make sure we don't get infinite dirty retries.. */
for (i = 0; i < nr; i++)
mark_buffer_clean(bhs[i]);
diff --git a/xen-2.4.16/drivers/block/xen_block.c b/xen-2.4.16/drivers/block/xen_block.c
index b6d0e8993f..c61597e3d8 100644
--- a/xen-2.4.16/drivers/block/xen_block.c
+++ b/xen-2.4.16/drivers/block/xen_block.c
@@ -15,6 +15,8 @@
#include <asm-i386/io.h>
#include <asm/spinlock.h>
+#include <xeno/keyhandler.h>
+
#define XEN_BLK_DEBUG 0
#define XEN_BLK_DEBUG_LEVEL KERN_ALERT
@@ -28,10 +30,12 @@ typedef struct blk_request
struct task_struct *domain; /* requesting domain */
} blk_request_t;
-static int pending_work; /* which domains have work for us? */
+static int pending_work; /* which domains have work for us? */
+
blk_request_t blk_request_list[XEN_BLK_REQUEST_LIST_SIZE];
-struct list_head free_queue; /* unused requests */
-struct list_head pending_queue; /* waiting for hardware */
+
+struct list_head free_queue; /* unused requests */
+struct list_head pending_queue; /* waiting for hardware */
struct list_head io_done_queue; /* request completed. send to guest os */
spinlock_t free_queue_lock;
spinlock_t pending_queue_lock;
@@ -49,61 +53,46 @@ int dispatch_debug_block_io (int index);
* end_block_io_op
*
* IO has completed. Need to notify the guest operating system.
- * Called from hardware interrupt.
+ * Called from ll_rw_block -- currently /DIRECTLY/ -- XXX FIXME
+ * (e.g. hook into proper end processing of ll_rw)
*/
void end_block_io_op(struct buffer_head * bh)
{
- unsigned long cpu_mask;
- /* struct list_head *list;*/
- blk_request_t *blk_request = NULL;
- unsigned long flags; /* irq save */
-
-#if 0
- printk("{E}");
-#endif
- if (XEN_BLK_DEBUG) printk(XEN_BLK_DEBUG_LEVEL
- "XEN end_block_io_op, bh: %lx\n",
- (unsigned long)bh);
-
- {
- char temp[100];
- sprintf(temp, "endio bh: 0x%p, blkno: 0x%lx",
- bh, bh->b_blocknr);
- printx(temp);
- }
-
- spin_lock_irqsave(&pending_queue_lock, flags);
- /*
- list_for_each (list, &pending_queue)
- {
- blk_request = list_entry(list, blk_request_t, queue);
- if (blk_request->bh == bh)
- {
- break;
+ unsigned long cpu_mask;
+ /* struct list_head *list;*/
+ blk_request_t *blk_request = NULL;
+ unsigned long flags; /* irq save */
+
+ if (XEN_BLK_DEBUG)
+ printk(XEN_BLK_DEBUG_LEVEL "XEN end_block_io_op, bh: %lx\n",
+ (unsigned long)bh);
+
+ spin_lock_irqsave(&pending_queue_lock, flags);
+ blk_request = (blk_request_t *)bh->b_xen_request;
+
+ if (blk_request == NULL) {
+ printk (KERN_ALERT
+ " block io interrupt received for unknown buffer [0x%lx]\n",
+ (unsigned long) bh);
+ spin_unlock_irqrestore(&pending_queue_lock, flags);
+ BUG();
+ return;
}
- }
- */
- blk_request = (blk_request_t *)bh->b_xen_request;
- if (blk_request == NULL)
- {
- printk (KERN_ALERT
- " block io interrupt received for unknown buffer [0x%lx]\n",
- (unsigned long) bh);
+
+ list_del(&blk_request->queue);
spin_unlock_irqrestore(&pending_queue_lock, flags);
+
+ spin_lock_irqsave(&io_done_queue_lock, flags);
+ list_add_tail(&blk_request->queue, &io_done_queue);
+
+ /* enqueue work for 'flush_blk_queue' handler */
+ cpu_mask = mark_hyp_event(blk_request->domain, _HYP_EVENT_BLK_RX);
+ spin_unlock_irqrestore(&io_done_queue_lock, flags);
+
+ /* now kick the hypervisor */
+ hyp_event_notify(cpu_mask);
return;
- }
- list_del(&blk_request->queue);
- spin_unlock_irqrestore(&pending_queue_lock, flags);
-
- spin_lock_irqsave(&io_done_queue_lock, flags);
- list_add_tail(&blk_request->queue, &io_done_queue);
- spin_unlock_irqrestore(&io_done_queue_lock, flags);
-
- /* enqueue work */
- cpu_mask = mark_hyp_event(blk_request->domain, _HYP_EVENT_BLK_RX);
-
- return;
}
/*
@@ -115,126 +104,82 @@ void end_block_io_op(struct buffer_head * bh)
void flush_blk_queue(void)
{
- blk_request_t *blk_request;
- int position = 0;
- blk_ring_t *blk_ring;
- unsigned long flags;
- int loop;
-
-#if 0
- printk("{F}");
-#endif
- /*
- if (XEN_BLK_DEBUG) printk(XEN_BLK_DEBUG_LEVEL
- "XEN flush_blk_queue\n");
- */
-
- clear_bit(_HYP_EVENT_BLK_RX, &current->hyp_events);
-
- /* NEED LOCK? */
- spin_lock_irqsave(&io_done_queue_lock, flags);
- while (!list_empty(&io_done_queue))
- {
- blk_request = list_entry(io_done_queue.next, blk_request_t, queue);
- list_del (&blk_request->queue);
+ blk_request_t *blk_request;
+ int position = 0;
+ blk_ring_t *blk_ring;
+ unsigned long flags;
+ int loop;
+
+ spin_lock_irqsave(&io_done_queue_lock, flags);
+ clear_bit(_HYP_EVENT_BLK_RX, &current->hyp_events);
+
+ while (!list_empty(&io_done_queue)) {
+
+ blk_request = list_entry(io_done_queue.next, blk_request_t, queue);
+ list_del (&blk_request->queue);
+ spin_unlock_irqrestore(&io_done_queue_lock, flags);
+
+ /* place on ring for guest os */
+ blk_ring = blk_request->domain->blk_ring_base;
+ position = blk_ring->brx_prod;
+
+ if (XEN_BLK_DEBUG)
+ printk(XEN_BLK_DEBUG_LEVEL "XEN flush_blk_queue [%d]\n", position);
+
+ memcpy(&blk_ring->brx_ring[position], &blk_request->request,
+ sizeof(blk_ring_entry_t));
+ blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod);
+
+ /* notify appropriate guest os */
+ set_bit(_EVENT_BLK_RX, &blk_request->domain->shared_info->events);
+
+ /* free the buffer header allocated in do_block_io_op */
+ if (blk_request->bh)
+ kfree(blk_request->bh);
+
+ spin_lock_irqsave(&free_queue_lock, flags);
+ list_add_tail(&blk_request->queue, &free_queue);
+ spin_unlock_irqrestore(&free_queue_lock, flags);
+
+ spin_lock_irqsave(&io_done_queue_lock, flags);
+ }
spin_unlock_irqrestore(&io_done_queue_lock, flags);
- /* place on ring for guest os */
- blk_ring = blk_request->domain->blk_ring_base;
- position = blk_ring->rx_prod;
- if (XEN_BLK_DEBUG) printk(XEN_BLK_DEBUG_LEVEL
- "XEN flush_blk_queue [%d]\n", position);
-
- memcpy(&blk_ring->rx_ring[position], &blk_request->request,
- sizeof(blk_ring_entry_t));
- blk_ring->rx_prod = BLK_RX_RING_INC(blk_ring->rx_prod);
+ /* XXX SMH: below is ugly and dangerous -- fix */
+ /*
+ * now check if there is any pending work from any domain
+ * that we were previously unable to process.
+ *
+ * NOTE: the current algorithm will check _every_ domain
+ * and wake up _every_ domain that has pending work.
+ * In the future, we should stop waking up domains once
+ * there isn't any space for their requests any more
+ * ALSO, we need to maintain a counter of the last domain
+ * that we woke up for fairness... we shouldn't restart
+ * at domain 0 every time (although we might want to special
+ * case domain 0);
+ */
+ for (loop = 0; loop < XEN_BLOCK_MAX_DOMAINS; loop++) {
- /* notify appropriate guest os */
- set_bit(_EVENT_BLK_RX,
- &blk_request->domain->shared_info->events);
+ int domain = pending_work & (1 << loop);
- if (0)
- {
- int temp;
- struct buffer_head *bh = blk_request->bh;
- char * vbuffer = bh->b_data;
-
- printk (KERN_ALERT "XEN return block 0x%lx\n", bh->b_blocknr);
-
- for (temp = 0; temp < bh->b_size; temp++)
- {
- if (temp % 16 == 0) printk ("[%04x] ", temp);
- else if (temp % 4 == 0) printk (" ");
- printk ("%02x",
- vbuffer[temp] & 255);
- if ((temp + 1) % 16 == 0) printk ("\n");
- }
- printk ("\n\n");
- }
+ if (domain) {
- /* free the buffer header allocated in do_block_io_op */
- if (blk_request->bh)
- {
- kfree(blk_request->bh); /* alloc in do_block_io_op */
- }
+ struct task_struct *mytask = current;
- spin_lock_irqsave(&free_queue_lock, flags);
- list_add_tail(&blk_request->queue, &free_queue);
- spin_unlock_irqrestore(&free_queue_lock, flags);
+ while (mytask->domain != loop)
+ mytask = mytask->next_task;
- spin_lock_irqsave(&io_done_queue_lock, flags);
- }
- spin_unlock_irqrestore(&io_done_queue_lock, flags);
-
- /*
- * now check if there is any pending work from any domain
- * that we were previously unable to process.
- *
- * NOTE: the current algorithm will check _every_ domain
- * and wake up _every_ domain that has pending work.
- * In the future, we should stop waking up domains once
- * there isn't any space for their requests any more
- * ALSO, we need to maintain a counter of the last domain
- * that we woke up for fairness... we shouldn't restart
- * at domain 0 every time (although we might want to special
- * case domain 0);
- */
- for (loop = 0; loop < XEN_BLOCK_MAX_DOMAINS; loop++)
- {
- int domain = pending_work & (1 << loop);
-
- if (domain)
- {
- struct task_struct *mytask = current;
-
- /*
- printk (KERN_ALERT
- "flush_blk_queue pending_work: %x domain: %d loop: %d\n",
- pending_work, domain, loop);
- */
- /* IS THERE A BETTER WAY OF FINDING THE TASK STRUCT FOR A
- * PARTICULAR DOMAIN?
- *
- * WHAT IF THE TASK GOES AWAY BEFORE WE HAVE A CHANCE TO
- * FINISH PROCESSING ALL OF ITS REQUESTS?
- */
- while (mytask->domain != loop)
- {
- mytask = mytask->next_task;
- }
- do_block_io_op_domain(mytask);
-
- pending_work = pending_work & !(1 << loop);
- /*
- printk (KERN_ALERT
- " pending_work: %x domain: %d loop: %d\n",
- pending_work, domain, loop);
- */
+ pending_work = pending_work & !(1 << loop);
+ do_block_io_op_domain(mytask);
+ }
}
- }
+
+ return;
}
+
/*
* do_block_io_op
*
@@ -244,186 +189,132 @@ void flush_blk_queue(void)
long do_block_io_op (void)
{
- return do_block_io_op_domain(current);
+ return do_block_io_op_domain(current);
}
+
/*
* do_block_io_op
*
* handle the requests for a particular domain
*/
-
long do_block_io_op_domain (struct task_struct* task)
{
- blk_ring_t *blk_ring = task->blk_ring_base;
- int loop;
-
-#if 0
- printk("{%d}", current->domain);
-#endif
- if (XEN_BLK_DEBUG) printk(XEN_BLK_DEBUG_LEVEL
- "XEN do_block_io_op %d %d\n",
- blk_ring->tx_cons, blk_ring->tx_prod);
-
- for (loop = blk_ring->tx_cons;
- loop != blk_ring->tx_prod;
- loop = BLK_TX_RING_INC(loop))
- {
- int status = 1;
-
- switch (blk_ring->tx_ring[loop].operation)
- {
- case XEN_BLOCK_READ :
- case XEN_BLOCK_WRITE :
- {
- status = dispatch_rw_block_io(loop);
- break;
- }
- case XEN_BLOCK_PROBE :
- {
- status = dispatch_probe_block_io(loop);
- break;
- }
- case XEN_BLOCK_DEBUG :
- {
- status = dispatch_debug_block_io(loop);
- break;
- }
- default :
- {
- printk (KERN_ALERT "error: unknown block io operation [%d]\n",
- blk_ring->tx_ring[loop].operation);
- BUG();
- }
+ blk_ring_t *blk_ring = task->blk_ring_base;
+ int loop, status;
+
+ if (XEN_BLK_DEBUG)
+ printk(XEN_BLK_DEBUG_LEVEL "XEN do_block_io_op %d %d\n",
+ blk_ring->btx_cons, blk_ring->btx_prod);
+
+ for (loop = blk_ring->btx_cons;
+ loop != blk_ring->btx_prod;
+ loop = BLK_TX_RING_INC(loop)) {
+
+ status = 1;
+
+ switch (blk_ring->btx_ring[loop].operation) {
+
+ case XEN_BLOCK_READ:
+ case XEN_BLOCK_WRITE:
+ status = dispatch_rw_block_io(loop);
+ break;
+
+ case XEN_BLOCK_PROBE:
+ status = dispatch_probe_block_io(loop);
+ break;
+
+ case XEN_BLOCK_DEBUG:
+ status = dispatch_debug_block_io(loop);
+ break;
+
+ default:
+ printk (KERN_ALERT "error: unknown block io operation [%d]\n",
+ blk_ring->btx_ring[loop].operation);
+ BUG();
+ }
+
+
+ if (status) {
+ /*
+ ** Unable to successfully issue / complete command, maybe because
+ ** another resource (e.g. disk request buffers) is unavailable.
+ ** stop removing items from the communications ring and try later
+ */
+ pending_work = pending_work | (1 << task->domain);
+ break;
+ }
}
- if (status)
- {
- /* unable to successfully issue / complete command, maybe because
- * another resource (e.g. disk request buffers) is unavailable.
- * stop removing items from the communications ring and try
- * again later
- */
-
- /*
- printk ("do_block_io_op_domain domain:%d, pending_work: %x\n",
- task->domain, pending_work);
- */
- pending_work = pending_work | (1 << task->domain);
- /*
- printk ("do_block_io_op_domain domain:%d, pending_work: %x\n",
- task->domain, pending_work);
- */
- break;
- }
- }
-
- blk_ring->tx_cons = loop;
-
- return 0L;
+ blk_ring->btx_cons = loop;
+ return 0L;
}
+
int dispatch_debug_block_io (int index)
{
- struct task_struct *task;
- blk_ring_t *blk_ring = current->blk_ring_base;
- char * buffer;
- char output[1000];
-
- int foobar = (unsigned long)blk_ring->tx_ring[index].block_number;
-
- printk (KERN_ALERT "dispatch_debug_block_io %d\n", foobar);
-
- buffer = phys_to_virt(blk_ring->tx_ring[index].buffer);
- strcpy (buffer, "DEBUG\n");
-
- task = current;
- sprintf (buffer, "current %d\n", current->domain);
- sprintf (buffer, "%s tx: prod: %d, cons: %d, size: %d\n", buffer,
- blk_ring->tx_prod, blk_ring->tx_cons, blk_ring->tx_ring_size);
- sprintf (buffer, "%s rx: prod: %d, cons: %d, size: %d\n", buffer,
- blk_ring->rx_prod, blk_ring->rx_cons, blk_ring->rx_ring_size);
-
- task = task->next_task;
- while (task != current)
- {
- blk_ring = task->blk_ring_base;
- sprintf (buffer, "%stask %d\n", buffer, task->domain);
- if (blk_ring != NULL)
- {
- sprintf (buffer, "%s tx: prod: %d, cons: %d, size: %d\n",
- buffer, blk_ring->tx_prod, blk_ring->tx_cons,
- blk_ring->tx_ring_size);
- sprintf (buffer, "%s rx: prod: %d, cons: %d, size: %d\n",
- buffer, blk_ring->rx_prod, blk_ring->rx_cons,
- blk_ring->rx_ring_size);
- }
- task = task->next_task;
- }
- dumpx(output, foobar);
- sprintf (buffer, "%s%s\n", buffer, output);
-
- return 0;
+ printk (KERN_ALERT "dispatch_debug_block_io: UNIMPL\n");
+ return 1;
}
+extern void ide_probe_devices(xen_disk_info_t *xdi);
+
int dispatch_probe_block_io (int index)
{
- blk_ring_t *blk_ring = current->blk_ring_base;
- xen_disk_info_t *xdi;
-
- xdi = phys_to_virt(blk_ring->tx_ring[index].buffer);
-
- ide_probe_devices(xdi);
-
- return 0;
+ blk_ring_t *blk_ring = current->blk_ring_base;
+ xen_disk_info_t *xdi;
+
+ xdi = phys_to_virt((unsigned long)blk_ring->btx_ring[index].buffer);
+
+ ide_probe_devices(xdi);
+
+ memcpy(&blk_ring->brx_ring[blk_ring->brx_prod],
+ &blk_ring->btx_ring[index],
+ sizeof(blk_ring_entry_t));
+ blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod);
+
+ return 0;
}
+extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
+
int dispatch_rw_block_io (int index)
{
- blk_ring_t *blk_ring = current->blk_ring_base;
- struct buffer_head *bh;
- struct request_queue *rq;
- int operation;
- blk_request_t *blk_request;
- unsigned long flags;
-
+ blk_ring_t *blk_ring = current->blk_ring_base;
+ struct buffer_head *bh;
+ struct request_queue *rq;
+ int operation;
+ blk_request_t *blk_request;
+ unsigned long flags;
+
/*
* check to make sure that the block request seems at least
* a bit legitimate
*/
- if ((blk_ring->tx_ring[index].block_size & (0x200 - 1)) != 0)
- {
- printk(KERN_ALERT
- " error: dodgy block size: %d\n",
- blk_ring->tx_ring[index].block_size);
- BUG();
- }
-
- if (XEN_BLK_DEBUG)
- {
- printk(XEN_BLK_DEBUG_LEVEL
- " tx_cons: %d tx_prod %d index: %d op: %s, pri: %s\n",
- blk_ring->tx_cons, blk_ring->tx_prod, index,
- (blk_ring->tx_ring[index].operation == XEN_BLOCK_READ ? "read" : "write"),
- (blk_ring->tx_ring[index].priority == XEN_BLOCK_SYNC ? "sync" : "async"));
+ if ((blk_ring->btx_ring[index].block_size & (0x200 - 1)) != 0) {
+ printk(KERN_ALERT " error: dodgy block size: %d\n",
+ blk_ring->btx_ring[index].block_size);
+ BUG();
}
+
- {
- char temp[100];
- sprintf(temp, "issue buf: 0x%p, bh: 0x%p, blkno: 0x%lx",
- blk_ring->tx_ring[index].buffer, bh,
- (unsigned long)blk_ring->tx_ring[index].block_number);
- printx(temp);
+ if (XEN_BLK_DEBUG) {
+ printk(XEN_BLK_DEBUG_LEVEL " btx_cons: %d btx_prod %d index: %d "
+ "op: %s, pri: %s\n", blk_ring->btx_cons, blk_ring->btx_prod,
+ index,
+ (blk_ring->btx_ring[index].operation == XEN_BLOCK_READ ?
+ "read" : "write"),
+ (blk_ring->btx_ring[index].priority == XEN_BLOCK_SYNC ?
+ "sync" : "async"));
}
/* find an empty request slot */
spin_lock_irqsave(&free_queue_lock, flags);
- if (list_empty(&free_queue))
- {
- /* printk (KERN_ALERT "dispatch_rw_block_io EMPTY FREE LIST!! %d\n", index); */
- spin_unlock_irqrestore(&free_queue_lock, flags);
- return 1;
+ if (list_empty(&free_queue)) {
+ spin_unlock_irqrestore(&free_queue_lock, flags);
+ return 1;
}
+
blk_request = list_entry(free_queue.next, blk_request_t, queue);
list_del(&blk_request->queue);
spin_unlock_irqrestore(&free_queue_lock, flags);
@@ -432,94 +323,51 @@ int dispatch_rw_block_io (int index)
spin_lock_irqsave(&pending_queue_lock, flags);
list_add_tail(&blk_request->queue, &pending_queue);
spin_unlock_irqrestore(&pending_queue_lock, flags);
-
+
/* we'll be doing this frequently, would a cache be appropriate? */
/* free in flush_blk_queue */
bh = (struct buffer_head *) kmalloc(sizeof(struct buffer_head),
GFP_KERNEL);
- if (!bh)
- {
- printk(KERN_ALERT "ERROR: bh is null\n");
- BUG();
+ if (!bh) {
+ printk(KERN_ALERT "ERROR: bh is null\n");
+ BUG();
}
/* set just the important bits of the buffer header */
memset (bh, 0, sizeof (struct buffer_head));
-
- bh->b_blocknr = blk_ring->tx_ring[index].block_number; /* block number */
- bh->b_size = blk_ring->tx_ring[index].block_size; /* block size */
- bh->b_dev = blk_ring->tx_ring[index].device; /* device (B_FREE = free) */
- bh->b_rsector = blk_ring->tx_ring[index].sector_number; /* sector number */
-
- bh->b_data = phys_to_virt(blk_ring->tx_ring[index].buffer);
- /* ptr to data blk */
- bh->b_count.counter = 1; /* users using this block */
- bh->b_xen_request = (void *)blk_request; /* save block request */
-
- if (blk_ring->tx_ring[index].operation == XEN_BLOCK_WRITE)
- {
- bh->b_state = ((1 << BH_JBD) | /* buffer state bitmap */
- (1 << BH_Mapped) |
- (1 << BH_Req) |
- (1 << BH_Dirty) |
- (1 << BH_Uptodate));
- operation = WRITE;
- }
- else
- {
- bh->b_state = (1 << BH_Mapped); /* buffer state bitmap */
- operation = READ;
+ bh->b_blocknr = blk_ring->btx_ring[index].block_number;
+ bh->b_size = blk_ring->btx_ring[index].block_size;
+ bh->b_dev = blk_ring->btx_ring[index].device;
+ bh->b_rsector = blk_ring->btx_ring[index].sector_number;
+ bh->b_data = phys_to_virt((unsigned long)
+ blk_ring->btx_ring[index].buffer);
+ bh->b_count.counter = 1;
+ bh->b_xen_request = (void *)blk_request;
+
+ if (blk_ring->btx_ring[index].operation == XEN_BLOCK_WRITE) {
+ bh->b_state = ((1 << BH_JBD) | (1 << BH_Mapped) | (1 << BH_Req) |
+ (1 << BH_Dirty) | (1 << BH_Uptodate));
+ operation = WRITE;
+ } else {
+ bh->b_state = (1 << BH_Mapped);
+ operation = READ;
}
- /* save meta data about request */
- memcpy(&blk_request->request, /* NEED COPY_FROM_USER? */
- &blk_ring->tx_ring[index], sizeof(blk_ring_entry_t));
- blk_request->bh = bh;
- blk_request->domain = current; /* save current domain */
-
+ /* save meta data about request XXX SMH: should copy_from_user() */
+ memcpy(&blk_request->request,
+ &blk_ring->btx_ring[index], sizeof(blk_ring_entry_t));
+ blk_request->bh = bh;
+ blk_request->domain = current;
+
/* dispatch single block request */
- ll_rw_block(operation, 1, &bh); /* linux top half */
+ ll_rw_block(operation, 1, &bh); /* linux top half */
rq = blk_get_queue(bh->b_rdev);
- generic_unplug_device(rq); /* linux bottom half */
+ generic_unplug_device(rq); /* linux bottom half */
return 0;
}
-/*
- * initialize_block_io
- *
- * initialize everything for block io
- * called from arch/i386/setup.c::start_of_day
- */
-
-void initialize_block_io ()
-{
- int loop;
-
- INIT_LIST_HEAD(&free_queue);
- INIT_LIST_HEAD(&pending_queue);
- INIT_LIST_HEAD(&io_done_queue);
-
- spin_lock_init(&free_queue_lock);
- spin_lock_init(&pending_queue_lock);
- spin_lock_init(&io_done_queue_lock);
-
- for (loop = 0; loop < XEN_BLK_REQUEST_LIST_SIZE; loop++)
- {
- list_add_tail(&blk_request_list[loop].queue, &free_queue);
- }
-
- /*
- * if bit i is true then domain i has work for us to do.
- */
- pending_work = 0;
-
- return;
-}
-
-
-#ifdef DEBUG
/*
* debug dump_queue
@@ -527,94 +375,91 @@ void initialize_block_io ()
*/
void dump_queue(struct list_head *queue, char *name)
{
- struct list_head *list;
- int loop = 0;
-
- printk ("QUEUE %s %lx n: %lx, p: %lx\n", name, (unsigned long)queue,
- (unsigned long) queue->next, (unsigned long) queue->prev);
- list_for_each (list, queue)
- {
- printk (" %s %d : %lx n: %lx, p: %lx\n", name, loop++,
- (unsigned long)list,
- (unsigned long)list->next, (unsigned long)list->prev);
- }
+ struct list_head *list;
+ int loop = 0;
+
+ printk ("QUEUE %s %lx n: %lx, p: %lx\n", name, (unsigned long)queue,
+ (unsigned long) queue->next, (unsigned long) queue->prev);
+ list_for_each (list, queue) {
+ printk (" %s %d : %lx n: %lx, p: %lx\n", name, loop++,
+ (unsigned long)list,
+ (unsigned long)list->next, (unsigned long)list->prev);
+ }
+ return;
}
void dump_queue_head(struct list_head *queue, char *name)
{
- struct list_head *list;
- int loop = 0;
-
- printk ("QUEUE %s %lx n: %lx, p: %lx\n", name, (unsigned long)queue,
- (unsigned long) queue->next, (unsigned long) queue->prev);
- list_for_each (list, queue)
- {
- printk (" %d : %lx n: %lx, p: %lx\n", loop++,
- (unsigned long)list,
- (unsigned long)list->next, (unsigned long)list->prev);
- if (loop >= 5) return;
- }
+ struct list_head *list;
+ int loop = 0;
+
+ printk ("QUEUE %s %lx n: %lx, p: %lx\n", name, (unsigned long)queue,
+ (unsigned long) queue->next, (unsigned long) queue->prev);
+ list_for_each (list, queue) {
+ printk (" %d : %lx n: %lx, p: %lx\n", loop++,
+ (unsigned long)list,
+ (unsigned long)list->next, (unsigned long)list->prev);
+ if (loop >= 5) return;
+ }
}
-#endif /* DEBUG */
+static void dump_blockq(u_char key, void *dev_id, struct pt_regs *regs)
+{
+ u_long flags;
+ printk("Dumping block queues:\n");
-#define debug_block_size 200000
-#define debug_output_size 10
+ spin_lock_irqsave(&free_queue_lock, flags);
+ dump_queue(&free_queue, "FREE QUEUE");
+ spin_unlock_irqrestore(&free_queue_lock, flags);
-static int countx = 0;
-static char * arrayx[debug_block_size];
-static int outputx = 0;
+ spin_lock_irqsave(&pending_queue_lock, flags);
+ dump_queue(&pending_queue, "PENDING QUEUE");
+ spin_unlock_irqrestore(&pending_queue_lock, flags);
-void
-printx (char * string)
-{
- char * s;
+ spin_lock_irqsave(&io_done_queue_lock, flags);
+ dump_queue(&io_done_queue, "IO DONE QUEUE");
+ spin_unlock_irqrestore(&io_done_queue_lock, flags);
- s = (char *) kmalloc(strlen(string), GFP_KERNEL);
- strcpy (s, string);
- arrayx[countx++] = s;
+ return;
+}
- if (countx >= debug_block_size)
- {
- countx = 0;
- printk (KERN_ALERT "printx wrap\n");
- }
-}
-void
-dumpx (char *buffer, int count)
-{
- int loop;
- int start;
-
- sprintf (buffer, "debug dump\n");
-
- /*
- for (loop = outputx;
- loop < outputx + debug_output_size && loop < countx;
- loop ++)
- {
- sprintf (buffer, "%s%02d:%s\n", buffer, loop, arrayx[loop]);
- }
- outputx = loop;
- */
-
- if (count == 0 || count > countx)
- {
- start = 0;
- }
- else
- {
- start = countx - count;
- }
-
- printk (KERN_ALERT "DUMPX BUFFER\n");
- for (loop = start; loop < countx; loop++)
- {
- printk (KERN_ALERT "%4d %s\n", loop, arrayx[loop]);
- }
- printk (KERN_ALERT "DUMPX bye bye\n");
+/*
+ * initialize_block_io
+ *
+ * initialize everything for block io
+ * called from arch/i386/setup.c::start_of_day
+ */
+
+void initialize_block_io (){
+
+ int loop;
+
+ INIT_LIST_HEAD(&free_queue);
+ INIT_LIST_HEAD(&pending_queue);
+ INIT_LIST_HEAD(&io_done_queue);
+
+ spin_lock_init(&free_queue_lock);
+ spin_lock_init(&pending_queue_lock);
+ spin_lock_init(&io_done_queue_lock);
+
+ for (loop = 0; loop < XEN_BLK_REQUEST_LIST_SIZE; loop++)
+ {
+ list_add_tail(&blk_request_list[loop].queue, &free_queue);
+ }
+
+
+ add_key_handler('b', dump_blockq, "dump xen ide block queues");
+
+ /*
+ * if bit i is true then domain i has work for us to do.
+ */
+ pending_work = 0;
+
+ return;
}
+
+
diff --git a/xen-2.4.16/drivers/char/xen_kbd.c b/xen-2.4.16/drivers/char/xen_kbd.c
index 780028ab69..ce8340e7bb 100644
--- a/xen-2.4.16/drivers/char/xen_kbd.c
+++ b/xen-2.4.16/drivers/char/xen_kbd.c
@@ -1,5 +1,6 @@
#include <asm-i386/io.h>
#include <xeno/sched.h> /* this has request_irq() proto for some reason */
+#include <xeno/keyhandler.h>
#define KEYBOARD_IRQ 1
@@ -22,74 +23,148 @@
#define kbd_read_status() inb(KBD_STATUS_REG)
+static int keyboard_shift = 0;
+static int keyboard_control = 0;
-static void
-dispatch_scancode (unsigned char scancode)
+/* the following is pretty gross...
+ * stop reading if you don't want to throw up!
+ */
+
+static unsigned char keymap_normal[] =
+{
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 ,'1','2', '3','4','5','6', '7','8','9','0', '-','=','\b','\t',
+ 'q','w','e','r', 't','y','u','i', 'o','p','[',']','\r', 0 ,'a','s',
+ 'd','f','g','h', 'j','k','l',';', '\'','`', 0 ,'#', 'z','x','c','v',
+ 'b','n','m',',', '.','/', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 ,'\\', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+};
+
+static unsigned char keymap_shift[] =
+{
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 ,'!','"', '#','$','%','^', '&','*','(',')', '_','+','\b','\t',
+ 'Q','W','E','R', 'T','Y','U','I', 'O','P','{','}','\r', 0 ,'A','S',
+ 'D','F','G','H', 'J','K','L',':', '@', 0 , 0 ,'~', 'Z','X','C','V',
+ 'B','N','M','<', '>','?', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 ,'|', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+};
+
+
+static unsigned char keymap_control[] =
+{ /* same as normal, except for a-z -> 1 to 26 */
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 ,'1','2', '3','4','5','6', '7','8','9','0', '-','=','\b','\t',
+ 17, 23, 5 , 18, 20, 25, 21, 9 , 15, 16,'[',']','\r', 0 , 1 , 19,
+ 4 , 6 , 7 , 8 , 10, 11, 12,';', '\'','`', 0 ,'#', 26, 24, 3 , 22,
+ 2 , 14, 13,',', '.','/', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 ,'\\', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+};
+
+
+static unsigned char convert_scancode (unsigned char scancode)
{
+ unsigned char value = 0;
- /*
- * we could be a bit more clever here, but why?
- * just add a jump to your debug routine for the appropriate character.
- */
- switch (scancode)
- {
- case 0x01 : /* esc */
- printk ("<esc>");
- break;
- case 0x9e : /* a */
- printk ("a");
- break;
- case 0x9f : /* s */
- printk ("s");
- break;
- case 0xae : /* c */
- printk ("c");
- break;
- case 0xb0 : /* b */
- printk ("b");
- break;
- case 0xbb : /* f1 */
- printk ("<f1>");
- break;
- case 0xbc : /* f2 */
- printk ("<f2>");
+ switch (scancode) {
+
+ case 0xba: /* caps lock UP */
+ case 0x9d: /* ctrl (left) UP */
+ keyboard_control = 0;
break;
- case 0xbd : /* f3 */
- printk ("<f3>");
+
+ case 0x3a: /* caps lock DOWN */
+ case 0x1d: /* ctrl (left) DOWN */
+ keyboard_control = 1;
break;
- case 0xbe : /* f4 */
- printk ("<f4>");
+
+ case 0xaa: /* shift (left) UP */
+ case 0xb6: /* shift (right) UP */
+ keyboard_shift = 0;
break;
- case 0xbf : /* f5 */
- /* xen_block_dump_state(); */
+
+ case 0x2a: /* shift (left) DOWN */
+ case 0x36: /* shift (right) DOWN */
+ keyboard_shift = 1;
break;
- default :
- /* printk ("%x ", scancode); */
- }
- return;
-}
+ default: /* normal keys */
+ if (keyboard_control)
+ value = keymap_control[scancode];
+ else if (keyboard_shift)
+ value = keymap_shift[scancode];
+ else
+ value = keymap_normal[scancode];
+ }
-/* regs should be struct pt_regs */
+ if (value) printk ("%c", value);
-static void keyboard_interrupt(int irq, void *dev_id, void *regs)
+ return value;
+}
+
+static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char status = kbd_read_status();
unsigned int work = 10000;
-
+
while ((--work > 0) && (status & KBD_STAT_OBF))
{
unsigned char scancode;
-
scancode = kbd_read_input();
if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
{
if (status & KBD_STAT_MOUSE_OBF)
/* mouse event, ignore */;
- else
- dispatch_scancode (scancode);
+ else {
+ unsigned char key;
+ key_handler *handler;
+
+ if((key = convert_scancode (scancode)) &&
+ (handler = get_key_handler(key)))
+ (*handler)(key, dev_id, regs);
+
+ }
}
status = kbd_read_status();
}
diff --git a/xen-2.4.16/drivers/char/xen_serial.c b/xen-2.4.16/drivers/char/xen_serial.c
index 7c62567fa4..7b7e4a7b80 100644
--- a/xen-2.4.16/drivers/char/xen_serial.c
+++ b/xen-2.4.16/drivers/char/xen_serial.c
@@ -1,6 +1,7 @@
#include <asm-i386/io.h>
#include <xeno/sched.h> /* this has request_irq() proto for some reason */
-
+#include <xeno/keyhandler.h>
+#include <xeno/reboot.h>
/* Register offsets */
#define NS16550_RBR 0x00 /* receive buffer */
@@ -43,51 +44,20 @@
-/*
-** We keep an array of 'handlers' for each key code between 0 and 255;
-** this is intended to allow very simple debugging routines (toggle
-** debug flag, dump registers, reboot, etc) to be hooked in in a slightly
-** nicer fashion than just editing this file :-)
-*/
-
-#define KEY_MAX 256
-typedef void key_handler(u_char key);
-
-static key_handler *key_table[KEY_MAX];
-
-void add_key_handler(u_char key, key_handler *handler)
-{
- if(key_table[key] != NULL)
- printk("Warning: overwriting handler for key 0x%x\n", key);
-
- key_table[key] = handler;
- return;
-}
-
-
-
static int serial_echo = 0; /* default is not to echo; change with 'e' */
-void toggle_echo(u_char key)
+void toggle_echo(u_char key, void *dev_id, struct pt_regs *regs)
{
serial_echo = !serial_echo;
return;
}
-void halt_machine(u_char key)
-{
- /* This is 'debug me please' => just dump info and halt machine */
- printk("serial_rx_int: got EOT => halting machine.\n");
- printk("<not actually halting for now>\n");
- return;
-}
-
-
static void serial_rx_int(int irq, void *dev_id, struct pt_regs *regs)
{
u_char c;
+ key_handler *handler;
/* XXX SMH: should probably check this is an RX interrupt :-) */
@@ -95,8 +65,8 @@ static void serial_rx_int(int irq, void *dev_id, struct pt_regs *regs)
c = inb(SERIAL_BASE + NS16550_RBR );
/* if there's a handler, call it: we trust it won't screw us too badly */
- if(key_table[c])
- (*key_table[c])(c);
+ if((handler = get_key_handler(c)) != NULL)
+ (*handler)(c, dev_id, regs);
if(serial_echo)
printk("%c", c);
@@ -104,19 +74,12 @@ static void serial_rx_int(int irq, void *dev_id, struct pt_regs *regs)
return;
}
-
void initialize_serial()
{
- int i, fifo, rc;
-
- /* first initialize key handler table */
- for(i = 0; i < KEY_MAX; i++)
- key_table[i] = (key_handler *)NULL;
-
- /* setup own handlers */
- add_key_handler(0x01, toggle_echo); /* <esc> to toggle echo */
- add_key_handler(0x04, halt_machine); /* CTRL-D to 'halt' */
-
+ int fifo, rc;
+
+ /* setup key handler */
+ add_key_handler('~', toggle_echo, "toggle serial echo");
/* Should detect this, but must be a ns16550a at least, surely? */
fifo = 1;
diff --git a/xen-2.4.16/drivers/ide/ide-xeno.c b/xen-2.4.16/drivers/ide/ide-xeno.c
index eb7e6cab58..e0ce54feed 100644
--- a/xen-2.4.16/drivers/ide/ide-xeno.c
+++ b/xen-2.4.16/drivers/ide/ide-xeno.c
@@ -5,42 +5,37 @@
#include <hypervisor-ifs/block.h>
-void
-ide_probe_devices (xen_disk_info_t* xdi)
+void ide_probe_devices (xen_disk_info_t* xdi)
{
- int loop;
-
- for (loop = 0; loop < MAX_HWIFS; ++loop)
- {
- ide_hwif_t *hwif = &ide_hwifs[loop];
- if (hwif->present)
- {
- struct gendisk *gd = hwif->gd;
- unsigned int unit;
-
- for (unit = 0; unit < MAX_DRIVES; ++unit)
- {
- unsigned long capacity;
-
- ide_drive_t *drive = &hwif->drives[unit];
-
- if (drive->present)
- {
- capacity = current_capacity (drive);
-
- xdi->disks[xdi->count].type = XEN_DISK_IDE;
- xdi->disks[xdi->count].capacity = capacity;
- xdi->count++;
-
- printk (KERN_ALERT "IDE-XENO %d\n", xdi->count);
- printk (KERN_ALERT " capacity 0x%x\n", capacity);
- printk (KERN_ALERT " head 0x%x\n", drive->bios_head);
- printk (KERN_ALERT " sector 0x%x\n", drive->bios_sect);
- printk (KERN_ALERT " cylinder 0x%x\n", drive->bios_cyl);
+ int loop;
+
+ for (loop = 0; loop < MAX_HWIFS; ++loop) {
+
+ ide_hwif_t *hwif = &ide_hwifs[loop];
+ if (hwif->present) {
+
+ struct gendisk *gd = hwif->gd;
+ unsigned int unit;
+
+ for (unit = 0; unit < MAX_DRIVES; ++unit) {
+ unsigned long capacity;
+ ide_drive_t *drive = &hwif->drives[unit];
+
+ if (drive->present) {
+ capacity = current_capacity (drive);
+ xdi->disks[xdi->count].type = XEN_DISK_IDE;
+ xdi->disks[xdi->count].capacity = capacity;
+ xdi->count++;
+
+ printk (KERN_ALERT "IDE-XENO %d\n", xdi->count);
+ printk (KERN_ALERT " capacity 0x%x\n", capacity);
+ printk (KERN_ALERT " head 0x%x\n", drive->bios_head);
+ printk (KERN_ALERT " sector 0x%x\n", drive->bios_sect);
+ printk (KERN_ALERT " cylinder 0x%x\n", drive->bios_cyl);
+ }
+ }
}
- }
}
- }
return;
}
diff --git a/xen-2.4.16/include/hypervisor-ifs/block.h b/xen-2.4.16/include/hypervisor-ifs/block.h
index 1722a6c288..76db90da1a 100644
--- a/xen-2.4.16/include/hypervisor-ifs/block.h
+++ b/xen-2.4.16/include/hypervisor-ifs/block.h
@@ -51,13 +51,13 @@ typedef struct blk_ring_entry
typedef struct blk_ring_st
{
- blk_ring_entry_t *tx_ring;
- unsigned int tx_prod, tx_cons;
- unsigned int tx_ring_size;
+ blk_ring_entry_t *btx_ring;
+ unsigned int btx_prod, btx_cons;
+ unsigned int btx_ring_size;
- blk_ring_entry_t *rx_ring;
- unsigned int rx_prod, rx_cons;
- unsigned int rx_ring_size;
+ blk_ring_entry_t *brx_ring;
+ unsigned int brx_prod, brx_cons;
+ unsigned int brx_ring_size;
} blk_ring_t;
#define MAX_XEN_DISK_COUNT 100
diff --git a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h
index ad3c9a5dd8..d00e50ddc8 100644
--- a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h
+++ b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h
@@ -107,10 +107,9 @@ typedef struct
#define EVENT_BLK_RX 0x02 /* empty buffers for receive. */
#define EVENT_TIMER 0x04 /* a timeout has been updated. */
#define EVENT_DIE 0x08 /* OS is about to be killed. Clean up please! */
-#define EVENT_NET_TX 0x10 /* packets for transmission. */
-#define EVENT_NET_RX 0x20 /* empty buffers for receive. */
-#define EVENT_NET2_TX 0x40 /* packets for transmission. */
-#define EVENT_NET2_RX 0x80 /* empty buffers for receive. */
+#define EVENT_DEBUG 0x10 /* request guest to dump debug info (gross!) */
+#define EVENT_NET_TX 0x20 /* packets for transmission. */
+#define EVENT_NET_RX 0x40 /* empty buffers for receive. */
/* should these macros and the ones below test for range violation? */
#define EVENT_NET_TX_FOR_VIF(x) (EVENT_NET_TX << (2 * x))
@@ -124,12 +123,12 @@ typedef struct
#define _EVENT_DIE 3
#define _EVENT_NET_TX 4
#define _EVENT_NET_RX 5
-#define _EVENT_NET2_TX 6
-#define _EVENT_NET2_RX 7
+#define _EVENT_DEBUG 6
#define _EVENT_NET_TX_FOR_VIF(x) (_EVENT_NET_TX + (2 * x))
#define _EVENT_NET_RX_FOR_VIF(x) (_EVENT_NET_RX + (2 * x))
+
/*
* NB. We expect that this struct is smaller than a page.
*/
diff --git a/xen-2.4.16/include/xeno/keyhandler.h b/xen-2.4.16/include/xeno/keyhandler.h
new file mode 100644
index 0000000000..d03e09aa47
--- /dev/null
+++ b/xen-2.4.16/include/xeno/keyhandler.h
@@ -0,0 +1,16 @@
+/*
+** We keep an array of 'handlers' for each key code between 0 and 255;
+** this is intended to allow very simple debugging routines (toggle
+** debug flag, dump registers, reboot, etc) to be hooked in in a slightly
+** nicer fashion than just editing the serial/keyboard drivers.
+*/
+#include <xeno/sched.h>
+
+typedef void key_handler(unsigned char key, void *dev_id,
+ struct pt_regs *regs);
+
+extern void add_key_handler(unsigned char key,
+ key_handler *handler, char *desc);
+
+extern key_handler *get_key_handler(unsigned char key);
+
diff --git a/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c b/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c
index 0416b467a7..f7bd088ff4 100644
--- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c
+++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c
@@ -30,19 +30,21 @@ typedef unsigned char byte;
void xlblk_ide_register_disk(int, unsigned long);
-#define XLBLK_MAX 2 /* very arbitrary */
-#define XLBLK_MAJOR_NAME "blk"
+#define XLBLK_MAX 2 /* very arbitrary */
+#define XLBLK_MAJOR_NAME "xhd"
#define IDE_PARTN_BITS 6 /* from ide.h::PARTN_BITS */
#define IDE_PARTN_MASK ((1<<IDE_PARTN_BITS)-1) /* from ide.h::PARTN_MASK */
static int xlblk_blk_size[XLBLK_MAX];
static int xlblk_blksize_size[XLBLK_MAX];
+static int xlblk_read_ahead;
static int xlblk_hardsect_size[XLBLK_MAX];
-static int xlblk_read_ahead[XLBLK_MAX];
static int xlblk_max_sectors[XLBLK_MAX];
#define XLBLK_RX_IRQ _EVENT_BLK_RX
#define XLBLK_TX_IRQ _EVENT_BLK_TX
+#define DEBUG_IRQ _EVENT_DEBUG
+
typedef struct xlblk_device
{
struct buffer_head *bh;
@@ -51,11 +53,6 @@ typedef struct xlblk_device
xlblk_device_t xlblk_device;
-/* USE_REQUEST_QUEUE = 1 use (multiple) request queues
- * = 0 don't use IO request queue
- */
-#define USE_REQUEST_QUEUE 1
-
#define XLBLK_DEBUG 0
#define XLBLK_DEBUG_IOCTL 0
@@ -80,130 +77,106 @@ void hypervisor_request(void * id,
static int xenolinux_block_open(struct inode *inode, struct file *filep)
{
- if (XLBLK_DEBUG) {
- printk (KERN_ALERT "xenolinux_block_open\n"); }
- return 0;
+ if (XLBLK_DEBUG)
+ printk (KERN_ALERT "xenolinux_block_open\n");
+
+ return 0;
}
static int xenolinux_block_release(struct inode *inode, struct file *filep)
{
- if (XLBLK_DEBUG) {
- printk (KERN_ALERT "xenolinux_block_release\n"); }
- return 0;
+ if (XLBLK_DEBUG)
+ printk (KERN_ALERT "xenolinux_block_release\n");
+
+ return 0;
}
static int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
unsigned command, unsigned long argument)
{
- int minor_dev;
-
- if (XLBLK_DEBUG_IOCTL)
- {
- printk (KERN_ALERT "xenolinux_block_ioctl\n");
- }
-
- /* check permissions */
- if (!capable(CAP_SYS_ADMIN)) return -EPERM;
- if (!inode) return -EINVAL;
- minor_dev = MINOR(inode->i_rdev);
- if (minor_dev >= XLBLK_MAX) return -ENODEV;
-
- if (XLBLK_DEBUG_IOCTL)
- {
- printk (KERN_ALERT
- " command: 0x%x, argument: 0x%lx, minor: 0x%x\n",
- command, (long) argument, minor_dev);
- }
+ int minor_dev;
+ struct hd_geometry *geo = (struct hd_geometry *)argument;
+
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT "xenolinux_block_ioctl\n");
+
+ /* check permissions */
+ if (!capable(CAP_SYS_ADMIN)) return -EPERM;
+ if (!inode) return -EINVAL;
+ minor_dev = MINOR(inode->i_rdev);
+ if (minor_dev >= XLBLK_MAX) return -ENODEV;
+
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT " command: 0x%x, argument: 0x%lx, minor: 0x%x\n",
+ command, (long) argument, minor_dev);
- switch (command)
- {
- case BLKGETSIZE :
- {
- if (XLBLK_DEBUG_IOCTL)
- {
- printk (KERN_ALERT
- " BLKGETSIZE: %x %lx\n", BLKGETSIZE,
- (long) xen_disk_info.disks[0].capacity);
- }
- return put_user(xen_disk_info.disks[0].capacity,
- (unsigned long *) argument);
- }
- case BLKRRPART :
- {
- if (XLBLK_DEBUG_IOCTL) {
- printk (KERN_ALERT " BLKRRPART: %x\n", BLKRRPART); }
- break;
- }
- case BLKSSZGET :
- {
- if (XLBLK_DEBUG_IOCTL) {
- printk (KERN_ALERT " BLKSSZGET: %x 0x%x\n", BLKSSZGET,
- xlblk_hardsect_size[minor_dev]); }
- return xlblk_hardsect_size[minor_dev];
- }
- case HDIO_GETGEO :
- {
- struct hd_geometry *geo = (struct hd_geometry *)argument;
-
- if (XLBLK_DEBUG_IOCTL) {
- printk (KERN_ALERT " HDIO_GETGEO: %x\n", HDIO_GETGEO); }
-
- if (!argument) return -EINVAL;
- /*
- if (put_user(0x80, (byte *)&geo->heads)) return -EFAULT;
- if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT;
- if (put_user(0x20b, (unsigned short *) &geo->cylinders)) return -EFAULT;
- */
- if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
- if (put_user(0xff, (byte *)&geo->heads)) return -EFAULT;
- if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT;
- if (put_user(0x106, (unsigned short *) &geo->cylinders)) return -EFAULT;
-
- return 0;
- }
- case HDIO_GETGEO_BIG :
- {
- struct hd_big_geometry *geo = (struct hd_big_geometry *) argument;
-
- if (XLBLK_DEBUG_IOCTL) {
- printk (KERN_ALERT " HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG); }
-
- if (!argument) return -EINVAL;
- /*
- if (put_user(0x80, (byte *)&geo->heads)) return -EFAULT;
- if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT;
- if (put_user(0x20b, (unsigned int *) &geo->cylinders)) return -EFAULT;
- */
- if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
- if (put_user(0xff, (byte *)&geo->heads)) return -EFAULT;
- if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT;
- if (put_user(0x106, (unsigned int *) &geo->cylinders)) return -EFAULT;
-
- return 0;
- }
- default :
- {
- if (XLBLK_DEBUG_IOCTL) {
- printk (KERN_ALERT " eh? unknown ioctl\n"); }
- break;
- }
- }
+ switch (command) {
+
+ case BLKGETSIZE:
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT
+ " BLKGETSIZE: %x %lx\n", BLKGETSIZE,
+ (long) xen_disk_info.disks[0].capacity);
+ return put_user(xen_disk_info.disks[0].capacity,
+ (unsigned long *) argument);
+
+ case BLKRRPART:
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT " BLKRRPART: %x\n", BLKRRPART);
+ break;
+
+ case BLKSSZGET:
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT " BLKSSZGET: %x 0x%x\n", BLKSSZGET,
+ xlblk_hardsect_size[minor_dev]);
+ return xlblk_hardsect_size[minor_dev];
+
+ case HDIO_GETGEO:
+
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT " HDIO_GETGEO: %x\n", HDIO_GETGEO);
+
+ if (!argument) return -EINVAL;
+ if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
+ if (put_user(0xff, (byte *)&geo->heads)) return -EFAULT;
+ if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT;
+ if (put_user(0x106, (unsigned short *)&geo->cylinders)) return -EFAULT;
+ return 0;
+
+ case HDIO_GETGEO_BIG:
+
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT " HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG);
+
+ if (!argument) return -EINVAL;
+ if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
+ if (put_user(0xff, (byte *)&geo->heads)) return -EFAULT;
+ if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT;
+ if (put_user(0x106, (unsigned int *) &geo->cylinders)) return -EFAULT;
- return 0;
+ return 0;
+
+ default:
+ if (XLBLK_DEBUG_IOCTL)
+ printk (KERN_ALERT " eh? unknown ioctl\n");
+ break;
+ }
+
+ return 0;
}
static int xenolinux_block_check(kdev_t dev)
{
- if (XLBLK_DEBUG) {
- printk (KERN_ALERT "xenolinux_block_check\n"); }
- return 0;
+ if (XLBLK_DEBUG)
+ printk (KERN_ALERT "xenolinux_block_check\n");
+ return 0;
}
static int xenolinux_block_revalidate(kdev_t dev)
{
- if (XLBLK_DEBUG) {
- printk (KERN_ALERT "xenolinux_block_revalidate\n"); }
- return 0;
+ if (XLBLK_DEBUG)
+ printk (KERN_ALERT "xenolinux_block_revalidate\n");
+ return 0;
}
/*
@@ -230,110 +203,88 @@ void hypervisor_request(void * id,
kdev_t device,
int mode)
{
- blk_ring_t *blk_ring = start_info.blk_ring;
- int position;
- void *buffer_pa, *buffer_ma;
- kdev_t phys_device = (kdev_t) 0;
- unsigned long sector_number = 0;
-
-#if 0
- printk(KERN_ALERT "[%x]", id);
- printk (KERN_ALERT
- "xlblk_req: id:%p op:%d, bf:%p, blk:%lu, sz:%u, dev:%x\n",
- id, operation, buffer, block_number, block_size, device);
-#endif
+ blk_ring_t *blk_ring = start_info.blk_ring;
+ int position;
+ void *buffer_pa, *buffer_ma;
+ kdev_t phys_device = (kdev_t) 0;
+ unsigned long sector_number = 0;
+ struct gendisk *gd;
+
- /* XXX SMH: now need to convert guest virtual address to machine address */
- buffer_pa = (void *)virt_to_phys((unsigned long)buffer);
- buffer_ma = (void *)phys_to_machine((unsigned long)buffer_pa);
+ buffer_pa = (void *)virt_to_phys(buffer);
+ buffer_ma = (void *)phys_to_machine((unsigned long)buffer_pa);
+
+ if (operation == XEN_BLOCK_PROBE) {
+ phys_device = (kdev_t) 0;
+ sector_number = 0;
+
+ } else if (operation == XEN_BLOCK_READ || operation == XEN_BLOCK_WRITE) {
+
+ /*
+ * map logial major device to the physical device number
+ *
+ * XLBLK_MAJOR -> IDE0_MAJOR (123 -> 3)
+ */
+ if (MAJOR(device) == XLBLK_MAJOR)
+ phys_device = MKDEV(IDE0_MAJOR, 0);
+ else {
+ printk (KERN_ALERT "error: xl_block::hypervisor_request: "
+ "unknown device [0x%x]\n", device);
+ BUG();
+ }
-#if 0
- printk(KERN_ALERT "va %p => pa %p => ma %p\n", buffer, buffer_pa, buffer_ma);
-#endif
+ /*
+ * compute real buffer location on disk
+ * (from ll_rw_block.c::submit_bh)
+ */
- if (operation == XEN_BLOCK_PROBE)
- {
- phys_device = (kdev_t) 0;
- sector_number = 0;
- }
- else if (operation == XEN_BLOCK_READ || operation == XEN_BLOCK_WRITE)
- {
- /*
- * map logial major device to the physical device number
- *
- * XLBLK_MAJOR -> IDE0_MAJOR (123 -> 3)
- */
- if (MAJOR(device) == XLBLK_MAJOR)
- {
- phys_device = MKDEV(IDE0_MAJOR, 0);
- }
- else
- {
- printk (KERN_ALERT
- "error: xl_block::hypervisor_request: unknown device [0x%x]\n",
- device);
- BUG();
- }
-
- /*
- * compute real buffer location on disk
- * (from ll_rw_block.c::submit_bh)
- */
- {
- int idx = 0;
- struct gendisk *gd = (struct gendisk *) xen_disk_info.disks[idx].gendisk;
- unsigned int minor = MINOR(device);
+ sector_number = block_number /* * block_size >> 9 */;
+
+ if((gd = (struct gendisk *)xen_disk_info.disks[0].gendisk) != NULL)
+ sector_number += gd->part[MINOR(device)&IDE_PARTN_MASK].start_sect;
+ }
- sector_number = block_number /* * block_size >> 9 */;
- if (gd != NULL) /* if we have a partition table... */
- {
- sector_number += gd->part[minor & IDE_PARTN_MASK].start_sect;
- }
+ if (BLK_TX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons) {
+ printk (KERN_ALERT "hypervisor_request: btx_cons: %d, btx_prod:%d",
+ blk_ring->btx_cons, blk_ring->btx_prod);
+ BUG();
}
- }
-
- /*
- * CHECK TO SEE IF THERE IS SPACE IN THE RING
- */
- if (BLK_TX_RING_INC(blk_ring->tx_prod) == blk_ring->tx_cons)
- {
- printk (KERN_ALERT "hypervisor_request: tx_cons: %d, tx_prod:%d",
- blk_ring->tx_cons, blk_ring->tx_prod);
- }
-
- /* fill out a communications ring structure
- and then trap into the hypervisor */
- position = blk_ring->tx_prod;
- blk_ring->tx_ring[position].id = id;
- blk_ring->tx_ring[position].priority = mode;
- blk_ring->tx_ring[position].operation = operation;
- blk_ring->tx_ring[position].buffer = buffer_ma;
- blk_ring->tx_ring[position].block_number = block_number;
- blk_ring->tx_ring[position].block_size = block_size;
- blk_ring->tx_ring[position].device = phys_device;
- blk_ring->tx_ring[position].sector_number = sector_number;
-
- blk_ring->tx_prod = BLK_TX_RING_INC(blk_ring->tx_prod);
-
- if (mode == XEN_BLOCK_SYNC)
- {
- /* trap into hypervisor */
- HYPERVISOR_block_io_op();
- }
- else if (mode == XEN_BLOCK_ASYNC)
- {
- /* for now, do nothing. the request will go in the ring and
- the next sync request will trigger the hypervisor to act */
- }
- else
- {
- /* ummm, unknown mode. */
- BUG();
- }
-
- return;
+
+ /* Fill out a communications ring structure & trap to the hypervisor */
+ position = blk_ring->btx_prod;
+ blk_ring->btx_ring[position].id = id;
+ blk_ring->btx_ring[position].priority = mode;
+ blk_ring->btx_ring[position].operation = operation;
+ blk_ring->btx_ring[position].buffer = buffer_ma;
+ blk_ring->btx_ring[position].block_number = block_number;
+ blk_ring->btx_ring[position].block_size = block_size;
+ blk_ring->btx_ring[position].device = phys_device;
+ blk_ring->btx_ring[position].sector_number = sector_number;
+
+ blk_ring->btx_prod = BLK_TX_RING_INC(blk_ring->btx_prod);
+
+ switch(mode) {
+
+ case XEN_BLOCK_SYNC:
+ /* trap into hypervisor */
+ HYPERVISOR_block_io_op();
+ break;
+
+ case XEN_BLOCK_ASYNC:
+ /* for now, do nothing. the request will go in the ring and
+ the next sync request will trigger the hypervisor to act */
+ printk("Oh dear-- ASYNC xen block of doom!\n");
+ break;
+
+ default:
+ /* ummm, unknown mode. */
+ printk("xl_block thingy: unknown mode %d\n", mode);
+ BUG();
+ }
+
+ return;
}
@@ -345,138 +296,82 @@ void hypervisor_request(void * id,
* TO DO: should probably release the io_request_lock and then re-acquire
* (see LDD p. 338)
*/
-
static void do_xlblk_request (request_queue_t *rq)
{
- struct request *req;
-
- if (XLBLK_DEBUG)
- {
- printk (KERN_ALERT "xlblk.c::do_xlblk_request for '%s'\n", DEVICE_NAME);
- }
-
- while (!QUEUE_EMPTY)
- {
- struct buffer_head *bh;
- unsigned long offset;
- unsigned long length;
- int rw;
-
- req = CURRENT;
-
- if (XLBLK_DEBUG)
- {
- printk (KERN_ALERT
- "do_xlblk_request %p: cmd %i, sec %lx, (%li) bh:%p\n",
- req, req->cmd, req->sector,
- req->current_nr_sectors, req->bh);
- }
-
- /* is there space in the tx ring for this request?
- * if the ring is full, then leave the request in the queue
- *
- * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING TX_CONS
- * AT THE SAME TIME
- */
- {
- blk_ring_t *blk_ring = start_info.blk_ring;
-
- if (BLK_RX_RING_INC(blk_ring->tx_prod) == blk_ring->tx_cons)
- {
- printk (KERN_ALERT "OOPS, TX LOOKS FULL cons: %d prod: %d\n",
- blk_ring->tx_cons, blk_ring->tx_prod);
- break;
- }
- }
-
- req->errors = 0;
- blkdev_dequeue_request(req);
-
- bh = req->bh;
-
- while (bh)
- {
-
- offset = bh->b_rsector << 9;
- length = bh->b_size;
+ struct request *req;
- rw = req->cmd;
- if (rw == READA) rw= READ;
- if ((rw != READ) && (rw != WRITE))
- {
- printk (KERN_ALERT
- "XenoLinux Virtual Block Device: bad command: %d\n", rw);
- BUG();
- }
-
- /*
if (XLBLK_DEBUG)
+ printk (KERN_ALERT "xlblk.c::do_xlblk_request for '%s'\n",
+ DEVICE_NAME);
+
+ while (!QUEUE_EMPTY)
{
- printk (KERN_ALERT "xlblk.c::do_xlblk_request\n");
- printk (KERN_ALERT " b_blocknr: 0x%lx %ld\n",
- bh->b_blocknr, bh->b_blocknr);
- printk (KERN_ALERT " b_size: 0x%x %d\n", bh->b_size, bh->b_size);
- printk (KERN_ALERT " b_dev: 0x%x %d\n", bh->b_dev, bh->b_dev);
- printk (KERN_ALERT " b_rsector: 0x%lx %ld\n",
- bh->b_rsector, bh->b_rsector);
- }
- */
+ struct buffer_head *bh;
+ unsigned long offset;
+ unsigned long length;
+ int rw;
+
+ if(rq->plugged)
+ return ;
+
+ req = CURRENT;
+
+ if (XLBLK_DEBUG)
+ printk (KERN_ALERT
+ "do_xlblk_request %p: cmd %i, sec %lx, (%li) bh:%p\n",
+ req, req->cmd, req->sector,
+ req->current_nr_sectors, req->bh);
+
+ /* is there space in the tx ring for this request?
+ * if the ring is full, then leave the request in the queue
+ *
+ * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING BTX_CONS
+ * AT THE SAME TIME
+ */
+ {
+ blk_ring_t *blk_ring = start_info.blk_ring;
+
+ if (BLK_RX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons)
+ {
+ printk (KERN_ALERT "OOPS, TX LOOKS FULL cons: %d prod: %d\n",
+ blk_ring->btx_cons, blk_ring->btx_prod);
+ BUG();
+ break;
+ }
+ }
+
+ req->errors = 0;
+ blkdev_dequeue_request(req);
+
+ bh = req->bh;
+
+ while (bh)
+ {
+ offset = bh->b_rsector << 9;
+ length = bh->b_size;
+
+ rw = req->cmd;
+ if (rw == READA) rw= READ;
+ if ((rw != READ) && (rw != WRITE)) {
+ printk (KERN_ALERT
+ "XenoLinux Virtual Block Device: bad cmd: %d\n", rw);
+ BUG();
+ }
+
+ hypervisor_request (req, rw == READ ?
+ XEN_BLOCK_READ : XEN_BLOCK_WRITE,
+ bh->b_data, bh->b_rsector, bh->b_size,
+ bh->b_dev, XEN_BLOCK_SYNC);
+ bh = bh->b_reqnext;
+ }
- hypervisor_request (req, rw == READ ? XEN_BLOCK_READ : XEN_BLOCK_WRITE,
- bh->b_data, bh->b_rsector, bh->b_size,
- bh->b_dev, XEN_BLOCK_SYNC);
+ blkdev_dequeue_request(req);
- bh = bh->b_reqnext;
}
- }
- return;
+ return;
}
-/*
- * xenolinux_block_request
- *
- * read a block without using a request queue
- */
-
-static int xenolinux_block_request(request_queue_t *rq,
- int rw,
- struct buffer_head *bh)
-{
- unsigned int minor;
- unsigned long offset;
- unsigned long length;
-
- if (XLBLK_DEBUG) {
- printk (KERN_ALERT "xlblk.c::xenolinux_block_request: %lx %d %lx\n",
- (unsigned long) rq, rw, (unsigned long) bh); }
- /*
- printk (KERN_ALERT "xlblk.c::xlblk_request: op:%d bh:%p sect:%lu sz:%u\n",
- rw, bh, bh->b_rsector, bh->b_size);
- */
-
- minor = MINOR(bh->b_rdev);
-
- offset = bh->b_rsector << 9;
- length = bh->b_size;
-
- if (rw == READA) rw= READ;
- if ((rw != READ) && (rw != WRITE))
- {
- printk (KERN_ALERT
- "XenoLinux Virtual Block Device: bad command: %d\n", rw);
- goto fail;
- }
-
- hypervisor_request (bh, rw == READ ? XEN_BLOCK_READ : XEN_BLOCK_WRITE,
- bh->b_data, bh->b_rsector, bh->b_size,
- bh->b_dev, XEN_BLOCK_SYNC);
-
- return 0;
-
- fail:
- return 0;
-}
static struct block_device_operations xenolinux_block_fops =
{
@@ -489,335 +384,208 @@ static struct block_device_operations xenolinux_block_fops =
static void xlblk_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
- xlblk_device_t *dev = (xlblk_device_t *)dev_id;
- blk_ring_t *blk_ring = start_info.blk_ring;
- struct buffer_head *bh;
- struct request *req;
- int loop;
-
- for (loop = blk_ring->rx_cons;
- loop != blk_ring->rx_prod;
- loop = BLK_RX_RING_INC(loop))
- {
- blk_ring_entry_t *bret = &blk_ring->rx_ring[loop];
- void *buffer_pa, *buffer_va;
-
- buffer_pa = machine_to_phys((unsigned long)bret->buffer);
- buffer_va = phys_to_virt((unsigned long)buffer_pa);
+ blk_ring_t *blk_ring = start_info.blk_ring;
+ struct request *req;
+ int loop;
+ u_long flags;
-#if 0
- printk(KERN_ALERT "xlblk_rx_int: buffer ma %p => pa %p => va %p\n",
- bret->buffer, buffer_pa, buffer_va);
-
-
- if (XLBLK_DEBUG)
- {
- printk (KERN_ALERT
- "xlblock::xlblk_rx_int [%s]\n",
- (bret->operation == XEN_BLOCK_READ) ? "read" : "write");
- printk (KERN_ALERT
- " vbuf: %lx, pbuf: %lx, blockno: %lx, size: %x, device %x\n",
- (unsigned long) buffer_va, (unsigned long) bret->buffer,
- bret->block_number, bret->block_size, bret->device);
- printk (KERN_ALERT " bret: %p bh: %p\n", bret, bret->id);
- }
-
- /*
- printk (KERN_ALERT
- "xlblk_rx: id:%p op:%d, bf:%p, blk:%lu, sz:%u, dev:%x\n",
- bret->id, bret->operation, bret->buffer, bret->block_number,
- bret->block_size, bret->device);
- */
-#endif
-
- if (USE_REQUEST_QUEUE)
- {
- req = (struct request *)bret->id;
- printk(KERN_ALERT "|%x|", req);
-
- if (!end_that_request_first(req, 1, "NAME"))
- {
- blkdev_dequeue_request(req);
-
- /* should be end_that_request_last(req)
- to wake up waiting processes (with complete) */
- blkdev_release_request(req);
- }
-
- /*
- if (XLBLK_DEBUG)
- {
- int temp;
- printk(KERN_ALERT
- "buff: 0x%p, blkno: 0x%lx, size: 0x%x, device 0x%x [%p]\n",
- vbuffer, bret->block_number, bret->block_size, bret->device,
- bh->b_end_io);
-
- for (temp = 0; temp < bret->block_size; temp++)
- {
- if (temp % 16 == 0) printk ("[%4x] ", temp);
- else if (temp % 4 == 0) printk (" ");
- printk ("%02x",
- vbuffer[temp] & 255);
- if ((temp + 1) % 16 == 0) printk ("\n");
- }
- printk ("\n\n");
- }
- */
-
-#ifdef BOGUS
- req = (struct request *)bret->id;
- while ((bh = req->bh) != NULL)
- {
- req->bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
- bh->b_end_io(bh,1);
- }
- blkdev_release_request(req);
-#endif /* BOGUS */
+ for (loop = blk_ring->brx_cons;
+ loop != blk_ring->brx_prod;
+ loop = BLK_RX_RING_INC(loop)) {
+
+ blk_ring_entry_t *bret = &blk_ring->brx_ring[loop];
+
+ if(bret->operation == XEN_BLOCK_PROBE)
+ continue;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ req = (struct request *)bret->id;
+
+ if (!end_that_request_first(req, 1, "XenBlk"))
+ end_that_request_last(req);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
}
- else
- {
- bh = (struct buffer_head *)bret->id;
- bh->b_end_io(bh,1);
-
- /*
- if (XLBLK_DEBUG)
- {
- int temp;
-#if 0
- printk(KERN_ALERT
- "buff: 0x%p, blkno: 0x%lx, size: 0x%x, device 0x%x [%p]\n",
- vbuffer, bret->block_number, bret->block_size, bret->device,
- bh->b_end_io);
-#endif
-
- for (temp = 0; temp < bret->block_size; temp++)
- {
- if (temp % 16 == 0) printk ("[%4x] ", temp);
- else if (temp % 4 == 0) printk (" ");
- printk ("%02x",
- vbuffer[temp] & 255);
- if ((temp + 1) % 16 == 0) printk ("\n");
- }
- printk ("\n\n");
- }
- */
- }
- }
-
- blk_ring->rx_cons = loop;
+
+ blk_ring->brx_cons = loop;
}
static void xlblk_tx_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
- if (XLBLK_DEBUG) {
- printk (KERN_ALERT "--- xlblock::xlblk_tx_int\n"); }
+ if (XLBLK_DEBUG)
+ printk (KERN_ALERT "--- xlblock::xlblk_tx_int\n");
}
int __init xlblk_init(void)
{
- blk_ring_t *blk_ring = start_info.blk_ring;
- int loop, error, result;
-
- /*
- * initialize memory rings to communicate with hypervisor
- */
-
- if ( blk_ring == NULL ) return -ENOMEM;
-
- blk_ring->tx_prod = blk_ring->tx_cons = 0;
- blk_ring->rx_prod = blk_ring->rx_cons = 0;
- blk_ring->tx_ring = NULL;
- blk_ring->rx_ring = NULL;
-
- blk_ring->tx_ring = kmalloc(BLK_TX_RING_SIZE * sizeof(blk_ring_entry_t),
- GFP_KERNEL);
- blk_ring->rx_ring = kmalloc(BLK_RX_RING_SIZE * sizeof(blk_ring_entry_t),
- GFP_KERNEL);
-
- if ((blk_ring->tx_ring == NULL) ||
- (blk_ring->rx_ring == NULL))
- {
- printk (KERN_ALERT
- "error, could not allocate ring memory for block device\n");
- error = -ENOBUFS;
- goto fail;
- }
-
- /*
- * setup soft interrupts to communicate with hypervisor
- */
-
- error = request_irq(XLBLK_RX_IRQ, xlblk_rx_int, 0, "xlblk-rx",
- &xlblk_device);
- if (error)
- {
- printk(KERN_ALERT "Could not allocate receive interrupt\n");
- goto fail;
- }
-
- error = request_irq(XLBLK_TX_IRQ, xlblk_tx_int, 0, "xlblk-tx",
- &xlblk_device);
- if (error)
- {
- printk(KERN_ALERT "Could not allocate transmit interrupt\n");
- free_irq(XLBLK_RX_IRQ, &xlblk_device);
- goto fail;
- }
-
- /*
- * get information about physical drives
- *
- */
- {
- /* NOTE: this should only occur in domain 0 */
+ blk_ring_t *blk_ring = start_info.blk_ring;
+ int loop, error, result;
+
+ /* initialize memory rings to communicate with hypervisor */
+ if ( blk_ring == NULL ) return -ENOMEM;
+
+ blk_ring->btx_prod = blk_ring->btx_cons = 0;
+ blk_ring->brx_prod = blk_ring->brx_cons = 0;
+ blk_ring->btx_ring = NULL;
+ blk_ring->brx_ring = NULL;
+
+ blk_ring->btx_ring = kmalloc(BLK_TX_RING_SIZE * sizeof(blk_ring_entry_t),
+ GFP_KERNEL);
+ blk_ring->brx_ring = kmalloc(BLK_RX_RING_SIZE * sizeof(blk_ring_entry_t),
+ GFP_KERNEL);
+
+ if ((blk_ring->btx_ring == NULL) || (blk_ring->brx_ring == NULL)) {
+ printk (KERN_ALERT "could not alloc ring memory for block device\n");
+ error = -ENOBUFS;
+ goto fail;
+ }
+
+ error = request_irq(XLBLK_RX_IRQ, xlblk_rx_int, 0,
+ "xlblk-rx", &xlblk_device);
+ if (error) {
+ printk(KERN_ALERT "Could not allocate receive interrupt\n");
+ goto fail;
+ }
+
+ error = request_irq(XLBLK_TX_IRQ, xlblk_tx_int, 0,
+ "xlblk-tx", &xlblk_device);
+ if (error) {
+ printk(KERN_ALERT "Could not allocate transmit interrupt\n");
+ free_irq(XLBLK_RX_IRQ, &xlblk_device);
+ goto fail;
+ }
+
memset (&xen_disk_info, 0, sizeof(xen_disk_info));
xen_disk_info.count = 0;
hypervisor_request(NULL, XEN_BLOCK_PROBE, (char *) &xen_disk_info,
0, 0, (kdev_t) 0, XEN_BLOCK_SYNC);
-
- {
- int loop;
- for (loop = 0; loop < xen_disk_info.count; loop++)
- {
+ for (loop = 0; loop < xen_disk_info.count; loop++)
printk (KERN_ALERT " %2d: type: %d, capacity: %ld\n",
loop, xen_disk_info.disks[loop].type,
xen_disk_info.disks[loop].capacity);
- }
+
+
+ SET_MODULE_OWNER(&xenolinux_block_fops);
+ result = register_blkdev(xlblk_major, "block", &xenolinux_block_fops);
+ if (result < 0) {
+ printk (KERN_ALERT "xenolinux block: can't get major %d\n",
+ xlblk_major);
+ return result;
+ }
+
+ /* initialize global arrays in drivers/block/ll_rw_block.c */
+ for (loop = 0; loop < XLBLK_MAX; loop++) {
+ xlblk_blk_size[loop] = xen_disk_info.disks[0].capacity;
+ xlblk_blksize_size[loop] = 512;
+ xlblk_hardsect_size[loop] = 512;
+ xlblk_max_sectors[loop] = 128;
}
- }
-
- /*
- * initialize device driver
- */
-
- SET_MODULE_OWNER(&xenolinux_block_fops);
-
- result = register_blkdev(xlblk_major, "block", &xenolinux_block_fops);
- if (result < 0)
- {
- printk (KERN_ALERT "xenolinux block: can't get major %d\n", xlblk_major);
- return result;
- }
-
- /* initialize global arrays in drivers/block/ll_rw_block.c */
- blk_size[xlblk_major] = xlblk_blk_size;
- blksize_size[xlblk_major] = xlblk_blksize_size;
- hardsect_size[xlblk_major] = xlblk_hardsect_size;
- read_ahead[xlblk_major] = xlblk_read_ahead;
- max_sectors[xlblk_major] = xlblk_max_sectors;
- for (loop = 0; loop < XLBLK_MAX; loop++)
- {
- xlblk_blk_size[loop] = xen_disk_info.disks[0].capacity;
- xlblk_blksize_size[loop] = 512;
- xlblk_hardsect_size[loop] = 512;
- xlblk_read_ahead[loop] = 8;
- xlblk_max_sectors[loop] = 128;
- }
-
- if (USE_REQUEST_QUEUE)
- {
- /* NEED TO MODIFY THIS TO HANDLE MULTIPLE QUEUES
- * also, should replace do_xlblk_request with blk.h::DEVICE_REQUEST
- */
+ xlblk_read_ahead = 8;
+
+ blk_size[xlblk_major] = xlblk_blk_size;
+ blksize_size[xlblk_major] = xlblk_blksize_size;
+ hardsect_size[xlblk_major] = xlblk_hardsect_size;
+ read_ahead[xlblk_major] = xlblk_read_ahead;
+ max_sectors[xlblk_major] = xlblk_max_sectors;
+
blk_init_queue(BLK_DEFAULT_QUEUE(xlblk_major), do_xlblk_request);
+ /*
+ ** XXX SMH: we don't leave req on queue => are happy for evelator
+ ** to reorder things including it. (main reason for this decision
+ ** is that it works while 'standard' case doesn't. Ho hum).
+ */
blk_queue_headactive(BLK_DEFAULT_QUEUE(xlblk_major), 0);
- }
- else
- {
- /* we don't use __make_request in ll_rw_blk */
- blk_queue_make_request(BLK_DEFAULT_QUEUE(xlblk_major),
- xenolinux_block_request);
- }
- xlblk_ide_register_disk(0, xen_disk_info.disks[0].capacity);
-
- /*
- * completion
- */
- printk(KERN_ALERT
- "XenoLinux Virtual Block Device Driver installed [device: %d]\n",
- xlblk_major);
- return 0;
+
+ xlblk_ide_register_disk(0, xen_disk_info.disks[0].capacity);
+
+ printk(KERN_ALERT
+ "XenoLinux Virtual Block Device Driver installed [device: %d]\n",
+ xlblk_major);
+ return 0;
fail:
- if (blk_ring->tx_ring) kfree(blk_ring->tx_ring);
- if (blk_ring->rx_ring) kfree(blk_ring->rx_ring);
- return error;
+ if (blk_ring->btx_ring) kfree(blk_ring->btx_ring);
+ if (blk_ring->brx_ring) kfree(blk_ring->brx_ring);
+ return error;
}
void xlblk_ide_register_disk(int idx, unsigned long capacity)
{
- int units;
- int minors;
- struct gendisk *gd;
-
- /* plagarized from ide-probe.c::init_gendisk */
-
- units = 2; /* from ide.h::MAX_DRIVES */
-
- minors = units * (1<<IDE_PARTN_BITS);
- gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
- gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
- gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
- memset(gd->part, 0, minors * sizeof(struct hd_struct));
-
- gd->major = xlblk_major; /* our major device number */
- gd->major_name = XLBLK_MAJOR_NAME; /* treated special in genhd.c */
- gd->minor_shift = IDE_PARTN_BITS; /* num bits for partitions */
- gd->max_p = 1<<IDE_PARTN_BITS; /* 1 + max partitions / drive */
- gd->nr_real = units; /* current num real drives */
- gd->real_devices= NULL; /* ptr to internal data (was: hwif) */
- gd->next = NULL; /* linked list of major devs */
- gd->fops = &xenolinux_block_fops; /* file operations */
- gd->de_arr = kmalloc (sizeof *gd->de_arr * units, GFP_KERNEL);
- gd->flags = kmalloc (sizeof *gd->flags * units, GFP_KERNEL);
- if (gd->de_arr) memset (gd->de_arr, 0, sizeof *gd->de_arr * units);
- if (gd->flags) memset (gd->flags, 0, sizeof *gd->flags * units);
- add_gendisk(gd);
-
- xen_disk_info.disks[idx].gendisk = gd;
-
- /* default disk size is just a big number. in the future, we
- need a message to probe the devices to determine the actual size */
- register_disk(gd, MKDEV(xlblk_major, 0), 1<<IDE_PARTN_BITS,
- &xenolinux_block_fops, capacity);
-
- return;
+ int units;
+ int minors;
+ struct gendisk *gd;
+
+ /* plagarized from ide-probe.c::init_gendisk */
+
+ units = 2; /* from ide.h::MAX_DRIVES */
+
+ minors = units * (1<<IDE_PARTN_BITS);
+ gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
+ gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
+ gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
+ memset(gd->part, 0, minors * sizeof(struct hd_struct));
+
+ gd->major = xlblk_major;
+ gd->major_name = XLBLK_MAJOR_NAME;
+ gd->minor_shift = IDE_PARTN_BITS;
+ gd->max_p = 1<<IDE_PARTN_BITS;
+ gd->nr_real = units;
+ gd->real_devices = NULL;
+ gd->next = NULL;
+ gd->fops = &xenolinux_block_fops;
+ gd->de_arr = kmalloc (sizeof *gd->de_arr * units, GFP_KERNEL);
+ gd->flags = kmalloc (sizeof *gd->flags * units, GFP_KERNEL);
+
+ if (gd->de_arr)
+ memset (gd->de_arr, 0, sizeof *gd->de_arr * units);
+
+ if (gd->flags)
+ memset (gd->flags, 0, sizeof *gd->flags * units);
+
+ add_gendisk(gd);
+
+ xen_disk_info.disks[idx].gendisk = gd;
+
+ /* default disk size is just a big number. in the future, we
+ need a message to probe the devices to determine the actual size */
+ register_disk(gd, MKDEV(xlblk_major, 0), 1<<IDE_PARTN_BITS,
+ &xenolinux_block_fops, capacity);
+
+ return;
}
+
+
static void __exit xlblk_cleanup(void)
{
- /* CHANGE FOR MULTIQUEUE */
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(xlblk_major));
-
- /* clean up global arrays */
- read_ahead[xlblk_major] = 0;
- if (blk_size[xlblk_major]) kfree(blk_size[xlblk_major]);
- blk_size[xlblk_major] = NULL;
- if (blksize_size[xlblk_major]) kfree(blksize_size[xlblk_major]);
- blksize_size[xlblk_major] = NULL;
- if (hardsect_size[xlblk_major]) kfree(hardsect_size[xlblk_major]);
- hardsect_size[xlblk_major] = NULL;
-
- /*
- *
- * TODO: FOR EACH GENDISK, FREE
- *
- */
-
- if (unregister_blkdev(xlblk_major, "block"))
- {
- printk(KERN_ALERT
- "XenoLinux Virtual Block Device Driver uninstalled with errors\n");
- }
- else
- {
- printk(KERN_ALERT "XenoLinux Virtual Block Device Driver uninstalled\n");
- }
-
- return;
+ /* CHANGE FOR MULTIQUEUE */
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(xlblk_major));
+
+ /* clean up global arrays */
+ read_ahead[xlblk_major] = 0;
+
+ if (blk_size[xlblk_major])
+ kfree(blk_size[xlblk_major]);
+ blk_size[xlblk_major] = NULL;
+
+ if (blksize_size[xlblk_major])
+ kfree(blksize_size[xlblk_major]);
+ blksize_size[xlblk_major] = NULL;
+
+ if (hardsect_size[xlblk_major])
+ kfree(hardsect_size[xlblk_major]);
+ hardsect_size[xlblk_major] = NULL;
+
+ /* XXX: free each gendisk */
+ if (unregister_blkdev(xlblk_major, "block"))
+ printk(KERN_ALERT
+ "XenoLinux Virtual Block Device Driver uninstalled w/ errs\n");
+ else
+ printk(KERN_ALERT
+ "XenoLinux Virtual Block Device Driver uninstalled\n");
+
+ return;
}
diff --git a/xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c b/xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c
index c6d5c9625b..cd1cb7ca9c 100644
--- a/xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c
+++ b/xenolinux-2.4.16-sparse/drivers/block/ll_rw_blk.c
@@ -533,6 +533,8 @@ static inline void add_request(request_queue_t * q, struct request * req,
if (!q->plugged && q->head_active && insert_here == &q->queue_head) {
spin_unlock_irq(&io_request_lock);
+ printk("list_empty(&q->queue_head) is %d\n",
+ list_empty(&q->queue_head));
BUG();
}
@@ -771,6 +773,7 @@ get_rq:
req->bhtail = bh;
req->rq_dev = bh->b_rdev;
blk_started_io(count);
+
add_request(q, req, insert_here);
out:
if (freereq)
diff --git a/xenolinux-2.4.16-sparse/include/linux/blk.h b/xenolinux-2.4.16-sparse/include/linux/blk.h
index 12eb99ff16..c96120e11b 100644
--- a/xenolinux-2.4.16-sparse/include/linux/blk.h
+++ b/xenolinux-2.4.16-sparse/include/linux/blk.h
@@ -326,7 +326,7 @@ static void floppy_off(unsigned int nr);
#elif (MAJOR_NR == XLBLK_MAJOR)
-#define DEVICE_NAME "blk"
+#define DEVICE_NAME "xeno disk"
#define DEVICE_REQUEST do_xlblk_request
/* #define DEVICE_INTR */
#define DEVICE_NR(device) (MINOR(device))
diff --git a/xenolinux-2.4.16-sparse/init/main.c b/xenolinux-2.4.16-sparse/init/main.c
index a48a7773b8..f2047ce611 100644
--- a/xenolinux-2.4.16-sparse/init/main.c
+++ b/xenolinux-2.4.16-sparse/init/main.c
@@ -149,7 +149,7 @@ static struct dev_name_struct {
const int num;
} root_dev_names[] __initdata = {
{ "nfs", 0x00ff },
- { "blk", 0x7b00 },
+ { "xhda", 0x7b00 },
{ "hda", 0x0300 },
{ "hdb", 0x0340 },
{ "loop", 0x0700 },