/* Called by xenbus when our backend node changes state */ static void pcifront_backend_changed(struct xenbus_device *xdev, XenbusState be_state) { struct pcifront_device *pdev = xdev->data; switch (be_state) { case XenbusStateClosing: DPRINTF("backend closing (%s)\n", xdev->nodename); pcifront_disconnect(pdev); break; case XenbusStateClosed: DPRINTF("backend closed (%s)\n", xdev->nodename); pcifront_disconnect(pdev); break; case XenbusStateConnected: DPRINTF("backend connected (%s)\n", xdev->nodename); pcifront_connect(pdev); break; default: break; } }
static int __devinit pcifront_try_connect(struct pcifront_device *pdev) { int err = -EFAULT; int i, num_roots, len; char str[64]; unsigned int domain, bus; spin_lock(&pdev->dev_lock); /* Only connect once */ if (xenbus_read_driver_state(pdev->xdev->nodename) != XenbusStateInitialised) goto out; err = pcifront_connect(pdev); if (err) { xenbus_dev_fatal(pdev->xdev, err, "Error connecting PCI Frontend"); goto out; } err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "root_num", "%d", &num_roots); if (err == -ENOENT) { xenbus_dev_error(pdev->xdev, err, "No PCI Roots found, trying 0000:00"); err = pcifront_scan_root(pdev, 0, 0); num_roots = 0; } else if (err != 1) { if (err == 0) err = -EINVAL; xenbus_dev_fatal(pdev->xdev, err, "Error reading number of PCI roots"); goto out; } for (i = 0; i < num_roots; i++) { len = snprintf(str, sizeof(str), "root-%d", i); if (unlikely(len >= (sizeof(str) - 1))) { err = -ENOMEM; goto out; } err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, "%x:%x", &domain, &bus); if (err != 2) { if (err >= 0) err = -EINVAL; xenbus_dev_fatal(pdev->xdev, err, "Error reading PCI root %d", i); goto out; } err = pcifront_scan_root(pdev, domain, bus); if (err) { xenbus_dev_fatal(pdev->xdev, err, "Error scanning PCI root %04x:%02x", domain, bus); goto out; } } err = xenbus_switch_state(pdev->xdev, XenbusStateConnected); if (err) goto out; out: spin_unlock(&pdev->dev_lock); return err; }