[FASTFAT] Implement write IOs defering.
[reactos.git] / drivers / usb / usbport / iface.c
1 /*
2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort interface functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
6 */
7
8 #include "usbport.h"
9
10 #define NDEBUG
11 #include <debug.h>
12
13 VOID
14 USB_BUSIFFN
15 USBI_InterfaceReference(IN PVOID BusContext)
16 {
17 DPRINT("USBI_InterfaceReference \n");
18 }
19
20 VOID
21 USB_BUSIFFN
22 USBI_InterfaceDereference(IN PVOID BusContext)
23 {
24 DPRINT("USBI_InterfaceDereference \n");
25 }
26
27 /* USB port driver Interface functions */
28
29 NTSTATUS
30 USB_BUSIFFN
31 USBHI_CreateUsbDevice(IN PVOID BusContext,
32 IN OUT PUSB_DEVICE_HANDLE *UsbdDeviceHandle,
33 IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
34 IN USHORT PortStatus,
35 IN USHORT PortNumber)
36 {
37 PDEVICE_OBJECT PdoDevice;
38 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
39 PUSB_DEVICE_HANDLE deviceHandle = NULL;
40 NTSTATUS Status;
41
42 DPRINT("USBHI_CreateUsbDevice: ... \n");
43
44 PdoDevice = BusContext;
45 PdoExtension = PdoDevice->DeviceExtension;
46
47 Status = USBPORT_CreateDevice(&deviceHandle,
48 PdoExtension->FdoDevice,
49 (PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
50 PortStatus,
51 PortNumber);
52
53 *UsbdDeviceHandle = deviceHandle;
54
55 return Status;
56 }
57
58 NTSTATUS
59 USB_BUSIFFN
60 USBHI_InitializeUsbDevice(IN PVOID BusContext,
61 OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
62 {
63 PDEVICE_OBJECT PdoDevice;
64 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
65
66 DPRINT("USBHI_InitializeUsbDevice \n");
67
68 PdoDevice = BusContext;
69 PdoExtension = PdoDevice->DeviceExtension;
70
71 return USBPORT_InitializeDevice((PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
72 PdoExtension->FdoDevice);
73 }
74
75 NTSTATUS
76 USB_BUSIFFN
77 USBHI_GetUsbDescriptors(IN PVOID BusContext,
78 IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
79 IN PUCHAR DeviceDescBuffer,
80 IN PULONG DeviceDescBufferLen,
81 IN PUCHAR ConfigDescBuffer,
82 IN PULONG ConfigDescBufferLen)
83 {
84 PDEVICE_OBJECT PdoDevice;
85 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
86 PUSBPORT_DEVICE_HANDLE DeviceHandle;
87
88 NTSTATUS Status;
89
90 DPRINT("USBHI_GetUsbDescriptors ...\n");
91
92 PdoDevice = BusContext;
93 PdoExtension = PdoDevice->DeviceExtension;
94 DeviceHandle = (PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle;
95
96 if (DeviceDescBuffer && *DeviceDescBufferLen)
97 {
98 if (*DeviceDescBufferLen > sizeof(USB_DEVICE_DESCRIPTOR))
99 *DeviceDescBufferLen = sizeof(USB_DEVICE_DESCRIPTOR);
100
101 RtlCopyMemory(DeviceDescBuffer,
102 &DeviceHandle->DeviceDescriptor,
103 *DeviceDescBufferLen);
104 }
105
106 Status = USBPORT_GetUsbDescriptor(DeviceHandle,
107 PdoExtension->FdoDevice,
108 USB_CONFIGURATION_DESCRIPTOR_TYPE,
109 ConfigDescBuffer,
110 ConfigDescBufferLen);
111
112 USBPORT_DumpingDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)DeviceDescBuffer);
113
114 return Status;
115 }
116
117 NTSTATUS
118 USB_BUSIFFN
119 USBHI_RemoveUsbDevice(IN PVOID BusContext,
120 IN OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle,
121 IN ULONG Flags)
122 {
123 PDEVICE_OBJECT PdoDevice;
124 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
125
126 DPRINT("USBHI_RemoveUsbDevice: UsbdDeviceHandle - %p, Flags - %x\n",
127 UsbdDeviceHandle,
128 Flags);
129
130 PdoDevice = BusContext;
131 PdoExtension = PdoDevice->DeviceExtension;
132
133 return USBPORT_RemoveDevice(PdoExtension->FdoDevice,
134 (PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
135 Flags);
136 }
137
138 NTSTATUS
139 USB_BUSIFFN
140 USBHI_RestoreUsbDevice(IN PVOID BusContext,
141 OUT PUSB_DEVICE_HANDLE OldUsbdDeviceHandle,
142 OUT PUSB_DEVICE_HANDLE NewUsbdDeviceHandle)
143 {
144 PDEVICE_OBJECT PdoDevice;
145 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
146
147 DPRINT("USBHI_RestoreUsbDevice: OldUsbdDeviceHandle - %p, NewUsbdDeviceHandle - %x\n",
148 OldUsbdDeviceHandle,
149 NewUsbdDeviceHandle);
150
151 PdoDevice = BusContext;
152 PdoExtension = PdoDevice->DeviceExtension;
153
154 return USBPORT_RestoreDevice(PdoExtension->FdoDevice,
155 (PUSBPORT_DEVICE_HANDLE)OldUsbdDeviceHandle,
156 (PUSBPORT_DEVICE_HANDLE)NewUsbdDeviceHandle);
157 }
158
159 NTSTATUS
160 USB_BUSIFFN
161 USBHI_QueryDeviceInformation(IN PVOID BusContext,
162 IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
163 OUT PVOID DeviceInfoBuffer,
164 IN ULONG DeviceInfoBufferLen,
165 OUT PULONG LenDataReturned)
166 {
167 PUSB_DEVICE_INFORMATION_0 DeviceInfo;
168 PUSBPORT_CONFIGURATION_HANDLE ConfigHandle;
169 PLIST_ENTRY InterfaceEntry;
170 PUSBPORT_DEVICE_HANDLE DeviceHandle;
171 ULONG NumberOfOpenPipes = 0;
172 PUSB_PIPE_INFORMATION_0 PipeInfo;
173 PUSBPORT_PIPE_HANDLE PipeHandle;
174 PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
175 ULONG ActualLength;
176 ULONG ix;
177
178 DPRINT("USBHI_QueryDeviceInformation: ... \n");
179
180 *LenDataReturned = 0;
181
182 if (DeviceInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
183 {
184 return STATUS_BUFFER_TOO_SMALL;
185 }
186
187 DeviceInfo = DeviceInfoBuffer;
188
189 if (DeviceInfo->InformationLevel > 0)
190 {
191 return STATUS_NOT_SUPPORTED;
192 }
193
194 DeviceHandle = UsbdDeviceHandle;
195 ConfigHandle = DeviceHandle->ConfigHandle;
196
197 if (ConfigHandle)
198 {
199 InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
200
201 while (InterfaceEntry &&
202 InterfaceEntry != &ConfigHandle->InterfaceHandleList)
203 {
204 InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
205 USBPORT_INTERFACE_HANDLE,
206 InterfaceLink);
207
208 NumberOfOpenPipes += InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
209
210 InterfaceEntry = InterfaceEntry->Flink;
211 }
212 }
213
214 ActualLength = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList) +
215 NumberOfOpenPipes * sizeof(USB_PIPE_INFORMATION_0);
216
217 if (DeviceInfoBufferLen < ActualLength)
218 {
219 DeviceInfo->ActualLength = ActualLength;
220 *LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
221
222 return STATUS_BUFFER_TOO_SMALL;
223 }
224
225 RtlZeroMemory(DeviceInfo, ActualLength);
226
227 DeviceInfo->InformationLevel = 0;
228 DeviceInfo->ActualLength = ActualLength;
229 DeviceInfo->DeviceAddress = DeviceHandle->DeviceAddress;
230 DeviceInfo->NumberOfOpenPipes = NumberOfOpenPipes;
231 DeviceInfo->DeviceSpeed = DeviceHandle->DeviceSpeed;
232
233 RtlCopyMemory(&DeviceInfo->DeviceDescriptor,
234 &DeviceHandle->DeviceDescriptor,
235 sizeof(USB_DEVICE_DESCRIPTOR));
236
237 USBPORT_DumpingDeviceDescriptor(&DeviceInfo->DeviceDescriptor);
238
239 if (DeviceHandle->DeviceSpeed == UsbFullSpeed ||
240 DeviceHandle->DeviceSpeed == UsbLowSpeed)
241 {
242 DeviceInfo->DeviceType = Usb11Device;
243 }
244 else if (DeviceHandle->DeviceSpeed == UsbHighSpeed)
245 {
246 DeviceInfo->DeviceType = Usb20Device;
247 }
248
249 DeviceInfo->CurrentConfigurationValue = 0;
250
251 if (!ConfigHandle)
252 {
253 *LenDataReturned = ActualLength;
254 return STATUS_SUCCESS;
255 }
256
257 DeviceInfo->CurrentConfigurationValue =
258 ConfigHandle->ConfigurationDescriptor->bConfigurationValue;
259
260 InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
261
262 while (InterfaceEntry &&
263 InterfaceEntry != &ConfigHandle->InterfaceHandleList)
264 {
265 InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
266 USBPORT_INTERFACE_HANDLE,
267 InterfaceLink);
268
269 if (InterfaceHandle->InterfaceDescriptor.bNumEndpoints > 0)
270 {
271 PipeInfo = &DeviceInfo->PipeList[0];
272 PipeHandle = &InterfaceHandle->PipeHandle[0];
273
274 for (ix = 0;
275 ix < InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
276 ix++)
277 {
278 if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)
279 {
280 PipeInfo->ScheduleOffset = 1;
281 }
282 else
283 {
284 PipeInfo->ScheduleOffset =
285 PipeHandle->Endpoint->EndpointProperties.ScheduleOffset;
286 }
287
288 RtlCopyMemory(&PipeInfo->EndpointDescriptor,
289 &PipeHandle->EndpointDescriptor,
290 sizeof(USB_ENDPOINT_DESCRIPTOR));
291
292 PipeInfo += 1;
293 PipeHandle += 1;
294 }
295 }
296
297 InterfaceEntry = InterfaceEntry->Flink;
298 }
299
300 *LenDataReturned = ActualLength;
301
302 return STATUS_SUCCESS;
303 }
304
305 NTSTATUS
306 USB_BUSIFFN
307 USBHI_GetControllerInformation(IN PVOID BusContext,
308 OUT PVOID ControllerInfoBuffer,
309 IN ULONG ControllerInfoBufferLen,
310 OUT PULONG LenDataReturned)
311 {
312 PDEVICE_OBJECT PdoDevice;
313 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
314 PDEVICE_OBJECT FdoDevice;
315 PUSBPORT_DEVICE_EXTENSION FdoExtension;
316 PUSB_CONTROLLER_INFORMATION_0 InfoBuffer;
317 NTSTATUS Status;
318
319 DPRINT("USBHI_GetControllerInformation: ControllerInfoBufferLen - %x\n",
320 ControllerInfoBufferLen);
321
322 PdoDevice = BusContext;
323 PdoExtension = PdoDevice->DeviceExtension;
324 FdoDevice = PdoExtension->FdoDevice;
325 FdoExtension = FdoDevice->DeviceExtension;
326
327 InfoBuffer = ControllerInfoBuffer;
328
329 *LenDataReturned = 0;
330
331 if (ControllerInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
332 {
333 Status = STATUS_BUFFER_TOO_SMALL;
334 return Status;
335 }
336
337 *LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
338
339 if (InfoBuffer->InformationLevel > 0)
340 {
341 Status = STATUS_NOT_SUPPORTED;
342 return Status;
343 }
344
345 InfoBuffer->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
346
347 if (ControllerInfoBufferLen >= sizeof(USB_CONTROLLER_INFORMATION_0))
348 {
349 InfoBuffer->SelectiveSuspendEnabled =
350 (FdoExtension->Flags & USBPORT_FLAG_SELECTIVE_SUSPEND) ==
351 USBPORT_FLAG_SELECTIVE_SUSPEND;
352 }
353
354 *LenDataReturned = sizeof(USB_CONTROLLER_INFORMATION_0);
355
356 return STATUS_SUCCESS;
357 }
358
359 NTSTATUS
360 USB_BUSIFFN
361 USBHI_ControllerSelectiveSuspend(IN PVOID BusContext,
362 IN BOOLEAN Enable)
363 {
364 PDEVICE_OBJECT PdoDevice;
365 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
366 PDEVICE_OBJECT FdoDevice;
367 PUSBPORT_DEVICE_EXTENSION FdoExtension;
368 ULONG Flags;
369 ULONG HcDisable;
370 NTSTATUS Status;
371
372 DPRINT("USBHI_ControllerSelectiveSuspend: Enable - %x\n", Enable);
373
374 PdoDevice = BusContext;
375 PdoExtension = PdoDevice->DeviceExtension;
376 FdoDevice = PdoExtension->FdoDevice;
377 FdoExtension = FdoDevice->DeviceExtension;
378
379 Flags = FdoExtension->Flags;
380
381 if (Flags & USBPORT_FLAG_BIOS_DISABLE_SS)
382 {
383 return STATUS_SUCCESS;
384 }
385
386 if (Enable)
387 {
388 FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
389 HcDisable = 0;
390 }
391 else
392 {
393 FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
394 HcDisable = 1;
395 }
396
397 Status = USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
398 TRUE,
399 REG_DWORD,
400 L"HcDisableSelectiveSuspend",
401 &HcDisable,
402 sizeof(HcDisable));
403
404 if (NT_SUCCESS(Status))
405 {
406 if (Enable)
407 FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
408 else
409 FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
410 }
411
412 return Status;
413 }
414
415 NTSTATUS
416 USB_BUSIFFN
417 USBHI_GetExtendedHubInformation(IN PVOID BusContext,
418 IN PDEVICE_OBJECT HubPhysicalDeviceObject,
419 IN OUT PVOID HubInformationBuffer,
420 IN ULONG HubInfoLen,
421 IN OUT PULONG LenDataReturned)
422 {
423 PDEVICE_OBJECT PdoDevice;
424 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
425 PDEVICE_OBJECT FdoDevice;
426 PUSBPORT_DEVICE_EXTENSION FdoExtension;
427 PUSBPORT_REGISTRATION_PACKET Packet;
428 ULONG NumPorts;
429 ULONG ix;
430 PUSB_EXTHUB_INFORMATION_0 HubInfoBuffer;
431 USB_PORT_STATUS_AND_CHANGE PortStatus;
432 ULONG PortAttrX;
433
434 DPRINT("USBHI_GetExtendedHubInformation: ... \n");
435
436 PdoDevice = BusContext;
437 PdoExtension = PdoDevice->DeviceExtension;
438 FdoDevice = PdoExtension->FdoDevice;
439 FdoExtension = FdoDevice->DeviceExtension;
440 Packet = &FdoExtension->MiniPortInterface->Packet;
441
442 HubInfoBuffer = HubInformationBuffer;
443 PortStatus.AsUlong32 = 0;
444
445 if (HubPhysicalDeviceObject != PdoDevice)
446 {
447 *LenDataReturned = 0;
448 return STATUS_NOT_SUPPORTED;
449 }
450
451 if (HubInfoLen < sizeof(USB_EXTHUB_INFORMATION_0))
452 {
453 *LenDataReturned = 0;
454 return STATUS_BUFFER_TOO_SMALL;
455 }
456
457 NumPorts = PdoExtension->RootHubDescriptors->Descriptor.bNumberOfPorts;
458 HubInfoBuffer->NumberOfPorts = NumPorts;
459
460 if (NumPorts == 0)
461 {
462 *LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
463 return STATUS_SUCCESS;
464 }
465
466 for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
467 {
468 HubInfoBuffer->Port[ix].PhysicalPortNumber = ix + 1;
469 HubInfoBuffer->Port[ix].PortLabelNumber = ix;
470 HubInfoBuffer->Port[ix].VidOverride = 0;
471 HubInfoBuffer->Port[ix].PidOverride = 0;
472 HubInfoBuffer->Port[ix].PortAttributes = 0;
473
474 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
475 {
476 HubInfoBuffer->Port[ix].PortAttributes = USB_PORTATTR_SHARED_USB2;
477
478 Packet->RH_GetPortStatus(FdoExtension->MiniPortExt,
479 ix + 1,
480 &PortStatus);
481
482 if (PortStatus.PortStatus.Usb20PortStatus.AsUshort16 & 0x8000)
483 {
484 HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_OWNED_BY_CC;
485 }
486 }
487 else
488 {
489 if (!(FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC))
490 {
491 continue;
492 }
493
494 if (USBPORT_FindUSB2Controller(FdoDevice))
495 {
496 HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_NO_OVERCURRENT_UI;
497 }
498 }
499 }
500
501 for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
502 {
503 PortAttrX = 0;
504
505 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
506 FdoExtension->CommonExtension.LowerPdoDevice,
507 FALSE,
508 L"PortAttrX",
509 sizeof(L"PortAttrX"),
510 &PortAttrX,
511 sizeof(PortAttrX));
512
513 HubInfoBuffer->Port[ix].PortAttributes |= PortAttrX;
514 }
515
516 *LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
517
518 return STATUS_SUCCESS;
519 }
520
521 NTSTATUS
522 USB_BUSIFFN
523 USBHI_GetRootHubSymbolicName(IN PVOID BusContext,
524 IN OUT PVOID HubInfoBuffer,
525 IN ULONG HubInfoBufferLen,
526 OUT PULONG HubNameActualLen)
527 {
528 PDEVICE_OBJECT PdoDevice;
529 UNICODE_STRING HubName;
530 PUNICODE_STRING InfoBuffer;
531 NTSTATUS Status;
532
533 DPRINT("USBHI_GetRootHubSymbolicName: ... \n");
534
535 PdoDevice = BusContext;
536
537 Status = USBPORT_GetSymbolicName(PdoDevice, &HubName);
538
539 if (HubInfoBufferLen < HubName.Length)
540 {
541 InfoBuffer = HubInfoBuffer;
542 InfoBuffer->Length = 0;
543 }
544 else
545 {
546 RtlCopyMemory(HubInfoBuffer, HubName.Buffer, HubName.Length);
547 }
548
549 *HubNameActualLen = HubName.Length;
550
551 if (NT_SUCCESS(Status))
552 RtlFreeUnicodeString(&HubName);
553
554 return Status;
555 }
556
557 PVOID
558 USB_BUSIFFN
559 USBHI_GetDeviceBusContext(IN PVOID BusContext,
560 IN PVOID DeviceHandle)
561 {
562 DPRINT1("USBHI_GetDeviceBusContext: UNIMPLEMENTED. FIXME. \n");
563 return NULL;
564 }
565
566 NTSTATUS
567 USB_BUSIFFN
568 USBHI_Initialize20Hub(IN PVOID BusContext,
569 IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
570 IN ULONG TtCount)
571 {
572 PDEVICE_OBJECT PdoDevice;
573 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
574
575 DPRINT("USBHI_Initialize20Hub: UsbdHubDeviceHandle - %p, TtCount - %x\n",
576 UsbdHubDeviceHandle,
577 TtCount);
578
579 PdoDevice = BusContext;
580 PdoExtension = PdoDevice->DeviceExtension;
581
582 return USBPORT_Initialize20Hub(PdoExtension->FdoDevice,
583 (PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
584 TtCount);
585 }
586
587 NTSTATUS
588 USB_BUSIFFN
589 USBHI_RootHubInitNotification(IN PVOID BusContext,
590 IN PVOID CallbackContext,
591 IN PRH_INIT_CALLBACK CallbackFunction)
592 {
593 PDEVICE_OBJECT PdoDevice;
594 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
595 PDEVICE_OBJECT FdoDevice;
596 PUSBPORT_DEVICE_EXTENSION FdoExtension;
597 KIRQL OldIrql;
598
599 DPRINT("USBHI_RootHubInitNotification \n");
600
601 PdoDevice = BusContext;
602 PdoExtension = PdoDevice->DeviceExtension;
603 FdoDevice = PdoExtension->FdoDevice;
604 FdoExtension = FdoDevice->DeviceExtension;
605
606 KeAcquireSpinLock(&FdoExtension->RootHubCallbackSpinLock, &OldIrql);
607 PdoExtension->RootHubInitContext = CallbackContext;
608 PdoExtension->RootHubInitCallback = CallbackFunction;
609 KeReleaseSpinLock(&FdoExtension->RootHubCallbackSpinLock, OldIrql);
610
611 return STATUS_SUCCESS;
612 }
613
614 VOID
615 USB_BUSIFFN
616 USBHI_FlushTransfers(IN PVOID BusContext,
617 OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
618 {
619 PDEVICE_OBJECT PdoDevice;
620 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
621
622 DPRINT("USBHI_FlushTransfers: ... \n");
623
624 PdoDevice = BusContext;
625 PdoExtension = PdoDevice->DeviceExtension;
626
627 USBPORT_BadRequestFlush(PdoExtension->FdoDevice);
628 }
629
630 VOID
631 USB_BUSIFFN
632 USBHI_SetDeviceHandleData(IN PVOID BusContext,
633 IN PVOID DeviceHandle,
634 IN PDEVICE_OBJECT UsbDevicePdo)
635 {
636 DPRINT1("USBHI_SetDeviceHandleData: UNIMPLEMENTED. FIXME. \n");
637 }
638
639 /* USB bus driver Interface functions */
640
641 VOID
642 USB_BUSIFFN
643 USBDI_GetUSBDIVersion(IN PVOID BusContext,
644 OUT PUSBD_VERSION_INFORMATION VersionInfo,
645 OUT PULONG HcdCapabilities)
646 {
647 DPRINT1("USBDI_GetUSBDIVersion: UNIMPLEMENTED. FIXME. \n");
648 }
649
650 NTSTATUS
651 USB_BUSIFFN
652 USBDI_QueryBusTime(IN PVOID BusContext,
653 OUT PULONG CurrentFrame)
654 {
655 DPRINT1("USBDI_QueryBusTime: UNIMPLEMENTED. FIXME. \n");
656 return STATUS_SUCCESS;
657 }
658
659 NTSTATUS
660 USB_BUSIFFN
661 USBDI_SubmitIsoOutUrb(IN PVOID BusContext,
662 IN PURB Urb)
663 {
664 DPRINT1("USBDI_SubmitIsoOutUrb: UNIMPLEMENTED. FIXME. \n");
665 return STATUS_SUCCESS;
666 }
667
668 NTSTATUS
669 USB_BUSIFFN
670 USBDI_QueryBusInformation(IN PVOID BusContext,
671 IN ULONG Level,
672 OUT PVOID BusInfoBuffer,
673 OUT PULONG BusInfoBufferLen,
674 OUT PULONG BusInfoActualLen)
675 {
676 PDEVICE_OBJECT PdoDevice;
677 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
678 PDEVICE_OBJECT FdoDevice;
679 PUSBPORT_DEVICE_EXTENSION FdoExtension;
680 SIZE_T Length;
681 PUSB_BUS_INFORMATION_LEVEL_1 Buffer1;
682
683 DPRINT("USBDI_QueryBusInformation: Level - %p\n", Level);
684
685 if ((Level != 0) && (Level != 1))
686 {
687 DPRINT1("USBDI_QueryBusInformation: Level should be 0 or 1\n");
688 return STATUS_NOT_SUPPORTED;
689 }
690
691 PdoDevice = BusContext;
692 PdoExtension = PdoDevice->DeviceExtension;
693 FdoDevice = PdoExtension->FdoDevice;
694 FdoExtension = FdoDevice->DeviceExtension;
695
696 if (Level == 0)
697 {
698 if (BusInfoActualLen)
699 *BusInfoActualLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
700
701 if (*BusInfoBufferLen < sizeof(USB_BUS_INFORMATION_LEVEL_0))
702 {
703 return STATUS_BUFFER_TOO_SMALL;
704 }
705
706 *BusInfoBufferLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
707
708 //Buffer0 = BusInfoBuffer;
709 DPRINT1("USBDI_QueryBusInformation: LEVEL_0 UNIMPLEMENTED. FIXME\n");
710 //Buffer0->TotalBandwidth = USBPORT_GetTotalBandwidth();
711 //Buffer0->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
712
713 return STATUS_SUCCESS;
714 }
715
716 if (Level == 1)
717 {
718 Length = sizeof(USB_BUS_INFORMATION_LEVEL_1) +
719 FdoExtension->CommonExtension.SymbolicLinkName.Length;
720
721 if (BusInfoActualLen)
722 *BusInfoActualLen = Length;
723
724 if (*BusInfoBufferLen < Length)
725 {
726 return STATUS_BUFFER_TOO_SMALL;
727 }
728
729 *BusInfoBufferLen = Length;
730
731 Buffer1 = BusInfoBuffer;
732 DPRINT1("USBDI_QueryBusInformation: LEVEL_1 UNIMPLEMENTED. FIXME\n");
733 //Buffer1->TotalBandwidth = USBPORT_GetTotalBandwidth();
734 //Buffer1->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
735 Buffer1->ControllerNameLength = FdoExtension->CommonExtension.SymbolicLinkName.Length;
736
737 RtlCopyMemory(&Buffer1->ControllerNameUnicodeString,
738 FdoExtension->CommonExtension.SymbolicLinkName.Buffer,
739 FdoExtension->CommonExtension.SymbolicLinkName.Length);
740
741 return STATUS_SUCCESS;
742 }
743
744 return STATUS_SUCCESS;
745 }
746
747 BOOLEAN
748 USB_BUSIFFN
749 USBDI_IsDeviceHighSpeed(IN PVOID BusContext)
750 {
751 PDEVICE_OBJECT PdoDevice;
752 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
753 PDEVICE_OBJECT FdoDevice;
754 PUSBPORT_DEVICE_EXTENSION FdoExtension;
755 PUSBPORT_REGISTRATION_PACKET Packet;
756
757 DPRINT("USBDI_IsDeviceHighSpeed: ... \n");
758
759 PdoDevice = BusContext;
760 PdoExtension = PdoDevice->DeviceExtension;
761 FdoDevice = PdoExtension->FdoDevice;
762 FdoExtension = FdoDevice->DeviceExtension;
763 Packet = &FdoExtension->MiniPortInterface->Packet;
764
765 return (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2) != 0;
766 }
767
768 NTSTATUS
769 USB_BUSIFFN
770 USBDI_EnumLogEntry(IN PVOID BusContext,
771 IN ULONG DriverTag,
772 IN ULONG EnumTag,
773 IN ULONG P1,
774 IN ULONG P2)
775 {
776 DPRINT1("USBDI_EnumLogEntry: UNIMPLEMENTED. FIXME. \n");
777 return STATUS_SUCCESS;
778 }
779
780 NTSTATUS
781 NTAPI
782 USBPORT_PdoQueryInterface(IN PDEVICE_OBJECT FdoDevice,
783 IN PDEVICE_OBJECT PdoDevice,
784 IN PIRP Irp)
785 {
786 PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
787 PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
788 PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
789 UNICODE_STRING GuidBuffer;
790 NTSTATUS Status;
791
792 DPRINT("USBPORT_PdoQueryInterface: ... \n");
793
794 if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
795 &USB_BUS_INTERFACE_HUB_GUID))
796 {
797 /* Get request parameters */
798 InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)IoStack->Parameters.QueryInterface.Interface;
799 InterfaceHub->Version = IoStack->Parameters.QueryInterface.Version;
800
801 /* Check version */
802 if (IoStack->Parameters.QueryInterface.Version >= 6)
803 {
804 DPRINT1("USB_BUS_INTERFACE_HUB_GUID version %x not supported!\n",
805 IoStack->Parameters.QueryInterface.Version);
806
807 return STATUS_NOT_SUPPORTED; // Version not supported
808 }
809
810 /* Interface version 0 */
811 InterfaceHub->Size = IoStack->Parameters.QueryInterface.Size;
812 InterfaceHub->BusContext = PdoDevice;
813
814 InterfaceHub->InterfaceReference = USBI_InterfaceReference;
815 InterfaceHub->InterfaceDereference = USBI_InterfaceDereference;
816
817 /* Interface version 1 */
818 if (IoStack->Parameters.QueryInterface.Version >= 1)
819 {
820 InterfaceHub->CreateUsbDevice = USBHI_CreateUsbDevice;
821 InterfaceHub->InitializeUsbDevice = USBHI_InitializeUsbDevice;
822 InterfaceHub->GetUsbDescriptors = USBHI_GetUsbDescriptors;
823 InterfaceHub->RemoveUsbDevice = USBHI_RemoveUsbDevice;
824 InterfaceHub->RestoreUsbDevice = USBHI_RestoreUsbDevice;
825 InterfaceHub->QueryDeviceInformation = USBHI_QueryDeviceInformation;
826 }
827
828 /* Interface version 2 */
829 if (IoStack->Parameters.QueryInterface.Version >= 2)
830 {
831 InterfaceHub->GetControllerInformation = USBHI_GetControllerInformation;
832 InterfaceHub->ControllerSelectiveSuspend = USBHI_ControllerSelectiveSuspend;
833 InterfaceHub->GetExtendedHubInformation = USBHI_GetExtendedHubInformation;
834 InterfaceHub->GetRootHubSymbolicName = USBHI_GetRootHubSymbolicName;
835 InterfaceHub->GetDeviceBusContext = USBHI_GetDeviceBusContext;
836 InterfaceHub->Initialize20Hub = USBHI_Initialize20Hub;
837 }
838
839 /* Interface version 3 */
840 if (IoStack->Parameters.QueryInterface.Version >= 3)
841 InterfaceHub->RootHubInitNotification = USBHI_RootHubInitNotification;
842
843 /* Interface version 4 */
844 if (IoStack->Parameters.QueryInterface.Version >= 4)
845 InterfaceHub->FlushTransfers = USBHI_FlushTransfers;
846
847 /* Interface version 5 */
848 if (IoStack->Parameters.QueryInterface.Version >= 5)
849 InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
850
851 /* Request completed */
852 return STATUS_SUCCESS;
853 }
854 else if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
855 &USB_BUS_INTERFACE_USBDI_GUID))
856 {
857 /* Get request parameters */
858 InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2)IoStack->Parameters.QueryInterface.Interface;
859 InterfaceDI->Version = IoStack->Parameters.QueryInterface.Version;
860
861 /* Check version */
862 if (IoStack->Parameters.QueryInterface.Version >= 3)
863 {
864 DPRINT1("USB_BUS_INTERFACE_USBDI_GUID version %x not supported!\n",
865 IoStack->Parameters.QueryInterface.Version);
866
867 return STATUS_NOT_SUPPORTED; // Version not supported
868 }
869
870 /* Interface version 0 */
871 InterfaceDI->Size = IoStack->Parameters.QueryInterface.Size;
872 InterfaceDI->BusContext = PdoDevice;
873 InterfaceDI->InterfaceReference = USBI_InterfaceReference;
874 InterfaceDI->InterfaceDereference = USBI_InterfaceDereference;
875 InterfaceDI->GetUSBDIVersion = USBDI_GetUSBDIVersion;
876 InterfaceDI->QueryBusTime = USBDI_QueryBusTime;
877 InterfaceDI->SubmitIsoOutUrb = USBDI_SubmitIsoOutUrb;
878 InterfaceDI->QueryBusInformation = USBDI_QueryBusInformation;
879
880 /* Interface version 1 */
881 if (IoStack->Parameters.QueryInterface.Version >= 1)
882 InterfaceDI->IsDeviceHighSpeed = USBDI_IsDeviceHighSpeed;
883
884 /* Interface version 2 */
885 if (IoStack->Parameters.QueryInterface.Version >= 2)
886 InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
887
888 return STATUS_SUCCESS;
889 }
890 else
891 {
892 /* Convert GUID to string */
893 Status = RtlStringFromGUID(IoStack->Parameters.QueryInterface.InterfaceType,
894 &GuidBuffer);
895
896 if (NT_SUCCESS(Status))
897 {
898 /* Print interface */
899 DPRINT1("HandleQueryInterface UNKNOWN INTERFACE GUID: %wZ Version %x\n",
900 &GuidBuffer,
901 IoStack->Parameters.QueryInterface.Version);
902
903 RtlFreeUnicodeString(&GuidBuffer); // Free GUID buffer
904 }
905 }
906
907 return STATUS_NOT_SUPPORTED;
908 }