unregister_xenbus_watch(&dev->otherend_watch);
kfree(dev->otherend_watch.node);
dev->otherend_watch.node = NULL;
+ }
+ if (dev->online_watch.node) {
+ unregister_xenbus_watch(&dev->online_watch);
+ kfree(dev->online_watch.node);
+ dev->online_watch.node = NULL;
}
}
},
};
-static void otherend_changed(struct xenbus_watch *watch,
- const char **vec, unsigned int len)
+static void otherend_changed_common(struct xenbus_device *dev,
+ const char **vec, unsigned int len)
{
- struct xenbus_device *dev =
- container_of(watch, struct xenbus_device, otherend_watch);
struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
enum xenbus_state state;
- /* Protect us against watches firing on old details when the otherend
- details change, say immediately after a resume. */
- if (!dev->otherend ||
- strncmp(dev->otherend, vec[XS_WATCH_PATH],
- strlen(dev->otherend))) {
- DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
- return;
- }
-
state = xenbus_read_driver_state(dev->otherend);
DPRINTK("state is %d (%s), %s, %s", state, xenbus_strstate(state),
drv->otherend_changed(dev, state);
}
+static void online_changed(struct xenbus_watch *watch,
+ const char **vec, unsigned int len)
+{
+ struct xenbus_device *dev =
+ container_of(watch, struct xenbus_device, online_watch);
+
+ otherend_changed_common(dev, vec, len);
+}
+
+static void otherend_changed(struct xenbus_watch *watch,
+ const char **vec, unsigned int len)
+{
+ struct xenbus_device *dev =
+ container_of(watch, struct xenbus_device, otherend_watch);
+
+ /* Protect us against watches firing on old details when the otherend
+ details change, say immediately after a resume. */
+ if (!dev->otherend ||
+ strncmp(dev->otherend, vec[XS_WATCH_PATH],
+ strlen(dev->otherend))) {
+ DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
+ return;
+ }
+
+ otherend_changed_common(dev, vec, len);
+}
+
static int talk_to_otherend(struct xenbus_device *dev)
{
static int watch_otherend(struct xenbus_device *dev)
{
- return xenbus_watch_path2(dev, dev->otherend, "state",
- &dev->otherend_watch, otherend_changed);
+ int i;
+ i = xenbus_watch_path2(dev, dev->otherend, "state",
+ &dev->otherend_watch, otherend_changed);
+ if (i >= 0) {
+ i = xenbus_watch_path2(dev, dev->nodename, "online",
+ &dev->online_watch, online_changed);
+ }
+ return i;
}