aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.21-pre4-sparse
diff options
context:
space:
mode:
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-03-06 16:54:15 +0000
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-03-06 16:54:15 +0000
commit796305db16ed924df9d4061b70ba110e5978b226 (patch)
tree99fa4a1fe2f7b38485172dfe7720924f0178c9dc /xenolinux-2.4.21-pre4-sparse
parent454a736db481ae4527360d5630ca9cd4148567c9 (diff)
parent8e06473cff7350a2ea62c5406cf2a733ebe82478 (diff)
downloadxen-796305db16ed924df9d4061b70ba110e5978b226.tar.gz
xen-796305db16ed924df9d4061b70ba110e5978b226.tar.bz2
xen-796305db16ed924df9d4061b70ba110e5978b226.zip
bitkeeper revision 1.109 (3e677d37B9PCxHLX7a1Iufrz4eSUqA)
Manual merge of SMH + ACH worlds.
Diffstat (limited to 'xenolinux-2.4.21-pre4-sparse')
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile3
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c348
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c200
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c211
-rw-r--r--xenolinux-2.4.21-pre4-sparse/include/linux/major.h4
-rw-r--r--xenolinux-2.4.21-pre4-sparse/init/do_mounts.c8
6 files changed, 585 insertions, 189 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 594aab25b8..fd6b63f51e 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,4 @@
O_TARGET := blk.o
-obj-y := xl_block.o xl_segment.o xl_segment_proc.o xl_block_test.o
+obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o
+obj-y += xl_segment_proc.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 bc87e7eb7b..af270f1aa1 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
@@ -1,7 +1,7 @@
/******************************************************************************
* xl_block.c
*
- * Xenolinux virtual block-device driver (xhd).
+ * Xenolinux virtual block-device driver.
*
*/
@@ -25,22 +25,23 @@
#include <asm/atomic.h>
#include <asm/uaccess.h>
-#define MAJOR_NR XLBLK_MAJOR /* force defns in blk.h, must precede include */
-static int xlblk_major = XLBLK_MAJOR;
#include <linux/blk.h>
/* Copied from linux/ide.h */
typedef unsigned char byte;
-#define XLBLK_MAX 32 /* Maximum minor devices we support */
-#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_max_sectors[XLBLK_MAX];
+extern int xlide_init(int xidx, int idx);
+extern int xlide_hwsect(int minor);
+extern void xlide_cleanup(void);
+extern int xlscsi_init(int xidx, int idx);
+extern int xlscsi_hwsect(int minor);
+extern void xlscsi_cleanup(void);
+
+static int nide = 0; // number of IDE devices we have
+static int nscsi = 0; // number of SCSI devices we have
+
+
+#define XLBLK_MAX 32 /* XXX SMH: this the max of XLIDE_MAX and XLSCSI_MAX */
#define XLBLK_RESPONSE_IRQ _EVENT_BLK_RESP
@@ -56,6 +57,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 xlblk_disk_info;
atomic_t xlblk_control_count;
@@ -69,54 +71,139 @@ int hypervisor_request(void * id,
kdev_t device,
struct gendisk *gd);
-
/* ------------------------------------------------------------------------
*/
-static int xenolinux_block_open(struct inode *inode, struct file *filep)
+/* Convert from a XenoLinux (major,minor) to the Xen-level 'physical' device */
+static kdev_t xldev_to_physdev(kdev_t xldev)
+{
+ int xlmajor = MAJOR(xldev);
+ int major, minor;
+
+ switch(xlmajor) {
+ case XLIDE_MAJOR:
+ major = IDE0_MAJOR;
+ minor = 0; /* we do minor offsetting manually by addition */
+ break;
+
+ case XLSCSI_MAJOR:
+ major = SCSI_DISK0_MAJOR;
+ minor = 0; /* we do minor offsetting manually by addition */
+ break;
+
+ default:
+ panic("xldev_to_physdev: unhandled major %d\n", xlmajor);
+ break;
+ }
+
+ return MKDEV(major, minor);
+}
+
+
+/*
+** Locate the gendisk structure associated with a particular xenolinux disk;
+** this requires a scan of the xen_disk_info[] array currently which kind of
+** sucks. However we can clean this whole area up later (i.e. post SOSP).
+*/
+struct gendisk *xldev_to_gendisk(kdev_t xldev, int *t)
+{
+ int i, j, posn, type;
+
+ switch(MAJOR(xldev)) {
+
+ case XLIDE_MAJOR:
+ type = 1;
+ posn = 1;
+ break;
+
+ case XLSCSI_MAJOR:
+ type = 2;
+ posn = 1;
+ break;
+
+ default:
+ panic("xldev_to_gendisk: unhandled major %d\n", MAJOR(xldev));
+ break;
+ }
+
+
+ for ( i = j = 0; i < xen_disk_info.count; i++ ) {
+ if(xen_disk_info.disks[i].type == type)
+ if(++j == posn)
+ break;
+ }
+
+ if(t)
+ *t = type;
+
+ return (xen_disk_info.disks[i].gendisk);
+}
+
+int xenolinux_block_open(struct inode *inode, struct file *filep)
{
DPRINTK("xenolinux_block_open\n");
return 0;
}
-static int xenolinux_block_release(struct inode *inode, struct file *filep)
+int xenolinux_block_release(struct inode *inode, struct file *filep)
{
DPRINTK("xenolinux_block_release\n");
return 0;
}
-static int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
+
+
+int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
unsigned command, unsigned long argument)
{
- int minor_dev;
+ int minor_dev, type;
struct hd_geometry *geo = (struct hd_geometry *)argument;
-
+ struct gendisk *gd;
+ struct hd_struct *part;
+
DPRINTK("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;
DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, minor: 0x%x\n",
command, (long) argument, minor_dev);
+ gd = xldev_to_gendisk(inode->i_rdev, &type);
+ part = &gd->part[minor_dev];
+
switch (command)
{
- case BLKGETSIZE: /* get size */
- DPRINTK_IOCTL(" BLKGETSIZE: %x %lx\n", BLKGETSIZE,
- (long) xlblk_disk_info.disks[0].capacity);
- return put_user(xlblk_disk_info.disks[0].capacity,
- (unsigned long *) argument);
+ case BLKGETSIZE:
+ DPRINTK_IOCTL(" BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects);
+ return put_user(part->nr_sects, (unsigned long *) argument);
case BLKRRPART: /* re-read partition table */
DPRINTK_IOCTL(" BLKRRPART: %x\n", BLKRRPART);
break;
- case BLKBSZGET: /* get block size */
- DPRINTK_IOCTL(" BLKBSZGET: %x\n", BLKBSZGET);
- break;
+ case BLKSSZGET:
+ switch(type) {
+ case 1:
+ DPRINTK_IOCTL(" BLKSSZGET: %x 0x%x\n", BLKSSZGET,
+ xlide_hwsect(minor_dev));
+ return xlide_hwsect(minor_dev);
+ break;
+ case 2:
+ DPRINTK_IOCTL(" BLKSSZGET: %x 0x%x\n", BLKSSZGET,
+ xlscsi_hwsect(minor_dev));
+ return xlscsi_hwsect(minor_dev);
+ break;
+
+ default:
+ printk("BLKSSZGET ioctl() on bogus type %d disk!\n", type);
+ return 0;
+
+ }
case BLKBSZSET: /* set block size */
DPRINTK_IOCTL(" BLKBSZSET: %x\n", BLKBSZSET);
@@ -163,13 +250,13 @@ static int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
return 0;
}
-static int xenolinux_block_check(kdev_t dev)
+int xenolinux_block_check(kdev_t dev)
{
DPRINTK("xenolinux_block_check\n");
return 0;
}
-static int xenolinux_block_revalidate(kdev_t dev)
+int xenolinux_block_revalidate(kdev_t dev)
{
DPRINTK("xenolinux_block_revalidate\n");
return 0;
@@ -224,30 +311,13 @@ int hypervisor_request(void * id,
case XEN_BLOCK_READ:
case XEN_BLOCK_WRITE:
- /* only accept requests for xhd and vhd devices */
- if (!IS_XHD_MAJOR(MAJOR(device)) && !IS_VHD_MAJOR(MAJOR(device)))
- panic("error: xl_block::hypervisor_request: "
- "unknown device [0x%x]\n", device);
- phys_device = MAJOR(device);
-
- /* Compute real buffer location on disk.
- * note: gd will be null when we read the partition table.
- */
+ phys_device = xldev_to_physdev(device);
+ if (!IS_XHD_MAJOR(MAJOR(device)))
+ phys_device = MAJOR(device);
+ /* Compute real buffer location on disk */
sector_number = block_number;
- if ( gd != NULL )
- {
- sector_number += gd->part[MINOR(device)&IDE_PARTN_MASK].start_sect;
- }
-
- /*
- if (IS_VHD_MAJOR(MAJOR(device)))
- {
- printk (KERN_ALERT "%lx + %lx = %lx (%x)\n",
- block_number,
- gd->part[MINOR(device)&IDE_PARTN_MASK].start_sect,
- sector_number, device);
- }
- */
+ gd = xldev_to_gendisk(device, NULL);
+ sector_number += gd->part[MINOR(device)].start_sect;
break;
default:
@@ -274,7 +344,7 @@ int hypervisor_request(void * id,
* do_xlblk_request
* read a block; request is in a request queue
*/
-static void do_xlblk_request (request_queue_t *rq)
+void do_xlblk_request (request_queue_t *rq)
{
struct request *req;
struct buffer_head *bh;
@@ -282,9 +352,10 @@ static void do_xlblk_request (request_queue_t *rq)
DPRINTK("xlblk.c::do_xlblk_request for '%s'\n", DEVICE_NAME);
- while ( !rq->plugged && !QUEUE_EMPTY )
+ while ( !rq->plugged && !list_empty(&rq->queue_head))
{
- if ( (req = CURRENT) == NULL ) goto out;
+ if ( (req = blkdev_entry_next_request(&rq->queue_head)) == NULL )
+ goto out;
DPRINTK("do_xlblk_request %p: cmd %i, sec %lx, (%li/%li) bh:%p\n",
req, req->cmd, req->sector,
@@ -351,7 +422,7 @@ static struct block_device_operations xenolinux_block_fops =
static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
- int i;
+ int i;
unsigned long flags;
struct buffer_head *bh;
@@ -383,10 +454,18 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs)
resp_cons = i;
/* KAF: We can push work down at this point. We have the lock. */
- /* aho: okay, so this is a bit of a hack. we'll kick every queue... */
- do_xlblk_request(BLK_DEFAULT_QUEUE(XLBLK_MAJOR));
- do_xlseg_requestX(BLK_DEFAULT_QUEUE(XLSEG_MAJOR));
-
+ for (i = 0; i < xen_disk_info.count; i++) {
+ /*
+ ** XXX SMH: this is pretty broken ...
+ ** a) should really only kick devs w/ outstanding work
+ ** b) should cover /all/ devs, not just first IDE & SCSI
+ ** KAF will fix this I'm sure.
+ */
+ do_xlblk_request(BLK_DEFAULT_QUEUE(IDE0_MAJOR));
+ do_xlblk_request(BLK_DEFAULT_QUEUE(SCSI_DISK0_MAJOR));
+ do_xlseg_requestX(BLK_DEFAULT_QUEUE(XLSEG_MAJOR));
+ }
+
spin_unlock_irqrestore(&io_request_lock, flags);
}
@@ -419,143 +498,54 @@ int __init xlblk_init(void)
BUG();
HYPERVISOR_block_io_op();
while ( blk_ring->resp_prod != 1 ) barrier();
- printk (KERN_ALERT "xhd block device probe:\n");
for ( i = 0; i < xlblk_disk_info.count; i++ )
{
+ /*
+ ** SMH: initialize all the disks we found; this is complicated a
+ ** bit by the fact that we have both IDE and SCSI disks underneath
+ */
printk (KERN_ALERT " %2d: type: %d, capacity: %ld\n",
i, xlblk_disk_info.disks[i].type,
xlblk_disk_info.disks[i].capacity);
+
+ switch(xen_disk_info.disks[i].type) {
+ case 1:
+ xlide_init(i, nide++);
+ break;
+ case 2:
+ xlscsi_init(i, nscsi++);
+ break;
+ default:
+ printk("Unknown Xen disk type %d\n", xen_disk_info.disks[i].type);
+ break;
+ }
}
-
- 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 (i = 0; i < XLBLK_MAX; i++) {
- xlblk_blk_size[i] = xlblk_disk_info.disks[0].capacity;
- xlblk_blksize_size[i] = 512;
- xlblk_hardsect_size[i] = 512;
- xlblk_max_sectors[i] = 128;
- }
- 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);
-
- /*
- * Turn off barking 'headactive' mode. We dequeue buffer heads as
- * soon as we pass them down to Xen.
- */
- blk_queue_headactive(BLK_DEFAULT_QUEUE(xlblk_major), 0);
- xlblk_ide_register_disk(0, xlblk_disk_info.disks[0].capacity);
-
- printk(KERN_ALERT
- "XenoLinux Virtual Block Device Driver installed [device: %d]\n",
- xlblk_major);
return 0;
fail:
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;
- 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);
-
- xlblk_disk_info.disks[idx].gendisk = gd;
-
- register_disk(gd, MKDEV(xlblk_major, 0), 1<<IDE_PARTN_BITS,
- &xenolinux_block_fops, capacity);
-
- {
- int loop = 0;
- printk (KERN_ALERT "Partition Table: (capacity: %lx)\n", capacity);
- for (loop = 0; loop < minors; loop++)
- {
- if (gd->part[loop].start_sect && gd->part[loop].nr_sects)
- {
- printk (KERN_ALERT
- " %2d: 0x%6lx %8ld 0x%6lx %7ld\n", loop,
- gd->part[loop].start_sect, gd->part[loop].start_sect,
- gd->part[loop].nr_sects, gd->part[loop].nr_sects);
- }
- }
- }
-
- 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;
+ int i;
- if (blksize_size[xlblk_major])
- kfree(blksize_size[xlblk_major]);
- blksize_size[xlblk_major] = NULL;
+ for ( i = 0; i < xen_disk_info.count; i++ )
+ {
+ switch(xen_disk_info.disks[i].type) {
+ case 1:
+ xlide_cleanup();
+ break;
+ case 2:
+ xlscsi_cleanup();
+ break;
+ default:
+ printk("Unknown Xen disk type %d\n", xen_disk_info.disks[i].type);
+ break;
+ }
- 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.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c
new file mode 100644
index 0000000000..50f80038ee
--- /dev/null
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c
@@ -0,0 +1,200 @@
+/******************************************************************************
+ * xl_ide.c
+ *
+ * Xenolinux virtual IDE block-device driver.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+
+#include <linux/fs.h>
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/major.h>
+
+#define MAJOR_NR XLIDE_MAJOR /* force defns in blk.h, must precede include */
+static int xlide_major = XLIDE_MAJOR;
+#include <linux/blk.h>
+
+void xlide_ide_register_disk(int, unsigned long);
+
+#define XLIDE_MAX 32 /* Maximum minor devices we support */
+#define XLIDE_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 xlide_blk_size[XLIDE_MAX];
+static int xlide_blksize_size[XLIDE_MAX];
+static int xlide_read_ahead;
+static int xlide_hardsect_size[XLIDE_MAX];
+static int xlide_max_sectors[XLIDE_MAX];
+
+extern xen_disk_info_t xen_disk_info;
+
+
+extern int xenolinux_block_open(struct inode *inode, struct file *filep);
+extern int xenolinux_block_release(struct inode *inode, struct file *filep);
+extern int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
+ unsigned command, unsigned long argument);
+extern int xenolinux_block_check(kdev_t dev);
+extern int xenolinux_block_revalidate(kdev_t dev);
+
+
+extern void do_xlblk_request (request_queue_t *rq);
+
+
+static struct block_device_operations xlide_block_fops =
+{
+ open: xenolinux_block_open,
+ release: xenolinux_block_release,
+ ioctl: xenolinux_block_ioctl,
+ check_media_change: xenolinux_block_check,
+ revalidate: xenolinux_block_revalidate,
+};
+
+
+/* tiny inteface fn */
+int xlide_hwsect(int minor)
+{
+ return xlide_hardsect_size[minor];
+}
+
+
+void xlide_register_disk(int xidx, int idx)
+{
+ 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 = xlide_major; /* XXX should be idx-specific */
+ gd->major_name = XLIDE_MAJOR_NAME; /* XXX should be idx-specific */
+ 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 = &xlide_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[xidx].gendisk = gd;
+
+ /* XXX major should be idx-specific */
+ register_disk(gd, MKDEV(xlide_major, 0), 1<<IDE_PARTN_BITS,
+ &xlide_block_fops, xen_disk_info.disks[xidx].capacity);
+
+ return;
+}
+
+
+
+/*
+** Initialize a XenoLinux IDE disk; the 'xidx' is the index into the
+** xen_disk_info array so we can grab interesting values; the 'idx' is
+** a count of the number of XLSCSI disks we've seen so far, starting at 0
+** XXX SMH: this is all so ugly because the xen_disk_info() structure and
+** array doesn't really give us what we want. Ho hum. To be tidied someday.
+*/
+int xlide_init(int xidx, int idx)
+{
+ int i, major, result;
+
+ SET_MODULE_OWNER(&xlide_block_fops);
+
+ major = xlide_major + idx; /* XXX assume we have a linear major space */
+
+ /* XXX SMH: name below should vary with major */
+ result = register_blkdev(major, XLIDE_MAJOR_NAME, &xlide_block_fops);
+ if (result < 0) {
+ printk (KERN_ALERT "XL IDE: can't get major %d\n",
+ major);
+ return result;
+ }
+
+ /* initialize global arrays in drivers/block/ll_rw_block.c */
+ for (i = 0; i < XLIDE_MAX; i++) {
+ xlide_blk_size[i] = xen_disk_info.disks[0].capacity;
+ xlide_blksize_size[i] = 512;
+ xlide_hardsect_size[i] = 512;
+ xlide_max_sectors[i] = 128;
+ }
+ xlide_read_ahead = 8;
+
+ blk_size[major] = xlide_blk_size;
+ blksize_size[major] = xlide_blksize_size;
+ hardsect_size[major] = xlide_hardsect_size;
+ read_ahead[major] = xlide_read_ahead;
+ max_sectors[major] = xlide_max_sectors;
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(major), do_xlblk_request);
+
+ /*
+ * Turn off barking 'headactive' mode. We dequeue buffer heads as
+ * soon as we pass them down to Xen.
+ */
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);
+
+ xlide_register_disk(xidx, idx);
+
+ printk(KERN_ALERT
+ "XenoLinux Virtual IDE Device Driver installed [device: %d]\n",
+ major);
+
+ return 0;
+}
+
+
+void xlide_cleanup(void)
+{
+ /* CHANGE FOR MULTIQUEUE */
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(xlide_major));
+
+ /* clean up global arrays */
+ read_ahead[xlide_major] = 0;
+
+ if (blk_size[xlide_major])
+ kfree(blk_size[xlide_major]);
+ blk_size[xlide_major] = NULL;
+
+ if (blksize_size[xlide_major])
+ kfree(blksize_size[xlide_major]);
+ blksize_size[xlide_major] = NULL;
+
+ if (hardsect_size[xlide_major])
+ kfree(hardsect_size[xlide_major]);
+ hardsect_size[xlide_major] = NULL;
+
+ /* XXX: free each gendisk */
+ if (unregister_blkdev(xlide_major, XLIDE_MAJOR_NAME))
+ printk(KERN_ALERT
+ "XenoLinux Virtual IDE Device Driver uninstalled w/ errs\n");
+ else
+ printk(KERN_ALERT
+ "XenoLinux Virtual IDE Device Driver uninstalled\n");
+
+ return;
+}
+
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c
new file mode 100644
index 0000000000..3ee86509f1
--- /dev/null
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c
@@ -0,0 +1,211 @@
+/******************************************************************************
+ * xl_scsi.c
+ *
+ * Xenolinux virtual SCSI block-device driver.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+
+#include <linux/fs.h>
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/major.h>
+
+#define MAJOR_NR XLSCSI_MAJOR /* force defns in blk.h, must precede include */
+static int xlscsi_major = XLSCSI_MAJOR;
+#include <linux/blk.h>
+
+/* Copied from linux/ide.h */
+typedef unsigned char byte;
+
+void xlscsi_ide_register_disk(int, unsigned long);
+
+#define SCSI_DISKS_PER_MAJOR 16 /* max number of devices per scsi major */
+#define XLSCSI_MAX 32 /* maximum minor devices we support */
+#define XLSCSI_MAJOR_NAME "xsd"
+
+static int xlscsi_blk_size[XLSCSI_MAX];
+static int xlscsi_blksize_size[XLSCSI_MAX];
+static int xlscsi_read_ahead;
+static int xlscsi_hardsect_size[XLSCSI_MAX];
+static int xlscsi_max_sectors[XLSCSI_MAX];
+
+#if 0
+#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a )
+#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
+#else
+#define DPRINTK(_f, _a...) ((void)0)
+#define DPRINTK_IOCTL(_f, _a...) ((void)0)
+#endif
+
+extern xen_disk_info_t xen_disk_info;
+
+extern int xenolinux_block_open(struct inode *inode, struct file *filep);
+extern int xenolinux_block_release(struct inode *inode, struct file *filep);
+extern int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
+ unsigned command, unsigned long argument);
+extern int xenolinux_block_check(kdev_t dev);
+extern int xenolinux_block_revalidate(kdev_t dev);
+
+
+extern void do_xlblk_request (request_queue_t *rq);
+
+static struct block_device_operations xlscsi_block_fops =
+{
+ open: xenolinux_block_open,
+ release: xenolinux_block_release,
+ ioctl: xenolinux_block_ioctl,
+ check_media_change: xenolinux_block_check,
+ revalidate: xenolinux_block_revalidate,
+};
+
+
+/* tiny inteface fn */
+int xlscsi_hwsect(int minor)
+{
+ return xlscsi_hardsect_size[minor];
+}
+
+
+void xlscsi_register_disk(int xidx, int idx)
+{
+ int minors;
+ struct gendisk *gd;
+ unsigned long capacity;
+
+ minors = XLSCSI_MAX;
+ 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));
+
+ if(idx > 0)
+ printk("xlscsi_register_disk: need fix to handle "
+ "multiple SCSI majors!\n");
+
+ gd->major = xlscsi_major; /* XXX should be idx-specific */
+ gd->major_name = XLSCSI_MAJOR_NAME; /* XXX should be idx-specific */
+ gd->minor_shift = 4;
+ gd->max_p = 1<<4;
+ gd->nr_real = SCSI_DISKS_PER_MAJOR;
+ gd->real_devices = NULL;
+ gd->next = NULL;
+ gd->fops = &xlscsi_block_fops;
+ gd->de_arr = kmalloc (sizeof *gd->de_arr * SCSI_DISKS_PER_MAJOR,
+ GFP_KERNEL);
+ gd->flags = kmalloc (sizeof *gd->flags * SCSI_DISKS_PER_MAJOR,
+ GFP_KERNEL);
+
+ if (gd->de_arr)
+ memset (gd->de_arr, 0, sizeof *gd->de_arr * SCSI_DISKS_PER_MAJOR);
+
+ if (gd->flags)
+ memset (gd->flags, 0, sizeof *gd->flags * SCSI_DISKS_PER_MAJOR);
+
+ add_gendisk(gd);
+
+ xen_disk_info.disks[xidx].gendisk = gd;
+
+ /* XXX major below should be idx-specific */
+ register_disk(gd, MKDEV(xlscsi_major, 0), 1<<4, &xlscsi_block_fops,
+ xen_disk_info.disks[xidx].capacity);
+
+ return;
+}
+
+
+/*
+** Initialize a XenoLinux SCSI disk; the 'xidx' is the index into the
+** xen_disk_info array so we can grab interesting values; the 'idx' is
+** a count of the number of XLSCSI disks we've seen so far, starting at 0
+** XXX SMH: this is all so ugly because the xen_disk_info() structure and
+** array doesn't really give us what we want. Ho hum. To be tidied someday.
+*/
+int xlscsi_init(int xidx, int idx)
+{
+ int i, major, result;
+
+ SET_MODULE_OWNER(&xlscsi_block_fops);
+
+ major = xlscsi_major + idx; /* XXX asume we have linear major space */
+
+ /* XXX SMH: 'name' below should vary for different major values */
+ result = register_blkdev(major, XLSCSI_MAJOR_NAME, &xlscsi_block_fops);
+
+ if (result < 0) {
+ printk (KERN_ALERT "XL SCSI: can't get major %d\n", major);
+ return result;
+ }
+
+ /* initialize global arrays in drivers/block/ll_rw_block.c */
+ for (i = 0; i < XLSCSI_MAX; i++) {
+ xlscsi_blk_size[i] = xen_disk_info.disks[xidx].capacity;
+ xlscsi_blksize_size[i] = 512;
+ xlscsi_hardsect_size[i] = 512;
+ xlscsi_max_sectors[i] = 128;
+ }
+ xlscsi_read_ahead = 8;
+
+ blk_size[major] = xlscsi_blk_size;
+ blksize_size[major] = xlscsi_blksize_size;
+ hardsect_size[major] = xlscsi_hardsect_size;
+ read_ahead[major] = xlscsi_read_ahead;
+ max_sectors[major] = xlscsi_max_sectors;
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(major), do_xlblk_request);
+
+ /*
+ * Turn off barking 'headactive' mode. We dequeue buffer heads as
+ * soon as we pass them down to Xen.
+ */
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);
+
+ xlscsi_register_disk(xidx, idx);
+
+ printk(KERN_ALERT
+ "XenoLinux Virtual SCSI Device Driver installed [device: %d]\n",
+ major);
+ return 0;
+}
+
+
+
+void xlscsi_cleanup(void)
+{
+ /* CHANGE FOR MULTIQUEUE */
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(xlscsi_major));
+
+ /* clean up global arrays */
+ read_ahead[xlscsi_major] = 0;
+
+ if (blk_size[xlscsi_major])
+ kfree(blk_size[xlscsi_major]);
+ blk_size[xlscsi_major] = NULL;
+
+ if (blksize_size[xlscsi_major])
+ kfree(blksize_size[xlscsi_major]);
+ blksize_size[xlscsi_major] = NULL;
+
+ if (hardsect_size[xlscsi_major])
+ kfree(hardsect_size[xlscsi_major]);
+ hardsect_size[xlscsi_major] = NULL;
+
+ /* XXX: free each gendisk */
+ if (unregister_blkdev(xlscsi_major, XLSCSI_MAJOR_NAME))
+ printk(KERN_ALERT
+ "XenoLinux Virtual SCSI Device Driver uninstalled w/ errs\n");
+ else
+ printk(KERN_ALERT
+ "XenoLinux Virtual SCSI Device Driver uninstalled\n");
+
+ return;
+}
+
diff --git a/xenolinux-2.4.21-pre4-sparse/include/linux/major.h b/xenolinux-2.4.21-pre4-sparse/include/linux/major.h
index 9cac1c2881..a838d477d1 100644
--- a/xenolinux-2.4.21-pre4-sparse/include/linux/major.h
+++ b/xenolinux-2.4.21-pre4-sparse/include/linux/major.h
@@ -145,8 +145,8 @@
#define UMEM_MAJOR 116 /* http://www.umem.com/ Battery Backed RAM */
-/* note: 123, 124, 125, 126 and 234, 235, 236, 237 are defined in xeno_major */
-#include <asm/hypervisor-ifs/xeno-major.h>
+#define XLIDE_MAJOR 123 /* XenoLinux IDE Device */
+#define XLSCSI_MAJOR 133 /* XenoLinux SCSI Device */
#define RTF_MAJOR 150
#define RAW_MAJOR 162
diff --git a/xenolinux-2.4.21-pre4-sparse/init/do_mounts.c b/xenolinux-2.4.21-pre4-sparse/init/do_mounts.c
index ddf2f96a39..68c1a4a002 100644
--- a/xenolinux-2.4.21-pre4-sparse/init/do_mounts.c
+++ b/xenolinux-2.4.21-pre4-sparse/init/do_mounts.c
@@ -232,13 +232,7 @@ static struct dev_name_struct {
{ "ataraid/d15p",0x72F0 },
#if defined(CONFIG_XENOLINUX_BLOCK)
{ "xhda", 0x7B00 },
- { "xhdb", 0x7C00 },
- { "xhdc", 0x7D00 },
- { "xhdd", 0x7E00 },
- { "vhda", 0xEA00 },
- { "vhdb", 0xEB00 },
- { "vhdc", 0xEC00 },
- { "vhdd", 0xED00 },
+ { "xsda", 0x8500 },
#endif
{ "nftla", 0x5d00 },
{ "nftlb", 0x5d10 },