[usb][banjo] Move USB function protocol to banjo

TEST: Tested all USB functions on hikey960
Change-Id: Ib7751ea5bb3373eb4b7ccd6dd6fa622c4f522a55
diff --git a/system/banjo/ddk-protocol-usb-function/rules.mk b/system/banjo/ddk-protocol-usb-function/rules.mk
new file mode 100644
index 0000000..a068aed
--- /dev/null
+++ b/system/banjo/ddk-protocol-usb-function/rules.mk
@@ -0,0 +1,25 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_TYPE := banjo
+
+MODULE_PACKAGE := banjo
+
+MODULE_BANJO_LIBRARY := ddk.protocol.usb.function
+
+MODULE_BANJO_NAME := usb/function
+
+MODULE_BANJO_DEPS := \
+    system/banjo/ddk-driver \
+    system/banjo/zircon-hw-usb \
+    system/banjo/ddk-protocol-usb-request \
+
+MODULE_SRCS += $(LOCAL_DIR)/usb-function.banjo
+
+include make/module.mk
+
diff --git a/system/banjo/ddk-protocol-usb-function/usb-function.banjo b/system/banjo/ddk-protocol-usb-function/usb-function.banjo
new file mode 100644
index 0000000..5a821c2
--- /dev/null
+++ b/system/banjo/ddk-protocol-usb-function/usb-function.banjo
@@ -0,0 +1,74 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb.function;
+
+using ddk.protocol.usb.request;
+using zircon.hw.usb;
+using zx;
+
+[Layout = "ddk-protocol", DefaultProtocol]
+interface UsbFunction {
+    /// Registers callbacks to the USB function driver.
+    SetInterface(UsbFunctionInterface @interface) -> (zx.status s);
+
+    /// Allocates a unique interface descriptor number.
+    AllocInterface() -> (zx.status s, uint8 intf_num);
+
+    /// Allocates a unique endpoint descriptor number.
+    AllocEp(uint8 direction) -> (zx.status s, uint8 address);
+
+    /// Configures an endpoint based on provided descriptors.
+    ConfigEp(zircon.hw.usb.UsbEndpointDescriptor ep_desc,
+                zircon.hw.usb.UsbSsEpCompDescriptor ss_comp_desc) -> (zx.status s);
+
+    /// Disables the specified endpoint.
+    DisableEp(uint8 address) -> (zx.status s);
+
+    /// Adds a string descriptor to the device configuration.
+    AllocStringDesc(string @string) -> (zx.status s, uint8 index);
+
+    /// Queues a USB request with the lower level driver.
+    RequestQueue(ddk.protocol.usb.request.UsbRequest? usb_request,
+                 ddk.protocol.usb.request.UsbRequestComplete? complete_cb) -> ();
+
+    /// Stalls the specified endpoint.
+    EpSetStall(uint8 ep_address) -> (zx.status s);
+
+    /// Clears a stall condition for the specified endpoint.
+    EpClearStall(uint8 ep_address) -> (zx.status s);
+
+    /// Returns the size needed for a |usb_request_t|, including private storage needed by the
+    /// HCI driver.
+    GetRequestSize() -> (usize size);
+};
+
+/// Interface implemented by the USB function driver.
+[Layout = "ddk-interface"]
+interface UsbFunctionInterface {
+    /// Returns the size of the descriptor list for the function.
+    GetDescriptorsSize() -> (usize size);
+
+    /// Returns the descriptor list for the function.
+    /// TODO(voydanoff) - descriptors will likely vary (different max packet sizes, etc)
+    /// depending on whether we are in low/full, high or super speed mode.
+    /// We will need to add a usb_speed_t argument to this callback.
+    GetDescriptors() -> (vector<voidptr> descriptors);
+
+    /// Callback for handling ep0 control requests.
+    Control(zircon.hw.usb.UsbSetup setup, vector<voidptr> write) -> (zx.status status,
+                                                                     vector<voidptr> read);
+    /// Called to inform the function driver when the USB device configured state changes.
+    /// Called with configured == true in response to a SET_CONFIGURATION control request
+    /// that selects a configuration that contains this function. In this case, the function driver
+    /// should call usb_function_config_ep() to configure its endpoints.
+    /// Called with configured == false when configuration is disabled or USB is disconnected.
+    /// The function driver should then call usb_function_disable_ep() to disable its endpoints.
+    SetConfigured(bool configured, zircon.hw.usb.UsbSpeed speed) -> (zx.status s);
+
+    /// Called to set an alternate setting for an interface due to a SET_INTERFACE control request.
+    /// The function driver should call usb_function_config_ep() and/or usb_function_config_ep()
+    /// to configure or disable the interface's endpoints as appropriate.
+    SetInterface(uint8 interface, uint8 alt_setting) -> (zx.status s);
+};
diff --git a/system/dev/block/ums-function/rules.mk b/system/dev/block/ums-function/rules.mk
index 2be10bc..7b43969 100644
--- a/system/dev/block/ums-function/rules.mk
+++ b/system/dev/block/ums-function/rules.mk
@@ -17,6 +17,7 @@
 
 MODULE_BANJO_LIBS := \
     system/banjo/ddk-protocol-block \
