[banjo] Inline interfaces in protocol call sites.

This reduces boilerplate callers need to write to invoke
protocol
methods where they send interfaces across.

Also includes some small unrelated fixes.

Tested: Builds.
Change-Id: If615c4f16f14b0dfa708eb8b4f5f50022762ff10
diff --git a/system/dev/block/ums-function/ums-function.c b/system/dev/block/ums-function/ums-function.c
index 85ed85a..8000f30 100644
--- a/system/dev/block/ums-function/ums-function.c
+++ b/system/dev/block/ums-function/ums-function.c
@@ -607,11 +607,7 @@
         goto fail;
     }
 
-    usb_function_interface_t intf = {
-        .ops = &ums_device_ops,
-        .ctx = ums,
-    };
-    usb_function_set_interface(&ums->function, &intf);
+    usb_function_set_interface(&ums->function, ums, &ums_device_ops);
 
     return ZX_OK;
 
diff --git a/system/dev/display/display/controller.cpp b/system/dev/display/display/controller.cpp
index 78e2a04..8bce30c 100644
--- a/system/dev/display/display/controller.cpp
+++ b/system/dev/display/display/controller.cpp
@@ -845,8 +845,7 @@
     }
     __UNUSED auto ptr = device_ptr->release();
 
-    display_controller_interface_t intf = {&display_controller_interface_ops_, this};
-    dc_.SetDisplayControllerInterface(&intf);
+    dc_.SetDisplayControllerInterface(this, &display_controller_interface_ops_);
 
     return ZX_OK;
 }
diff --git a/system/dev/ethernet/ethernet/ethernet.c b/system/dev/ethernet/ethernet/ethernet.c
index ec3682c..e157bc6 100644
--- a/system/dev/ethernet/ethernet/ethernet.c
+++ b/system/dev/ethernet/ethernet/ethernet.c
@@ -665,8 +665,7 @@
         // Release the lock to allow other device operations in callback routine.
         // Re-acquire lock afterwards.
         mtx_unlock(&edev0->lock);
-        const ethmac_ifc_t ifc = {&ethmac_ifc, edev0};
-        status = ethmac_start(&edev->edev0->mac, &ifc);
+        status = ethmac_start(&edev->edev0->mac, edev0, &ethmac_ifc);
         mtx_lock(&edev0->lock);
         // Check whether unbind was called while we were unlocked.
         if (edev->state & ETHDEV_DEAD) {
diff --git a/system/dev/ethernet/usb-cdc-function/cdc-eth-function.cpp b/system/dev/ethernet/usb-cdc-function/cdc-eth-function.cpp
index dd288d0..71d1679 100644
--- a/system/dev/ethernet/usb-cdc-function/cdc-eth-function.cpp
+++ b/system/dev/ethernet/usb-cdc-function/cdc-eth-function.cpp
@@ -631,10 +631,6 @@
     mtx_init(&cdc->rx_mutex, mtx_plain);
     mtx_init(&cdc->intr_mutex, mtx_plain);
 
-    usb_function_interface_t intf = {};
-    intf.ops = &device_ops;
-    intf.ctx = cdc;
-
     cdc->bulk_max_packet = BULK_MAX_PACKET; // FIXME(voydanoff) USB 3.0 support
     cdc->parent_req_size = usb_function_get_request_size(&cdc->function);
     uint64_t req_size = cdc->parent_req_size + sizeof(usb_req_internal_t);
@@ -727,7 +723,7 @@
         goto fail;
     }
 
-    usb_function_set_interface(&cdc->function, &intf);
+    usb_function_set_interface(&cdc->function, cdc, &device_ops);
 
     return ZX_OK;
 
diff --git a/system/dev/input/hid/hid.c b/system/dev/input/hid/hid.c
index 4037467..95fa301 100644
--- a/system/dev/input/hid/hid.c
+++ b/system/dev/input/hid/hid.c
@@ -92,8 +92,8 @@
     return hid->hid.ops->query(hid->hid.ctx, options, info);
 }
 
