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.
This commit is contained in:
Chaoqiong Xiao 2023-06-30 02:15:38 +00:00
parent ef2fa7717b
commit 7c928b43db
82 changed files with 2050 additions and 306 deletions

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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. */

View File

@ -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. */

View File

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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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. */

View File

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

View File

@ -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);

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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. */

View File

@ -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 */

View File

@ -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])

View File

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

View File

@ -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

View File

@ -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. */

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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
}
/**************************************************************************/

View File

@ -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) */

View File

@ -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);

View File

@ -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 */
}

View File

@ -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
}
/**************************************************************************/

View File

@ -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);

View File

@ -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. */

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

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

View File

@ -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, &current_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)
{

View File

@ -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. */

View File

@ -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,13 +103,23 @@ 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;

View File

@ -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)

View File

@ -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);

View File

@ -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
}

View File

@ -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. */

View File

@ -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);
}

View File

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

View File

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

View File

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

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

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

View File

@ -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. */

View File

@ -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. */

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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. */

View File

@ -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);
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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. */

View File

@ -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. */

View File

@ -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)

View File

@ -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);

View File

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

View File

@ -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 UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
/* 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 !defined(UX_DEVICE_STANDALONE)
/* 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);
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)
/* 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;
/* 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);

View File

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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 ++;

View File

@ -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);