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 /** USBX Component                                                        */
15 /**                                                                       */
16 /**   Device Printer Class                                                */
17 /**                                                                       */
18 /**************************************************************************/
19 /**************************************************************************/
20 
21 /**************************************************************************/
22 /*                                                                        */
23 /*  COMPONENT DEFINITION                                   RELEASE        */
24 /*                                                                        */
25 /*    ux_device_class_printer.h                           PORTABLE C      */
26 /*                                                           6.3.0        */
27 /*  AUTHOR                                                                */
28 /*                                                                        */
29 /*    Chaoqiong Xiao, Microsoft Corporation                               */
30 /*                                                                        */
31 /*  DESCRIPTION                                                           */
32 /*                                                                        */
33 /*    This file defines the equivalences for the USBX Device Class        */
34 /*    Printer component.                                                  */
35 /*                                                                        */
36 /*  RELEASE HISTORY                                                       */
37 /*                                                                        */
38 /*    DATE              NAME                      DESCRIPTION             */
39 /*                                                                        */
40 /*  01-31-2022     Chaoqiong Xiao           Initial Version 6.1.10        */
41 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
42 /*                                            fixed standalone compile,   */
43 /*                                            resulting in version 6.1.11 */
44 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
45 /*                                            resulting in version 6.1.12 */
46 /*  10-31-2022     Yajun xia                Modified comment(s),          */
47 /*                                            added standalone support,   */
48 /*                                            resulting in version 6.2.0  */
49 /*  03-08-2023     Yajun xia                Modified comment(s),          */
50 /*                                            added error checks support, */
51 /*                                            resulting in version 6.2.1  */
52 /*  10-31-2023     Yajun Xia, CQ Xiao       Modified comment(s),          */
53 /*                                            added a new mode to manage  */
54 /*                                            endpoint buffer in classes, */
55 /*                                            fixed error checking issue, */
56 /*                                            resulting in version 6.3.0  */
57 /*                                                                        */
58 /**************************************************************************/
59 
60 #ifndef UX_DEVICE_CLASS_PRINTER_H
61 #define UX_DEVICE_CLASS_PRINTER_H
62 
63 /* Determine if a C++ compiler is being used.  If so, ensure that standard
64    C is used to process the API information.  */
65 
66 #ifdef   __cplusplus
67 
68 /* Yes, C++ compiler is present.  Use standard C.  */
69 extern   "C" {
70 
71 #endif
72 
73 /* Internal option: enable the basic USBX error checking. This define is typically used
74    while debugging application.  */
75 #if defined(UX_ENABLE_ERROR_CHECKING) && !defined(UX_DEVICE_CLASS_PRINTER_ENABLE_ERROR_CHECKING)
76 #define UX_DEVICE_CLASS_PRINTER_ENABLE_ERROR_CHECKING
77 #endif
78 
79 
80 /* Option: defined, it enables zero copy support (works if PRINTER owns endpoint buffer).
81     Defined, it enables zero copy for bulk in/out endpoints (write/read). In this case, the endpoint
82     buffer is not allocated in class, application must provide the buffer for read/write, and the
83     buffer must meet device controller driver (DCD) buffer requirements (e.g., aligned and cache
84     safe if buffer is for DMA).
85  */
86 /* #define UX_DEVICE_CLASS_PRINTER_ZERO_COPY  */
87 
88 
89 /* Defined, _write is pending ZLP automatically (complete transfer) after buffer is sent.  */
90 
91 /* #define UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP  */
92 
93 
94 /* Option: bulk out endpoint / read buffer size, must be larger than max packet size in framework, and aligned in 4-bytes.  */
95 #ifndef UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE
96 #define UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE                         512
97 #endif
98 
99 /* Option: bulk in endpoint / write buffer size, must be larger than max packet size in framework, and aligned in 4-bytes.  */
100 #ifndef UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE
101 #define UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE                        UX_SLAVE_REQUEST_DATA_MAX_LENGTH
102 #endif
103 
104 
105 /* Internal: check if class own endpoint buffer  */
106 #if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) &&                                   \
107     (!defined(UX_DEVICE_CLASS_PRINTER_ZERO_COPY))
108 #define UX_DEVICE_CLASS_PRINTER_OWN_ENDPOINT_BUFFER
109 #endif
110 
111 
112 /* Define Printer Class USB Class constants.  */
113 #define UX_DEVICE_CLASS_PRINTER_CLASS                                    7
114 
115 #define UX_DEVICE_CLASS_PRINTER_SUBCLASS                                 1
116 
117 #define UX_DEVICE_CLASS_PRINTER_PROTOCOL_UNIDIRECTIONAL                  1
118 #define UX_DEVICE_CLASS_PRINTER_PROTOCOL_BIDIRECTIONAL                   2
119 #define UX_DEVICE_CLASS_PRINTER_PROTOCOL_1284_4_COMPATIBLE_BIDIR         3
120 
121 
122 /* Device Printer Requests */
123 #define UX_DEVICE_CLASS_PRINTER_GET_DEVICE_ID                            0x00
124 #define UX_DEVICE_CLASS_PRINTER_GET_PORT_STATUS                          0x01
125 #define UX_DEVICE_CLASS_PRINTER_SOFT_RESET                               0x02
126 
127 
128 /* Printer Port Status.  */
129 #define UX_DEVICE_CLASS_PRINTER_PAPER_EMPTY                             (1u << 5)
130 #define UX_DEVICE_CLASS_PRINTER_SELECT                                  (1u << 4)
131 #define UX_DEVICE_CLASS_PRINTER_NOT_ERROR                               (1u << 3)
132 
133 
134 /* Printer IOCTL code.  */
135 #define UX_DEVICE_CLASS_PRINTER_IOCTL_PORT_STATUS_SET                   1
136 #define UX_DEVICE_CLASS_PRINTER_IOCTL_READ_TIMEOUT_SET                  2
137 #define UX_DEVICE_CLASS_PRINTER_IOCTL_WRITE_TIMEOUT_SET                 3
138 
139 #if defined(UX_DEVICE_STANDALONE)
140 
141 /* Printer read state machine states.  */
142 #define UX_DEVICE_CLASS_PRINTER_READ_START                              (UX_STATE_STEP + 1)
143 #define UX_DEVICE_CLASS_PRINTER_READ_WAIT                               (UX_STATE_STEP + 2)
144 
145 /* Printer write state machine states.  */
146 #define UX_DEVICE_CLASS_PRINTER_WRITE_START                             (UX_STATE_STEP + 1)
147 #define UX_DEVICE_CLASS_PRINTER_WRITE_WAIT                              (UX_STATE_STEP + 2)
148 #endif
149 
150 /* Define Device Printer Class Calling Parameter structure */
151 
152 typedef struct UX_DEVICE_CLASS_PRINTER_PARAMETER_STRUCT
153 {
154     UCHAR                   *ux_device_class_printer_device_id; /* IEEE 1284 string, first 2 big endian length.  */
155     VOID                    (*ux_device_class_printer_instance_activate)(VOID *);
156     VOID                    (*ux_device_class_printer_instance_deactivate)(VOID *);
157     VOID                    (*ux_device_class_printer_soft_reset)(VOID *);
158 } UX_DEVICE_CLASS_PRINTER_PARAMETER;
159 
160 
161 /* Define Printer Class structure.  */
162 
163 typedef struct UX_DEVICE_CLASS_PRINTER_STRUCT
164 {
165     UX_SLAVE_INTERFACE      *ux_device_class_printer_interface;
166     UX_SLAVE_ENDPOINT       *ux_device_class_printer_endpoint_out;
167     UX_SLAVE_ENDPOINT       *ux_device_class_printer_endpoint_in;
168 #if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
169     UCHAR                   *ux_device_class_printer_endpoint_buffer;
170 #endif
171     ULONG                   ux_device_class_printer_port_status;
172     UX_DEVICE_CLASS_PRINTER_PARAMETER
173                             ux_device_class_printer_parameter;
174 #if !defined(UX_DEVICE_STANDALONE)
175     UX_MUTEX                ux_device_class_printer_endpoint_out_mutex;
176     UX_MUTEX                ux_device_class_printer_endpoint_in_mutex;
177 #else
178     UCHAR                  *ux_device_class_printer_read_buffer;
179     ULONG                   ux_device_class_printer_read_requested_length;
180     ULONG                   ux_device_class_printer_read_transfer_length;
181     ULONG                   ux_device_class_printer_read_actual_length;
182     UINT                    ux_device_class_printer_read_status;
183     UINT                    ux_device_class_printer_read_state;
184 
185     UCHAR                  *ux_device_class_printer_write_buffer;
186     ULONG                   ux_device_class_printer_write_transfer_length;
187     ULONG                   ux_device_class_printer_write_host_length;
188     ULONG                   ux_device_class_printer_write_requested_length;
189     ULONG                   ux_device_class_printer_write_actual_length;
190     UINT                    ux_device_class_printer_write_status;
191     UINT                    ux_device_class_printer_write_state;
192 #endif
193 } UX_DEVICE_CLASS_PRINTER;
194 
195 /* Define PRINTER endpoint buffer settings (when PRINTER owns buffer).  */
196 #define UX_DEVICE_CLASS_PRINTER_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \
197     (UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE,      \
198                                  UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE))
199 #define UX_DEVICE_CLASS_PRINTER_ENDPOINT_BUFFER_SIZE    (UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE + UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER_SIZE)
200 #define UX_DEVICE_CLASS_PRINTER_READ_BUFFER(ecm)        ((ecm)->ux_device_class_printer_endpoint_buffer)
201 #define UX_DEVICE_CLASS_PRINTER_WRITE_BUFFER(ecm)       (UX_DEVICE_CLASS_PRINTER_READ_BUFFER(ecm) + UX_DEVICE_CLASS_PRINTER_READ_BUFFER_SIZE)
202 
203 
204 /* Define Device Printer Class prototypes.  */
205 
206 UINT  _ux_device_class_printer_activate(UX_SLAVE_CLASS_COMMAND *command);
207 UINT  _ux_device_class_printer_control_request(UX_SLAVE_CLASS_COMMAND *command);
208 UINT  _ux_device_class_printer_deactivate(UX_SLAVE_CLASS_COMMAND *command);
209 UINT  _ux_device_class_printer_entry(UX_SLAVE_CLASS_COMMAND *command);
210 UINT  _ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND *command);
211 UINT  _ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND *command);
212 
213 VOID  _ux_device_class_printer_soft_reset(UX_DEVICE_CLASS_PRINTER *printer);
214 
215 UINT  _ux_device_class_printer_write(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
216                                 ULONG requested_length, ULONG *actual_length);
217 UINT  _ux_device_class_printer_read(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
218                                 ULONG requested_length, ULONG *actual_length);
219 
220 UINT  _ux_device_class_printer_ioctl(UX_DEVICE_CLASS_PRINTER *printer, ULONG ioctl_function,
221                                     VOID *parameter);
222 
223 UINT  _ux_device_class_printer_write_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
224                                 ULONG requested_length, ULONG *actual_length);
225 UINT  _ux_device_class_printer_read_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
226                                 ULONG requested_length, ULONG *actual_length);
227 
228 UINT  _uxe_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND *command);
229 UINT  _uxe_device_class_printer_read(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
230                                 ULONG requested_length, ULONG *actual_length);
231 UINT  _uxe_device_class_printer_write(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
232                                 ULONG requested_length, ULONG *actual_length);
233 UINT  _uxe_device_class_printer_ioctl(UX_DEVICE_CLASS_PRINTER *printer, ULONG ioctl_function,
234                                     VOID *parameter);
235 UINT  _uxe_device_class_printer_write_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
236                                 ULONG requested_length, ULONG *actual_length);
237 UINT  _uxe_device_class_printer_read_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
238                                 ULONG requested_length, ULONG *actual_length);
239 
240 /* Define Device Printer Class API prototypes.  */
241 #if defined(UX_DEVICE_CLASS_PRINTER_ENABLE_ERROR_CHECKING)
242 
243 #define ux_device_class_printer_entry               _ux_device_class_printer_entry
244 #define ux_device_class_printer_read                _uxe_device_class_printer_read
245 #define ux_device_class_printer_write               _uxe_device_class_printer_write
246 #define ux_device_class_printer_ioctl               _uxe_device_class_printer_ioctl
247 #define ux_device_class_printer_read_run            _uxe_device_class_printer_read_run
248 #define ux_device_class_printer_write_run           _uxe_device_class_printer_write_run
249 
250 #else
251 
252 #define ux_device_class_printer_entry               _ux_device_class_printer_entry
253 #define ux_device_class_printer_read                _ux_device_class_printer_read
254 #define ux_device_class_printer_write               _ux_device_class_printer_write
255 #define ux_device_class_printer_ioctl               _ux_device_class_printer_ioctl
256 #define ux_device_class_printer_read_run            _ux_device_class_printer_read_run
257 #define ux_device_class_printer_write_run           _ux_device_class_printer_write_run
258 
259 #endif
260 
261 /* Determine if a C++ compiler is being used.  If so, complete the standard
262    C conditional started above.  */
263 #ifdef __cplusplus
264 }
265 #endif
266 
267 #endif /* UX_DEVICE_CLASS_PRINTER_H */
268