-static inline zx_status_t hid_op_start(hid_device_t* hid, const hidbus_ifc_t* ifc) {
-    return hidbus_start(&hid->hid, ifc);
+static inline zx_status_t hid_op_start(hid_device_t* hid, void* ctx, hidbus_ifc_ops_t* ops) {
+    return hidbus_start(&hid->hid, ctx, ops);
 }
 
 static inline void hid_op_stop(hid_device_t* hid) {
@@ -692,7 +692,7 @@
     }
 
     // TODO: delay calling start until we've been opened by someone
-    status = hid_op_start(hiddev, &(hidbus_ifc_t){&hid_ifc_ops, hiddev});
+    status = hid_op_start(hiddev, hiddev, &hid_ifc_ops);
     if (status != ZX_OK) {
         zxlogf(ERROR, "hid: could not start hid device: %d\n", status);
         device_remove(hiddev->zxdev);
diff --git a/system/dev/usb/usb-bus/usb-bus.cpp b/system/dev/usb/usb-bus/usb-bus.cpp
index 7830635..49a9c11 100644
--- a/system/dev/usb/usb-bus/usb-bus.cpp
+++ b/system/dev/usb/usb-bus/usb-bus.cpp
@@ -52,12 +52,7 @@
         return status;
     }
 
-    // TODO(surajmalhotra) is there a better way to do this?
-    usb_bus_interface_t intf = {
-        .ops = &usb_bus_interface_ops_,
-        .ctx = this,
-    };
-    hci_.SetBusInterface(&intf);
+    hci_.SetBusInterface(this, &usb_bus_interface_ops_);
 
     return ZX_OK;
 }
@@ -222,7 +217,7 @@
 }
 
 void UsbBus::DdkUnbind() {
-    hci_.SetBusInterface(nullptr);
+    hci_.SetBusInterface(nullptr, nullptr);
 
     for (auto device : devices_) {
         if (device != nullptr) {
diff --git a/system/dev/usb/usb-hub/usb-hub.c b/system/dev/usb/usb-hub/usb-hub.c
index d39f9aa..daf20d9 100644
--- a/system/dev/usb/usb-hub/usb-hub.c
+++ b/system/dev/usb/usb-hub/usb-hub.c
@@ -508,10 +508,7 @@
         return status;
     }
 
-    static usb_hub_interface_t hub_intf;
-    hub_intf.ops = &_hub_interface;
-    hub_intf.ctx = hub;
-    usb_bus_set_hub_interface(&bus, hub->usb_device, &hub_intf);
+    usb_bus_set_hub_interface(&bus, hub->usb_device, hub, &_hub_interface);
 
     int ret = thrd_create_with_name(&hub->thread, usb_hub_thread, hub, "usb_hub_thread");
     if (ret != thrd_success) {
diff --git a/system/dev/usb/usb-peripheral-test/driver.cpp b/system/dev/usb/usb-peripheral-test/driver.cpp
index c2df475..99372d5 100644
--- a/system/dev/usb/usb-peripheral-test/driver.cpp
+++ b/system/dev/usb/usb-peripheral-test/driver.cpp
@@ -335,9 +335,6 @@
     list_initialize(&test->intr_reqs);
 
     device_add_args_t args = {};
-    usb_function_interface_t intf = {};
-    intf.ops = &device_ops;
-    intf.ctx = test;
 
     status = usb_function_alloc_interface(&test->function, &descriptors.intf.bInterfaceNumber);
     if (status != ZX_OK) {
@@ -409,7 +406,7 @@
         goto fail;
     }
 
-    usb_function_set_interface(&test->function, &intf);
+    usb_function_set_interface(&test->function, test, &device_ops);
 
     return ZX_OK;
 
diff --git a/system/dev/usb/usb-peripheral/usb-peripheral.cpp b/system/dev/usb/usb-peripheral/usb-peripheral.cpp
index 80ac781..16a58d5 100644
--- a/system/dev/usb/usb-peripheral/usb-peripheral.cpp
+++ b/system/dev/usb/usb-peripheral/usb-peripheral.cpp
@@ -79,12 +79,7 @@
         return status;
     }
 
-    // TODO(surajmalhotra) is there a better way to do this?
-    usb_dci_interface_t intf = {
-        .ops = &usb_dci_interface_ops_,
-        .ctx = this,
-    };
-    dci_.SetInterface(&intf);
+    dci_.SetInterface(this, &usb_dci_interface_ops_);
 
 #if defined(USB_DEVICE_VID) && defined(USB_DEVICE_PID) && defined(USB_DEVICE_FUNCTIONS)
     // Set compile time configuration, if we have one.
diff --git a/system/host/banjo/lib/ddk_generator.cpp b/system/host/banjo/lib/ddk_generator.cpp
index 93880ed..215c7c8 100644
--- a/system/host/banjo/lib/ddk_generator.cpp
+++ b/system/host/banjo/lib/ddk_generator.cpp
@@ -74,7 +74,7 @@
     *file << "// Use of this source code is governed by a BSD-style license that can be\n";
     *file << "// found in the LICENSE file.\n\n";
     *file << "// WARNING: THIS FILE IS MACHINE GENERATED. DO NOT EDIT.\n";
-    *file << "//          MODIFY system/banjo/ddk-protocol-" << name <<  "/" << name
+    *file << "//          MODIFY system/banjo/ddk-protocol-" << name << "/" << name
           << ".banjo INSTEAD.\n\n";
 }
 
@@ -110,11 +110,13 @@
 
         if (end == std::string::npos) {
             StringView view(&src[start], src.size() - start);
-            if (!view.empty()) result.push_back(view);
+            if (!view.empty())
+                result.push_back(view);
             start = std::string::npos;
         } else {
             StringView view(&src[start], end - start);
-            if (!view.empty()) result.push_back(view);
+            if (!view.empty())
+                result.push_back(view);
             start = end + 1;
         }
     }