+    system/banjo/ddk-protocol-usb-function \
     system/banjo/ddk-protocol-usb-request \
 
 include make/module.mk
diff --git a/system/dev/block/ums-function/ums-function.c b/system/dev/block/ums-function/ums-function.c
index 7c307e0..7aec6e1 100644
--- a/system/dev/block/ums-function/ums-function.c
+++ b/system/dev/block/ums-function/ums-function.c
@@ -12,7 +12,8 @@
 #include <ddk/debug.h>
 #include <ddk/device.h>
 #include <ddk/driver.h>
-#include <ddk/protocol/usb-function.h>
+#include <ddk/phys-iter.h>
+#include <ddk/protocol/usb/function.h>
 #include <usb/usb-request.h>
 #include <zircon/process.h>
 #include <zircon/syscalls.h>
@@ -104,7 +105,7 @@
         .callback = ums_data_complete,
         .ctx = ums,
     };
-    usb_function_queue(&ums->function, req, &complete);
+    usb_function_request_queue(&ums->function, req, &complete);
 }
 
 static void ums_queue_csw(usb_ums_t* ums, uint8_t status) {
@@ -113,7 +114,7 @@
         .callback = ums_cbw_complete,
         .ctx = ums,
     };
-    usb_function_queue(&ums->function, ums->cbw_req, &cbw_complete);
+    usb_function_request_queue(&ums->function, ums->cbw_req, &cbw_complete);
 
     usb_request_t* req = ums->csw_req;
     ums_csw_t* csw;
@@ -130,7 +131,7 @@
         .callback = ums_csw_complete,
         .ctx = ums,
     };
-    usb_function_queue(&ums->function, ums->csw_req, &csw_complete);
+    usb_function_request_queue(&ums->function, ums->csw_req, &csw_complete);
 }
 
 static void ums_continue_transfer(usb_ums_t* ums) {
@@ -427,18 +428,27 @@
     zxlogf(TRACE, "ums_csw_complete %d %ld\n", req->response.status, req->response.actual);
 }
 
-static const usb_descriptor_header_t* ums_get_descriptors(void* ctx, size_t* out_length) {
-    *out_length = sizeof(descriptors);
-    return (const usb_descriptor_header_t *)&descriptors;
+static size_t ums_get_descriptors_size(void* ctx) {
+    return sizeof(descriptors);
 }
 
-static zx_status_t ums_control(void* ctx, const usb_setup_t* setup, void* buffer,
-                                         size_t length, size_t* out_actual) {
+static void ums_get_descriptors(void* ctx, void* buffer, size_t buffer_size, size_t* out_actual) {
+    size_t length = sizeof(descriptors);
+    if (length > buffer_size) {
+        length = buffer_size;
+    }
+    memcpy(buffer, &descriptors, length);
+    *out_actual = length;
+}
+
+static zx_status_t ums_control(void* ctx, const usb_setup_t* setup, const void* write_buffer,
+                               size_t write_size, void* out_read_buffer, size_t read_size,
+                               size_t* out_read_actual) {
     if (setup->bmRequestType == (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) &&
         setup->bRequest == USB_REQ_GET_MAX_LUN && setup->wValue == 0 && setup->wIndex == 0 &&
         setup->wLength >= sizeof(uint8_t)) {
-        *((uint8_t *)buffer) = 0;
-        *out_actual = sizeof(uint8_t);
+        *((uint8_t *)out_read_buffer) = 0;
+        *out_read_actual = sizeof(uint8_t);
         return ZX_OK;
     }
 
@@ -469,16 +479,17 @@
             .callback = ums_cbw_complete,
             .ctx = ums,
         };
-        usb_function_queue(&ums->function, ums->cbw_req, &cbw_complete);
+        usb_function_request_queue(&ums->function, ums->cbw_req, &cbw_complete);
     }
     return status;
 }
 
