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 #if !defined(UX_HOST_STACK_DEVICE_DRIVER_SCAN_DISABLE)
32 #if defined(UX_HOST_STACK_DEVICE_DRIVER_SCAN_VIDPID_DISABLE) && \
33 defined(UX_HOST_STACK_DEVICE_DRIVER_SCAN_DCSP_DISABLE)
34 #error When device driver scan is enabled at least one of scan method must be enabled in (VIDPID, DeviceClassSubclassProtocol)
35 #endif
36 #endif
37
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _ux_host_stack_class_device_scan PORTABLE C */
43 /* 6.1.10 */
44 /* AUTHOR */
45 /* */
46 /* Chaoqiong Xiao, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function will scan all registered classes with a device */
51 /* candidate. Priority is given to the PID/VID and then the */
52 /* Class/Subclass/Protocol. */
53 /* */
54 /* INPUT */
55 /* */
56 /* device Pointer to device */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* Completion Status */
61 /* */
62 /* CALLS */
63 /* */
64 /* _ux_host_stack_class_call Call host stack class */
65 /* (ux_host_class_entry_function) Class entry function */
66 /* */
67 /* CALLED BY */
68 /* */
69 /* USBX Components */
70 /* */
71 /* RELEASE HISTORY */
72 /* */
73 /* DATE NAME DESCRIPTION */
74 /* */
75 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
76 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
77 /* used query usage of device */
78 /* ClassSubclassProtocol, */
79 /* resulting in version 6.1 */
80 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */
81 /* removed duplicate line, */
82 /* resulting in version 6.1.7 */
83 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
84 /* added standalone support, */
85 /* resulting in version 6.1.10 */
86 /* */
87 /**************************************************************************/
_ux_host_stack_class_device_scan(UX_DEVICE * device)88 UINT _ux_host_stack_class_device_scan(UX_DEVICE *device)
89 {
90 #if !defined(UX_HOST_STACK_DEVICE_DRIVER_SCAN_DISABLE)
91
92 UINT status;
93 UX_HOST_CLASS *class_inst = UX_NULL;
94 UX_HOST_CLASS_COMMAND class_command;
95
96 /* Perform the command initialization. */
97 class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY;
98 class_command.ux_host_class_command_container = (VOID *) device;
99 class_command.ux_host_class_command_vid = device -> ux_device_descriptor.idVendor;
100 class_command.ux_host_class_command_pid = device -> ux_device_descriptor.idProduct;
101 class_command.ux_host_class_command_class = device -> ux_device_descriptor.bDeviceClass;
102 class_command.ux_host_class_command_subclass = device -> ux_device_descriptor.bDeviceSubClass;
103 class_command.ux_host_class_command_protocol = device -> ux_device_descriptor.bDeviceProtocol;
104 class_command.ux_host_class_command_iad_class = 0;
105 class_command.ux_host_class_command_iad_subclass = 0;
106 class_command.ux_host_class_command_iad_protocol = 0;
107
108 #if !defined(UX_HOST_STACK_DEVICE_DRIVER_SCAN_VIDPID_DISABLE)
109 /* We start with the PID/VID for this device. */
110 class_command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_PIDVID;
111 class_inst = _ux_host_stack_class_call(&class_command);
112 #endif
113
114 #if !defined(UX_HOST_STACK_DEVICE_DRIVER_SCAN_DCSP_DISABLE)
115 /* On return, either we have found a class or the device is still an orphan. */
116 if (class_inst == UX_NULL)
117 {
118
119 /* It the PID/VID did not work, we continue looking for the Class\Subclass\Protocol match. */
120 class_command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_DCSP;
121 class_inst = _ux_host_stack_class_call(&class_command);
122
123 }
124 #endif
125
126 /* On return, either we have found a class or the device is still an orphan. */
127 if (class_inst != UX_NULL)
128 {
129
130 device -> ux_device_class = class_inst;
131
132 #if defined(UX_HOST_STANDALONE)
133
134 /* Activation may take time, run as state machine. */
135 status = UX_SUCCESS;
136 return(status);
137 #else
138 class_command.ux_host_class_command_class_ptr = class_inst;
139 class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE;
140 status = device -> ux_device_class -> ux_host_class_entry_function(&class_command);
141
142 /* Return result of activation. */
143 return(status);
144 #endif
145 }
146
147 #endif
148
149 /* Return an error. */
150 return(UX_NO_CLASS_MATCH);
151 }
152
153