1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** USBX Component                                                        */
16 /**                                                                       */
17 /**   Host Stack                                                          */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /* Include necessary system files.  */
24 
25 #define UX_SOURCE_CODE
26 
27 #include "ux_api.h"
28 #include "ux_host_stack.h"
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _ux_host_stack_configuration_descriptor_parse       PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Chaoqiong Xiao, Microsoft Corporation                               */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function reads the entire configuration descriptor and         */
44 /*    enumerates the interfaces, binds the interface to a class driver... */
45 /*    if the device has multiple configurations, we read all the          */
46 /*    configurations but do not instantiate any configuration. Rather we  */
47 /*    let a class driver do the work.                                     */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    device                                Pointer to device             */
52 /*    configuration                         Pointer to configuration      */
53 /*    configuration_index                   Index of configuration        */
54 /*                                                                        */
55 /*  OUTPUT                                                                */
56 /*                                                                        */
57 /*    Completion Status                                                   */
58 /*                                                                        */
59 /*  CALLS                                                                 */
60 /*                                                                        */
61 /*    _ux_host_stack_interfaces_scan        Scan host interfaces          */
62 /*    _ux_host_stack_transfer_request       Process transfer request      */
63 /*    _ux_utility_memory_allocate           Allocate block of memory      */
64 /*    _ux_utility_memory_free               Free block of memory          */
65 /*                                                                        */
66 /*  CALLED BY                                                             */
67 /*                                                                        */
68 /*    USBX Components                                                     */
69 /*                                                                        */
70 /*  RELEASE HISTORY                                                       */
71 /*                                                                        */
72 /*    DATE              NAME                      DESCRIPTION             */
73 /*                                                                        */
74 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
75 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
76 /*                                            resulting in version 6.1    */
77 /*                                                                        */
78 /**************************************************************************/
_ux_host_stack_configuration_descriptor_parse(UX_DEVICE * device,UX_CONFIGURATION * configuration,UINT configuration_index)79 UINT  _ux_host_stack_configuration_descriptor_parse(UX_DEVICE *device, UX_CONFIGURATION *configuration,
80                                                                         UINT configuration_index)
81 {
82 
83 UX_TRANSFER     *transfer_request;
84 UINT            status;
85 UCHAR           *descriptor;
86 UX_ENDPOINT     *control_endpoint;
87 ULONG           total_configuration_length;
88 
89 
90     /* Retrieve the pointer to the control endpoint and its transfer_request.  */
91     control_endpoint =  &device -> ux_device_control_endpoint;
92     transfer_request =  &control_endpoint -> ux_endpoint_transfer_request;
93 
94     /* Retrieve the size of all the configuration descriptor.  */
95     total_configuration_length =  configuration -> ux_configuration_descriptor.wTotalLength;
96 
97     /* Allocate enough memory to read all descriptors attached to this configuration.  */
98     descriptor =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, total_configuration_length);
99 
100     /* Determine if the memory was allocated.  */
101     if (descriptor == UX_NULL)
102     {
103 
104         /* No, return an error.  */
105         return(UX_MEMORY_INSUFFICIENT);
106     }
107     else
108     {
109 
110         /* Create a transfer_request for the GET_DESCRIPTOR request.  */
111         transfer_request -> ux_transfer_request_data_pointer =      descriptor;
112         transfer_request -> ux_transfer_request_requested_length =  total_configuration_length;
113         transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
114         transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
115         transfer_request -> ux_transfer_request_value =             configuration_index | (UINT)(UX_CONFIGURATION_DESCRIPTOR_ITEM << 8);
116         transfer_request -> ux_transfer_request_index =             0;
117 
118         /* Send request to HCD layer.  */
119         status =  _ux_host_stack_transfer_request(transfer_request);
120 
121         /* Check for correct transfer and entire descriptor returned.  */
122         if((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == total_configuration_length))
123         {
124 
125             /* The entire descriptor now contains the configuration descriptor,
126                the interface(s) descriptors, all alternate settings, endpoints
127                and descriptor specific to the class. The descriptor is parsed for all interfaces.  */
128             status =  _ux_host_stack_interfaces_scan(configuration, descriptor);
129         }
130     }
131 
132     /* Free all used resources.  */
133     _ux_utility_memory_free(descriptor);
134 
135     /* Return completion status.  */
136     return(status);
137 }
138 
139