aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/pcifront.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-06-03 11:09:14 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-06-03 11:09:14 +0100
commit8323478d5bd96cb1c00cd67da33f59a42965d9be (patch)
tree3d710fd5ec5b81c3e10d65a0c7208224dd23ae55 /extras/mini-os/pcifront.c
parent44d374adc01fc7cd3e516d6475dc5e9ddedf928d (diff)
downloadxen-8323478d5bd96cb1c00cd67da33f59a42965d9be.tar.gz
xen-8323478d5bd96cb1c00cd67da33f59a42965d9be.tar.bz2
xen-8323478d5bd96cb1c00cd67da33f59a42965d9be.zip
minios: refactor xenbus state machine
Implement xenbus_wait_for_state_change and xenbus_switch_state and change the various frontends to use the two functions and do proper error checking. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/pcifront.c')
-rw-r--r--extras/mini-os/pcifront.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/extras/mini-os/pcifront.c b/extras/mini-os/pcifront.c
index 5b68d86b56..70ea89b82d 100644
--- a/extras/mini-os/pcifront.c
+++ b/extras/mini-os/pcifront.c
@@ -111,9 +111,12 @@ again:
goto abort_transaction;
}
- err = xenbus_printf(xbt, nodename, "state", "%u",
- 3); /* initialised */
-
+ snprintf(path, sizeof(path), "%s/state", nodename);
+ err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
+ if (err) {
+ message = "switching state";
+ goto abort_transaction;
+ }
err = xenbus_transaction_end(xbt, 0, &retry);
if (retry) {
@@ -140,13 +143,29 @@ done:
{
char path[strlen(dev->backend) + 1 + 5 + 1];
+ char frontpath[strlen(nodename) + 1 + 5 + 1];
+ XenbusState state;
snprintf(path, sizeof(path), "%s/state", dev->backend);
xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
- xenbus_wait_for_value(path, "4", &dev->events);
+ err = NULL;
+ state = xenbus_read_integer(path);
+ while (err == NULL && state < XenbusStateConnected)
+ err = xenbus_wait_for_state_change(path, &state, &dev->events);
+ if (state != XenbusStateConnected) {
+ printk("backend not avalable, state=%d\n", state);
+ xenbus_unwatch_path(XBT_NIL, path);
+ goto error;
+ }
- xenbus_printf(xbt, nodename, "state", "%u", 4); /* connected */
+ snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
+ if ((err = xenbus_switch_state(XBT_NIL, frontpath, XenbusStateConnected))
+ != NULL) {
+ printk("error switching state %s\n", err);
+ xenbus_unwatch_path(XBT_NIL, path);
+ goto error;
+ }
}
unmask_evtchn(dev->evtchn);
@@ -190,23 +209,45 @@ void pcifront_scan(struct pcifront_dev *dev, void (*func)(unsigned int domain, u
void shutdown_pcifront(struct pcifront_dev *dev)
{
- char* err;
- char *nodename = dev->nodename;
+ char* err = NULL;
+ XenbusState state;
char path[strlen(dev->backend) + 1 + 5 + 1];
+ char nodename[strlen(dev->nodename) + 1 + 5 + 1];
printk("close pci: backend at %s\n",dev->backend);
snprintf(path, sizeof(path), "%s/state", dev->backend);
- err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
- xenbus_wait_for_value(path, "5", &dev->events);
-
- err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
- xenbus_wait_for_value(path, "6", &dev->events);
-
- err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
- xenbus_wait_for_value(path, "2", &dev->events);
+ snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
+ if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
+ printk("shutdown_pcifront: error changing state to %d: %s\n",
+ XenbusStateClosing, err);
+ goto close_pcifront;
+ }
+ state = xenbus_read_integer(path);
+ while (err == NULL && state < XenbusStateClosing)
+ err = xenbus_wait_for_state_change(path, &state, &dev->events);
+
+ if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
+ printk("shutdown_pcifront: error changing state to %d: %s\n",
+ XenbusStateClosed, err);
+ goto close_pcifront;
+ }
+ state = xenbus_read_integer(path);
+ if (state < XenbusStateClosed)
+ xenbus_wait_for_state_change(path, &state, &dev->events);
+
+ if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) {
+ printk("shutdown_pcifront: error changing state to %d: %s\n",
+ XenbusStateInitialising, err);
+ goto close_pcifront;
+ }
+ err = NULL;
+ state = xenbus_read_integer(path);
+ while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
+ err = xenbus_wait_for_state_change(path, &state, &dev->events);
+close_pcifront:
xenbus_unwatch_path(XBT_NIL, path);
snprintf(path, sizeof(path), "%s/info-ref", nodename);