-static zx_status_t ums_set_interface(void* ctx, unsigned interface, unsigned alt_setting) {
+static zx_status_t ums_set_interface(void* ctx, uint8_t interface, uint8_t alt_setting) {
     return ZX_ERR_NOT_SUPPORTED;
 }
 
 usb_function_interface_ops_t ums_device_ops = {
+    .get_descriptors_size = ums_get_descriptors_size,
     .get_descriptors = ums_get_descriptors,
     .control = ums_control,
     .set_configured = ums_set_configured,
@@ -601,7 +612,7 @@
         .ops = &ums_device_ops,
         .ctx = ums,
     };
-    usb_function_register(&ums->function, &intf);
+    usb_function_set_interface(&ums->function, &intf);
 
     return ZX_OK;
 
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 682fd5d..6483cfe 100644
--- a/system/dev/ethernet/usb-cdc-function/cdc-eth-function.cpp
+++ b/system/dev/ethernet/usb-cdc-function/cdc-eth-function.cpp
@@ -14,8 +14,10 @@
 #include <ddk/debug.h>
 #include <ddk/device.h>
 #include <ddk/driver.h>
+#include <ddk/phys-iter.h>
 #include <ddk/protocol/ethernet.h>
-#include <ddk/protocol/usb-function.h>
+#include <ddk/protocol/usb/function.h>
+#include <fbl/algorithm.h>
 #include <inet6/inet6.h>
 #include <usb/usb-request.h>
 #include <zircon/listnode.h>
@@ -250,7 +252,7 @@
         .callback = cdc_tx_complete,
         .ctx = cdc,
     };
-    usb_function_queue(&cdc->function, tx_req, &complete);
+    usb_function_request_queue(&cdc->function, tx_req, &complete);
 
     return ZX_OK;
 }
@@ -358,7 +360,7 @@
         .callback = cdc_intr_complete,
         .ctx = cdc,
     };
-    usb_function_queue(&cdc->function, req, &complete);
+    usb_function_request_queue(&cdc->function, req, &complete);
 
     mtx_lock(&cdc->intr_mutex);
     req = usb_req_list_remove_head(&cdc->intr_reqs, cdc->parent_req_size);
@@ -371,7 +373,7 @@
     usb_request_copy_to(req, &speed_notification, sizeof(speed_notification), 0);
     req->header.length = sizeof(speed_notification);
 
-    usb_function_queue(&cdc->function, req, &complete);
+    usb_function_request_queue(&cdc->function, req, &complete);
 }
 
 static void cdc_rx_complete(void* ctx, usb_request_t* req) {
@@ -405,7 +407,7 @@
         .callback = cdc_rx_complete,
         .ctx = cdc,
     };
-    usb_function_queue(&cdc->function, req, &complete);
+    usb_function_request_queue(&cdc->function, req, &complete);
 }
 
 static void cdc_tx_complete(void* ctx, usb_request_t* req) {
@@ -437,14 +439,20 @@
     }
 }
 
-static const usb_descriptor_header_t* cdc_get_descriptors(void* ctx, size_t* out_length) {
-    *out_length = sizeof(descriptors);
-    return (const usb_descriptor_header_t *)&descriptors;
+static size_t cdc_get_descriptors_size(void* ctx) {
+    return sizeof(descriptors);
 }
 
-static zx_status_t cdc_control(void* ctx, const usb_setup_t* setup, void* buffer,
-                               size_t length, size_t* out_actual) {
-    *out_actual = 0;
+static void cdc_get_descriptors(void* ctx, void* buffer, size_t buffer_size, size_t* out_actual) {
+    const size_t length = fbl::min(sizeof(descriptors), buffer_size);
+    memcpy(buffer, &descriptors, length);
+    *out_actual = length;
+}
+
+static zx_status_t cdc_control(void* ctx, const usb_setup_t* setup, const void* write_buffer,
+                               size_t write_size, void* out_read_buffer, size_t read_size,
+                               size_t* out_read_actual) {
+    *out_read_actual = 0;
 
     zxlogf(TRACE, "%s\n", __func__);
 
@@ -489,7 +497,7 @@
     return ZX_OK;
 }
 
-static zx_status_t cdc_set_interface(void* ctx, unsigned interface, unsigned alt_setting) {
+static zx_status_t cdc_set_interface(void* ctx, uint8_t interface, uint8_t alt_setting) {
     zxlogf(TRACE, "%s: %d %d\n", __func__, interface, alt_setting);
     auto* cdc = static_cast<usb_cdc_t*>(ctx);
     zx_status_t status;
@@ -526,7 +534,7 @@
                 .callback = cdc_rx_complete,
                 .ctx = cdc,
             };
-            usb_function_queue(&cdc->function, req, &complete);
+            usb_function_request_queue(&cdc->function, req, &complete);
         }
         mtx_unlock(&cdc->rx_mutex);
     }
@@ -545,6 +553,7 @@
 }
 
 usb_function_interface_ops_t device_ops = {
+    .get_descriptors_size = cdc_get_descriptors_size,
     .get_descriptors = cdc_get_descriptors,
     .control = cdc_control,
     .set_configured = cdc_set_configured,
@@ -719,7 +728,7 @@
         goto fail;
     }
 
-    usb_function_register(&cdc->function, &intf);
+    usb_function_set_interface(&cdc->function, &intf);
 
     return ZX_OK;
 
diff --git a/system/dev/ethernet/usb-cdc-function/rules.mk b/system/dev/ethernet/usb-cdc-function/rules.mk
index 32cef3b..fd63491 100644
--- a/system/dev/ethernet/usb-cdc-function/rules.mk
+++ b/system/dev/ethernet/usb-cdc-function/rules.mk
@@ -13,6 +13,7 @@
 
 MODULE_STATIC_LIBS := \
     system/ulib/ddk \
