diff options
Diffstat (limited to 'drivers/xen/xenbus')
| -rw-r--r-- | drivers/xen/xenbus/xenbus_client.c | 30 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_probe.c | 24 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_probe.h | 2 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_probe_backend.c | 2 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_probe_frontend.c | 4 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_xs.c | 44 | 
6 files changed, 65 insertions, 41 deletions
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index ec097d6f964..439c9dca9ee 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -45,6 +45,7 @@  #include <xen/grant_table.h>  #include <xen/xenbus.h>  #include <xen/xen.h> +#include <xen/features.h>  #include "xenbus_probe.h" @@ -400,33 +401,6 @@ EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);  /** - * Bind to an existing interdomain event channel in another domain. Returns 0 - * on success and stores the local port in *port. On error, returns -errno, - * switches the device to XenbusStateClosing, and saves the error in XenStore. - */ -int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port) -{ -	struct evtchn_bind_interdomain bind_interdomain; -	int err; - -	bind_interdomain.remote_dom = dev->otherend_id; -	bind_interdomain.remote_port = remote_port; - -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, -					  &bind_interdomain); -	if (err) -		xenbus_dev_fatal(dev, err, -				 "binding to event channel %d from domain %d", -				 remote_port, dev->otherend_id); -	else -		*port = bind_interdomain.local_port; - -	return err; -} -EXPORT_SYMBOL_GPL(xenbus_bind_evtchn); - - -/**   * Free an existing event channel. Returns 0 on success or -errno on error.   */  int xenbus_free_evtchn(struct xenbus_device *dev, int port) @@ -743,7 +717,7 @@ static const struct xenbus_ring_ops ring_ops_hvm = {  void __init xenbus_ring_ops_init(void)  { -	if (xen_pv_domain()) +	if (!xen_feature(XENFEAT_auto_translated_physmap))  		ring_ops = &ring_ops_pv;  	else  		ring_ops = &ring_ops_hvm; diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 38e92b770e9..3c0a74b3e9b 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -384,12 +384,14 @@ static ssize_t nodename_show(struct device *dev,  {  	return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);  } +static DEVICE_ATTR_RO(nodename);  static ssize_t devtype_show(struct device *dev,  			    struct device_attribute *attr, char *buf)  {  	return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);  } +static DEVICE_ATTR_RO(devtype);  static ssize_t modalias_show(struct device *dev,  			     struct device_attribute *attr, char *buf) @@ -397,14 +399,24 @@ static ssize_t modalias_show(struct device *dev,  	return sprintf(buf, "%s:%s\n", dev->bus->name,  		       to_xenbus_device(dev)->devicetype);  } +static DEVICE_ATTR_RO(modalias); -struct device_attribute xenbus_dev_attrs[] = { -	__ATTR_RO(nodename), -	__ATTR_RO(devtype), -	__ATTR_RO(modalias), -	__ATTR_NULL +static struct attribute *xenbus_dev_attrs[] = { +	&dev_attr_nodename.attr, +	&dev_attr_devtype.attr, +	&dev_attr_modalias.attr, +	NULL,  }; -EXPORT_SYMBOL_GPL(xenbus_dev_attrs); + +static const struct attribute_group xenbus_dev_group = { +	.attrs = xenbus_dev_attrs, +}; + +const struct attribute_group *xenbus_dev_groups[] = { +	&xenbus_dev_group, +	NULL, +}; +EXPORT_SYMBOL_GPL(xenbus_dev_groups);  int xenbus_probe_node(struct xen_bus_type *bus,  		      const char *type, diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h index 146f857a36f..1085ec294a1 100644 --- a/drivers/xen/xenbus/xenbus_probe.h +++ b/drivers/xen/xenbus/xenbus_probe.h @@ -54,7 +54,7 @@ enum xenstore_init {  	XS_LOCAL,  }; -extern struct device_attribute xenbus_dev_attrs[]; +extern const struct attribute_group *xenbus_dev_groups[];  extern int xenbus_match(struct device *_dev, struct device_driver *_drv);  extern int xenbus_dev_probe(struct device *_dev); diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c index 998bbbab816..5125dce11a6 100644 --- a/drivers/xen/xenbus/xenbus_probe_backend.c +++ b/drivers/xen/xenbus/xenbus_probe_backend.c @@ -200,7 +200,7 @@ static struct xen_bus_type xenbus_backend = {  		.probe		= xenbus_dev_probe,  		.remove		= xenbus_dev_remove,  		.shutdown	= xenbus_dev_shutdown, -		.dev_attrs	= xenbus_dev_attrs, +		.dev_groups	= xenbus_dev_groups,  	},  }; diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index 34b20bfa4e8..cb385c10d2b 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -154,7 +154,7 @@ static struct xen_bus_type xenbus_frontend = {  		.probe		= xenbus_frontend_dev_probe,  		.remove		= xenbus_dev_remove,  		.shutdown	= xenbus_dev_shutdown, -		.dev_attrs	= xenbus_dev_attrs, +		.dev_groups	= xenbus_dev_groups,  		.pm		= &xenbus_pm_ops,  	}, @@ -496,7 +496,7 @@ subsys_initcall(xenbus_probe_frontend_init);  #ifndef MODULE  static int __init boot_wait_for_devices(void)  { -	if (xen_hvm_domain() && !xen_platform_pci_unplug) +	if (!xen_has_pv_devices())  		return -ENODEV;  	ready_to_wait_for_devices = 1; diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index b6d5fff43d1..ba804f3d827 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -50,6 +50,7 @@  #include <xen/xenbus.h>  #include <xen/xen.h>  #include "xenbus_comms.h" +#include "xenbus_probe.h"  struct xs_stored_msg {  	struct list_head list; @@ -139,6 +140,29 @@ static int get_error(const char *errorstring)  	return xsd_errors[i].errnum;  } +static bool xenbus_ok(void) +{ +	switch (xen_store_domain_type) { +	case XS_LOCAL: +		switch (system_state) { +		case SYSTEM_POWER_OFF: +		case SYSTEM_RESTART: +		case SYSTEM_HALT: +			return false; +		default: +			break; +		} +		return true; +	case XS_PV: +	case XS_HVM: +		/* FIXME: Could check that the remote domain is alive, +		 * but it is normally initial domain. */ +		return true; +	default: +		break; +	} +	return false; +}  static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)  {  	struct xs_stored_msg *msg; @@ -148,9 +172,20 @@ static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)  	while (list_empty(&xs_state.reply_list)) {  		spin_unlock(&xs_state.reply_lock); -		/* XXX FIXME: Avoid synchronous wait for response here. */ -		wait_event(xs_state.reply_waitq, -			   !list_empty(&xs_state.reply_list)); +		if (xenbus_ok()) +			/* XXX FIXME: Avoid synchronous wait for response here. */ +			wait_event_timeout(xs_state.reply_waitq, +					   !list_empty(&xs_state.reply_list), +					   msecs_to_jiffies(500)); +		else { +			/* +			 * If we are in the process of being shut-down there is +			 * no point of trying to contact XenBus - it is either +			 * killed (xenstored application) or the other domain +			 * has been killed or is unreachable. +			 */ +			return ERR_PTR(-EIO); +		}  		spin_lock(&xs_state.reply_lock);  	} @@ -215,6 +250,9 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)  	mutex_unlock(&xs_state.request_mutex); +	if (IS_ERR(ret)) +		return ret; +  	if ((msg->type == XS_TRANSACTION_END) ||  	    ((req_msg.type == XS_TRANSACTION_START) &&  	     (msg->type == XS_ERROR)))  | 
