aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-01-11 14:30:17 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-01-11 14:30:17 +0000
commit5d89512faeb066cc2cbbe604690f7383a9726326 (patch)
tree516397242dcacdd057e64a6025e8929854bcabab
parent836d83fb96a484b00f27acd9b41ad8c563715912 (diff)
downloadxen-5d89512faeb066cc2cbbe604690f7383a9726326.tar.gz
xen-5d89512faeb066cc2cbbe604690f7383a9726326.tar.bz2
xen-5d89512faeb066cc2cbbe604690f7383a9726326.zip
bitkeeper revision 1.1159.170.85 (41e3e2f9yjG4A65d-L23jd66Wzw4bQ)
Minor blkfront cleanups and clarifications.
-rw-r--r--linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c94
-rw-r--r--linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h28
-rw-r--r--linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c493
3 files changed, 298 insertions, 317 deletions
diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c
index 957db72432..e81afa9f03 100644
--- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c
+++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c
@@ -60,19 +60,6 @@ static void vbd_update(void){};
#define BLKIF_STATE_DISCONNECTED 1
#define BLKIF_STATE_CONNECTED 2
-static char *blkif_state_name[] = {
- [BLKIF_STATE_CLOSED] = "closed",
- [BLKIF_STATE_DISCONNECTED] = "disconnected",
- [BLKIF_STATE_CONNECTED] = "connected",
-};
-
-static char * blkif_status_name[] = {
- [BLKIF_INTERFACE_STATUS_CLOSED] = "closed",
- [BLKIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected",
- [BLKIF_INTERFACE_STATUS_CONNECTED] = "connected",
- [BLKIF_INTERFACE_STATUS_CHANGED] = "changed",
-};
-
#define WPRINTK(fmt, args...) printk(KERN_WARNING "xen_blk: " fmt, ##args)
static int blkif_handle = 0;
@@ -334,11 +321,11 @@ static int blkif_queue_request(struct request *req)
blkif_request_t *ring_req;
struct bio *bio;
struct bio_vec *bvec;
- int idx, s;
+ int idx;
unsigned long id;
unsigned int fsect, lsect;
- if (unlikely(blkif_state != BLKIF_STATE_CONNECTED))
+ if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
return 1;
/* Fill out a communications ring structure. */
@@ -352,29 +339,25 @@ static int blkif_queue_request(struct request *req)
ring_req->sector_number = (blkif_sector_t)req->sector;
ring_req->device = di->xd_device;
- s = 0;
ring_req->nr_segments = 0;
- rq_for_each_bio(bio, req) {
- bio_for_each_segment(bvec, bio, idx) {
- buffer_ma = page_to_phys(bvec->bv_page);
- if (unlikely((buffer_ma & ((1<<9)-1)) != 0))
+ rq_for_each_bio(bio, req)
+ {
+ bio_for_each_segment(bvec, bio, idx)
+ {
+ if ( ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST )
BUG();
-
+ buffer_ma = page_to_phys(bvec->bv_page);
fsect = bvec->bv_offset >> 9;
lsect = fsect + (bvec->bv_len >> 9) - 1;
- if (unlikely(lsect > 7))
- BUG();
-
ring_req->frame_and_sects[ring_req->nr_segments++] =
buffer_ma | (fsect << 3) | lsect;
- s += bvec->bv_len >> 9;
}
}
req_prod++;
/* Keep a private copy so we can reissue requests when recovering. */
- translate_req_to_pfn( &rec_ring[id], ring_req);
+ translate_req_to_pfn(&rec_ring[id], ring_req);
return 0;
}
@@ -442,15 +425,15 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
for ( i = resp_cons; i != rp; i++ )
{
- unsigned long id;
+ unsigned long id;
bret = &blk_ring->ring[MASK_BLKIF_IDX(i)].resp;
- id = bret->id;
- req = (struct request *)rec_ring[id].id;
+ id = bret->id;
+ req = (struct request *)rec_ring[id].id;
- blkif_completion( &rec_ring[id] );
+ blkif_completion( &rec_ring[id] );
- ADD_ID_TO_FREELIST(id); /* overwrites req */
+ ADD_ID_TO_FREELIST(id); /* overwrites req */
switch ( bret->operation )
{
@@ -459,7 +442,7 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
if ( unlikely(bret->status != BLKIF_RSP_OKAY) )
DPRINTK("Bad return from blkdev data request: %x\n",
bret->status);
-
+
if ( unlikely(end_that_request_first
(req,
(bret->status == BLKIF_RSP_OKAY),
@@ -655,7 +638,7 @@ int blkif_ioctl(struct inode *inode, struct file *filep,
if (!argument) return -EINVAL;
/* We don't have real geometry info, but let's at least return
- values consistent with the size of the device */
+ values consistent with the size of the device */
heads = 0xff;
sectors = 0x3f;
@@ -673,7 +656,7 @@ int blkif_ioctl(struct inode *inode, struct file *filep,
if (!argument) return -EINVAL;
/* We don't have real geometry info, but let's at least return
- values consistent with the size of the device */
+ values consistent with the size of the device */
heads = 0xff;
sectors = 0x3f;
@@ -832,11 +815,11 @@ static int blkif_queue_request(unsigned long id,
req = &blk_ring->ring[MASK_BLKIF_IDX(req_prod-1)].req;
bh = (struct buffer_head *)id;
-
+
bh->b_reqnext = (struct buffer_head *)rec_ring[req->id].id;
-
+
- rec_ring[req->id].id = id;
+ rec_ring[req->id].id = id;
req->frame_and_sects[req->nr_segments] =
buffer_ma | (fsect<<3) | lsect;
@@ -989,15 +972,15 @@ static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
for ( i = resp_cons; i != rp; i++ )
{
- unsigned long id;
+ unsigned long id;
blkif_response_t *bret = &blk_ring->ring[MASK_BLKIF_IDX(i)].resp;
- id = bret->id;
- bh = (struct buffer_head *)rec_ring[id].id;
+ id = bret->id;
+ bh = (struct buffer_head *)rec_ring[id].id;
- blkif_completion( &rec_ring[id] );
+ blkif_completion( &rec_ring[id] );
- ADD_ID_TO_FREELIST(id);
+ ADD_ID_TO_FREELIST(id);
switch ( bret->operation )
{
@@ -1172,7 +1155,7 @@ static void blkif_recover(void)
/* Stage 2 : Set up shadow list. */
for ( i = 0; i < req_prod; i++ )
{
- rec_ring[i].id = blk_ring->ring[i].req.id;
+ rec_ring[i].id = blk_ring->ring[i].req.id;
blk_ring->ring[i].req.id = i;
translate_req_to_pfn(&rec_ring[i], &blk_ring->ring[i].req);
}
@@ -1235,9 +1218,8 @@ static void blkif_connect(blkif_fe_interface_status_t *status)
static void unexpected(blkif_fe_interface_status_t *status)
{
- DPRINTK(" Unexpected blkif status %s in state %s\n",
- blkif_status_name[status->status],
- blkif_state_name[blkif_state]);
+ DPRINTK(" Unexpected blkif status %u in state %u\n",
+ status->status, blkif_state);
}
static void blkif_status(blkif_fe_interface_status_t *status)
@@ -1296,7 +1278,7 @@ static void blkif_status(blkif_fe_interface_status_t *status)
}
break;
- case BLKIF_INTERFACE_STATUS_CHANGED:
+ case BLKIF_INTERFACE_STATUS_CHANGED:
switch ( blkif_state )
{
case BLKIF_STATE_CLOSED:
@@ -1307,7 +1289,7 @@ static void blkif_status(blkif_fe_interface_status_t *status)
vbd_update();
break;
}
- break;
+ break;
default:
WPRINTK(" Invalid blkif status: %d\n", status->status);
@@ -1375,7 +1357,7 @@ int __init xlblk_init(void)
rec_ring_free = 0;
for ( i = 0; i < BLKIF_RING_SIZE; i++ )
- rec_ring[i].id = i+1;
+ rec_ring[i].id = i+1;
rec_ring[BLKIF_RING_SIZE-1].id = 0x0fffffff;
(void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
@@ -1404,13 +1386,13 @@ void blkif_completion(blkif_request_t *req)
switch ( req->operation )
{
case BLKIF_OP_READ:
- for ( i = 0; i < req->nr_segments; i++ )
- {
- unsigned long pfn = req->frame_and_sects[i] >> PAGE_SHIFT;
- unsigned long mfn = phys_to_machine_mapping[pfn];
- xen_machphys_update(mfn, pfn);
- }
- break;
+ for ( i = 0; i < req->nr_segments; i++ )
+ {
+ unsigned long pfn = req->frame_and_sects[i] >> PAGE_SHIFT;
+ unsigned long mfn = phys_to_machine_mapping[pfn];
+ xen_machphys_update(mfn, pfn);
+ }
+ break;
}
}
diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h
index f50ce03bca..1edebd5e05 100644
--- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h
+++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h
@@ -63,12 +63,12 @@
#endif
struct xlbd_type_info {
- int partn_shift;
- int partn_per_major;
- int devs_per_major;
- int hardsect_size;
- int max_sectors;
- char *name;
+ int partn_shift;
+ int partn_per_major;
+ int devs_per_major;
+ int hardsect_size;
+ int max_sectors;
+ char *name;
};
/*
@@ -77,19 +77,19 @@ struct xlbd_type_info {
* putting all kinds of interesting stuff here :-)
*/
struct xlbd_major_info {
- int major;
- int index;
- int usage;
- struct xlbd_type_info *type;
+ int major;
+ int index;
+ int usage;
+ struct xlbd_type_info *type;
};
struct xlbd_disk_info {
- int xd_device;
- struct xlbd_major_info *mi;
+ int xd_device;
+ struct xlbd_major_info *mi;
};
typedef struct xen_block {
- int usage;
+ int usage;
} xen_block_t;
extern struct request_queue *xlbd_blk_queue;
@@ -98,7 +98,7 @@ extern spinlock_t blkif_io_lock;
extern int blkif_open(struct inode *inode, struct file *filep);
extern int blkif_release(struct inode *inode, struct file *filep);
extern int blkif_ioctl(struct inode *inode, struct file *filep,
- unsigned command, unsigned long argument);
+ unsigned command, unsigned long argument);
extern int blkif_check(dev_t dev);
extern int blkif_revalidate(dev_t dev);
extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c
index 341979b6aa..00be870d91 100644
--- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c
+++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c
@@ -43,39 +43,37 @@
#define NUM_VBD_MAJORS 1
static struct xlbd_type_info xlbd_ide_type = {
- .partn_shift = 6,
- .partn_per_major = 2,
- // XXXcl todo blksize_size[major] = 1024;
- .hardsect_size = 512,
- .max_sectors = 128, /* 'hwif->rqsize' if we knew it */
- // XXXcl todo read_ahead[major] = 8; /* from drivers/ide/ide-probe.c */
- .name = "hd",
+ .partn_shift = 6,
+ .partn_per_major = 2,
+ // XXXcl todo blksize_size[major] = 1024;
+ .hardsect_size = 512,
+ .max_sectors = 128, /* 'hwif->rqsize' if we knew it */
+ // XXXcl todo read_ahead[major] = 8; /* from drivers/ide/ide-probe.c */
+ .name = "hd",
};
static struct xlbd_type_info xlbd_scsi_type = {
- .partn_shift = 4,
- .partn_per_major = 16,
- // XXXcl todo blksize_size[major] = 1024; /* XXX 512; */
- .hardsect_size = 512,
- .max_sectors = 128*8, /* XXX 128; */
- // XXXcl todo read_ahead[major] = 0; /* XXX 8; -- guessing */
- .name = "sd",
+ .partn_shift = 4,
+ .partn_per_major = 16,
+ // XXXcl todo blksize_size[major] = 1024; /* XXX 512; */
+ .hardsect_size = 512,
+ .max_sectors = 128*8, /* XXX 128; */
+ // XXXcl todo read_ahead[major] = 0; /* XXX 8; -- guessing */
+ .name = "sd",
};
static struct xlbd_type_info xlbd_vbd_type = {
- .partn_shift = 4,
- .partn_per_major = 16,
- // XXXcl todo blksize_size[major] = 512;
- .hardsect_size = 512,
- .max_sectors = 128,
- // XXXcl todo read_ahead[major] = 8;
- .name = "xvd",
+ .partn_shift = 4,
+ .partn_per_major = 16,
+ // XXXcl todo blksize_size[major] = 512;
+ .hardsect_size = 512,
+ .max_sectors = 128,
+ // XXXcl todo read_ahead[major] = 8;
+ .name = "xvd",
};
-/* XXXcl handle cciss after finding out why it's "hacked" in */
-
static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
- NUM_VBD_MAJORS];
+ NUM_VBD_MAJORS];
/* Information about our VBDs. */
#define MAX_VBDS 64
@@ -84,15 +82,15 @@ static vdisk_t *vbd_info;
struct request_queue *xlbd_blk_queue = NULL;
-#define MAJOR_XEN(dev) ((dev)>>8)
-#define MINOR_XEN(dev) ((dev) & 0xff)
+#define MAJOR_XEN(dev) ((dev)>>8)
+#define MINOR_XEN(dev) ((dev) & 0xff)
static struct block_device_operations xlvbd_block_fops =
{
- .owner = THIS_MODULE,
- .open = blkif_open,
- .release = blkif_release,
- .ioctl = blkif_ioctl,
+ .owner = THIS_MODULE,
+ .open = blkif_open,
+ .release = blkif_release,
+ .ioctl = blkif_ioctl,
#if 0
check_media_change: blkif_check,
revalidate: blkif_revalidate,
@@ -122,7 +120,7 @@ static int xlvbd_get_vbd_info(vdisk_t *disk_info)
}
if ( (nr = rsp.status) > MAX_VBDS )
- nr = MAX_VBDS;
+ nr = MAX_VBDS;
memcpy(disk_info, buf, nr * sizeof(vdisk_t));
free_page((unsigned long)buf);
@@ -132,153 +130,154 @@ static int xlvbd_get_vbd_info(vdisk_t *disk_info)
static struct xlbd_major_info *xlbd_get_major_info(int xd_device, int *minor)
{
- int mi_idx, new_major;
- int xd_major = MAJOR_XEN(xd_device);
- int xd_minor = MINOR_XEN(xd_device);
-
- *minor = xd_minor;
-
- 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;
- 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 (major_info[mi_idx])
- return major_info[mi_idx];
-
- major_info[mi_idx] = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
- if (major_info[mi_idx] == NULL)
- return NULL;
-
- memset(major_info[mi_idx], 0, sizeof(struct xlbd_major_info));
-
- 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);
- break;
- }
- major_info[mi_idx]->major = new_major;
-
- if (register_blkdev(major_info[mi_idx]->major, major_info[mi_idx]->type->name)) {
- printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n",
- major_info[mi_idx]->major, major_info[mi_idx]->type->name);
- goto out;
- }
-
- devfs_mk_dir(major_info[mi_idx]->type->name);
-
- return major_info[mi_idx];
+ int mi_idx, new_major;
+ int xd_major = MAJOR_XEN(xd_device);
+ int xd_minor = MINOR_XEN(xd_device);
+
+ *minor = xd_minor;
+
+ 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;
+ 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 (major_info[mi_idx])
+ return major_info[mi_idx];
+
+ major_info[mi_idx] = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
+ if (major_info[mi_idx] == NULL)
+ return NULL;
+
+ memset(major_info[mi_idx], 0, sizeof(struct xlbd_major_info));
+
+ 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);
+ break;
+ }
+ major_info[mi_idx]->major = new_major;
+
+ if (register_blkdev(major_info[mi_idx]->major, major_info[mi_idx]->type->name)) {
+ printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n",
+ major_info[mi_idx]->major, major_info[mi_idx]->type->name);
+ goto out;
+ }
+
+ devfs_mk_dir(major_info[mi_idx]->type->name);
+
+ return major_info[mi_idx];
out:
- kfree(major_info[mi_idx]);
- major_info[mi_idx] = NULL;
- return NULL;
+ kfree(major_info[mi_idx]);
+ major_info[mi_idx] = NULL;
+ return NULL;
}
static struct gendisk *xlvbd_get_gendisk(struct xlbd_major_info *mi,
- int xd_minor, vdisk_t *xd)
+ int xd_minor, vdisk_t *xd)
{
- struct gendisk *gd;
- struct xlbd_disk_info *di;
- int device, partno;
-
- device = MKDEV(mi->major, xd_minor);
- gd = get_gendisk(device, &partno);
- if (gd)
- return gd;
-
- di = kmalloc(sizeof(struct xlbd_disk_info), GFP_KERNEL);
- if (di == NULL)
- return NULL;
- di->mi = mi;
- di->xd_device = xd->device;
-
- /* Construct an appropriate gendisk structure. */
- gd = alloc_disk(1);
- if (gd == NULL)
- goto out;
-
- gd->major = mi->major;
- gd->first_minor = xd_minor;
- gd->fops = &xlvbd_block_fops;
- gd->private_data = di;
- sprintf(gd->disk_name, "%s%c%d", mi->type->name,
- 'a' + mi->index * mi->type->partn_per_major +
- (xd_minor >> mi->type->partn_shift),
- xd_minor & ((1 << mi->type->partn_shift) - 1));
- /* sprintf(gd->devfs_name, "%s%s/disc%d", mi->type->name, , ); XXXdevfs */
-
- set_capacity(gd, xd->capacity);
-
- if (xlbd_blk_queue == NULL) {
- xlbd_blk_queue = blk_init_queue(do_blkif_request,
- &blkif_io_lock);
- if (xlbd_blk_queue == NULL)
- goto out;
- elevator_init(xlbd_blk_queue, "noop");
-
- /*
- * Turn off barking 'headactive' mode. We dequeue
- * buffer heads as soon as we pass them to back-end
- * driver.
- */
- blk_queue_headactive(xlbd_blk_queue, 0); /* XXXcl: noop according to blkdev.h */
-
- blk_queue_hardsect_size(xlbd_blk_queue,
- mi->type->hardsect_size);
- blk_queue_max_sectors(xlbd_blk_queue, mi->type->max_sectors); /* 'hwif->rqsize' if we knew it */
-
- /* XXXcl: set mask to PAGE_SIZE for now, to improve either use
- - blk_queue_merge_bvec to merge requests with adjacent ma's
- - the tags infrastructure
- - the dma infrastructure
- */
- blk_queue_segment_boundary(xlbd_blk_queue, PAGE_SIZE - 1);
-
- blk_queue_max_phys_segments(xlbd_blk_queue,
- BLKIF_MAX_SEGMENTS_PER_REQUEST);
- blk_queue_max_hw_segments(xlbd_blk_queue,
- BLKIF_MAX_SEGMENTS_PER_REQUEST); /* XXXcl not needed? */
-
-
- }
- gd->queue = xlbd_blk_queue;
-
- add_disk(gd);
-
- return gd;
+ struct gendisk *gd;
+ struct xlbd_disk_info *di;
+ int device, partno;
+
+ device = MKDEV(mi->major, xd_minor);
+ gd = get_gendisk(device, &partno);
+ if ( gd != NULL )
+ return gd;
+
+ di = kmalloc(sizeof(struct xlbd_disk_info), GFP_KERNEL);
+ if ( di == NULL )
+ return NULL;
+ di->mi = mi;
+ di->xd_device = xd->device;
+
+ /* Construct an appropriate gendisk structure. */
+ gd = alloc_disk(1);
+ if ( gd == NULL )
+ goto out;
+
+ gd->major = mi->major;
+ gd->first_minor = xd_minor;
+ gd->fops = &xlvbd_block_fops;
+ gd->private_data = di;
+ sprintf(gd->disk_name, "%s%c%d", mi->type->name,
+ 'a' + mi->index * mi->type->partn_per_major +
+ (xd_minor >> mi->type->partn_shift),
+ xd_minor & ((1 << mi->type->partn_shift) - 1));
+
+ set_capacity(gd, xd->capacity);
+
+ if ( xlbd_blk_queue == NULL )
+ {
+ xlbd_blk_queue = blk_init_queue(do_blkif_request,
+ &blkif_io_lock);
+ if ( xlbd_blk_queue == NULL )
+ goto out;
+ elevator_init(xlbd_blk_queue, "noop");
+
+ /*
+ * Turn off barking 'headactive' mode. We dequeue
+ * buffer heads as soon as we pass them to back-end
+ * driver.
+ */
+ blk_queue_headactive(xlbd_blk_queue, 0);
+
+ /* Hard sector size and max sectors impersonate the equiv. hardware. */
+ blk_queue_hardsect_size(
+ xlbd_blk_queue, mi->type->hardsect_size);
+ blk_queue_max_sectors(
+ xlbd_blk_queue, mi->type->max_sectors);
+
+ /* Each segment in a request is up to an aligned page in size. */
+ blk_queue_segment_boundary(xlbd_blk_queue, PAGE_SIZE - 1);
+ blk_queue_max_segment_size(xlbd_blk_queue, PAGE_SIZE);
+
+ /* Ensure a merged request will fit in a single I/O ring slot. */
+ blk_queue_max_phys_segments(
+ xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+ blk_queue_max_hw_segments(
+ xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+
+ /* Make sure buffer addresses are sector-aligned. */
+ blk_queue_dma_alignment(xlbd_blk_queue, 511);
+ }
+ gd->queue = xlbd_blk_queue;
+
+ add_disk(gd);
+
+ return gd;
out:
- if (gd)
- del_gendisk(gd);
- kfree(di);
- return NULL;
+ if ( gd != NULL )
+ del_gendisk(gd);
+ kfree(di);
+ return NULL;
}
/*
@@ -294,62 +293,62 @@ static struct gendisk *xlvbd_get_gendisk(struct xlbd_major_info *mi,
*/
static int xlvbd_init_device(vdisk_t *xd)
{
- struct block_device *bd;
- struct gendisk *gd;
- struct xlbd_major_info *mi;
- int device;
- int minor;
-
- int err = -ENOMEM;
-
- mi = xlbd_get_major_info(xd->device, &minor);
- if (mi == NULL)
- return -EPERM;
-
- device = MKDEV(mi->major, minor);
-
- if ((bd = bdget(device)) == NULL)
- return -EPERM;
-
- /*
- * Update of partition info, and check of usage count, is protected
- * by the per-block-device semaphore.
- */
- down(&bd->bd_sem);
-
- gd = xlvbd_get_gendisk(mi, minor, xd);
- if (mi == NULL) {
- err = -EPERM;
- goto out;
- }
-
- if (VDISK_READONLY(xd->info))
- set_disk_ro(gd, 1);
-
- /* Some final fix-ups depending on the device type */
- switch (VDISK_TYPE(xd->info)) {
- case VDISK_TYPE_CDROM:
- gd->flags |= GENHD_FL_REMOVABLE | GENHD_FL_CD;
- /* FALLTHROUGH */
- case VDISK_TYPE_FLOPPY:
- case VDISK_TYPE_TAPE:
- gd->flags |= GENHD_FL_REMOVABLE;
- break;
-
- case VDISK_TYPE_DISK:
- break;
-
- default:
- printk(KERN_ALERT "XenLinux: unknown device type %d\n",
- VDISK_TYPE(xd->info));
- break;
- }
-
- err = 0;
+ struct block_device *bd;
+ struct gendisk *gd;
+ struct xlbd_major_info *mi;
+ int device;
+ int minor;
+
+ int err = -ENOMEM;
+
+ mi = xlbd_get_major_info(xd->device, &minor);
+ if (mi == NULL)
+ return -EPERM;
+
+ device = MKDEV(mi->major, minor);
+
+ if ((bd = bdget(device)) == NULL)
+ return -EPERM;
+
+ /*
+ * Update of partition info, and check of usage count, is protected
+ * by the per-block-device semaphore.
+ */
+ down(&bd->bd_sem);
+
+ gd = xlvbd_get_gendisk(mi, minor, xd);
+ if (mi == NULL) {
+ err = -EPERM;
+ goto out;
+ }
+
+ if (VDISK_READONLY(xd->info))
+ set_disk_ro(gd, 1);
+
+ /* Some final fix-ups depending on the device type */
+ switch (VDISK_TYPE(xd->info)) {
+ case VDISK_TYPE_CDROM:
+ gd->flags |= GENHD_FL_REMOVABLE | GENHD_FL_CD;
+ /* FALLTHROUGH */
+ case VDISK_TYPE_FLOPPY:
+ case VDISK_TYPE_TAPE:
+ gd->flags |= GENHD_FL_REMOVABLE;
+ break;
+
+ case VDISK_TYPE_DISK:
+ break;
+
+ default:
+ printk(KERN_ALERT "XenLinux: unknown device type %d\n",
+ VDISK_TYPE(xd->info));
+ break;
+ }
+
+ err = 0;
out:
- up(&bd->bd_sem);
- bdput(bd);
- return err;
+ up(&bd->bd_sem);
+ bdput(bd);
+ return err;
}
#if 0
@@ -393,7 +392,7 @@ static int xlvbd_remove_device(int device)
{
/* 1: The VBD is mapped to a partition rather than a whole unit. */
invalidate_device(device, 1);
- gd->part[minor].start_sect = 0;
+ gd->part[minor].start_sect = 0;
gd->part[minor].nr_sects = 0;
gd->sizes[minor] = 0;
@@ -531,31 +530,31 @@ void xlvbd_update_vbds(void)
*/
int xlvbd_init(void)
{
- int i;
+ int i;
- /*
- * If compiled as a module, we don't support unloading yet. We
- * therefore permanently increment the reference count to
- * disallow it.
- */
- /* MOD_INC_USE_COUNT; */
+ /*
+ * If compiled as a module, we don't support unloading yet. We
+ * therefore permanently increment the reference count to
+ * disallow it.
+ */
+ /* MOD_INC_USE_COUNT; */
- memset(major_info, 0, sizeof(major_info));
+ memset(major_info, 0, sizeof(major_info));
- for (i = 0; i < sizeof(major_info) / sizeof(major_info[0]); i++) {
- }
+ for (i = 0; i < sizeof(major_info) / sizeof(major_info[0]); i++) {
+ }
- vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
- nr_vbds = xlvbd_get_vbd_info(vbd_info);
+ vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
+ nr_vbds = xlvbd_get_vbd_info(vbd_info);
- if (nr_vbds < 0) {
- kfree(vbd_info);
- vbd_info = NULL;
- nr_vbds = 0;
- } else {
- for (i = 0; i < nr_vbds; i++)
- xlvbd_init_device(&vbd_info[i]);
- }
+ if (nr_vbds < 0) {
+ kfree(vbd_info);
+ vbd_info = NULL;
+ nr_vbds = 0;
+ } else {
+ for (i = 0; i < nr_vbds; i++)
+ xlvbd_init_device(&vbd_info[i]);
+ }
- return 0;
+ return 0;
}