[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;