static void _app_main(void *arg) { start_info_t *si = arg; #ifdef CONFIG_PCI init_pcifront(NULL); #endif app_main(si); }
void pcifront_watches(void *opaque) { XenbusState state; char *err = NULL, *msg = NULL; char *be_path, *be_state; char* nodename = opaque ? opaque : "device/pci/0"; char path[strlen(nodename) + 9]; char fe_state[strlen(nodename) + 7]; xenbus_event_queue events = NULL; snprintf(path, sizeof(path), "%s/backend", nodename); snprintf(fe_state, sizeof(fe_state), "%s/state", nodename); while (1) { printk("pcifront_watches: waiting for backend path to appear %s\n", path); xenbus_watch_path_token(XBT_NIL, path, path, &events); while ((err = xenbus_read(XBT_NIL, path, &be_path)) != NULL) { free(err); xenbus_wait_for_watch(&events); } xenbus_unwatch_path_token(XBT_NIL, path, path); printk("pcifront_watches: waiting for backend to get into the right state %s\n", be_path); be_state = (char *) malloc(strlen(be_path) + 7); snprintf(be_state, strlen(be_path) + 7, "%s/state", be_path); xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events); while ((err = xenbus_read(XBT_NIL, be_state, &msg)) != NULL || msg[0] > '4') { free(msg); free(err); xenbus_wait_for_watch(&events); } xenbus_unwatch_path_token(XBT_NIL, be_state, be_state); if (init_pcifront(NULL) == NULL) { free(be_state); free(be_path); continue; } xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events); state = XenbusStateConnected; printk("pcifront_watches: waiting for backend events %s\n", be_state); while ((err = xenbus_wait_for_state_change(be_state, &state, &events)) == NULL && (err = xenbus_read(XBT_NIL, pcidev->backend, &msg)) == NULL) { free(msg); printk("pcifront_watches: backend state changed: %s %d\n", be_state, state); if (state == XenbusStateReconfiguring) { printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateReconfiguring); if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateReconfiguring)) != NULL) { printk("pcifront_watches: error changing state to %d: %s\n", XenbusStateReconfiguring, err); if (!strcmp(err, "ENOENT")) { xenbus_write(XBT_NIL, fe_state, "7"); free(err); } } } else if (state == XenbusStateReconfigured) { printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateConnected); printk("pcifront_watches: changing state to %d\n", XenbusStateConnected); if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateConnected)) != NULL) { printk("pcifront_watches: error changing state to %d: %s\n", XenbusStateConnected, err); if (!strcmp(err, "ENOENT")) { xenbus_write(XBT_NIL, fe_state, "4"); free(err); } } } else if (state == XenbusStateClosing) break; } if (err) { printk("pcifront_watches: done waiting err=%s\n", err); free(err); } else printk("pcifront_watches: done waiting\n"); err = xenbus_unwatch_path_token(XBT_NIL, be_state, be_state); shutdown_pcifront(pcidev); free(be_state); free(be_path); free(err); pcidev = NULL; } xenbus_unwatch_path_token(XBT_NIL, path, path); }