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 /** Printer Class */
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_class_printer.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_printer_activate PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function calls the USBX stack to activate the class. */
45 /* */
46 /* INPUT */
47 /* */
48 /* command Printer class command pointer */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* Completion Status */
53 /* */
54 /* CALLS */
55 /* */
56 /* _ux_host_class_printer_configure Configure printer class */
57 /* _ux_host_class_printer_endpoints_get Get endpoints of printer */
58 /* _ux_host_class_printer_name_get Get printer name */
59 /* _ux_host_stack_class_instance_create Create class instance */
60 /* _ux_host_stack_class_instance_destroy Destroy the class instance */
61 /* _ux_utility_memory_allocate Allocate memory block */
62 /* _ux_utility_memory_free Free memory block */
63 /* _ux_host_semaphore_create Create printer semaphore */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* _ux_host_class_printer_entry Entry of printer class */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
74 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
75 /* resulting in version 6.1 */
76 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
77 /* added standalone support, */
78 /* resulting in version 6.1.10 */
79 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
80 /* fixed parameter/variable */
81 /* names conflict C++ keyword, */
82 /* resulting in version 6.1.12 */
83 /* */
84 /**************************************************************************/
_ux_host_class_printer_activate(UX_HOST_CLASS_COMMAND * command)85 UINT _ux_host_class_printer_activate(UX_HOST_CLASS_COMMAND *command)
86 {
87
88 UX_INTERFACE *interface_ptr;
89 UX_HOST_CLASS_PRINTER *printer;
90 #if !defined(UX_HOST_STANDALONE)
91 UINT status;
92 #endif
93
94
95 /* The printer is always activated by the interface descriptor and not the
96 device descriptor. */
97 interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container;
98
99 /* Obtain memory for this class instance. */
100 printer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_PRINTER));
101 if (printer == UX_NULL)
102 return(UX_MEMORY_INSUFFICIENT);
103
104 /* Store the class container into this instance. */
105 printer -> ux_host_class_printer_class = command -> ux_host_class_command_class_ptr;
106
107 /* Store the interface container into the printer class instance. */
108 printer -> ux_host_class_printer_interface = interface_ptr;
109
110 /* Store the device container into the printer class instance. */
111 printer -> ux_host_class_printer_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device;
112
113 /* This instance of the device must also be stored in the interface container. */
114 interface_ptr -> ux_interface_class_instance = (VOID *) printer;
115
116 /* Create this class instance. */
117 _ux_host_stack_class_instance_create(printer -> ux_host_class_printer_class, (VOID *) printer);
118
119 #if defined(UX_HOST_STANDALONE)
120
121 /* Do activate steps. */
122 printer -> ux_host_class_printer_enum_state = UX_STATE_WAIT;
123 printer -> ux_host_class_printer_state = UX_HOST_CLASS_INSTANCE_MOUNTING;
124 return(UX_SUCCESS);
125 #else
126
127 /* Configure the printer. */
128 status = _ux_host_class_printer_configure(printer);
129
130 /* Get the printer endpoint(s). We may need to search for Bulk Out and Bulk In endpoints. */
131 if (status == UX_SUCCESS)
132 status = _ux_host_class_printer_endpoints_get(printer);
133
134 /* Get the name of the printer from the 1284 descriptor. */
135 if (status == UX_SUCCESS)
136 status = _ux_host_class_printer_name_get(printer);
137
138 /* Create the semaphore to protect 2 threads from accessing the same printer instance. */
139 if (status == UX_SUCCESS)
140 {
141 status = _ux_host_semaphore_create(&printer -> ux_host_class_printer_semaphore, "ux_host_class_printer_semaphore", 1);
142 if (status != UX_SUCCESS)
143 status = UX_SEMAPHORE_ERROR;
144 }
145
146 /* Success things. */
147 if (status == UX_SUCCESS)
148 {
149
150 /* Mark the printer as live now. */
151 printer -> ux_host_class_printer_state = UX_HOST_CLASS_INSTANCE_LIVE;
152
153 /* If all is fine and the device is mounted, we may need to inform the application
154 if a function has been programmed in the system structure. */
155 if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
156 {
157
158 /* Call system change function. */
159 _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, printer -> ux_host_class_printer_class, (VOID *) printer);
160 }
161
162 /* If trace is enabled, insert this event into the trace buffer. */
163 UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_PRINTER_ACTIVATE, printer, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
164
165 /* If trace is enabled, register this object. */
166 UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, printer, 0, 0, 0)
167
168 /* Return success. */
169 return(UX_SUCCESS);
170 }
171
172 /* On error, free resources. */
173 _ux_host_stack_class_instance_destroy(printer -> ux_host_class_printer_class, (VOID *) printer);
174 interface_ptr -> ux_interface_class_instance = UX_NULL;
175 _ux_utility_memory_free(printer);
176
177 /* Return completion status. */
178 return(status);
179
180 #endif
181 }
182
183