diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2005-01-11 14:30:17 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2005-01-11 14:30:17 +0000 |
commit | 5d89512faeb066cc2cbbe604690f7383a9726326 (patch) | |
tree | 516397242dcacdd057e64a6025e8929854bcabab | |
parent | 836d83fb96a484b00f27acd9b41ad8c563715912 (diff) | |
download | xen-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.c | 94 | ||||
-rw-r--r-- | linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h | 28 | ||||
-rw-r--r-- | linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c | 493 |
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; } |