]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/block/xen-blkfront.c
Merge commit 'v2.6.26' into bkl-removal
[linux-2.6-omap-h63xx.git] / drivers / block / xen-blkfront.c
index 8afce67c0aa56293f815f55fb949983082ba2a9d..f2fff5799ddf0fe1b41909b64d606d747f9081f7 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
+#include <linux/hdreg.h>
 #include <linux/module.h>
 
 #include <xen/xenbus.h>
@@ -46,6 +47,7 @@
 
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/blkif.h>
+#include <xen/interface/io/protocols.h>
 
 #include <asm/xen/hypervisor.h>
 
@@ -73,7 +75,6 @@ static struct block_device_operations xlvbd_block_fops;
 struct blkfront_info
 {
        struct xenbus_device *xbdev;
-       dev_t dev;
        struct gendisk *gd;
        int vdevice;
        blkif_vdev_t handle;
@@ -87,6 +88,7 @@ struct blkfront_info
        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
@@ -135,6 +137,22 @@ static void blkif_restart_queue_callback(void *arg)
        schedule_work(&info->work);
 }
 
+static 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
  *
@@ -597,6 +615,12 @@ again:
                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) {
@@ -816,6 +840,8 @@ static void blkfront_connect(struct blkfront_info *info)
        spin_unlock_irq(&blkif_io_lock);
 
        add_disk(info->gd);
+
+       info->is_ready = 1;
 }
 
 /**
@@ -879,7 +905,7 @@ static void backend_changed(struct xenbus_device *dev,
                break;
 
        case XenbusStateClosing:
-               bd = bdget(info->dev);
+               bd = bdget_disk(info->gd, 0);
                if (bd == NULL)
                        xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
 
@@ -908,6 +934,13 @@ static int blkfront_remove(struct xenbus_device *dev)
        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;
@@ -937,6 +970,7 @@ static struct block_device_operations xlvbd_block_fops =
        .owner = THIS_MODULE,
        .open = blkif_open,
        .release = blkif_release,
+       .getgeo = blkif_getgeo,
 };
 
 
@@ -953,6 +987,7 @@ static struct xenbus_driver blkfront = {
        .remove = blkfront_remove,
        .resume = blkfront_resume,
        .otherend_changed = backend_changed,
+       .is_ready = blkfront_is_ready,
 };
 
 static int __init xlblk_init(void)
@@ -980,3 +1015,5 @@ module_exit(xlblk_exit);
 MODULE_DESCRIPTION("Xen virtual block device frontend");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR);
+MODULE_ALIAS("xen:vbd");
+MODULE_ALIAS("xenblk");