#include <linux/interrupt.h>
#include <linux/blkdev.h>
+#include <linux/hdreg.h>
#include <linux/module.h>
#include <xen/xenbus.h>
#include <xen/interface/grant_table.h>
#include <xen/interface/io/blkif.h>
+#include <xen/interface/io/protocols.h>
#include <asm/xen/hypervisor.h>
struct blkfront_info
{
struct xenbus_device *xbdev;
- dev_t dev;
struct gendisk *gd;
int vdevice;
blkif_vdev_t handle;
struct blk_shadow shadow[BLK_RING_SIZE];
unsigned long shadow_free;
int feature_barrier;
+ int is_ready;
/**
* The number of people holding this device open. We won't allow a
schedule_work(&info->work);
}
+int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
+{
+ /* We don't have real geometry info, but let's at least return
+ values consistent with the size of the device */
+ sector_t nsect = get_capacity(bd->bd_disk);
+ sector_t cylinders = nsect;
+
+ hg->heads = 0xff;
+ hg->sectors = 0x3f;
+ sector_div(cylinders, hg->heads * hg->sectors);
+ hg->cylinders = cylinders;
+ if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
+ hg->cylinders = 0xffff;
+ return 0;
+}
+
/*
* blkif_queue_request
*
message = "writing event-channel";
goto abort_transaction;
}
+ err = xenbus_printf(xbt, dev->nodename, "protocol", "%s",
+ XEN_IO_PROTO_ABI_NATIVE);
+ if (err) {
+ message = "writing protocol";
+ goto abort_transaction;
+ }
err = xenbus_transaction_end(xbt, 0);
if (err) {
spin_unlock_irq(&blkif_io_lock);
add_disk(info->gd);
+
+ info->is_ready = 1;
}
/**
break;
case XenbusStateClosing:
- bd = bdget(info->dev);
+ bd = bdget_disk(info->gd, 0);
if (bd == NULL)
xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
return 0;
}
+static int blkfront_is_ready(struct xenbus_device *dev)
+{
+ struct blkfront_info *info = dev->dev.driver_data;
+
+ return info->is_ready;
+}
+
static int blkif_open(struct inode *inode, struct file *filep)
{
struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
.owner = THIS_MODULE,
.open = blkif_open,
.release = blkif_release,
+ .getgeo = blkif_getgeo,
};
.remove = blkfront_remove,
.resume = blkfront_resume,
.otherend_changed = backend_changed,
+ .is_ready = blkfront_is_ready,
};
static int __init xlblk_init(void)
MODULE_DESCRIPTION("Xen virtual block device frontend");
MODULE_LICENSE("GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR);
+MODULE_ALIAS("xen:vbd");
+MODULE_ALIAS("xenblk");