return intf;
}
-/*
- * Tear down a previously set up interface.
- */
-void gb_interface_remove(struct gb_interface *intf)
-{
- struct gb_bundle *bundle;
- struct gb_bundle *next;
-
- /*
- * Disable the control-connection early to avoid operation timeouts
- * when the interface is already gone.
- */
- if (intf->disconnected)
- gb_control_disable(intf->control);
-
- list_for_each_entry_safe(bundle, next, &intf->bundles, links)
- gb_bundle_destroy(bundle);
-
- if (device_is_registered(&intf->dev)) {
- device_del(&intf->dev);
- dev_info(&intf->dev, "Interface removed\n");
- }
-
- gb_control_disable(intf->control);
-
- list_del(&intf->links);
-
- put_device(&intf->dev);
-}
-
/*
* Enable an interface by enabling its control connection and fetching the
* manifest and other information over it.
return ret;
}
+/* Disable an interface and destroy its bundles. */
+void gb_interface_disable(struct gb_interface *intf)
+{
+ struct gb_bundle *bundle;
+ struct gb_bundle *next;
+
+ /*
+ * Disable the control-connection early to avoid operation timeouts
+ * when the interface is already gone.
+ */
+ if (intf->disconnected)
+ gb_control_disable(intf->control);
+
+ list_for_each_entry_safe(bundle, next, &intf->bundles, links)
+ gb_bundle_destroy(bundle);
+
+ gb_control_disable(intf->control);
+}
+
/* Register an interface and its bundles. */
int gb_interface_add(struct gb_interface *intf)
{
return 0;
}
+
+/* Deregister an interface and drop its reference. */
+void gb_interface_remove(struct gb_interface *intf)
+{
+ if (device_is_registered(&intf->dev)) {
+ device_del(&intf->dev);
+ dev_info(&intf->dev, "Interface removed\n");
+ }
+
+ list_del(&intf->links);
+
+ put_device(&intf->dev);
+}
{
intf->disconnected = true;
- get_device(&intf->dev);
-
- gb_interface_remove(intf);
+ gb_interface_disable(intf);
gb_svc_interface_route_destroy(svc, intf);
-
- put_device(&intf->dev);
+ gb_interface_remove(intf);
}
static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
{
struct gb_interface *intf, *tmp;
- list_for_each_entry_safe(intf, tmp, &svc->hd->interfaces, links)
+ list_for_each_entry_safe(intf, tmp, &svc->hd->interfaces, links) {
+ gb_interface_disable(intf);
gb_interface_remove(intf);
+ }
}
void gb_svc_del(struct gb_svc *svc)