/** * Entry point to this code when a new device is created. Allocate the basic * structures, and watch the store waiting for the hotplug scripts to tell us * the device's handle. Switch to InitWait. */ static int netback_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { const char *message; xenbus_transaction_t xbt; int err; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); if (!be) { xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure"); return -ENOMEM; } be->dev = dev; dev->data = be; err = xenbus_watch_path2(dev, dev->nodename, "handle", &be->backend_watch, backend_changed); if (err) goto fail; do { err = xenbus_transaction_start(&xbt); if (err) { xenbus_dev_fatal(dev, err, "starting transaction"); goto fail; } err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); if (err) { message = "writing feature-sg"; goto abort_transaction; } err = xenbus_transaction_end(xbt, 0); } while (err == -EAGAIN); if (err) { xenbus_dev_fatal(dev, err, "completing transaction"); goto fail; } err = xenbus_switch_state(dev, XenbusStateInitWait); if (err) { goto fail; } return 0; abort_transaction: xenbus_transaction_end(xbt, 1); xenbus_dev_fatal(dev, err, "%s", message); fail: DPRINTK("failed"); netback_remove(dev); return err; }
/** * Entry point to this code when a new device is created. Allocate the basic * structures and switch to InitWait. */ static int netback_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { const char *message; struct xenbus_transaction xbt; int err; int sg; const char *script; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); if (!be) { xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure"); return -ENOMEM; } be->dev = dev; dev_set_drvdata(&dev->dev, be); be->state = XenbusStateInitialising; err = xenbus_switch_state(dev, XenbusStateInitialising); if (err) goto fail; sg = 1; do { err = xenbus_transaction_start(&xbt); if (err) { xenbus_dev_fatal(dev, err, "starting transaction"); goto fail; } err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", sg); if (err) { message = "writing feature-sg"; goto abort_transaction; } err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", sg); if (err) { message = "writing feature-gso-tcpv4"; goto abort_transaction; } err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv6", "%d", sg); if (err) { message = "writing feature-gso-tcpv6"; goto abort_transaction; } /* We support partial checksum setup for IPv6 packets */ err = xenbus_printf(xbt, dev->nodename, "feature-ipv6-csum-offload", "%d", 1); if (err) { message = "writing feature-ipv6-csum-offload"; goto abort_transaction; } /* We support rx-copy path. */ err = xenbus_printf(xbt, dev->nodename, "feature-rx-copy", "%d", 1); if (err) { message = "writing feature-rx-copy"; goto abort_transaction; } /* * We don't support rx-flip path (except old guests who don't * grok this feature flag). */ err = xenbus_printf(xbt, dev->nodename, "feature-rx-flip", "%d", 0); if (err) { message = "writing feature-rx-flip"; goto abort_transaction; } /* We support dynamic multicast-control. */ err = xenbus_printf(xbt, dev->nodename, "feature-multicast-control", "%d", 1); if (err) { message = "writing feature-multicast-control"; goto abort_transaction; } err = xenbus_printf(xbt, dev->nodename, "feature-dynamic-multicast-control", "%d", 1); if (err) { message = "writing feature-dynamic-multicast-control"; goto abort_transaction; } err = xenbus_transaction_end(xbt, 0); } while (err == -EAGAIN); if (err) { xenbus_dev_fatal(dev, err, "completing transaction"); goto fail; } /* * Split event channels support, this is optional so it is not * put inside the above loop. */ err = xenbus_printf(XBT_NIL, dev->nodename, "feature-split-event-channels", "%u", separate_tx_rx_irq); if (err) pr_debug("Error writing feature-split-event-channels\n"); /* Multi-queue support: This is an optional feature. */ err = xenbus_printf(XBT_NIL, dev->nodename, "multi-queue-max-queues", "%u", xenvif_max_queues); if (err) pr_debug("Error writing multi-queue-max-queues\n"); err = xenbus_printf(XBT_NIL, dev->nodename, "feature-ctrl-ring", "%u", true); if (err) pr_debug("Error writing feature-ctrl-ring\n"); script = xenbus_read(XBT_NIL, dev->nodename, "script", NULL); if (IS_ERR(script)) { err = PTR_ERR(script); xenbus_dev_fatal(dev, err, "reading script"); goto fail; } be->hotplug_script = script; /* This kicks hotplug scripts, so do it immediately. */ err = backend_create_xenvif(be); if (err) goto fail; return 0; abort_transaction: xenbus_transaction_end(xbt, 1); xenbus_dev_fatal(dev, err, "%s", message); fail: pr_debug("failed\n"); netback_remove(dev); return err; }
/** * Entry point to this code when a new device is created. Allocate the basic * structures and switch to InitWait. */ static int netback_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { const char *message; struct xenbus_transaction xbt; int err; int sg; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); if (!be) { xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure"); return -ENOMEM; } be->dev = dev; dev_set_drvdata(&dev->dev, be); sg = 1; do { err = xenbus_transaction_start(&xbt); if (err) { xenbus_dev_fatal(dev, err, "starting transaction"); goto fail; } err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", sg); if (err) { message = "writing feature-sg"; goto abort_transaction; } err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", sg); if (err) { message = "writing feature-gso-tcpv4"; goto abort_transaction; } /* We support rx-copy path. */ err = xenbus_printf(xbt, dev->nodename, "feature-rx-copy", "%d", 1); if (err) { message = "writing feature-rx-copy"; goto abort_transaction; } /* * We don't support rx-flip path (except old guests who don't * grok this feature flag). */ err = xenbus_printf(xbt, dev->nodename, "feature-rx-flip", "%d", 0); if (err) { message = "writing feature-rx-flip"; goto abort_transaction; } err = xenbus_transaction_end(xbt, 0); } while (err == -EAGAIN); if (err) { xenbus_dev_fatal(dev, err, "completing transaction"); goto fail; } err = xenbus_switch_state(dev, XenbusStateInitWait); if (err) goto fail; /* This kicks hotplug scripts, so do it immediately. */ backend_create_xenvif(be); return 0; abort_transaction: xenbus_transaction_end(xbt, 1); xenbus_dev_fatal(dev, err, "%s", message); fail: pr_debug("failed"); netback_remove(dev); return err; }
/** * Entry point to this code when a new device is created. Allocate the basic * structures and switch to InitWait. */ static int netback_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { const char *message; struct xenbus_transaction xbt; int err; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); if (!be) { xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure"); return -ENOMEM; } be->dev = dev; dev->dev.driver_data = be; do { err = xenbus_transaction_start(&xbt); if (err) { xenbus_dev_fatal(dev, err, "starting transaction"); goto fail; } err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); if (err) { message = "writing feature-sg"; goto abort_transaction; } err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1); if (err) { message = "writing feature-gso-tcpv4"; goto abort_transaction; } err = xenbus_printf(xbt, dev->nodename, "feature-rx-copy", "%d", 1); if (err) { message = "writing feature-copying"; goto abort_transaction; } err = xenbus_transaction_end(xbt, 0); } while (err == -EAGAIN); if (err) { xenbus_dev_fatal(dev, err, "completing transaction"); goto fail; } err = xenbus_switch_state(dev, XenbusStateInitWait); if (err) goto fail; /* This kicks hotplug scripts, so do it immediately. */ backend_create_netif(be); return 0; abort_transaction: xenbus_transaction_end(xbt, 1); xenbus_dev_fatal(dev, err, "%s", message); fail: DPRINTK("failed"); netback_remove(dev); return err; }