aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.21-pre4-sparse
diff options
context:
space:
mode:
authorach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>2003-02-26 19:17:32 +0000
committerach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>2003-02-26 19:17:32 +0000
commita474d07ad6848eb61c591d57ff64400d66cd9007 (patch)
tree8ea698bf53a6faa850ef9c63dc0659c0feb5db01 /xenolinux-2.4.21-pre4-sparse
parent5f8cbb69be187519af9ecee587d5152be1c00cc2 (diff)
parent47b95f44ede3bb13fd5d22e29921255274f87926 (diff)
downloadxen-a474d07ad6848eb61c591d57ff64400d66cd9007.tar.gz
xen-a474d07ad6848eb61c591d57ff64400d66cd9007.tar.bz2
xen-a474d07ad6848eb61c591d57ff64400d66cd9007.zip
bitkeeper revision 1.106 (3e5d12ccK5E6c5JC__10GKs1f6x0fw)
Merge labyrinth.cl.cam.ac.uk:/usr/groups/xeno/BK/xeno.bk into labyrinth.cl.cam.ac.uk:/anfs/scratch/boulderdash/ach61/xeno/xeno.bk
Diffstat (limited to 'xenolinux-2.4.21-pre4-sparse')
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile2
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c25
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c43
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c275
-rw-r--r--xenolinux-2.4.21-pre4-sparse/drivers/block/ll_rw_blk.c1
5 files changed, 336 insertions, 10 deletions
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile
index 74a0c6c565..c6d1c7dc63 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile
@@ -1,3 +1,3 @@
O_TARGET := blk.o
-obj-y := xl_block.o xl_block_test.o
+obj-y := xl_block.o xl_segment.o xl_block_test.o
include $(TOPDIR)/Rules.make
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c
index 0b77e5536e..6e7e713c86 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c
@@ -22,6 +22,7 @@
#include <asm/hypervisor-ifs/block.h>
#include <asm/hypervisor-ifs/hypervisor-if.h>
#include <asm/io.h>
+#include <asm/atomic.h>
#include <asm/uaccess.h>
#define MAJOR_NR XLBLK_MAJOR /* force defns in blk.h, must precede include */
@@ -58,6 +59,7 @@ static int xlblk_max_sectors[XLBLK_MAX];
static blk_ring_t *blk_ring;
static unsigned int resp_cons; /* Response consumer for comms ring. */
static xen_disk_info_t xen_disk_info;
+atomic_t xlblk_control_count;
int hypervisor_request(void * id,
int operation,
@@ -166,7 +168,7 @@ static int xenolinux_block_revalidate(kdev_t dev)
* virtual address in the guest os.
* block_number: block to read
* block_size: size of each block
- * device: ide/hda is 768 or 0x300
+ * device: ide/hda is 768 or 0x300 should be disk#!!!
*/
int hypervisor_request(void * id,
int operation,
@@ -193,6 +195,8 @@ int hypervisor_request(void * id,
switch ( operation )
{
+ case XEN_BLOCK_SEG_CREATE:
+ case XEN_BLOCK_SEG_DELETE:
case XEN_BLOCK_PROBE:
phys_device = (kdev_t) 0;
sector_number = 0;
@@ -321,7 +325,21 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs)
i = BLK_RING_INC(i) )
{
blk_ring_resp_entry_t *bret = &blk_ring->ring[i].resp;
- if ( (bh = bret->id) != NULL ) bh->b_end_io(bh, 1);
+ switch (bret->operation)
+ {
+ case XEN_BLOCK_READ :
+ case XEN_BLOCK_WRITE :
+ if ( (bh = bret->id) != NULL ) bh->b_end_io(bh, 1);
+ break;
+
+ case XEN_BLOCK_SEG_CREATE :
+ case XEN_BLOCK_SEG_DELETE :
+ atomic_dec(&xlblk_control_count);
+ break;
+
+ default:
+ break;
+ }
}
resp_cons = i;
@@ -337,6 +355,8 @@ int __init xlblk_init(void)
{
int i, error, result;
+ atomic_set(&xlblk_control_count, 0);
+
/* This mapping was created early at boot time. */
blk_ring = (blk_ring_t *)fix_to_virt(FIX_BLKRING_BASE);
blk_ring->req_prod = blk_ring->resp_prod = resp_cons = 0;
@@ -356,6 +376,7 @@ int __init xlblk_init(void)
BUG();
HYPERVISOR_block_io_op();
while ( blk_ring->resp_prod != 1 ) barrier();
+ printk (KERN_ALERT "block device probe:\n");
for ( i = 0; i < xen_disk_info.count; i++ )
{
printk (KERN_ALERT " %2d: type: %d, capacity: %ld\n",
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c
index 2ddef271e5..8d695689ba 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c
@@ -138,6 +138,11 @@ int proc_write_bdt(struct file *file, const char *buffer,
sscanf(local, "%c %i %i %i",
&opcode, &block_number, &block_size, &device);
+ if (data)
+ {
+ kfree(data);
+ }
+
if (opcode == 'r' || opcode == 'R')
{
meta.operation = XEN_BLOCK_READ;
@@ -151,6 +156,31 @@ int proc_write_bdt(struct file *file, const char *buffer,
meta.operation = XEN_BLOCK_DEBUG;
block_size = 10000;
}
+ else if (opcode == 'c' || opcode == 'C')
+ {
+ xv_disk_t *xvd;
+ int loop;
+
+ meta.operation = XEN_BLOCK_SEG_CREATE;
+ data = kmalloc (sizeof(xv_disk_t), GFP_KERNEL);
+ if (data == NULL)
+ {
+ kfree(local);
+ return -ENOMEM;
+ }
+
+ xvd = (xv_disk_t *)data;
+ xvd->mode = XEN_DISK_READ_WRITE;
+ xvd->domain = block_number;
+ xvd->segment = block_size;
+ xvd->ext_count = device;
+ for (loop = 0; loop < xvd->ext_count; loop++)
+ {
+ xvd->extents[loop].disk = block_number + 1; /* random */
+ xvd->extents[loop].offset = block_size + 1;
+ xvd->extents[loop].size = device + 1;
+ }
+ }
else
{
printk(KERN_ALERT
@@ -158,15 +188,14 @@ int proc_write_bdt(struct file *file, const char *buffer,
return -EINVAL;
}
- if (data)
- {
- kfree(data);
- }
- data = kmalloc(block_size * sizeof(char), GFP_KERNEL);
if (data == NULL)
{
- kfree(local);
- return -ENOMEM;
+ data = kmalloc(block_size * sizeof(char), GFP_KERNEL);
+ if (data == NULL)
+ {
+ kfree(local);
+ return -ENOMEM;
+ }
}
meta.block_number = block_number;
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c
new file mode 100644
index 0000000000..da14be14df
--- /dev/null
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c
@@ -0,0 +1,275 @@
+/*
+ * xl_segment.c
+ *
+ * XenoLinux virtual disk driver.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+
+#include <asm/hypervisor-ifs/block.h>
+#include <asm/hypervisor-ifs/hypervisor-if.h>
+
+static struct proc_dir_entry *vhd;
+xv_disk_t xvd;
+
+extern atomic_t xlblk_control_count; /* xl_block.c */
+
+/******************************************************************/
+
+static int proc_read_vhd(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ return 0;
+}
+
+#define isdelim(c) \
+ (c==' '||c==','||c=='\n'||c=='\r'||c=='\t'||c==':'||c=='('||c==')' ? 1 : 0)
+
+char *get_string(char *string) /* a bit like strtok */
+{
+ static char *temp;
+ int loop = 0;
+
+ if (string != NULL)
+ temp = string;
+ else
+ string = temp;
+
+ try_again:
+
+ while (!isdelim(string[loop]))
+ {
+ if (string[loop] == '\0')
+ return NULL;
+ loop++;
+ }
+
+ string[loop] = '\0';
+ temp = (string + loop + 1);
+
+ if (loop == 0)
+ {
+ string = temp;
+ goto try_again;
+ }
+
+ return string;
+}
+
+
+#define isdigit(c) (c >= '0' && c <= '9' ? 1 : 0)
+unsigned long to_number(char *string) /* atoi */
+{
+ unsigned long value = 0;
+
+ if (string == NULL) return 0;
+
+ while (!isdigit(*string) && *string != '\0') string++;
+
+ while (isdigit(*string))
+ {
+ value = value * 10 + (*string - '0');
+ string++;
+ }
+
+ return value;
+}
+
+static int proc_write_vhd(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ char *local = kmalloc((count + 1) * sizeof(char), GFP_KERNEL);
+ char *string;
+ int loop;
+ int counter;
+ xv_disk_t xvd;
+
+ memset (&xvd, 0, sizeof(xvd));
+
+ if (copy_from_user(local, buffer, count))
+ {
+ return -EFAULT;
+ }
+ local[count] = '\0';
+
+ string = get_string(local); /* look for Domain */
+ if (string == NULL) /* empty string */
+ {
+ return count;
+ }
+ if (*string != 'd' && *string != 'D')
+ {
+ printk (KERN_ALERT
+ "error: domain specifier missing [%s]. should be \"domain\".\n",
+ string);
+ return count;
+ }
+
+ string = get_string(NULL); /* domain number */
+ if (string == NULL)
+ {
+ printk (KERN_ALERT "error: domain number missing\n");
+ return count;
+ }
+ xvd.domain = (int) to_number(string);
+
+ string = get_string(NULL);
+ if (string && (strcmp(string, "RO") == 0 || strcmp(string, "ro") == 0))
+ {
+ xvd.mode = XEN_DISK_READ_ONLY;
+ }
+ else if (string && (strcmp(string, "RW") == 0 || strcmp(string, "rw") == 0))
+ {
+ xvd.mode = XEN_DISK_READ_ONLY;
+ }
+ else
+ {
+ printk (KERN_ALERT
+ "error: bad mode [%s]. should be \"rw\" or \"ro\".\n",
+ string);
+ return count;
+ }
+
+ string = get_string(NULL); /* look for Segment */
+ if (string == NULL || (*string != 's' && *string != 'S'))
+ {
+ printk (KERN_ALERT
+ "error: segment specifier missing [%s]. should be \"segment\".\n",
+ string);
+ return count;
+ }
+
+ string = get_string(NULL); /* segment number */
+ if (string == NULL)
+ {
+ printk (KERN_ALERT "error: segment number missing\n");
+ return count;
+ }
+ xvd.segment = (int) to_number(string);
+
+ string = get_string(NULL); /* look for Extents */
+ if (string == NULL || (*string != 'e' && *string != 'E'))
+ {
+ printk (KERN_ALERT
+ "error: extents specifier missing [%s]. should be \"extents\".\n",
+ string);
+ return count;
+ }
+
+ string = get_string(NULL); /* number of extents */
+ if (string == NULL)
+ {
+ printk (KERN_ALERT "error: number of extents missing\n");
+ return count;
+ }
+ xvd.ext_count = (int) to_number(string);
+
+ /* ignore parenthesis */
+
+ for (loop = 0; loop < xvd.ext_count; loop++)
+ {
+ string = get_string(NULL); /* look for Disk */
+ if (string == NULL || (*string != 'd' && *string != 'D'))
+ {
+ printk (KERN_ALERT
+ "hmm, extent disk specifier missing [%s]. should be \"disk\".\n",
+ string);
+ return count;
+ }
+ string = get_string(NULL); /* disk number */
+ if (string == NULL)
+ {
+ printk (KERN_ALERT "error: disk number missing\n");
+ return count;
+ }
+ xvd.extents[loop].disk = (int) to_number(string);
+
+ string = get_string(NULL); /* look for Offset */
+ if (string == NULL || (*string != 'o' && *string != 'O'))
+ {
+ printk (KERN_ALERT
+ "error: disk offset missing [%s]. should be \"offset\".\n",
+ string);
+ return count;
+ }
+ string = get_string(NULL); /* offset */
+ if (string == NULL)
+ {
+ printk (KERN_ALERT "error: offset missing\n");
+ return count;
+ }
+ xvd.extents[loop].offset = to_number(string);
+
+ string = get_string(NULL); /* look for Size */
+ if (string == NULL || (*string != 's' && *string != 'S'))
+ {
+ printk (KERN_ALERT
+ "error: extent size missing [%s]. should be \"size\".\n",
+ string);
+ return count;
+ }
+ string = get_string(NULL); /* size */
+ if (string == NULL)
+ {
+ printk (KERN_ALERT "error: extent size missing\n");
+ return count;
+ }
+ xvd.extents[loop].size = to_number(string);
+ }
+
+ {
+ /* get lock xlblk_control_lock */
+ counter = atomic_read(&xlblk_control_count);
+ atomic_inc(&xlblk_control_count);
+ /* release lock xlblk_control_lock */
+ }
+
+ hypervisor_request (NULL, XEN_BLOCK_SEG_CREATE, (char *)&xvd,
+ 0, 0, (kdev_t) 0);
+ HYPERVISOR_block_io_op();
+
+ while (atomic_read(&xlblk_control_count) != counter) barrier();
+
+ /* while ( blk_ring->resp_prod != 1 ) barrier(); */
+
+ /* mdelay(1000); */
+
+ return count;
+}
+
+/******************************************************************/
+
+int __init xlseg_init(void)
+{
+ vhd = create_proc_entry("xeno/dom0/vhd", 0644, NULL);
+ if (vhd == NULL)
+ {
+ panic ("xlseg_init: unable to create vhd proc entry\n");
+ }
+ vhd->data = NULL;
+ vhd->read_proc = proc_read_vhd;
+ vhd->write_proc = proc_write_vhd;
+ vhd->owner = THIS_MODULE;
+
+ memset(&xvd, 0, sizeof(xvd));
+
+ printk(KERN_ALERT "XenoLinux Virtual Disk Device Driver installed\n");
+ return 0;
+}
+
+static void __exit xlseg_cleanup(void)
+{
+ printk(KERN_ALERT "XenoLinux Virtual Disk Device Driver uninstalled\n");
+}
+
+#ifdef MODULE
+module_init(xlseg_init);
+module_exit(xlseg_cleanup);
+#endif
diff --git a/xenolinux-2.4.21-pre4-sparse/drivers/block/ll_rw_blk.c b/xenolinux-2.4.21-pre4-sparse/drivers/block/ll_rw_blk.c
index 4fd98e94a5..470b206726 100644
--- a/xenolinux-2.4.21-pre4-sparse/drivers/block/ll_rw_blk.c
+++ b/xenolinux-2.4.21-pre4-sparse/drivers/block/ll_rw_blk.c
@@ -1504,6 +1504,7 @@ int __init blk_dev_init(void)
#ifdef CONFIG_XENOLINUX_BLOCK
xlblk_init();
+ xlseg_init();
#endif
return 0;