1 /**
2  * @file usbdi.h
3  * Copyright 2012, 2013 MinGW.org project
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 /* Created by Casper S. Hornstrup <chorns@users.sourceforge.net> */
25 #ifndef __USBDI_H
26 #define __USBDI_H
27 #pragma GCC system_header
28 #include <_mingw.h>
29 
30 /*
31  * USBD and USB device driver definitions
32  */
33 
34 #ifdef __USB_H
35 #error usb.h cannot be included with usbdi.h
36 #else
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #include "ntddk.h"
43 #include "usbioctl.h"
44 
45 #define USBDI_VERSION                     0x300
46 
47 #define USB_DEFAULT_DEVICE_ADDRESS        0
48 #define USB_DEFAULT_ENDPOINT_ADDRESS      0
49 #define USB_DEFAULT_MAX_PACKET            64
50 
51 #define URB_FROM_IRP(Irp) ((IoGetCurrentIrpStackLocation(Irp))->Parameters.Others.Argument1)
52 
53 #define URB_FUNCTION_SELECT_CONFIGURATION           0x0000
54 #define URB_FUNCTION_SELECT_INTERFACE               0x0001
55 #define URB_FUNCTION_ABORT_PIPE                     0x0002
56 #define URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL      0x0003
57 #define URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL   0x0004
58 #define URB_FUNCTION_GET_FRAME_LENGTH               0x0005
59 #define URB_FUNCTION_SET_FRAME_LENGTH               0x0006
60 #define URB_FUNCTION_GET_CURRENT_FRAME_NUMBER       0x0007
61 #define URB_FUNCTION_CONTROL_TRANSFER               0x0008
62 #define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER     0x0009
63 #define URB_FUNCTION_ISOCH_TRANSFER                 0x000A
64 #define URB_FUNCTION_RESET_PIPE                     0x001E
65 #define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE     0x000B
66 #define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT   0x0024
67 #define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE  0x0028
68 #define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE       0x000C
69 #define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT     0x0025
70 #define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE    0x0029
71 #define URB_FUNCTION_SET_FEATURE_TO_DEVICE          0x000D
72 #define URB_FUNCTION_SET_FEATURE_TO_INTERFACE       0x000E
73 #define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT        0x000F
74 #define URB_FUNCTION_SET_FEATURE_TO_OTHER           0x0023
75 #define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE        0x0010
76 #define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE     0x0011
77 #define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT      0x0012
78 #define URB_FUNCTION_CLEAR_FEATURE_TO_OTHER         0x0022
79 #define URB_FUNCTION_GET_STATUS_FROM_DEVICE         0x0013
80 #define URB_FUNCTION_GET_STATUS_FROM_INTERFACE      0x0014
81 #define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT       0x0015
82 #define URB_FUNCTION_GET_STATUS_FROM_OTHER          0x0021
83 #define URB_FUNCTION_RESERVED0                      0x0016
84 #define URB_FUNCTION_VENDOR_DEVICE                  0x0017
85 #define URB_FUNCTION_VENDOR_INTERFACE               0x0018
86 #define URB_FUNCTION_VENDOR_ENDPOINT                0x0019
87 #define URB_FUNCTION_VENDOR_OTHER                   0x0020
88 #define URB_FUNCTION_CLASS_DEVICE                   0x001A
89 #define URB_FUNCTION_CLASS_INTERFACE                0x001B
90 #define URB_FUNCTION_CLASS_ENDPOINT                 0x001C
91 #define URB_FUNCTION_CLASS_OTHER                    0x001F
92 #define URB_FUNCTION_RESERVED                       0x001D
93 #define URB_FUNCTION_GET_CONFIGURATION              0x0026
94 #define URB_FUNCTION_GET_INTERFACE                  0x0027
95 #define URB_FUNCTION_LAST                           0x0029
96 
97 typedef LONG USBD_STATUS;
98 typedef PVOID USBD_PIPE_HANDLE;
99 typedef PVOID USBD_CONFIGURATION_HANDLE;
100 typedef PVOID USBD_INTERFACE_HANDLE;
101 
102 #define USBD_ERROR(Status) ((USBD_STATUS)(Status) < 0)
103 #define USBD_HALTED(Status) ((ULONG)(Status) >> 30 == 3)
104 #define USBD_PENDING(Status) ((ULONG)(Status) >> 30 == 1)
105 #define USBD_STATUS(Status) ((ULONG)(Status) & 0x0FFFFFFFL)
106 #define USBD_SUCCESS(Status) ((USBD_STATUS)(Status) >= 0)
107 
108 #define USBD_STATUS_SUCCESS               ((USBD_STATUS)0x00000000L)
109 #define USBD_STATUS_PENDING               ((USBD_STATUS)0x40000000L)
110 #define USBD_STATUS_HALTED                ((USBD_STATUS)0xC0000000L)
111 #define USBD_STATUS_ERROR                 ((USBD_STATUS)0x80000000L)
112 #define USBD_STATUS_NO_MEMORY             ((USBD_STATUS)0x80000100L)
113 #define USBD_STATUS_INVALID_URB_FUNCTION  ((USBD_STATUS)0x80000200L)
114 #define USBD_STATUS_INVALID_PARAMETER     ((USBD_STATUS)0x80000300L)
115 #define USBD_STATUS_ERROR_BUSY            ((USBD_STATUS)0x80000400L)
116 #define USBD_STATUS_REQUEST_FAILED        ((USBD_STATUS)0x80000500L)
117 #define USBD_STATUS_INVALID_PIPE_HANDLE   ((USBD_STATUS)0x80000600L)
118 #define USBD_STATUS_NO_BANDWIDTH          ((USBD_STATUS)0x80000700L)
119 #define USBD_STATUS_INTERNAL_HC_ERROR     ((USBD_STATUS)0x80000800L)
120 #define USBD_STATUS_ERROR_SHORT_TRANSFER  ((USBD_STATUS)0x80000900L)
121 #define USBD_STATUS_CRC                   ((USBD_STATUS)0xC0000001L)
122 #define USBD_STATUS_BTSTUFF               ((USBD_STATUS)0xC0000002L)
123 #define USBD_STATUS_DATA_TOGGLE_MISMATCH  ((USBD_STATUS)0xC0000003L)
124 #define USBD_STATUS_STALL_PID             ((USBD_STATUS)0xC0000004L)
125 #define USBD_STATUS_DEV_NOT_RESPONDING    ((USBD_STATUS)0xC0000005L)
126 #define USBD_STATUS_PID_CHECK_FAILURE     ((USBD_STATUS)0xC0000006L)
127 #define USBD_STATUS_UNEXPECTED_PID        ((USBD_STATUS)0xC0000007L)
128 #define USBD_STATUS_DATA_OVERRUN          ((USBD_STATUS)0xC0000008L)
129 #define USBD_STATUS_DATA_UNDERRUN         ((USBD_STATUS)0xC0000009L)
130 #define USBD_STATUS_RESERVED1             ((USBD_STATUS)0xC000000AL)
131 #define USBD_STATUS_RESERVED2             ((USBD_STATUS)0xC000000BL)
132 #define USBD_STATUS_BUFFER_OVERRUN        ((USBD_STATUS)0xC000000CL)
133 #define USBD_STATUS_BUFFER_UNDERRUN       ((USBD_STATUS)0xC000000DL)
134 #define USBD_STATUS_NOT_ACCESSED          ((USBD_STATUS)0xC000000FL)
135 #define USBD_STATUS_FIFO                  ((USBD_STATUS)0xC0000010L)
136 #define USBD_STATUS_ENDPOINT_HALTED       ((USBD_STATUS)0xC0000030L)
137 #define USBD_STATUS_BAD_START_FRAME       ((USBD_STATUS)0xC0000A00L)
138 #define USBD_STATUS_ISOCH_REQUEST_FAILED  ((USBD_STATUS)0xC0000B00L)
139 #define USBD_STATUS_FRAME_CONTROL_OWNED   ((USBD_STATUS)0xC0000C00L)
140 #define USBD_STATUS_FRAME_CONTROL_NOT_OWNED \
141                                           ((USBD_STATUS)0xC0000D00L)
142 #define USBD_STATUS_INAVLID_CONFIGURATION_DESCRIPTOR \
143                                           ((USBD_STATUS)0xC0000F00L)
144 #define USBD_STATUS_CANCELING             ((USBD_STATUS)0x00020000L)
145 
146 #define USBD_PIPE_DIRECTION_IN(pipeInformation) \
147   ((pipeInformation)->EndpointAddress & USB_ENDPOINT_DIRECTION_MASK)
148 
149 struct _URB_HEADER {
150 	USHORT  Length;
151 	USHORT  Function;
152 	USBD_STATUS  Status;
153 	PVOID  UsbdDeviceHandle;
154 	ULONG  UsbdFlags;
155 };
156 
157 struct _URB_HCD_AREA {
158 	PVOID  HcdEndpoint;
159 	PIRP  HcdIrp;
160 	LIST_ENTRY  HcdListEntry;
161 	LIST_ENTRY  HcdListEntry2;
162 	PVOID  HcdCurrentIoFlushPointer;
163 	PVOID  HcdExtension;
164 };
165 
166 struct _URB_BULK_OR_INTERRUPT_TRANSFER {
167 	struct _URB_HEADER  Hdr;
168 	USBD_PIPE_HANDLE  PipeHandle;
169 	ULONG  TransferFlags;
170 	ULONG  TransferBufferLength;
171 	PVOID  TransferBuffer;
172 	PMDL  TransferBufferMDL;
173 	struct _URB  *UrbLink;
174 	struct _URB_HCD_AREA  hca;
175 };
176 
177 struct _URB_CONTROL_DESCRIPTOR_REQUEST {
178 	struct _URB_HEADER  Hdr;
179 	PVOID  Reserved;
180 	ULONG  Reserved0;
181 	ULONG  TransferBufferLength;
182 	PVOID  TransferBuffer;
183 	PMDL  TransferBufferMDL;
184 	struct _URB  *UrbLink;
185 	struct _URB_HCD_AREA  hca;
186 	USHORT  Reserved1;
187 	UCHAR  Index;
188 	UCHAR  DescriptorType;
189 	USHORT  LanguageId;
190 	USHORT  Reserved2;
191 };
192 
193 struct _URB_CONTROL_FEATURE_REQUEST {
194 	struct _URB_HEADER  Hdr;
195 	PVOID  Reserved;
196 	ULONG  Reserved2;
197 	ULONG  Reserved3;
198 	PVOID  Reserved4;
199 	PMDL  Reserved5;
200 	struct _URB  *UrbLink;
201 	struct _URB_HCD_AREA  hca;
202 	USHORT  Reserved0;
203 	USHORT  FeatureSelector;
204 	USHORT  Index;
205 	USHORT  Reserved1;
206 };
207 
208 struct _URB_CONTROL_GET_CONFIGURATION_REQUEST {
209 	struct _URB_HEADER  Hdr;
210 	PVOID  Reserved;
211 	ULONG  Reserved0;
212 	ULONG  TransferBufferLength;
213 	PVOID  TransferBuffer;
214 	PMDL  TransferBufferMDL;
215 	struct _URB  *UrbLink;
216 	struct _URB_HCD_AREA  hca;
217 	UCHAR  Reserved1[8];
218 };
219 
220 struct _URB_CONTROL_GET_INTERFACE_REQUEST {
221 	struct _URB_HEADER  Hdr;
222 	PVOID  Reserved;
223 	ULONG  Reserved0;
224 	ULONG  TransferBufferLength;
225 	PVOID  TransferBuffer;
226 	PMDL  TransferBufferMDL;
227 	struct _URB  *UrbLink;
228 	struct _URB_HCD_AREA  hca;
229 	UCHAR  Reserved1[4];
230 	USHORT  Interface;
231 	USHORT  Reserved2;
232 };
233 
234 struct _URB_CONTROL_GET_STATUS_REQUEST {
235 	struct _URB_HEADER  Hdr;
236 	PVOID  Reserved;
237 	ULONG  Reserved0;
238 	ULONG  TransferBufferLength;
239 	PVOID  TransferBuffer;
240 	PMDL  TransferBufferMDL;
241 	struct _URB  *UrbLink;
242 	struct _URB_HCD_AREA  hca;
243 	UCHAR  Reserved1[4];
244 	USHORT  Index;
245 	USHORT  Reserved2;
246 };
247 
248 struct _URB_CONTROL_TRANSFER {
249 	struct _URB_HEADER  Hdr;
250 	USBD_PIPE_HANDLE  PipeHandle;
251 	ULONG  TransferFlags;
252 	ULONG  TransferBufferLength;
253 	PVOID  TransferBuffer;
254 	PMDL  TransferBufferMDL;
255 	struct _URB  *UrbLink;
256 	struct _URB_HCD_AREA  hca;
257 	UCHAR  SetupPacket[8];
258 };
259 
260 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST {
261 	struct _URB_HEADER  Hdr;
262 	PVOID  Reserved;
263 	ULONG  TransferFlags;
264 	ULONG  TransferBufferLength;
265 	PVOID  TransferBuffer;
266 	PMDL  TransferBufferMDL;
267 	struct _URB  *UrbLink;
268 	struct _URB_HCD_AREA  hca;
269 	UCHAR  RequestTypeReservedBits;
270 	UCHAR  Request;
271 	USHORT  Value;
272 	USHORT  Index;
273 	USHORT  Reserved1;
274 };
275 
276 struct _URB_FRAME_LENGTH_CONTROL {
277 	struct _URB_HEADER  Hdr;
278 };
279 
280 struct _URB_GET_CURRENT_FRAME_NUMBER {
281 	struct _URB_HEADER  Hdr;
282 	ULONG  FrameNumber;
283 };
284 
285 struct _URB_GET_FRAME_LENGTH {
286 	struct _URB_HEADER  Hdr;
287 	ULONG  FrameLength;
288 	ULONG  FrameNumber;
289 };
290 
291 typedef struct _USBD_ISO_PACKET_DESCRIPTOR {
292   ULONG  Offset;
293   ULONG  Length;
294   USBD_STATUS  Status;
295 } USBD_ISO_PACKET_DESCRIPTOR, *PUSBD_ISO_PACKET_DESCRIPTOR;
296 
297 struct _URB_ISOCH_TRANSFER {
298 	struct _URB_HEADER  Hdr;
299 	USBD_PIPE_HANDLE  PipeHandle;
300 	ULONG  TransferFlags;
301 	ULONG  TransferBufferLength;
302 	PVOID  TransferBuffer;
303 	PMDL  TransferBufferMDL;
304 	struct _URB  *UrbLink;
305 	struct _URB_HCD_AREA  hca;
306 	ULONG  StartFrame;
307 	ULONG  NumberOfPackets;
308 	ULONG  ErrorCount;
309 	USBD_ISO_PACKET_DESCRIPTOR  IsoPacket[1];
310 };
311 
312 struct _URB_PIPE_REQUEST {
313 	struct _URB_HEADER  Hdr;
314 	USBD_PIPE_HANDLE  PipeHandle;
315 	ULONG  Reserved;
316 };
317 
318 struct _URB_SET_FRAME_LENGTH {
319 	struct _URB_HEADER  Hdr;
320 	LONG  FrameLengthDelta;
321 };
322 
323 typedef struct _USBD_DEVICE_INFORMATION {
324 	ULONG  OffsetNext;
325 	PVOID  UsbdDeviceHandle;
326 	USB_DEVICE_DESCRIPTOR  DeviceDescriptor;
327 } USBD_DEVICE_INFORMATION, *PUSBD_DEVICE_INFORMATION;
328 
329 typedef enum _USBD_PIPE_TYPE {
330 	UsbdPipeTypeControl,
331 	UsbdPipeTypeIsochronous,
332 	UsbdPipeTypeBulk,
333 	UsbdPipeTypeInterrupt
334 } USBD_PIPE_TYPE;
335 
336 /* USBD_PIPE_INFORMATION.PipeFlags constants */
337 #define USBD_PF_CHANGE_MAX_PACKET         0x00000001
338 #define USBD_PF_DOUBLE_BUFFER             0x00000002
339 #define USBD_PF_ENABLE_RT_THREAD_ACCESS   0x00000004
340 #define USBD_PF_MAP_ADD_TRANSFERS         0x00000008
341 
342 typedef struct _USBD_PIPE_INFORMATION {
343   USHORT  MaximumPacketSize;
344   UCHAR  EndpointAddress;
345   UCHAR  Interval;
346   USBD_PIPE_TYPE  PipeType;
347   USBD_PIPE_HANDLE  PipeHandle;
348   ULONG  MaximumTransferSize;
349   ULONG  PipeFlags;
350 } USBD_PIPE_INFORMATION, *PUSBD_PIPE_INFORMATION;
351 
352 typedef struct _USBD_INTERFACE_INFORMATION {
353   USHORT  Length;
354   UCHAR  InterfaceNumber;
355   UCHAR  AlternateSetting;
356   UCHAR  Class;
357   UCHAR  SubClass;
358   UCHAR  Protocol;
359   UCHAR  Reserved;
360   USBD_INTERFACE_HANDLE  InterfaceHandle;
361   ULONG  NumberOfPipes;
362   USBD_PIPE_INFORMATION  Pipes[1];
363 } USBD_INTERFACE_INFORMATION, *PUSBD_INTERFACE_INFORMATION;
364 
365 struct _URB_SELECT_CONFIGURATION {
366 	struct _URB_HEADER  Hdr;
367 	PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor;
368 	USBD_CONFIGURATION_HANDLE  ConfigurationHandle;
369 	USBD_INTERFACE_INFORMATION  Interface;
370 };
371 
372 struct _URB_SELECT_INTERFACE {
373 	struct _URB_HEADER  Hdr;
374 	USBD_CONFIGURATION_HANDLE  ConfigurationHandle;
375 	USBD_INTERFACE_INFORMATION  Interface;
376 };
377 
378 typedef struct _USBD_VERSION_INFORMATION {
379 	ULONG  USBDI_Version;
380 	ULONG  Supported_USB_Version;
381 } USBD_VERSION_INFORMATION, *PUSBD_VERSION_INFORMATION;
382 
383 typedef struct _URB {
384 	union {
385 		struct _URB_HEADER  UrbHeader;
386 		struct _URB_SELECT_INTERFACE  UrbSelectInterface;
387 		struct _URB_SELECT_CONFIGURATION  UrbSelectConfiguration;
388 		struct _URB_PIPE_REQUEST  UrbPipeRequest;
389 		struct _URB_FRAME_LENGTH_CONTROL  UrbFrameLengthControl;
390 		struct _URB_GET_FRAME_LENGTH  UrbGetFrameLength;
391 		struct _URB_SET_FRAME_LENGTH  UrbSetFrameLength;
392 		struct _URB_GET_CURRENT_FRAME_NUMBER  UrbGetCurrentFrameNumber;
393 		struct _URB_CONTROL_TRANSFER  UrbControlTransfer;
394 		struct _URB_BULK_OR_INTERRUPT_TRANSFER  UrbBulkOrInterruptTransfer;
395 		struct _URB_ISOCH_TRANSFER  UrbIsochronousTransfer;
396 		struct _URB_CONTROL_DESCRIPTOR_REQUEST  UrbControlDescriptorRequest;
397 		struct _URB_CONTROL_GET_STATUS_REQUEST  UrbControlGetStatusRequest;
398 		struct _URB_CONTROL_FEATURE_REQUEST  UrbControlFeatureRequest;
399 		struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST  UrbControlVendorClassRequest;
400 		struct _URB_CONTROL_GET_INTERFACE_REQUEST  UrbControlGetInterfaceRequest;
401 		struct _URB_CONTROL_GET_CONFIGURATION_REQUEST  UrbControlGetConfigurationRequest;
402 	};
403 } URB, *PURB;
404 
405 #ifdef __cplusplus
406 }
407 #endif
408 
409 #endif /* defined __USB_H */
410 
411 #endif /* __USBDI_H */
412