[LIBUSB][USBCCGP]
[reactos.git] / reactos / drivers / usb / usbehci / common.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbehci/common.c
5 * PURPOSE: Common operations.
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 */
9
10 #define INITGUID
11 #include "usbehci.h"
12 #include <wdmguid.h>
13 #include <stdio.h>
14
15 VOID
16 DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
17 {
18 DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor);
19 DPRINT1("bLength %x\n", DeviceDescriptor->bLength);
20 DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
21 DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
22 DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
23 DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
24 DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
25 DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
26 DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor);
27 DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct);
28 DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
29 DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
30 DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct);
31 DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
32 DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
33 }
34
35 VOID
36 DumpFullConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
37 {
38 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
39 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
40 LONG i, j;
41
42 DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
43 DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
44 DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
45 DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
46 DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
47 DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
48 DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
49 DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
50 DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
51
52 InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR) ((ULONG_PTR)ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));
53
54 for (i=0; i < ConfigurationDescriptor->bNumInterfaces; i++)
55 {
56 DPRINT1("- Dumping InterfaceDescriptor %x\n", InterfaceDescriptor);
57 DPRINT1(" bLength %x\n", InterfaceDescriptor->bLength);
58 DPRINT1(" bDescriptorType %x\n", InterfaceDescriptor->bDescriptorType);
59 DPRINT1(" bInterfaceNumber %x\n", InterfaceDescriptor->bInterfaceNumber);
60 DPRINT1(" bAlternateSetting %x\n", InterfaceDescriptor->bAlternateSetting);
61 DPRINT1(" bNumEndpoints %x\n", InterfaceDescriptor->bNumEndpoints);
62 DPRINT1(" bInterfaceClass %x\n", InterfaceDescriptor->bInterfaceClass);
63 DPRINT1(" bInterfaceSubClass %x\n", InterfaceDescriptor->bInterfaceSubClass);
64 DPRINT1(" bInterfaceProtocol %x\n", InterfaceDescriptor->bInterfaceProtocol);
65 DPRINT1(" iInterface %x\n", InterfaceDescriptor->iInterface);
66
67 EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) ((ULONG_PTR)InterfaceDescriptor + sizeof(USB_INTERFACE_DESCRIPTOR));
68
69 for (j=0; j < InterfaceDescriptor->bNumEndpoints; j++)
70 {
71 DPRINT1(" bLength %x\n", EndpointDescriptor->bLength);
72 DPRINT1(" bDescriptorType %x\n", EndpointDescriptor->bDescriptorType);
73 DPRINT1(" bEndpointAddress %x\n", EndpointDescriptor->bEndpointAddress);
74 DPRINT1(" bmAttributes %x\n", EndpointDescriptor->bmAttributes);
75 DPRINT1(" wMaxPacketSize %x\n", EndpointDescriptor->wMaxPacketSize);
76 DPRINT1(" bInterval %x\n", EndpointDescriptor->bInterval);
77 EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) ((ULONG_PTR)EndpointDescriptor + sizeof(USB_ENDPOINT_DESCRIPTOR));
78 }
79 InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)(ULONG_PTR)EndpointDescriptor;
80 }
81
82 }
83
84 VOID
85 DumpQueueHead(PQUEUE_HEAD QueueHead)
86 {
87 DPRINT1("Dumping QueueHead %x\n", QueueHead);
88 DPRINT1(" CurrentLinkPointer %x\n", QueueHead->CurrentLinkPointer);
89 DPRINT1(" NextPointer %x\n", QueueHead->NextPointer);
90 DPRINT1(" AlternateNextPointer %x\n", QueueHead->AlternateNextPointer);
91 DPRINT1(" HorizontalLinkPointer %x\n", QueueHead->HorizontalLinkPointer);
92 DPRINT1(" Active %x\n", QueueHead->Token.Bits.Active);
93 DPRINT1(" Halted %x\n", QueueHead->Token.Bits.Halted);
94 DPRINT1(" DataBufferError %x\n", QueueHead->Token.Bits.DataBufferError);
95 DPRINT1(" BabbleDetected %x\n", QueueHead->Token.Bits.BabbleDetected);
96 DPRINT1(" TransactionError %x\n", QueueHead->Token.Bits.TransactionError);
97 DPRINT1(" MissedMicroFrame %x\n", QueueHead->Token.Bits.MissedMicroFrame);
98 DPRINT1(" PingState %x\n", QueueHead->Token.Bits.PingState);
99 DPRINT1(" SplitTransactionState %x\n", QueueHead->Token.Bits.SplitTransactionState);
100 DPRINT1(" ErrorCounter %x\n", QueueHead->Token.Bits.ErrorCounter);
101 DPRINT1(" First TransferDescriptor %x\n", QueueHead->FirstTransferDescriptor);
102 }
103
104 VOID
105 DumpTransferDescriptor(PQUEUE_TRANSFER_DESCRIPTOR TransferDescriptor)
106 {
107 DPRINT1("Dumping Descriptor %x\n", TransferDescriptor);
108 DPRINT1(" Active %x\n", TransferDescriptor->Token.Bits.Active);
109 DPRINT1(" Halted %x\n", TransferDescriptor->Token.Bits.Halted);
110 DPRINT1(" DataBufferError %x\n", TransferDescriptor->Token.Bits.DataBufferError);
111 DPRINT1(" BabbleDetected %x\n", TransferDescriptor->Token.Bits.BabbleDetected);
112 DPRINT1(" TransactionError %x\n", TransferDescriptor->Token.Bits.TransactionError);
113 DPRINT1(" MissedMicroFrame %x\n", TransferDescriptor->Token.Bits.MissedMicroFrame);
114 DPRINT1(" PingState %x\n", TransferDescriptor->Token.Bits.PingState);
115 DPRINT1(" SplitTransactionState %x\n", TransferDescriptor->Token.Bits.SplitTransactionState);
116 DPRINT1(" ErrorCounter %x\n", TransferDescriptor->Token.Bits.ErrorCounter);
117 }
118
119 NTSTATUS NTAPI
120 GetBusInterface(PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface)
121 {
122 KEVENT Event;
123 NTSTATUS Status;
124 PIRP Irp;
125 IO_STATUS_BLOCK IoStatus;
126 PIO_STACK_LOCATION Stack;
127
128 if ((!DeviceObject) || (!busInterface))
129 return STATUS_UNSUCCESSFUL;
130
131 KeInitializeEvent(&Event, NotificationEvent, FALSE);
132
133 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
134 DeviceObject,
135 NULL,
136 0,
137 NULL,
138 &Event,
139 &IoStatus);
140
141 if (Irp == NULL)
142 {
143 return STATUS_INSUFFICIENT_RESOURCES;
144 }
145
146 Stack=IoGetNextIrpStackLocation(Irp);
147 Stack->MajorFunction = IRP_MJ_PNP;
148 Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
149 Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
150 Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD;
151 Stack->Parameters.QueryInterface.Version = 1;
152 Stack->Parameters.QueryInterface.Interface = (PINTERFACE)busInterface;
153 Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
154 Irp->IoStatus.Status=STATUS_NOT_SUPPORTED ;
155
156 Status=IoCallDriver(DeviceObject, Irp);
157
158 if (Status == STATUS_PENDING)
159 {
160 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
161
162 Status=IoStatus.Status;
163 }
164
165 return Status;
166 }
167
168 NTSTATUS NTAPI
169 ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT Event)
170 {
171 if (Irp->PendingReturned)
172 {
173 KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
174 }
175 return STATUS_MORE_PROCESSING_REQUIRED;
176 }
177
178 NTSTATUS NTAPI
179 ForwardAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
180 {
181 PFDO_DEVICE_EXTENSION DeviceExtensions;
182 KEVENT Event;
183 NTSTATUS Status;
184
185
186 DeviceExtensions = DeviceObject->DeviceExtension;
187 KeInitializeEvent(&Event, NotificationEvent, FALSE);
188 IoCopyCurrentIrpStackLocationToNext(Irp);
189 IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)ForwardAndWaitCompletionRoutine, &Event, TRUE, TRUE, TRUE);
190 Status = IoCallDriver(DeviceExtensions->LowerDevice, Irp);
191 if (Status == STATUS_PENDING)
192 {
193 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
194 Status = Irp->IoStatus.Status;
195 }
196
197 return Status;
198 }
199
200 NTSTATUS NTAPI
201 ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject, PIRP Irp)
202 {
203 PDEVICE_OBJECT LowerDevice;
204
205 LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
206 ASSERT(LowerDevice);
207
208 IoSkipCurrentIrpStackLocation(Irp);
209 return IoCallDriver(LowerDevice, Irp);
210 }
211
212 /* Copied fom trunk PCI drivers */
213 NTSTATUS
214 DuplicateUnicodeString(ULONG Flags, PCUNICODE_STRING SourceString, PUNICODE_STRING DestinationString)
215 {
216 if (SourceString == NULL || DestinationString == NULL
217 || SourceString->Length > SourceString->MaximumLength
218 || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
219 || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
220 {
221 return STATUS_INVALID_PARAMETER;
222 }
223
224
225 if ((SourceString->Length == 0)
226 && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
227 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
228 {
229 DestinationString->Length = 0;
230 DestinationString->MaximumLength = 0;
231 DestinationString->Buffer = NULL;
232 }
233 else
234 {
235 USHORT DestMaxLength = SourceString->Length;
236
237 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
238 DestMaxLength += sizeof(UNICODE_NULL);
239
240 DestinationString->Buffer = ExAllocatePoolWithTag(NonPagedPool, DestMaxLength, USB_POOL_TAG);
241 if (DestinationString->Buffer == NULL)
242 return STATUS_NO_MEMORY;
243
244 RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
245 DestinationString->Length = SourceString->Length;
246 DestinationString->MaximumLength = DestMaxLength;
247
248 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
249 DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
250 }
251
252 return STATUS_SUCCESS;
253 }
254