From 7c928b43db68b72970b3effd5a2582eb5a6869c7 Mon Sep 17 00:00:00 2001 From: Chaoqiong Xiao Date: Fri, 30 Jun 2023 02:15:38 +0000 Subject: [PATCH] Update on 30 Jun 2023. Expand to see details. 92c60270 Added device HID flexible event queue and zero copy support. a15f80ab Added device CDC ACM zero copy support 9fcd26f7 Improve device request handling with print GET_DEVICE_ID support. bea6252c Add new device side endpoint buffer management mode. --- common/core/inc/ux_api.h | 11 + common/core/inc/ux_device_class_dpump.h | 25 +- common/core/inc/ux_user_sample.h | 38 ++- .../core/src/ux_device_class_dpump_activate.c | 25 +- .../core/src/ux_device_class_dpump_change.c | 17 +- .../src/ux_device_class_dpump_initialize.c | 20 +- common/core/src/ux_device_class_dpump_read.c | 10 +- .../core/src/ux_device_class_dpump_read_run.c | 10 +- common/core/src/ux_device_class_dpump_write.c | 10 +- .../src/ux_device_class_dpump_write_run.c | 10 +- .../ux_device_stack_control_request_process.c | 29 ++- common/core/src/ux_device_stack_initialize.c | 14 +- .../core/src/ux_device_stack_uninitialize.c | 12 +- .../inc/ux_device_class_audio.h | 24 +- .../inc/ux_device_class_ccid.h | 24 +- .../inc/ux_device_class_cdc_acm.h | 59 ++++- .../inc/ux_device_class_cdc_ecm.h | 36 ++- .../inc/ux_device_class_hid.h | 120 +++++++++- .../inc/ux_device_class_pima.h | 21 ++ .../inc/ux_device_class_printer.h | 26 +- .../inc/ux_device_class_rndis.h | 33 ++- .../inc/ux_device_class_storage.h | 16 +- .../inc/ux_device_class_video.h | 7 +- .../src/ux_device_class_audio_activate.c | 10 +- .../src/ux_device_class_audio_change.c | 15 +- .../src/ux_device_class_audio_initialize.c | 55 ++++- .../src/ux_device_class_audio_unitialize.c | 16 +- .../src/ux_device_class_ccid_activate.c | 25 +- .../src/ux_device_class_ccid_initialize.c | 25 +- .../src/ux_device_class_ccid_uninitialize.c | 11 +- .../ux_device_class_cdc_acm_bulkin_thread.c | 46 +++- .../ux_device_class_cdc_acm_bulkout_thread.c | 14 +- .../src/ux_device_class_cdc_acm_initialize.c | 33 ++- .../src/ux_device_class_cdc_acm_read.c | 39 ++- .../src/ux_device_class_cdc_acm_read_run.c | 60 ++++- .../src/ux_device_class_cdc_acm_tasks_run.c | 114 ++++++++- .../src/ux_device_class_cdc_acm_unitialize.c | 13 +- .../src/ux_device_class_cdc_acm_write.c | 50 +++- .../src/ux_device_class_cdc_acm_write_run.c | 74 +++++- .../src/ux_device_class_cdc_ecm_activate.c | 35 ++- .../ux_device_class_cdc_ecm_bulkin_thread.c | 10 +- .../ux_device_class_cdc_ecm_bulkout_thread.c | 12 +- .../src/ux_device_class_cdc_ecm_change.c | 21 +- .../src/ux_device_class_cdc_ecm_initialize.c | 21 +- .../ux_device_class_cdc_ecm_uninitialize.c | 9 +- .../src/ux_device_class_hid_activate.c | 38 ++- .../src/ux_device_class_hid_event_get.c | 222 +++++++++++++----- .../src/ux_device_class_hid_event_set.c | 40 ++-- .../src/ux_device_class_hid_initialize.c | 107 ++++++++- .../ux_device_class_hid_interrupt_thread.c | 37 ++- .../src/ux_device_class_hid_read.c | 21 +- .../src/ux_device_class_hid_read_run.c | 45 +++- .../ux_device_class_hid_receiver_event_free.c | 11 +- .../ux_device_class_hid_receiver_event_get.c | 10 +- .../ux_device_class_hid_receiver_initialize.c | 51 +++- .../ux_device_class_hid_receiver_tasks_run.c | 22 +- .../src/ux_device_class_hid_receiver_thread.c | 27 ++- ...x_device_class_hid_receiver_uninitialize.c | 11 +- .../src/ux_device_class_hid_tasks_run.c | 26 +- .../src/ux_device_class_hid_uninitialize.c | 14 +- .../src/ux_device_class_pima_activate.c | 15 +- .../src/ux_device_class_pima_initialize.c | 23 +- .../ux_device_class_pima_object_info_get.c | 8 +- ...x_device_class_pima_object_prop_desc_get.c | 8 +- ..._device_class_pima_object_prop_value_get.c | 8 +- ..._device_class_pima_object_references_get.c | 8 +- .../src/ux_device_class_printer_activate.c | 14 +- .../src/ux_device_class_printer_initialize.c | 25 +- .../ux_device_class_printer_uninitialize.c | 9 +- .../src/ux_device_class_printer_write.c | 14 +- .../src/ux_device_class_printer_write_run.c | 14 +- .../src/ux_device_class_rndis_activate.c | 31 ++- .../src/ux_device_class_rndis_bulkin_thread.c | 10 +- .../ux_device_class_rndis_bulkout_thread.c | 12 +- .../src/ux_device_class_rndis_initialize.c | 35 ++- .../src/ux_device_class_storage_activate.c | 15 +- .../src/ux_device_class_storage_initialize.c | 56 +++-- .../src/ux_device_class_storage_thread.c | 17 +- .../ux_device_class_storage_uninitialize.c | 10 +- .../src/ux_device_class_video_change.c | 11 +- .../src/ux_device_class_video_initialize.c | 21 +- .../src/ux_device_class_video_uninitialize.c | 9 +- 82 files changed, 2052 insertions(+), 308 deletions(-) diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h index 51c98db7..006fa589 100644 --- a/common/core/inc/ux_api.h +++ b/common/core/inc/ux_api.h @@ -134,6 +134,8 @@ /* added a new error code, */ /* resulting in version 6.2.1 */ /* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* optimized USB descriptors, */ /* added error checks support, */ /* resulting in version 6.x */ @@ -208,6 +210,15 @@ extern "C" { #define UX_HOST_STACK_ENABLE_ERROR_CHECKING #endif +/* Defined, this value represents the endpoint buffer owner. + 0 - The default, endpoint buffer is managed by core stack. Each endpoint takes UX_SLAVE_REQUEST_DATA_MAX_LENGTH bytes. + 1 - Endpoint buffer managed by classes. In this case not all endpoints consume UX_SLAVE_REQUEST_DATA_MAX_LENGTH bytes. +*/ +#ifndef UX_DEVICE_ENDPOINT_BUFFER_OWNER +#define UX_DEVICE_ENDPOINT_BUFFER_OWNER 0 +#endif +#define UX_DEVICE_ENDPOINT_BUFFER_OWNER_CORE 0 +#define UX_DEVICE_ENDPOINT_BUFFER_OWNER_CLASS 1 /* Define the maximum length for class names (exclude string null-terminator). */ #define UX_MAX_CLASS_NAME_LENGTH 63 diff --git a/common/core/inc/ux_device_class_dpump.h b/common/core/inc/ux_device_class_dpump.h index 94633e6e..76f55812 100644 --- a/common/core/inc/ux_device_class_dpump.h +++ b/common/core/inc/ux_device_class_dpump.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_dpump.h PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -50,6 +50,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -67,6 +71,13 @@ extern "C" { #endif +/* Bulk out endpoint / read buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */ +#define UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE UX_SLAVE_REQUEST_DATA_MAX_LENGTH + +/* Bulk in endpoint / write buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */ +#define UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER_SIZE UX_SLAVE_REQUEST_DATA_MAX_LENGTH + + /* Define Storage Class USB Class constants. */ #define UX_SLAVE_CLASS_DPUMP_CLASS 0x99 @@ -94,6 +105,9 @@ typedef struct UX_SLAVE_CLASS_DPUMP_STRUCT UX_SLAVE_CLASS_DPUMP_PARAMETER ux_slave_class_dpump_parameter; UX_SLAVE_ENDPOINT *ux_slave_class_dpump_bulkin_endpoint; UX_SLAVE_ENDPOINT *ux_slave_class_dpump_bulkout_endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_dpump_endpoint_buffer; +#endif ULONG ux_slave_class_dpump_alternate_setting; #if defined(UX_DEVICE_STANDALONE) UCHAR *ux_device_class_dpump_write_buffer; @@ -111,6 +125,15 @@ typedef struct UX_SLAVE_CLASS_DPUMP_STRUCT #endif } UX_SLAVE_CLASS_DPUMP; +/* Defined for endpoint buffer settings (when DPUMP owns buffer). */ +#define UX_DEVICE_CLASS_DPUMP_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE, \ + UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER_SIZE)) +#define UX_DEVICE_CLASS_DPUMP_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE + UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER_SIZE) +#define UX_DEVICE_CLASS_DPUMP_READ_BUFFER(dpump) ((dpump)->ux_device_class_dpump_endpoint_buffer) +#define UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER(dpump) (UX_DEVICE_CLASS_DPUMP_READ_BUFFER(dpump) + UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE) + + /* Define Device Data Pump Class prototypes. */ UINT _ux_device_class_dpump_initialize(UX_SLAVE_CLASS_COMMAND *command); diff --git a/common/core/inc/ux_user_sample.h b/common/core/inc/ux_user_sample.h index 216f3ecb..28a09346 100644 --- a/common/core/inc/ux_user_sample.h +++ b/common/core/inc/ux_user_sample.h @@ -99,7 +99,11 @@ /* added option to enable */ /* basic USBX error checking, */ /* resulting in version 6.2.1 */ -/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* xx-xx-xxxx Xiuwen Cai, CQ Xiao Modified comment(s), */ +/* added zero copy support */ +/* in many device classes, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* added option for get string */ /* requests with zero wIndex, */ /* resulting in version 6.x */ @@ -220,6 +224,33 @@ /* #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 */ +/* Defined, this value represents the endpoint buffer owner. + 0 - The default, endpoint buffer is managed by core stack. Each endpoint takes UX_SLAVE_REQUEST_DATA_MAX_LENGTH bytes. + 1 - Endpoint buffer managed by classes. In this case not all endpoints consume UX_SLAVE_REQUEST_DATA_MAX_LENGTH bytes. +*/ + +#define UX_DEVICE_ENDPOINT_BUFFER_OWNER 0 + +/* Defined, it enables device CDC ACM zero copy for bulk in/out endpoints (write/read). + Enabled, the endpoint buffer is not allocated in class, application must + provide the buffer for read/write, and the buffer must meet device controller driver (DCD) + buffer requirements (e.g., aligned and cache safe). + It only works if UX_DEVICE_ENDPOINT_BUFFER_OWNER is 1 (endpoint buffer managed by class). + */ +/* #define UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY */ + +/* Defined, it enables zero copy and flexible queue support (works if HID owns endpoint buffer). + Enabled, the internal queue buffer is directly used for transfer, the APIs are kept to keep + backword compatibility, to AVOID KEEPING BUFFERS IN APPLICATION. + Flexible queue introduces initialization parameter _event_max_number and _event_max_length, + so each HID function could have different queue settings. + _event_max_number could be 2 ~ UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE. + Max of _event_max_length could be UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH. + If the initialization parameters are invalid (are 0s or exceed upper mentioned definition), + UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE and UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH are used to + calculate and allocate the queue. + */ +/* #define UX_DEVICE_CLASS_HID_ZERO_COPY */ /* Defined, this value represents the maximum number of bytes that can be received or transmitted on any endpoint. This value cannot be less than the maximum packet size of any endpoint. The default @@ -414,6 +445,11 @@ /* #define UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT */ +/* Works if UX_DEVICE_ENDPOINT_BUFFER_OWNER is 1. + Defined, it represents feedback endpoint buffer size. + It should be larger than feedback endpoint max packet size in framework. */ +/* #define UX_DEVICE_CLASS_AUDIO_FEEDBACK_ENDPOINT_BUFFER_SIZE 8 */ + /* Defined, class _write is pending ZLP automatically (complete transfer) after buffer is sent. */ /* #define UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP */ diff --git a/common/core/src/ux_device_class_dpump_activate.c b/common/core/src/ux_device_class_dpump_activate.c index 80626d61..ab6963b0 100644 --- a/common/core/src/ux_device_class_dpump_activate.c +++ b/common/core/src/ux_device_class_dpump_activate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -111,18 +115,31 @@ UX_SLAVE_ENDPOINT *endpoint; /* Look at type. */ if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT) - + { + /* We have found the bulk in endpoint, save it. */ dpump -> ux_slave_class_dpump_bulkin_endpoint = endpoint; - +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER(dpump); +#endif + } } else { /* Look at type for out endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT) - + { + /* We have found the bulk out endpoint, save it. */ dpump -> ux_slave_class_dpump_bulkout_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_DPUMP_READ_BUFFER(dpump); +#endif + } } /* Next endpoint. */ diff --git a/common/core/src/ux_device_class_dpump_change.c b/common/core/src/ux_device_class_dpump_change.c index acad9cff..24f52aed 100644 --- a/common/core/src/ux_device_class_dpump_change.c +++ b/common/core/src/ux_device_class_dpump_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_change PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -76,6 +76,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND *command) @@ -120,7 +124,11 @@ UX_SLAVE_ENDPOINT *endpoint; /* We have found the bulk in endpoint, save it. */ dpump -> ux_slave_class_dpump_bulkin_endpoint = endpoint; - +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER(dpump); +#endif } else { @@ -129,6 +137,11 @@ UX_SLAVE_ENDPOINT *endpoint; /* We have found the bulk out endpoint, save it. */ dpump -> ux_slave_class_dpump_bulkout_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_DPUMP_READ_BUFFER(dpump); +#endif } /* Next endpoint. */ diff --git a/common/core/src/ux_device_class_dpump_initialize.c b/common/core/src/ux_device_class_dpump_initialize.c index adccf6df..853b4f8b 100644 --- a/common/core/src/ux_device_class_dpump_initialize.c +++ b/common/core/src/ux_device_class_dpump_initialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_initialize PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -91,7 +95,19 @@ UX_SLAVE_CLASS_DPUMP_PARAMETER *dpump_parameter; /* Save the address of the DPUMP instance inside the DPUMP container. */ class_ptr -> ux_slave_class_instance = (VOID *) dpump; - + +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UX_ASSERT(!UX_DEVICE_CLASS_DPUMP_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + dpump -> ux_device_class_dpump_endpoint_buffer = _ux_utility_memory_allocate( + UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_DPUMP_ENDPOINT_BUFFER_SIZE); + if (dpump -> ux_device_class_dpump_endpoint_buffer == UX_NULL) + { + _ux_utility_memory_free(dpump); + return(UX_MEMORY_INSUFFICIENT); + } +#endif + /* Get the pointer to the application parameters for the cdc class. */ dpump_parameter = command -> ux_slave_class_command_parameter; diff --git a/common/core/src/ux_device_class_dpump_read.c b/common/core/src/ux_device_class_dpump_read.c index 7108cf5c..c93df013 100644 --- a/common/core/src/ux_device_class_dpump_read.c +++ b/common/core/src/ux_device_class_dpump_read.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_read PORTABLE C */ -/* 6.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_read(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer, @@ -128,10 +132,10 @@ ULONG local_requested_length; { /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE) /* We have too much to transfer. */ - local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + local_requested_length = UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE; else diff --git a/common/core/src/ux_device_class_dpump_read_run.c b/common/core/src/ux_device_class_dpump_read_run.c index 73fad411..0bd3da40 100644 --- a/common/core/src/ux_device_class_dpump_read_run.c +++ b/common/core/src/ux_device_class_dpump_read_run.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_read_run PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,10 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_read_run(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer, @@ -158,10 +162,10 @@ UINT read_state; } /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE) /* We have too much to transfer. */ - dpump -> ux_device_class_dpump_read_transfer_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + dpump -> ux_device_class_dpump_read_transfer_length = UX_DEVICE_CLASS_DPUMP_READ_BUFFER_SIZE; else diff --git a/common/core/src/ux_device_class_dpump_write.c b/common/core/src/ux_device_class_dpump_write.c index 4d72b420..2e950aae 100644 --- a/common/core/src/ux_device_class_dpump_write.c +++ b/common/core/src/ux_device_class_dpump_write.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_write PORTABLE C */ -/* 6.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_write(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer, @@ -129,10 +133,10 @@ UINT status; { /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER_SIZE) /* We have too much to transfer. */ - local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + local_requested_length = UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER_SIZE; else diff --git a/common/core/src/ux_device_class_dpump_write_run.c b/common/core/src/ux_device_class_dpump_write_run.c index 437ce072..b08e49bd 100644 --- a/common/core/src/ux_device_class_dpump_write_run.c +++ b/common/core/src/ux_device_class_dpump_write_run.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_write_run PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,10 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_write_run(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer, @@ -161,10 +165,10 @@ UINT read_state; } /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER_SIZE) /* We have too much to transfer. */ - dpump -> ux_device_class_dpump_write_transfer_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + dpump -> ux_device_class_dpump_write_transfer_length = UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER_SIZE; else diff --git a/common/core/src/ux_device_stack_control_request_process.c b/common/core/src/ux_device_stack_control_request_process.c index 91e1ca0e..826097a6 100644 --- a/common/core/src/ux_device_stack_control_request_process.c +++ b/common/core/src/ux_device_stack_control_request_process.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_control_request_process PORTABLE C */ -/* 6.2.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -94,6 +94,10 @@ /* 03-08-2023 Chaoqiong Xiao Modified comment(s), */ /* fixed vendor request issue, */ /* resulting in version 6.2.1 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* improved interface request */ +/* process with print class, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_stack_control_request_process(UX_SLAVE_TRANSFER *transfer_request) @@ -219,12 +223,23 @@ ULONG application_data_length; the request index, we should go to the next one. */ /* For printer class (0x07) GET_DEVICE_ID (0x00) the high byte of wIndex is interface index (for recommended index sequence the interface - number is same as interface index inside configuration). */ - if (((request_index & 0xFF) != class_index) || - ((class_ptr -> ux_slave_class_interface -> ux_slave_interface_descriptor.bInterfaceClass == 0x07) && - (request == 0x00) && - *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_INDEX + 1) != class_index)) - continue; + number is same as interface index inside configuration). + */ + if ((request_type == 0xA1) && (request == 0x00) && + (class_ptr -> ux_slave_class_interface -> ux_slave_interface_descriptor.bInterfaceClass == 0x07)) + { + + /* Check wIndex high byte. */ + if(*(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_INDEX + 1) != class_index) + continue; + } + else + { + + /* Check wIndex low. */ + if ((request_index & 0xFF) != class_index) + continue; + } } /* Memorize the class in the command. */ diff --git a/common/core/src/ux_device_stack_initialize.c b/common/core/src/ux_device_stack_initialize.c index e5e07e70..5b7a9b1f 100644 --- a/common/core/src/ux_device_stack_initialize.c +++ b/common/core/src/ux_device_stack_initialize.c @@ -54,7 +54,7 @@ UX_SYSTEM_SLAVE *_ux_system_slave; /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -109,6 +109,10 @@ UX_SYSTEM_SLAVE *_ux_system_slave; /* added CCID support, */ /* added video support, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_stack_initialize(UCHAR * device_framework_high_speed, ULONG device_framework_length_high_speed, @@ -383,6 +387,8 @@ UCHAR *memory; while (endpoints_pool < (device -> ux_slave_device_endpoints_pool + endpoints_found)) { +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 0 + /* Obtain some memory. */ endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); @@ -393,7 +399,8 @@ UCHAR *memory; status = UX_MEMORY_INSUFFICIENT; break; } - +#endif + /* Create the semaphore for the endpoint. */ status = _ux_device_semaphore_create(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore, "ux_transfer_request_semaphore", 0); @@ -432,9 +439,12 @@ UCHAR *memory; if (_ux_device_semaphore_created(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore)) _ux_device_semaphore_delete(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore); +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 0 + /* Free ux_slave_transfer_request_data_pointer buffer. */ if (endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer) _ux_utility_memory_free(endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer); +#endif /* Move to previous endpoint. */ endpoints_pool --; diff --git a/common/core/src/ux_device_stack_uninitialize.c b/common/core/src/ux_device_stack_uninitialize.c index 18d5a5f2..4622e382 100644 --- a/common/core/src/ux_device_stack_uninitialize.c +++ b/common/core/src/ux_device_stack_uninitialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_uninitialize PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,6 +72,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_stack_uninitialize(VOID) @@ -106,9 +110,13 @@ ULONG endpoints_found; /* Parse all endpoints and fee memory and semaphore. */ while (endpoints_found-- != 0) { + +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 0 + /* Free the memory for endpoint data pointer. */ _ux_utility_memory_free(endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer); - +#endif + /* Remove the TX semaphore for the endpoint. */ _ux_device_semaphore_delete(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore); diff --git a/common/usbx_device_classes/inc/ux_device_class_audio.h b/common/usbx_device_classes/inc/ux_device_class_audio.h index 63ce8c34..d6166cca 100644 --- a/common/usbx_device_classes/inc/ux_device_class_audio.h +++ b/common/usbx_device_classes/inc/ux_device_class_audio.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_audio.h PORTABLE C */ -/* 6.2.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -65,6 +65,10 @@ /* 03-08-2023 Chaoqiong Xiao Modified comment(s), */ /* added error checks support, */ /* resulting in version 6.2.1 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -95,6 +99,11 @@ extern "C" { #endif +/* Works if UX_DEVICE_ENDPOINT_BUFFER_OWNER is 1. + If defined, it represents feedback endpoint buffer size. + It should be larger than feedback endpoint max packet size in framework. */ +#define UX_DEVICE_CLASS_AUDIO_FEEDBACK_BUFFER_SIZE 8 + /* Define Audio Class OS related constants. */ #define UX_DEVICE_CLASS_AUDIO_FEEDBACK_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE @@ -413,9 +422,18 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT UX_SLAVE_INTERFACE *ux_device_class_audio_stream_interface; UX_SLAVE_ENDPOINT *ux_device_class_audio_stream_endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_audio_stream_endpoint_buffer; +#endif + #if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) UX_SLAVE_ENDPOINT *ux_device_class_audio_stream_feedback; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_audio_stream_feedback_buffer; +#endif + + #if !defined(UX_DEVICE_STANDALONE) UCHAR *ux_device_class_audio_stream_feedback_thread_stack; UX_THREAD ux_device_class_audio_stream_feedback_thread; @@ -461,6 +479,10 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STRUCT #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) UX_SLAVE_ENDPOINT *ux_device_class_audio_interrupt; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_audio_interrupt_buffer; +#endif + ULONG ux_device_class_audio_status_size; /* in Bytes. */ ULONG ux_device_class_audio_status_queue_bytes;/* in Bytes. */ ULONG ux_device_class_audio_status_queued; /* in Bytes. */ diff --git a/common/usbx_device_classes/inc/ux_device_class_ccid.h b/common/usbx_device_classes/inc/ux_device_class_ccid.h index 801ff5a2..832422ed 100644 --- a/common/usbx_device_classes/inc/ux_device_class_ccid.h +++ b/common/usbx_device_classes/inc/ux_device_class_ccid.h @@ -42,7 +42,7 @@ /* 03-08-2023 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.1 */ -/* xx-xx-xxxx Yajun xia Modified comment(s), */ +/* xx-xx-xxxx Yajun xia, CQ Xiao Modified comment(s), */ /* added error checks support, */ /* resulting in version 6.x */ /* */ @@ -66,6 +66,14 @@ extern "C" { #define UX_DEVICE_CLASS_CCID_ENABLE_ERROR_CHECKING #endif + +/* Notification/interrupt endpoint buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */ +#define UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE 16 + +/* Bulk endpoints buffer size, must be larger than dwMaxCCIDMessageLength and wMaxPacketSize in framework, and aligned in 4-bytes. */ +#define UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE UX_SLAVE_REQUEST_DATA_MAX_LENGTH + + #if !defined(UX_DEVICE_STANDALONE) /* Define CCID max number of slots, 32 for 32 bit data width. */ @@ -1010,6 +1018,10 @@ typedef struct UX_DEVICE_CLASS_CCID_STRUCT UX_SLAVE_ENDPOINT *ux_device_class_ccid_endpoint_in; UX_SLAVE_ENDPOINT *ux_device_class_ccid_endpoint_notify; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_ccid_endpoint_buffer; +#endif + UX_DEVICE_CLASS_CCID_PARAMETER ux_device_class_ccid_parameter; @@ -1042,6 +1054,16 @@ typedef struct UX_DEVICE_CLASS_CCID_STRUCT #endif } UX_DEVICE_CLASS_CCID; +/* Device CCID endpoint buffer settings (when CCID owns buffer). */ +#define UX_DEVICE_CLASS_CCID_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_MULC_ULONG(UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE, 2) || \ + UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE * 2, \ + UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE)) +#define UX_DEVICE_CLASS_CCID_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE * 2 + UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE) +#define UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid) ((ccid) -> ux_device_class_ccid_endpoint_buffer) +#define UX_DEVICE_CLASS_CCID_BULKIN_BUFFER(ccid) (UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid) + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE) +#define UX_DEVICE_CLASS_CCID_INTERRUPTIN_BUFFER(ccid) (UX_DEVICE_CLASS_CCID_BULKIN_BUFFER(ccid) + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE) + /* Device CCID flags. */ #define UX_DEVICE_CLASS_CCID_FLAG_LOCK 0x0001u #define UX_DEVICE_CLASS_CCID_FLAG_CMD_RSP 0x0010u diff --git a/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h b/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h index bce70bbf..748d345e 100644 --- a/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h +++ b/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h @@ -58,7 +58,10 @@ /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ /* added write auto ZLP, */ /* resulting in version 6.1.12 */ -/* xx-xx-xxxx Yajun xia Modified comment(s), */ +/* xx-xx-xxxx Yajun xia, CQ Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* added error checks support, */ /* resulting in version 6.x */ /* */ @@ -87,6 +90,32 @@ extern "C" { /* #define UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP */ +/* Option: bulk out endpoint / read buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */ +#ifndef UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE +#define UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE 512 +#endif + +/* Option: bulk in endpoint / write buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */ +#ifndef UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE +#define UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE UX_SLAVE_REQUEST_DATA_MAX_LENGTH +#endif + +/* Option: zero copy enable. + Works if UX_DEVICE_ENDPOINT_BUFFER_OWNER is 1 (endpoint buffer managed by class). + Defined, it enables zero copy for bulk in/out endpoints (write/read). In this case, the endpoint + buffer is not allocated in class, application must provide the buffer for read/write, and the + buffer must meet device controller driver (DCD) buffer requirements (e.g., aligned and cache safe). + */ +/* #define UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY */ + +/* Internal: check if class own endpoint buffer */ +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && \ + (!defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) || \ + !defined(UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE)) +#define UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER +#endif + + /* Define CDC Class USB Class constants. */ #define UX_SLAVE_CLASS_CDC_ACM_CLASS 10 @@ -189,22 +218,30 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_STRUCT UX_SLAVE_INTERFACE *ux_slave_class_cdc_acm_interface; UX_SLAVE_CLASS_CDC_ACM_PARAMETER ux_slave_class_cdc_acm_parameter; +#if defined(UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER) + UCHAR *ux_device_class_cdc_acm_endpoint_buffer; +#endif + #if !defined(UX_DEVICE_STANDALONE) UX_MUTEX ux_slave_class_cdc_acm_endpoint_in_mutex; UX_MUTEX ux_slave_class_cdc_acm_endpoint_out_mutex; #else +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER != 1) || !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) UCHAR *ux_device_class_cdc_acm_read_buffer; ULONG ux_device_class_cdc_acm_read_requested_length; ULONG ux_device_class_cdc_acm_read_transfer_length; ULONG ux_device_class_cdc_acm_read_actual_length; - UINT ux_device_class_cdc_acm_read_status; +#endif UINT ux_device_class_cdc_acm_read_state; + UINT ux_device_class_cdc_acm_read_status; - UCHAR *ux_device_class_cdc_acm_write_buffer; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER != 1) || !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) ULONG ux_device_class_cdc_acm_write_transfer_length; ULONG ux_device_class_cdc_acm_write_host_length; - ULONG ux_device_class_cdc_acm_write_requested_length; ULONG ux_device_class_cdc_acm_write_actual_length; +#endif + UCHAR *ux_device_class_cdc_acm_write_buffer; + ULONG ux_device_class_cdc_acm_write_requested_length; UINT ux_device_class_cdc_acm_write_status; UINT ux_device_class_cdc_acm_write_state; #endif @@ -237,6 +274,20 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_STRUCT #endif } UX_SLAVE_CLASS_CDC_ACM; +#if defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) && !defined(UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE) +#define UX_DEVICE_CLASS_CDC_ACM_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW (UX_FALSE) +#define UX_DEVICE_CLASS_CDC_ACM_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE) +#define UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER(acm) ((acm) -> ux_device_class_cdc_acm_endpoint_buffer) +#define UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER(acm) (UX_NULL) +#else +#define UX_DEVICE_CLASS_CDC_ACM_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE, UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE)) +#define UX_DEVICE_CLASS_CDC_ACM_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE + UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE) +#define UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER(acm) ((acm) -> ux_device_class_cdc_acm_endpoint_buffer) +#define UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER(acm) (UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER(acm) + UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE) +#endif + + /* Define some CDC Class structures */ typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER_STRUCT diff --git a/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h b/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h index 54f3ac77..d578136e 100644 --- a/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h +++ b/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h @@ -24,7 +24,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_cdc_ecm.h PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -55,6 +55,10 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added wait definitions, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -94,6 +98,17 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle); #endif #endif + +/* Bulk out endpoint buffer size, must be larger than endpoint and ethernet max packet size, and aligned in 4-bytes. */ +#define UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH + +/* Bulk in endpoint buffer size, must be larger than endpoint and ethernet max packet size, and aligned in 4-bytes. */ +#define UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE UX_DEVICE_CLASS_CDC_ECM_ETHERNET_PACKET_SIZE + +/* Interrupt in endpoint buffer size... */ +#define UX_DEVICE_CLASS_CDC_ECM_INTERRUPTIN_BUFFER_SIZE UX_DEVICE_CLASS_CDC_ECM_INTERRUPT_RESPONSE_LENGTH + + /* Define generic CDC_ECM equivalences. */ #define UX_DEVICE_CLASS_CDC_ECM_CLASS_COMMUNICATION_CONTROL 0x02 #define UX_DEVICE_CLASS_CDC_ECM_SUBCLASS_COMMUNICATION_CONTROL 0x06 @@ -161,7 +176,7 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle); #define UX_DEVICE_CLASS_CDC_ECM_VERSION_MAJOR 0x00000001 #define UX_DEVICE_CLASS_CDC_ECM_VERSION_MINOR 0x00000000 -/* Define CDC_ECM Connection type supported. Set to conectionless. */ +/* Define CDC_ECM Connection type supported. Set to connectionless. */ #define UX_DEVICE_CLASS_CDC_ECM_DF_CONNECTIONLESS 0x00000001 #define UX_DEVICE_CLASS_CDC_ECM_DF_CONNECTION_ORIENTED 0x00000002 #define UX_DEVICE_CLASS_CDC_ECM_DF_CONNECTION_SUPPORTED UX_DEVICE_CLASS_CDC_ECM_DF_CONNECTIONLESS @@ -179,7 +194,7 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle); /* Define LINK speeds. */ #define UX_DEVICE_CLASS_CDC_ECM_LINK_SPEED_FS 0x0001D4C0 -/* Define LINK statess. */ +/* Define LINK states. */ #define UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_DOWN 0 #define UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP 1 #define UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_PENDING_UP 2 @@ -306,6 +321,9 @@ typedef struct UX_SLAVE_CLASS_CDC_ECM_STRUCT UX_SLAVE_ENDPOINT *ux_slave_class_cdc_ecm_bulkin_endpoint; UX_SLAVE_ENDPOINT *ux_slave_class_cdc_ecm_bulkout_endpoint; UX_SLAVE_ENDPOINT *ux_slave_class_cdc_ecm_interrupt_endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_cdc_ecm_endpoint_buffer; +#endif ULONG ux_slave_class_cdc_ecm_state; ULONG ux_slave_class_cdc_ecm_current_alternate_setting; ULONG ux_slave_class_cdc_ecm_max_transfer_size; @@ -351,6 +369,18 @@ typedef struct UX_SLAVE_CLASS_CDC_ECM_STRUCT } UX_SLAVE_CLASS_CDC_ECM; +/* Define CDC ECM endpoint buffer settings (when CDC ECM owns buffer). */ +#define UX_DEVICE_CLASS_CDC_ECM_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE, \ + UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE) || \ + UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE + \ + UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE, \ + UX_DEVICE_CLASS_CDC_ECM_INTERRUPTIN_BUFFER_SIZE)) +#define UX_DEVICE_CLASS_CDC_ECM_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE + UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE + UX_DEVICE_CLASS_CDC_ECM_INTERRUPTIN_BUFFER_SIZE) +#define UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER(ecm) ((ecm)->ux_device_class_cdc_ecm_endpoint_buffer) +#define UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER(ecm) (UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER(ecm) + UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE) +#define UX_DEVICE_CLASS_CDC_ECM_INTERRUPTIN_BUFFER(ecm) (UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER(ecm) + UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE) + /* Requests - Ethernet Networking Control Model */ diff --git a/common/usbx_device_classes/inc/ux_device_class_hid.h b/common/usbx_device_classes/inc/ux_device_class_hid.h index 7a119dfe..ffadc242 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_hid.h PORTABLE C */ -/* 6.X */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -64,7 +64,10 @@ /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone int out, */ /* resulting in version 6.1.12 */ -/* XX-XX-XXXX Chaoqiong Xiao Modified comment(s), */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* moved build option check, */ /* resulting in version 6.x */ /* */ @@ -102,6 +105,38 @@ extern "C" { /* Use UX general thread stack size for HID class thread. */ #define UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE +/* Interrupt out endpoint buffer size, must be larger than endpoint, and aligned in 4-bytes. */ +#define UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER_SIZE UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH + +/* Interrupt in endpoint buffer size, must be larger than endpoint, and aligned in 4-bytes. */ +#ifdef UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT +#define UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER_SIZE 8 +#else +#define UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER_SIZE 0 +#endif + +/* Option: defined, it enables zero copy support (works if HID owns endpoint buffer). */ +/* #define UX_DEVICE_CLASS_HID_ZERO_COPY */ + +/* Option: defined, it enables initialize parameters to set event queue size and event max length. + If disabled, the default value is UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE for queue size + and UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH for event max length. + If enabled, the parameter _event_max_number (2~UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE) sets + the queue size and _event_max_length (max UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH) sets + event max length. If parameters are not valid, maximum values are used. + It's enabled automatically if HID owns endpoint buffer and zero copy is enabled. + */ +#ifndef UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) +#define UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE +#endif +#endif + +/* Internal: check if class own endpoint buffer */ +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) +#define UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER +#endif + /* Define HID Class constants. */ @@ -179,11 +214,27 @@ typedef struct UX_SLAVE_CLASS_HID_EVENT_STRUCT { ULONG ux_device_class_hid_event_report_id; ULONG ux_device_class_hid_event_report_type; - UCHAR ux_device_class_hid_event_buffer[UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH]; ULONG ux_device_class_hid_event_length; + UCHAR ux_device_class_hid_event_buffer[UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH]; } UX_SLAVE_CLASS_HID_EVENT; +/* Internal (transmit) event header. */ +typedef struct UX_DEVICE_CLASS_HID_EVENT_STRUCT +{ + ULONG ux_device_class_hid_event_report_id; + ULONG ux_device_class_hid_event_report_type; + ULONG ux_device_class_hid_event_length; + UCHAR *ux_device_class_hid_event_buffer; +} UX_DEVICE_CLASS_HID_EVENT; + +#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) +#define UX_DEVICE_CLASS_HID_EVENT_BUFFER(e) ((e)->ux_device_class_hid_event_buffer) +#else +#define UX_DEVICE_CLASS_HID_EVENT_BUFFER(e) (((UX_SLAVE_CLASS_HID_EVENT*)e)->ux_device_class_hid_event_buffer) +#endif + + /* Define HID structure. */ typedef struct UX_SLAVE_CLASS_HID_STRUCT @@ -191,6 +242,11 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT UX_SLAVE_INTERFACE *ux_slave_class_hid_interface; UX_SLAVE_ENDPOINT *ux_device_class_hid_interrupt_endpoint; + +#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) + UCHAR *ux_device_class_hid_endpoint_buffer; +#endif + UINT ux_device_class_hid_state; UINT (*ux_device_class_hid_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); UINT (*ux_device_class_hid_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); @@ -204,15 +260,18 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT #else UINT ux_device_class_hid_event_state; ULONG ux_device_class_hid_event_wait_start; - UX_SLAVE_CLASS_HID_EVENT ux_device_class_hid_event; + UX_DEVICE_CLASS_HID_EVENT ux_device_class_hid_event; #endif ULONG ux_device_class_hid_event_idle_rate; ULONG ux_device_class_hid_event_wait_timeout; ULONG ux_device_class_hid_protocol; - UX_SLAVE_CLASS_HID_EVENT *ux_device_class_hid_event_array; - UX_SLAVE_CLASS_HID_EVENT *ux_device_class_hid_event_array_head; - UX_SLAVE_CLASS_HID_EVENT *ux_device_class_hid_event_array_tail; - UX_SLAVE_CLASS_HID_EVENT *ux_device_class_hid_event_array_end; + UX_DEVICE_CLASS_HID_EVENT *ux_device_class_hid_event_array; + UX_DEVICE_CLASS_HID_EVENT *ux_device_class_hid_event_array_head; + UX_DEVICE_CLASS_HID_EVENT *ux_device_class_hid_event_array_tail; + UX_DEVICE_CLASS_HID_EVENT *ux_device_class_hid_event_array_end; +#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) + ULONG ux_device_class_hid_event_max_length; +#endif #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) UX_SLAVE_ENDPOINT *ux_device_class_hid_read_endpoint; @@ -221,10 +280,12 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT #if !defined(UX_DEVICE_STANDALONE) UX_MUTEX ux_device_class_hid_read_mutex; #else + UCHAR *ux_device_class_hid_read_buffer; ULONG ux_device_class_hid_read_requested_length; ULONG ux_device_class_hid_read_actual_length; ULONG ux_device_class_hid_read_transfer_length; + UINT ux_device_class_hid_read_state; UINT ux_device_class_hid_read_status; #endif @@ -232,6 +293,26 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT } UX_SLAVE_CLASS_HID; +/* Define HID endpoint buffer settings (when HID owns buffer). */ +#define UX_DEVICE_CLASS_HID_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER_SIZE, \ + UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER_SIZE)) +#define UX_DEVICE_CLASS_HID_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER_SIZE + UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER_SIZE) +#define UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER(hid) ((hid)->ux_device_class_hid_endpoint_buffer) +#define UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER(hid) (UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER(hid) + UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER_SIZE) + +#ifdef UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE +#define UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid) ((hid)->ux_device_class_hid_event_max_length) +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) +#define UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid) sizeof(UX_DEVICE_CLASS_HID_EVENT) +#else +#define UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid) (sizeof(UX_DEVICE_CLASS_HID_EVENT) - 4 + UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid)) +#endif +#else +#define UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid) UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH +#define UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid) sizeof(UX_SLAVE_CLASS_HID_EVENT) +#endif + /* HID interrupt OUT support extensions. */ @@ -264,6 +345,14 @@ typedef struct UX_DEVICE_CLASS_HID_RECEIVER_STRUCT #endif } UX_DEVICE_CLASS_HID_RECEIVER; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) +#define UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_BUFFER(i) ((i) -> ux_device_class_hid_received_event_data) +#define UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_SIZE(r) sizeof(UX_DEVICE_CLASS_HID_RECEIVED_EVENT) +#else +#define UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_BUFFER(i) ((UCHAR*)&(i) -> ux_device_class_hid_received_event_data) +#define UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_SIZE(r) ((r) -> ux_device_class_hid_receiver_event_buffer_size + sizeof(ULONG)) +#endif + /* Define HID initialization command structure. */ @@ -277,6 +366,10 @@ typedef struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT ULONG ux_device_class_hid_parameter_report_length; UINT (*ux_device_class_hid_parameter_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); UINT (*ux_device_class_hid_parameter_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); +#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) + ULONG ux_device_class_hid_parameter_event_max_number; + ULONG ux_device_class_hid_parameter_event_max_length; +#endif #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) UINT (*ux_device_class_hid_parameter_receiver_initialize)(UX_SLAVE_CLASS_HID *hid, struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT *parameter, UX_DEVICE_CLASS_HID_RECEIVER **receiver); ULONG ux_device_class_hid_parameter_receiver_event_max_number; @@ -286,6 +379,14 @@ typedef struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT } UX_SLAVE_CLASS_HID_PARAMETER; +#ifdef UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE +#define UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(p) ((p)->ux_device_class_hid_parameter_event_max_number) +#define UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(p) ((p)->ux_device_class_hid_parameter_event_max_length) +#else +#define UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(p) UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE +#define UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(p) UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH +#endif + /* Define HID Class function prototypes. */ UINT _ux_device_class_hid_descriptor_send(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_type, @@ -299,6 +400,9 @@ UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command); UINT _ux_device_class_hid_uninitialize(UX_SLAVE_CLASS_COMMAND *command); UINT _ux_device_class_hid_event_set(UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event); +UINT _ux_device_class_hid_event_check(UX_SLAVE_CLASS_HID *hid, + UX_DEVICE_CLASS_HID_EVENT **hid_event); +VOID _ux_device_class_hid_event_free(UX_SLAVE_CLASS_HID *hid); UINT _ux_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event); UINT _ux_device_class_hid_report_set(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_type, diff --git a/common/usbx_device_classes/inc/ux_device_class_pima.h b/common/usbx_device_classes/inc/ux_device_class_pima.h index ae7c7c42..31278b10 100644 --- a/common/usbx_device_classes/inc/ux_device_class_pima.h +++ b/common/usbx_device_classes/inc/ux_device_class_pima.h @@ -59,6 +59,8 @@ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ /* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* added error checks support, */ /* resulting in version 6.x */ /* */ @@ -84,10 +86,15 @@ extern "C" { #define UX_DEVICE_CLASS_PIMA_ENABLE_ERROR_CHECKING #endif +#define UX_DEVICE_CLASS_PIMA_BULK_BUFFER_LENGTH UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH +#define UX_DEVICE_CLASS_PIMA_INTERRUPT_BUFFER_LENGTH 32 /* >=UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH */ + /* Define PIMA Class constants. */ +#ifndef UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH #define UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH UX_SLAVE_REQUEST_DATA_MAX_LENGTH +#endif #define UX_DEVICE_CLASS_PIMA_MAX_PAYLOAD (UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH - UX_DEVICE_CLASS_PIMA_DATA_HEADER_SIZE) #define UX_DEVICE_CLASS_PIMA_OBJECT_INFO_BUFFER_SIZE (UX_DEVICE_CLASS_PIMA_MAX_PAYLOAD) #define UX_DEVICE_CLASS_PIMA_DEVICE_INFO_BUFFER_SIZE (UX_DEVICE_CLASS_PIMA_MAX_PAYLOAD) @@ -813,6 +820,9 @@ typedef struct UX_SLAVE_CLASS_PIMA_STRUCT UX_SLAVE_ENDPOINT *ux_device_class_pima_bulk_in_endpoint; UX_SLAVE_ENDPOINT *ux_device_class_pima_bulk_out_endpoint; UX_SLAVE_ENDPOINT *ux_device_class_pima_interrupt_endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_pima_endpoint_buffer; +#endif UINT ux_device_class_pima_state; USHORT ux_device_class_pima_device_status; ULONG ux_device_class_pima_session_id; @@ -884,6 +894,17 @@ typedef struct UX_SLAVE_CLASS_PIMA_STRUCT } UX_SLAVE_CLASS_PIMA; +/* Define PIMA endpoint buffer settings (when PIMA owns buffer). */ +#define UX_DEVICE_CLASS_PIMA_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_MULC_ULONG(UX_DEVICE_CLASS_PIMA_BULK_BUFFER_LENGTH, 2) ||\ + UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_PIMA_BULK_BUFFER_LENGTH * 2, \ + UX_DEVICE_CLASS_PIMA_INTERRUPT_BUFFER_LENGTH)) +#define UX_DEVICE_CLASS_PIMA_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_PIMA_BULK_BUFFER_LENGTH * 2 + UX_DEVICE_CLASS_PIMA_INTERRUPT_BUFFER_LENGTH) +#define UX_DEVICE_CLASS_PIMA_BULKOUT_BUFFER(pima) ((pima)->ux_device_class_pima_endpoint_buffer) +#define UX_DEVICE_CLASS_PIMA_BULKIN_BUFFER(pima) (UX_DEVICE_CLASS_PIMA_BULKOUT_BUFFER(pima) + UX_DEVICE_CLASS_PIMA_BULK_BUFFER_LENGTH) +#define UX_DEVICE_CLASS_PIMA_INTERRUPTIN_BUFFER(pima) (UX_DEVICE_CLASS_PIMA_BULKIN_BUFFER(pima) + UX_DEVICE_CLASS_PIMA_BULK_BUFFER_LENGTH) + + /* Define PIMA initialization command structure. */ typedef struct UX_SLAVE_CLASS_PIMA_PARAMETER_STRUCT diff --git a/common/usbx_device_classes/inc/ux_device_class_printer.h b/common/usbx_device_classes/inc/ux_device_class_printer.h index 1aa787ba..9dcb4584 100644 --- a/common/usbx_device_classes/inc/ux_device_class_printer.h +++ b/common/usbx_device_classes/inc/ux_device_class_printer.h @@ -50,7 +50,9 @@ /* 03-08-2023 Yajun xia Modified comment(s), */ /* added error checks support, */ /* resulting in version 6.2.1 */ -/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* xx-xx-xxxx Yajun Xia, CQ Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* fixed error checking issue, */ /* resulting in version 6.x */ /* */ @@ -80,6 +82,17 @@ extern "C" { /* #define UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP */ +/* Option: bulk out endpoint / read buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */ +#ifndef UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE +#define UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE 512 +#endif + +/* Option: bulk in endpoint / write buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */ +#ifndef UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE +#define UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE UX_SLAVE_REQUEST_DATA_MAX_LENGTH +#endif + + /* Define Printer Class USB Class constants. */ #define UX_DEVICE_CLASS_PRINTER_CLASS 7 @@ -136,6 +149,9 @@ typedef struct UX_DEVICE_CLASS_PRINTER_STRUCT UX_SLAVE_INTERFACE *ux_device_class_printer_interface; UX_SLAVE_ENDPOINT *ux_device_class_printer_endpoint_out; UX_SLAVE_ENDPOINT *ux_device_class_printer_endpoint_in; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_printer_endpoint_buffer; +#endif ULONG ux_device_class_printer_port_status; UX_DEVICE_CLASS_PRINTER_PARAMETER ux_device_class_printer_parameter; @@ -160,6 +176,14 @@ typedef struct UX_DEVICE_CLASS_PRINTER_STRUCT #endif } UX_DEVICE_CLASS_PRINTER; +/* Define PRINTER endpoint buffer settings (when PRINTER owns buffer). */ +#define UX_DEVICE_CLASS_PRINTER_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE, \ + UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE)) +#define UX_DEVICE_CLASS_PRINTER_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE + UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE) +#define UX_DEVICE_CLASS_PRINTER_READ_BUFFER(ecm) ((ecm)->ux_device_class_printer_endpoint_buffer) +#define UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER(ecm) (UX_DEVICE_CLASS_PRINTER_READ_BUFFER(ecm) + UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE) + /* Define Device Printer Class prototypes. */ diff --git a/common/usbx_device_classes/inc/ux_device_class_rndis.h b/common/usbx_device_classes/inc/ux_device_class_rndis.h index 72b15e16..d1263b72 100644 --- a/common/usbx_device_classes/inc/ux_device_class_rndis.h +++ b/common/usbx_device_classes/inc/ux_device_class_rndis.h @@ -56,6 +56,8 @@ /* added wait and length DEFs, */ /* resulting in version 6.2.0 */ /* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* improved error checking, */ /* resulting in version 6.x */ /* */ @@ -74,6 +76,16 @@ extern "C" { #endif +/* Bulk out endpoint buffer size (UX_DEVICE_CLASS_RNDIS_MAX_PACKET_TRANSFER_SIZE). */ +#define UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE UX_DEVICE_CLASS_RNDIS_MAX_PACKET_TRANSFER_SIZE + +/* Bulk in endpoint buffer size (UX_DEVICE_CLASS_RNDIS_MAX_PACKET_TRANSFER_SIZE). */ +#define UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE UX_DEVICE_CLASS_RNDIS_MAX_PACKET_TRANSFER_SIZE + +/* Interrupt in endpoint buffer size (UX_DEVICE_CLASS_RNDIS_INTERRUPT_RESPONSE_LENGTH). */ +#define UX_DEVICE_CLASS_RNDIS_INTERRUPTIN_BUFFER_SIZE UX_DEVICE_CLASS_RNDIS_INTERRUPT_RESPONSE_LENGTH + + #if !defined(UX_DEVICE_STANDALONE) #include "nx_api.h" #include "ux_network_driver.h" @@ -488,12 +500,6 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle); #define UX_DEVICE_CLASS_RNDIS_PACKET_POOL_INST_WAIT 100 #endif -/* Calculate message buffer length (not overflow). */ -#define UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH (UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH) -#if UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH > UX_SLAVE_REQUEST_DATA_MAX_LENGTH -/* Checked in _initialize(). */ -#endif - /* Calculate response buffer length. */ #define UX_DEVICE_CLASS_RNDIS_OID_SUPPORTED_RESPONSE_LENGTH (UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER + UX_DEVICE_CLASS_RNDIS_OID_SUPPORTED_LIST_LENGTH * 4) #define UX_DEVICE_CLASS_RNDIS_VENDOR_DESCRIPTION_MAX_RESPONSE_LENGTH (UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER + UX_DEVICE_CLASS_RNDIS_VENDOR_DESCRIPTION_MAX_LENGTH) @@ -543,6 +549,9 @@ typedef struct UX_SLAVE_CLASS_RNDIS_STRUCT UX_SLAVE_ENDPOINT *ux_slave_class_rndis_interrupt_endpoint; UX_SLAVE_ENDPOINT *ux_slave_class_rndis_bulkin_endpoint; UX_SLAVE_ENDPOINT *ux_slave_class_rndis_bulkout_endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_rndis_endpoint_buffer; +#endif UCHAR ux_slave_class_rndis_response[UX_DEVICE_CLASS_RNDIS_MAX_CONTROL_RESPONSE_LENGTH]; ULONG ux_slave_class_rndis_response_length; ULONG ux_slave_class_rndis_state; @@ -587,6 +596,18 @@ typedef struct UX_SLAVE_CLASS_RNDIS_STRUCT } UX_SLAVE_CLASS_RNDIS; +/* Define RNDIS endpoint buffer settings (when RNDIS owns buffer). */ +#define UX_DEVICE_CLASS_RNDIS_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE, \ + UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE) || \ + UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE + \ + UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE, \ + UX_DEVICE_CLASS_RNDIS_INTERRUPTIN_BUFFER_SIZE)) +#define UX_DEVICE_CLASS_RNDIS_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE + UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE + UX_DEVICE_CLASS_RNDIS_INTERRUPTIN_BUFFER_SIZE) +#define UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER(rndis) ((rndis)->ux_device_class_rndis_endpoint_buffer) +#define UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER(rndis) (UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER(rndis) + UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE) +#define UX_DEVICE_CLASS_RNDIS_INTERRUPTIN_BUFFER(rndis) (UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER(rndis) + UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE) + /* Requests - Ethernet Networking Control Model */ diff --git a/common/usbx_device_classes/inc/ux_device_class_storage.h b/common/usbx_device_classes/inc/ux_device_class_storage.h index 9c0a1a3b..3ff31b5e 100644 --- a/common/usbx_device_classes/inc/ux_device_class_storage.h +++ b/common/usbx_device_classes/inc/ux_device_class_storage.h @@ -58,8 +58,10 @@ /* added standalone support, */ /* resulting in version 6.1.10 */ /* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* added error checks support, */ -/* resulting in version 6.1.10 */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -83,6 +85,8 @@ extern "C" { #define UX_DEVICE_CLASS_STORAGE_ENABLE_ERROR_CHECKING #endif +/* Bulk endpoint buffer size (UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE). */ +#define UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE /* Define User configurable Storage Class constants. */ @@ -522,6 +526,9 @@ typedef struct UX_SLAVE_CLASS_STORAGE_LUN_STRUCT typedef struct UX_SLAVE_CLASS_STORAGE_STRUCT { UX_SLAVE_INTERFACE *ux_slave_class_storage_interface; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_storage_endpoint_buffer; +#endif ULONG ux_slave_class_storage_number_lun; UX_SLAVE_CLASS_STORAGE_LUN ux_slave_class_storage_lun[UX_MAX_SLAVE_LUN]; ULONG ux_slave_class_storage_host_length; @@ -568,6 +575,13 @@ typedef struct UX_SLAVE_CLASS_STORAGE_STRUCT } UX_SLAVE_CLASS_STORAGE; +/* Defined for endpoint buffer settings (when STORAGE owns buffer). */ +#define UX_DEVICE_CLASS_STORAGE_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ + (UX_OVERFLOW_CHECK_MULC_ULONG(UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE, 2)) +#define UX_DEVICE_CLASS_STORAGE_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE * 2) +#define UX_DEVICE_CLASS_STORAGE_BULKOUT_BUFFER(storage) ((storage)->ux_device_class_storage_endpoint_buffer) +#define UX_DEVICE_CLASS_STORAGE_BULKIN_BUFFER(storage) (UX_DEVICE_CLASS_STORAGE_BULKOUT_BUFFER(storage) + UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE) + #define UX_DEVICE_CLASS_STORAGE_CSW_STATUS(p) (((UCHAR*)(p))[0]) #define UX_DEVICE_CLASS_STORAGE_CSW_SKIP(p) (((UCHAR*)(p))[3]) diff --git a/common/usbx_device_classes/inc/ux_device_class_video.h b/common/usbx_device_classes/inc/ux_device_class_video.h index ea3515f5..a7a4f72c 100644 --- a/common/usbx_device_classes/inc/ux_device_class_video.h +++ b/common/usbx_device_classes/inc/ux_device_class_video.h @@ -44,7 +44,9 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ -/* xx-xx-xxxx Yajun xia Modified comment(s), */ +/* xx-xx-xxxx Yajun xia, CQ Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* added error checks support, */ /* resulting in version 6.x */ /* */ @@ -586,6 +588,9 @@ typedef struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT struct UX_DEVICE_CLASS_VIDEO_STRUCT *ux_device_class_video_stream_video; UX_SLAVE_INTERFACE *ux_device_class_video_stream_interface; UX_SLAVE_ENDPOINT *ux_device_class_video_stream_endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + UCHAR *ux_device_class_video_stream_endpoint_buffer; +#endif ULONG ux_device_class_video_stream_error; diff --git a/common/usbx_device_classes/src/ux_device_class_audio_activate.c b/common/usbx_device_classes/src/ux_device_class_audio_activate.c index 2f9b89d7..f6468fdb 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_activate PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,10 @@ /* 10-31-2022 Yajun Xia Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -122,6 +126,10 @@ ULONG stream_index; audio -> ux_device_class_audio_status_queued = 0; audio -> ux_device_class_audio_status_head = audio -> ux_device_class_audio_status_queue; audio -> ux_device_class_audio_status_tail = audio -> ux_device_class_audio_status_queue; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + audio -> ux_device_class_audio_interrupt -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = audio -> ux_device_class_audio_interrupt_buffer; +#endif #endif } else diff --git a/common/usbx_device_classes/src/ux_device_class_audio_change.c b/common/usbx_device_classes/src/ux_device_class_audio_change.c index 9ac4e679..5ad1c8a3 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_change.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_change PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -84,6 +84,10 @@ /* 10-31-2022 Yajun Xia Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_change(UX_SLAVE_CLASS_COMMAND *command) @@ -233,6 +237,15 @@ ULONG endpoint_dir; return(UX_DESCRIPTOR_CORRUPTED); } +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + stream -> ux_device_class_audio_stream_endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = stream -> ux_device_class_audio_stream_endpoint_buffer; +#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) + stream -> ux_device_class_audio_stream_feedback -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = stream -> ux_device_class_audio_stream_feedback_buffer; +#endif +#endif + #if defined(UX_DEVICE_STANDALONE) /* Reset background transfer state. */ diff --git a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c index 92ab207e..1a261821 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_initialize PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -87,6 +87,10 @@ /* 10-31-2022 Yajun Xia Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -226,6 +230,19 @@ ULONG i; } #endif +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Allocate memory for interrupt endpoint buffer. */ + audio -> ux_device_class_audio_interrupt_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + audio_parameter -> ux_device_class_audio_parameter_status_size); + if (audio -> ux_device_class_audio_interrupt_buffer == UX_NULL) + { + _ux_utility_memory_free(audio -> ux_device_class_audio_status_queue); + _ux_utility_memory_free(audio); + return(UX_MEMORY_INSUFFICIENT); + } +#endif + #endif /* Save streams. */ @@ -241,6 +258,30 @@ ULONG i; for (i = 0; i < audio -> ux_device_class_audio_streams_nb; i ++) { +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Allocate memory for stream endpoint buffer. */ + stream -> ux_device_class_audio_stream_endpoint_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + stream_parameter -> ux_device_class_audio_stream_parameter_max_frame_buffer_size); + if (stream -> ux_device_class_audio_stream_endpoint_buffer == UX_NULL) + { + status = UX_MEMORY_INSUFFICIENT; + break; + } + +#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) + + /* Allocate memory for feedback endpoint buffer. */ + stream -> ux_device_class_audio_stream_feedback_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_AUDIO_FEEDBACK_BUFFER_SIZE); + if (stream -> ux_device_class_audio_stream_feedback_buffer == UX_NULL) + { + status = UX_MEMORY_INSUFFICIENT; + break; + } +#endif +#endif + /* Create memory block based on max frame buffer size and max number of frames buffered. Each frame require some additional header memory (8 bytes). */ stream -> ux_device_class_audio_stream_frame_buffer_size = stream_parameter -> ux_device_class_audio_stream_parameter_max_frame_buffer_size; @@ -406,6 +447,10 @@ ULONG i; for (i = 0; i < audio -> ux_device_class_audio_streams_nb; i ++) { #if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + if (stream -> ux_device_class_audio_stream_feedback_buffer) + _ux_utility_memory_free(stream -> ux_device_class_audio_stream_feedback_buffer); +#endif #if !defined(UX_DEVICE_STANDALONE) if (stream -> ux_device_class_audio_stream_feedback_thread_stack) { @@ -420,12 +465,20 @@ ULONG i; _ux_device_thread_delete(&stream -> ux_device_class_audio_stream_thread); _ux_utility_memory_free(stream -> ux_device_class_audio_stream_thread_stack); } +#endif +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + if (stream -> ux_device_class_audio_stream_endpoint_buffer) + _ux_utility_memory_free(stream -> ux_device_class_audio_stream_endpoint_buffer); #endif if (stream -> ux_device_class_audio_stream_buffer) _ux_utility_memory_free(stream -> ux_device_class_audio_stream_buffer); stream ++; } #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + if (audio -> ux_device_class_audio_interrupt_buffer) + _ux_utility_memory_free(audio -> ux_device_class_audio_interrupt_buffer); +#endif #if !defined(UX_DEVICE_STANDALONE) if (audio_class -> ux_slave_class_thread_stack) { diff --git a/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c b/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c index 495e9a8e..0c59d53c 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_uninitialize PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -113,11 +117,21 @@ ULONG i; #endif _ux_utility_memory_free(stream -> ux_device_class_audio_stream_buffer); +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(stream -> ux_device_class_audio_stream_endpoint_buffer); +#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) + _ux_utility_memory_free(stream -> ux_device_class_audio_stream_feedback_buffer); +#endif +#endif + /* Next stream instance. */ stream ++; } #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(audio -> ux_device_class_audio_interrupt_buffer); +#endif #if !defined(UX_DEVICE_STANDALONE) _ux_device_thread_delete(&audio_class -> ux_slave_class_thread); _ux_utility_memory_free(audio_class -> ux_slave_class_thread_stack); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_activate.c b/common/usbx_device_classes/src/ux_device_class_ccid_activate.c index 990f584c..a1bc8653 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_activate PORTABLE C */ -/* 6.2.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* 03-08-2023 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.1 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -109,13 +113,32 @@ UINT i; if (endpoint_type == UX_INTERRUPT_ENDPOINT) { ccid -> ux_device_class_ccid_endpoint_notify = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CCID_INTERRUPTIN_BUFFER(ccid); +#endif } if (endpoint_type == UX_BULK_ENDPOINT) { if (endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_IN) + { ccid -> ux_device_class_ccid_endpoint_in = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CCID_BULKIN_BUFFER(ccid); +#endif + } else + { ccid -> ux_device_class_ccid_endpoint_out = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid); +#endif + } } endpoint = endpoint -> ux_slave_endpoint_next_endpoint; } diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c b/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c index 5e20857c..dd732bd5 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_initialize PORTABLE C */ -/* 6.2.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* 03-08-2023 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.1 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -120,7 +124,7 @@ ULONG stacks_size; #endif UX_ASSERT(ccid_parameter -> ux_device_class_ccid_max_transfer_length <= - UX_SLAVE_REQUEST_DATA_MAX_LENGTH); + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE); UX_ASSERT(ccid_parameter->ux_device_class_ccid_handles != UX_NULL); /* Calculate size for instance (structures already aligned). */ @@ -343,6 +347,16 @@ ULONG stacks_size; } } +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Create endpoint buffers. */ + UX_ASSERT(!UX_DEVICE_CLASS_CCID_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + ccid -> ux_device_class_ccid_endpoint_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, + UX_CACHE_SAFE_MEMORY, UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE * 2); + if (ccid -> ux_device_class_ccid_endpoint_buffer == UX_NULL) + status = UX_MEMORY_INSUFFICIENT; +#endif + #if !defined(UX_DEVICE_STANDALONE) /* CCID mutexes, semaphore and event flags. */ @@ -430,6 +444,13 @@ ULONG stacks_size; _ux_utility_thread_delete(&ccid -> ux_device_class_ccid_notify_thread); #endif +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Free the endpoint buffers. */ + if (ccid -> ux_device_class_ccid_endpoint_buffer) + _ux_utility_memory_free(ccid -> ux_device_class_ccid_endpoint_buffer); +#endif + /* Free the memory. */ _ux_utility_memory_free(ccid); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_ccid_uninitialize.c index 776d8d47..2b970a2f 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_uninitialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_uninitialize PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,6 +66,10 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -105,6 +109,11 @@ ULONG i; _ux_device_mutex_delete(&ccid -> ux_device_class_ccid_response_mutex); #endif +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + /* Free the bulk in endpoint memory. */ + _ux_utility_memory_free(ccid -> ux_device_class_ccid_endpoint_buffer); +#endif + /* Free instance memory. */ _ux_utility_memory_free(ccid); } diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c index 36d1acaf..22c9b08d 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_bulkin_thread PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -92,6 +92,11 @@ /* names conflict C++ keyword, */ /* added auto ZLP support, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_acm_bulkin_thread(ULONG cdc_acm_class) @@ -130,6 +135,11 @@ ULONG sent_length; endpoint = endpoint -> ux_slave_endpoint_next_endpoint; } +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER(cdc_acm); +#endif + /* This thread runs forever but can be suspended or resumed. */ while(1) { @@ -152,6 +162,31 @@ ULONG sent_length; /* Get the length of the entire buffer to send. */ total_length = cdc_acm -> ux_slave_class_cdc_acm_callback_total_length; +#if defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + +#if !defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + + /* Assume host request length just equal. */ + host_length = total_length; +#else + + /* Assume host request length larger to append ZLP automatically. */ + host_length = total_length + 1; +#endif + + /* Pass all data to lower level transfer. */ + transfer_length = total_length; + + /* Setup the data pointer. */ + transfer_request -> ux_slave_transfer_request_data_pointer = cdc_acm -> ux_slave_class_cdc_acm_callback_data_pointer; + + /* Issue the transfer request. */ + status = _ux_device_stack_transfer_request(transfer_request, transfer_length, host_length); + + /* Update length sent. */ + sent_length = transfer_request -> ux_slave_transfer_request_actual_length; +#else + /* Duplicate the data pointer to keep a current pointer. */ cdc_acm -> ux_slave_class_cdc_acm_callback_current_data_pointer = cdc_acm -> ux_slave_class_cdc_acm_callback_data_pointer; @@ -168,15 +203,15 @@ ULONG sent_length; { /* We should send the total length. But we may have a case of ZLP. */ - host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; while (total_length) { /* Check the length remaining to send. */ - if (total_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (total_length > UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE) /* We can't fit all the length. */ - transfer_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + transfer_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; else { @@ -191,7 +226,7 @@ ULONG sent_length; #else /* Assume expected more to let stack append ZLP if needed. */ - host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; + host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE + 1; #endif } @@ -224,6 +259,7 @@ ULONG sent_length; } } } +#endif /* Schedule of transmission was completed. */ cdc_acm -> ux_slave_class_cdc_acm_scheduled_write = UX_FALSE; diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c index 736cff86..707d7fc7 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_bulkout_thread PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -83,6 +83,11 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_acm_bulkout_thread(ULONG cdc_acm_class) @@ -126,6 +131,13 @@ UINT status; while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED) { +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Use class managed buffer. */ + transfer_request -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER(cdc_acm); +#endif + /* Send the request to the device controller. */ status = _ux_device_stack_transfer_request(transfer_request, endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize, endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize); diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c index 3b207d9a..1ac48fd0 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_initialize PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -87,6 +87,11 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -120,6 +125,23 @@ UINT status; cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_instance_deactivate = cdc_acm_parameter -> ux_slave_class_cdc_acm_instance_deactivate; cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change = cdc_acm_parameter -> ux_slave_class_cdc_acm_parameter_change; +#if defined(UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER) + + /* Allocate the buffer for the CDC ACM endpoints. */ + UX_ASSERT(!UX_DEVICE_CLASS_CDC_ACM_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + cdc_acm -> ux_device_class_cdc_acm_endpoint_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_CDC_ACM_ENDPOINT_BUFFER_SIZE); + if (cdc_acm -> ux_device_class_cdc_acm_endpoint_buffer == UX_NULL) + { + + /* Free the resources. */ + _ux_utility_memory_free(cdc_acm); + + /* Return fatal error. */ + return(UX_MEMORY_INSUFFICIENT); + } +#endif + #if !defined(UX_DEVICE_STANDALONE) /* Create the Mutex for each endpoint as multiple threads cannot access each pipe at the same time. */ @@ -130,6 +152,9 @@ UINT status; { /* Free the resources. */ +#if defined(UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER) + _ux_utility_memory_free(cdc_acm -> ux_device_class_cdc_acm_endpoint_buffer); +#endif _ux_utility_memory_free(cdc_acm); /* Return fatal error. */ @@ -147,6 +172,9 @@ UINT status; _ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex); /* Free the resources. */ +#if defined(UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER) + _ux_utility_memory_free(cdc_acm -> ux_device_class_cdc_acm_endpoint_buffer); +#endif _ux_utility_memory_free(cdc_acm); /* Return fatal error. */ @@ -269,6 +297,9 @@ UINT status; _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack); _ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex); _ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex); +#if defined(UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER) + _ux_utility_memory_free(cdc_acm -> ux_device_class_cdc_acm_endpoint_buffer); +#endif _ux_utility_memory_free(cdc_acm); return(status); } diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c index dc2fe461..ef77298b 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c @@ -90,7 +90,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ -/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* xx-xx-xxxx Yajun Xia, CQ Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -151,13 +154,36 @@ ULONG local_requested_length; /* Protect this thread. */ _ux_device_mutex_on(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex); - - /* All CDC reading are on the endpoint OUT, from the host. */ + + /* All CDC readings are on the endpoint OUT, from the host. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; - + +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 +#if !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + transfer_request -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER(cdc_acm); +#else + transfer_request -> ux_slave_transfer_request_data_pointer = buffer; +#endif +#endif + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + + /* Check if device is configured. */ + if (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED) + { + + /* Issue the transfer request. */ + local_requested_length = requested_length; + status = _ux_device_stack_transfer_request(transfer_request, requested_length, local_requested_length); + *actual_length = transfer_request -> ux_slave_transfer_request_actual_length; + } + +#else + /* Reset the actual length. */ *actual_length = 0; - + /* Check if we need more transactions. */ while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED && requested_length != 0) { @@ -218,7 +244,8 @@ ULONG local_requested_length; } } - +#endif + /* Free Mutex resource. */ _ux_device_mutex_off(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex); diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c index ae7e065b..0fac5bd3 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c @@ -83,7 +83,10 @@ /* 10-31-2022 Yajun Xia Modified comment(s), */ /* fixed return code, */ /* resulting in version 6.2.0 */ -/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* xx-xx-xxxx Yajun Xia, CQ Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* fixed return code, */ /* resulting in version 6.x */ /* */ @@ -147,6 +150,57 @@ UINT status = UX_SUCCESS; /* All CDC reading are on the endpoint OUT, from the host. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + transfer_request -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER(cdc_acm); +#endif + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + + /* Run the transfer state machine. */ + if(cdc_acm -> ux_device_class_cdc_acm_read_state == UX_STATE_RESET) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ACM_READ, cdc_acm, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) + + cdc_acm -> ux_device_class_cdc_acm_read_state = UX_DEVICE_CLASS_CDC_ACM_READ_WAIT; + cdc_acm -> ux_device_class_cdc_acm_read_status = UX_TRANSFER_NO_ANSWER; + transfer_request -> ux_slave_transfer_request_data_pointer = buffer; + UX_SLAVE_TRANSFER_STATE_RESET(transfer_request); + } + + /* Issue the transfer request. */ + max_transfer_length = requested_length; + status = _ux_device_stack_transfer_run(transfer_request, max_transfer_length, max_transfer_length); + + /* Error case. */ + if (status < UX_STATE_NEXT) + { + cdc_acm -> ux_device_class_cdc_acm_read_state = UX_STATE_RESET; + cdc_acm -> ux_device_class_cdc_acm_read_status = + transfer_request -> ux_slave_transfer_request_completion_code; + return(UX_STATE_ERROR); + } + + /* Success case. */ + if (status == UX_STATE_NEXT) + { + + /* Last transfer status. */ + cdc_acm -> ux_device_class_cdc_acm_read_status = + transfer_request -> ux_slave_transfer_request_completion_code; + + /* Update actual length. */ + *actual_length = transfer_request -> ux_slave_transfer_request_actual_length; + + /* It's done. */ + cdc_acm -> ux_device_class_cdc_acm_read_state = UX_STATE_RESET; + } + + return(status); +#else + /* Handle state cases. */ switch(cdc_acm -> ux_device_class_cdc_acm_read_state) { @@ -178,7 +232,7 @@ UINT status = UX_SUCCESS; } /* Check if we have enough in the local buffer. */ - /* Use wMaxPacketSize for faster action, UX_SLAVE_REQUEST_DATA_MAX_LENGTH for better performance. */ + /* Use wMaxPacketSize for faster action, UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE for better performance. */ max_transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize; if (requested_length > max_transfer_length) { @@ -256,9 +310,11 @@ UINT status = UX_SUCCESS; cdc_acm -> ux_device_class_cdc_acm_read_status = UX_INVALID_STATE; break; } + /* Error cases. */ return(UX_STATE_EXIT); +#endif } /**************************************************************************/ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c index 55f5dddb..ab861027 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c @@ -43,7 +43,7 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_tasks_run PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -86,6 +86,11 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed compile warnings, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_tasks_run(VOID *instance) @@ -124,6 +129,8 @@ UX_SLAVE_CLASS_CDC_ACM *cdc_acm; /* There must be something running. */ status = UX_STATE_WAIT; +#else + UX_PARAMETER_NOT_USED(instance); #endif return(status); @@ -154,9 +161,56 @@ ULONG max_transfer_length; endpoint = endpoint -> ux_slave_endpoint_next_endpoint; } - /* All CDC reading are on the endpoint OUT, from the host. */ + /* All CDC readings are on the endpoint OUT, from the host. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) + transfer_request -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER(cdc_acm); +#endif + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + + /* Run the transfer state machine. */ + if (cdc_acm -> ux_device_class_cdc_acm_read_state == UX_STATE_RESET) + { + cdc_acm -> ux_device_class_cdc_acm_read_state = UX_DEVICE_CLASS_CDC_ACM_READ_WAIT; + cdc_acm -> ux_device_class_cdc_acm_read_status = UX_TRANSFER_NO_ANSWER; + UX_SLAVE_TRANSFER_STATE_RESET(transfer_request); + } + + /* Use wMaxPacketSize for faster action, UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE for better performance. */ + max_transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize; + + /* Issue the transfer request. */ + status = _ux_device_stack_transfer_run(transfer_request, max_transfer_length, max_transfer_length); + + /* Success/Error cases. */ + if (status <= UX_STATE_NEXT) + { + + /* Do it again. */ + cdc_acm -> ux_device_class_cdc_acm_read_state = UX_STATE_RESET; + + /* Last transfer status. */ + cdc_acm -> ux_device_class_cdc_acm_read_status = + transfer_request -> ux_slave_transfer_request_completion_code; + + if (cdc_acm -> ux_device_class_cdc_acm_read_callback) + { + cdc_acm -> ux_device_class_cdc_acm_read_callback(cdc_acm, + transfer_request -> ux_slave_transfer_request_completion_code, + transfer_request -> ux_slave_transfer_request_data_pointer, + transfer_request -> ux_slave_transfer_request_actual_length); + } + return; + } + + /* Keep state - waiting. */ + return; + +#else + /* Handle state cases. */ switch(cdc_acm -> ux_device_class_cdc_acm_read_state) { @@ -164,7 +218,7 @@ ULONG max_transfer_length; cdc_acm -> ux_device_class_cdc_acm_read_state = UX_DEVICE_CLASS_CDC_ACM_READ_WAIT; cdc_acm -> ux_device_class_cdc_acm_read_status = UX_TRANSFER_NO_ANSWER; - /* Use wMaxPacketSize for faster action, UX_SLAVE_REQUEST_DATA_MAX_LENGTH for better performance. */ + /* Use wMaxPacketSize for faster action, UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE for better performance. */ max_transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize; cdc_acm -> ux_device_class_cdc_acm_read_transfer_length = max_transfer_length; @@ -209,6 +263,7 @@ ULONG max_transfer_length; cdc_acm -> ux_device_class_cdc_acm_read_status = UX_INVALID_STATE; break; } +#endif } static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm) { @@ -217,8 +272,10 @@ UINT status; UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; -UINT zlp = UX_FALSE; ULONG requested_length; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER != 1) || !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) +UINT zlp = UX_FALSE; +#endif /* If write not started, return. */ @@ -242,6 +299,46 @@ ULONG requested_length; /* We are writing to the IN endpoint. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + transfer_request -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER(cdc_acm); +#endif + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + + /* Handle state cases. */ + if(cdc_acm -> ux_device_class_cdc_acm_write_state == UX_STATE_RESET) + { + cdc_acm -> ux_device_class_cdc_acm_write_state = UX_DEVICE_CLASS_CDC_ACM_WRITE_START; + transfer_request -> ux_slave_transfer_request_data_pointer = + cdc_acm -> ux_device_class_cdc_acm_write_buffer; + UX_SLAVE_TRANSFER_STATE_RESET(transfer_request); + } + + /* Run the transfer request. */ + requested_length = cdc_acm -> ux_device_class_cdc_acm_write_requested_length; +#if defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + status = _ux_device_stack_transfer_run(transfer_request, requested_length, requested_length + 1); +#else + status = _ux_device_stack_transfer_run(transfer_request, requested_length, requested_length); +#endif + + /* Success/Error case. */ + if (status <= UX_STATE_NEXT) + { + cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET; + cdc_acm -> ux_device_class_cdc_acm_write_status = + transfer_request -> ux_slave_transfer_request_completion_code; + cdc_acm -> ux_slave_class_cdc_acm_scheduled_write = UX_FALSE; + if (cdc_acm -> ux_device_class_cdc_acm_write_callback) + { + cdc_acm -> ux_device_class_cdc_acm_write_callback(cdc_acm, + transfer_request -> ux_slave_transfer_request_completion_code, + transfer_request -> ux_slave_transfer_request_actual_length); + } + return; + } +#else /* Handle state cases. */ switch(cdc_acm -> ux_device_class_cdc_acm_write_state) { @@ -249,7 +346,7 @@ ULONG requested_length; cdc_acm -> ux_device_class_cdc_acm_write_state = UX_DEVICE_CLASS_CDC_ACM_WRITE_START; cdc_acm -> ux_device_class_cdc_acm_write_status = UX_TRANSFER_NO_ANSWER; cdc_acm -> ux_device_class_cdc_acm_write_actual_length = 0; - cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; if (cdc_acm -> ux_device_class_cdc_acm_write_requested_length == 0) zlp = UX_TRUE; @@ -275,11 +372,11 @@ ULONG requested_length; } /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE) /* We have too much to transfer. */ cdc_acm -> ux_device_class_cdc_acm_write_transfer_length = - UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; else { @@ -294,7 +391,7 @@ ULONG requested_length; #else /* Assume expected more to let stack append ZLP if needed. */ - cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE + 1; #endif } @@ -373,6 +470,7 @@ ULONG requested_length; cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET; break; } +#endif } #endif /* !defined(UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE) */ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c index 5f09cc40..36954f0f 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_uninitialize PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,11 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -118,6 +123,12 @@ UX_SLAVE_CLASS *class_ptr; #endif #endif +#if defined(UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER) + + /* Free the buffer for bulk endpoints. */ + _ux_utility_memory_free(cdc_acm -> ux_device_class_cdc_acm_endpoint_buffer); +#endif + /* Free the resources. */ _ux_utility_memory_free(cdc_acm); diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c index 73ca5f9f..aee5590c 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c @@ -92,7 +92,10 @@ /* names conflict C++ keyword, */ /* added auto ZLP support, */ /* resulting in version 6.1.12 */ -/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* xx-xx-xxxx Yajun Xia, CQ Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -153,10 +156,19 @@ UINT status = 0; /* Protect this thread. */ _ux_device_mutex_on(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex); - + /* We are writing to the IN endpoint. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 +#if !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + transfer_request -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER(cdc_acm); +#else + transfer_request -> ux_slave_transfer_request_data_pointer = buffer; +#endif +#endif + /* Reset the actual length. */ *actual_length = 0; @@ -176,17 +188,40 @@ UINT status = 0; } else - { + { + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + + /* Check if device is configured. */ + if (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED) + { + +#if defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + + /* Issue with larger host length to append zlp if necessary. */ + local_host_length = requested_length + 1; +#else + local_host_length = requested_length; +#endif + local_requested_length = requested_length; + + /* Issue the transfer request. */ + status = _ux_device_stack_transfer_request(transfer_request, local_requested_length, local_host_length); + if (status == UX_SUCCESS) + *actual_length = transfer_request -> ux_slave_transfer_request_actual_length; + } +#else + /* Check if we need more transactions. */ - local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + local_host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED && requested_length != 0) { /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE) /* We have too much to transfer. */ - local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + local_requested_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; else { @@ -201,7 +236,7 @@ UINT status = 0; #else /* Assume expecting more, so ZLP is appended in stack. */ - local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; + local_host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE + 1; #endif } @@ -238,6 +273,7 @@ UINT status = 0; return(status); } } +#endif /* _BUFF_OWNER && _ZERO_COPY */ } diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c index b2547b11..33db3f03 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c @@ -87,7 +87,10 @@ /* 10-31-2022 Yajun Xia Modified comment(s), */ /* fixed return code, */ /* resulting in version 6.2.0 */ -/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* xx-xx-xxxx Yajun Xia, CQ Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* fixed return code, */ /* resulting in version 6.x */ /* */ @@ -100,15 +103,17 @@ UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_DEVICE *device; UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; -UINT zlp = UX_FALSE; UINT status = 0; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER != 1) || !defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) +UINT zlp = UX_FALSE; +#endif /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ACM_WRITE, cdc_acm, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) #ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE - /* Check if current cdc-acm is using callback or not. We cannot use direct reads with callback on. */ + /* Check if current cdc-acm is using callback or not. We cannot use direct writes with callback on. */ if (cdc_acm -> ux_slave_class_cdc_acm_transmission_status == UX_TRUE) /* Not allowed. */ @@ -152,6 +157,60 @@ UINT status = 0; /* We are writing to the IN endpoint. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; +#if defined(UX_DEVICE_CLASS_CDC_ACM_OWN_ENDPOINT_BUFFER) + transfer_request -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER(cdc_acm); +#endif + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ACM_ZERO_COPY) + + /* Run the transfer state machine. */ + if(cdc_acm -> ux_device_class_cdc_acm_write_state == UX_STATE_RESET) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ACM_WRITE, cdc_acm, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) + + cdc_acm -> ux_device_class_cdc_acm_write_state = UX_DEVICE_CLASS_CDC_ACM_WRITE_WAIT; + cdc_acm -> ux_device_class_cdc_acm_write_status = UX_TRANSFER_NO_ANSWER; + transfer_request -> ux_slave_transfer_request_data_pointer = buffer; + UX_SLAVE_TRANSFER_STATE_RESET(transfer_request); + } + + /* Issue the transfer request. */ +#if defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + status = _ux_device_stack_transfer_run(transfer_request, requested_length, requested_length + 1); +#else + status = _ux_device_stack_transfer_run(transfer_request, requested_length, requested_length); +#endif + + /* Error case. */ + if (status < UX_STATE_NEXT) + { + cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET; + cdc_acm -> ux_device_class_cdc_acm_write_status = + transfer_request -> ux_slave_transfer_request_completion_code; + return(UX_STATE_ERROR); + } + + /* Success case. */ + if (status == UX_STATE_NEXT) + { + + /* Last transfer status. */ + cdc_acm -> ux_device_class_cdc_acm_write_status = + transfer_request -> ux_slave_transfer_request_completion_code; + + /* Update actual length. */ + *actual_length = transfer_request -> ux_slave_transfer_request_actual_length; + + /* It's done. */ + cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET; + } + + return(status); +#else + /* Handle state cases. */ switch(cdc_acm -> ux_device_class_cdc_acm_write_state) { @@ -161,7 +220,7 @@ UINT status = 0; cdc_acm -> ux_device_class_cdc_acm_write_buffer = buffer; cdc_acm -> ux_device_class_cdc_acm_write_requested_length = requested_length; cdc_acm -> ux_device_class_cdc_acm_write_actual_length = 0; - cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; if (requested_length == 0) zlp = UX_TRUE; @@ -182,11 +241,11 @@ UINT status = 0; } /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE) /* We have too much to transfer. */ cdc_acm -> ux_device_class_cdc_acm_write_transfer_length = - UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE; else { @@ -201,7 +260,7 @@ UINT status = 0; #else /* Assume expected more than transfer to let stack append ZLP if needed. */ - cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_DEVICE_CLASS_CDC_ACM_WRITE_BUFFER_SIZE + 1; #endif } @@ -274,6 +333,7 @@ UINT status = 0; /* Error case. */ return(UX_STATE_EXIT); +#endif } /**************************************************************************/ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c index 26de96ae..021e66eb 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -134,10 +138,17 @@ ULONG physical_address_lsw; /* We have found the interrupt endpoint, save it. */ cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Set the endpoint buffer to the endpoint. */ + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ECM_INTERRUPTIN_BUFFER(cdc_ecm); +#endif /* Reset the endpoint buffers. */ _ux_utility_memory_set(cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_endpoint -> ux_slave_endpoint_transfer_request. - ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */ + ux_slave_transfer_request_data_pointer, 0, UX_DEVICE_CLASS_CDC_ECM_INTERRUPTIN_BUFFER_SIZE); /* Use case of memset is verified. */ /* Resume the interrupt endpoint threads. */ _ux_device_thread_resume(&cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread); @@ -185,18 +196,30 @@ ULONG physical_address_lsw; /* Look at type. */ if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT) - + { + /* We have found the bulk in endpoint, save it. */ cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER(cdc_ecm); +#endif + } } else { /* Look at type for out endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT) - + { + /* We have found the bulk out endpoint, save it. */ cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER(cdc_ecm); +#endif + } } /* Next endpoint. */ @@ -219,9 +242,9 @@ ULONG physical_address_lsw; /* Reset the endpoint buffers. */ _ux_utility_memory_set(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint -> ux_slave_endpoint_transfer_request. - ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */ + ux_slave_transfer_request_data_pointer, 0, UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE); /* Use case of memset is verified. */ _ux_utility_memory_set(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint -> ux_slave_endpoint_transfer_request. - ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */ + ux_slave_transfer_request_data_pointer, 0, UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE); /* Use case of memset is verified. */ /* Resume the endpoint threads. */ _ux_device_thread_resume(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread); diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c index 57968f64..ca3bf1e8 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_bulkin_thread PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -86,6 +86,10 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* used NX API to copy data, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_ecm_bulkin_thread(ULONG cdc_ecm_class) @@ -152,7 +156,7 @@ ULONG copied; { /* Can the packet fit in the transfer requests data buffer? */ - if (current_packet -> nx_packet_length <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (current_packet -> nx_packet_length <= UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE) { /* Copy the packet in the transfer descriptor buffer. */ @@ -169,7 +173,7 @@ ULONG copied; UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ECM_PACKET_TRANSMIT, cdc_ecm, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) /* Send the request to the device controller. */ - status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_CDC_ECM_ETHERNET_PACKET_SIZE + 1); + status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE + 1); } /* Check error code. */ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c index 8b1cc267..0b266f78 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_bulkout_thread PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -88,6 +88,10 @@ /* used pool from NX IP inst, */ /* used NX API to copy data, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_ecm_bulkout_thread(ULONG cdc_ecm_class) @@ -159,7 +163,7 @@ USB_NETWORK_DEVICE_TYPE *ux_nx_device; transfer_request = &cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint -> ux_slave_endpoint_transfer_request; /* And length. */ - transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH; + transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE; transfer_request -> ux_slave_transfer_request_actual_length = 0; /* Memorize this packet at the beginning of the queue. */ @@ -169,8 +173,8 @@ USB_NETWORK_DEVICE_TYPE *ux_nx_device; packet -> nx_packet_queue_next = UX_NULL; /* Send the request to the device controller. */ - status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH, - UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH); + status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE, + UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE); /* Check the completion code. */ if (status == UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c index 7d16c444..6b472a08 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_change PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -85,6 +85,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_change(UX_SLAVE_CLASS_COMMAND *command) @@ -126,7 +130,11 @@ UX_SLAVE_ENDPOINT *endpoint; /* We have found the bulk in endpoint, save it. */ cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint = endpoint; - +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER(cdc_ecm); +#endif } else { @@ -135,6 +143,11 @@ UX_SLAVE_ENDPOINT *endpoint; /* We have found the bulk out endpoint, save it. */ cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER(cdc_ecm); +#endif } /* Next endpoint. */ @@ -155,9 +168,9 @@ UX_SLAVE_ENDPOINT *endpoint; /* Reset the endpoint buffers. */ _ux_utility_memory_set(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint -> ux_slave_endpoint_transfer_request. - ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */ + ux_slave_transfer_request_data_pointer, 0, UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE); /* Use case of memset is verified. */ _ux_utility_memory_set(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint -> ux_slave_endpoint_transfer_request. - ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */ + ux_slave_transfer_request_data_pointer, 0, UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE); /* Use case of memset is verified. */ /* Resume the endpoint threads. */ _ux_device_thread_resume(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread); diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c index 84ae21ba..ba3e475b 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_initialize PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -89,6 +89,10 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* removed internal NX pool, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -125,6 +129,17 @@ UINT status; /* Assume good result. */ status = UX_SUCCESS; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Allocate buffer for endpoints. */ + UX_ASSERT(!UX_DEVICE_CLASS_CDC_ECM_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer = + _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_CDC_ECM_ENDPOINT_BUFFER_SIZE); + if (cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer == UX_NULL) + status = (UX_MEMORY_INSUFFICIENT); +#endif + /* Allocate some memory for the bulk out thread stack. */ cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE); @@ -251,6 +266,10 @@ UINT status; _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack); if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack) _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack); +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + if (cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer) + _ux_utility_memory_free(cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer); +#endif _ux_device_mutex_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_mutex); _ux_utility_memory_free(cdc_ecm); diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c index 43ae2175..36972dd3 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_uninitialize PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -85,6 +85,10 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* removed internal NX pool, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -137,6 +141,9 @@ UX_SLAVE_CLASS *class_ptr; #endif /* Free the resources. */ +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer); +#endif _ux_utility_memory_free(cdc_ecm); } diff --git a/common/usbx_device_classes/src/ux_device_class_hid_activate.c b/common/usbx_device_classes/src/ux_device_class_hid_activate.c index c731e95d..fb9fb128 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -84,6 +84,11 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -96,6 +101,7 @@ UX_SLAVE_ENDPOINT *endpoint_interrupt; UX_SLAVE_ENDPOINT *endpoint_in = UX_NULL; #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; +UCHAR *pos; #endif /* Get the class container. */ @@ -128,6 +134,15 @@ UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; /* It's interrupt IN endpoint we need. */ endpoint_in = endpoint_interrupt; + +#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) + + /* Set endpoint buffer owner to class instance. */ + endpoint_in -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER(hid); +#endif + #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) if (endpoint_out != UX_NULL) #endif @@ -139,6 +154,15 @@ UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; /* It's optional interrupt OUT endpoint. */ endpoint_out = endpoint_interrupt; + +#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) + + /* Set endpoint buffer owner to class instance. */ + endpoint_out -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_HID_INTERRUPTOUT_BUFFER(hid); +#endif + if (endpoint_in != UX_NULL) break; } @@ -178,10 +202,12 @@ UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_events; hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_event_read_pos = hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_events; - _ux_utility_memory_set( - hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_events, 0x00, - (ALIGN_TYPE)hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_events_end - - (ALIGN_TYPE)hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_events); /* Use case of memset is verified. */ + for (pos = (UCHAR*)hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_events; + pos < (UCHAR*)hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_events_end; + pos += UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_SIZE(hid -> ux_device_class_hid_receiver)) + { + ((UX_DEVICE_CLASS_HID_RECEIVED_EVENT*)pos) -> ux_device_class_hid_received_event_length = 0; + } #if !defined(UX_DEVICE_STANDALONE) @@ -203,7 +229,7 @@ UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; /* Reset event buffered for background transfer. */ _ux_utility_memory_set((VOID *)&hid -> ux_device_class_hid_event, 0, - sizeof(UX_SLAVE_CLASS_HID_EVENT)); /* Use case of memset is verified. */ + sizeof(UX_DEVICE_CLASS_HID_EVENT)); /* Use case of memset is verified. */ hid -> ux_device_class_hid_event.ux_device_class_hid_event_length = endpoint_in -> ux_slave_endpoint_transfer_request. ux_slave_transfer_request_transfer_length; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_event_get.c b/common/usbx_device_classes/src/ux_device_class_hid_event_get.c index 61a83505..b3d060b8 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_event_get.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_event_get.c @@ -11,8 +11,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -29,93 +29,191 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_event_get PORTABLE C */ -/* 6.1 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_event_check PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function checks if there is an event from the application */ -/* */ -/* INPUT */ -/* */ -/* hid Address of hid class */ -/* event Pointer of the event */ -/* */ -/* OUTPUT */ -/* */ -/* status UX_SUCCESS if there is an */ -/* event */ -/* CALLS */ -/* */ -/* _ux_utility_memory_copy Copy memory */ -/* */ -/* CALLED BY */ -/* */ -/* ThreadX */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ -/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ -/* verified memset and memcpy */ -/* cases, */ -/* resulting in version 6.1 */ +/* */ +/* This function checks if there is an event from the application and */ +/* fill a pointer to access the event. */ +/* */ +/* INPUT */ +/* */ +/* hid Address of hid class */ +/* event Pointer to fill address */ +/* to access event */ +/* */ +/* OUTPUT */ +/* */ +/* status UX_SUCCESS if there is an */ +/* event */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Device HID Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx Chaoqiong Xiao Initial Version 6.x */ /* */ /**************************************************************************/ -UINT _ux_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid, - UX_SLAVE_CLASS_HID_EVENT *hid_event) +UINT _ux_device_class_hid_event_check(UX_SLAVE_CLASS_HID *hid, + UX_DEVICE_CLASS_HID_EVENT **hid_event) { - -UX_SLAVE_CLASS_HID_EVENT *current_hid_event; UX_SLAVE_DEVICE *device; - /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_EVENT_GET, hid, hid_event, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) - - /* Get the pointer to the device. */ + /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; - + /* Check the device state. */ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) return(UX_DEVICE_HANDLE_UNKNOWN); /* Check if the head and the tail of the event array is the same. */ - if (hid -> ux_device_class_hid_event_array_head == + if (hid -> ux_device_class_hid_event_array_head == hid -> ux_device_class_hid_event_array_tail) /* No event to report. */ - return(UX_ERROR); + return(UX_ERROR); /* There is an event to report, get the current pointer to the event. */ - current_hid_event = hid -> ux_device_class_hid_event_array_tail; + *hid_event = hid -> ux_device_class_hid_event_array_tail; + return(UX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_event_free PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function free the event in queue tail. */ +/* */ +/* INPUT */ +/* */ +/* hid Address of hid class */ +/* */ +/* OUTPUT */ +/* */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Device HID Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx Chaoqiong Xiao Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID _ux_device_class_hid_event_free(UX_SLAVE_CLASS_HID *hid) +{ +UCHAR *pos; + + pos = (UCHAR *) hid -> ux_device_class_hid_event_array_tail; + pos += UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid); + if (pos >= (UCHAR *) hid -> ux_device_class_hid_event_array_end) + pos = (UCHAR *) hid -> ux_device_class_hid_event_array; + hid -> ux_device_class_hid_event_array_tail = (UX_DEVICE_CLASS_HID_EVENT *) pos; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_event_get PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks if there is an event from the application */ +/* */ +/* INPUT */ +/* */ +/* hid Address of hid class */ +/* event Pointer of the event */ +/* */ +/* OUTPUT */ +/* */ +/* status UX_SUCCESS if there is an */ +/* event */ +/* CALLS */ +/* */ +/* _ux_utility_memory_copy Copy memory */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ +/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ +/* verified memset and memcpy */ +/* cases, */ +/* resulting in version 6.1 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ +/* */ +/**************************************************************************/ +UINT _ux_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid, + UX_SLAVE_CLASS_HID_EVENT *hid_event) +{ + +UX_DEVICE_CLASS_HID_EVENT *current_hid_event; +UINT status; + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_EVENT_GET, hid, hid_event, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) + + /* Check and get event pointer. */ + status = _ux_device_class_hid_event_check(hid, ¤t_hid_event); + if (status != UX_SUCCESS) + return(status); /* Keep the event data length inside buffer area. */ - if (current_hid_event -> ux_device_class_hid_event_length > UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH) - current_hid_event -> ux_device_class_hid_event_length = UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH; + if (current_hid_event -> ux_device_class_hid_event_length > UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid)) + current_hid_event -> ux_device_class_hid_event_length = UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid); /* fill in the event structure from the user. */ hid_event -> ux_device_class_hid_event_length = current_hid_event -> ux_device_class_hid_event_length; - _ux_utility_memory_copy(hid_event -> ux_device_class_hid_event_buffer, current_hid_event -> ux_device_class_hid_event_buffer, - current_hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */ - /* Adjust the tail pointer. Check if we are at the end. */ - if ((current_hid_event + 1) == hid -> ux_device_class_hid_event_array_end) + /* Copy the event data into the user buffer. */ + _ux_utility_memory_copy(hid_event -> ux_device_class_hid_event_buffer, + UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event), + current_hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */ - /* We are at the end, go back to the beginning. */ - hid -> ux_device_class_hid_event_array_tail = hid -> ux_device_class_hid_event_array; - - else - /* We are not at the end, increment the tail position. */ - hid -> ux_device_class_hid_event_array_tail++; + /* Free the tail event. */ + _ux_device_class_hid_event_free(hid); /* Return event status to the user. */ return(UX_SUCCESS); @@ -160,7 +258,7 @@ UX_SLAVE_DEVICE *device; /* xx-xx-xxxx Chaoqiong Xiao Initial Version 6.x */ /* */ /**************************************************************************/ -UINT _uxe_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid, +UINT _uxe_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event) { diff --git a/common/usbx_device_classes/src/ux_device_class_hid_event_set.c b/common/usbx_device_classes/src/ux_device_class_hid_event_set.c index 3629d259..5c3f9237 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_event_set.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_event_set.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_event_set PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,36 +79,34 @@ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_event_set(UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event) { -UX_SLAVE_CLASS_HID_EVENT *current_hid_event; -UX_SLAVE_CLASS_HID_EVENT *next_hid_event; +UX_DEVICE_CLASS_HID_EVENT *current_hid_event; +UX_DEVICE_CLASS_HID_EVENT *next_hid_event; +UCHAR *next_position; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_EVENT_SET, hid, hid_event, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) /* Current position of the head. */ current_hid_event = hid -> ux_device_class_hid_event_array_head; - + /* If the pointer is NULL, the round robin buffer has not been activated. */ if (current_hid_event == UX_NULL) return (UX_ERROR); /* Calculate the next position. */ - if ((current_hid_event + 1) == hid -> ux_device_class_hid_event_array_end) - - /* We are at the end, go back to the beginning. */ - next_hid_event = hid -> ux_device_class_hid_event_array; - - else - - /* We are not at the end, increment the head position. */ - next_hid_event = current_hid_event + 1; - + next_position = (UCHAR *)current_hid_event + UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid); + if (next_position >= (UCHAR *)hid -> ux_device_class_hid_event_array_end) + next_position = (UCHAR *)hid -> ux_device_class_hid_event_array; + next_hid_event = (UX_DEVICE_CLASS_HID_EVENT *)next_position; /* Any place left for this event ? */ if (next_hid_event == hid -> ux_device_class_hid_event_array_tail) @@ -126,7 +124,7 @@ UX_SLAVE_CLASS_HID_EVENT *next_hid_event; /* Yes, there's a report ID. Check to see if our event buffer can also fit the extra byte. */ - if (hid_event -> ux_device_class_hid_event_length + 1 > UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH) + if (hid_event -> ux_device_class_hid_event_length + 1 > UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid)) { /* Error trap. */ @@ -140,10 +138,11 @@ UX_SLAVE_CLASS_HID_EVENT *next_hid_event; } /* Store the report ID. */ - *current_hid_event -> ux_device_class_hid_event_buffer = (UCHAR)(hid_event -> ux_device_class_hid_event_report_id); - + *UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event) = (UCHAR)(hid_event -> ux_device_class_hid_event_report_id); + /* Store the data itself. */ - _ux_utility_memory_copy(current_hid_event -> ux_device_class_hid_event_buffer + 1, hid_event -> ux_device_class_hid_event_buffer, + _ux_utility_memory_copy(UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event) + 1, + hid_event -> ux_device_class_hid_event_buffer, hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */ /* fill in the event structure from the user. */ @@ -153,7 +152,10 @@ UX_SLAVE_CLASS_HID_EVENT *next_hid_event; { /* No report ID to consider. */ - _ux_utility_memory_copy(current_hid_event -> ux_device_class_hid_event_buffer, hid_event -> ux_device_class_hid_event_buffer, + + /* Store copy of data so application can free event there (easier use). */ + _ux_utility_memory_copy(UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event), + hid_event -> ux_device_class_hid_event_buffer, hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */ /* fill in the event structure from the user. */ diff --git a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c index d2e2ab4f..fd87bd04 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c @@ -89,6 +89,9 @@ /* fixed compile warnings, */ /* resulting in version 6.2.0 */ /* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* checked compile options, */ /* resulting in version 6.x */ /* */ @@ -100,12 +103,22 @@ UX_SLAVE_CLASS_HID *hid; UX_SLAVE_CLASS_HID_PARAMETER *hid_parameter; UX_SLAVE_CLASS *class_ptr; UINT status = UX_SUCCESS; +ULONG array_memory_size; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) +UINT i; +UCHAR *buffer; +#endif /* Compile option checks. */ UX_ASSERT(UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH <= UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH); +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 0 UX_ASSERT(UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH); +#endif + + /* Get the pointer to the application parameters for the hid class. */ + hid_parameter = command -> ux_slave_class_command_parameter; /* Get the class container. */ class_ptr = command -> ux_slave_class_command_class_ptr; @@ -120,6 +133,20 @@ UINT status = UX_SUCCESS; /* Save the address of the HID instance inside the HID container. */ class_ptr -> ux_slave_class_instance = (VOID *) hid; +#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) + + /* Allocate buffer(s) for endpoint(s). */ + UX_ASSERT(!UX_DEVICE_CLASS_HID_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + hid -> ux_device_class_hid_endpoint_buffer = _ux_utility_memory_allocate( + UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_HID_ENDPOINT_BUFFER_SIZE); + if (hid -> ux_device_class_hid_endpoint_buffer == UX_NULL) + { + _ux_utility_memory_free(hid); + return(UX_MEMORY_INSUFFICIENT); + } +#endif + #if !defined(UX_DEVICE_STANDALONE) /* Allocate some memory for the thread stack. */ @@ -141,6 +168,13 @@ UINT status = UX_SUCCESS; UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); #else +#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) + + /* Set event buffer. */ + hid -> ux_device_class_hid_event.ux_device_class_hid_event_buffer = + UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER(hid); +#endif + /* Set task function. */ class_ptr -> ux_slave_class_task_function = _ux_device_class_hid_tasks_run; #endif @@ -153,8 +187,6 @@ UINT status = UX_SUCCESS; UX_THREAD_EXTENSION_PTR_SET(&(class_ptr -> ux_slave_class_thread), class_ptr) #endif - /* Get the pointer to the application parameters for the hid class. */ - hid_parameter = command -> ux_slave_class_command_parameter; /* Store all the application parameter information about the report. */ hid -> ux_device_class_hid_report_address = hid_parameter -> ux_device_class_hid_parameter_report_address; @@ -165,8 +197,68 @@ UINT status = UX_SUCCESS; hid -> ux_device_class_hid_callback = hid_parameter -> ux_device_class_hid_parameter_callback; hid -> ux_device_class_hid_get_callback = hid_parameter -> ux_device_class_hid_parameter_get_callback; +#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) + + /* If event length is invalid, UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH is used. */ + if (UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter) == 0 || + UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter) > UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH) + UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter) = UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH; + + /* If event queue size is invalid, UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE is used. */ + if (UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter) < 2 || + UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter) > UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE) + UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter) = UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE; + + /* Save event size. */ + UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid) = UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter); +#endif + /* Create the event array. */ - hid -> ux_device_class_hid_event_array = _ux_utility_memory_allocate_mulc_safe(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_HID_EVENT), UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE); + UX_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG( + UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid), + UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter))); + array_memory_size = UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid) * UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter); + hid -> ux_device_class_hid_event_array = _ux_utility_memory_allocate(UX_NO_ALIGN, + UX_REGULAR_MEMORY, array_memory_size); + + /* Do we need event buffer? + * 1. Even zero copy, report copy is kept to avoid keep buffers in application. + * 2. Other cases, buffer must be allocated. + */ + /* Allocate buffer if needed. */ + { + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Allocate cache safe event buffers. */ + buffer = _ux_utility_memory_allocate_mulv_safe(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter), + UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter)); + + /* Allocation error check. */ + if (buffer == UX_NULL) + { + if (hid -> ux_device_class_hid_event_array != UX_NULL) + { + _ux_utility_memory_free(hid -> ux_device_class_hid_event_array); + hid -> ux_device_class_hid_event_array = UX_NULL; + } + } + else + { + + /* Assign event buffers. */ + for (i = 0; i < UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter); i ++) + { + hid -> ux_device_class_hid_event_array[i].ux_device_class_hid_event_buffer = buffer; + buffer += UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter); + } + } +#else + + /* Regular event place data following id,type and length. */ +#endif + } /* Check for successful allocation. */ if (hid -> ux_device_class_hid_event_array != UX_NULL) @@ -176,7 +268,7 @@ UINT status = UX_SUCCESS; At first, the head and tail are pointing to the beginning of the array. */ hid -> ux_device_class_hid_event_array_head = hid -> ux_device_class_hid_event_array; hid -> ux_device_class_hid_event_array_tail = hid -> ux_device_class_hid_event_array; - hid -> ux_device_class_hid_event_array_end = hid -> ux_device_class_hid_event_array + UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE; + hid -> ux_device_class_hid_event_array_end = (UX_DEVICE_CLASS_HID_EVENT*)((UCHAR*)hid -> ux_device_class_hid_event_array + array_memory_size); /* Store the start and stop signals if needed by the application. */ hid -> ux_slave_class_hid_instance_activate = hid_parameter -> ux_slave_class_hid_instance_activate; @@ -244,6 +336,9 @@ UINT status = UX_SUCCESS; /* There is still initialization activities after array creation, * and some error occurs in this stage. */ /* Free allocated event array memory. */ +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + _ux_utility_memory_free(hid -> ux_device_class_hid_event_array -> ux_device_class_hid_event_buffer); +#endif _ux_utility_memory_free(hid -> ux_device_class_hid_event_array); #endif @@ -267,6 +362,10 @@ UINT status = UX_SUCCESS; _ux_utility_memory_free(class_ptr -> ux_slave_class_thread_stack); #endif +#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) + _ux_utility_memory_free(hid -> ux_device_class_hid_endpoint_buffer); +#endif + /* Unmount instance. */ class_ptr -> ux_slave_class_instance = UX_NULL; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c b/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c index 0cd80c0f..2cd10e09 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_interrupt_thread PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -84,6 +84,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* off for standalone compile, */ /* resulting in version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_hid_interrupt_thread(ULONG hid_class) @@ -93,7 +96,7 @@ UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_HID *hid; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request_in; -UX_SLAVE_CLASS_HID_EVENT hid_event; +UX_DEVICE_CLASS_HID_EVENT *hid_event; UINT status; UCHAR *buffer; ULONG actual_flags; @@ -139,10 +142,18 @@ ULONG actual_flags; transfer_request_in -> ux_slave_transfer_request_requested_length = transfer_request_in -> ux_slave_transfer_request_transfer_length; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Restore endpoint buffer (never touched, filled with zeros). */ + transfer_request_in -> ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER(hid); +#else + /* Set the data to zeros. */ _ux_utility_memory_set( transfer_request_in -> ux_slave_transfer_request_data_pointer, 0, transfer_request_in -> ux_slave_transfer_request_requested_length); /* Use case of memset is verified. */ +#endif } /* Send the request to the device controller. */ @@ -174,19 +185,29 @@ ULONG actual_flags; /* Check if we have an event to report. */ - while (_ux_device_class_hid_event_get(hid, &hid_event) == UX_SUCCESS) + while (_ux_device_class_hid_event_check(hid, &hid_event) == UX_SUCCESS) { +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Directly use the event buffer for transfer. */ + buffer = hid_event -> ux_device_class_hid_event_buffer; + transfer_request_in -> ux_slave_transfer_request_data_pointer = buffer; +#else /* Prepare the event data payload from the hid event structure. Get a pointer to the buffer area. */ buffer = transfer_request_in -> ux_slave_transfer_request_data_pointer; /* Copy the event buffer into the target buffer. */ - _ux_utility_memory_copy(buffer, hid_event.ux_device_class_hid_event_buffer, hid_event.ux_device_class_hid_event_length); /* Use case of memcpy is verified. */ - + _ux_utility_memory_copy(buffer, UX_DEVICE_CLASS_HID_EVENT_BUFFER(hid_event), hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */ +#endif + /* Send the request to the device controller. */ - status = _ux_device_stack_transfer_request(transfer_request_in, hid_event.ux_device_class_hid_event_length, - hid_event.ux_device_class_hid_event_length); - + status = _ux_device_stack_transfer_request(transfer_request_in, hid_event -> ux_device_class_hid_event_length, + hid_event -> ux_device_class_hid_event_length); + + /* The queue tail is handled and should be freed. */ + _ux_device_class_hid_event_free(hid); + /* Check error code. We don't want to invoke the error callback if the device was disconnected, since that's expected. */ if (status != UX_SUCCESS && status != UX_TRANSFER_BUS_RESET) diff --git a/common/usbx_device_classes/src/ux_device_class_hid_read.c b/common/usbx_device_classes/src/ux_device_class_hid_read.c index 80039dc1..dbd85b1c 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_read.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_read.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_read PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* resulting in version 6.1.11 */ /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_read(UX_SLAVE_CLASS_HID *hid, UCHAR *buffer, @@ -129,6 +132,20 @@ ULONG local_requested_length; /* All HID reading are on the endpoint OUT, from the host. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Directly use buffer from application. */ + transfer_request -> ux_slave_transfer_request_data_pointer = buffer; + + /* Send the request to the device controller. */ + local_requested_length = requested_length; + status = _ux_device_stack_transfer_request(transfer_request, local_requested_length, local_requested_length); + + /* Save actual length. */ + *actual_length = transfer_request -> ux_slave_transfer_request_actual_length; + +#else + /* Reset the actual length. */ *actual_length = 0; @@ -190,6 +207,8 @@ ULONG local_requested_length; } } +#endif + /* Free Mutex resource. */ _ux_device_mutex_off(&hid -> ux_device_class_hid_read_mutex); diff --git a/common/usbx_device_classes/src/ux_device_class_hid_read_run.c b/common/usbx_device_classes/src/ux_device_class_hid_read_run.c index 9dca780a..923c854d 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_read_run.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_read_run.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_read_run PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_read_run(UX_SLAVE_CLASS_HID *hid, UCHAR *buffer, @@ -135,6 +138,45 @@ UINT status= UX_SUCCESS; /* Handle state cases. */ read_state = hid -> ux_device_class_hid_read_state; + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + if (read_state == UX_STATE_RESET) + { + + /* Initialize read states. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_READ_START; + hid -> ux_device_class_hid_read_status = UX_TRANSFER_NO_ANSWER; + + /* Set the data pointer to the buffer. */ + transfer_request -> ux_slave_transfer_request_data_pointer = buffer; + + /* Reset request state. */ + UX_SLAVE_TRANSFER_STATE_RESET(transfer_request); + } + + /* Send the request to the device controller. */ + status = _ux_device_stack_transfer_run(transfer_request, requested_length, requested_length); + + /* Error/success case. */ + if (status <= UX_STATE_NEXT) + { + + /* Update actual length. */ + *actual_length = transfer_request -> ux_slave_transfer_request_actual_length; + + /* Last transfer status. */ + hid -> ux_device_class_hid_read_status = + transfer_request -> ux_slave_transfer_request_completion_code; + + /* Reset read state. */ + hid -> ux_device_class_hid_read_state = UX_STATE_RESET; + } + + /* Return status indicator. */ + return(status); + +#else switch(read_state) { case UX_STATE_RESET: @@ -251,6 +293,7 @@ UINT status= UX_SUCCESS; /* Error case. */ return(UX_STATE_EXIT); #endif +#endif } diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_free.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_free.c index 78b8504c..5d16067b 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_free.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_free.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_event_free PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +68,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_receiver_event_free(UX_SLAVE_CLASS_HID *hid) @@ -95,10 +98,14 @@ UCHAR *next_pos; return(UX_ERROR); /* Invalidate the event and advance position. */ - next_pos = (UCHAR *)pos + receiver -> ux_device_class_hid_receiver_event_buffer_size + sizeof(ULONG); + + /* Calculate next item address. */ + next_pos = (UCHAR *)pos + UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_SIZE(receiver); + if (next_pos >= (UCHAR *)receiver -> ux_device_class_hid_receiver_events_end) next_pos = (UCHAR *)receiver -> ux_device_class_hid_receiver_events; receiver -> ux_device_class_hid_receiver_event_read_pos = (UX_DEVICE_CLASS_HID_RECEIVED_EVENT *)next_pos; + pos -> ux_device_class_hid_received_event_length = 0; /* Inform receiver thread to (re)start. */ diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c index 41334c35..e765a9d1 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_event_get PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,9 @@ /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ /* cleaned compile with TRACE, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_receiver_event_get(UX_SLAVE_CLASS_HID *hid, @@ -102,7 +105,10 @@ UX_DEVICE_CLASS_HID_RECEIVED_EVENT *pos; /* Fill event structure to return. */ event -> ux_device_class_hid_received_event_length = pos -> ux_device_class_hid_received_event_length; - event -> ux_device_class_hid_received_event_data = (UCHAR *)&pos -> ux_device_class_hid_received_event_data; + + /* Fill data buffer address to return. */ + event -> ux_device_class_hid_received_event_data = UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_BUFFER(pos); + return(UX_SUCCESS); } diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c index de5dbe7d..ee1fc3be 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_initialize PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +77,9 @@ /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone receiver, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_receiver_initialize(UX_SLAVE_CLASS_HID *hid, @@ -96,6 +99,11 @@ UCHAR *memory_events; #if !defined(UX_DEVICE_STANDALONE) UCHAR *memory_stack; #endif +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) +UX_DEVICE_CLASS_HID_RECEIVED_EVENT *events_head; +UCHAR *buffer; +UINT i; +#endif UINT status = UX_SUCCESS; @@ -114,10 +122,20 @@ UINT status = UX_SUCCESS; #endif UX_ASSERT(!UX_OVERFLOW_CHECK_ADD_ULONG(parameter -> ux_device_class_hid_parameter_receiver_event_max_length, sizeof(ULONG))); +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Events structs are in regular memory. */ + UX_ASSERT(!UX_OVERFLOW_CHECK_MULV_ULONG(sizeof(UX_DEVICE_CLASS_HID_RECEIVED_EVENT), parameter -> ux_device_class_hid_parameter_receiver_event_max_number)); + events_size = sizeof(UX_DEVICE_CLASS_HID_RECEIVED_EVENT) * parameter -> ux_device_class_hid_parameter_receiver_event_max_number; + + /* Memory of events are allocated later as cache safe memory. */ +#else + /* Memory of events. */ events_size = parameter -> ux_device_class_hid_parameter_receiver_event_max_length + sizeof(ULONG); UX_ASSERT(!UX_OVERFLOW_CHECK_MULV_ULONG(events_size, parameter -> ux_device_class_hid_parameter_receiver_event_max_number)); events_size *= parameter -> ux_device_class_hid_parameter_receiver_event_max_number; +#endif UX_ASSERT(!UX_OVERFLOW_CHECK_ADD_ULONG(memory_size, events_size)); memory_size += events_size; @@ -132,6 +150,37 @@ UINT status = UX_SUCCESS; memory_events = memory_receiver + sizeof(UX_DEVICE_CLASS_HID_RECEIVER); #endif +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Allocate cache safe memory. */ + + /* Total buffer size calculate. */ + events_size = parameter -> ux_device_class_hid_parameter_receiver_event_max_length; + UX_ASSERT(!UX_OVERFLOW_CHECK_MULV_ULONG(events_size, parameter -> ux_device_class_hid_parameter_receiver_event_max_number)); + events_size *= parameter -> ux_device_class_hid_parameter_receiver_event_max_number; + + /* Allocate buffer. */ + buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, events_size); + if (buffer == UX_NULL) + { + _ux_utility_memory_free(memory_receiver); + return(UX_MEMORY_INSUFFICIENT); + } + + /* Assign events buffers. */ + events_head = (UX_DEVICE_CLASS_HID_RECEIVED_EVENT *) memory_events; + for (i = 0; i < parameter -> ux_device_class_hid_parameter_receiver_event_max_number; i++) + { + + /* Assign event buffer. */ + events_head -> ux_device_class_hid_received_event_data = buffer; + + /* Move to next event and next buffer. */ + buffer += parameter -> ux_device_class_hid_parameter_receiver_event_max_length; + events_head ++; + } +#endif + /* Store receiver instance pointer. */ (*receiver) = (UX_DEVICE_CLASS_HID_RECEIVER *)memory_receiver; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_tasks_run.c index 0f5dda2a..a8b9bbb9 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_tasks_run.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_tasks_run.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_tasks_run PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_receiver_tasks_run(UX_SLAVE_CLASS_HID *hid) @@ -117,6 +120,13 @@ ULONG temp; return(UX_STATE_IDLE); } +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Set request buffer. */ + buffer = pos -> ux_device_class_hid_received_event_data; + transfer -> ux_slave_transfer_request_data_pointer = buffer; +#endif + /* Set request length. */ hid -> ux_device_class_hid_read_requested_length = receiver -> ux_device_class_hid_receiver_event_buffer_size; @@ -155,6 +165,12 @@ ULONG temp; return(UX_STATE_NEXT); } +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Save received event length. */ + temp = transfer -> ux_slave_transfer_request_actual_length; +#else + /* Save received event data and length. */ pos = receiver -> ux_device_class_hid_receiver_event_save_pos; buffer = (UCHAR *)&pos -> ux_device_class_hid_received_event_data; @@ -162,9 +178,11 @@ ULONG temp; _ux_utility_memory_copy(buffer, transfer -> ux_slave_transfer_request_data_pointer, temp); /* Use case of memcpy is verified. */ +#endif /* Advance the save position. */ - next_pos = (UCHAR *)pos + receiver -> ux_device_class_hid_receiver_event_buffer_size + sizeof(ULONG); + next_pos = (UCHAR *)pos + UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_SIZE(receiver); + if (next_pos >= (UCHAR *)receiver -> ux_device_class_hid_receiver_events_end) next_pos = (UCHAR *)receiver -> ux_device_class_hid_receiver_events; receiver -> ux_device_class_hid_receiver_event_save_pos = (UX_DEVICE_CLASS_HID_RECEIVED_EVENT *)next_pos; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_thread.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_thread.c index 41eeed4f..bf583484 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_thread PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -56,7 +56,6 @@ /* CALLS */ /* */ /* _ux_utility_event_flags_get Get event flags */ -/* _ux_device_class_hid_event_get Get HID event */ /* _ux_device_stack_transfer_request Request transfer */ /* _ux_utility_memory_copy Copy memory */ /* _ux_utility_thread_suspend Suspend thread */ @@ -73,6 +72,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* added receiver callback, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_hid_receiver_thread(ULONG hid_instance) @@ -111,6 +113,9 @@ ULONG temp; continue; } + /* Protect read. */ + _ux_device_mutex_on(&hid -> ux_device_class_hid_read_mutex); + /* Check if there is buffer available. */ pos = receiver -> ux_device_class_hid_receiver_event_save_pos; if (pos -> ux_device_class_hid_received_event_length != 0) @@ -125,6 +130,7 @@ ULONG temp; { /* Keep checking before a good state. */ + _ux_device_mutex_off(&hid -> ux_device_class_hid_read_mutex); continue; } } @@ -132,8 +138,12 @@ ULONG temp; /* Event buffer available, issue request to get data. */ transfer = &hid -> ux_device_class_hid_read_endpoint -> ux_slave_endpoint_transfer_request; - /* Protect read. */ - _ux_device_mutex_on(&hid -> ux_device_class_hid_read_mutex); +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Directly use event buffer for transfer. */ + buffer = pos -> ux_device_class_hid_received_event_data; + transfer -> ux_slave_transfer_request_data_pointer = buffer; +#endif /* Issue the transfer request. */ status = _ux_device_stack_transfer_request(transfer, @@ -148,18 +158,25 @@ ULONG temp; continue; } +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Save received event length. */ + temp = transfer -> ux_slave_transfer_request_actual_length; +#else /* Save received event data and length. */ buffer = (UCHAR *)&pos -> ux_device_class_hid_received_event_data; temp = transfer -> ux_slave_transfer_request_actual_length; _ux_utility_memory_copy(buffer, transfer -> ux_slave_transfer_request_data_pointer, temp); /* Use case of memcpy is verified. */ +#endif /* Unprotect read. */ _ux_device_mutex_off(&hid -> ux_device_class_hid_read_mutex); /* Advance the save position. */ - next_pos = (UCHAR *)pos + receiver -> ux_device_class_hid_receiver_event_buffer_size + sizeof(ULONG); + next_pos = (UCHAR *)pos + UX_DEVICE_CLASS_HID_RECEIVED_QUEUE_ITEM_SIZE(receiver); + if (next_pos >= (UCHAR *)receiver -> ux_device_class_hid_receiver_events_end) next_pos = (UCHAR *)receiver -> ux_device_class_hid_receiver_events; receiver -> ux_device_class_hid_receiver_event_save_pos = (UX_DEVICE_CLASS_HID_RECEIVED_EVENT *)next_pos; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_uninitialize.c index c45157d4..b45e9122 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_uninitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_uninitialize PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,6 +66,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_hid_receiver_uninitialize(UX_DEVICE_CLASS_HID_RECEIVER *receiver) @@ -77,6 +80,12 @@ VOID _ux_device_class_hid_receiver_uninitialize(UX_DEVICE_CLASS_HID_RECEIVER *re _ux_utility_thread_delete(&receiver -> ux_device_class_hid_receiver_thread); #endif +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Free cache safe event memory. */ + _ux_utility_memory_free(receiver -> ux_device_class_hid_receiver_events -> ux_device_class_hid_received_event_data); +#endif + /* Free receiver and events memory. */ _ux_utility_memory_free(receiver); } diff --git a/common/usbx_device_classes/src/ux_device_class_hid_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_hid_tasks_run.c index 1bcaf391..4f72f2f7 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_tasks_run.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_tasks_run.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_tasks_run PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_tasks_run(VOID *instance) @@ -80,7 +83,7 @@ UINT _ux_device_class_hid_tasks_run(VOID *instance) UX_SLAVE_CLASS_HID *hid; UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS_HID_EVENT *hid_event; +UX_DEVICE_CLASS_HID_EVENT *hid_event; UX_SLAVE_TRANSFER *trans; ULONG tick, elapsed; UINT status; @@ -122,8 +125,7 @@ UINT status; case UX_STATE_IDLE: /* Check if there is event ready. */ - hid_event = &hid -> ux_device_class_hid_event; - status = _ux_device_class_hid_event_get(hid, hid_event); + status = _ux_device_class_hid_event_check(hid, &hid_event); /* If there is no event, check idle rate. */ if (status != UX_SUCCESS) @@ -153,9 +155,20 @@ UINT status; /* Prepare the request to send event. */ trans = &hid -> ux_device_class_hid_interrupt_endpoint -> ux_slave_endpoint_transfer_request; + +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + + /* Directly use event buffer for transfer. */ + trans -> ux_slave_transfer_request_data_pointer = + hid_event -> ux_device_class_hid_event_buffer; +#else + + /* Copy event data to endpoint buffer. */ _ux_utility_memory_copy(trans -> ux_slave_transfer_request_data_pointer, - hid_event -> ux_device_class_hid_event_buffer, + UX_DEVICE_CLASS_HID_EVENT_BUFFER(hid_event), hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */ +#endif + trans -> ux_slave_transfer_request_requested_length = hid_event -> ux_device_class_hid_event_length; UX_SLAVE_TRANSFER_STATE_RESET(trans); @@ -176,6 +189,9 @@ UINT status; if (status <= UX_STATE_NEXT) { + /* Event handled and the tail should be freed. */ + _ux_device_class_hid_event_free(hid); + /* Next round. */ hid -> ux_device_class_hid_event_state = UX_STATE_RESET; return(UX_STATE_IDLE); diff --git a/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c index afb662a8..4770532e 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_uninitialize PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,11 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added zero copy support, */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -106,6 +111,9 @@ UX_SLAVE_CLASS *class_ptr; #endif /* Free memory for the array. */ +#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) + _ux_utility_memory_free(hid -> ux_device_class_hid_event_array -> ux_device_class_hid_event_buffer); +#endif _ux_utility_memory_free(hid -> ux_device_class_hid_event_array); #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) @@ -122,6 +130,10 @@ UX_SLAVE_CLASS *class_ptr; ux_device_class_hid_receiver_uninitialize(hid -> ux_device_class_hid_receiver); #endif +#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) + _ux_utility_memory_free(hid -> ux_device_class_hid_endpoint_buffer); +#endif + /* Free the resources. */ _ux_utility_memory_free(hid); diff --git a/common/usbx_device_classes/src/ux_device_class_pima_activate.c b/common/usbx_device_classes/src/ux_device_class_pima_activate.c index 7c73659f..1bdf500b 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -76,6 +76,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -136,6 +140,15 @@ UX_SLAVE_ENDPOINT *endpoint_interrupt; pima -> ux_device_class_pima_bulk_out_endpoint = endpoint_out; pima -> ux_device_class_pima_interrupt_endpoint = endpoint_interrupt; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint_in -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_PIMA_BULKIN_BUFFER(pima); + endpoint_out -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_PIMA_BULKOUT_BUFFER(pima); + endpoint_interrupt -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_PIMA_INTERRUPTIN_BUFFER(pima); +#endif + /* Initialize status code. */ pima -> ux_device_class_pima_state = UX_DEVICE_CLASS_PIMA_PHASE_IDLE; pima -> ux_device_class_pima_session_id = 0; diff --git a/common/usbx_device_classes/src/ux_device_class_pima_initialize.c b/common/usbx_device_classes/src/ux_device_class_pima_initialize.c index 67f69fcd..c12ed51d 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_initialize PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,6 +81,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -107,6 +111,20 @@ UX_SLAVE_CLASS *class_ptr; /* Save the address of the PIMA instance inside the PIMA container. */ class_ptr -> ux_slave_class_instance = (VOID *) pima; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Allocate some memory for endpoints. */ + UX_ASSERT(!UX_DEVICE_CLASS_PIMA_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + pima -> ux_device_class_pima_endpoint_buffer = + _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_PIMA_ENDPOINT_BUFFER_SIZE); + if (pima -> ux_device_class_pima_endpoint_buffer == UX_NULL) + { + _ux_utility_memory_free(pima); + return(UX_MEMORY_INSUFFICIENT); + } +#endif + /* Allocate some memory for the thread stack. */ class_ptr -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE); @@ -147,6 +165,9 @@ UX_SLAVE_CLASS *class_ptr; /* Detach instance and free memory. */ class_ptr -> ux_slave_class_instance = UX_NULL; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(pima -> ux_device_class_pima_endpoint_buffer); +#endif _ux_utility_memory_free(pima); /* Return completion status. */ diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_info_get.c b/common/usbx_device_classes/src/ux_device_class_pima_object_info_get.c index 18be07a7..c990b22a 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_object_info_get.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_object_info_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_object_info_get PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_object_info_get(UX_SLAVE_CLASS_PIMA *pima, ULONG object_handle) @@ -125,7 +129,7 @@ ULONG keywords_length; keywords_length; /* Ensure the object info data can fit in the endpoint's data buffer. */ - if (object_info_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (object_info_length > UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH) { /* If trace is enabled, insert this event into the trace buffer. */ diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_prop_desc_get.c b/common/usbx_device_classes/src/ux_device_class_pima_object_prop_desc_get.c index 20075e91..86ed781c 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_object_prop_desc_get.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_object_prop_desc_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_object_prop_desc_get PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,6 +81,10 @@ /* updated status handling, */ /* passed max length to app, */ /* resulting in version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_object_prop_desc_get(UX_SLAVE_CLASS_PIMA *pima, @@ -105,7 +109,7 @@ UCHAR *object_props_desc_end; object_props_desc = transfer_request -> ux_slave_transfer_request_data_pointer; /* Save the end of the object info. */ - object_props_desc_end = object_props_desc + UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + object_props_desc_end = object_props_desc + UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH; /* Fill in the data container type. */ _ux_utility_short_put(object_props_desc + UX_DEVICE_CLASS_PIMA_DATA_HEADER_TYPE, diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_prop_value_get.c b/common/usbx_device_classes/src/ux_device_class_pima_object_prop_value_get.c index 917de74f..e52728d0 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_object_prop_value_get.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_object_prop_value_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_object_prop_value_get PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -84,6 +84,10 @@ /* updated status handling, */ /* passed max length to app, */ /* resulting in version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_object_prop_value_get(UX_SLAVE_CLASS_PIMA *pima, @@ -108,7 +112,7 @@ ULONG object_property_value_length; pima_data_buffer = transfer_request -> ux_slave_transfer_request_data_pointer; /* Save the end of the buffer. */ - pima_data_buffer_end = pima_data_buffer + UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + pima_data_buffer_end = pima_data_buffer + UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH; /* Fill in the data container type. */ _ux_utility_short_put(pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_TYPE, diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_references_get.c b/common/usbx_device_classes/src/ux_device_class_pima_object_references_get.c index a3cf39cd..42a4d4dd 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_object_references_get.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_object_references_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_object_references_get PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,6 +81,10 @@ /* updated status handling, */ /* passed max length to app, */ /* resulting in version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_object_references_get(UX_SLAVE_CLASS_PIMA *pima, @@ -104,7 +108,7 @@ ULONG object_references_length; pima_data_buffer = transfer_request -> ux_slave_transfer_request_data_pointer; /* Save end of buffer. */ - pima_data_buffer_end = pima_data_buffer + UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + pima_data_buffer_end = pima_data_buffer + UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH; /* Fill in the data container type. */ _ux_utility_short_put(pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_TYPE, diff --git a/common/usbx_device_classes/src/ux_device_class_printer_activate.c b/common/usbx_device_classes/src/ux_device_class_printer_activate.c index f004d660..9080a023 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +68,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -104,12 +108,20 @@ UX_SLAVE_ENDPOINT *endpoint; if (endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_IN) { printer -> ux_device_class_printer_endpoint_in = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER(printer); +#endif if (printer -> ux_device_class_printer_endpoint_out) break; } else { printer -> ux_device_class_printer_endpoint_out = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_PRINTER_READ_BUFFER(printer); +#endif if (printer -> ux_device_class_printer_endpoint_in) break; } diff --git a/common/usbx_device_classes/src/ux_device_class_printer_initialize.c b/common/usbx_device_classes/src/ux_device_class_printer_initialize.c index 49722b9f..18385424 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_initialize PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,6 +72,10 @@ /* 10-31-2022 Yajun Xia Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -106,6 +110,19 @@ UINT status; printer -> ux_device_class_printer_parameter.ux_device_class_printer_instance_deactivate = printer_parameter -> ux_device_class_printer_instance_deactivate; printer -> ux_device_class_printer_parameter.ux_device_class_printer_soft_reset = printer_parameter -> ux_device_class_printer_soft_reset; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Allocate endpoint buffer. */ + UX_ASSERT(!UX_DEVICE_CLASS_PRINTER_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + printer -> ux_device_class_printer_endpoint_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, + UX_CACHE_SAFE_MEMORY, UX_DEVICE_CLASS_PRINTER_ENDPOINT_BUFFER_SIZE); + if (printer -> ux_device_class_printer_endpoint_buffer == UX_NULL) + { + _ux_utility_memory_free(printer); + return(UX_MEMORY_INSUFFICIENT); + } +#endif + #if !defined(UX_DEVICE_STANDALONE) /* Create the Mutex for each endpoint as multiple threads cannot access each pipe at the same time. */ status = _ux_utility_mutex_create(&printer -> ux_device_class_printer_endpoint_in_mutex, "ux_device_class_printer_in_mutex"); @@ -115,6 +132,9 @@ UINT status; { /* Free the resources. */ +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(printer -> ux_device_class_printer_endpoint_buffer); +#endif _ux_utility_memory_free(printer); /* Return fatal error. */ @@ -132,6 +152,9 @@ UINT status; _ux_device_mutex_delete(&printer -> ux_device_class_printer_endpoint_in_mutex); /* Free the resources. */ +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(printer -> ux_device_class_printer_endpoint_buffer); +#endif _ux_utility_memory_free(printer); /* Return fatal error. */ diff --git a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c index 6a4e9560..89f5c37f 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_uninitialize PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* 10-31-2022 Yajun Xia Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -100,6 +104,9 @@ UX_SLAVE_CLASS *class_ptr; _ux_device_mutex_delete(&printer -> ux_device_class_printer_endpoint_out_mutex); #endif /* Free the resources. */ +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(printer -> ux_device_class_printer_endpoint_buffer); +#endif _ux_utility_memory_free(printer); } diff --git a/common/usbx_device_classes/src/ux_device_class_printer_write.c b/common/usbx_device_classes/src/ux_device_class_printer_write.c index 924be2ad..f2df267a 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_write.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_write.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_write PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,10 @@ /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ /* added auto ZLP support, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_write(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer, @@ -143,16 +147,16 @@ UINT status = 0; } /* Check if we need more transactions. */ - local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + local_host_length = UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE; while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED && requested_length != 0) { /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE) /* We have too much to transfer. */ - local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + local_requested_length = UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE; else { @@ -167,7 +171,7 @@ UINT status = 0; #else /* Assume expected more so stack appends ZLP if needed. */ - local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; + local_host_length = UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE + 1; #endif } diff --git a/common/usbx_device_classes/src/ux_device_class_printer_write_run.c b/common/usbx_device_classes/src/ux_device_class_printer_write_run.c index 9e740c45..034fcd74 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_write_run.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_write_run.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_write_run PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Yajun Xia, Microsoft Corporation */ @@ -78,6 +78,10 @@ /* DATE NAME DESCRIPTION */ /* */ /* 10-31-2022 Yajun Xia Initial Version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_write_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer, @@ -140,7 +144,7 @@ UINT status = 0; printer -> ux_device_class_printer_write_buffer = buffer; printer -> ux_device_class_printer_write_requested_length = requested_length; printer -> ux_device_class_printer_write_actual_length = 0; - printer -> ux_device_class_printer_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + printer -> ux_device_class_printer_write_host_length = UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE; if (requested_length == 0) zlp = UX_TRUE; @@ -161,11 +165,11 @@ UINT status = 0; } /* Check if we have enough in the local buffer. */ - if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (requested_length > UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE) /* We have too much to transfer. */ printer -> ux_device_class_printer_write_transfer_length = - UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE; else { @@ -180,7 +184,7 @@ UINT status = 0; #else /* Assume expected more than transfer to let stack append ZLP if needed. */ - printer -> ux_device_class_printer_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; + printer -> ux_device_class_printer_write_host_length = UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE + 1; #endif } diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_activate.c b/common/usbx_device_classes/src/ux_device_class_rndis_activate.c index c8e3f0c0..141cc2e3 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_rndis_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -138,23 +142,40 @@ ULONG physical_address_lsw; /* Look at type. */ if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_INTERRUPT_ENDPOINT) - + { + /* We have found the interrupt endpoint, save it. */ rndis -> ux_slave_class_rndis_interrupt_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_RNDIS_INTERRUPTIN_BUFFER(rndis); +#endif + } else - + { + /* We have found the bulk in endpoint, save it. */ rndis -> ux_slave_class_rndis_bulkin_endpoint = endpoint; - +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER(rndis); +#endif + } } else { /* Look at type for out endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT) - + { + /* We have found the bulk out endpoint, save it. */ rndis -> ux_slave_class_rndis_bulkout_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER(rndis); +#endif + } } /* Next endpoint. */ diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c index 92c11151..c2c0e61d 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_bulkin_thread PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -88,6 +88,10 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* used NX API to copy data, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_rndis_bulkin_thread(ULONG rndis_class) @@ -157,7 +161,7 @@ ULONG copied; transfer_length = current_packet -> nx_packet_length + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH; /* Is there enough space for this packet in the transfer buffer? */ - if (transfer_length <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + if (transfer_length <= UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE) { /* Copy the packet in the transfer descriptor buffer. */ @@ -179,7 +183,7 @@ ULONG copied; UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_PACKET_TRANSMIT, rndis, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) /* Send the request to the device controller. */ - status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_RNDIS_ETHERNET_PACKET_SIZE + 1); + status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE + 1); } /* Check for error. */ diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c index 1fcc35a1..e4c3b508 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_bulkout_thread PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -88,6 +88,10 @@ /* used NX API to copy data, */ /* used linked NX IP pool, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_rndis_bulkout_thread(ULONG rndis_class) @@ -153,7 +157,7 @@ USB_NETWORK_DEVICE_TYPE *ux_nx_device; { /* And length. */ - transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH; + transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE; transfer_request -> ux_slave_transfer_request_actual_length = 0; /* Memorize this packet at the beginning of the queue. */ @@ -163,8 +167,8 @@ USB_NETWORK_DEVICE_TYPE *ux_nx_device; packet -> nx_packet_queue_next = UX_NULL; /* Send the request to the device controller. */ - status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH, - UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH); + status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE, + UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE); /* Check the completion code. */ if (status == UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c index cd2ccff6..582b7746 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c @@ -140,6 +140,8 @@ ULONG ux_device_class_rndis_oid_supported_list[UX_DEVICE_CLASS_RNDIS_OID_SUPPORT /* removed internal NX pool, */ /* resulting in version 6.2.0 */ /* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ /* checked compile options, */ /* resulting in version 6.x */ /* */ @@ -158,8 +160,12 @@ UINT status; /* Compile option checks. */ - UX_ASSERT(UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH); UX_ASSERT(UX_DEVICE_CLASS_RNDIS_MAX_CONTROL_RESPONSE_LENGTH <= UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH); +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 0 + UX_ASSERT(UX_DEVICE_CLASS_RNDIS_BULKOUT_BUFFER_SIZE <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH); + UX_ASSERT(UX_DEVICE_CLASS_RNDIS_BULKIN_BUFFER_SIZE <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH); + UX_ASSERT(UX_DEVICE_CLASS_RNDIS_INTERRUPTIN_BUFFER_SIZE <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH); +#endif /* Get the class container. */ class_ptr = command -> ux_slave_class_command_class_ptr; @@ -201,10 +207,26 @@ UINT status; /* Store the rest of the parameters as they are in the local instance. */ _ux_utility_memory_copy(&rndis -> ux_slave_class_rndis_parameter, rndis_parameter, sizeof (UX_SLAVE_CLASS_RNDIS_PARAMETER)); /* Use case of memcpy is verified. */ +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Allocate memory for endpoints. */ + UX_ASSERT(!UX_DEVICE_CLASS_RNDIS_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + rndis -> ux_device_class_rndis_endpoint_buffer = _ux_utility_memory_allocate( + UX_NO_ALIGN,UX_CACHE_SAFE_MEMORY, + UX_DEVICE_CLASS_RNDIS_ENDPOINT_BUFFER_SIZE); + if (rndis -> ux_device_class_rndis_endpoint_buffer == UX_NULL) + status = UX_MEMORY_INSUFFICIENT; +#else + status = UX_SUCCESS; +#endif + /* Create a mutex to protect the RNDIS thread and the application messing up the transmit queue. */ - status = _ux_utility_mutex_create(&rndis -> ux_slave_class_rndis_mutex, "ux_slave_class_rndis_mutex"); - if (status != UX_SUCCESS) - status = UX_MUTEX_ERROR; + if (status == UX_SUCCESS) + { + status = _ux_utility_mutex_create(&rndis -> ux_slave_class_rndis_mutex, "ux_slave_class_rndis_mutex"); + if (status != UX_SUCCESS) + status = UX_MUTEX_ERROR; + } /* Allocate some memory for the interrupt thread stack. */ if (status == UX_SUCCESS) @@ -356,6 +378,11 @@ UINT status; if (rndis -> ux_slave_class_rndis_mutex.tx_mutex_id != 0) _ux_device_mutex_delete(&rndis -> ux_slave_class_rndis_mutex); +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + if (rndis -> ux_device_class_rndis_endpoint_buffer != UX_NULL) + _ux_utility_memory_free(rndis -> ux_device_class_rndis_endpoint_buffer); +#endif + /* Free memory for rndis instance. */ _ux_utility_memory_free(rndis); diff --git a/common/usbx_device_classes/src/ux_device_class_storage_activate.c b/common/usbx_device_classes/src/ux_device_class_storage_activate.c index e0762300..6b34c2a8 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -132,6 +136,15 @@ UX_SLAVE_ENDPOINT *endpoint; storage -> ux_device_class_storage_ep_out = endpoint -> ux_slave_endpoint_next_endpoint; } +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Assign endpoint buffers. */ + storage -> ux_device_class_storage_ep_in -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = UX_DEVICE_CLASS_STORAGE_BULKIN_BUFFER(storage); + storage -> ux_device_class_storage_ep_out -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = UX_DEVICE_CLASS_STORAGE_BULKOUT_BUFFER(storage); +#endif + /* Reset states. */ storage -> ux_device_class_storage_buffer[0] = storage -> ux_device_class_storage_ep_out -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer; diff --git a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c index f7990892..b9e46e99 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c @@ -41,7 +41,7 @@ UCHAR _ux_system_slave_class_storage_product_serial[] = "123 /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_initialize PORTABLE C */ -/* 6.1.10 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,10 @@ UCHAR _ux_system_slave_class_storage_product_serial[] = "123 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -112,30 +116,41 @@ ULONG lun_index; if (storage == UX_NULL) return(UX_MEMORY_INSUFFICIENT); -#if !defined(UX_DEVICE_STANDALONE) +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 - /* Allocate some memory for the thread stack. */ - class_inst -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE); + /* Allocate bulk endpoint buffer. */ + UX_ASSERT(!UX_DEVICE_CLASS_STORAGE_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); + storage -> ux_device_class_storage_endpoint_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, + UX_CACHE_SAFE_MEMORY, UX_DEVICE_CLASS_STORAGE_ENDPOINT_BUFFER_SIZE); +#else + status = UX_SUCCESS; +#endif - /* If it's OK, create thread. */ - if (class_inst -> ux_slave_class_thread_stack != UX_NULL) +#if !defined(UX_DEVICE_STANDALONE) - /* This instance needs to be running in a different thread. So start - a new thread. We pass a pointer to the class to the new thread. This thread - does not start until we have a instance of the class. */ - status = _ux_device_thread_create(&class_inst -> ux_slave_class_thread, "ux_slave_storage_thread", - _ux_device_class_storage_thread, - (ULONG) (ALIGN_TYPE) class_inst, (VOID *) class_inst -> ux_slave_class_thread_stack, - UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, - UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); - else - status = UX_MEMORY_INSUFFICIENT; + /* Allocate some memory for the thread stack. */ + if (status == UX_SUCCESS) + { + class_inst -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE); + + /* If it's OK, create thread. */ + if (class_inst -> ux_slave_class_thread_stack != UX_NULL) + + /* This instance needs to be running in a different thread. So start + a new thread. We pass a pointer to the class to the new thread. This thread + does not start until we have a instance of the class. */ + status = _ux_device_thread_create(&class_inst -> ux_slave_class_thread, "ux_slave_storage_thread", + _ux_device_class_storage_thread, + (ULONG) (ALIGN_TYPE) class_inst, (VOID *) class_inst -> ux_slave_class_thread_stack, + UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, + UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); + else + status = UX_MEMORY_INSUFFICIENT; + } #else /* Save tasks run entry. */ class_inst -> ux_slave_class_task_function = _ux_device_class_storage_tasks_run; - - status = UX_SUCCESS; #endif /* If thread resources allocated, go on. */ @@ -216,6 +231,11 @@ ULONG lun_index; _ux_utility_memory_free(&class_inst -> ux_slave_class_thread_stack); #endif +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + if (storage -> ux_device_class_storage_endpoint_buffer != UX_NULL) + _ux_utility_memory_free(storage -> ux_device_class_storage_endpoint_buffer); +#endif + /* Free instance. */ _ux_utility_memory_free(storage); diff --git a/common/usbx_device_classes/src/ux_device_class_storage_thread.c b/common/usbx_device_classes/src/ux_device_class_storage_thread.c index 0ff75a75..6a2e873a 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_thread.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_thread PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -127,6 +127,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_storage_thread(ULONG storage_class) @@ -190,6 +194,17 @@ UCHAR *cbw_cb; endpoint_out = endpoint_in -> ux_slave_endpoint_next_endpoint; } +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + + /* Assign endpoint buffers. */ + endpoint_out -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_STORAGE_BULKOUT_BUFFER(storage); + endpoint_in -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + UX_DEVICE_CLASS_STORAGE_BULKIN_BUFFER(storage); +#endif + /* All SCSI commands are on the endpoint OUT, from the host. */ transfer_request = &endpoint_out -> ux_slave_endpoint_transfer_request; diff --git a/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c index 5931caf2..59a7453e 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_uninitialize PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -101,6 +105,10 @@ UX_SLAVE_CLASS *class_ptr; _ux_utility_memory_free(class_ptr -> ux_slave_class_thread_stack); #endif +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(storage -> ux_device_class_storage_endpoint_buffer); +#endif + /* Free the resources. */ _ux_utility_memory_free(storage); } diff --git a/common/usbx_device_classes/src/ux_device_class_video_change.c b/common/usbx_device_classes/src/ux_device_class_video_change.c index 9bf5e016..443fb9f6 100644 --- a/common/usbx_device_classes/src/ux_device_class_video_change.c +++ b/common/usbx_device_classes/src/ux_device_class_video_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_video_change PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_video_change(UX_SLAVE_CLASS_COMMAND *command) @@ -145,6 +149,11 @@ ULONG stream_index; /* Save it. */ stream -> ux_device_class_video_stream_endpoint = endpoint; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + endpoint -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_data_pointer = + stream -> ux_device_class_video_stream_endpoint_buffer; +#endif break; } diff --git a/common/usbx_device_classes/src/ux_device_class_video_initialize.c b/common/usbx_device_classes/src/ux_device_class_video_initialize.c index 814b1873..12e39bc0 100644 --- a/common/usbx_device_classes/src/ux_device_class_video_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_video_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_video_initialize PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_video_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -162,6 +166,16 @@ ULONG i; stream -> ux_device_class_video_stream_transfer_pos = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)stream -> ux_device_class_video_stream_buffer; stream -> ux_device_class_video_stream_access_pos = stream -> ux_device_class_video_stream_transfer_pos; +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + stream -> ux_device_class_video_stream_endpoint_buffer = _ux_utility_memory_allocate( + UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + stream -> ux_device_class_video_stream_payload_buffer_size); + if (stream -> ux_device_class_video_stream_endpoint_buffer == UX_NULL) + { + status = UX_MEMORY_INSUFFICIENT; + break; + } +#endif #if !defined(UX_DEVICE_STANDALONE) @@ -248,7 +262,10 @@ ULONG i; if (stream -> ux_device_class_video_stream_thread_stack) _ux_utility_memory_free(stream -> ux_device_class_video_stream_thread_stack); #endif - +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + if (stream -> ux_device_class_video_stream_endpoint_buffer) + _ux_utility_memory_free(stream -> ux_device_class_video_stream_endpoint_buffer); +#endif if (stream -> ux_device_class_video_stream_buffer) _ux_utility_memory_free(stream -> ux_device_class_video_stream_buffer); stream ++; diff --git a/common/usbx_device_classes/src/ux_device_class_video_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_video_uninitialize.c index 9eebf2ee..1feb1aa5 100644 --- a/common/usbx_device_classes/src/ux_device_class_video_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_video_uninitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_video_uninitialize PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -65,6 +65,10 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added a new mode to manage */ +/* endpoint buffer in classes, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_video_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -93,6 +97,9 @@ ULONG i; #if !defined(UX_DEVICE_STANDALONE) _ux_utility_thread_delete(&stream -> ux_device_class_video_stream_thread); _ux_utility_memory_free(stream -> ux_device_class_video_stream_thread_stack); +#endif +#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 + _ux_utility_memory_free(stream -> ux_device_class_video_stream_endpoint_buffer); #endif _ux_utility_memory_free(stream -> ux_device_class_video_stream_buffer);