ChangeSet 1.1419.1.1, 2005/04/01 14:20:59+01:00, vh249@xxxxxxxxxxxxxxxxxxxxxx
big cleanup. better support for refresh.
Signed-off-by: Vincent Hanquez <vincent@xxxxxxxxxxxxx>
vbd.c | 601 +++++++++++++++++++++++++++++++++---------------------------------
1 files changed, 305 insertions(+), 296 deletions(-)
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c
b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c 2005-04-01
09:03:00 -05:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c 2005-04-01
09:03:00 -05:00
@@ -31,6 +31,7 @@
#include "block.h"
#include <linux/blkdev.h>
+#include <linux/list.h>
/*
* For convenience we distinguish between ide, scsi and 'other' (i.e.,
@@ -42,6 +43,14 @@
#define NUM_SCSI_MAJORS 9
#define NUM_VBD_MAJORS 1
+struct lvdisk
+{
+ blkif_sector_t capacity; /* 0: Size in terms of 512-byte sectors. */
+ blkif_vdev_t device; /* 8: Device number (opaque 16 bit value). */
+ u16 info;
+ struct list_head list;
+};
+
static struct xlbd_type_info xlbd_ide_type = {
.partn_shift = 6,
.partn_per_major = 2,
@@ -66,10 +75,17 @@
static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
NUM_VBD_MAJORS];
+#define XLBD_MAJOR_IDE_START 0
+#define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS)
+#define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
+
+#define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START
- 1
+#define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START
- 1
+#define XLBD_MAJOR_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START
+ NUM_VBD_MAJORS - 1
+
/* Information about our VBDs. */
#define MAX_VBDS 64
-static int nr_vbds;
-static vdisk_t *vbd_info;
+struct list_head vbds_list;
struct request_queue *xlbd_blk_queue = NULL;
@@ -82,388 +98,386 @@
.open = blkif_open,
.release = blkif_release,
.ioctl = blkif_ioctl,
-#if 0
- check_media_change: blkif_check,
- revalidate: blkif_revalidate,
-#endif
};
spinlock_t blkif_io_lock = SPIN_LOCK_UNLOCKED;
-static int xlvbd_get_vbd_info(vdisk_t *disk_info)
+static struct lvdisk * xlvbd_device_alloc(void)
+{
+ struct lvdisk *ret;
+
+ ret = kmalloc(sizeof(struct lvdisk), GFP_KERNEL);
+ if ( ret ) {
+ memset(ret, '\0', 0);
+ INIT_LIST_HEAD(&ret->list);
+ }
+ return ret;
+}
+
+static void xlvbd_device_free(struct lvdisk *disk)
+{
+ list_del(&disk->list);
+ kfree(disk);
+}
+
+static vdisk_t * xlvbd_probe(int *ret)
{
- vdisk_t *buf = (vdisk_t *)__get_free_page(GFP_KERNEL);
- blkif_request_t req;
blkif_response_t rsp;
- int nr;
+ blkif_request_t req;
+ vdisk_t *disk_info = NULL;
+ unsigned long buf;
+ int nr;
+
+ buf = __get_free_page(GFP_KERNEL);
+ if ( !buf )
+ goto out;
memset(&req, 0, sizeof(req));
- req.operation = BLKIF_OP_PROBE;
+ req.operation = BLKIF_OP_PROBE;
req.nr_segments = 1;
req.frame_and_sects[0] = virt_to_machine(buf) | 7;
blkif_control_send(&req, &rsp);
-
- if ( rsp.status <= 0 )
- {
+ if ( rsp.status <= 0 ) {
printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status);
- return -1;
+ goto out;
}
-
- if ( (nr = rsp.status) > MAX_VBDS )
+ nr = rsp.status;
+ if ( nr > MAX_VBDS )
nr = MAX_VBDS;
- memcpy(disk_info, buf, nr * sizeof(vdisk_t));
-
- free_page((unsigned long)buf);
- return nr;
+ disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
+ if ( disk_info )
+ memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
+ if ( ret )
+ *ret = nr;
+out:
+ free_page(buf);
+ return disk_info;
}
-static struct xlbd_major_info *xlbd_get_major_info(int xd_device, int *minor)
+static struct xlbd_major_info *xlbd_alloc_major_info(int major, int minor, int
index)
{
- int mi_idx, new_major;
- int xd_major = MAJOR_XEN(xd_device);
- int xd_minor = MINOR_XEN(xd_device);
+ struct xlbd_major_info *ptr;
- *minor = xd_minor;
+ ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
+ if ( !ptr )
+ return NULL;
- switch (xd_major) {
- case IDE0_MAJOR: mi_idx = 0; new_major = IDE0_MAJOR; break;
- case IDE1_MAJOR: mi_idx = 1; new_major = IDE1_MAJOR; break;
- case IDE2_MAJOR: mi_idx = 2; new_major = IDE2_MAJOR; break;
- case IDE3_MAJOR: mi_idx = 3; new_major = IDE3_MAJOR; break;
- case IDE4_MAJOR: mi_idx = 4; new_major = IDE4_MAJOR; break;
- case IDE5_MAJOR: mi_idx = 5; new_major = IDE5_MAJOR; break;
- case IDE6_MAJOR: mi_idx = 6; new_major = IDE6_MAJOR; break;
- case IDE7_MAJOR: mi_idx = 7; new_major = IDE7_MAJOR; break;
- case IDE8_MAJOR: mi_idx = 8; new_major = IDE8_MAJOR; break;
- case IDE9_MAJOR: mi_idx = 9; new_major = IDE9_MAJOR; break;
- case SCSI_DISK0_MAJOR: mi_idx = 10; new_major = SCSI_DISK0_MAJOR; break;
- case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
- mi_idx = 11 + xd_major - SCSI_DISK1_MAJOR;
- new_major = SCSI_DISK1_MAJOR + xd_major - SCSI_DISK1_MAJOR;
+ memset(ptr, 0, sizeof(struct xlbd_major_info));
+
+ ptr->major = major;
+
+ switch (index) {
+ case XLBD_MAJOR_IDE_RANGE:
+ ptr->type = &xlbd_ide_type;
+ ptr->index = index - XLBD_MAJOR_IDE_START;
+ break;
+ case XLBD_MAJOR_SCSI_RANGE:
+ ptr->type = &xlbd_scsi_type;
+ ptr->index = index - XLBD_MAJOR_SCSI_START;
+ break;
+ case XLBD_MAJOR_VBD_RANGE:
+ ptr->type = &xlbd_vbd_type;
+ ptr->index = index - XLBD_MAJOR_VBD_START;
break;
- case SCSI_CDROM_MAJOR: mi_idx = 18; new_major = SCSI_CDROM_MAJOR; break;
- default: mi_idx = 19; new_major = 0;/* XXXcl notyet */ break;
+ }
+
+ if ( register_blkdev(ptr->major, ptr->type->devname) ) {
+ printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n",
+ ptr->major, ptr->type->devname);
+ kfree(ptr);
+ return NULL;
}
- if (major_info[mi_idx])
- return major_info[mi_idx];
+ devfs_mk_dir(ptr->type->devname);
+ major_info[index] = ptr;
+ return ptr;
+}
- major_info[mi_idx] = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
- if (major_info[mi_idx] == NULL)
- return NULL;
+static struct xlbd_major_info *xlbd_get_major_info(int device)
+{
+ int major, minor, index;
- memset(major_info[mi_idx], 0, sizeof(struct xlbd_major_info));
+ major = MAJOR_XEN(device);
+ minor = MINOR_XEN(device);
- switch (mi_idx) {
- case 0 ... (NUM_IDE_MAJORS - 1):
- major_info[mi_idx]->type = &xlbd_ide_type;
- major_info[mi_idx]->index = mi_idx;
- break;
- case NUM_IDE_MAJORS ... (NUM_IDE_MAJORS + NUM_SCSI_MAJORS - 1):
- major_info[mi_idx]->type = &xlbd_scsi_type;
- major_info[mi_idx]->index = mi_idx - NUM_IDE_MAJORS;
- break;
- case (NUM_IDE_MAJORS + NUM_SCSI_MAJORS) ...
- (NUM_IDE_MAJORS + NUM_SCSI_MAJORS + NUM_VBD_MAJORS - 1):
- major_info[mi_idx]->type = &xlbd_vbd_type;
- major_info[mi_idx]->index = mi_idx -
- (NUM_IDE_MAJORS + NUM_SCSI_MAJORS);
+ switch (major) {
+ case IDE0_MAJOR: index = 0; break;
+ case IDE1_MAJOR: index = 1; break;
+ case IDE2_MAJOR: index = 2; break;
+ case IDE3_MAJOR: index = 3; break;
+ case IDE4_MAJOR: index = 4; break;
+ case IDE5_MAJOR: index = 5; break;
+ case IDE6_MAJOR: index = 6; break;
+ case IDE7_MAJOR: index = 7; break;
+ case IDE8_MAJOR: index = 8; break;
+ case IDE9_MAJOR: index = 9; break;
+ case SCSI_DISK0_MAJOR: index = 10; break;
+ case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
+ index = 11 + major - SCSI_DISK1_MAJOR;
break;
+ case SCSI_CDROM_MAJOR: index = 18; break;
+ default: index = 19; break;
}
- major_info[mi_idx]->major = new_major;
- if (register_blkdev(major_info[mi_idx]->major,
major_info[mi_idx]->type->devname)) {
- printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n",
- major_info[mi_idx]->major, major_info[mi_idx]->type->devname);
- goto out;
- }
+ return major_info[index]
+ ? major_info[index]
+ : xlbd_alloc_major_info(major, minor, index);
+}
- devfs_mk_dir(major_info[mi_idx]->type->devname);
+static int xlvbd_blk_queue_alloc(struct xlbd_type_info *type)
+{
+ xlbd_blk_queue = blk_init_queue(do_blkif_request, &blkif_io_lock);
+ if ( !xlbd_blk_queue )
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|