1 /*
2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort main driver 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 #define NDEBUG_USBPORT_CORE
14 #define NDEBUG_USBPORT_INTERRUPT
15 #define NDEBUG_USBPORT_TIMER
16 #include "usbdebug.h"
17
18 LIST_ENTRY USBPORT_MiniPortDrivers = {NULL, NULL};
19 LIST_ENTRY USBPORT_USB1FdoList = {NULL, NULL};
20 LIST_ENTRY USBPORT_USB2FdoList = {NULL, NULL};
21
22 KSPIN_LOCK USBPORT_SpinLock;
23 BOOLEAN USBPORT_Initialized = FALSE;
24
25 PDEVICE_OBJECT
26 NTAPI
USBPORT_FindUSB2Controller(IN PDEVICE_OBJECT FdoDevice)27 USBPORT_FindUSB2Controller(IN PDEVICE_OBJECT FdoDevice)
28 {
29 PUSBPORT_DEVICE_EXTENSION FdoExtension;
30 PUSBPORT_DEVICE_EXTENSION USB2FdoExtension;
31 KIRQL OldIrql;
32 PLIST_ENTRY USB2FdoEntry;
33 PDEVICE_OBJECT USB2FdoDevice = NULL;
34
35 DPRINT("USBPORT_FindUSB2Controller: FdoDevice - %p\n", FdoDevice);
36
37 FdoExtension = FdoDevice->DeviceExtension;
38
39 KeAcquireSpinLock(&USBPORT_SpinLock, &OldIrql);
40
41 USB2FdoEntry = USBPORT_USB2FdoList.Flink;
42
43 while (USB2FdoEntry && USB2FdoEntry != &USBPORT_USB2FdoList)
44 {
45 USB2FdoExtension = CONTAINING_RECORD(USB2FdoEntry,
46 USBPORT_DEVICE_EXTENSION,
47 ControllerLink);
48
49 if (USB2FdoExtension->BusNumber == FdoExtension->BusNumber &&
50 USB2FdoExtension->PciDeviceNumber == FdoExtension->PciDeviceNumber)
51 {
52 USB2FdoDevice = USB2FdoExtension->CommonExtension.SelfDevice;
53 break;
54 }
55
56 USB2FdoEntry = USB2FdoEntry->Flink;
57 }
58
59 KeReleaseSpinLock(&USBPORT_SpinLock, OldIrql);
60
61 return USB2FdoDevice;
62 }
63
64 VOID
65 NTAPI
USBPORT_AddUSB1Fdo(IN PDEVICE_OBJECT FdoDevice)66 USBPORT_AddUSB1Fdo(IN PDEVICE_OBJECT FdoDevice)
67 {
68 PUSBPORT_DEVICE_EXTENSION FdoExtension;
69
70 DPRINT("USBPORT_AddUSB1Fdo: FdoDevice - %p\n", FdoDevice);
71
72 FdoExtension = FdoDevice->DeviceExtension;
73 FdoExtension->Flags |= USBPORT_FLAG_REGISTERED_FDO;
74
75 ExInterlockedInsertTailList(&USBPORT_USB1FdoList,
76 &FdoExtension->ControllerLink,
77 &USBPORT_SpinLock);
78 }
79
80 VOID
81 NTAPI
USBPORT_AddUSB2Fdo(IN PDEVICE_OBJECT FdoDevice)82 USBPORT_AddUSB2Fdo(IN PDEVICE_OBJECT FdoDevice)
83 {
84 PUSBPORT_DEVICE_EXTENSION FdoExtension;
85
86 DPRINT("USBPORT_AddUSB2Fdo: FdoDevice - %p\n", FdoDevice);
87
88 FdoExtension = FdoDevice->DeviceExtension;
89 FdoExtension->Flags |= USBPORT_FLAG_REGISTERED_FDO;
90
91 ExInterlockedInsertTailList(&USBPORT_USB2FdoList,
92 &FdoExtension->ControllerLink,
93 &USBPORT_SpinLock);
94 }
95
96 VOID
97 NTAPI
USBPORT_RemoveUSBxFdo(IN PDEVICE_OBJECT FdoDevice)98 USBPORT_RemoveUSBxFdo(IN PDEVICE_OBJECT FdoDevice)
99 {
100 PUSBPORT_DEVICE_EXTENSION FdoExtension;
101 KIRQL OldIrql;
102
103 DPRINT("USBPORT_RemoveUSBxFdo: FdoDevice - %p\n", FdoDevice);
104
105 FdoExtension = FdoDevice->DeviceExtension;
106
107 KeAcquireSpinLock(&USBPORT_SpinLock, &OldIrql);
108 RemoveEntryList(&FdoExtension->ControllerLink);
109 KeReleaseSpinLock(&USBPORT_SpinLock, OldIrql);
110
111 FdoExtension->Flags &= ~USBPORT_FLAG_REGISTERED_FDO;
112
113 FdoExtension->ControllerLink.Flink = NULL;
114 FdoExtension->ControllerLink.Blink = NULL;
115 }
116
117 BOOLEAN
118 NTAPI
USBPORT_IsCompanionFdoExtension(IN PDEVICE_OBJECT USB2FdoDevice,IN PUSBPORT_DEVICE_EXTENSION USB1FdoExtension)119 USBPORT_IsCompanionFdoExtension(IN PDEVICE_OBJECT USB2FdoDevice,
120 IN PUSBPORT_DEVICE_EXTENSION USB1FdoExtension)
121 {
122 PUSBPORT_DEVICE_EXTENSION USB2FdoExtension;
123
124 DPRINT("USBPORT_IsCompanionFdoExtension: USB2Fdo - %p, USB1FdoExtension - %p\n",
125 USB2FdoDevice,
126 USB1FdoExtension);
127
128 USB2FdoExtension = USB2FdoDevice->DeviceExtension;
129
130 return USB2FdoExtension->BusNumber == USB1FdoExtension->BusNumber &&
131 USB2FdoExtension->PciDeviceNumber == USB1FdoExtension->PciDeviceNumber;
132 }
133
134 PDEVICE_RELATIONS
135 NTAPI
USBPORT_FindCompanionControllers(IN PDEVICE_OBJECT USB2FdoDevice,IN BOOLEAN IsObRefer,IN BOOLEAN IsFDOsReturned)136 USBPORT_FindCompanionControllers(IN PDEVICE_OBJECT USB2FdoDevice,
137 IN BOOLEAN IsObRefer,
138 IN BOOLEAN IsFDOsReturned)
139 {
140 PLIST_ENTRY USB1FdoList;
141 PUSBPORT_DEVICE_EXTENSION USB1FdoExtension;
142 ULONG NumControllers = 0;
143 PDEVICE_OBJECT * Entry;
144 PDEVICE_RELATIONS ControllersList = NULL;
145 KIRQL OldIrql;
146
147 DPRINT("USBPORT_FindCompanionControllers: USB2Fdo - %p, IsObRefer - %x, IsFDOs - %x\n",
148 USB2FdoDevice,
149 IsObRefer,
150 IsFDOsReturned);
151
152 KeAcquireSpinLock(&USBPORT_SpinLock, &OldIrql);
153
154 USB1FdoList = USBPORT_USB1FdoList.Flink;
155
156 while (USB1FdoList && USB1FdoList != &USBPORT_USB1FdoList)
157 {
158 USB1FdoExtension = CONTAINING_RECORD(USB1FdoList,
159 USBPORT_DEVICE_EXTENSION,
160 ControllerLink);
161
162 if (USB1FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC &&
163 USBPORT_IsCompanionFdoExtension(USB2FdoDevice, USB1FdoExtension))
164 {
165 ++NumControllers;
166 }
167
168 USB1FdoList = USB1FdoExtension->ControllerLink.Flink;
169 }
170
171 DPRINT("USBPORT_FindCompanionControllers: NumControllers - %x\n",
172 NumControllers);
173
174 if (!NumControllers)
175 {
176 goto Exit;
177 }
178
179 ControllersList = ExAllocatePoolWithTag(NonPagedPool,
180 NumControllers * sizeof(DEVICE_RELATIONS),
181 USB_PORT_TAG);
182
183 if (!ControllersList)
184 {
185 goto Exit;
186 }
187
188 RtlZeroMemory(ControllersList, NumControllers * sizeof(DEVICE_RELATIONS));
189
190 ControllersList->Count = NumControllers;
191
192 USB1FdoList = USBPORT_USB1FdoList.Flink;
193
194 Entry = &ControllersList->Objects[0];
195
196 while (USB1FdoList && USB1FdoList != &USBPORT_USB1FdoList)
197 {
198 USB1FdoExtension = CONTAINING_RECORD(USB1FdoList,
199 USBPORT_DEVICE_EXTENSION,
200 ControllerLink);
201
202 if (USB1FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC &&
203 USBPORT_IsCompanionFdoExtension(USB2FdoDevice, USB1FdoExtension))
204 {
205 *Entry = USB1FdoExtension->CommonExtension.LowerPdoDevice;
206
207 if (IsObRefer)
208 {
209 ObReferenceObject(USB1FdoExtension->CommonExtension.LowerPdoDevice);
210 }
211
212 if (IsFDOsReturned)
213 {
214 *Entry = USB1FdoExtension->CommonExtension.SelfDevice;
215 }
216
217 ++Entry;
218 }
219
220 USB1FdoList = USB1FdoExtension->ControllerLink.Flink;
221 }
222
223 Exit:
224
225 KeReleaseSpinLock(&USBPORT_SpinLock, OldIrql);
226
227 return ControllersList;
228 }
229
230 MPSTATUS
231 NTAPI
USBPORT_NtStatusToMpStatus(NTSTATUS NtStatus)232 USBPORT_NtStatusToMpStatus(NTSTATUS NtStatus)
233 {
234 DPRINT("USBPORT_NtStatusToMpStatus: NtStatus - %x\n", NtStatus);
235
236 if (NtStatus == STATUS_SUCCESS)
237 {
238 return MP_STATUS_SUCCESS;
239 }
240 else
241 {
242 return MP_STATUS_UNSUCCESSFUL;
243 }
244 }
245
246 NTSTATUS
247 NTAPI
USBPORT_SetRegistryKeyValue(IN PDEVICE_OBJECT DeviceObject,IN BOOL UseDriverKey,IN ULONG Type,IN PCWSTR ValueNameString,IN PVOID Data,IN ULONG DataSize)248 USBPORT_SetRegistryKeyValue(IN PDEVICE_OBJECT DeviceObject,
249 IN BOOL UseDriverKey,
250 IN ULONG Type,
251 IN PCWSTR ValueNameString,
252 IN PVOID Data,
253 IN ULONG DataSize)
254 {
255 UNICODE_STRING ValueName;
256 HANDLE KeyHandle;
257 NTSTATUS Status;
258
259 DPRINT("USBPORT_SetRegistryKeyValue: ValueNameString - %S\n",
260 ValueNameString);
261
262 if (UseDriverKey)
263 {
264 Status = IoOpenDeviceRegistryKey(DeviceObject,
265 PLUGPLAY_REGKEY_DRIVER,
266 STANDARD_RIGHTS_ALL,
267 &KeyHandle);
268 }
269 else
270 {
271 Status = IoOpenDeviceRegistryKey(DeviceObject,
272 PLUGPLAY_REGKEY_DEVICE,
273 STANDARD_RIGHTS_ALL,
274 &KeyHandle);
275 }
276
277 if (NT_SUCCESS(Status))
278 {
279 RtlInitUnicodeString(&ValueName, ValueNameString);
280
281 Status = ZwSetValueKey(KeyHandle,
282 &ValueName,
283 0,
284 Type,
285 Data,
286 DataSize);
287
288 ZwClose(KeyHandle);
289 }
290
291 return Status;
292 }
293
294 NTSTATUS
295 NTAPI
USBPORT_GetRegistryKeyValueFullInfo(IN PDEVICE_OBJECT FdoDevice,IN PDEVICE_OBJECT PdoDevice,IN BOOL UseDriverKey,IN PCWSTR SourceString,IN ULONG LengthStr,IN PVOID Buffer,IN ULONG BufferLength)296 USBPORT_GetRegistryKeyValueFullInfo(IN PDEVICE_OBJECT FdoDevice,
297 IN PDEVICE_OBJECT PdoDevice,
298 IN BOOL UseDriverKey,
299 IN PCWSTR SourceString,
300 IN ULONG LengthStr,
301 IN PVOID Buffer,
302 IN ULONG BufferLength)
303 {
304 NTSTATUS Status;
305 PKEY_VALUE_FULL_INFORMATION KeyValue;
306 UNICODE_STRING ValueName;
307 HANDLE KeyHandle;
308 ULONG LengthKey;
309
310 DPRINT("USBPORT_GetRegistryKeyValue: UseDriverKey - %x, SourceString - %S, LengthStr - %x, Buffer - %p, BufferLength - %x\n",
311 UseDriverKey,
312 SourceString,
313 LengthStr,
314 Buffer,
315 BufferLength);
316
317 if (UseDriverKey)
318 {
319 Status = IoOpenDeviceRegistryKey(PdoDevice,
320 PLUGPLAY_REGKEY_DRIVER,
321 STANDARD_RIGHTS_ALL,
322 &KeyHandle);
323 }
324 else
325 {
326 Status = IoOpenDeviceRegistryKey(PdoDevice,
327 PLUGPLAY_REGKEY_DEVICE,
328 STANDARD_RIGHTS_ALL,
329 &KeyHandle);
330 }
331
332 if (NT_SUCCESS(Status))
333 {
334 RtlInitUnicodeString(&ValueName, SourceString);
335
336 LengthKey = sizeof(KEY_VALUE_FULL_INFORMATION) +
337 LengthStr +
338 BufferLength;
339
340 KeyValue = ExAllocatePoolWithTag(PagedPool,
341 LengthKey,
342 USB_PORT_TAG);
343
344 if (KeyValue)
345 {
346 RtlZeroMemory(KeyValue, LengthKey);
347
348 Status = ZwQueryValueKey(KeyHandle,
349 &ValueName,
350 KeyValueFullInformation,
351 KeyValue,
352 LengthKey,
353 &LengthKey);
354
355 if (NT_SUCCESS(Status))
356 {
357 RtlCopyMemory(Buffer,
358 (PUCHAR)KeyValue + KeyValue->DataOffset,
359 BufferLength);
360 }
361
362 ExFreePoolWithTag(KeyValue, USB_PORT_TAG);
363 }
364
365 ZwClose(KeyHandle);
366 }
367
368 return Status;
369 }
370
371 MPSTATUS
372 NTAPI
USBPORT_GetMiniportRegistryKeyValue(IN PVOID MiniPortExtension,IN BOOL UseDriverKey,IN PCWSTR SourceString,IN SIZE_T LengthStr,IN PVOID Buffer,IN SIZE_T BufferLength)373 USBPORT_GetMiniportRegistryKeyValue(IN PVOID MiniPortExtension,
374 IN BOOL UseDriverKey,
375 IN PCWSTR SourceString,
376 IN SIZE_T LengthStr,
377 IN PVOID Buffer,
378 IN SIZE_T BufferLength)
379 {
380 PUSBPORT_DEVICE_EXTENSION FdoExtension;
381 PDEVICE_OBJECT FdoDevice;
382 NTSTATUS Status;
383
384 DPRINT("USBPORT_GetMiniportRegistryKeyValue: MiniPortExtension - %p, UseDriverKey - %x, SourceString - %S, LengthStr - %x, Buffer - %p, BufferLength - %x\n",
385 MiniPortExtension,
386 UseDriverKey,
387 SourceString,
388 LengthStr,
389 Buffer,
390 BufferLength);
391
392 FdoExtension = (PUSBPORT_DEVICE_EXTENSION)((ULONG_PTR)MiniPortExtension -
393 sizeof(USBPORT_DEVICE_EXTENSION));
394
395 FdoDevice = FdoExtension->CommonExtension.SelfDevice;
396
397 Status = USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
398 FdoExtension->CommonExtension.LowerPdoDevice,
399 UseDriverKey,
400 SourceString,
401 LengthStr,
402 Buffer,
403 BufferLength);
404
405 return USBPORT_NtStatusToMpStatus(Status);
406 }
407
408 NTSTATUS
409 NTAPI
USBPORT_GetSetConfigSpaceData(IN PDEVICE_OBJECT FdoDevice,IN BOOLEAN IsReadData,IN PVOID Buffer,IN ULONG Offset,IN ULONG Length)410 USBPORT_GetSetConfigSpaceData(IN PDEVICE_OBJECT FdoDevice,
411 IN BOOLEAN IsReadData,
412 IN PVOID Buffer,
413 IN ULONG Offset,
414 IN ULONG Length)
415 {
416 PUSBPORT_DEVICE_EXTENSION FdoExtension;
417 ULONG BytesReadWrite;
418
419 DPRINT("USBPORT_GetSetConfigSpaceData ...\n");
420
421 FdoExtension = FdoDevice->DeviceExtension;
422
423 BytesReadWrite = Length;
424
425 if (IsReadData)
426 {
427 RtlZeroMemory(Buffer, Length);
428
429 BytesReadWrite = (*FdoExtension->BusInterface.GetBusData)
430 (FdoExtension->BusInterface.Context,
431 PCI_WHICHSPACE_CONFIG,
432 Buffer,
433 Offset,
434 Length);
435 }
436 else
437 {
438 BytesReadWrite = (*FdoExtension->BusInterface.SetBusData)
439 (FdoExtension->BusInterface.Context,
440 PCI_WHICHSPACE_CONFIG,
441 Buffer,
442 Offset,
443 Length);
444 }
445
446 if (BytesReadWrite == Length)
447 {
448 return STATUS_SUCCESS;
449 }
450
451 return STATUS_UNSUCCESSFUL;
452 }
453
454 MPSTATUS
455 NTAPI
USBPORT_ReadWriteConfigSpace(IN PVOID MiniPortExtension,IN BOOLEAN IsReadData,IN PVOID Buffer,IN ULONG Offset,IN ULONG Length)456 USBPORT_ReadWriteConfigSpace(IN PVOID MiniPortExtension,
457 IN BOOLEAN IsReadData,
458 IN PVOID Buffer,
459 IN ULONG Offset,
460 IN ULONG Length)
461 {
462 NTSTATUS Status;
463 PUSBPORT_DEVICE_EXTENSION FdoExtension;
464 PDEVICE_OBJECT FdoDevice;
465
466 DPRINT("USBPORT_ReadWriteConfigSpace: ...\n");
467
468 //FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION));
469 FdoExtension = (PUSBPORT_DEVICE_EXTENSION)((ULONG_PTR)MiniPortExtension -
470 sizeof(USBPORT_DEVICE_EXTENSION));
471
472 FdoDevice = FdoExtension->CommonExtension.SelfDevice;
473
474 Status = USBPORT_GetSetConfigSpaceData(FdoDevice,
475 IsReadData,
476 Buffer,
477 Offset,
478 Length);
479
480 return USBPORT_NtStatusToMpStatus(Status);
481 }
482
483 NTSTATUS
484 NTAPI
USBPORT_USBDStatusToNtStatus(IN PURB Urb,IN USBD_STATUS USBDStatus)485 USBPORT_USBDStatusToNtStatus(IN PURB Urb,
486 IN USBD_STATUS USBDStatus)
487 {
488 NTSTATUS Status;
489
490 if (USBD_ERROR(USBDStatus))
491 {
492 DPRINT1("USBPORT_USBDStatusToNtStatus: Urb - %p, USBDStatus - %x\n",
493 Urb,
494 USBDStatus);
495 }
496
497 if (Urb)
498 Urb->UrbHeader.Status = USBDStatus;
499
500 switch (USBDStatus)
501 {
502 case USBD_STATUS_SUCCESS:
503 Status = STATUS_SUCCESS;
504 break;
505
506 case USBD_STATUS_INSUFFICIENT_RESOURCES:
507 Status = STATUS_INSUFFICIENT_RESOURCES;
508 break;
509
510 case USBD_STATUS_DEVICE_GONE:
511 Status = STATUS_DEVICE_NOT_CONNECTED;
512 break;
513
514 case USBD_STATUS_CANCELED:
515 Status = STATUS_CANCELLED;
516 break;
517
518 case USBD_STATUS_NOT_SUPPORTED:
519 Status = STATUS_NOT_SUPPORTED;
520 break;
521
522 case USBD_STATUS_INVALID_URB_FUNCTION:
523 case USBD_STATUS_INVALID_PARAMETER:
524 case USBD_STATUS_INVALID_PIPE_HANDLE:
525 case USBD_STATUS_BAD_START_FRAME:
526 Status = STATUS_INVALID_PARAMETER;
527 break;
528
529 default:
530 if (USBD_ERROR(USBDStatus))
531 Status = STATUS_UNSUCCESSFUL;
532 else
533 Status = STATUS_SUCCESS;
534
535 break;
536 }
537
538 return Status;
539 }
540
541 NTSTATUS
542 NTAPI
USBPORT_Wait(IN PVOID MiniPortExtension,IN ULONG Milliseconds)543 USBPORT_Wait(IN PVOID MiniPortExtension,
544 IN ULONG Milliseconds)
545 {
546 LARGE_INTEGER Interval = {{0, 0}};
547
548 DPRINT("USBPORT_Wait: Milliseconds - %x\n", Milliseconds);
549 Interval.QuadPart -= 10000 * Milliseconds + (KeQueryTimeIncrement() - 1);
550 return KeDelayExecutionThread(KernelMode, FALSE, &Interval);
551 }
552
553 VOID
554 NTAPI
USBPORT_MiniportInterrupts(IN PDEVICE_OBJECT FdoDevice,IN BOOLEAN IsEnable)555 USBPORT_MiniportInterrupts(IN PDEVICE_OBJECT FdoDevice,
556 IN BOOLEAN IsEnable)
557 {
558 PUSBPORT_DEVICE_EXTENSION FdoExtension;
559 PUSBPORT_REGISTRATION_PACKET Packet;
560 BOOLEAN IsLock;
561 KIRQL OldIrql;
562
563 DPRINT_INT("USBPORT_MiniportInterrupts: IsEnable - %p\n", IsEnable);
564
565 FdoExtension = FdoDevice->DeviceExtension;
566 Packet = &FdoExtension->MiniPortInterface->Packet;
567
568 IsLock = (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_NOT_LOCK_INT) == 0;
569
570 if (IsLock)
571 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
572
573 if (IsEnable)
574 {
575 FdoExtension->Flags |= USBPORT_FLAG_INTERRUPT_ENABLED;
576 Packet->EnableInterrupts(FdoExtension->MiniPortExt);
577 }
578 else
579 {
580 Packet->DisableInterrupts(FdoExtension->MiniPortExt);
581 FdoExtension->Flags &= ~USBPORT_FLAG_INTERRUPT_ENABLED;
582 }
583
584 if (IsLock)
585 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
586 }
587
588 VOID
589 NTAPI
USBPORT_SoftInterruptDpc(IN PRKDPC Dpc,IN PVOID DeferredContext,IN PVOID SystemArgument1,IN PVOID SystemArgument2)590 USBPORT_SoftInterruptDpc(IN PRKDPC Dpc,
591 IN PVOID DeferredContext,
592 IN PVOID SystemArgument1,
593 IN PVOID SystemArgument2)
594 {
595 PDEVICE_OBJECT FdoDevice;
596 PUSBPORT_DEVICE_EXTENSION FdoExtension;
597
598 DPRINT_INT("USBPORT_SoftInterruptDpc: ...\n");
599
600 FdoDevice = DeferredContext;
601 FdoExtension = FdoDevice->DeviceExtension;
602
603 if (!KeInsertQueueDpc(&FdoExtension->IsrDpc, NULL, (PVOID)1))
604 {
605 InterlockedDecrement(&FdoExtension->IsrDpcCounter);
606 }
607 }
608
609 VOID
610 NTAPI
USBPORT_SoftInterrupt(IN PDEVICE_OBJECT FdoDevice)611 USBPORT_SoftInterrupt(IN PDEVICE_OBJECT FdoDevice)
612 {
613 PUSBPORT_DEVICE_EXTENSION FdoExtension;
614 LARGE_INTEGER DueTime = {{0, 0}};
615
616 DPRINT_INT("USBPORT_SoftInterrupt: ...\n");
617
618 FdoExtension = FdoDevice->DeviceExtension;
619
620 KeInitializeTimer(&FdoExtension->TimerSoftInterrupt);
621
622 KeInitializeDpc(&FdoExtension->SoftInterruptDpc,
623 USBPORT_SoftInterruptDpc,
624 FdoDevice);
625
626 DueTime.QuadPart -= 10000 + (KeQueryTimeIncrement() - 1);
627
628 KeSetTimer(&FdoExtension->TimerSoftInterrupt,
629 DueTime,
630 &FdoExtension->SoftInterruptDpc);
631 }
632
633 VOID
634 NTAPI
USBPORT_InvalidateControllerHandler(IN PDEVICE_OBJECT FdoDevice,IN ULONG Type)635 USBPORT_InvalidateControllerHandler(IN PDEVICE_OBJECT FdoDevice,
636 IN ULONG Type)
637 {
638 PUSBPORT_DEVICE_EXTENSION FdoExtension;
639
640 DPRINT_CORE("USBPORT_InvalidateControllerHandler: Invalidate Type - %x\n",
641 Type);
642
643 FdoExtension = FdoDevice->DeviceExtension;
644
645 switch (Type)
646 {
647 case USBPORT_INVALIDATE_CONTROLLER_RESET:
648 DPRINT1("USBPORT_InvalidateControllerHandler: INVALIDATE_CONTROLLER_RESET UNIMPLEMENTED. FIXME.\n");
649 break;
650
651 case USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE:
652 DPRINT1("USBPORT_InvalidateControllerHandler: INVALIDATE_CONTROLLER_SURPRISE_REMOVE UNIMPLEMENTED. FIXME.\n");
653 break;
654
655 case USBPORT_INVALIDATE_CONTROLLER_SOFT_INTERRUPT:
656 if (InterlockedIncrement(&FdoExtension->IsrDpcCounter))
657 {
658 InterlockedDecrement(&FdoExtension->IsrDpcCounter);
659 }
660 else
661 {
662 USBPORT_SoftInterrupt(FdoDevice);
663 }
664 break;
665 }
666 }
667
668 ULONG
669 NTAPI
USBPORT_InvalidateController(IN PVOID MiniPortExtension,IN ULONG Type)670 USBPORT_InvalidateController(IN PVOID MiniPortExtension,
671 IN ULONG Type)
672 {
673 PUSBPORT_DEVICE_EXTENSION FdoExtension;
674 PDEVICE_OBJECT FdoDevice;
675
676 DPRINT("USBPORT_InvalidateController: Invalidate Type - %x\n", Type);
677
678 //FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION));
679 FdoExtension = (PUSBPORT_DEVICE_EXTENSION)((ULONG_PTR)MiniPortExtension -
680 sizeof(USBPORT_DEVICE_EXTENSION));
681 FdoDevice = FdoExtension->CommonExtension.SelfDevice;
682
683 USBPORT_InvalidateControllerHandler(FdoDevice, Type);
684
685 return 0;
686 }
687
688 ULONG
689 NTAPI
USBPORT_NotifyDoubleBuffer(IN PVOID MiniPortExtension,IN PVOID MiniPortTransfer,IN PVOID Buffer,IN SIZE_T Length)690 USBPORT_NotifyDoubleBuffer(IN PVOID MiniPortExtension,
691 IN PVOID MiniPortTransfer,
692 IN PVOID Buffer,
693 IN SIZE_T Length)
694 {
695 DPRINT1("USBPORT_NotifyDoubleBuffer: UNIMPLEMENTED. FIXME.\n");
696 return 0;
697 }
698
699 VOID
700 NTAPI
USBPORT_WorkerRequestDpc(IN PRKDPC Dpc,IN PVOID DeferredContext,IN PVOID SystemArgument1,IN PVOID SystemArgument2)701 USBPORT_WorkerRequestDpc(IN PRKDPC Dpc,
702 IN PVOID DeferredContext,
703 IN PVOID SystemArgument1,
704 IN PVOID SystemArgument2)
705 {
706 PDEVICE_OBJECT FdoDevice;
707 PUSBPORT_DEVICE_EXTENSION FdoExtension;
708
709 DPRINT("USBPORT_WorkerRequestDpc: ...\n");
710
711 FdoDevice = DeferredContext;
712 FdoExtension = FdoDevice->DeviceExtension;
713
714 if (!InterlockedIncrement(&FdoExtension->IsrDpcHandlerCounter))
715 {
716 USBPORT_DpcHandler(FdoDevice);
717 }
718
719 InterlockedDecrement(&FdoExtension->IsrDpcHandlerCounter);
720 }
721
722 VOID
723 NTAPI
USBPORT_DoneTransfer(IN PUSBPORT_TRANSFER Transfer)724 USBPORT_DoneTransfer(IN PUSBPORT_TRANSFER Transfer)
725 {
726 PUSBPORT_ENDPOINT Endpoint;
727 PDEVICE_OBJECT FdoDevice;
728 PUSBPORT_DEVICE_EXTENSION FdoExtension;
729 PURB Urb;
730 PIRP Irp;
731 KIRQL CancelIrql;
732 KIRQL OldIrql;
733
734 DPRINT_CORE("USBPORT_DoneTransfer: Transfer - %p\n", Transfer);
735
736 Endpoint = Transfer->Endpoint;
737 FdoDevice = Endpoint->FdoDevice;
738 FdoExtension = FdoDevice->DeviceExtension;
739
740 Urb = Transfer->Urb;
741 Irp = Transfer->Irp;
742
743 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql);
744
745 if (Irp)
746 {
747 IoAcquireCancelSpinLock(&CancelIrql);
748 IoSetCancelRoutine(Irp, NULL);
749 IoReleaseCancelSpinLock(CancelIrql);
750
751 USBPORT_RemoveActiveTransferIrp(FdoDevice, Irp);
752 }
753
754 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
755
756 USBPORT_USBDStatusToNtStatus(Transfer->Urb, Transfer->USBDStatus);
757 USBPORT_CompleteTransfer(Urb, Urb->UrbHeader.Status);
758
759 DPRINT_CORE("USBPORT_DoneTransfer: exit\n");
760 }
761
762 VOID
763 NTAPI
USBPORT_FlushDoneTransfers(IN PDEVICE_OBJECT FdoDevice)764 USBPORT_FlushDoneTransfers(IN PDEVICE_OBJECT FdoDevice)
765 {
766 PUSBPORT_DEVICE_EXTENSION FdoExtension;
767 PLIST_ENTRY DoneTransferList;
768 PUSBPORT_TRANSFER Transfer;
769 PUSBPORT_ENDPOINT Endpoint;
770 ULONG TransferCount;
771 KIRQL OldIrql;
772 BOOLEAN IsHasTransfers;
773
774 DPRINT_CORE("USBPORT_FlushDoneTransfers: ...\n");
775
776 FdoExtension = FdoDevice->DeviceExtension;
777 DoneTransferList = &FdoExtension->DoneTransferList;
778
779 while (TRUE)
780 {
781 KeAcquireSpinLock(&FdoExtension->DoneTransferSpinLock, &OldIrql);
782
783 if (IsListEmpty(DoneTransferList))
784 break;
785
786 Transfer = CONTAINING_RECORD(DoneTransferList->Flink,
787 USBPORT_TRANSFER,
788 TransferLink);
789
790 RemoveHeadList(DoneTransferList);
791 KeReleaseSpinLock(&FdoExtension->DoneTransferSpinLock, OldIrql);
792
793 if (Transfer)
794 {
795 Endpoint = Transfer->Endpoint;
796
797 if ((Transfer->Flags & TRANSFER_FLAG_SPLITED))
798 {
799 USBPORT_DoneSplitTransfer(Transfer);
800 }
801 else
802 {
803 USBPORT_DoneTransfer(Transfer);
804 }
805
806 IsHasTransfers = USBPORT_EndpointHasQueuedTransfers(FdoDevice,
807 Endpoint,
808 &TransferCount);
809
810 if (IsHasTransfers && !TransferCount)
811 {
812 USBPORT_InvalidateEndpointHandler(FdoDevice,
813 Endpoint,
814 INVALIDATE_ENDPOINT_WORKER_DPC);
815 }
816 }
817 }
818
819 KeReleaseSpinLock(&FdoExtension->DoneTransferSpinLock, OldIrql);
820 }
821
822
823 VOID
824 NTAPI
USBPORT_TransferFlushDpc(IN PRKDPC Dpc,IN PVOID DeferredContext,IN PVOID SystemArgument1,IN PVOID SystemArgument2)825 USBPORT_TransferFlushDpc(IN PRKDPC Dpc,
826 IN PVOID DeferredContext,
827 IN PVOID SystemArgument1,
828 IN PVOID SystemArgument2)
829 {
830 PDEVICE_OBJECT FdoDevice;
831
832 DPRINT_CORE("USBPORT_TransferFlushDpc: ...\n");
833 FdoDevice = DeferredContext;
834 USBPORT_FlushDoneTransfers(FdoDevice);
835 }
836
837 BOOLEAN
838 NTAPI
USBPORT_QueueDoneTransfer(IN PUSBPORT_TRANSFER Transfer,IN USBD_STATUS USBDStatus)839 USBPORT_QueueDoneTransfer(IN PUSBPORT_TRANSFER Transfer,
840 IN USBD_STATUS USBDStatus)
841 {
842 PDEVICE_OBJECT FdoDevice;
843 PUSBPORT_DEVICE_EXTENSION FdoExtension;
844
845 DPRINT_CORE("USBPORT_QueueDoneTransfer: Transfer - %p, USBDStatus - %p\n",
846 Transfer,
847 USBDStatus);
848
849 FdoDevice = Transfer->Endpoint->FdoDevice;
850 FdoExtension = FdoDevice->DeviceExtension;
851
852 RemoveEntryList(&Transfer->TransferLink);
853 Transfer->USBDStatus = USBDStatus;
854
855 ExInterlockedInsertTailList(&FdoExtension->DoneTransferList,
856 &Transfer->TransferLink,
857 &FdoExtension->DoneTransferSpinLock);
858
859 return KeInsertQueueDpc(&FdoExtension->TransferFlushDpc, NULL, NULL);
860 }
861
862 VOID
863 NTAPI
USBPORT_DpcHandler(IN PDEVICE_OBJECT FdoDevice)864 USBPORT_DpcHandler(IN PDEVICE_OBJECT FdoDevice)
865 {
866 PUSBPORT_DEVICE_EXTENSION FdoExtension;
867 PUSBPORT_ENDPOINT Endpoint;
868 PLIST_ENTRY Entry;
869 LIST_ENTRY List;
870 LONG LockCounter;
871
872 DPRINT_CORE("USBPORT_DpcHandler: ...\n");
873
874 FdoExtension = FdoDevice->DeviceExtension;
875
876 InitializeListHead(&List);
877
878 KeAcquireSpinLockAtDpcLevel(&FdoExtension->EndpointListSpinLock);
879 Entry = FdoExtension->EndpointList.Flink;
880
881 while (Entry && Entry != &FdoExtension->EndpointList)
882 {
883 Endpoint = CONTAINING_RECORD(Entry,
884 USBPORT_ENDPOINT,
885 EndpointLink);
886
887 LockCounter = InterlockedIncrement(&Endpoint->LockCounter);
888
889 if (USBPORT_GetEndpointState(Endpoint) != USBPORT_ENDPOINT_ACTIVE ||
890 LockCounter ||
891 Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0)
892 {
893 InterlockedDecrement(&Endpoint->LockCounter);
894 }
895 else
896 {
897 InsertTailList(&List, &Endpoint->DispatchLink);
898
899 if (Endpoint->WorkerLink.Flink && Endpoint->WorkerLink.Blink)
900 {
901 RemoveEntryList(&Endpoint->WorkerLink);
902
903 Endpoint->WorkerLink.Flink = NULL;
904 Endpoint->WorkerLink.Blink = NULL;
905 }
906 }
907
908 Entry = Endpoint->EndpointLink.Flink;
909 }
910
911 KeReleaseSpinLockFromDpcLevel(&FdoExtension->EndpointListSpinLock);
912
913 while (!IsListEmpty(&List))
914 {
915 Endpoint = CONTAINING_RECORD(List.Flink,
916 USBPORT_ENDPOINT,
917 DispatchLink);
918
919 RemoveEntryList(List.Flink);
920 Endpoint->DispatchLink.Flink = NULL;
921 Endpoint->DispatchLink.Blink = NULL;
922
923 USBPORT_EndpointWorker(Endpoint, TRUE);
924 USBPORT_FlushPendingTransfers(Endpoint);
925 }
926
927 KeAcquireSpinLockAtDpcLevel(&FdoExtension->EndpointListSpinLock);
928
929 if (!IsListEmpty(&FdoExtension->WorkerList))
930 {
931 USBPORT_SignalWorkerThread(FdoDevice);
932 }
933
934 KeReleaseSpinLockFromDpcLevel(&FdoExtension->EndpointListSpinLock);
935
936 USBPORT_FlushDoneTransfers(FdoDevice);
937 }
938
939 VOID
940 NTAPI
USBPORT_IsrDpcHandler(IN PDEVICE_OBJECT FdoDevice,IN BOOLEAN IsDpcHandler)941 USBPORT_IsrDpcHandler(IN PDEVICE_OBJECT FdoDevice,
942 IN BOOLEAN IsDpcHandler)
943 {
944 PUSBPORT_DEVICE_EXTENSION FdoExtension;
945 PUSBPORT_REGISTRATION_PACKET Packet;
946 PUSBPORT_ENDPOINT Endpoint;
947 PLIST_ENTRY List;
948 ULONG FrameNumber;
949
950 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
951
952 DPRINT_CORE("USBPORT_IsrDpcHandler: IsDpcHandler - %x\n", IsDpcHandler);
953
954 FdoExtension = FdoDevice->DeviceExtension;
955 Packet = &FdoExtension->MiniPortInterface->Packet;
956
957 if (InterlockedIncrement(&FdoExtension->IsrDpcHandlerCounter))
958 {
959 KeInsertQueueDpc(&FdoExtension->IsrDpc, NULL, NULL);
960 InterlockedDecrement(&FdoExtension->IsrDpcHandlerCounter);
961 return;
962 }
963
964 for (List = ExInterlockedRemoveHeadList(&FdoExtension->EpStateChangeList,
965 &FdoExtension->EpStateChangeSpinLock);
966 List != NULL;
967 List = ExInterlockedRemoveHeadList(&FdoExtension->EpStateChangeList,
968 &FdoExtension->EpStateChangeSpinLock))
969 {
970 Endpoint = CONTAINING_RECORD(List,
971 USBPORT_ENDPOINT,
972 StateChangeLink);
973
974 DPRINT_CORE("USBPORT_IsrDpcHandler: Endpoint - %p\n", Endpoint);
975
976 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
977
978 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
979 FrameNumber = Packet->Get32BitFrameNumber(FdoExtension->MiniPortExt);
980 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
981
982 if (FrameNumber <= Endpoint->FrameNumber &&
983 !(Endpoint->Flags & ENDPOINT_FLAG_NUKE))
984 {
985 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
986
987 ExInterlockedInsertHeadList(&FdoExtension->EpStateChangeList,
988 &Endpoint->StateChangeLink,
989 &FdoExtension->EpStateChangeSpinLock);
990
991 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
992 Packet->InterruptNextSOF(FdoExtension->MiniPortExt);
993 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
994
995 break;
996 }
997
998 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
999
1000 KeAcquireSpinLockAtDpcLevel(&Endpoint->StateChangeSpinLock);
1001 Endpoint->StateLast = Endpoint->StateNext;
1002 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
1003
1004 DPRINT_CORE("USBPORT_IsrDpcHandler: Endpoint->StateLast - %x\n",
1005 Endpoint->StateLast);
1006
1007 if (IsDpcHandler)
1008 {
1009 USBPORT_InvalidateEndpointHandler(FdoDevice,
1010 Endpoint,
1011 INVALIDATE_ENDPOINT_ONLY);
1012 }
1013 else
1014 {
1015 USBPORT_InvalidateEndpointHandler(FdoDevice,
1016 Endpoint,
1017 INVALIDATE_ENDPOINT_WORKER_THREAD);
1018 }
1019 }
1020
1021 if (IsDpcHandler)
1022 {
1023 USBPORT_DpcHandler(FdoDevice);
1024 }
1025
1026 InterlockedDecrement(&FdoExtension->IsrDpcHandlerCounter);
1027 }
1028
1029 VOID
1030 NTAPI
USBPORT_IsrDpc(IN PRKDPC Dpc,IN PVOID DeferredContext,IN PVOID SystemArgument1,IN PVOID SystemArgument2)1031 USBPORT_IsrDpc(IN PRKDPC Dpc,
1032 IN PVOID DeferredContext,
1033 IN PVOID SystemArgument1,
1034 IN PVOID SystemArgument2)
1035 {
1036 PDEVICE_OBJECT FdoDevice;
1037 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1038 PUSBPORT_REGISTRATION_PACKET Packet;
1039 BOOLEAN InterruptEnable;
1040
1041 DPRINT_INT("USBPORT_IsrDpc: DeferredContext - %p, SystemArgument2 - %p\n",
1042 DeferredContext,
1043 SystemArgument2);
1044
1045 FdoDevice = DeferredContext;
1046 FdoExtension = FdoDevice->DeviceExtension;
1047 Packet = &FdoExtension->MiniPortInterface->Packet;
1048
1049 if (SystemArgument2)
1050 {
1051 InterlockedDecrement(&FdoExtension->IsrDpcCounter);
1052 }
1053
1054 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportInterruptsSpinLock);
1055 InterruptEnable = (FdoExtension->Flags & USBPORT_FLAG_INTERRUPT_ENABLED) ==
1056 USBPORT_FLAG_INTERRUPT_ENABLED;
1057
1058 Packet->InterruptDpc(FdoExtension->MiniPortExt, InterruptEnable);
1059
1060 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportInterruptsSpinLock);
1061
1062 if (FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND &&
1063 FdoExtension->TimerFlags & USBPORT_TMFLAG_WAKE)
1064 {
1065 USBPORT_CompletePdoWaitWake(FdoDevice);
1066 }
1067 else
1068 {
1069 USBPORT_IsrDpcHandler(FdoDevice, TRUE);
1070 }
1071
1072 DPRINT_INT("USBPORT_IsrDpc: exit\n");
1073 }
1074
1075 BOOLEAN
1076 NTAPI
USBPORT_InterruptService(IN PKINTERRUPT Interrupt,IN PVOID ServiceContext)1077 USBPORT_InterruptService(IN PKINTERRUPT Interrupt,
1078 IN PVOID ServiceContext)
1079 {
1080 PDEVICE_OBJECT FdoDevice;
1081 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1082 PUSBPORT_REGISTRATION_PACKET Packet;
1083 BOOLEAN Result = FALSE;
1084
1085 FdoDevice = ServiceContext;
1086 FdoExtension = FdoDevice->DeviceExtension;
1087 Packet = &FdoExtension->MiniPortInterface->Packet;
1088
1089 DPRINT_INT("USBPORT_InterruptService: FdoExtension[%p]->Flags - %08X\n",
1090 FdoExtension,
1091 FdoExtension->Flags);
1092
1093 if (FdoExtension->Flags & USBPORT_FLAG_INTERRUPT_ENABLED &&
1094 FdoExtension->MiniPortFlags & USBPORT_MPFLAG_INTERRUPTS_ENABLED)
1095 {
1096 Result = Packet->InterruptService(FdoExtension->MiniPortExt);
1097
1098 if (Result)
1099 {
1100 KeInsertQueueDpc(&FdoExtension->IsrDpc, NULL, NULL);
1101 }
1102 }
1103
1104 DPRINT_INT("USBPORT_InterruptService: return - %x\n", Result);
1105
1106 return Result;
1107 }
1108
1109 VOID
1110 NTAPI
USBPORT_SignalWorkerThread(IN PDEVICE_OBJECT FdoDevice)1111 USBPORT_SignalWorkerThread(IN PDEVICE_OBJECT FdoDevice)
1112 {
1113 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1114 KIRQL OldIrql;
1115
1116 DPRINT_CORE("USBPORT_SignalWorkerThread ...\n");
1117
1118 FdoExtension = FdoDevice->DeviceExtension;
1119
1120 KeAcquireSpinLock(&FdoExtension->WorkerThreadEventSpinLock, &OldIrql);
1121 KeSetEvent(&FdoExtension->WorkerThreadEvent, EVENT_INCREMENT, FALSE);
1122 KeReleaseSpinLock(&FdoExtension->WorkerThreadEventSpinLock, OldIrql);
1123 }
1124
1125 VOID
1126 NTAPI
USBPORT_WorkerThreadHandler(IN PDEVICE_OBJECT FdoDevice)1127 USBPORT_WorkerThreadHandler(IN PDEVICE_OBJECT FdoDevice)
1128 {
1129 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1130 PUSBPORT_REGISTRATION_PACKET Packet;
1131 PLIST_ENTRY workerList;
1132 KIRQL OldIrql;
1133 PUSBPORT_ENDPOINT Endpoint;
1134 LIST_ENTRY list;
1135 BOOLEAN Result;
1136
1137 DPRINT_CORE("USBPORT_WorkerThreadHandler: ...\n");
1138
1139 FdoExtension = FdoDevice->DeviceExtension;
1140 Packet = &FdoExtension->MiniPortInterface->Packet;
1141
1142 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1143
1144 if (!(FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND))
1145 {
1146 Packet->CheckController(FdoExtension->MiniPortExt);
1147 }
1148
1149 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1150
1151 InitializeListHead(&list);
1152
1153 USBPORT_FlushAllEndpoints(FdoDevice);
1154
1155 while (TRUE)
1156 {
1157 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
1158 KeAcquireSpinLockAtDpcLevel(&FdoExtension->EndpointListSpinLock);
1159
1160 workerList = &FdoExtension->WorkerList;
1161
1162 if (IsListEmpty(workerList))
1163 break;
1164
1165 Endpoint = CONTAINING_RECORD(workerList->Flink,
1166 USBPORT_ENDPOINT,
1167 WorkerLink);
1168
1169 DPRINT_CORE("USBPORT_WorkerThreadHandler: Endpoint - %p\n", Endpoint);
1170
1171 RemoveHeadList(workerList);
1172 Endpoint->WorkerLink.Blink = NULL;
1173 Endpoint->WorkerLink.Flink = NULL;
1174
1175 KeReleaseSpinLockFromDpcLevel(&FdoExtension->EndpointListSpinLock);
1176
1177 Result = USBPORT_EndpointWorker(Endpoint, FALSE);
1178 KeAcquireSpinLockAtDpcLevel(&FdoExtension->EndpointListSpinLock);
1179
1180 if (Result)
1181 {
1182 if (Endpoint->FlushAbortLink.Flink == NULL ||
1183 Endpoint->FlushAbortLink.Blink == NULL)
1184 {
1185 InsertTailList(&list, &Endpoint->FlushAbortLink);
1186 }
1187 }
1188
1189 while (!IsListEmpty(&list))
1190 {
1191 Endpoint = CONTAINING_RECORD(list.Flink,
1192 USBPORT_ENDPOINT,
1193 FlushAbortLink);
1194
1195 RemoveHeadList(&list);
1196
1197 Endpoint->FlushAbortLink.Flink = NULL;
1198 Endpoint->FlushAbortLink.Blink = NULL;
1199
1200 if (Endpoint->WorkerLink.Flink == NULL ||
1201 Endpoint->WorkerLink.Blink == NULL)
1202 {
1203 InsertTailList(&FdoExtension->WorkerList,
1204 &Endpoint->WorkerLink);
1205
1206 USBPORT_SignalWorkerThread(FdoDevice);
1207 }
1208 }
1209
1210 KeReleaseSpinLockFromDpcLevel(&FdoExtension->EndpointListSpinLock);
1211 KeLowerIrql(OldIrql);
1212 }
1213
1214 KeReleaseSpinLockFromDpcLevel(&FdoExtension->EndpointListSpinLock);
1215 KeLowerIrql(OldIrql);
1216
1217 USBPORT_FlushClosedEndpointList(FdoDevice);
1218 }
1219
1220 VOID
1221 NTAPI
USBPORT_DoRootHubCallback(IN PDEVICE_OBJECT FdoDevice)1222 USBPORT_DoRootHubCallback(IN PDEVICE_OBJECT FdoDevice)
1223 {
1224 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1225 PDEVICE_OBJECT PdoDevice;
1226 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
1227 PRH_INIT_CALLBACK RootHubInitCallback;
1228 PVOID RootHubInitContext;
1229
1230 FdoExtension = FdoDevice->DeviceExtension;
1231
1232 DPRINT("USBPORT_DoRootHubCallback: FdoDevice - %p\n", FdoDevice);
1233
1234 PdoDevice = FdoExtension->RootHubPdo;
1235
1236 if (PdoDevice)
1237 {
1238 PdoExtension = PdoDevice->DeviceExtension;
1239
1240 RootHubInitContext = PdoExtension->RootHubInitContext;
1241 RootHubInitCallback = PdoExtension->RootHubInitCallback;
1242
1243 PdoExtension->RootHubInitCallback = NULL;
1244 PdoExtension->RootHubInitContext = NULL;
1245
1246 if (RootHubInitCallback)
1247 {
1248 RootHubInitCallback(RootHubInitContext);
1249 }
1250 }
1251
1252 DPRINT("USBPORT_DoRootHubCallback: exit\n");
1253 }
1254
1255 VOID
1256 NTAPI
USBPORT_SynchronizeRootHubCallback(IN PDEVICE_OBJECT FdoDevice,IN PDEVICE_OBJECT Usb2FdoDevice)1257 USBPORT_SynchronizeRootHubCallback(IN PDEVICE_OBJECT FdoDevice,
1258 IN PDEVICE_OBJECT Usb2FdoDevice)
1259 {
1260 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1261 PUSBPORT_REGISTRATION_PACKET Packet;
1262 PUSBPORT_DEVICE_EXTENSION Usb2FdoExtension;
1263 PDEVICE_RELATIONS CompanionControllersList;
1264 PUSBPORT_DEVICE_EXTENSION CompanionFdoExtension;
1265 PDEVICE_OBJECT * Entry;
1266 ULONG ix;
1267
1268 DPRINT("USBPORT_SynchronizeRootHubCallback: FdoDevice - %p, Usb2FdoDevice - %p\n",
1269 FdoDevice,
1270 Usb2FdoDevice);
1271
1272 FdoExtension = FdoDevice->DeviceExtension;
1273 Packet = &FdoExtension->MiniPortInterface->Packet;
1274
1275 if (Usb2FdoDevice == NULL &&
1276 !(Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2))
1277 {
1278 /* Not Companion USB11 Controller */
1279 USBPORT_DoRootHubCallback(FdoDevice);
1280
1281 FdoExtension->Flags &= ~USBPORT_FLAG_RH_INIT_CALLBACK;
1282 InterlockedCompareExchange(&FdoExtension->RHInitCallBackLock, 0, 1);
1283
1284 DPRINT("USBPORT_SynchronizeRootHubCallback: exit\n");
1285 return;
1286 }
1287
1288 /* USB2 or Companion USB11 */
1289
1290 DPRINT("USBPORT_SynchronizeRootHubCallback: FdoExtension->Flags - %p\n",
1291 FdoExtension->Flags);
1292
1293 if (!(FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC))
1294 {
1295 KeWaitForSingleObject(&FdoExtension->ControllerSemaphore,
1296 Executive,
1297 KernelMode,
1298 FALSE,
1299 NULL);
1300
1301 FdoExtension->Flags |= USBPORT_FLAG_PWR_AND_CHIRP_LOCK;
1302
1303 if (!(FdoExtension->Flags & (USBPORT_FLAG_HC_SUSPEND |
1304 USBPORT_FLAG_POWER_AND_CHIRP_OK)))
1305 {
1306 USBPORT_RootHubPowerAndChirpAllCcPorts(FdoDevice);
1307 FdoExtension->Flags |= USBPORT_FLAG_POWER_AND_CHIRP_OK;
1308 }
1309
1310 FdoExtension->Flags &= ~USBPORT_FLAG_PWR_AND_CHIRP_LOCK;
1311
1312 KeReleaseSemaphore(&FdoExtension->ControllerSemaphore,
1313 LOW_REALTIME_PRIORITY,
1314 1,
1315 FALSE);
1316
1317 CompanionControllersList = USBPORT_FindCompanionControllers(FdoDevice,
1318 FALSE,
1319 TRUE);
1320
1321 if (CompanionControllersList)
1322 {
1323 Entry = &CompanionControllersList->Objects[0];
1324
1325 for (ix = 0; ix < CompanionControllersList->Count; ++ix)
1326 {
1327 CompanionFdoExtension = ((*Entry)->DeviceExtension);
1328
1329 InterlockedCompareExchange(&CompanionFdoExtension->RHInitCallBackLock,
1330 0,
1331 1);
1332
1333 ++Entry;
1334 }
1335
1336 ExFreePoolWithTag(CompanionControllersList, USB_PORT_TAG);
1337 }
1338
1339 USBPORT_DoRootHubCallback(FdoDevice);
1340
1341 FdoExtension->Flags &= ~USBPORT_FLAG_RH_INIT_CALLBACK;
1342 InterlockedCompareExchange(&FdoExtension->RHInitCallBackLock, 0, 1);
1343 }
1344 else
1345 {
1346 Usb2FdoExtension = Usb2FdoDevice->DeviceExtension;
1347
1348 USBPORT_Wait(FdoDevice, 50);
1349
1350 while (FdoExtension->RHInitCallBackLock)
1351 {
1352 USBPORT_Wait(FdoDevice, 10);
1353
1354 Usb2FdoExtension->Flags |= USBPORT_FLAG_RH_INIT_CALLBACK;
1355 USBPORT_SignalWorkerThread(Usb2FdoDevice);
1356 }
1357
1358 USBPORT_DoRootHubCallback(FdoDevice);
1359
1360 FdoExtension->Flags &= ~USBPORT_FLAG_RH_INIT_CALLBACK;
1361 }
1362
1363 DPRINT("USBPORT_SynchronizeRootHubCallback: exit\n");
1364 }
1365
1366 VOID
1367 NTAPI
USBPORT_WorkerThread(IN PVOID StartContext)1368 USBPORT_WorkerThread(IN PVOID StartContext)
1369 {
1370 PDEVICE_OBJECT FdoDevice;
1371 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1372 LARGE_INTEGER OldTime;
1373 LARGE_INTEGER NewTime;
1374 KIRQL OldIrql;
1375
1376 DPRINT_CORE("USBPORT_WorkerThread ...\n");
1377
1378 FdoDevice = StartContext;
1379 FdoExtension = FdoDevice->DeviceExtension;
1380
1381 FdoExtension->WorkerThread = KeGetCurrentThread();
1382
1383 do
1384 {
1385 KeQuerySystemTime(&OldTime);
1386
1387 KeWaitForSingleObject(&FdoExtension->WorkerThreadEvent,
1388 Suspended,
1389 KernelMode,
1390 FALSE,
1391 NULL);
1392
1393 if (FdoExtension->Flags & USBPORT_FLAG_WORKER_THREAD_EXIT)
1394 {
1395 break;
1396 }
1397
1398 KeQuerySystemTime(&NewTime);
1399
1400 KeAcquireSpinLock(&FdoExtension->WorkerThreadEventSpinLock, &OldIrql);
1401 KeClearEvent(&FdoExtension->WorkerThreadEvent);
1402 KeReleaseSpinLock(&FdoExtension->WorkerThreadEventSpinLock, OldIrql);
1403 DPRINT_CORE("USBPORT_WorkerThread: run\n");
1404
1405 if (FdoExtension->MiniPortFlags & USBPORT_MPFLAG_INTERRUPTS_ENABLED)
1406 {
1407 USBPORT_DoSetPowerD0(FdoDevice);
1408
1409 if (FdoExtension->Flags & USBPORT_FLAG_RH_INIT_CALLBACK)
1410 {
1411 PDEVICE_OBJECT USB2FdoDevice = NULL;
1412
1413 USB2FdoDevice = USBPORT_FindUSB2Controller(FdoDevice);
1414 USBPORT_SynchronizeRootHubCallback(FdoDevice, USB2FdoDevice);
1415 }
1416 }
1417
1418 USBPORT_WorkerThreadHandler(FdoDevice);
1419 }
1420 while (!(FdoExtension->Flags & USBPORT_FLAG_WORKER_THREAD_ON));
1421
1422 PsTerminateSystemThread(0);
1423 }
1424
1425 NTSTATUS
1426 NTAPI
USBPORT_CreateWorkerThread(IN PDEVICE_OBJECT FdoDevice)1427 USBPORT_CreateWorkerThread(IN PDEVICE_OBJECT FdoDevice)
1428 {
1429 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1430 NTSTATUS Status;
1431
1432 DPRINT("USBPORT_CreateWorkerThread ...\n");
1433
1434 FdoExtension = FdoDevice->DeviceExtension;
1435
1436 FdoExtension->Flags &= ~USBPORT_FLAG_WORKER_THREAD_ON;
1437
1438 KeInitializeEvent(&FdoExtension->WorkerThreadEvent,
1439 NotificationEvent,
1440 FALSE);
1441
1442 Status = PsCreateSystemThread(&FdoExtension->WorkerThreadHandle,
1443 THREAD_ALL_ACCESS,
1444 NULL,
1445 NULL,
1446 NULL,
1447 USBPORT_WorkerThread,
1448 (PVOID)FdoDevice);
1449
1450 return Status;
1451 }
1452
1453 VOID
1454 NTAPI
USBPORT_StopWorkerThread(IN PDEVICE_OBJECT FdoDevice)1455 USBPORT_StopWorkerThread(IN PDEVICE_OBJECT FdoDevice)
1456 {
1457 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1458 NTSTATUS Status;
1459
1460 DPRINT("USBPORT_StopWorkerThread ...\n");
1461
1462 FdoExtension = FdoDevice->DeviceExtension;
1463
1464 FdoExtension->Flags |= USBPORT_FLAG_WORKER_THREAD_EXIT;
1465 USBPORT_SignalWorkerThread(FdoDevice);
1466 Status = ZwWaitForSingleObject(FdoExtension->WorkerThreadHandle, FALSE, NULL);
1467 NT_ASSERT(Status == STATUS_SUCCESS);
1468 }
1469
1470 VOID
1471 NTAPI
USBPORT_SynchronizeControllersStart(IN PDEVICE_OBJECT FdoDevice)1472 USBPORT_SynchronizeControllersStart(IN PDEVICE_OBJECT FdoDevice)
1473 {
1474 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1475 PDEVICE_OBJECT PdoDevice;
1476 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
1477 PDEVICE_OBJECT USB2FdoDevice = NULL;
1478 PUSBPORT_DEVICE_EXTENSION USB2FdoExtension;
1479 BOOLEAN IsOn;
1480
1481 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: FdoDevice - %p\n",
1482 FdoDevice);
1483
1484 FdoExtension = FdoDevice->DeviceExtension;
1485
1486 PdoDevice = FdoExtension->RootHubPdo;
1487
1488 if (!PdoDevice)
1489 {
1490 return;
1491 }
1492
1493 PdoExtension = PdoDevice->DeviceExtension;
1494
1495 if (PdoExtension->RootHubInitCallback == NULL ||
1496 FdoExtension->Flags & USBPORT_FLAG_RH_INIT_CALLBACK)
1497 {
1498 return;
1499 }
1500
1501 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: Flags - %p\n",
1502 FdoExtension->Flags);
1503
1504 if (FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC)
1505 {
1506 IsOn = FALSE;
1507
1508 USB2FdoDevice = USBPORT_FindUSB2Controller(FdoDevice);
1509
1510 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: USB2FdoDevice - %p\n",
1511 USB2FdoDevice);
1512
1513 if (USB2FdoDevice)
1514 {
1515 USB2FdoExtension = USB2FdoDevice->DeviceExtension;
1516
1517 if (USB2FdoExtension->CommonExtension.PnpStateFlags &
1518 USBPORT_PNP_STATE_STARTED)
1519 {
1520 IsOn = TRUE;
1521 }
1522 }
1523
1524 if (!(FdoExtension->Flags & USBPORT_FLAG_NO_HACTION))
1525 {
1526 goto Start;
1527 }
1528
1529 USB2FdoDevice = NULL;
1530 }
1531
1532 IsOn = TRUE;
1533
1534 Start:
1535
1536 if (IsOn &&
1537 !InterlockedCompareExchange(&FdoExtension->RHInitCallBackLock, 1, 0))
1538 {
1539 FdoExtension->Flags |= USBPORT_FLAG_RH_INIT_CALLBACK;
1540 USBPORT_SignalWorkerThread(FdoDevice);
1541
1542 if (USB2FdoDevice)
1543 {
1544 USB2FdoExtension = USB2FdoDevice->DeviceExtension;
1545
1546 USB2FdoExtension->Flags |= USBPORT_FLAG_RH_INIT_CALLBACK;
1547 USBPORT_SignalWorkerThread(USB2FdoDevice);
1548 }
1549 }
1550
1551 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: exit\n");
1552 }
1553
1554 VOID
1555 NTAPI
USBPORT_TimerDpc(IN PRKDPC Dpc,IN PVOID DeferredContext,IN PVOID SystemArgument1,IN PVOID SystemArgument2)1556 USBPORT_TimerDpc(IN PRKDPC Dpc,
1557 IN PVOID DeferredContext,
1558 IN PVOID SystemArgument1,
1559 IN PVOID SystemArgument2)
1560 {
1561 PDEVICE_OBJECT FdoDevice;
1562 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1563 PUSBPORT_REGISTRATION_PACKET Packet;
1564 LARGE_INTEGER DueTime = {{0, 0}};
1565 ULONG TimerFlags;
1566 PTIMER_WORK_QUEUE_ITEM IdleQueueItem;
1567 KIRQL OldIrql;
1568 KIRQL TimerOldIrql;
1569
1570 DPRINT_TIMER("USBPORT_TimerDpc: Dpc - %p, DeferredContext - %p\n",
1571 Dpc,
1572 DeferredContext);
1573
1574 FdoDevice = DeferredContext;
1575 FdoExtension = FdoDevice->DeviceExtension;
1576 Packet = &FdoExtension->MiniPortInterface->Packet;
1577
1578 KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &TimerOldIrql);
1579
1580 TimerFlags = FdoExtension->TimerFlags;
1581
1582 DPRINT_TIMER("USBPORT_TimerDpc: Flags - %p, TimerFlags - %p\n",
1583 FdoExtension->Flags,
1584 TimerFlags);
1585
1586 if (FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND &&
1587 FdoExtension->Flags & USBPORT_FLAG_HC_WAKE_SUPPORT &&
1588 !(TimerFlags & USBPORT_TMFLAG_HC_RESUME))
1589 {
1590 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1591 Packet->PollController(FdoExtension->MiniPortExt);
1592 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1593 }
1594
1595 USBPORT_SynchronizeControllersStart(FdoDevice);
1596
1597 if (TimerFlags & USBPORT_TMFLAG_HC_SUSPENDED)
1598 {
1599 USBPORT_BadRequestFlush(FdoDevice);
1600 goto Exit;
1601 }
1602
1603 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1604
1605 if (!(FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND))
1606 {
1607 Packet->CheckController(FdoExtension->MiniPortExt);
1608 }
1609
1610 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1611
1612 if (FdoExtension->Flags & USBPORT_FLAG_HC_POLLING)
1613 {
1614 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1615 Packet->PollController(FdoExtension->MiniPortExt);
1616 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1617 }
1618
1619 USBPORT_IsrDpcHandler(FdoDevice, FALSE);
1620
1621 DPRINT_TIMER("USBPORT_TimerDpc: USBPORT_TimeoutAllEndpoints UNIMPLEMENTED.\n");
1622 //USBPORT_TimeoutAllEndpoints(FdoDevice);
1623 DPRINT_TIMER("USBPORT_TimerDpc: USBPORT_CheckIdleEndpoints UNIMPLEMENTED.\n");
1624 //USBPORT_CheckIdleEndpoints(FdoDevice);
1625
1626 USBPORT_BadRequestFlush(FdoDevice);
1627
1628 if (FdoExtension->IdleLockCounter > -1 &&
1629 !(TimerFlags & USBPORT_TMFLAG_IDLE_QUEUEITEM_ON))
1630 {
1631 IdleQueueItem = ExAllocatePoolWithTag(NonPagedPool,
1632 sizeof(TIMER_WORK_QUEUE_ITEM),
1633 USB_PORT_TAG);
1634
1635 DPRINT("USBPORT_TimerDpc: IdleLockCounter - %x, IdleQueueItem - %p\n",
1636 FdoExtension->IdleLockCounter,
1637 IdleQueueItem);
1638
1639 if (IdleQueueItem)
1640 {
1641 RtlZeroMemory(IdleQueueItem, sizeof(TIMER_WORK_QUEUE_ITEM));
1642
1643 IdleQueueItem->WqItem.List.Flink = NULL;
1644 IdleQueueItem->WqItem.WorkerRoutine = USBPORT_DoIdleNotificationCallback;
1645 IdleQueueItem->WqItem.Parameter = IdleQueueItem;
1646
1647 IdleQueueItem->FdoDevice = FdoDevice;
1648 IdleQueueItem->Context = 0;
1649
1650 FdoExtension->TimerFlags |= USBPORT_TMFLAG_IDLE_QUEUEITEM_ON;
1651
1652 ExQueueWorkItem(&IdleQueueItem->WqItem, CriticalWorkQueue);
1653 }
1654 }
1655
1656 Exit:
1657
1658 KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, TimerOldIrql);
1659
1660 if (TimerFlags & USBPORT_TMFLAG_TIMER_QUEUED)
1661 {
1662 DueTime.QuadPart -= FdoExtension->TimerValue * 10000 +
1663 (KeQueryTimeIncrement() - 1);
1664
1665 KeSetTimer(&FdoExtension->TimerObject,
1666 DueTime,
1667 &FdoExtension->TimerDpc);
1668 }
1669
1670 DPRINT_TIMER("USBPORT_TimerDpc: exit\n");
1671 }
1672
1673 BOOLEAN
1674 NTAPI
USBPORT_StartTimer(IN PDEVICE_OBJECT FdoDevice,IN ULONG Time)1675 USBPORT_StartTimer(IN PDEVICE_OBJECT FdoDevice,
1676 IN ULONG Time)
1677 {
1678 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1679 LARGE_INTEGER DueTime = {{0, 0}};
1680 ULONG TimeIncrement;
1681 BOOLEAN Result;
1682
1683 DPRINT_TIMER("USBPORT_StartTimer: FdoDevice - %p, Time - %x\n",
1684 FdoDevice,
1685 Time);
1686
1687 FdoExtension = FdoDevice->DeviceExtension;
1688
1689 TimeIncrement = KeQueryTimeIncrement();
1690
1691 FdoExtension->TimerFlags |= USBPORT_TMFLAG_TIMER_QUEUED;
1692 FdoExtension->TimerValue = Time;
1693
1694 KeInitializeTimer(&FdoExtension->TimerObject);
1695 KeInitializeDpc(&FdoExtension->TimerDpc, USBPORT_TimerDpc, FdoDevice);
1696
1697 DueTime.QuadPart -= 10000 * Time + (TimeIncrement - 1);
1698
1699 Result = KeSetTimer(&FdoExtension->TimerObject,
1700 DueTime,
1701 &FdoExtension->TimerDpc);
1702
1703 return Result;
1704 }
1705
1706 PUSBPORT_COMMON_BUFFER_HEADER
1707 NTAPI
USBPORT_AllocateCommonBuffer(IN PDEVICE_OBJECT FdoDevice,IN SIZE_T BufferLength)1708 USBPORT_AllocateCommonBuffer(IN PDEVICE_OBJECT FdoDevice,
1709 IN SIZE_T BufferLength)
1710 {
1711 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer = NULL;
1712 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1713 PDMA_ADAPTER DmaAdapter;
1714 PDMA_OPERATIONS DmaOperations;
1715 SIZE_T HeaderSize;
1716 ULONG Length = 0;
1717 ULONG LengthPadded;
1718 PHYSICAL_ADDRESS LogicalAddress;
1719 ULONG_PTR BaseVA;
1720 ULONG_PTR StartBufferVA;
1721 ULONG StartBufferPA;
1722
1723 DPRINT("USBPORT_AllocateCommonBuffer: FdoDevice - %p, BufferLength - %p\n",
1724 FdoDevice,
1725 BufferLength);
1726
1727 if (BufferLength == 0)
1728 goto Exit;
1729
1730 FdoExtension = FdoDevice->DeviceExtension;
1731
1732 DmaAdapter = FdoExtension->DmaAdapter;
1733 DmaOperations = DmaAdapter->DmaOperations;
1734
1735 HeaderSize = sizeof(USBPORT_COMMON_BUFFER_HEADER);
1736 Length = ROUND_TO_PAGES(BufferLength + HeaderSize);
1737 LengthPadded = Length - (BufferLength + HeaderSize);
1738
1739 BaseVA = (ULONG_PTR)DmaOperations->AllocateCommonBuffer(DmaAdapter,
1740 Length,
1741 &LogicalAddress,
1742 TRUE);
1743
1744 if (!BaseVA)
1745 goto Exit;
1746
1747 StartBufferVA = BaseVA & ~(PAGE_SIZE - 1);
1748 StartBufferPA = LogicalAddress.LowPart & ~(PAGE_SIZE - 1);
1749
1750 HeaderBuffer = (PUSBPORT_COMMON_BUFFER_HEADER)(StartBufferVA +
1751 BufferLength +
1752 LengthPadded);
1753
1754 HeaderBuffer->Length = Length;
1755 HeaderBuffer->BaseVA = BaseVA;
1756 HeaderBuffer->LogicalAddress = LogicalAddress;
1757
1758 HeaderBuffer->BufferLength = BufferLength + LengthPadded;
1759 HeaderBuffer->VirtualAddress = StartBufferVA;
1760 HeaderBuffer->PhysicalAddress = StartBufferPA;
1761
1762 RtlZeroMemory((PVOID)StartBufferVA, BufferLength + LengthPadded);
1763
1764 Exit:
1765 return HeaderBuffer;
1766 }
1767
1768 VOID
1769 NTAPI
USBPORT_FreeCommonBuffer(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer)1770 USBPORT_FreeCommonBuffer(IN PDEVICE_OBJECT FdoDevice,
1771 IN PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer)
1772 {
1773 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1774 PDMA_ADAPTER DmaAdapter;
1775 PDMA_OPERATIONS DmaOperations;
1776
1777 DPRINT("USBPORT_FreeCommonBuffer: ...\n");
1778
1779 FdoExtension = FdoDevice->DeviceExtension;
1780
1781 DmaAdapter = FdoExtension->DmaAdapter;
1782 DmaOperations = DmaAdapter->DmaOperations;
1783
1784 DmaOperations->FreeCommonBuffer(FdoExtension->DmaAdapter,
1785 HeaderBuffer->Length,
1786 HeaderBuffer->LogicalAddress,
1787 (PVOID)HeaderBuffer->VirtualAddress,
1788 TRUE);
1789 }
1790
1791 PUSBPORT_MINIPORT_INTERFACE
1792 NTAPI
USBPORT_FindMiniPort(IN PDRIVER_OBJECT DriverObject)1793 USBPORT_FindMiniPort(IN PDRIVER_OBJECT DriverObject)
1794 {
1795 KIRQL OldIrql;
1796 PLIST_ENTRY List;
1797 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface;
1798 BOOLEAN IsFound = FALSE;
1799
1800 DPRINT("USBPORT_FindMiniPort: ...\n");
1801
1802 KeAcquireSpinLock(&USBPORT_SpinLock, &OldIrql);
1803
1804 for (List = USBPORT_MiniPortDrivers.Flink;
1805 List != &USBPORT_MiniPortDrivers;
1806 List = List->Flink)
1807 {
1808 MiniPortInterface = CONTAINING_RECORD(List,
1809 USBPORT_MINIPORT_INTERFACE,
1810 DriverLink);
1811
1812 if (MiniPortInterface->DriverObject == DriverObject)
1813 {
1814 DPRINT("USBPORT_FindMiniPort: find MiniPortInterface - %p\n",
1815 MiniPortInterface);
1816
1817 IsFound = TRUE;
1818 break;
1819 }
1820 }
1821
1822 KeReleaseSpinLock(&USBPORT_SpinLock, OldIrql);
1823
1824 if (IsFound)
1825 return MiniPortInterface;
1826 else
1827 return NULL;
1828
1829 }
1830
1831 NTSTATUS
1832 NTAPI
USBPORT_AddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)1833 USBPORT_AddDevice(IN PDRIVER_OBJECT DriverObject,
1834 IN PDEVICE_OBJECT PhysicalDeviceObject)
1835 {
1836 NTSTATUS Status;
1837 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface;
1838 ULONG DeviceNumber = 0;
1839 WCHAR CharDeviceName[64];
1840 UNICODE_STRING DeviceName;
1841 PDEVICE_OBJECT DeviceObject;
1842 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1843 PUSBPORT_COMMON_DEVICE_EXTENSION FdoCommonExtension;
1844 PDEVICE_OBJECT LowerDevice;
1845 ULONG Length;
1846
1847 DPRINT("USBPORT_AddDevice: DriverObject - %p, PhysicalDeviceObject - %p\n",
1848 DriverObject,
1849 PhysicalDeviceObject);
1850
1851 MiniPortInterface = USBPORT_FindMiniPort(DriverObject);
1852
1853 if (!MiniPortInterface)
1854 {
1855 DPRINT("USBPORT_AddDevice: USBPORT_FindMiniPort not found MiniPortInterface\n");
1856 return STATUS_UNSUCCESSFUL;
1857 }
1858
1859 while (TRUE)
1860 {
1861 /* Construct device name */
1862 RtlStringCbPrintfW(CharDeviceName,
1863 sizeof(CharDeviceName),
1864 L"\\Device\\USBFDO-%d",
1865 DeviceNumber);
1866
1867 RtlInitUnicodeString(&DeviceName, CharDeviceName);
1868
1869 ASSERT(MiniPortInterface->Packet.MiniPortExtensionSize <=
1870 MAXULONG - sizeof(USBPORT_DEVICE_EXTENSION) - sizeof(USB2_HC_EXTENSION));
1871 Length = (ULONG)(sizeof(USBPORT_DEVICE_EXTENSION) +
1872 MiniPortInterface->Packet.MiniPortExtensionSize +
1873 sizeof(USB2_HC_EXTENSION));
1874
1875 /* Create device */
1876 Status = IoCreateDevice(DriverObject,
1877 Length,
1878 &DeviceName,
1879 FILE_DEVICE_CONTROLLER,
1880 0,
1881 FALSE,
1882 &DeviceObject);
1883
1884 /* Check for success */
1885 if (NT_SUCCESS(Status)) break;
1886
1887 /* Is there a device object with that same name */
1888 if ((Status == STATUS_OBJECT_NAME_EXISTS) ||
1889 (Status == STATUS_OBJECT_NAME_COLLISION))
1890 {
1891 /* Try the next name */
1892 DeviceNumber++;
1893 continue;
1894 }
1895
1896 /* Bail out on other errors */
1897 if (!NT_SUCCESS(Status))
1898 {
1899 DPRINT1("USBPORT_AddDevice: failed to create %wZ, Status %x\n",
1900 &DeviceName,
1901 Status);
1902
1903 return Status;
1904 }
1905 }
1906
1907 DPRINT("USBPORT_AddDevice: created device %p <%wZ>, Status %x\n",
1908 DeviceObject,
1909 &DeviceName,
1910 Status);
1911
1912 FdoExtension = DeviceObject->DeviceExtension;
1913 FdoCommonExtension = &FdoExtension->CommonExtension;
1914
1915 RtlZeroMemory(FdoExtension, sizeof(USBPORT_DEVICE_EXTENSION));
1916
1917 FdoCommonExtension->SelfDevice = DeviceObject;
1918 FdoCommonExtension->LowerPdoDevice = PhysicalDeviceObject;
1919 FdoCommonExtension->IsPDO = FALSE;
1920
1921 LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject,
1922 PhysicalDeviceObject);
1923
1924 FdoCommonExtension->LowerDevice = LowerDevice;
1925
1926 FdoCommonExtension->DevicePowerState = PowerDeviceD3;
1927
1928 FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension +
1929 sizeof(USBPORT_DEVICE_EXTENSION));
1930
1931 if (MiniPortInterface->Packet.MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
1932 {
1933 FdoExtension->Usb2Extension =
1934 (PUSB2_HC_EXTENSION)((ULONG_PTR)FdoExtension->MiniPortExt +
1935 MiniPortInterface->Packet.MiniPortExtensionSize);
1936
1937 DPRINT("USBPORT_AddDevice: Usb2Extension - %p\n",
1938 FdoExtension->Usb2Extension);
1939
1940 USB2_InitController(FdoExtension->Usb2Extension);
1941 }
1942 else
1943 {
1944 FdoExtension->Usb2Extension = NULL;
1945 }
1946
1947 FdoExtension->MiniPortInterface = MiniPortInterface;
1948 FdoExtension->FdoNameNumber = DeviceNumber;
1949
1950 KeInitializeSemaphore(&FdoExtension->DeviceSemaphore, 1, 1);
1951 KeInitializeSemaphore(&FdoExtension->ControllerSemaphore, 1, 1);
1952
1953 InitializeListHead(&FdoExtension->EndpointList);
1954 InitializeListHead(&FdoExtension->DoneTransferList);
1955 InitializeListHead(&FdoExtension->WorkerList);
1956 InitializeListHead(&FdoExtension->EpStateChangeList);
1957 InitializeListHead(&FdoExtension->MapTransferList);
1958 InitializeListHead(&FdoExtension->DeviceHandleList);
1959 InitializeListHead(&FdoExtension->IdleIrpList);
1960 InitializeListHead(&FdoExtension->BadRequestList);
1961 InitializeListHead(&FdoExtension->EndpointClosedList);
1962
1963 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1964
1965 return Status;
1966 }
1967
1968 VOID
1969 NTAPI
USBPORT_Unload(IN PDRIVER_OBJECT DriverObject)1970 USBPORT_Unload(IN PDRIVER_OBJECT DriverObject)
1971 {
1972 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface;
1973
1974 DPRINT1("USBPORT_Unload: FIXME!\n");
1975
1976 MiniPortInterface = USBPORT_FindMiniPort(DriverObject);
1977
1978 if (!MiniPortInterface)
1979 {
1980 DPRINT("USBPORT_Unload: CRITICAL ERROR!!! Not found MiniPortInterface\n");
1981 KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0);
1982 }
1983
1984 DPRINT1("USBPORT_Unload: UNIMPLEMENTED. FIXME.\n");
1985 //MiniPortInterface->DriverUnload(DriverObject); // Call MiniPort _HCI_Unload
1986 }
1987
1988 VOID
1989 NTAPI
USBPORT_MiniportCompleteTransfer(IN PVOID MiniPortExtension,IN PVOID MiniPortEndpoint,IN PVOID TransferParameters,IN USBD_STATUS USBDStatus,IN ULONG TransferLength)1990 USBPORT_MiniportCompleteTransfer(IN PVOID MiniPortExtension,
1991 IN PVOID MiniPortEndpoint,
1992 IN PVOID TransferParameters,
1993 IN USBD_STATUS USBDStatus,
1994 IN ULONG TransferLength)
1995 {
1996 PUSBPORT_TRANSFER Transfer;
1997 PUSBPORT_TRANSFER ParentTransfer;
1998 PUSBPORT_TRANSFER SplitTransfer;
1999 PLIST_ENTRY SplitHead;
2000 PLIST_ENTRY Entry;
2001 KIRQL OldIrql;
2002
2003 DPRINT_CORE("USBPORT_MiniportCompleteTransfer: USBDStatus - %x, TransferLength - %x\n",
2004 USBDStatus,
2005 TransferLength);
2006
2007 Transfer = CONTAINING_RECORD(TransferParameters,
2008 USBPORT_TRANSFER,
2009 TransferParameters);
2010
2011 Transfer->Flags |= TRANSFER_FLAG_COMPLETED;
2012 Transfer->CompletedTransferLen = TransferLength;
2013
2014 if (((Transfer->Flags & TRANSFER_FLAG_SPLITED) == 0) ||
2015 TransferLength >= Transfer->TransferParameters.TransferBufferLength)
2016 {
2017 goto Exit;
2018 }
2019
2020 ParentTransfer = Transfer->ParentTransfer;
2021
2022 KeAcquireSpinLock(&ParentTransfer->TransferSpinLock, &OldIrql);
2023
2024 if (IsListEmpty(&ParentTransfer->SplitTransfersList))
2025 {
2026 goto Exit;
2027 }
2028
2029 SplitHead = &ParentTransfer->SplitTransfersList;
2030 Entry = SplitHead->Flink;
2031
2032 while (Entry && !IsListEmpty(SplitHead))
2033 {
2034 SplitTransfer = CONTAINING_RECORD(Entry,
2035 USBPORT_TRANSFER,
2036 SplitLink);
2037
2038 if (!(SplitTransfer->Flags & TRANSFER_FLAG_SUBMITED))
2039 {
2040 DPRINT1("USBPORT_MiniportCompleteTransfer: SplitTransfer->Flags - %X\n",
2041 SplitTransfer->Flags);
2042 //Add TRANSFER_FLAG_xxx
2043 }
2044
2045 Entry = Entry->Flink;
2046 }
2047
2048 KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
2049
2050 Exit:
2051 USBPORT_QueueDoneTransfer(Transfer, USBDStatus);
2052 }
2053
2054 VOID
2055 NTAPI
USBPORT_AsyncTimerDpc(IN PRKDPC Dpc,IN PVOID DeferredContext,IN PVOID SystemArgument1,IN PVOID SystemArgument2)2056 USBPORT_AsyncTimerDpc(IN PRKDPC Dpc,
2057 IN PVOID DeferredContext,
2058 IN PVOID SystemArgument1,
2059 IN PVOID SystemArgument2)
2060 {
2061 PDEVICE_OBJECT FdoDevice;
2062 PUSBPORT_DEVICE_EXTENSION FdoExtension;
2063 PUSBPORT_ASYNC_CALLBACK_DATA AsyncCallbackData;
2064
2065 DPRINT("USBPORT_AsyncTimerDpc: ...\n");
2066
2067 AsyncCallbackData = DeferredContext;
2068 FdoDevice = AsyncCallbackData->FdoDevice;
2069 FdoExtension = FdoDevice->DeviceExtension;
2070
2071 (*AsyncCallbackData->CallbackFunction)(FdoExtension->MiniPortExt,
2072 &AsyncCallbackData->CallbackContext);
2073
2074 ExFreePoolWithTag(AsyncCallbackData, USB_PORT_TAG);
2075 }
2076
2077 ULONG
2078 NTAPI
USBPORT_RequestAsyncCallback(IN PVOID MiniPortExtension,IN ULONG TimerValue,IN PVOID Buffer,IN SIZE_T Length,IN ASYNC_TIMER_CALLBACK * Callback)2079 USBPORT_RequestAsyncCallback(IN PVOID MiniPortExtension,
2080 IN ULONG TimerValue,
2081 IN PVOID Buffer,
2082 IN SIZE_T Length,
2083 IN ASYNC_TIMER_CALLBACK * Callback)
2084 {
2085 PUSBPORT_DEVICE_EXTENSION FdoExtension;
2086 PDEVICE_OBJECT FdoDevice;
2087 PUSBPORT_ASYNC_CALLBACK_DATA AsyncCallbackData;
2088 LARGE_INTEGER DueTime = {{0, 0}};
2089
2090 DPRINT("USBPORT_RequestAsyncCallback: ...\n");
2091
2092 FdoExtension = (PUSBPORT_DEVICE_EXTENSION)((ULONG_PTR)MiniPortExtension -
2093 sizeof(USBPORT_DEVICE_EXTENSION));
2094
2095 FdoDevice = FdoExtension->CommonExtension.SelfDevice;
2096
2097 AsyncCallbackData = ExAllocatePoolWithTag(NonPagedPool,
2098 sizeof(USBPORT_ASYNC_CALLBACK_DATA) + Length,
2099 USB_PORT_TAG);
2100
2101 if (!AsyncCallbackData)
2102 {
2103 DPRINT1("USBPORT_RequestAsyncCallback: Not allocated AsyncCallbackData!\n");
2104 return 0;
2105 }
2106
2107 RtlZeroMemory(AsyncCallbackData,
2108 sizeof(USBPORT_ASYNC_CALLBACK_DATA) + Length);
2109
2110 if (Length)
2111 {
2112 RtlCopyMemory(&AsyncCallbackData->CallbackContext, Buffer, Length);
2113 }
2114
2115 AsyncCallbackData->FdoDevice = FdoDevice;
2116 AsyncCallbackData->CallbackFunction = Callback;
2117
2118 KeInitializeTimer(&AsyncCallbackData->AsyncTimer);
2119
2120 KeInitializeDpc(&AsyncCallbackData->AsyncTimerDpc,
2121 USBPORT_AsyncTimerDpc,
2122 AsyncCallbackData);
2123
2124 DueTime.QuadPart -= (KeQueryTimeIncrement() - 1) + 10000 * TimerValue;
2125
2126 KeSetTimer(&AsyncCallbackData->AsyncTimer,
2127 DueTime,
2128 &AsyncCallbackData->AsyncTimerDpc);
2129
2130 return 0;
2131 }
2132
2133 PVOID
2134 NTAPI
USBPORT_GetMappedVirtualAddress(IN ULONG PhysicalAddress,IN PVOID MiniPortExtension,IN PVOID MiniPortEndpoint)2135 USBPORT_GetMappedVirtualAddress(IN ULONG PhysicalAddress,
2136 IN PVOID MiniPortExtension,
2137 IN PVOID MiniPortEndpoint)
2138 {
2139 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer;
2140 PUSBPORT_ENDPOINT Endpoint;
2141 ULONG Offset;
2142 ULONG_PTR VirtualAddress;
2143
2144 DPRINT_CORE("USBPORT_GetMappedVirtualAddress ...\n");
2145
2146 Endpoint = (PUSBPORT_ENDPOINT)((ULONG_PTR)MiniPortEndpoint -
2147 sizeof(USBPORT_ENDPOINT));
2148
2149 if (!Endpoint)
2150 {
2151 ASSERT(FALSE);
2152 }
2153
2154 HeaderBuffer = Endpoint->HeaderBuffer;
2155
2156 Offset = PhysicalAddress - HeaderBuffer->PhysicalAddress;
2157 VirtualAddress = HeaderBuffer->VirtualAddress + Offset;
2158
2159 return (PVOID)VirtualAddress;
2160 }
2161
2162 ULONG
2163 NTAPI
USBPORT_InvalidateEndpoint(IN PVOID MiniPortExtension,IN PVOID MiniPortEndpoint)2164 USBPORT_InvalidateEndpoint(IN PVOID MiniPortExtension,
2165 IN PVOID MiniPortEndpoint)
2166 {
2167 PUSBPORT_DEVICE_EXTENSION FdoExtension;
2168 PDEVICE_OBJECT FdoDevice;
2169 PUSBPORT_ENDPOINT Endpoint;
2170
2171 DPRINT_CORE("USBPORT_InvalidateEndpoint: ...\n");
2172
2173 FdoExtension = (PUSBPORT_DEVICE_EXTENSION)((ULONG_PTR)MiniPortExtension -
2174 sizeof(USBPORT_DEVICE_EXTENSION));
2175
2176 FdoDevice = FdoExtension->CommonExtension.SelfDevice;
2177
2178 if (!MiniPortEndpoint)
2179 {
2180 USBPORT_InvalidateEndpointHandler(FdoDevice,
2181 NULL,
2182 INVALIDATE_ENDPOINT_ONLY);
2183 return 0;
2184 }
2185
2186 Endpoint = (PUSBPORT_ENDPOINT)((ULONG_PTR)MiniPortEndpoint -
2187 sizeof(USBPORT_ENDPOINT));
2188
2189 USBPORT_InvalidateEndpointHandler(FdoDevice,
2190 Endpoint,
2191 INVALIDATE_ENDPOINT_ONLY);
2192
2193 return 0;
2194 }
2195
2196 VOID
2197 NTAPI
USBPORT_CompleteTransfer(IN PURB Urb,IN USBD_STATUS TransferStatus)2198 USBPORT_CompleteTransfer(IN PURB Urb,
2199 IN USBD_STATUS TransferStatus)
2200 {
2201 struct _URB_CONTROL_TRANSFER *UrbTransfer;
2202 PUSBPORT_TRANSFER Transfer;
2203 NTSTATUS Status;
2204 PIRP Irp;
2205 KIRQL OldIrql;
2206 PRKEVENT Event;
2207 BOOLEAN WriteToDevice;
2208 BOOLEAN IsFlushSuccess;
2209 PMDL Mdl;
2210 ULONG_PTR CurrentVa;
2211 SIZE_T TransferLength;
2212 PUSBPORT_ENDPOINT Endpoint;
2213 PDEVICE_OBJECT FdoDevice;
2214 PUSBPORT_DEVICE_EXTENSION FdoExtension;
2215 PDMA_OPERATIONS DmaOperations;
2216
2217 DPRINT("USBPORT_CompleteTransfer: Urb - %p, TransferStatus - %X\n",
2218 Urb,
2219 TransferStatus);
2220
2221 UrbTransfer = &Urb->UrbControlTransfer;
2222 Transfer = UrbTransfer->hca.Reserved8[0];
2223
2224 Transfer->USBDStatus = TransferStatus;
2225 Status = USBPORT_USBDStatusToNtStatus(Urb, TransferStatus);
2226
2227 UrbTransfer->TransferBufferLength = Transfer->CompletedTransferLen;
2228
2229 if (Transfer->Flags & TRANSFER_FLAG_DMA_MAPPED)
2230 {
2231 Endpoint = Transfer->Endpoint;
2232 FdoDevice = Endpoint->FdoDevice;
2233 FdoExtension = FdoDevice->DeviceExtension;
2234 DmaOperations = FdoExtension->DmaAdapter->DmaOperations;
2235
2236 WriteToDevice = Transfer->Direction == USBPORT_DMA_DIRECTION_TO_DEVICE;
2237 Mdl = UrbTransfer->TransferBufferMDL;
2238 CurrentVa = (ULONG_PTR)MmGetMdlVirtualAddress(Mdl);
2239 TransferLength = UrbTransfer->TransferBufferLength;
2240
2241 IsFlushSuccess = DmaOperations->FlushAdapterBuffers(FdoExtension->DmaAdapter,
2242 Mdl,
2243 Transfer->MapRegisterBase,
2244 (PVOID)CurrentVa,
2245 TransferLength,
2246 WriteToDevice);
2247
2248 if (!IsFlushSuccess)
2249 {
2250 DPRINT("USBPORT_CompleteTransfer: no FlushAdapterBuffers !!!\n");
2251 ASSERT(FALSE);
2252 }
2253
2254 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
2255
2256 DmaOperations->FreeMapRegisters(FdoExtension->DmaAdapter,
2257 Transfer->MapRegisterBase,
2258 Transfer->NumberOfMapRegisters);
2259
2260 KeLowerIrql(OldIrql);
2261 }
2262
2263 if (Urb->UrbHeader.UsbdFlags & USBD_FLAG_ALLOCATED_MDL)
2264 {
2265 IoFreeMdl(Transfer->TransferBufferMDL);
2266 Urb->UrbHeader.UsbdFlags |= ~USBD_FLAG_ALLOCATED_MDL;
2267 }
2268
2269 Urb->UrbControlTransfer.hca.Reserved8[0] = NULL;
2270 Urb->UrbHeader.UsbdFlags |= ~USBD_FLAG_ALLOCATED_TRANSFER;
2271
2272 Irp = Transfer->Irp;
2273
2274 if (Irp)
2275 {
2276 if (!NT_SUCCESS(Status))
2277 {
2278 //DbgBreakPoint();
2279 DPRINT1("USBPORT_CompleteTransfer: Irp - %p complete with Status - %lx\n",
2280 Irp,
2281 Status);
2282
2283 USBPORT_DumpingURB(Urb);
2284 }
2285
2286 Irp->IoStatus.Status = Status;
2287 Irp->IoStatus.Information = 0;
2288
2289 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
2290 IoCompleteRequest(Irp, IO_NO_INCREMENT);
2291 KeLowerIrql(OldIrql);
2292 }
2293
2294 Event = Transfer->Event;
2295
2296 if (Event)
2297 {
2298 KeSetEvent(Event, EVENT_INCREMENT, FALSE);
2299 }
2300
2301 ExFreePoolWithTag(Transfer, USB_PORT_TAG);
2302
2303 DPRINT_CORE("USBPORT_CompleteTransfer: exit\n");
2304 }
2305
2306 IO_ALLOCATION_ACTION
2307 NTAPI
USBPORT_MapTransfer(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PVOID MapRegisterBase,IN PVOID Context)2308 USBPORT_MapTransfer(IN PDEVICE_OBJECT FdoDevice,
2309 IN PIRP Irp,
2310 IN PVOID MapRegisterBase,
2311 IN PVOID Context)
2312 {
2313 PUSBPORT_DEVICE_EXTENSION FdoExtension;
2314 PDMA_ADAPTER DmaAdapter;
2315 PUSBPORT_TRANSFER Transfer;
2316 PURB Urb;
2317 PUSBPORT_ENDPOINT Endpoint;
2318 PMDL Mdl;
2319 ULONG_PTR CurrentVa;
2320 PUSBPORT_SCATTER_GATHER_LIST sgList;
2321 SIZE_T CurrentLength;
2322 ULONG ix;
2323 BOOLEAN WriteToDevice;
2324 PHYSICAL_ADDRESS PhAddr = {{0, 0}};
2325 PHYSICAL_ADDRESS PhAddress = {{0, 0}};
2326 ULONG TransferLength;
2327 SIZE_T SgCurrentLength;
2328 SIZE_T ElementLength;
2329 PUSBPORT_DEVICE_HANDLE DeviceHandle;
2330 PDMA_OPERATIONS DmaOperations;
2331 USBD_STATUS USBDStatus;
2332 LIST_ENTRY List;
2333 PUSBPORT_TRANSFER transfer;
2334
2335 DPRINT_CORE("USBPORT_MapTransfer: ...\n");
2336
2337 FdoExtension = FdoDevice->DeviceExtension;
2338 DmaAdapter = FdoExtension->DmaAdapter;
2339 DmaOperations = DmaAdapter->DmaOperations;
2340
2341 Transfer = Context;
2342
2343 Urb = Transfer->Urb;
2344 Endpoint = Transfer->Endpoint;
2345 TransferLength = Transfer->TransferParameters.TransferBufferLength;
2346
2347 Mdl = Urb->UrbControlTransfer.TransferBufferMDL;
2348 CurrentVa = (ULONG_PTR)MmGetMdlVirtualAddress(Mdl);
2349
2350 sgList = &Transfer->SgList;
2351
2352 sgList->Flags = 0;
2353 sgList->CurrentVa = CurrentVa;
2354 sgList->MappedSystemVa = MmGetSystemAddressForMdlSafe(Mdl,
2355 NormalPagePriority);
2356 Transfer->MapRegisterBase = MapRegisterBase;
2357
2358 ix = 0;
2359 CurrentLength = 0;
2360
2361 do
2362 {
2363 WriteToDevice = Transfer->Direction == USBPORT_DMA_DIRECTION_TO_DEVICE;
2364 ASSERT(Transfer->Direction != 0);
2365
2366 PhAddress = DmaOperations->MapTransfer(DmaAdapter,
2367 Mdl,
2368 MapRegisterBase,
2369 (PVOID)CurrentVa,
2370 &TransferLength,
2371 WriteToDevice);
2372
2373 DPRINT_CORE("USBPORT_MapTransfer: PhAddress.LowPart - %p, PhAddress.HighPart - %x, TransferLength - %x\n",
2374 PhAddress.LowPart,
2375 PhAddress.HighPart,
2376 TransferLength);
2377
2378 PhAddress.HighPart = 0;
2379 SgCurrentLength = TransferLength;
2380
2381 do
2382 {
2383 ElementLength = PAGE_SIZE - (PhAddress.LowPart & (PAGE_SIZE - 1));
2384
2385 if (ElementLength > SgCurrentLength)
2386 ElementLength = SgCurrentLength;
2387
2388 DPRINT_CORE("USBPORT_MapTransfer: PhAddress.LowPart - %p, HighPart - %x, ElementLength - %x\n",
2389 PhAddress.LowPart,
2390 PhAddress.HighPart,
2391 ElementLength);
2392
2393 sgList->SgElement[ix].SgPhysicalAddress = PhAddress;
2394 sgList->SgElement[ix].SgTransferLength = ElementLength;
2395 sgList->SgElement[ix].SgOffset = CurrentLength +
2396 (TransferLength - SgCurrentLength);
2397
2398 PhAddress.LowPart += ElementLength;
2399 SgCurrentLength -= ElementLength;
2400
2401 ++ix;
2402 }
2403 while (SgCurrentLength);
2404
2405 if (PhAddr.QuadPart == PhAddress.QuadPart)
2406 {
2407 DPRINT1("USBPORT_MapTransfer: PhAddr == PhAddress\n");
2408 ASSERT(FALSE);
2409 }
2410
2411 PhAddr = PhAddress;
2412
2413 CurrentLength += TransferLength;
2414 CurrentVa += TransferLength;
2415
2416 TransferLength = Transfer->TransferParameters.TransferBufferLength -
2417 CurrentLength;
2418 }
2419 while (CurrentLength != Transfer->TransferParameters.TransferBufferLength);
2420
2421 sgList->SgElementCount = ix;
2422
2423 if (Endpoint->EndpointProperties.DeviceSpeed == UsbHighSpeed)
2424 {
2425 Transfer->Flags |= TRANSFER_FLAG_HIGH_SPEED;
2426 }
2427
2428 Transfer->Flags |= TRANSFER_FLAG_DMA_MAPPED;
2429
2430 if ((Transfer->Flags & TRANSFER_FLAG_ISO) == 0)
2431 {
2432 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
2433 &Endpoint->EndpointOldIrql);
2434
2435 USBPORT_SplitTransfer(FdoDevice, Endpoint, Transfer, &List);
2436
2437 while (!IsListEmpty(&List))
2438 {
2439 transfer = CONTAINING_RECORD(List.Flink,
2440 USBPORT_TRANSFER,
2441 TransferLink);
2442
2443 RemoveHeadList(&List);
2444 InsertTailList(&Endpoint->TransferList, &transfer->TransferLink);
2445 }
2446
2447 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
2448 Endpoint->EndpointOldIrql);
2449 }
2450 else
2451 {
2452 USBDStatus = USBPORT_InitializeIsoTransfer(FdoDevice,
2453 &Urb->UrbIsochronousTransfer,
2454 Transfer);
2455
2456 if (USBDStatus != USBD_STATUS_SUCCESS)
2457 {
2458 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
2459 &Endpoint->EndpointOldIrql);
2460
2461 USBPORT_QueueDoneTransfer(Transfer, USBDStatus);
2462
2463 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
2464 Endpoint->EndpointOldIrql);
2465 }
2466 }
2467
2468 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
2469 InterlockedDecrement(&DeviceHandle->DeviceHandleLock);
2470
2471 if (USBPORT_EndpointWorker(Endpoint, 0))
2472 {
2473 USBPORT_InvalidateEndpointHandler(FdoDevice,
2474 Endpoint,
2475 INVALIDATE_ENDPOINT_WORKER_THREAD);
2476 }
2477
2478 return DeallocateObjectKeepRegisters;
2479 }
2480
2481 VOID
2482 NTAPI
USBPORT_FlushMapTransfers(IN PDEVICE_OBJECT FdoDevice)2483 USBPORT_FlushMapTransfers(IN PDEVICE_OBJECT FdoDevice)
2484 {
2485 PUSBPORT_DEVICE_EXTENSION FdoExtension;
2486 PLIST_ENTRY MapTransferList;
2487 PUSBPORT_TRANSFER Transfer;
2488 ULONG NumMapRegisters;
2489 PMDL Mdl;
2490 SIZE_T TransferBufferLength;
2491 ULONG_PTR VirtualAddr;
2492 KIRQL OldIrql;
2493 NTSTATUS Status;
2494 PDMA_OPERATIONS DmaOperations;
2495
2496 DPRINT_CORE("USBPORT_FlushMapTransfers: ...\n");
2497
2498 FdoExtension = FdoDevice->DeviceExtension;
2499 DmaOperations = FdoExtension->DmaAdapter->DmaOperations;
2500
2501 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
2502
2503 while (TRUE)
2504 {
2505 MapTransferList = &FdoExtension->MapTransferList;
2506
2507 if (IsListEmpty(&FdoExtension->MapTransferList))
2508 {
2509 KeLowerIrql(OldIrql);
2510 return;
2511 }
2512
2513 Transfer = CONTAINING_RECORD(MapTransferList->Flink,
2514 USBPORT_TRANSFER,
2515 TransferLink);
2516
2517 RemoveHeadList(MapTransferList);
2518
2519 Mdl = Transfer->Urb->UrbControlTransfer.TransferBufferMDL;
2520 TransferBufferLength = Transfer->TransferParameters.TransferBufferLength;
2521 VirtualAddr = (ULONG_PTR)MmGetMdlVirtualAddress(Mdl);
2522
2523 NumMapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddr,
2524 TransferBufferLength);
2525
2526 Transfer->NumberOfMapRegisters = NumMapRegisters;
2527
2528 Status = DmaOperations->AllocateAdapterChannel(FdoExtension->DmaAdapter,
2529 FdoDevice,
2530 NumMapRegisters,
2531 USBPORT_MapTransfer,
2532 Transfer);
2533
2534 if (!NT_SUCCESS(Status))
2535 ASSERT(FALSE);
2536 }
2537
2538 KeLowerIrql(OldIrql);
2539 }
2540
2541 USBD_STATUS
2542 NTAPI
USBPORT_AllocateTransfer(IN PDEVICE_OBJECT FdoDevice,IN PURB Urb,IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PIRP Irp,IN PRKEVENT Event)2543 USBPORT_AllocateTransfer(IN PDEVICE_OBJECT FdoDevice,
2544 IN PURB Urb,
2545 IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
2546 IN PIRP Irp,
2547 IN PRKEVENT Event)
2548 {
2549 PUSBPORT_DEVICE_EXTENSION FdoExtension;
2550 SIZE_T TransferLength;
2551 PMDL Mdl;
2552 ULONG_PTR VirtualAddr;
2553 ULONG PagesNeed = 0;
2554 SIZE_T PortTransferLength;
2555 SIZE_T FullTransferLength;
2556 PUSBPORT_TRANSFER Transfer;
2557 PUSBPORT_PIPE_HANDLE PipeHandle;
2558 USBD_STATUS USBDStatus;
2559 SIZE_T IsoBlockLen = 0;
2560
2561 DPRINT_CORE("USBPORT_AllocateTransfer: FdoDevice - %p, Urb - %p, DeviceHandle - %p, Irp - %p, Event - %p\n",
2562 FdoDevice,
2563 Urb,
2564 DeviceHandle,
2565 Irp,
2566 Event);
2567
2568 FdoExtension = FdoDevice->DeviceExtension;
2569
2570 TransferLength = Urb->UrbControlTransfer.TransferBufferLength;
2571 PipeHandle = Urb->UrbControlTransfer.PipeHandle;
2572
2573 if (TransferLength)
2574 {
2575 Mdl = Urb->UrbControlTransfer.TransferBufferMDL;
2576 VirtualAddr = (ULONG_PTR)MmGetMdlVirtualAddress(Mdl);
2577
2578 PagesNeed = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddr,
2579 TransferLength);
2580 if (PagesNeed > 0)
2581 {
2582 PagesNeed--;
2583 }
2584 }
2585
2586 if (Urb->UrbHeader.Function == URB_FUNCTION_ISOCH_TRANSFER)
2587 {
2588 DPRINT1("USBPORT_AllocateTransfer: ISOCH_TRANSFER UNIMPLEMENTED. FIXME\n");
2589
2590 //IsoBlockLen = sizeof(USBPORT_ISO_BLOCK) +
2591 // Urb->UrbIsochronousTransfer.NumberOfPackets *
2592 // sizeof(USBPORT_ISO_BLOCK_PACKET);
2593 }
2594
2595 PortTransferLength = sizeof(USBPORT_TRANSFER) +
2596 PagesNeed * sizeof(USBPORT_SCATTER_GATHER_ELEMENT) +
2597 IsoBlockLen;
2598
2599 FullTransferLength = PortTransferLength +
2600 FdoExtension->MiniPortInterface->Packet.MiniPortTransferSize;
2601
2602 Transfer = ExAllocatePoolWithTag(NonPagedPool,
2603 FullTransferLength,
2604 USB_PORT_TAG);
2605
2606 if (!Transfer)
2607 {
2608 DPRINT1("USBPORT_AllocateTransfer: Transfer not allocated!\n");
2609 return USBD_STATUS_INSUFFICIENT_RESOURCES;
2610 }
2611
2612 RtlZeroMemory(Transfer, FullTransferLength);
2613
2614 Transfer->Irp = Irp;
2615 Transfer->Urb = Urb;
2616 Transfer->Endpoint = PipeHandle->Endpoint;
2617 Transfer->Event = Event;
2618 Transfer->PortTransferLength = PortTransferLength;
2619 Transfer->FullTransferLength = FullTransferLength;
2620 Transfer->IsoBlockPtr = NULL;
2621 Transfer->Period = 0;
2622 Transfer->ParentTransfer = Transfer;
2623
2624 if (IsoBlockLen)
2625 {
2626 Transfer->IsoBlockPtr = (PVOID)((ULONG_PTR)Transfer +
2627 PortTransferLength - IsoBlockLen);
2628
2629 Transfer->Period = PipeHandle->Endpoint->EndpointProperties.Period;
2630 Transfer->Flags |= TRANSFER_FLAG_ISO;
2631 }
2632
2633 Transfer->MiniportTransfer = (PVOID)((ULONG_PTR)Transfer +
2634 PortTransferLength);
2635
2636 KeInitializeSpinLock(&Transfer->TransferSpinLock);
2637
2638 Urb->UrbControlTransfer.hca.Reserved8[0] = Transfer;
2639 Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_TRANSFER;
2640
2641 USBDStatus = USBD_STATUS_SUCCESS;
2642
2643 DPRINT_CORE("USBPORT_AllocateTransfer: return USBDStatus - %x\n",
2644 USBDStatus);
2645
2646 return USBDStatus;
2647 }
2648
2649 NTSTATUS
2650 NTAPI
USBPORT_Dispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)2651 USBPORT_Dispatch(IN PDEVICE_OBJECT DeviceObject,
2652 IN PIRP Irp)
2653 {
2654 PUSBPORT_COMMON_DEVICE_EXTENSION DeviceExtension;
2655 PIO_STACK_LOCATION IoStack;
2656 NTSTATUS Status = STATUS_SUCCESS;
2657
2658 DeviceExtension = DeviceObject->DeviceExtension;
2659 IoStack = IoGetCurrentIrpStackLocation(Irp);
2660
2661 if (DeviceExtension->PnpStateFlags & USBPORT_PNP_STATE_FAILED)
2662 {
2663 DPRINT1("USBPORT_Dispatch: USBPORT_PNP_STATE_FAILED\n");
2664 DbgBreakPoint();
2665 }
2666
2667 switch (IoStack->MajorFunction)
2668 {
2669 case IRP_MJ_DEVICE_CONTROL:
2670 if (DeviceExtension->IsPDO)
2671 {
2672 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2673 IoStack->MajorFunction,
2674 IoStack->MinorFunction);
2675
2676 Status = USBPORT_PdoDeviceControl(DeviceObject, Irp);
2677 }
2678 else
2679 {
2680 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2681 IoStack->MajorFunction,
2682 IoStack->MinorFunction);
2683
2684 Status = USBPORT_FdoDeviceControl(DeviceObject, Irp);
2685 }
2686
2687 break;
2688
2689 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
2690 if (DeviceExtension->IsPDO)
2691 {
2692 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_INTERNAL_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2693 IoStack->MajorFunction,
2694 IoStack->MinorFunction);
2695
2696 Status = USBPORT_PdoInternalDeviceControl(DeviceObject, Irp);
2697 }
2698 else
2699 {
2700 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_INTERNAL_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2701 IoStack->MajorFunction,
2702 IoStack->MinorFunction);
2703
2704 Status = USBPORT_FdoInternalDeviceControl(DeviceObject, Irp);
2705 }
2706
2707 break;
2708
2709 case IRP_MJ_POWER:
2710 if (DeviceExtension->IsPDO)
2711 {
2712 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_POWER. Major - %d, Minor - %d\n",
2713 IoStack->MajorFunction,
2714 IoStack->MinorFunction);
2715
2716 Status = USBPORT_PdoPower(DeviceObject, Irp);
2717 }
2718 else
2719 {
2720 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_POWER. Major - %d, Minor - %d\n",
2721 IoStack->MajorFunction,
2722 IoStack->MinorFunction);
2723
2724 Status = USBPORT_FdoPower(DeviceObject, Irp);
2725 }
2726
2727 break;
2728
2729 case IRP_MJ_SYSTEM_CONTROL:
2730 if (DeviceExtension->IsPDO)
2731 {
2732 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_SYSTEM_CONTROL. Major - %d, Minor - %d\n",
2733 IoStack->MajorFunction,
2734 IoStack->MinorFunction);
2735
2736 Status = Irp->IoStatus.Status;
2737 IoCompleteRequest(Irp, IO_NO_INCREMENT);
2738 }
2739 else
2740 {
2741 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_SYSTEM_CONTROL. Major - %d, Minor - %d\n",
2742 IoStack->MajorFunction,
2743 IoStack->MinorFunction);
2744
2745 IoSkipCurrentIrpStackLocation(Irp);
2746 Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
2747 }
2748
2749 break;
2750
2751 case IRP_MJ_PNP:
2752 if (DeviceExtension->IsPDO)
2753 {
2754 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_PNP. Major - %d, Minor - %d\n",
2755 IoStack->MajorFunction,
2756 IoStack->MinorFunction);
2757
2758 Status = USBPORT_PdoPnP(DeviceObject, Irp);
2759 }
2760 else
2761 {
2762 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_PNP. Major - %d, Minor - %d\n",
2763 IoStack->MajorFunction,
2764 IoStack->MinorFunction);
2765
2766 Status = USBPORT_FdoPnP(DeviceObject, Irp);
2767 }
2768
2769 break;
2770
2771 case IRP_MJ_CREATE:
2772 case IRP_MJ_CLOSE:
2773 DPRINT("USBPORT_Dispatch: IRP_MJ_CREATE | IRP_MJ_CLOSE\n");
2774 Irp->IoStatus.Status = Status;
2775 IoCompleteRequest(Irp, IO_NO_INCREMENT);
2776 break;
2777
2778 default:
2779 if (DeviceExtension->IsPDO)
2780 {
2781 DPRINT("USBPORT_Dispatch: PDO unhandled IRP_MJ_???. Major - %d, Minor - %d\n",
2782 IoStack->MajorFunction,
2783 IoStack->MinorFunction);
2784 }
2785 else
2786 {
2787 DPRINT("USBPORT_Dispatch: FDO unhandled IRP_MJ_???. Major - %d, Minor - %d\n",
2788 IoStack->MajorFunction,
2789 IoStack->MinorFunction);
2790 }
2791
2792 Status = STATUS_INVALID_DEVICE_REQUEST;
2793 Irp->IoStatus.Status = Status;
2794 IoCompleteRequest(Irp, IO_NO_INCREMENT);
2795 break;
2796 }
2797
2798 DPRINT("USBPORT_Dispatch: Status - %x\n", Status);
2799 return Status;
2800 }
2801
2802 ULONG
2803 NTAPI
USBPORT_GetHciMn(VOID)2804 USBPORT_GetHciMn(VOID)
2805 {
2806 return USBPORT_HCI_MN;
2807 }
2808
2809 NTSTATUS
2810 NTAPI
USBPORT_RegisterUSBPortDriver(IN PDRIVER_OBJECT DriverObject,IN ULONG Version,IN PUSBPORT_REGISTRATION_PACKET RegPacket)2811 USBPORT_RegisterUSBPortDriver(IN PDRIVER_OBJECT DriverObject,
2812 IN ULONG Version,
2813 IN PUSBPORT_REGISTRATION_PACKET RegPacket)
2814 {
2815 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface;
2816
2817 DPRINT("USBPORT_RegisterUSBPortDriver: DriverObject - %p, Version - %p, RegPacket - %p\n",
2818 DriverObject,
2819 Version,
2820 RegPacket);
2821
2822 DPRINT("USBPORT_RegisterUSBPortDriver: sizeof(USBPORT_MINIPORT_INTERFACE) - %x\n",
2823 sizeof(USBPORT_MINIPORT_INTERFACE));
2824
2825 DPRINT("USBPORT_RegisterUSBPortDriver: sizeof(USBPORT_DEVICE_EXTENSION) - %x\n",
2826 sizeof(USBPORT_DEVICE_EXTENSION));
2827
2828 if (Version < USB10_MINIPORT_INTERFACE_VERSION)
2829 {
2830 return STATUS_UNSUCCESSFUL;
2831 }
2832
2833 if (!USBPORT_Initialized)
2834 {
2835 InitializeListHead(&USBPORT_MiniPortDrivers);
2836 InitializeListHead(&USBPORT_USB1FdoList);
2837 InitializeListHead(&USBPORT_USB2FdoList);
2838
2839 KeInitializeSpinLock(&USBPORT_SpinLock);
2840 USBPORT_Initialized = TRUE;
2841 }
2842
2843 MiniPortInterface = ExAllocatePoolWithTag(NonPagedPool,
2844 sizeof(USBPORT_MINIPORT_INTERFACE),
2845 USB_PORT_TAG);
2846 if (!MiniPortInterface)
2847 {
2848 return STATUS_INSUFFICIENT_RESOURCES;
2849 }
2850
2851 RtlZeroMemory(MiniPortInterface, sizeof(USBPORT_MINIPORT_INTERFACE));
2852
2853 MiniPortInterface->DriverObject = DriverObject;
2854 MiniPortInterface->DriverUnload = DriverObject->DriverUnload;
2855 MiniPortInterface->Version = Version;
2856
2857 ExInterlockedInsertTailList(&USBPORT_MiniPortDrivers,
2858 &MiniPortInterface->DriverLink,
2859 &USBPORT_SpinLock);
2860
2861 DriverObject->DriverExtension->AddDevice = USBPORT_AddDevice;
2862 DriverObject->DriverUnload = USBPORT_Unload;
2863
2864 DriverObject->MajorFunction[IRP_MJ_CREATE] = USBPORT_Dispatch;
2865 DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBPORT_Dispatch;
2866 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBPORT_Dispatch;
2867 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBPORT_Dispatch;
2868 DriverObject->MajorFunction[IRP_MJ_PNP] = USBPORT_Dispatch;
2869 DriverObject->MajorFunction[IRP_MJ_POWER] = USBPORT_Dispatch;
2870 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = USBPORT_Dispatch;
2871
2872 RegPacket->UsbPortDbgPrint = USBPORT_DbgPrint;
2873 RegPacket->UsbPortTestDebugBreak = USBPORT_TestDebugBreak;
2874 RegPacket->UsbPortAssertFailure = USBPORT_AssertFailure;
2875 RegPacket->UsbPortGetMiniportRegistryKeyValue = USBPORT_GetMiniportRegistryKeyValue;
2876 RegPacket->UsbPortInvalidateRootHub = USBPORT_InvalidateRootHub;
2877 RegPacket->UsbPortInvalidateEndpoint = USBPORT_InvalidateEndpoint;
2878 RegPacket->UsbPortCompleteTransfer = USBPORT_MiniportCompleteTransfer;
2879 RegPacket->UsbPortCompleteIsoTransfer = USBPORT_CompleteIsoTransfer;
2880 RegPacket->UsbPortLogEntry = USBPORT_LogEntry;
2881 RegPacket->UsbPortGetMappedVirtualAddress = USBPORT_GetMappedVirtualAddress;
2882 RegPacket->UsbPortRequestAsyncCallback = USBPORT_RequestAsyncCallback;
2883 RegPacket->UsbPortReadWriteConfigSpace = USBPORT_ReadWriteConfigSpace;
2884 RegPacket->UsbPortWait = USBPORT_Wait;
2885 RegPacket->UsbPortInvalidateController = USBPORT_InvalidateController;
2886 RegPacket->UsbPortBugCheck = USBPORT_BugCheck;
2887 RegPacket->UsbPortNotifyDoubleBuffer = USBPORT_NotifyDoubleBuffer;
2888
2889 RtlCopyMemory(&MiniPortInterface->Packet,
2890 RegPacket,
2891 sizeof(USBPORT_REGISTRATION_PACKET));
2892
2893 return STATUS_SUCCESS;
2894 }
2895
2896 NTSTATUS
2897 NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)2898 DriverEntry(IN PDRIVER_OBJECT DriverObject,
2899 IN PUNICODE_STRING RegistryPath)
2900 {
2901 return STATUS_SUCCESS;
2902 }
2903