aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/block/xen-blkfront.c11
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c5
-rw-r--r--include/xen/xenbus.h1
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 4497ff84f64..dfe61afe676 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -88,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
@@ -839,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;
}
/**
@@ -931,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;
@@ -977,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)
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 4750de316ad..88fc5ec665f 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -846,6 +846,7 @@ static int is_disconnected_device(struct device *dev, void *data)
{
struct xenbus_device *xendev = to_xenbus_device(dev);
struct device_driver *drv = data;
+ struct xenbus_driver *xendrv;
/*
* A device with no driver will never connect. We care only about
@@ -858,7 +859,9 @@ static int is_disconnected_device(struct device *dev, void *data)
if (drv && (dev->driver != drv))
return 0;
- return (xendev->state != XenbusStateConnected);
+ xendrv = to_xenbus_driver(dev->driver);
+ return (xendev->state != XenbusStateConnected ||
+ (xendrv->is_ready && !xendrv->is_ready(xendev)));
}
static int exists_disconnected_device(struct device_driver *drv)
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index 6f7c290651a..6369d89c25d 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -97,6 +97,7 @@ struct xenbus_driver {
int (*uevent)(struct xenbus_device *, char **, int, char *, int);
struct device_driver driver;
int (*read_otherend_details)(struct xenbus_device *dev);
+ int (*is_ready)(struct xenbus_device *dev);
};
static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)