diff options
23 files changed, 712 insertions, 138 deletions
diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h index d0f1f93..872f6cc 100644 --- a/common/core/inc/ux_api.h +++ b/common/core/inc/ux_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* ux_api.h PORTABLE C */ -/* 6.1.2 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +68,9 @@ /* modified HCD status code, */ /* fixed compile warnings, */ /* resulting in version 6.1.2 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* added BOS support, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ @@ -202,7 +205,7 @@ typedef signed char SCHAR; #define AZURE_RTOS_USBX #define USBX_MAJOR_VERSION 6 #define USBX_MINOR_VERSION 1 -#define USBX_PATCH_VERSION 2 +#define USBX_PATCH_VERSION 3 /* Macros for concatenating tokens, where UX_CONCATn concatenates n tokens. */ @@ -945,9 +948,28 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_OTHER_SPEED_DESCRIPTOR_ITEM 7u #define UX_OTG_DESCRIPTOR_ITEM 9u #define UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ITEM 11u +#define UX_BOS_DESCRIPTOR_ITEM 15u +#define UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM 16u #define UX_DFU_FUNCTIONAL_DESCRIPTOR_ITEM 0x21u #define UX_HUB_DESCRIPTOR_ITEM 0x29u +#define UX_CAPABILITY_WIRELESS_USB 0x01u +#define UX_CAPABILITY_USB_2_0_EXTENSION 0x02u +#define UX_CAPABILITY_SUPERSPEED_USB 0x03u +#define UX_CAPABILITY_CONTAINER_ID 0x04u +#define UX_CAPABILITY_PLATFORM 0x05u +#define UX_CAPABILITY_POWER_DELIVERY 0x06u +#define UX_CAPABILITY_BATTERY_INFO 0x07u +#define UX_CAPABILITY_PD_CONSUMER_PORT 0x08u +#define UX_CAPABILITY_PD_PROVIDER_PORT 0x09u +#define UX_CAPABILITY_SUPERSPEED_PLUS 0x0Au +#define UX_CAPABILITY_PRECISION_TIME_MEASUREMENT 0x0Bu +#define UX_CAPABILITY_WIRELESS_USB_EXT 0x0Cu +#define UX_CAPABILITY_BILLBOARD 0x0Du +#define UX_CAPABILITY_AUTHENTICATION 0x0Eu +#define UX_CAPABILITY_BILLBOARD_EX 0x0Fu +#define UX_CAPABILITY_CONFIGURATION_SUMMARY 0x10u + #define UX_CONTROL_TRANSFER_TIMEOUT 1000 #define UX_NON_CONTROL_TRANSFER_TIMEOUT 5000 @@ -957,6 +979,15 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_ENUMERATION_THREAD_WAIT 200 +/* USB Billboard constants. */ + +#define UX_CLASS_BILLBOARD_CLASS 0x11 +#define UX_CLASS_BILLBOARD_SUBCLASS 0x00 +#define UX_CLASS_BILLBOARD_PROTOCOL 0x00 +#define UX_CLASS_BILLBOARD_DESCRIPTOR_BILLBOARD 0x0D +#define UX_CLASS_BILLBOARD_DESCRIPTOR_ALTERNATE_MODE 0x0F +#define UX_CLASS_BILLBOARD_MAX_NUM_ALT_MODE 0x34 + /* USBX 5.8 BACKWARD COMPATIBILITY DEFINITIONS. THESE DEFINITIONS ARE NOW OBSOLETE BUT DEFINED HERE FOR COMPATIBILITY REASONS. */ @@ -1717,6 +1748,49 @@ typedef struct UX_STRING_DESCRIPTOR_STRUCT #define UX_STRING_DESCRIPTOR_LENGTH 4 +/* Define USBX BOS Descriptor structure. */ + +typedef struct UX_BOS_DESCRIPTOR_STRUCT +{ + ULONG bLength; + ULONG bDescriptorType; + ULONG wTotalLength; + ULONG bNumDeviceCaps; +} UX_BOS_DESCRIPTOR; + +#define UX_BOS_DESCRIPTOR_ENTRIES 4 +#define UX_BOS_DESCRIPTOR_LENGTH 5 + + +/* Define USBX USB 2.0 Descriptor structure. */ + +typedef struct UX_USB_2_0_EXTENSION_DESCRIPTOR_STRUCT +{ + ULONG bLength; + ULONG bDescriptorType; + ULONG bDevCapabilityType; + ULONG bmAttributes; +} UX_USB_2_0_EXTENSION_DESCRIPTOR; + +#define UX_USB_2_0_EXTENSION_DESCRIPTOR_ENTRIES 4 +#define UX_USB_2_0_EXTENSION_DESCRIPTOR_LENGTH 7 + + +/* Define USBX Container ID Descriptor structure. */ + +typedef struct UX_CONTAINER_ID_DESCRIPTOR_STRUCT +{ + ULONG bLength; + ULONG bDescriptorType; + ULONG bDevCapabilityType; + ULONG bReserved; + ULONG ContainerID[4]; +} UX_CONTAINER_ID_DESCRIPTOR; + +#define UX_CONTAINER_ID_DESCRIPTOR_ENTRIES 5 +#define UX_CONTAINER_ID_DESCRIPTOR_LENGTH 20 + + /* Define USBX DFU functional descriptor. */ typedef struct UX_DFU_FUNCTIONAL_DESCRIPTOR_STRUCT diff --git a/common/core/inc/ux_system.h b/common/core/inc/ux_system.h index ac46308..5c64ab2 100644 --- a/common/core/inc/ux_system.h +++ b/common/core/inc/ux_system.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_system.h PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -43,6 +43,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* added BOS support, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ @@ -86,6 +89,10 @@ extern UCHAR _ux_system_class_pima_storage_structure[]; extern UCHAR _ux_system_class_pima_object_structure[]; extern UCHAR _ux_system_ecm_interface_descriptor_structure[]; +extern UCHAR _ux_system_bos_descriptor_structure[]; +extern UCHAR _ux_system_usb_2_0_extension_descriptor_structure[]; +extern UCHAR _ux_system_container_id_descriptor_structure[]; + extern UINT _ux_system_host_hcd_periodic_tree_entries[32]; extern UCHAR _ux_system_host_class_hub_name[]; diff --git a/common/core/src/ux_device_stack_descriptor_send.c b/common/core/src/ux_device_stack_descriptor_send.c index a165810..3bf18ec 100644 --- a/common/core/src/ux_device_stack_descriptor_send.c +++ b/common/core/src/ux_device_stack_descriptor_send.c @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_descriptor_send PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,9 @@ /* logic, verified memset and */ /* memcpy cases, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* added BOS support, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_stack_descriptor_send(ULONG descriptor_type, ULONG request_index, ULONG host_length) @@ -93,12 +96,15 @@ ULONG descriptor_index; ULONG parsed_descriptor_index; UX_SLAVE_TRANSFER *transfer_request; UX_CONFIGURATION_DESCRIPTOR configuration_descriptor; +#ifndef UX_BOS_SUPPORT_DISABLE +UX_BOS_DESCRIPTOR bos_descriptor; +#endif UX_SLAVE_ENDPOINT *endpoint; UCHAR *device_framework; UCHAR *device_framework_end; ULONG device_framework_length; ULONG descriptor_length; -ULONG configuration_descriptor_length; +ULONG target_descriptor_length; UINT status = UX_ERROR; ULONG length; UCHAR *string_memory; @@ -195,6 +201,10 @@ ULONG string_length; } break; +#ifndef UX_BOS_SUPPORT_DISABLE + case UX_BOS_DESCRIPTOR_ITEM: + /* Fall through. */ +#endif case UX_OTHER_SPEED_DESCRIPTOR_ITEM: /* Fall through. */ case UX_CONFIGURATION_DESCRIPTOR_ITEM: @@ -226,64 +236,63 @@ ULONG string_length; /* Get descriptor length. */ descriptor_length = (ULONG) *device_framework; - /* Check if this is a configuration descriptor. We are cheating here. Instead of creating - a OTHER SPEED descriptor, we simply scan the configuration descriptor for the Full Speed - framework and return this configuration after we manually changed the configuration descriptor - item into a Other Speed Descriptor. */ - if (*(device_framework + 1) == UX_CONFIGURATION_DESCRIPTOR_ITEM) - { +#ifndef UX_BOS_SUPPORT_DISABLE - /* Check the index. It must be the same as the one requested. */ - if (parsed_descriptor_index == descriptor_index) + /* Check if we are finding BOS descriptor. */ + if (descriptor_type == UX_BOS_DESCRIPTOR_ITEM) + { + if (*(device_framework + 1) == UX_BOS_DESCRIPTOR_ITEM) { - /* Parse the configuration descriptor. */ + /* Parse the BOS descriptor. */ _ux_utility_descriptor_parse(device_framework, - _ux_system_configuration_descriptor_structure, - UX_CONFIGURATION_DESCRIPTOR_ENTRIES, - (UCHAR *) &configuration_descriptor); + _ux_system_bos_descriptor_structure, + UX_BOS_DESCRIPTOR_ENTRIES, + (UCHAR *) &bos_descriptor); - /* Get the length of entire configuration descriptor. */ - configuration_descriptor_length = configuration_descriptor.wTotalLength; + /* Get the length of entire BOS descriptor. */ + target_descriptor_length = bos_descriptor.wTotalLength; - /* Ensure the host does not demand a length beyond our descriptor (Windows does that) - and do not return more than what is allowed. */ - if (configuration_descriptor_length < host_length) - length = configuration_descriptor_length; - else - length = host_length; + /* Descriptor is found. */ + status = UX_SUCCESS; + break; + } + } + else +#endif - /* Check buffer length, since total descriptors length may exceed buffer... */ - if (length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH) - { - /* Error trap. */ - _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DEVICE_STACK, UX_MEMORY_INSUFFICIENT); + { - /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, device, 0, 0, UX_TRACE_ERRORS, 0, 0) + /* Check if this is a configuration descriptor. We are cheating here. Instead of creating + a OTHER SPEED descriptor, we simply scan the configuration descriptor for the Full Speed + framework and return this configuration after we manually changed the configuration descriptor + item into a Other Speed Descriptor. */ + if (*(device_framework + 1) == UX_CONFIGURATION_DESCRIPTOR_ITEM) + { - /* Stall the endpoint. */ - status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint); - break; - } + /* Check the index. It must be the same as the one requested. */ + if (parsed_descriptor_index == descriptor_index) + { - /* Copy the device descriptor into the transfer request memory. */ - _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, - device_framework, length); /* Use case of memcpy is verified. */ + /* Parse the configuration descriptor. */ + _ux_utility_descriptor_parse(device_framework, + _ux_system_configuration_descriptor_structure, + UX_CONFIGURATION_DESCRIPTOR_ENTRIES, + (UCHAR *) &configuration_descriptor); - /* Now we need to hack the found descriptor because this request expect a OTHER_SPEED - descriptor instead of the regular CONFIGURATION descriptor. */ - *(transfer_request -> ux_slave_transfer_request_data_pointer + 1) = (UCHAR)descriptor_type; + /* Get the length of entire configuration descriptor. */ + target_descriptor_length = configuration_descriptor.wTotalLength; - /* We can return the configuration descriptor. */ - status = _ux_device_stack_transfer_request(transfer_request, length, host_length); - break; - } - else - { + /* Descriptor is found. */ + status = UX_SUCCESS; + break; + } + else + { - /* There may be more configuration descriptors in this framework. */ - parsed_descriptor_index++; + /* There may be more configuration descriptors in this framework. */ + parsed_descriptor_index++; + } } } @@ -293,6 +302,43 @@ ULONG string_length; /* Point to the next descriptor. */ device_framework += descriptor_length; } + + /* Send the descriptor. */ + if (status == UX_SUCCESS) + { + + /* Ensure the host does not demand a length beyond our descriptor (Windows does that) + and do not return more than what is allowed. */ + if (target_descriptor_length < host_length) + length = target_descriptor_length; + else + length = host_length; + + /* Check buffer length, since total descriptors length may exceed buffer... */ + if (length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DEVICE_STACK, UX_MEMORY_INSUFFICIENT); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, device, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* Stall the endpoint. */ + status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint); + break; + } + + /* Copy the device descriptor into the transfer request memory. */ + _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, + device_framework, length); /* Use case of memcpy is verified. */ + + /* Now we need to hack the found descriptor because this request expect a requested + descriptor type instead of the regular descriptor. */ + *(transfer_request -> ux_slave_transfer_request_data_pointer + 1) = (UCHAR)descriptor_type; + + /* We can return the configuration descriptor. */ + status = _ux_device_stack_transfer_request(transfer_request, length, host_length); + } break; case UX_STRING_DESCRIPTOR_ITEM: diff --git a/common/core/src/ux_hcd_sim_host_request_bulk_transfer.c b/common/core/src/ux_hcd_sim_host_request_bulk_transfer.c index 4036ba3..73d5289 100644 --- a/common/core/src/ux_hcd_sim_host_request_bulk_transfer.c +++ b/common/core/src/ux_hcd_sim_host_request_bulk_transfer.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_sim_host_request_bulk_transfer PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed ZLP sending, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_hcd_sim_host_request_bulk_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request) @@ -109,7 +112,7 @@ UCHAR * data_pointer; transfer_request_payload_length = transfer_request -> ux_transfer_request_requested_length; data_pointer = transfer_request -> ux_transfer_request_data_pointer; - while (transfer_request_payload_length != 0) + do { if (transfer_request_payload_length > UX_HCD_SIM_HOST_MAX_PAYLOAD) @@ -181,7 +184,7 @@ UCHAR * data_pointer; previous_td -> ux_sim_host_td_next_td_transfer_request = data_td; previous_td = data_td; } - } + } while (transfer_request_payload_length != 0); /* At this stage, the Head and Tail in the ED are still the same and the host simulator controller will skip this ED until we have hooked the new tail TD. */ diff --git a/common/core/src/ux_system_initialize.c b/common/core/src/ux_system_initialize.c index 17c0d3a..214701e 100644 --- a/common/core/src/ux_system_initialize.c +++ b/common/core/src/ux_system_initialize.c @@ -59,13 +59,17 @@ UCHAR _ux_system_class_pima_storage_structure[] = {2,2 UCHAR _ux_system_class_pima_object_structure[] = {4,2,2,4,2,4,4,4,4,4,4,4,2,4,4}; UCHAR _ux_system_ecm_interface_descriptor_structure[] = {1,1,1,1,4,2,2,1}; +UCHAR _ux_system_bos_descriptor_structure[] = {1,1,2,1}; +UCHAR _ux_system_usb_2_0_extension_descriptor_structure[] = {1,1,1,4}; +UCHAR _ux_system_container_id_descriptor_structure[] = {1,1,1,1,4,4,4,4}; + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_system_initialize PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -105,6 +109,9 @@ UCHAR _ux_system_ecm_interface_descriptor_structure[] = {1,1 /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* added BOS support, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_system_initialize(VOID *regular_memory_pool_start, ULONG regular_memory_size, diff --git a/common/usbx_device_classes/inc/ux_device_class_hid.h b/common/usbx_device_classes/inc/ux_device_class_hid.h index 05e3833..fc86bdd 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_hid.h PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -46,6 +46,10 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* added Get/Set Protocol */ +/* request support, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ @@ -79,6 +83,11 @@ #define UX_DEVICE_CLASS_HID_REPORT_TYPE_OUTPUT 0x2 #define UX_DEVICE_CLASS_HID_REPORT_TYPE_FEATURE 0x3 +/* Define HID Protocols. */ + +#define UX_DEVICE_CLASS_HID_PROTOCOL_BOOT 0 +#define UX_DEVICE_CLASS_HID_PROTOCOL_REPORT 1 + /* Define HID event info structure. */ #ifndef UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH @@ -130,6 +139,7 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT UX_EVENT_FLAGS_GROUP ux_device_class_hid_event_flags_group; 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; @@ -171,8 +181,7 @@ UINT _ux_device_class_hid_report_set(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_ ULONG request_index, ULONG host_length); UINT _ux_device_class_hid_report_get(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_type, ULONG request_index, ULONG host_length); - - + /* Define Device HID Class API prototypes. */ #define ux_device_class_hid_entry _ux_device_class_hid_entry @@ -181,5 +190,7 @@ UINT _ux_device_class_hid_report_get(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_ #define ux_device_class_hid_report_set _ux_device_class_hid_report_set #define ux_device_class_hid_report_get _ux_device_class_hid_report_get +#define ux_device_class_hid_protocol_get(hid) (hid -> ux_device_class_hid_protocol) + #endif diff --git a/common/usbx_device_classes/inc/ux_device_class_storage.h b/common/usbx_device_classes/inc/ux_device_class_storage.h index e658da8..c55bbec 100644 --- a/common/usbx_device_classes/inc/ux_device_class_storage.h +++ b/common/usbx_device_classes/inc/ux_device_class_storage.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_storage.h PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,9 @@ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* optimized command logic, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ @@ -450,6 +453,11 @@ typedef struct UX_SLAVE_CLASS_STORAGE_STRUCT UX_SLAVE_INTERFACE *ux_slave_class_storage_interface; 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; + UCHAR ux_slave_class_storage_cbw_flags; + UCHAR ux_slave_class_storage_cbw_lun; + UCHAR ux_slave_class_storage_reserved[2]; + ULONG ux_slave_class_storage_csw_residue; ULONG ux_slave_class_storage_csw_status; VOID (*ux_slave_class_storage_instance_activate)(VOID *); VOID (*ux_slave_class_storage_instance_deactivate)(VOID *); diff --git a/common/usbx_device_classes/src/ux_device_class_hid_activate.c b/common/usbx_device_classes/src/ux_device_class_hid_activate.c index 749b7de..0d3b12c 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_activate PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -65,6 +65,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* added Get/Set Protocol */ +/* request support, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -113,6 +117,9 @@ UX_SLAVE_ENDPOINT *endpoint_interrupt; if (endpoint_interrupt == UX_NULL) return (UX_ERROR); + /* Default HID protocol is report protocol. */ + hid -> ux_device_class_hid_protocol = UX_DEVICE_CLASS_HID_PROTOCOL_REPORT; + /* Save the endpoint in the hid instance. */ hid -> ux_device_class_hid_interrupt_endpoint = endpoint_interrupt; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c index a2a58b5..f5c9d10 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_control_request PORTABLE C */ -/* 6.1.2 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +77,10 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* fixed compile warnings 64b, */ /* resulting in version 6.1.2 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* added Get/Set Protocol */ +/* request support, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -183,9 +187,17 @@ UX_SLAVE_CLASS_HID *hid; break; case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL: + + /* Send the protocol. */ + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)hid -> ux_device_class_hid_protocol; + _ux_device_stack_transfer_request(transfer_request, 1, request_length); + break; + case UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL: - /* Not supported now. */ + /* Accept the protocol. */ + hid -> ux_device_class_hid_protocol = request_value; + break; default: diff --git a/common/usbx_device_classes/src/ux_device_class_storage_control_request.c b/common/usbx_device_classes/src/ux_device_class_storage_control_request.c index bd9925d..aec7681 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_control_request.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_control_request PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,9 @@ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* optimized command logic, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -79,6 +82,8 @@ UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; UX_SLAVE_CLASS *class; ULONG request; +ULONG request_value; +ULONG request_length; UX_SLAVE_CLASS_STORAGE *storage; UX_SLAVE_INTERFACE *interface; UX_SLAVE_ENDPOINT *endpoint_in; @@ -93,6 +98,12 @@ UX_SLAVE_ENDPOINT *endpoint_out; /* Extract the request type from the SETUP packet.. */ request = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST); + request_value = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE); + request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); + + /* Check if wValue is valid. */ + if (request_value != 0) + return(UX_ERROR); /* Get the class container. */ class = command -> ux_slave_class_command_class_ptr; @@ -106,6 +117,10 @@ UX_SLAVE_ENDPOINT *endpoint_out; case UX_SLAVE_CLASS_STORAGE_RESET: + /* Check if wLength is valid. */ + if (request_length != 0) + return(UX_ERROR); + /* We need the interface to the class. */ interface = storage -> ux_slave_class_storage_interface; @@ -144,6 +159,10 @@ UX_SLAVE_ENDPOINT *endpoint_out; case UX_SLAVE_CLASS_STORAGE_GET_MAX_LUN: + /* Check if wLength is valid. */ + if (request_length < 1) + return(UX_ERROR); + /* Set the value of the number of LUN in the buffer. The max number of LUN is the number of declared LUN - 1. */ *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)(storage -> ux_slave_class_storage_number_lun -1); @@ -157,8 +176,8 @@ UX_SLAVE_ENDPOINT *endpoint_out; default: - /* Unknown function. It's not handled. */ - return(UX_ERROR); + /* Unknown function. It's not handled. */ + return(UX_ERROR); } /* It's handled. */ diff --git a/common/usbx_device_classes/src/ux_device_class_storage_csw_send.c b/common/usbx_device_classes/src/ux_device_class_storage_csw_send.c index 8e9374a..2eb5709 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_csw_send.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_csw_send.c @@ -38,7 +38,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_csw_send PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_csw_send(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, @@ -112,6 +115,9 @@ UCHAR *csw_buffer; /* Store the SCSI tag from the CBW. */ _ux_utility_long_put(&csw_buffer[UX_SLAVE_CLASS_STORAGE_CSW_TAG], storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_scsi_tag); + /* Store the dCSWDataResidue. */ + _ux_utility_long_put(&csw_buffer[UX_SLAVE_CLASS_STORAGE_CSW_DATA_RESIDUE], storage -> ux_slave_class_storage_csw_residue); + /* Store the status of the previous operation. */ csw_buffer[UX_SLAVE_CLASS_STORAGE_CSW_STATUS] = (UCHAR)storage -> ux_slave_class_storage_csw_status; diff --git a/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c b/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c index 1cd1d05..2c5a005 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_inquiry PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,16 +82,19 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_inquiry(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb) { -UINT status; +UINT status = UX_SUCCESS; UX_SLAVE_TRANSFER *transfer_request; UCHAR inquiry_page_code; -UCHAR inquiry_length; +ULONG inquiry_length; UCHAR *inquiry_buffer; UX_PARAMETER_NOT_USED(endpoint_out); @@ -99,11 +102,20 @@ UCHAR *inquiry_buffer; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_STORAGE_INQUIRY, storage, lun, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) + /* Check direction. */ + if (storage -> ux_slave_class_storage_host_length && + (storage -> ux_slave_class_storage_cbw_flags & 0x80) == 0) + { + _ux_device_stack_endpoint_stall(endpoint_out); + storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR; + return(UX_ERROR); + } + /* From the SCSI Inquiry payload, get the page code. */ inquiry_page_code = *(cbwcb + UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE); /* And the length to be returned. */ - inquiry_length = *(cbwcb + UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_ADDITIONAL_LENGTH); + inquiry_length = storage -> ux_slave_class_storage_host_length; /* Obtain the pointer to the transfer request. */ transfer_request = &endpoint_in -> ux_slave_endpoint_transfer_request; @@ -116,7 +128,7 @@ UCHAR *inquiry_buffer; /* Check for the maximum length to be returned. */ if (inquiry_length > UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH) - inquiry_length = UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH; + inquiry_length = UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH; /* Default CSW to passed. */ storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED; @@ -157,12 +169,6 @@ UCHAR *inquiry_buffer; _ux_utility_memory_copy(inquiry_buffer + UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_REVISION, storage -> ux_slave_class_storage_product_rev, 4); /* Use case of memcpy is verified. */ - /* Send a data payload with the inquiry response buffer. */ - _ux_device_stack_transfer_request(transfer_request, inquiry_length, inquiry_length); - - /* Now success. */ - status = UX_SUCCESS; - break; case UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_SERIAL: @@ -177,11 +183,9 @@ UCHAR *inquiry_buffer; _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer + 4, storage -> ux_slave_class_storage_product_serial, 20); /* Use case of memcpy is verified. */ /* Send a data payload with the inquiry response buffer. */ - _ux_device_stack_transfer_request(transfer_request, 24, 24); + if (inquiry_length > 24) + inquiry_length = 24; - /* Now success. */ - status = UX_SUCCESS; - break; default: @@ -202,6 +206,20 @@ UCHAR *inquiry_buffer; break; } + /* Error cases. */ + if (status != UX_SUCCESS) + return(status); + + /* Send a data payload with the inquiry response buffer. */ + if (inquiry_length) + _ux_device_stack_transfer_request(transfer_request, inquiry_length, inquiry_length); + + /* Check length. */ + if (storage -> ux_slave_class_storage_host_length != inquiry_length) + { + _ux_device_stack_endpoint_stall(endpoint_in); + } + /* Return completion status. */ return(status); } diff --git a/common/usbx_device_classes/src/ux_device_class_storage_mode_select.c b/common/usbx_device_classes/src/ux_device_class_storage_mode_select.c index 08c3d7d..6ef4fdd 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_mode_select.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_mode_select.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_mode_select PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,9 @@ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* optimized command logic, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_mode_select(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, @@ -87,7 +90,11 @@ UINT _ux_device_class_storage_mode_select(UX_SLAVE_CLASS_STORAGE *storage, ULON UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_STORAGE_MODE_SELECT, storage, lun, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) /* This command is not yet supported. So Stall the endpoint. */ - _ux_device_stack_endpoint_stall(endpoint_out); + if (storage -> ux_slave_class_storage_host_length) + { + _ux_device_stack_endpoint_stall(endpoint_out); + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length; + } /* And update the REQUEST_SENSE codes. */ storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status = diff --git a/common/usbx_device_classes/src/ux_device_class_storage_read.c b/common/usbx_device_classes/src/ux_device_class_storage_read.c index 79f00cf..08e7e1e 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_read.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_read.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_read PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,9 @@ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* optimized command logic, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_read(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, @@ -93,6 +96,7 @@ ULONG number_blocks; ULONG media_status; ULONG total_length; ULONG transfer_length; +ULONG done_length; UX_PARAMETER_NOT_USED(endpoint_out); @@ -120,7 +124,26 @@ ULONG transfer_length; /* Default CSW to failed. */ storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_FAILED; + /* Check transfer length. */ + + /* Case (7). Host length < device length. */ + if (total_length > storage -> ux_slave_class_storage_host_length) + { + _ux_device_stack_endpoint_stall(endpoint_in); + storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR; + return(UX_ERROR); + } + + /* Case (8). Hi <> Do. */ + if ((storage -> ux_slave_class_storage_cbw_flags & 0x80) == 0) + { + _ux_device_stack_endpoint_stall(endpoint_out); + storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR; + return(UX_ERROR); + } + /* It may take several transfers to send the requested data. */ + done_length = 0; while (total_number_blocks) { @@ -138,6 +161,9 @@ ULONG transfer_length; /* We have a problem, media status error. Return a bad completion and wait for the REQUEST_SENSE command. */ _ux_device_stack_endpoint_stall(endpoint_in); + + /* Update residue. */ + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - done_length; /* Return an error. */ return(UX_ERROR); @@ -173,6 +199,9 @@ ULONG transfer_length; REQUEST_SENSE command. */ _ux_device_stack_endpoint_stall(endpoint_in); + /* Update residue. */ + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - done_length; + /* And update the REQUEST_SENSE codes. */ storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status = media_status; @@ -191,6 +220,9 @@ ULONG transfer_length; REQUEST_SENSE command. */ _ux_device_stack_endpoint_stall(endpoint_in); + /* Update residue. */ + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - done_length; + /* Update the REQUEST_SENSE codes. */ storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00); @@ -205,14 +237,26 @@ ULONG transfer_length; /* Update the length to remain. */ total_length -= transfer_length; + done_length += transfer_length; /* Update the number of blocks to read. */ total_number_blocks -= number_blocks; } - + + /* Case (4), (5). Host length too large. */ + if (storage -> ux_slave_class_storage_host_length > done_length) + { + + /* Stall Bulk-In. */ + _ux_device_stack_endpoint_stall(endpoint_in); + + /* Update residure. */ + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - done_length; + } + /* Now we set the CSW with success. */ storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED; /* Return completion status. */ - return(status); + return(UX_SUCCESS); } diff --git a/common/usbx_device_classes/src/ux_device_class_storage_report_key.c b/common/usbx_device_classes/src/ux_device_class_storage_report_key.c index 70b1662..003ae94 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_report_key.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_report_key.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_report_key PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,9 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile warning, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_report_key(UX_SLAVE_CLASS_STORAGE *storage, @@ -88,7 +91,7 @@ UINT _ux_device_class_storage_report_key(UX_SLAVE_CLASS_STORAGE *storage, UCHAR *cbwcb) { -UINT status; +UINT status = UX_SUCCESS; UX_SLAVE_TRANSFER *transfer_request; ULONG allocation_length; ULONG key_format; diff --git a/common/usbx_device_classes/src/ux_device_class_storage_request_sense.c b/common/usbx_device_classes/src/ux_device_class_storage_request_sense.c index 6d7d4ef..15c2015 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_request_sense.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_request_sense.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_request_sense PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,16 +80,20 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_request_sense(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb) { -UINT status; +UINT status = UX_SUCCESS; UX_SLAVE_TRANSFER *transfer_request; UCHAR *sense_buffer; UCHAR key, code, qualifier; +ULONG sense_length; UX_PARAMETER_NOT_USED(cbwcb); @@ -98,11 +102,16 @@ UCHAR key, code, qualifier; /* Obtain the pointer to the transfer request. */ transfer_request = &endpoint_in -> ux_slave_endpoint_transfer_request; + /* Get length. */ + sense_length = storage -> ux_slave_class_storage_host_length; + if (sense_length > UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH) + sense_length = UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH; + /* Obtain sense buffer. */ sense_buffer = transfer_request -> ux_slave_transfer_request_data_pointer; /* Ensure it is cleaned. */ - _ux_utility_memory_set(sense_buffer, 0, UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH); /* Use case of memset is verified. */ + _ux_utility_memory_set(sense_buffer, 0, sense_length); /* Use case of memset is verified. */ /* Initialize the response buffer with the error code. */ sense_buffer[UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ERROR_CODE] = @@ -133,12 +142,15 @@ UCHAR key, code, qualifier; sense_buffer[UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ADD_LENGTH] = 10; /* Send a data payload with the sense codes. */ - _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH, - UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH); - - /* Now we set the CSW with success. */ - storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED; - status = UX_SUCCESS; + if (sense_length) + _ux_device_stack_transfer_request(transfer_request, sense_length, sense_length); + + /* Check length. */ + if (storage -> ux_slave_class_storage_host_length != sense_length) + { + _ux_device_stack_endpoint_stall(endpoint_in); + storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR; + } /* Return completion status. */ return(status); diff --git a/common/usbx_device_classes/src/ux_device_class_storage_test_ready.c b/common/usbx_device_classes/src/ux_device_class_storage_test_ready.c index 295ade0..ac627f9 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_test_ready.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_test_ready.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_test_ready PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,9 @@ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* optimized command logic, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_test_ready(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, @@ -103,7 +106,14 @@ ULONG media_status; storage -> ux_slave_class_storage_csw_status = (status == UX_SUCCESS) ? UX_SLAVE_CLASS_STORAGE_CSW_PASSED : UX_SLAVE_CLASS_STORAGE_CSW_FAILED; status = UX_SUCCESS; - + + /* Case (9) Ho > Dn. */ + if (storage -> ux_slave_class_storage_host_length) + { + _ux_device_stack_endpoint_stall(endpoint_out); + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length; + } + /* Return completion status. */ return(status); } diff --git a/common/usbx_device_classes/src/ux_device_class_storage_thread.c b/common/usbx_device_classes/src/ux_device_class_storage_thread.c index 3fa1d29..5f6983a 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_thread PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -100,6 +100,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ VOID _ux_device_class_storage_thread(ULONG storage_class) @@ -117,6 +120,7 @@ ULONG length; ULONG cbwcb_length; ULONG lun; UCHAR *scsi_command; +UCHAR *cbw_cb; /* This thread runs forever but can be suspended or resumed. */ @@ -188,10 +192,21 @@ UCHAR *scsi_command; /* Obtain the lun from the CBW. */ lun = (ULONG) *(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_LUN); + storage -> ux_slave_class_storage_cbw_lun = (UCHAR)lun; /* We have to memorize the SCSI command tag for the CSW phase. */ storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_scsi_tag = _ux_utility_long_get(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_TAG); + /* Get dCBWDataTransferLength: number of bytes to transfer. */ + storage -> ux_slave_class_storage_host_length = _ux_utility_long_get(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_DATA_LENGTH); + + /* Save bmCBWFlags. */ + storage -> ux_slave_class_storage_cbw_flags = *(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_FLAGS); + + /* Reset CSW status. */ + storage -> ux_slave_class_storage_csw_residue = 0; + storage -> ux_slave_class_storage_csw_status = 0; + /* Ensure the LUN number is within our declared values and check the command content and format. First we make sure we have a complete CBW. */ if ((lun < storage -> ux_slave_class_storage_number_lun) && (length == UX_SLAVE_CLASS_STORAGE_CBW_LENGTH)) @@ -209,128 +224,129 @@ UCHAR *scsi_command; { /* Analyze the command stored in the CBWCB. */ - switch (*(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB)) + cbw_cb = scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB; + switch (*(cbw_cb)) { case UX_SLAVE_CLASS_STORAGE_SCSI_TEST_READY: - _ux_device_class_storage_test_ready(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_test_ready(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_REQUEST_SENSE: - _ux_device_class_storage_request_sense(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_request_sense(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_FORMAT: - _ux_device_class_storage_format(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_format(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_INQUIRY: - _ux_device_class_storage_inquiry(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_inquiry(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_START_STOP: - _ux_device_class_storage_start_stop(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_start_stop(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_PREVENT_ALLOW_MEDIA_REMOVAL: - _ux_device_class_storage_prevent_allow_media_removal(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_prevent_allow_media_removal(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_READ_FORMAT_CAPACITY: - _ux_device_class_storage_read_format_capacity(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_read_format_capacity(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_READ_CAPACITY: - _ux_device_class_storage_read_capacity(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_read_capacity(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_VERIFY: - _ux_device_class_storage_verify(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_verify(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SELECT: - _ux_device_class_storage_mode_select(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_mode_select(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE_SHORT: case UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE: - _ux_device_class_storage_mode_sense(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_mode_sense(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_READ32: - _ux_device_class_storage_read(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB, + _ux_device_class_storage_read(storage, lun, endpoint_in, endpoint_out, cbw_cb, UX_SLAVE_CLASS_STORAGE_SCSI_READ32); break; case UX_SLAVE_CLASS_STORAGE_SCSI_READ16: - _ux_device_class_storage_read(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB, + _ux_device_class_storage_read(storage, lun, endpoint_in, endpoint_out, cbw_cb, UX_SLAVE_CLASS_STORAGE_SCSI_READ16); break; case UX_SLAVE_CLASS_STORAGE_SCSI_WRITE32: - _ux_device_class_storage_write(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB, + _ux_device_class_storage_write(storage, lun, endpoint_in, endpoint_out, cbw_cb, UX_SLAVE_CLASS_STORAGE_SCSI_WRITE32); break; case UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16: - _ux_device_class_storage_write(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB, + _ux_device_class_storage_write(storage, lun, endpoint_in, endpoint_out, cbw_cb, UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16); break; case UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE: - _ux_device_class_storage_synchronize_cache(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB, *(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB)); + _ux_device_class_storage_synchronize_cache(storage, lun, endpoint_in, endpoint_out, cbw_cb, *(cbw_cb)); break; #ifdef UX_SLAVE_CLASS_STORAGE_INCLUDE_MMC case UX_SLAVE_CLASS_STORAGE_SCSI_GET_STATUS_NOTIFICATION: - _ux_device_class_storage_get_status_notification(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_get_status_notification(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_GET_CONFIGURATION: - _ux_device_class_storage_get_configuration(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_get_configuration(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_READ_DISK_INFORMATION: - _ux_device_class_storage_read_disk_information(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_read_disk_information(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_REPORT_KEY: - _ux_device_class_storage_report_key(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_report_key(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_GET_PERFORMANCE: - _ux_device_class_storage_get_performance(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_get_performance(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_READ_DVD_STRUCTURE: - _ux_device_class_storage_read_dvd_structure(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + _ux_device_class_storage_read_dvd_structure(storage, lun, endpoint_in, endpoint_out, cbw_cb); break; case UX_SLAVE_CLASS_STORAGE_SCSI_READ_TOC: - status = _ux_device_class_storage_read_toc(storage, lun, endpoint_in, endpoint_out, scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_CB); + status = _ux_device_class_storage_read_toc(storage, lun, endpoint_in, endpoint_out, cbw_cb); /* Special treatment of TOC command. If error, default to Stall endpoint. */ if (status == UX_SUCCESS) @@ -342,8 +358,8 @@ UCHAR *scsi_command; /* The command is unknown or unsupported, so we stall the endpoint. */ - if (_ux_utility_long_get(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_DATA_LENGTH) > 0 && - ((*(scsi_command + UX_SLAVE_CLASS_STORAGE_CBW_FLAGS) & 0x80) == 0)) + if (storage -> ux_slave_class_storage_host_length > 0 && + ((storage -> ux_slave_class_storage_cbw_flags & 0x80) == 0)) /* Data-Out from host to device, stall OUT. */ _ux_device_stack_endpoint_stall(endpoint_out); diff --git a/common/usbx_device_classes/src/ux_device_class_storage_write.c b/common/usbx_device_classes/src/ux_device_class_storage_write.c index c42bf10..47560f0 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_write.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_write.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_write PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* optimized command logic, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed USB CV test issues, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_write(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, @@ -95,6 +98,7 @@ ULONG number_blocks; ULONG media_status; ULONG total_length; ULONG transfer_length; +ULONG done_length; UX_PARAMETER_NOT_USED(endpoint_in); @@ -160,11 +164,30 @@ ULONG transfer_length; /* Compute the total length to transfer and how much remains. */ total_length = total_number_blocks * storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_media_block_length; - + + /* Check transfer length. */ + + /* Case (3) Hn < Do. */ + if (total_length > storage -> ux_slave_class_storage_host_length) + { + _ux_device_stack_endpoint_stall(endpoint_out); + storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR; + return(UX_ERROR); + } + + /* Case (8). Hi <> Do. */ + if ((storage -> ux_slave_class_storage_cbw_flags & 0x80) != 0) + { + _ux_device_stack_endpoint_stall(endpoint_in); + storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR; + return(UX_ERROR); + } + /* Default status to success. */ status = UX_SUCCESS; /* It may take several transfers to send the requested data. */ + done_length = 0; while (total_length) { @@ -185,6 +208,9 @@ ULONG transfer_length; REQUEST_SENSE command. */ _ux_device_stack_endpoint_stall(endpoint_out); + /* Update residue. */ + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - done_length; + /* And update the REQUEST_SENSE codes. */ storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00); @@ -207,6 +233,9 @@ ULONG transfer_length; REQUEST_SENSE command. */ _ux_device_stack_endpoint_stall(endpoint_out); + /* Update residue. */ + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - done_length; + /* And update the REQUEST_SENSE codes. */ storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status = media_status; @@ -218,9 +247,17 @@ ULONG transfer_length; lba += number_blocks; /* Update the length to remain. */ - total_length -= transfer_length; + total_length -= transfer_length; + done_length += transfer_length; } + /* Update residue. */ + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - done_length; + + /* Case (9), (11). If host expects more transfer, stall it. */ + if (storage -> ux_slave_class_storage_csw_residue) + _ux_device_stack_endpoint_stall(endpoint_out); + /* Now we set the CSW with success. */ storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED; diff --git a/common/usbx_host_classes/inc/ux_host_class_storage.h b/common/usbx_host_classes/inc/ux_host_class_storage.h index 17b53b5..977d66c 100644 --- a/common/usbx_host_classes/inc/ux_host_class_storage.h +++ b/common/usbx_host_classes/inc/ux_host_class_storage.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_host_class_storage.h PORTABLE C */ -/* 6.1.2 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -55,6 +55,8 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* added exFAT type define, */ /* resulting in version 6.1.2 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ @@ -482,7 +484,7 @@ typedef struct UX_HOST_CLASS_STORAGE_MEDIA_STRUCT /* Define Storage Class function prototypes. */ UINT _ux_host_class_storage_activate(UX_HOST_CLASS_COMMAND *command); -VOID _ux_host_class_storage_cbw_initialize(UX_HOST_CLASS_STORAGE *storage, UINT direction, +VOID _ux_host_class_storage_cbw_initialize(UX_HOST_CLASS_STORAGE *storage, UINT flags, ULONG data_transfer_length, UINT command_length); UINT _ux_host_class_storage_configure(UX_HOST_CLASS_STORAGE *storage); UINT _ux_host_class_storage_deactivate(UX_HOST_CLASS_COMMAND *command); diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c b/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c index 2c6e34e..91ef76f 100644 --- a/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c +++ b/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_cdc_acm_write PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* fixed ZLP sending, */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ UINT _ux_host_class_cdc_acm_write(UX_HOST_CLASS_CDC_ACM *cdc_acm, UCHAR *data_pointer, @@ -122,7 +125,7 @@ ULONG transfer_request_length; /* Perform a transfer on the bulk out endpoint until either the transfer is completed or when there is an error. */ - while (requested_length) + do { /* Program the maximum authorized length for this transfer_request. */ @@ -194,7 +197,8 @@ ULONG transfer_request_length; /* Update what is left to send out. */ requested_length -= transfer_request_length; - } + + } while (requested_length); /* We get here when all the transfers went through without errors. */ return(UX_SUCCESS); diff --git a/common/usbx_host_classes/src/ux_host_class_storage_cbw_initialize.c b/common/usbx_host_classes/src/ux_host_class_storage_cbw_initialize.c index c056a17..564ec69 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_cbw_initialize.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_cbw_initialize.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_storage_cbw_initialize PORTABLE C */ -/* 6.1 */ +/* 6.1.3 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -49,7 +49,7 @@ /* INPUT */ /* */ /* storage Pointer to storage class */ -/* direction Direction of transfer */ +/* flags Flags for transfer */ /* data_transfer_length Length of data transfer */ /* command_length Length of command */ /* */ @@ -75,9 +75,11 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ +/* resulting in version 6.1.3 */ /* */ /**************************************************************************/ -VOID _ux_host_class_storage_cbw_initialize(UX_HOST_CLASS_STORAGE *storage, UINT direction, +VOID _ux_host_class_storage_cbw_initialize(UX_HOST_CLASS_STORAGE *storage, UINT flags, ULONG data_transfer_length, UINT command_length) { @@ -97,8 +99,8 @@ UCHAR *cbw; /* Store the Data Transfer Length expected for the data payload. */ _ux_utility_long_put(cbw + UX_HOST_CLASS_STORAGE_CBW_DATA_LENGTH, data_transfer_length); - /* Store the CBW Flag field that contains the transfer direction. */ - *(cbw + UX_HOST_CLASS_STORAGE_CBW_FLAGS) = (UCHAR)direction; + /* Store the CBW Flag field that contains the transfer flags. */ + *(cbw + UX_HOST_CLASS_STORAGE_CBW_FLAGS) = (UCHAR)flags; /* Store the LUN value. */ *(cbw + UX_HOST_CLASS_STORAGE_CBW_LUN) = (UCHAR)storage -> ux_host_class_storage_lun; diff --git a/ports/generic/inc/ux_port.h b/ports/generic/inc/ux_port.h new file mode 100644 index 0000000..daee582 --- /dev/null +++ b/ports/generic/inc/ux_port.h @@ -0,0 +1,219 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* ux_port.h Generic */ +/* 6.1.3 */ +/* */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make USBX function */ +/* identically on a variety of different processor architectures. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 12-31-2020 Chaoqiong Xiao Initial Version 6.1.3 */ +/* */ +/**************************************************************************/ + +#ifndef UX_PORT_H +#define UX_PORT_H + + +/* Determine if the optional USBX user define file should be used. */ + +#ifdef UX_INCLUDE_USER_DEFINE_FILE + + +/* Yes, include the user defines in ux_user.h. The defines in this file may + alternately be defined on the command line. */ + +#include "ux_user.h" +#endif + + +/* Include library header files. */ + +#include <stdio.h> +#include <string.h> + + +/* CPU definition for X86 systems without preemptive timer function. + This will make USBX uses the controller for the timer. */ + +#undef THREADX_X86_NO_PTIMER + + +/* For X86 systems, the define #define UX_USE_IO_INSTRUCTIONS should be used. */ + + +/* Define additional generic USBX types. */ + +typedef long SLONG; + + +/* Generic USBX Project constants follow. */ + +#ifndef UX_PERIODIC_RATE +#define UX_PERIODIC_RATE 100 +#endif + +#ifndef UX_MAX_CLASS_DRIVER +#define UX_MAX_CLASS_DRIVER 2 +#endif + +#ifndef UX_MAX_SLAVE_CLASS_DRIVER +#define UX_MAX_SLAVE_CLASS_DRIVER 2 +#endif + +#ifndef UX_MAX_HCD +#define UX_MAX_HCD 1 +#endif + +#ifndef UX_MAX_DEVICES +#define UX_MAX_DEVICES 2 +#endif + +#ifndef UX_MAX_ED +#define UX_MAX_ED 80 +#endif + +#ifndef UX_MAX_TD +#define UX_MAX_TD 32 +#endif + +#ifndef UX_MAX_ISO_TD +#define UX_MAX_ISO_TD 2 +#endif + +#ifndef UX_HOST_ENUM_THREAD_STACK_SIZE +#define UX_HOST_ENUM_THREAD_STACK_SIZE (2*1024) +#endif + +#ifndef UX_THREAD_STACK_SIZE +#define UX_THREAD_STACK_SIZE (1*1024) +#endif + +#ifndef UX_THREAD_PRIORITY_ENUM +#define UX_THREAD_PRIORITY_ENUM 20 +#endif + +#ifndef UX_THREAD_PRIORITY_CLASS +#define UX_THREAD_PRIORITY_CLASS 20 +#endif + +#ifndef UX_THREAD_PRIORITY_KEYBOARD +#define UX_THREAD_PRIORITY_KEYBOARD 20 +#endif + +#ifndef UX_THREAD_PRIORITY_HCD +#define UX_THREAD_PRIORITY_HCD 2 +#endif + +#ifndef UX_THREAD_PRIORITY_DCD +#define UX_THREAD_PRIORITY_DCD 2 +#endif + +#ifndef UX_NO_TIME_SLICE +#define UX_NO_TIME_SLICE 0 +#endif + +#ifndef UX_MAX_SLAVE_LUN +#define UX_MAX_SLAVE_LUN 1 +#endif + +#ifndef UX_MAX_HOST_LUN +#define UX_MAX_HOST_LUN 1 +#endif + +#ifndef UX_HOST_CLASS_STORAGE_MAX_MEDIA +#define UX_HOST_CLASS_STORAGE_MAX_MEDIA 1 +#endif + +#ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH +#define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 +#endif + + +#ifndef UX_SLAVE_REQUEST_DATA_MAX_LENGTH +#define UX_SLAVE_REQUEST_DATA_MAX_LENGTH 2048 +#endif + +#ifndef UX_USE_IO_INSTRUCTIONS + +/* Don't use IO instructions if this define is not set. Default to memory mapped. */ + +#define inpb(a) *((UCHAR *) (a)) +#define inpw(a) *((USHORT *) (a)) +#define inpl(a) *((ULONG *) (a)) +#define outpb(a, b) *((UCHAR *) (a)) = ((UCHAR) (b)) +#define outpw(a, b) *((USHORT *) (a)) = ((USHORT) (b)) +#define outpl(a, b) *((ULONG *) (a)) = ((ULONG) (b)) +#else + + +/* Define simple prototypes for non-memory mapped hardware access. */ + +UCHAR inpb(ULONG); +USHORT inpw(ULONG); +ULONG inpl(ULONG); + +VOID outpb(ULONG,UCHAR); +VOID outpw(ULONG,USHORT); +VOID outpl(ULONG,ULONG); + +#endif +/* Define local delay function for board specific bsps. */ +#ifdef TI_AM335 + #define UX_BSP_SPECIFIC_DELAY_FUNCTION +#endif + + +/* Define interrupt lockout constructs to protect the memory allocation/release which could happen + under ISR in the device stack. */ + +#define UX_INT_SAVE_AREA unsigned int old_interrupt_posture; +#define UX_DISABLE_INTS old_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE); +#define UX_RESTORE_INTS tx_interrupt_control(old_interrupt_posture); + + +/* Define the version ID of USBX. This may be utilized by the application. */ + +#ifdef UX_SYSTEM_INIT +CHAR _ux_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Generic Version 6.1.3 *"; +#else +extern CHAR _ux_version_id[]; +#endif + +#endif + |
