summaryrefslogtreecommitdiff
blob: 8f5fdc251494c6817e405d92ef237693f90f34ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# HG changeset 82 patch
# User Christian Limpach <Christian.Limpach@xensource.com>
# Date 1183716504 -3600
# Node ID 11483a00c017ea82a4c2948724eb36ba6ec5c0ba
# Parent  cb040341e05af32c804afef4216ec5491dcbf9e3
Subject: Delay wait for block devices until after the disk is added.

Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>

Acked-by: jbeulich@novell.com

---
 drivers/xen/blkfront/blkfront.c   |   10 ++++++++++
 drivers/xen/blkfront/block.h      |    1 +
 drivers/xen/xenbus/xenbus_probe.c |    5 ++++-
 include/xen/xenbus.h              |    1 +
 4 files changed, 16 insertions(+), 1 deletion(-)

--- a/drivers/xen/blkfront/blkfront.c	2007-08-27 14:01:25.000000000 -0400
+++ b/drivers/xen/blkfront/blkfront.c	2007-08-27 14:02:03.000000000 -0400
@@ -354,6 +354,8 @@ static void connect(struct blkfront_info
 	spin_unlock_irq(&blkif_io_lock);
 
 	add_disk(info->gd);
+
+	info->is_ready = 1;
 }
 
 /**
@@ -862,6 +864,13 @@ static void blkif_recover(struct blkfron
 	spin_unlock_irq(&blkif_io_lock);
 }
 
+int blkfront_is_ready(struct xenbus_device *dev)
+{
+	struct blkfront_info *info = dev->dev.driver_data;
+
+	return info->is_ready;
+}
+
 
 /* ** Driver Registration ** */
 
@@ -880,6 +889,7 @@ static struct xenbus_driver blkfront = {
 	.remove = blkfront_remove,
 	.resume = blkfront_resume,
 	.otherend_changed = backend_changed,
+	.is_ready = blkfront_is_ready,
 };
 
 
--- a/drivers/xen/blkfront/block.h	2007-08-27 14:01:25.000000000 -0400
+++ b/drivers/xen/blkfront/block.h	2007-08-27 14:01:25.000000000 -0400
@@ -111,6 +111,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
--- a/drivers/xen/xenbus/xenbus_probe.c	2007-08-27 14:01:25.000000000 -0400
+++ b/drivers/xen/xenbus/xenbus_probe.c	2007-08-27 14:02:01.000000000 -0400
@@ -992,6 +992,7 @@ static int is_disconnected_device(struct
 {
 	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
@@ -1004,7 +1005,9 @@ static int is_disconnected_device(struct
 	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)
--- a/include/xen/xenbus.h	2007-08-27 14:01:25.000000000 -0400
+++ b/include/xen/xenbus.h	2007-08-27 14:01:25.000000000 -0400
@@ -106,6 +106,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)