/** * Callback received when the frontend's state changes. */ static void frontend_changed(struct xenbus_device *dev, enum xenbus_state frontend_state) { struct backend_info *be = dev->dev.driver_data; DPRINTK("%s", xenbus_strstate(frontend_state)); be->frontend_state = frontend_state; switch (frontend_state) { case XenbusStateInitialising: if (dev->state == XenbusStateClosed) { printk("%s: %s: prepare for reconnect\n", __FUNCTION__, dev->nodename); if (be->netif) { netif_disconnect(be->netif); be->netif = NULL; } xenbus_switch_state(dev, XenbusStateInitWait); } break; case XenbusStateInitialised: break; case XenbusStateConnected: backend_create_netif(be); if (be->netif) connect(be); break; case XenbusStateClosing: xenbus_switch_state(dev, XenbusStateClosing); break; case XenbusStateClosed: xenbus_switch_state(dev, XenbusStateClosed); if (xenbus_dev_is_online(dev)) break; /* fall through if not online */ case XenbusStateUnknown: if (be->netif != NULL) kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); device_unregister(&dev->dev); break; default: xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend", frontend_state); break; } }
/** * 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; if (netbk_copy_skb_mode == NETBK_ALWAYS_COPY_SKB) sg = 0; 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; } /* We support data smart poll mechanism */ err = xenbus_printf(xbt, dev->nodename, "feature-smart-poll", "%d", 1); if (err) { message = "writing feature-smart-poll"; goto abort_transaction; } err = xenbus_transaction_end(xbt, 0); } while (err == -EAGAIN); if (err) { xenbus_dev_fatal(dev, err, "completing transaction"); goto fail; } //netback_probe_accelerators(be, dev); 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; }
/** * 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; }