+    system/ulib/fbl \
     system/ulib/sync \
     system/dev/lib/usb \
 
@@ -23,6 +24,7 @@
 
 MODULE_BANJO_LIBS := \
     system/banjo/ddk-protocol-ethernet \
+    system/banjo/ddk-protocol-usb-function \
     system/banjo/ddk-protocol-usb-request \
 
 MODULE_HEADER_DEPS := \
diff --git a/system/dev/usb/dwc3/dwc3.cpp b/system/dev/usb/dwc3/dwc3.cpp
index a49e2d2..0755951 100644
--- a/system/dev/usb/dwc3/dwc3.cpp
+++ b/system/dev/usb/dwc3/dwc3.cpp
@@ -5,7 +5,6 @@
 #include <ddk/binding.h>
 #include <ddk/debug.h>
 #include <ddk/platform-defs.h>
-#include <ddk/protocol/usb-function.h>
 #include <usb/usb-request.h>
 #include <fbl/auto_lock.h>
 #include <hw/reg.h>
diff --git a/system/dev/usb/usb-peripheral-test/driver.cpp b/system/dev/usb/usb-peripheral-test/driver.cpp
index c7a90a3..1706558 100644
--- a/system/dev/usb/usb-peripheral-test/driver.cpp
+++ b/system/dev/usb/usb-peripheral-test/driver.cpp
@@ -14,7 +14,8 @@
 #include <ddk/debug.h>
 #include <ddk/device.h>
 #include <ddk/driver.h>
-#include <ddk/protocol/usb-function.h>
+#include <ddk/phys-iter.h>
+#include <ddk/protocol/usb/function.h>
 #include <fbl/auto_lock.h>
 #include <fbl/mutex.h>
 #include <usb/usb-request.h>
@@ -142,7 +143,7 @@
                 .callback = test_bulk_in_complete,
                 .ctx = test,
             };
-            usb_function_queue(&test->function, in_req, &complete);
+            usb_function_request_queue(&test->function, in_req, &complete);
         } else {
             zxlogf(ERROR, "%s: no bulk in request available\n", __func__);
         }
@@ -156,7 +157,7 @@
         .callback = test_bulk_out_complete,
         .ctx = test,
     };
-    usb_function_queue(&test->function, req, &complete);
+    usb_function_request_queue(&test->function, req, &complete);
 }
 
 static void test_bulk_in_complete(void* ctx, usb_request_t* req) {
@@ -169,19 +170,24 @@
     ZX_DEBUG_ASSERT(status == ZX_OK);
 }
 
-const usb_descriptor_header_t* test_get_descriptors(void* ctx, size_t* out_length) {
-    *out_length = sizeof(descriptors);
-    return reinterpret_cast<const usb_descriptor_header_t*>(&descriptors);
+static size_t test_get_descriptors_size(void* ctx) {
+    return sizeof(descriptors);
 }
 
-static zx_status_t test_control(void* ctx, const usb_setup_t* setup, void* buffer,
-                                size_t buffer_length, size_t* out_actual) {
+static void test_get_descriptors(void* ctx, void* buffer, size_t buffer_size, size_t* out_actual) {
+    size_t length = sizeof(descriptors);
+    if (length > buffer_size) {
+        length = buffer_size;
+    }
+    memcpy(buffer, &descriptors, length);
+    *out_actual = length;
+}
+
+static zx_status_t test_control(void* ctx, const usb_setup_t* setup, const void* write_buffer,
+                                size_t write_size, void* read_buffer, size_t read_size,
+                                size_t* out_read_actual) {
     auto* test = static_cast<usb_test_t*>(ctx);
     size_t length = le16toh(setup->wLength);
-    if (length > buffer_length) {
-        length = buffer_length;
-    }
-    *out_actual = 0;
 
     zxlogf(TRACE, "%s\n", __func__);
     if (setup->bmRequestType == (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE) &&
@@ -189,17 +195,16 @@
         if (length > sizeof(test->test_data)) {
             length = sizeof(test->test_data);
         }
-        memcpy(test->test_data, buffer, length);
+        memcpy(test->test_data, write_buffer, length);
         test->test_data_length = length;
-        *out_actual = length;
         return ZX_OK;
     } else if (setup->bmRequestType == (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE) &&
         setup->bRequest == USB_PERIPHERAL_TEST_GET_DATA) {
         if (length > test->test_data_length) {
             length = test->test_data_length;
         }
-        memcpy(buffer, test->test_data, length);
-        *out_actual = length;
+        memcpy(read_buffer, test->test_data, length);
+        *out_read_actual = length;
         return ZX_OK;
     } else if (setup->bmRequestType == (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE) &&
         setup->bRequest == USB_PERIPHERAL_TEST_SEND_INTERUPT) {
@@ -219,7 +224,7 @@
             .callback = test_intr_complete,
             .ctx = test,
         };
-        usb_function_queue(&test->function, req, &complete);
+        usb_function_request_queue(&test->function, req, &complete);
         return ZX_OK;
     } else {
         return ZX_ERR_NOT_SUPPORTED;
@@ -256,18 +261,19 @@
                 .callback = test_bulk_out_complete,
                 .ctx = test,
             };
-            usb_function_queue(&test->function, req, &complete);
+            usb_function_request_queue(&test->function, req, &complete);
         }
     }
 
     return ZX_OK;
 }
 
