Sync with trunk head (part 1 of x)
[reactos.git] / drivers / usb / usbehci / irp.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/irp.c
5 * PURPOSE: IRP Handling.
6 * PROGRAMMERS:
7 * Michael Martin
8 */
9
10 #include "usbehci.h"
11
12 VOID
13 RequestURBCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp)
14 {
15 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
16
17 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
18
19 KIRQL OldIrql = Irp->CancelIrql;
20 IoReleaseCancelSpinLock(DISPATCH_LEVEL);
21
22 KeAcquireSpinLockAtDpcLevel(&PdoDeviceExtension->IrpQueueLock);
23 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
24
25 KeReleaseSpinLock(&PdoDeviceExtension->IrpQueueLock, OldIrql);
26
27 Irp->IoStatus.Status = STATUS_CANCELLED;
28 IoCompleteRequest(Irp, IO_NO_INCREMENT);
29 }
30
31 VOID
32 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
33 {
34 KIRQL OldIrql;
35
36 KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &OldIrql);
37
38 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
39 {
40 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
41 Irp->IoStatus.Status = STATUS_CANCELLED;
42 IoCompleteRequest(Irp, IO_NO_INCREMENT);
43 }
44 else
45 {
46 InsertTailList(&DeviceExtension->IrpQueue, &Irp->Tail.Overlay.ListEntry);
47 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
48 }
49 }
50
51 VOID
52 CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
53 {
54 PLIST_ENTRY NextIrp = NULL;
55 NTSTATUS Status = STATUS_UNSUCCESSFUL;
56 ULONG_PTR Information = 0;
57 PIO_STACK_LOCATION Stack;
58 PUSB_DEVICE UsbDevice = NULL;
59 KIRQL oldIrql;
60 PIRP Irp = NULL;
61 URB *Urb;
62
63 KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
64
65 while(!IsListEmpty(&DeviceExtension->IrpQueue))
66 {
67 NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
68 Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
69
70 if (!Irp)
71 break;
72
73 Stack = IoGetCurrentIrpStackLocation(Irp);
74 ASSERT(Stack);
75
76 Urb = (PURB) Stack->Parameters.Others.Argument1;
77 ASSERT(Urb);
78
79 Information = 0;
80 Status = STATUS_SUCCESS;
81
82 DPRINT1("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
83 DPRINT1("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
84 DPRINT1("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
85
86 UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
87 /* UsbdDeviceHandle of 0 is root hub */
88 if (UsbDevice == NULL)
89 UsbDevice = DeviceExtension->UsbDevices[0];
90
91 switch (Urb->UrbHeader.Function)
92 {
93 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
94 {
95 /* Are we suppose to only return on this request when a device is connected
96 or is it the RootHubInitNotification Callback */
97 DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
98 DPRINT1("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
99 DPRINT1("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
100 DPRINT1("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
101 DPRINT1("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
102 /* FIXME */
103 RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
104 ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1;
105 /* Turn off Irp handling as nothing is handled beyond this */
106 DeviceExtension->HaltUrbHandling = TRUE;
107 break;
108 }
109 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
110 {
111 DPRINT1("Get Status from Device\n");
112 break;
113 }
114 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
115 {
116 Urb->UrbHeader.Function = 0x08;
117 Urb->UrbHeader.UsbdFlags = 0;
118 Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
119
120 switch(Urb->UrbControlDescriptorRequest.DescriptorType)
121 {
122 case USB_DEVICE_DESCRIPTOR_TYPE:
123 {
124 DPRINT1("USB DEVICE DESC\n");
125 if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR))
126 {
127 Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
128 }
129
130 RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
131 &UsbDevice->DeviceDescriptor,
132 Urb->UrbControlDescriptorRequest.TransferBufferLength);
133
134 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
135
136 break;
137 }
138 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
139 {
140 DPRINT1("USB CONFIG DESC\n");
141 ULONG FullDescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR) +
142 sizeof(USB_INTERFACE_DESCRIPTOR) +
143 sizeof(USB_ENDPOINT_DESCRIPTOR);
144
145 if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= FullDescriptorLength)
146 {
147 Urb->UrbControlDescriptorRequest.TransferBufferLength = FullDescriptorLength;
148 }
149
150 RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
151 &UsbDevice->ConfigurationDescriptor,
152 Urb->UrbControlDescriptorRequest.TransferBufferLength);
153
154 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
155
156 break;
157 }
158 case USB_STRING_DESCRIPTOR_TYPE:
159 {
160 DPRINT1("Usb String Descriptor not implemented\n");
161 break;
162 }
163 default:
164 {
165 DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType);
166 }
167 }
168 break;
169 }
170 case URB_FUNCTION_SELECT_CONFIGURATION:
171 {
172 PUSBD_INTERFACE_INFORMATION InterfaceInfo;
173 LONG iCount, pCount;
174
175 DPRINT("Selecting Configuration\n");
176 DPRINT("Length %x\n", Urb->UrbHeader.Length);
177 DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
178
179 if (Urb->UrbSelectConfiguration.ConfigurationDescriptor)
180 {
181 DPRINT("ConfigurationDescriptor = %p\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor);
182 DPRINT(" bLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength);
183 DPRINT(" bDescriptorType = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType);
184 DPRINT(" wTotalLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength);
185 DPRINT(" bNumInterfaces = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces);
186 DPRINT(" bConfigurationValue = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue);
187 DPRINT(" iConfiguration = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration);
188 DPRINT(" bmAttributes = %04x\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes);
189 DPRINT(" MaxPower = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower);
190
191
192 Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ConfigurationDescriptor;
193 DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
194 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
195
196 for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++)
197 {
198 DPRINT("InterfaceInformation[%d]\n", iCount);
199 DPRINT(" Length = %d\n", InterfaceInfo->Length);
200 DPRINT(" InterfaceNumber = %d\n", InterfaceInfo->InterfaceNumber);
201 DPRINT(" AlternateSetting = %d\n", InterfaceInfo->AlternateSetting);
202 DPRINT(" Class = %02x\n", (ULONG)InterfaceInfo->Class);
203 DPRINT(" SubClass = %02x\n", (ULONG)InterfaceInfo->SubClass);
204 DPRINT(" Protocol = %02x\n", (ULONG)InterfaceInfo->Protocol);
205 DPRINT(" Reserved = %02x\n", (ULONG)InterfaceInfo->Reserved);
206 DPRINT(" InterfaceHandle = %p\n", InterfaceInfo->InterfaceHandle);
207 DPRINT(" NumberOfPipes = %d\n", InterfaceInfo->NumberOfPipes);
208 InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->InterfaceDescriptor;
209 InterfaceInfo->Class = UsbDevice->InterfaceDescriptor.bInterfaceClass;
210 InterfaceInfo->SubClass = UsbDevice->InterfaceDescriptor.bInterfaceSubClass;
211 InterfaceInfo->Protocol = UsbDevice->InterfaceDescriptor.bInterfaceProtocol;
212 InterfaceInfo->Reserved = 0;
213
214 for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++)
215 {
216 DPRINT("Pipe[%d]\n", pCount);
217 DPRINT(" MaximumPacketSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumPacketSize);
218 DPRINT(" EndpointAddress = %d\n", InterfaceInfo->Pipes[pCount].EndpointAddress);
219 DPRINT(" Interval = %d\n", InterfaceInfo->Pipes[pCount].Interval);
220 DPRINT(" PipeType = %d\n", InterfaceInfo->Pipes[pCount].PipeType);
221 DPRINT(" PipeHandle = %x\n", InterfaceInfo->Pipes[pCount].PipeHandle);
222 DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumTransferSize);
223 DPRINT(" PipeFlags = %08x\n", InterfaceInfo->Pipes[pCount].PipeFlags);
224 InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->EndPointDescriptor.wMaxPacketSize;
225 InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->EndPointDescriptor.bEndpointAddress;
226 InterfaceInfo->Pipes[pCount].Interval = UsbDevice->EndPointDescriptor.bInterval;
227 InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt;
228 InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->EndPointDescriptor;
229 if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0)
230 InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096;
231 /* InterfaceInfo->Pipes[j].PipeFlags = 0; */
232 }
233 InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
234 }
235
236 Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
237 Urb->UrbHeader.UsbdFlags = 0;
238 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
239 }
240 else
241 {
242 /* FIXME: Set device to unconfigured state */
243 }
244 break;
245 }
246 case URB_FUNCTION_CLASS_DEVICE:
247 {
248 switch (Urb->UrbControlVendorClassRequest.Request)
249 {
250 case USB_REQUEST_GET_DESCRIPTOR:
251 {
252 DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
253 DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n", Urb->UrbControlVendorClassRequest.Value);
254
255
256 switch (Urb->UrbControlVendorClassRequest.Value >> 8)
257 {
258 case USB_DEVICE_CLASS_AUDIO:
259 {
260 DPRINT1("USB_DEVICE_CLASS_AUDIO\n");
261 break;
262 }
263 case USB_DEVICE_CLASS_COMMUNICATIONS:
264 {
265 DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS\n");
266 break;
267 }
268 case USB_DEVICE_CLASS_HUMAN_INTERFACE:
269 {
270 DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE\n");
271 break;
272 }
273 case USB_DEVICE_CLASS_MONITOR:
274 {
275 DPRINT1("USB_DEVICE_CLASS_MONITOR\n");
276 break;
277 }
278 case USB_DEVICE_CLASS_PHYSICAL_INTERFACE:
279 {
280 DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE\n");
281 break;
282 }
283 case USB_DEVICE_CLASS_POWER:
284 {
285 DPRINT1("USB_DEVICE_CLASS_POWER\n");
286 break;
287 }
288 case USB_DEVICE_CLASS_PRINTER:
289 {
290 DPRINT1("USB_DEVICE_CLASS_PRINTER\n");
291 break;
292 }
293 case USB_DEVICE_CLASS_STORAGE:
294 {
295 DPRINT1("USB_DEVICE_CLASS_STORAGE\n");
296 break;
297 }
298 case USB_DEVICE_CLASS_RESERVED:
299 case USB_DEVICE_CLASS_HUB:
300 {
301 PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer;
302 /* FIXME: Handle more than root hub? */
303 if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR))
304 {
305 Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
306 }
307 else
308 {
309 /* FIXME: Handle this correctly */
310 UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
311 UsbHubDescr->bDescriptorType = 0x29;
312 return;
313 }
314 DPRINT1("USB_DEVICE_CLASS_HUB request\n");
315 UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
316 UsbHubDescr->bDescriptorType = 0x29;
317 UsbHubDescr->bNumberOfPorts = 0x08;
318 UsbHubDescr->wHubCharacteristics = 0x0012;
319 UsbHubDescr->bPowerOnToPowerGood = 0x01;
320 UsbHubDescr->bHubControlCurrent = 0x00;
321 UsbHubDescr->bRemoveAndPowerMask[0] = 0x00;
322 UsbHubDescr->bRemoveAndPowerMask[1] = 0x00;
323 UsbHubDescr->bRemoveAndPowerMask[2] = 0xff;
324 break;
325 }
326 default:
327 {
328 DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
329 }
330 }
331 Urb->UrbHeader.Function = 0x08;
332 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
333 Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
334 Urb->UrbHeader.UsbdFlags = 0;
335 break;
336 }
337 default:
338 {
339 DPRINT1("Unhandled URB request for class device\n");
340 Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
341 }
342 }
343 break;
344 }
345 case URB_FUNCTION_CLASS_OTHER:
346 {
347 switch (Urb->UrbControlVendorClassRequest.Request)
348 {
349 case USB_REQUEST_GET_STATUS:
350 {
351 DPRINT1("USB_REQUEST_GET_STATUS\n");
352 break;
353 }
354 case USB_REQUEST_CLEAR_FEATURE:
355 {
356 DPRINT1("USB_REQUEST_CLEAR_FEATURE\n");
357 break;
358 }
359 case USB_REQUEST_SET_FEATURE:
360 {
361 DPRINT1("USB_REQUEST_SET_FEATURE value %x\n", Urb->UrbControlVendorClassRequest.Value);
362 switch(Urb->UrbControlVendorClassRequest.Value)
363 {
364 /* FIXME: Needs research */
365 case 0x01:
366 {
367 }
368 }
369 break;
370 }
371 case USB_REQUEST_SET_ADDRESS:
372 {
373 DPRINT1("USB_REQUEST_SET_ADDRESS\n");
374 break;
375 }
376 case USB_REQUEST_GET_DESCRIPTOR:
377 {
378 DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n");
379 break;
380 }
381 case USB_REQUEST_SET_DESCRIPTOR:
382 {
383 DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n");
384 break;
385 }
386 case USB_REQUEST_GET_CONFIGURATION:
387 {
388 DPRINT1("USB_REQUEST_GET_CONFIGURATION\n");
389 break;
390 }
391 case USB_REQUEST_SET_CONFIGURATION:
392 {
393 DPRINT1("USB_REQUEST_SET_CONFIGURATION\n");
394 break;
395 }
396 case USB_REQUEST_GET_INTERFACE:
397 {
398 DPRINT1("USB_REQUEST_GET_INTERFACE\n");
399 break;
400 }
401 case USB_REQUEST_SET_INTERFACE:
402 {
403 DPRINT1("USB_REQUEST_SET_INTERFACE\n");
404 break;
405 }
406 case USB_REQUEST_SYNC_FRAME:
407 {
408 DPRINT1("USB_REQUEST_SYNC_FRAME\n");
409 break;
410 }
411 }
412 break;
413 }
414 default:
415 {
416 DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
417 Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
418 }
419
420 }
421
422 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
423
424 Irp->IoStatus.Status = Status;
425 Irp->IoStatus.Information = Information;
426
427 IoCompleteRequest(Irp, IO_NO_INCREMENT);
428 KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
429 }
430
431 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
432 }
433