return ret;
iface->state = IFS_SETUP;
- ret = iface->proto->handler(iface->proto, PROTO_CMD_SETUP, false);
+ ret = interface_proto_event(iface->proto, PROTO_CMD_SETUP, false);
if (ret) {
mark_interface_down(iface);
return ret;
iface->state = IFS_TEARDOWN;
interface_event(iface, IFEV_DOWN);
- iface->proto->handler(iface->proto, PROTO_CMD_TEARDOWN, force);
+ interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, force);
release_device(iface->main_dev.dev);
}
void interface_set_proto_state(struct interface *iface, struct interface_proto_state *state)
{
if (iface->proto) {
- iface->proto->handler(iface->proto, PROTO_CMD_TEARDOWN, true);
+ interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, true);
iface->proto->free(iface->proto);
iface->proto = NULL;
}
static int
default_proto_handler(struct interface_proto_state *proto,
enum interface_proto_cmd cmd, bool force)
+{
+ return 0;
+}
+
+struct interface_proto_state *get_default_proto(void)
+{
+ struct interface_proto_state *proto;
+
+ proto = calloc(1, sizeof(*proto));
+ proto->handler = default_proto_handler;
+ proto->free = default_proto_free;
+ proto->flags = PROTO_FLAG_IMMEDIATE;
+
+ return proto;
+}
+
+int interface_proto_event(struct interface_proto_state *proto,
+ enum interface_proto_cmd cmd, bool force)
{
enum interface_event ev;
+ int ret;
+
+ ret = proto->handler(proto, cmd, force);
+ if (ret || !(proto->flags & PROTO_FLAG_IMMEDIATE))
+ goto out;
switch(cmd) {
case PROTO_CMD_SETUP:
return -EINVAL;
}
proto->proto_event(proto, ev);
- return 0;
-}
-struct interface_proto_state *get_default_proto(void)
-{
- struct interface_proto_state *proto;
-
- proto = calloc(1, sizeof(*proto));
- proto->handler = default_proto_handler;
- proto->free = default_proto_free;
- return proto;
+out:
+ return ret;
}
PROTO_CMD_TEARDOWN,
};
+enum {
+ PROTO_FLAG_IMMEDIATE = (1 << 0),
+};
+
struct interface_proto_state {
struct interface *iface;
+ unsigned int flags;
/* filled in by the protocol user */
void (*proto_event)(struct interface_proto_state *, enum interface_proto_event ev);
};
struct interface_proto_state *get_default_proto(void);
+int interface_proto_event(struct interface_proto_state *proto,
+ enum interface_proto_cmd cmd, bool force);
#endif