-static zx_status_t test_set_interface(void* ctx, unsigned interface, unsigned alt_setting) {
+static zx_status_t test_set_interface(void* ctx, uint8_t interface, uint8_t alt_setting) {
     return ZX_ERR_NOT_SUPPORTED;
 }
 
 static usb_function_interface_ops_t device_ops = {
+    .get_descriptors_size = test_get_descriptors_size,
     .get_descriptors = test_get_descriptors,
     .control = test_control,
     .set_configured = test_set_configured,
@@ -404,7 +410,7 @@
         goto fail;
     }
 
-    usb_function_register(&test->function, &intf);
+    usb_function_set_interface(&test->function, &intf);
 
     return ZX_OK;
 
diff --git a/system/dev/usb/usb-peripheral-test/rules.mk b/system/dev/usb/usb-peripheral-test/rules.mk
index 3210669..50d94c0 100644
--- a/system/dev/usb/usb-peripheral-test/rules.mk
+++ b/system/dev/usb/usb-peripheral-test/rules.mk
@@ -23,6 +23,7 @@
     system/ulib/c \
 
 MODULE_BANJO_LIBS := \
+    system/banjo/ddk-protocol-usb-function \
     system/banjo/ddk-protocol-usb-request \
 
 MODULE_HEADER_DEPS := \
diff --git a/system/dev/usb/usb-peripheral/rules.mk b/system/dev/usb/usb-peripheral/rules.mk
index f4e0edb..960cd5b 100644
--- a/system/dev/usb/usb-peripheral/rules.mk
+++ b/system/dev/usb/usb-peripheral/rules.mk
@@ -25,6 +25,7 @@
 
 MODULE_BANJO_LIBS := \
     system/banjo/ddk-protocol-usb-dci \
+    system/banjo/ddk-protocol-usb-function \
     system/banjo/ddk-protocol-usb-mode-switch \
     system/banjo/ddk-protocol-usb-request \
 
diff --git a/system/dev/usb/usb-peripheral/usb-peripheral.c b/system/dev/usb/usb-peripheral/usb-peripheral.c
index a7bb67e..67b4b7d 100644
--- a/system/dev/usb/usb-peripheral/usb-peripheral.c
+++ b/system/dev/usb/usb-peripheral/usb-peripheral.c
@@ -16,7 +16,7 @@
 #include <ddk/metadata.h>
 #include <ddk/phys-iter.h>
 #include <ddk/protocol/usb/dci.h>
-#include <ddk/protocol/usb-function.h>
+#include <ddk/protocol/usb/function.h>
 #include <ddk/protocol/usb/modeswitch.h>
 #include <usb/usb-request.h>
 #include <zircon/listnode.h>
@@ -238,23 +238,27 @@
     return status;
 }
 