@@ -151,7 +153,8 @@
         } else {
             const auto prefix = member.nullability == types::Nullability::kNullable ? "" : "const ";
             *file << prefix << member.element_type << (output ? "** " : "* ")
-                  << NameBuffer(member) << ";\n" << kIndent << "size_t " << NameCount(member);
+                  << NameBuffer(member) << ";\n"
+                  << kIndent << "size_t " << NameCount(member);
         }
         break;
     case flat::Type::Kind::kString:
@@ -189,8 +192,10 @@
     }
 }
 
+// If tranform is true, interface structs will be inlined as void* ctx and
+// foo_ops_t* ops members.
 void EmitMethodInParamDecl(std::ostream* file, const DdkGenerator::Member& member,
-                           bool emit_name = true) {
+                           bool emit_name = true, bool transform = false) {
     const auto member_name = emit_name ? " " + member.name : "";
     switch (member.kind) {
     case flat::Type::Kind::kArray:
@@ -222,7 +227,17 @@
             *file << member.type << member_name;
             break;
         case flat::Decl::Kind::kInterface:
-            *file << member.type << "*" << member_name;
+            if (transform &&
+                member.name.find("cb") == std::string::npos &&
+                member.name.find("callback") == std::string::npos &&
+                member.name.find("func") == std::string::npos) {
+                const auto ctx = emit_name ? member_name + "_ctx" : "";
+                const auto ops = emit_name ? member_name + "_ops" : "";
+                const auto type = member.type.substr(6, member.type.size() - 8) + "_ops_t";
+                *file << "void*" << ctx << ", " << type << "*" << ops;
+            } else {
+                *file << member.type << "*" << member_name;
+            }
             break;
         case flat::Decl::Kind::kStruct:
         case flat::Decl::Kind::kUnion:
@@ -232,7 +247,7 @@
                 *file << member.type << member_name;
                 break;
             case types::Nullability::kNonnullable:
-                *file << "const " << member.type << "*" <<  member_name;
+                *file << "const " << member.type << "*" << member_name;
                 break;
             }
             break;
@@ -299,7 +314,7 @@
 void EmitMethodDeclHelper(std::ostream* file, StringView method_name,
                           const std::vector<DdkGenerator::Member>& input,
                           const std::vector<DdkGenerator::Member>& output,
-                          StringView ctx) {
+                          StringView ctx, bool transform = false) {
     const bool return_first = ReturnFirst(output);
     if (return_first) {
         *file << output[0].type << " ";
@@ -317,7 +332,7 @@
         } else {
             *file << ", ";
         }
-        EmitMethodInParamDecl(file, member);
+        EmitMethodInParamDecl(file, member, true, transform);
     }
     for (auto member = output.begin() + (return_first ? 1 : 0); member != output.end();
          member++) {
@@ -336,6 +351,12 @@
     EmitMethodDeclHelper(file, method_name, input, output, "");
 }
 
+void EmitProtocolMethodDeclTransform(std::ostream* file, StringView method_name,
+                                     const std::vector<DdkGenerator::Member>& input,
+                                     const std::vector<DdkGenerator::Member>& output) {
+    EmitMethodDeclHelper(file, method_name, input, output, "", true);
+}
+
 void EmitProtocolMethodWithCtxDecl(std::ostream* file, StringView method_name,
                                    const std::vector<DdkGenerator::Member>& input,
                                    const std::vector<DdkGenerator::Member>& output) {
@@ -347,7 +368,7 @@
                                            const std::vector<DdkGenerator::Member>& input,
                                            const std::vector<DdkGenerator::Member>& output) {
     EmitMethodDeclHelper(file, method_name, input, output,
-                         "const " + protocol_name + "_t* proto");
+                         "const " + protocol_name + "_t* proto", true);
 }
 
 void EmitProtocolMethodPtrDecl(std::ostream* file, const std::string& method_name,
@@ -366,7 +387,7 @@
 void EmitMethodImplHelper(std::ostream* file, StringView method_name,
                           const std::vector<DdkGenerator::Member>& input,
                           const std::vector<DdkGenerator::Member>& output,
-                          StringView ctx, bool save_ret=false) {
+                          StringView ctx, bool save_ret = false) {
     const bool return_first = ReturnFirst(output);
     if (return_first)
         *file << (save_ret ? "auto ret = " : "return ");
@@ -412,7 +433,22 @@
 void EmitDdkProtocolMethodImpl(std::ostream* file, const std::string& method_name,
                                const std::vector<DdkGenerator::Member>& input,
                                const std::vector<DdkGenerator::Member>& output) {
-    EmitMethodImplHelper(file,  "proto->ops->" + method_name, input, output,
+    for (auto& member : input) {
+        if (member.kind == flat::Type::Kind::kIdentifier &&
+            member.decl_kind == flat::Decl::Kind::kInterface &&
+            member.name.find("cb") == std::string::npos &&
+            member.name.find("callback") == std::string::npos &&
+            member.name.find("func") == std::string::npos) {
+            *file << member.type << " " << member.name << "2 = {\n";
+            *file << kIndent << kIndent << kIndent << ".ops = " << member.name << "_ops,\n";
+            *file << kIndent << kIndent << kIndent << ".ctx = " << member.name << "_ctx,\n";
+            *file << kIndent << kIndent << "};\n";
+            *file << kIndent << kIndent << member.type << "* " << member.name
+                  << " = &" << member.name << "2;\n";
+            *file << kIndent << kIndent;
+        }
+    }
+    EmitMethodImplHelper(file, "proto->ops->" + method_name, input, output,
                          "proto->ctx");
     *file << ");\n";
 }
@@ -427,7 +463,7 @@
     }
     for (auto& member : output) {
         if (member.kind == flat::Type::Kind::kHandle) {
-            *file << kIndent << kIndent <<  member.type << " out_" << member.name << "2;\n";
+            *file << kIndent << kIndent << member.type << " out_" << member.name << "2;\n";
             member.name = member.name + "2";
             member.address_of = true;
         }
@@ -437,7 +473,7 @@
     *file << ");\n";
     for (auto& member : output) {
         if (member.kind == flat::Type::Kind::kHandle) {
-            *file << kIndent << kIndent <<  "*out_"
+            *file << kIndent << kIndent << "*out_"
                   << member.name.substr(0, member.name.size() - 1) << " = out_"
                   << member.name << ".release();\n";
         }
@@ -450,6 +486,22 @@
 void EmitClientMethodImpl(std::ostream* file, const std::string& method_name,
                           std::vector<DdkGenerator::Member>& input,
                           std::vector<DdkGenerator::Member>& output) {
+
+    for (auto& member : input) {
+        if (member.kind == flat::Type::Kind::kIdentifier &&
+            member.decl_kind == flat::Decl::Kind::kInterface && 
+            member.name.find("cb") == std::string::npos &&
+            member.name.find("callback") == std::string::npos &&
+            member.name.find("func") == std::string::npos) {
+            *file << member.type << " " << member.name << "2 = {\n";
+            *file << kIndent << kIndent << kIndent << ".ops = " << member.name << "_ops,\n";
+            *file << kIndent << kIndent << kIndent << ".ctx = " << member.name << "_ctx,\n";
+            *file << kIndent << kIndent << "};\n";
+            *file << kIndent << kIndent << member.type << "* " << member.name
+                  << " = &" << member.name << "2;\n";
+            *file << kIndent << kIndent;
+        }
+    }
     for (auto& member : input) {
         if (member.kind == flat::Type::Kind::kHandle) {
             member.name = member.name + ".release()";
@@ -476,7 +528,7 @@
             break;
         case flat::Type::Kind::kVector:
             *file << kIndent << "memcpy(ctx->" << NameBuffer(member) << ", " << NameBuffer(member)
-                  << ", sizeof(*" << NameBuffer(member) <<  ") * " << NameCount(member) << ");\n";
+                  << ", sizeof(*" << NameBuffer(member) << ") * " << NameCount(member) << ");\n";
             *file << kIndent << "*ctx->" << name << "_actual = " << NameCount(member) << ";\n";
             break;
         case flat::Type::Kind::kString:
@@ -703,7 +755,9 @@
     std::vector<uint32_t> array_counts;
     for (;;) {
         switch (type->kind) {
-        default: { return array_counts; }
+        default: {
+            return array_counts;
+        }
         case flat::Type::Kind::kArray: {
             auto array_type = static_cast<const flat::ArrayType*>(type);
             uint32_t element_count = array_type->element_count.Value();
@@ -771,12 +825,14 @@
         return "zx::bti";
     case types::HandleSubtype::kProfile:
         return "zx::profile";
-    default: { abort(); }
+    default: {
+        abort();
+    }
     }
 }
 
 std::string NameType(const flat::Type* type, const flat::Decl::Kind& decl_kind,
-                     bool handle_wrappers=false) {
+                     bool handle_wrappers = false) {
     for (;;) {
         switch (type->kind) {
         case flat::Type::Kind::kHandle:
@@ -829,17 +885,21 @@
                 return std::string(
                     "const " + ToSnakeCase(identifier_type->name.name().data()) + "_t");
             }
-            default: { abort(); }
+            default: {
+                abort();
+            }
             }
         }
-        default: { abort(); }
+        default: {
+            abort();
+        }
         }
     }
 }
 
 template <typename T>
 DdkGenerator::Member CreateMember(const flat::Library* library, const T& decl,
-                                  bool handle_wrappers=false) {
+                                  bool handle_wrappers = false, bool transform = false) {
     std::string name = NameIdentifier(decl.name);
     const flat::Type* type = decl.type.get();
     auto decl_kind = GetDeclKind(library, type);
@@ -887,7 +947,7 @@
                          const DdkGenerator::NamedMethod& method_info,
                          std::vector<DdkGenerator::Member>* input,
                          std::vector<DdkGenerator::Member>* output,
-                         bool handle_wrappers=false) {
+                         bool handle_wrappers = false) {
     input->reserve(method_info.input_parameters.size() + (method_info.async ? 2 : 0));
     for (const auto& parameter : method_info.input_parameters) {
         input->push_back(CreateMember(library, parameter, handle_wrappers));
@@ -931,13 +991,13 @@
             continue;
         if (dep_library->HasAttribute("Internal"))
             continue;
-        EmitIncludeHeader(&file_, "<" +  ToLispCase(StringJoin(dep_library->name(), "/")) + ".h>");
+        EmitIncludeHeader(&file_, "<" + ToLispCase(StringJoin(dep_library->name(), "/")) + ".h>");
     }
     EmitIncludeHeader(&file_, "<zircon/compiler.h>");
     EmitIncludeHeader(&file_, "<zircon/types.h>");
 
     EmitBlank(&file_);
-    file_ <<  "__BEGIN_CDECLS;\n";
+    file_ << "__BEGIN_CDECLS;\n";
 }
 
 void DdktlGenerator::GeneratePrologues() {
@@ -945,13 +1005,13 @@
     EmitHeaderGuard(&file_);
     EmitBlank(&file_);
     EmitIncludeHeader(&file_, "<ddk/driver.h>");
-    EmitIncludeHeader(&file_, "<" +  ToLispCase(LibraryName(library_, "/")) + ".h>");
+    EmitIncludeHeader(&file_, "<" + ToLispCase(LibraryName(library_, "/")) + ".h>");
     for (const auto& dep_library : library_->dependencies()) {
         if (dep_library == library_)
             continue;
         if (dep_library->HasAttribute("Internal"))
             continue;
-        EmitIncludeHeader(&file_, "<" +  ToLispCase(StringJoin(dep_library->name(), "/")) + ".h>");
+        EmitIncludeHeader(&file_, "<" + ToLispCase(StringJoin(dep_library->name(), "/")) + ".h>");
     }
     EmitIncludeHeader(&file_, "<ddktl/device-internal.h>");
     EmitIncludeHeader(&file_, "<zircon/assert.h>");
@@ -983,7 +1043,7 @@
     }
 
     for (const auto& include : includes) {
-        EmitIncludeHeader(&file_, "<lib/zx/" + include  + ".h>");
+        EmitIncludeHeader(&file_, "<lib/zx/" + include + ".h>");
     }
 
     EmitBlank(&file_);
@@ -994,7 +1054,7 @@
 }
 
 void DdkGenerator::GenerateEpilogues() {
-    file_ <<  "__END_CDECLS;\n";
+    file_ << "__END_CDECLS;\n";
 }
 
 void DdktlGenerator::GenerateEpilogues() {
@@ -1074,7 +1134,8 @@
         file_ << kIndent;
         EmitMemberDecl(&file_, member, helper && !first);
         file_ << ";\n";
-        if (first) first = false;
+        if (first)
+            first = false;
     }
     if (packed) {
         file_ << "} __attribute__((__packed__));\n";
@@ -1373,7 +1434,8 @@
 
 void DdkGenerator::ProduceStructForwardDeclaration(const NamedStruct& named_struct) {
     // TODO: Hack - structs with no members are defined in a different header.
-    if (named_struct.struct_info.members.empty()) return;
+    if (named_struct.struct_info.members.empty())
+        return;
 
     GenerateStructTypedef(named_struct.name, named_struct.type_name);
 }
@@ -1470,7 +1532,8 @@
 
     // Emit Protocol async helper functions.
     for (const auto& method_info : named_interface.methods) {
-        if (!method_info.async || !method_info.generate_sync_method) continue;
+        if (!method_info.async || !method_info.generate_sync_method)
+            continue;
         // Generate context struct.
         std::vector<DdkGenerator::Member> members;
         members.reserve(method_info.output_parameters.size() + 1);
@@ -1576,7 +1639,8 @@
 }
 
 void DdktlGenerator::ProduceProtocolImplementation(const NamedInterface& named_interface) {
-    if (named_interface.type == InterfaceType::kCallback) return;
+    if (named_interface.type == InterfaceType::kCallback)
+        return;
 
     const auto& sc_name = named_interface.snake_case_name;
     const auto& cc_name = named_interface.camel_case_name;
@@ -1601,7 +1665,7 @@
               << "// Can only inherit from one base_protocol implementation.\n";
         file_ << kIndent << kIndent << kIndent << "ZX_ASSERT(dev->ddk_proto_id_ == 0);\n";
         file_ << kIndent << kIndent << kIndent << "dev->ddk_proto_id_ = ZX_PROTOCOL_"
-            << ToSnakeCase(named_interface.shortname, true) << ";\n";
+              << ToSnakeCase(named_interface.shortname, true) << ";\n";
         file_ << kIndent << kIndent << kIndent << "dev->ddk_proto_ops_ = &" << ops << ";\n";
         file_ << kIndent << kIndent << "}\n";
     }
@@ -1633,7 +1697,8 @@
 }
 
 void DdktlGenerator::ProduceClientImplementation(const NamedInterface& named_interface) {
-    if (named_interface.type == InterfaceType::kCallback) return;
+    if (named_interface.type == InterfaceType::kCallback)
+        return;
 
     const auto& sc_name = named_interface.snake_case_name;
     const auto& cc_name = named_interface.camel_case_name;
@@ -1680,7 +1745,7 @@
 
         EmitDocstring(&file_, method_info, true);
         file_ << kIndent;
-        EmitProtocolMethodDecl(&file_, method_info.proxy_name, input, output);
+        EmitProtocolMethodDeclTransform(&file_, method_info.proxy_name, input, output);
         file_ << ") const {\n"
               << kIndent << kIndent;
         EmitClientMethodImpl(&file_, method_info.c_name, input, output);
@@ -1695,7 +1760,8 @@
 }
 
 void DdktlGenerator::ProduceProtocolSubclass(const NamedInterface& named_interface) {
-    if (named_interface.type == InterfaceType::kCallback) return;
+    if (named_interface.type == InterfaceType::kCallback)
+        return;
 
     const auto& sc_name = named_interface.snake_case_name;
     const auto& cc_name = named_interface.camel_case_name;
@@ -1732,7 +1798,8 @@
 
 void DdkGenerator::ProduceStructDeclaration(const NamedStruct& named_struct) {
     // TODO: Hack - structs with no members are defined in a different header.
-    if (named_struct.struct_info.members.empty()) return;
+    if (named_struct.struct_info.members.empty())
+        return;
 
     std::vector<DdkGenerator::Member> members =
         GenerateMembers(library_, named_struct.struct_info.members);
diff --git a/system/ulib/ddktl/test/ethernet-tests.cpp b/system/ulib/ddktl/test/ethernet-tests.cpp
index 77b0839..a291e43 100644
--- a/system/ulib/ddktl/test/ethernet-tests.cpp
+++ b/system/ulib/ddktl/test/ethernet-tests.cpp
@@ -55,8 +55,7 @@
     ethmac_ifc_t ethmac_ifc() { return {&ethmac_ifc_ops_, this}; }
 
     zx_status_t StartProtocol(ddk::EthmacProtocolClient* client) {
-        const ethmac_ifc_t ifc = ethmac_ifc();
-        return client->Start(&ifc);
+        return client->Start(this, &ethmac_ifc_ops_);
     }
 
   private:
@@ -207,7 +206,7 @@
     EXPECT_EQ(ZX_OK, ethmac_query(&proto, 0, nullptr), "");
     proto.ops->stop(proto.ctx);
     ethmac_ifc_t ifc = {nullptr, nullptr};
-    EXPECT_EQ(ZX_OK, ethmac_start(&proto, &ifc), "");
+    EXPECT_EQ(ZX_OK, ethmac_start(&proto, ifc.ctx, ifc.ops), "");
     ethmac_netbuf_t netbuf = {};
     EXPECT_EQ(ZX_OK, ethmac_queue_tx(&proto, 0, &netbuf), "");
     EXPECT_EQ(ZX_OK, ethmac_set_param(&proto, 0, 0, nullptr, 0), "");
@@ -236,7 +235,7 @@
 
     EXPECT_EQ(ZX_OK, client.Query(0, nullptr), "");
     client.Stop();
-    EXPECT_EQ(ZX_OK, client.Start(&ifc), "");
+    EXPECT_EQ(ZX_OK, client.Start(ifc.ctx, ifc.ops), "");
     ethmac_netbuf_t netbuf = {};
     EXPECT_EQ(ZX_OK, client.QueueTx(0, &netbuf), "");
     EXPECT_EQ(ZX_OK, client.SetParam(0, 0, nullptr, 0));