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:04:47 +0000
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-03-06 16:04:47 +0000
commit8e06473cff7350a2ea62c5406cf2a733ebe82478 (patch)
tree029a9c0d9c0e8634889fe34738b4d084f46ac5c1 /xenolinux-2.4.21-pre4-sparse
parentdfca2c82d597482bab554fd1256cdb13154efba7 (diff)
downloadxen-8e06473cff7350a2ea62c5406cf2a733ebe82478.tar.gz
xen-8e06473cff7350a2ea62c5406cf2a733ebe82478.tar.bz2
xen-8e06473cff7350a2ea62c5406cf2a733ebe82478.zip
bitkeeper revision 1.105.1.9 (3e67719fUVPJZo6pYtLZ12frkd1BqQ)
xl_scsi.c, xl_ide.c, grok.c: new file Many files: Steve's new SCSI world.
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.c313
-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.h3
-rw-r--r--xenolinux-2.4.21-pre4-sparse/init/do_mounts.c4
6 files changed, 582 insertions, 151 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..56413ed106 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_ide.o xl_scsi.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..3130280c57 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
@@ -24,27 +24,26 @@
#include <asm/io.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;
-void xlblk_ide_register_disk(int, unsigned long);
-#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_RESPONSE_IRQ _EVENT_BLK_RESP
+#define XLBLK_MAX 32 /* XXX SMH: this the max of XLIDE_MAX and XLSCSI_MAX */
+
+#define XLBLK_RESPONSE_IRQ _EVENT_BLK_RESP
#define DEBUG_IRQ _EVENT_DEBUG
#if 0
@@ -57,7 +56,8 @@ 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;
+
+xen_disk_info_t xen_disk_info;
int hypervisor_request(void * id,
int operation,
@@ -70,52 +70,136 @@ int hypervisor_request(void * id,
/* ------------------------------------------------------------------------
*/
-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:
- DPRINTK_IOCTL(" BLKGETSIZE: %x %lx\n", BLKGETSIZE,
- (long) xen_disk_info.disks[0].capacity);
- return put_user(xen_disk_info.disks[0].capacity,
- (unsigned long *) argument);
+ DPRINTK_IOCTL(" BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects);
+ return put_user(part->nr_sects, (unsigned long *) argument);
case BLKRRPART:
DPRINTK_IOCTL(" BLKRRPART: %x\n", BLKRRPART);
break;
case BLKSSZGET:
- DPRINTK_IOCTL(" BLKSSZGET: %x 0x%x\n", BLKSSZGET,
- xlblk_hardsect_size[minor_dev]);
- return xlblk_hardsect_size[minor_dev];
-
+ 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 HDIO_GETGEO:
DPRINTK_IOCTL(" HDIO_GETGEO: %x\n", HDIO_GETGEO);
if (!argument) return -EINVAL;
@@ -143,13 +227,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;
@@ -200,14 +284,13 @@ int hypervisor_request(void * id,
case XEN_BLOCK_READ:
case XEN_BLOCK_WRITE:
- if ( MAJOR(device) != XLBLK_MAJOR )
- panic("error: xl_block::hypervisor_request: "
- "unknown device [0x%x]\n", device);
- phys_device = MKDEV(IDE0_MAJOR, 0);
+
+ phys_device = xldev_to_physdev(device);
+
/* Compute real buffer location on disk */
sector_number = block_number;
- if ( (gd = (struct gendisk *)xen_disk_info.disks[0].gendisk) != NULL )
- sector_number += gd->part[MINOR(device)&IDE_PARTN_MASK].start_sect;
+ gd = xldev_to_gendisk(device, NULL);
+ sector_number += gd->part[MINOR(device)].start_sect;
break;
default:
@@ -234,7 +317,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;
@@ -242,9 +325,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,
@@ -310,7 +394,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;
@@ -327,15 +411,24 @@ 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. */
- do_xlblk_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
+ 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));
+ }
+
spin_unlock_irqrestore(&io_request_lock, flags);
}
int __init xlblk_init(void)
{
- int i, error, result;
+ int i, error;
/* This mapping was created early at boot time. */
blk_ring = (blk_ring_t *)fix_to_virt(FIX_BLKRING_BASE);
@@ -356,129 +449,57 @@ int __init xlblk_init(void)
BUG();
HYPERVISOR_block_io_op();
while ( blk_ring->resp_prod != 1 ) barrier();
+
for ( i = 0; i < xen_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, xen_disk_info.disks[i].type,
xen_disk_info.disks[i].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;
- }
+
+ 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;
+ }
- /* initialize global arrays in drivers/block/ll_rw_block.c */
- for (i = 0; i < XLBLK_MAX; i++) {
- xlblk_blk_size[i] = xen_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, xen_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);
-
- 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;
+ int i;
- 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;
+ 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 dfcb6f79f0..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,7 +145,8 @@
#define UMEM_MAJOR 116 /* http://www.umem.com/ Battery Backed RAM */
-#define XLBLK_MAJOR 123 /* XenoLinux Block Device */
+#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 b0b143a264..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,9 +232,7 @@ static struct dev_name_struct {
{ "ataraid/d15p",0x72F0 },
#if defined(CONFIG_XENOLINUX_BLOCK)
{ "xhda", 0x7B00 },
- { "xhdb", 0x7C00 },
- { "xhdc", 0x7D00 },
- { "xhdd", 0x7E00 },
+ { "xsda", 0x8500 },
#endif
{ "nftla", 0x5d00 },
{ "nftlb", 0x5d10 },