-static zx_status_t usb_func_register(void* ctx, usb_function_interface_t* interface) {
+static zx_status_t usb_func_set_interface(void* ctx, const usb_function_interface_t* interface) {
     usb_function_t* function = ctx;
     usb_device_t* dev = function->dev;
     usb_function_t** endpoint_map = dev->endpoint_map;
 
-    size_t length;
-    const usb_descriptor_header_t* descriptors = usb_function_get_descriptors(interface, &length);
-
-    // validate the descriptor list
-    if (!descriptors || length < sizeof(usb_interface_descriptor_t)) {
-        return ZX_ERR_INVALID_ARGS;
+    size_t length = usb_function_interface_get_descriptors_size(interface);
+    void* descriptors = malloc(length);
+    if (!descriptors) {
+        return ZX_ERR_NO_MEMORY;
+    }
+    size_t actual;
+    usb_function_interface_get_descriptors(interface, descriptors, length, &actual);
+    if (actual != length) {
+        zxlogf(ERROR, "usb_function_interface_get_descriptors failed\n");
+        return ZX_ERR_INTERNAL;
     }
 
     usb_interface_descriptor_t* intf_desc = (usb_interface_descriptor_t *)descriptors;
     if (intf_desc->bDescriptorType != USB_DT_INTERFACE ||
             intf_desc->bLength != sizeof(usb_interface_descriptor_t)) {
-        zxlogf(ERROR, "usb_func_register: first descriptor not an interface descriptor\n");
+        zxlogf(ERROR, "usb_func_set_interface: first descriptor not an interface descriptor\n");
         return ZX_ERR_INVALID_ARGS;
     }
 
@@ -266,7 +270,7 @@
             usb_interface_descriptor_t* desc = (usb_interface_descriptor_t *)header;
             if (desc->bInterfaceNumber >= countof(dev->interface_map) ||
                 dev->interface_map[desc->bInterfaceNumber] != function) {
-                zxlogf(ERROR, "usb_func_register: bInterfaceNumber %u\n",
+                zxlogf(ERROR, "usb_func_set_interface: bInterfaceNumber %u\n",
                        desc->bInterfaceNumber);
                 return ZX_ERR_INVALID_ARGS;
             }
@@ -278,14 +282,14 @@
             unsigned index = ep_address_to_index(desc->bEndpointAddress);
             if (index == 0 || index >= countof(dev->endpoint_map) ||
                 endpoint_map[index] != function) {
-                zxlogf(ERROR, "usb_func_register: bad endpoint address 0x%X\n",
+                zxlogf(ERROR, "usb_func_set_interface: bad endpoint address 0x%X\n",
                        desc->bEndpointAddress);
                 return ZX_ERR_INVALID_ARGS;
             }
         }
 
         if (header->bLength == 0) {
-            zxlogf(ERROR, "usb_func_register: zero length descriptor\n");
+            zxlogf(ERROR, "usb_func_set_interface: zero length descriptor\n");
             return ZX_ERR_INVALID_ARGS;
         }
         header = (void *)header + header->bLength;
@@ -352,8 +356,8 @@
     return ZX_ERR_NO_RESOURCES;
 }
 
-static zx_status_t usb_func_config_ep(void* ctx, usb_endpoint_descriptor_t* ep_desc,
-                                      usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
+static zx_status_t usb_func_config_ep(void* ctx, const usb_endpoint_descriptor_t* ep_desc,
+                                      const usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
     usb_function_t* function = ctx;
     return usb_dci_config_ep(&function->dev->usb_dci, ep_desc, ss_comp_desc);
 }
@@ -369,7 +373,7 @@
     return usb_device_alloc_string_desc(function->dev, string, out_index);
 }
 
-static void usb_func_queue(void* ctx, usb_request_t* req, const usb_request_complete_t* cb) {
+static void usb_func_request_queue(void* ctx, usb_request_t* req, const usb_request_complete_t* cb) {
     usb_function_t* function = ctx;
     usb_dci_request_queue(&function->dev->usb_dci, req, cb);
 }
@@ -390,13 +394,13 @@
 }
 
 usb_function_protocol_ops_t usb_function_proto = {
-    .register_func = usb_func_register,
+    .set_interface = usb_func_set_interface,
     .alloc_interface = usb_func_alloc_interface,
     .alloc_ep = usb_func_alloc_ep,
     .config_ep = usb_func_config_ep,
     .disable_ep = usb_func_disable_ep,
     .alloc_string_desc = usb_func_alloc_string_desc,
-    .queue = usb_func_queue,
+    .request_queue = usb_func_request_queue,
     .ep_set_stall = usb_func_ep_set_stall,
     .ep_clear_stall = usb_func_ep_clear_stall,
     .get_request_size = usb_func_get_request_size,
@@ -479,7 +483,8 @@
     usb_function_t* function;
     list_for_every_entry(&dev->functions, function, usb_function_t, node) {
         if (function->interface.ops) {
-            status = usb_function_set_configured(&function->interface, configured, dev->speed);
+            status = usb_function_interface_set_configured(&function->interface, configured,
+                                                           dev->speed);
             if (status != ZX_OK && configured) {
                 goto fail;
             }
@@ -497,13 +502,13 @@
                                          unsigned alt_setting) {
     usb_function_t* function = dev->interface_map[interface];
     if (function && function->interface.ops) {
-        return usb_function_set_interface(&function->interface, interface, alt_setting);
+        return usb_function_interface_set_interface(&function->interface, interface, alt_setting);
     }
     return ZX_ERR_NOT_SUPPORTED;
 }
 
 static zx_status_t usb_dev_control(void* ctx, const usb_setup_t* setup, const void* write_buffer,
-                                   size_t write_size, void* out_read_buffer, size_t read_size,
+                                   size_t write_size, void* read_buffer, size_t read_size,
                                    size_t* out_read_actual) {
     usb_device_t* dev = ctx;
     uint8_t request_type = setup->bmRequestType;
@@ -518,7 +523,7 @@
     } else if (direction == USB_DIR_OUT && length > write_size) {
         return ZX_ERR_BUFFER_TOO_SMALL;
     }
-    if ((write_size > 0 && write_buffer == NULL) || (read_size > 0 && out_read_buffer == NULL)) {
+    if ((write_size > 0 && write_buffer == NULL) || (read_size > 0 && read_buffer == NULL)) {
         return ZX_ERR_INVALID_ARGS;
     }
 
@@ -530,14 +535,14 @@
         // handle standard device requests
         if ((request_type & (USB_DIR_MASK | USB_TYPE_MASK)) == (USB_DIR_IN | USB_TYPE_STANDARD) &&
             request == USB_REQ_GET_DESCRIPTOR) {
-            return usb_dev_get_descriptor(dev, request_type, value, index, out_read_buffer, length,
+            return usb_dev_get_descriptor(dev, request_type, value, index, read_buffer, length,
                                           out_read_actual);
         } else if (request_type == (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE) &&
                    request == USB_REQ_SET_CONFIGURATION && length == 0) {
             return usb_dev_set_configuration(dev, value);
         } else if (request_type == (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) &&
                    request == USB_REQ_GET_CONFIGURATION && length > 0) {
-            *((uint8_t *)out_read_buffer) = dev->configuration;
+            *((uint8_t *)read_buffer) = dev->configuration;
             *out_read_actual = sizeof(uint8_t);
             return ZX_OK;
         }
@@ -550,14 +555,9 @@
             // delegate to the function driver for the interface
             usb_function_t* function = dev->interface_map[index];
             if (function && function->interface.ops) {
-                if (direction == USB_DIR_IN) {
-                    return usb_function_control(&function->interface, setup, out_read_buffer,
-                                                read_size, out_read_actual);
-                } else {
-                    size_t actual;
-                    return usb_function_control(&function->interface, setup, (void *)write_buffer,
-                                                write_size, &actual);
-                }
+                return usb_function_interface_control(&function->interface, setup, write_buffer,
+                                                      write_size, read_buffer, read_size,
+                                                      out_read_actual);
             }
         }
         break;
@@ -570,13 +570,9 @@
         }
         usb_function_t* function = dev->endpoint_map[index];
         if (function && function->interface.ops) {
-            if (direction == USB_DIR_IN) {
-                return usb_function_control(&function->interface, setup, out_read_buffer, read_size,
-                                            out_read_actual);
-            } else {
-                return usb_function_control(&function->interface, setup, (void *)write_buffer,
-                                            write_size, NULL);
-            }
+            return usb_function_interface_control(&function->interface, setup, write_buffer,
+                                                   write_size, read_buffer, read_size,
+                                                   out_read_actual);
         }
         break;
     }
@@ -596,7 +592,8 @@
             usb_function_t* function;
             list_for_every_entry(&dev->functions, function, usb_function_t, node) {
                 if (function->interface.ops) {
-                    usb_function_set_configured(&function->interface, false, USB_SPEED_UNDEFINED);
+                    usb_function_interface_set_configured(&function->interface, false,
+                                                          USB_SPEED_UNDEFINED);
                 }
             }
         }
diff --git a/system/ulib/ddk/include/ddk/protocol/usb-function.h b/system/ulib/ddk/include/ddk/protocol/usb-function.h
deleted file mode 100644
index e40a86d..0000000
--- a/system/ulib/ddk/include/ddk/protocol/usb-function.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <ddk/protocol/usb.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-#include <zircon/hw/usb.h>
-
-__BEGIN_CDECLS;
-
-// This protocol is used for USB peripheral function functions
-
-// callbacks implemented by the function driver
-typedef struct {
-
-    // return the descriptor list for the function
-    // TODO(voydanoff) - descriptors will likely vary (different max packet sizes, etc)
-    // depending on whether we are in low/full, high or super speed mode.
-    // We will need to add a usb_speed_t argument to this callback.
-    const usb_descriptor_header_t* (*get_descriptors)(void* ctx, size_t* out_length);
-
-    // callback for handling ep0 control requests
-    zx_status_t (*control)(void* ctx, const usb_setup_t* setup, void* buffer, size_t buffer_length,
-                           size_t* out_actual);
-
-    // Called to inform the function driver when the USB device configured state changes.
-    // Called with configured == true in response to a SET_CONFIGURATION control request
-    // that selects a configuration that contains this function. In this case, the function driver
-    // should call usb_function_config_ep() to configure its endpoints.
-    // Called with configured == false when configuration is disabled or USB is disconnected.
-    // The function driver should then call usb_function_disable_ep() to disable its endpoints.
-    zx_status_t (*set_configured)(void* ctx, bool configured, usb_speed_t speed);
-
-    // Called to set an alternate setting for an interface due to a SET_INTERFACE control request.
-    // The function driver should call usb_function_config_ep() and/or usb_function_config_ep()
-    // to configure or disable the interface's endpoints as appropriate.
-    zx_status_t (*set_interface)(void* ctx, unsigned interface, unsigned alt_setting);
-} usb_function_interface_ops_t;
-
-typedef struct {
-    usb_function_interface_ops_t* ops;
-    void* ctx;
-} usb_function_interface_t;
-
-static inline const usb_descriptor_header_t* usb_function_get_descriptors(
-                                        usb_function_interface_t* intf, size_t* out_length) {
-    return intf->ops->get_descriptors(intf->ctx, out_length);
-}
-
-static inline zx_status_t usb_function_control(usb_function_interface_t* intf,
-                                               const usb_setup_t* setup, void* buffer,
-                                               size_t buffer_length, size_t* out_actual) {
-    return intf->ops->control(intf->ctx, setup, buffer, buffer_length, out_actual);
-}
-
-static inline zx_status_t usb_function_set_configured(usb_function_interface_t* intf,
-                                                      bool configured, usb_speed_t speed) {
-    return intf->ops->set_configured(intf->ctx, configured, speed);
-}
-
-static inline zx_status_t usb_function_set_interface(usb_function_interface_t* intf,
-                                                     unsigned interface, unsigned alt_setting) {
-    return intf->ops->set_interface(intf->ctx, interface, alt_setting);
-}
-
-typedef struct {
-    zx_status_t (*register_func)(void* ctx, usb_function_interface_t* intf);
-    zx_status_t (*alloc_interface)(void* ctx, uint8_t* out_intf_num);
-    zx_status_t (*alloc_ep)(void* ctx, uint8_t direction, uint8_t* out_address);
-    zx_status_t (*config_ep)(void* ctx, usb_endpoint_descriptor_t* ep_desc,
-                             usb_ss_ep_comp_descriptor_t* ss_comp_desc);
-    zx_status_t (*disable_ep)(void* ctx, uint8_t ep_addr);
-    zx_status_t (*alloc_string_desc)(void* ctx, const char* string, uint8_t* out_index);
-    void (*queue)(void* ctx, usb_request_t* req, const usb_request_complete_t* complete_cb);
-    zx_status_t (*ep_set_stall)(void* ctx, uint8_t ep_address);
-    zx_status_t (*ep_clear_stall)(void* ctx, uint8_t ep_address);
-    size_t (*get_request_size)(void* ctx);
-} usb_function_protocol_ops_t;
-
-typedef struct {
-    usb_function_protocol_ops_t* ops;
-    void* ctx;
-} usb_function_protocol_t;
-
-// registers the function driver's callback interface
-static inline void usb_function_register(usb_function_protocol_t* func,
-                                         usb_function_interface_t* intf) {
-    func->ops->register_func(func->ctx, intf);
-}
-
-// allocates a unique interface descriptor number
-static inline zx_status_t usb_function_alloc_interface(usb_function_protocol_t* func,
-                                                       uint8_t* out_intf_num) {
-    return func->ops->alloc_interface(func->ctx, out_intf_num);
-}
-
-// allocates a unique endpoint descriptor number
-// direction should be either USB_DIR_OUT or USB_DIR_IN
-static inline zx_status_t usb_function_alloc_ep(usb_function_protocol_t* func, uint8_t direction,
-                                                uint8_t* out_address) {
-    return func->ops->alloc_ep(func->ctx, direction, out_address);
-}
-
-// configures an endpoint based on the provided usb_endpoint_descriptor_t and
-// usb_ss_ep_comp_descriptor_t descriptors.
-static inline zx_status_t usb_function_config_ep(usb_function_protocol_t* func,
-                                                 usb_endpoint_descriptor_t* ep_desc,
-                                                 usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
-    return func->ops->config_ep(func->ctx, ep_desc, ss_comp_desc);
-}
-
-// disables an endpoint. called when the device is no longer configured or an alternate interface
-// is selected.
-static inline zx_status_t usb_function_disable_ep(usb_function_protocol_t* func, uint8_t ep_addr) {
-    return func->ops->disable_ep(func->ctx, ep_addr);
-}
-
-// adds a string descriptor to the device configuration.
-static inline zx_status_t usb_function_alloc_string_desc(usb_function_protocol_t* func,
-                                                         const char* string, uint8_t* out_index) {
-    return func->ops->alloc_string_desc(func->ctx, string, out_index);
-}
-
-// helper for queueing a usb request on an endpoint.
-static inline void usb_function_queue(usb_function_protocol_t* func, usb_request_t* req,
-                                      const usb_request_complete_t* complete_cb) {
-    return func->ops->queue(func->ctx, req, complete_cb);
-}
-
-// stalls an endpoint
-static zx_status_t usb_function_ep_set_stall(usb_function_protocol_t* func, uint8_t ep_address) {
-    return func->ops->ep_set_stall(func->ctx, ep_address);
-}
-
-// clears endpoint stall state
-static zx_status_t usb_function_ep_clear_stall(usb_function_protocol_t* func, uint8_t ep_address) {
-    return func->ops->ep_clear_stall(func->ctx, ep_address);
-}
-
-// returns the total request size including any internal context size at this
-// layer per usb_request
-static size_t usb_function_get_request_size(usb_function_protocol_t* func) {
-    return func->ops->get_request_size(func->ctx);
-}
-__END_CDECLS;