6 #define NDEBUG_USBPORT_CORE
7 #define NDEBUG_USBPORT_INTERRUPT
8 #define NDEBUG_USBPORT_TIMER
11 LIST_ENTRY USBPORT_MiniPortDrivers
= {NULL
, NULL
};
12 LIST_ENTRY USBPORT_USB1FdoList
= {NULL
, NULL
};
13 LIST_ENTRY USBPORT_USB2FdoList
= {NULL
, NULL
};
15 KSPIN_LOCK USBPORT_SpinLock
;
16 BOOLEAN USBPORT_Initialized
= FALSE
;
20 USBPORT_FindUSB2Controller(IN PDEVICE_OBJECT FdoDevice
)
22 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
23 PUSBPORT_DEVICE_EXTENSION USB2FdoExtension
;
25 PLIST_ENTRY USB2FdoEntry
;
26 PDEVICE_OBJECT USB2FdoDevice
= NULL
;
28 DPRINT("USBPORT_FindUSB2Controller: FdoDevice - %p\n", FdoDevice
);
30 FdoExtension
= FdoDevice
->DeviceExtension
;
32 KeAcquireSpinLock(&USBPORT_SpinLock
, &OldIrql
);
34 USB2FdoEntry
= USBPORT_USB2FdoList
.Flink
;
36 while (USB2FdoEntry
&& USB2FdoEntry
!= &USBPORT_USB2FdoList
)
38 USB2FdoExtension
= CONTAINING_RECORD(USB2FdoEntry
,
39 USBPORT_DEVICE_EXTENSION
,
42 if (USB2FdoExtension
->BusNumber
== FdoExtension
->BusNumber
&&
43 USB2FdoExtension
->PciDeviceNumber
== FdoExtension
->PciDeviceNumber
)
45 USB2FdoDevice
= USB2FdoExtension
->CommonExtension
.SelfDevice
;
49 USB2FdoEntry
= USB2FdoEntry
->Flink
;
52 KeReleaseSpinLock(&USBPORT_SpinLock
, OldIrql
);
59 USBPORT_AddUSB1Fdo(IN PDEVICE_OBJECT FdoDevice
)
61 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
63 DPRINT("USBPORT_AddUSB1Fdo: FdoDevice - %p\n", FdoDevice
);
65 FdoExtension
= FdoDevice
->DeviceExtension
;
66 FdoExtension
->Flags
|= USBPORT_FLAG_REGISTERED_FDO
;
68 ExInterlockedInsertTailList(&USBPORT_USB1FdoList
,
69 &FdoExtension
->ControllerLink
,
75 USBPORT_AddUSB2Fdo(IN PDEVICE_OBJECT FdoDevice
)
77 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
79 DPRINT("USBPORT_AddUSB2Fdo: FdoDevice - %p\n", FdoDevice
);
81 FdoExtension
= FdoDevice
->DeviceExtension
;
82 FdoExtension
->Flags
|= USBPORT_FLAG_REGISTERED_FDO
;
84 ExInterlockedInsertTailList(&USBPORT_USB2FdoList
,
85 &FdoExtension
->ControllerLink
,
91 USBPORT_RemoveUSBxFdo(IN PDEVICE_OBJECT FdoDevice
)
93 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
96 DPRINT("USBPORT_RemoveUSBxFdo: FdoDevice - %p\n", FdoDevice
);
98 FdoExtension
= FdoDevice
->DeviceExtension
;
100 KeAcquireSpinLock(&USBPORT_SpinLock
, &OldIrql
);
101 RemoveEntryList(&FdoExtension
->ControllerLink
);
102 KeReleaseSpinLock(&USBPORT_SpinLock
, OldIrql
);
104 FdoExtension
->Flags
&= ~USBPORT_FLAG_REGISTERED_FDO
;
106 FdoExtension
->ControllerLink
.Flink
= NULL
;
107 FdoExtension
->ControllerLink
.Blink
= NULL
;
112 USBPORT_IsCompanionFdoExtension(IN PDEVICE_OBJECT USB2FdoDevice
,
113 IN PUSBPORT_DEVICE_EXTENSION USB1FdoExtension
)
115 PUSBPORT_DEVICE_EXTENSION USB2FdoExtension
;
117 DPRINT("USBPORT_IsCompanionFdoExtension: USB2Fdo - %p, USB1FdoExtension - %p\n",
121 USB2FdoExtension
= USB2FdoDevice
->DeviceExtension
;
123 return USB2FdoExtension
->BusNumber
== USB1FdoExtension
->BusNumber
&&
124 USB2FdoExtension
->PciDeviceNumber
== USB1FdoExtension
->PciDeviceNumber
;
129 USBPORT_FindCompanionControllers(IN PDEVICE_OBJECT USB2FdoDevice
,
130 IN BOOLEAN IsObRefer
,
131 IN BOOLEAN IsFDOsReturned
)
133 PLIST_ENTRY USB1FdoList
;
134 PUSBPORT_DEVICE_EXTENSION USB1FdoExtension
;
135 ULONG NumControllers
= 0;
136 PDEVICE_OBJECT
* Entry
;
137 PDEVICE_RELATIONS ControllersList
= NULL
;
140 DPRINT("USBPORT_FindCompanionControllers: USB2Fdo - %p, IsObRefer - %x, IsFDOs - %x\n",
145 KeAcquireSpinLock(&USBPORT_SpinLock
, &OldIrql
);
147 USB1FdoList
= USBPORT_USB1FdoList
.Flink
;
149 while (USB1FdoList
&& USB1FdoList
!= &USBPORT_USB1FdoList
)
151 USB1FdoExtension
= CONTAINING_RECORD(USB1FdoList
,
152 USBPORT_DEVICE_EXTENSION
,
155 if (USB1FdoExtension
->Flags
& USBPORT_FLAG_COMPANION_HC
&&
156 USBPORT_IsCompanionFdoExtension(USB2FdoDevice
, USB1FdoExtension
))
161 USB1FdoList
= USB1FdoExtension
->ControllerLink
.Flink
;
164 DPRINT("USBPORT_FindCompanionControllers: NumControllers - %x\n",
172 ControllersList
= ExAllocatePoolWithTag(NonPagedPool
,
173 NumControllers
* sizeof(DEVICE_RELATIONS
),
176 if (!ControllersList
)
181 RtlZeroMemory(ControllersList
, NumControllers
* sizeof(DEVICE_RELATIONS
));
183 ControllersList
->Count
= NumControllers
;
185 USB1FdoList
= USBPORT_USB1FdoList
.Flink
;
187 Entry
= &ControllersList
->Objects
[0];
189 while (USB1FdoList
&& USB1FdoList
!= &USBPORT_USB1FdoList
)
191 USB1FdoExtension
= CONTAINING_RECORD(USB1FdoList
,
192 USBPORT_DEVICE_EXTENSION
,
195 if (USB1FdoExtension
->Flags
& USBPORT_FLAG_COMPANION_HC
&&
196 USBPORT_IsCompanionFdoExtension(USB2FdoDevice
, USB1FdoExtension
))
198 *Entry
= USB1FdoExtension
->CommonExtension
.LowerPdoDevice
;
202 ObReferenceObject(USB1FdoExtension
->CommonExtension
.LowerPdoDevice
);
207 *Entry
= USB1FdoExtension
->CommonExtension
.SelfDevice
;
213 USB1FdoList
= USB1FdoExtension
->ControllerLink
.Flink
;
218 KeReleaseSpinLock(&USBPORT_SpinLock
, OldIrql
);
220 return ControllersList
;
225 USBPORT_NtStatusToMpStatus(NTSTATUS NtStatus
)
227 DPRINT("USBPORT_NtStatusToMpStatus: NtStatus - %x\n", NtStatus
);
229 if (NtStatus
== STATUS_SUCCESS
)
231 return MP_STATUS_SUCCESS
;
235 return MP_STATUS_UNSUCCESSFUL
;
241 USBPORT_SetRegistryKeyValue(IN PDEVICE_OBJECT DeviceObject
,
242 IN BOOL UseDriverKey
,
244 IN PCWSTR ValueNameString
,
248 UNICODE_STRING ValueName
;
252 DPRINT("USBPORT_SetRegistryKeyValue: ValueNameString - %S \n",
257 Status
= IoOpenDeviceRegistryKey(DeviceObject
,
258 PLUGPLAY_REGKEY_DRIVER
,
264 Status
= IoOpenDeviceRegistryKey(DeviceObject
,
265 PLUGPLAY_REGKEY_DEVICE
,
270 if (NT_SUCCESS(Status
))
272 RtlInitUnicodeString(&ValueName
, ValueNameString
);
274 Status
= ZwSetValueKey(KeyHandle
,
289 USBPORT_GetRegistryKeyValueFullInfo(IN PDEVICE_OBJECT FdoDevice
,
290 IN PDEVICE_OBJECT PdoDevice
,
291 IN BOOL UseDriverKey
,
292 IN PCWSTR SourceString
,
295 IN ULONG BufferLength
)
298 PKEY_VALUE_FULL_INFORMATION KeyValue
;
299 UNICODE_STRING ValueName
;
303 DPRINT("USBPORT_GetRegistryKeyValue: UseDriverKey - %x, SourceString - %S, LengthStr - %x, Buffer - %p, BufferLength - %x\n",
312 Status
= IoOpenDeviceRegistryKey(PdoDevice
,
313 PLUGPLAY_REGKEY_DRIVER
,
319 Status
= IoOpenDeviceRegistryKey(PdoDevice
,
320 PLUGPLAY_REGKEY_DEVICE
,
325 if (NT_SUCCESS(Status
))
327 RtlInitUnicodeString(&ValueName
, SourceString
);
329 LengthKey
= sizeof(KEY_VALUE_FULL_INFORMATION
) +
333 KeyValue
= ExAllocatePoolWithTag(PagedPool
,
339 RtlZeroMemory(KeyValue
, LengthKey
);
341 Status
= ZwQueryValueKey(KeyHandle
,
343 KeyValueFullInformation
,
348 if (NT_SUCCESS(Status
))
350 RtlCopyMemory(Buffer
,
351 (PUCHAR
)KeyValue
+ KeyValue
->DataOffset
,
355 ExFreePoolWithTag(KeyValue
, USB_PORT_TAG
);
366 USBPORT_GetMiniportRegistryKeyValue(IN PVOID MiniPortExtension
,
367 IN BOOL UseDriverKey
,
368 IN PCWSTR SourceString
,
371 IN SIZE_T BufferLength
)
373 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
374 PDEVICE_OBJECT FdoDevice
;
377 DPRINT("USBPORT_GetMiniportRegistryKeyValue: MiniPortExtension - %p, UseDriverKey - %x, SourceString - %S, LengthStr - %x, Buffer - %p, BufferLength - %x\n",
385 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)MiniPortExtension
-
386 sizeof(USBPORT_DEVICE_EXTENSION
));
388 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
390 Status
= USBPORT_GetRegistryKeyValueFullInfo(FdoDevice
,
391 FdoExtension
->CommonExtension
.LowerPdoDevice
,
398 return USBPORT_NtStatusToMpStatus(Status
);
403 USBPORT_GetSetConfigSpaceData(IN PDEVICE_OBJECT FdoDevice
,
404 IN BOOLEAN IsReadData
,
409 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
410 ULONG BytesReadWrite
;
412 DPRINT("USBPORT_GetSetConfigSpaceData ... \n");
414 FdoExtension
= FdoDevice
->DeviceExtension
;
416 BytesReadWrite
= Length
;
420 RtlZeroMemory(Buffer
, Length
);
422 BytesReadWrite
= (*FdoExtension
->BusInterface
.GetBusData
)
423 (FdoExtension
->BusInterface
.Context
,
424 PCI_WHICHSPACE_CONFIG
,
431 BytesReadWrite
= (*FdoExtension
->BusInterface
.SetBusData
)
432 (FdoExtension
->BusInterface
.Context
,
433 PCI_WHICHSPACE_CONFIG
,
439 if (BytesReadWrite
== Length
)
441 return STATUS_SUCCESS
;
444 return STATUS_UNSUCCESSFUL
;
449 USBPORT_ReadWriteConfigSpace(IN PVOID MiniPortExtension
,
450 IN BOOLEAN IsReadData
,
456 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
457 PDEVICE_OBJECT FdoDevice
;
459 DPRINT("USBPORT_ReadWriteConfigSpace: ... \n");
461 //FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION));
462 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)MiniPortExtension
-
463 sizeof(USBPORT_DEVICE_EXTENSION
));
465 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
467 Status
= USBPORT_GetSetConfigSpaceData(FdoDevice
,
473 return USBPORT_NtStatusToMpStatus(Status
);
478 USBPORT_USBDStatusToNtStatus(IN PURB Urb
,
479 IN USBD_STATUS USBDStatus
)
483 if (USBD_ERROR(USBDStatus
))
485 DPRINT1("USBPORT_USBDStatusToNtStatus: Urb - %p, USBDStatus - %x\n",
491 Urb
->UrbHeader
.Status
= USBDStatus
;
495 case USBD_STATUS_SUCCESS
:
496 Status
= STATUS_SUCCESS
;
499 case USBD_STATUS_INSUFFICIENT_RESOURCES
:
500 Status
= STATUS_INSUFFICIENT_RESOURCES
;
503 case USBD_STATUS_DEVICE_GONE
:
504 Status
= STATUS_DEVICE_NOT_CONNECTED
;
507 case USBD_STATUS_CANCELED
:
508 Status
= STATUS_CANCELLED
;
511 case USBD_STATUS_NOT_SUPPORTED
:
512 Status
= STATUS_NOT_SUPPORTED
;
515 case USBD_STATUS_INVALID_URB_FUNCTION
:
516 case USBD_STATUS_INVALID_PARAMETER
:
517 case USBD_STATUS_INVALID_PIPE_HANDLE
:
518 case USBD_STATUS_BAD_START_FRAME
:
519 Status
= STATUS_INVALID_PARAMETER
;
523 if (USBD_ERROR(USBDStatus
))
524 Status
= STATUS_UNSUCCESSFUL
;
526 Status
= STATUS_SUCCESS
;
536 USBPORT_Wait(IN PVOID MiniPortExtension
,
537 IN ULONG Milliseconds
)
539 LARGE_INTEGER Interval
= {{0, 0}};
541 DPRINT("USBPORT_Wait: Milliseconds - %x\n", Milliseconds
);
542 Interval
.QuadPart
-= 10000 * Milliseconds
+ (KeQueryTimeIncrement() - 1);
543 return KeDelayExecutionThread(KernelMode
, FALSE
, &Interval
);
548 USBPORT_MiniportInterrupts(IN PDEVICE_OBJECT FdoDevice
,
551 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
552 PUSBPORT_REGISTRATION_PACKET Packet
;
556 DPRINT_INT("USBPORT_MiniportInterrupts: IsEnable - %p\n", IsEnable
);
558 FdoExtension
= FdoDevice
->DeviceExtension
;
559 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
561 IsLock
= (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_NOT_LOCK_INT
) == 0;
564 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
568 FdoExtension
->Flags
|= USBPORT_FLAG_INTERRUPT_ENABLED
;
569 Packet
->EnableInterrupts(FdoExtension
->MiniPortExt
);
573 Packet
->DisableInterrupts(FdoExtension
->MiniPortExt
);
574 FdoExtension
->Flags
&= ~USBPORT_FLAG_INTERRUPT_ENABLED
;
578 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
583 USBPORT_SoftInterruptDpc(IN PRKDPC Dpc
,
584 IN PVOID DeferredContext
,
585 IN PVOID SystemArgument1
,
586 IN PVOID SystemArgument2
)
588 PDEVICE_OBJECT FdoDevice
;
589 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
591 DPRINT_INT("USBPORT_SoftInterruptDpc: ... \n");
593 FdoDevice
= DeferredContext
;
594 FdoExtension
= FdoDevice
->DeviceExtension
;
596 if (!KeInsertQueueDpc(&FdoExtension
->IsrDpc
, NULL
, (PVOID
)1))
598 InterlockedDecrement(&FdoExtension
->IsrDpcCounter
);
604 USBPORT_SoftInterrupt(IN PDEVICE_OBJECT FdoDevice
)
606 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
607 LARGE_INTEGER DueTime
= {{0, 0}};
609 DPRINT_INT("USBPORT_SoftInterrupt: ... \n");
611 FdoExtension
= FdoDevice
->DeviceExtension
;
613 KeInitializeTimer(&FdoExtension
->TimerSoftInterrupt
);
615 KeInitializeDpc(&FdoExtension
->SoftInterruptDpc
,
616 USBPORT_SoftInterruptDpc
,
619 DueTime
.QuadPart
-= 10000 + (KeQueryTimeIncrement() - 1);
621 KeSetTimer(&FdoExtension
->TimerSoftInterrupt
,
623 &FdoExtension
->SoftInterruptDpc
);
628 USBPORT_InvalidateControllerHandler(IN PDEVICE_OBJECT FdoDevice
,
631 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
633 DPRINT("USBPORT_InvalidateControllerHandler: Invalidate Type - %x\n",
636 FdoExtension
= FdoDevice
->DeviceExtension
;
640 case USBPORT_INVALIDATE_CONTROLLER_RESET
:
641 DPRINT1("USBPORT_InvalidateControllerHandler: INVALIDATE_CONTROLLER_RESET UNIMPLEMENTED. FIXME. \n");
644 case USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE
:
645 DPRINT1("USBPORT_InvalidateControllerHandler: INVALIDATE_CONTROLLER_SURPRISE_REMOVE UNIMPLEMENTED. FIXME. \n");
648 case USBPORT_INVALIDATE_CONTROLLER_SOFT_INTERRUPT
:
649 if (InterlockedIncrement(&FdoExtension
->IsrDpcCounter
))
651 InterlockedDecrement(&FdoExtension
->IsrDpcCounter
);
655 USBPORT_SoftInterrupt(FdoDevice
);
663 USBPORT_InvalidateController(IN PVOID MiniPortExtension
,
666 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
667 PDEVICE_OBJECT FdoDevice
;
669 DPRINT("USBPORT_InvalidateController: Invalidate Type - %x\n", Type
);
671 //FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION));
672 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)MiniPortExtension
-
673 sizeof(USBPORT_DEVICE_EXTENSION
));
674 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
676 USBPORT_InvalidateControllerHandler(FdoDevice
, Type
);
683 USBPORT_NotifyDoubleBuffer(IN PVOID MiniPortExtension
,
684 IN PVOID MiniPortTransfer
,
688 DPRINT1("USBPORT_NotifyDoubleBuffer: UNIMPLEMENTED. FIXME. \n");
694 USBPORT_WorkerRequestDpc(IN PRKDPC Dpc
,
695 IN PVOID DeferredContext
,
696 IN PVOID SystemArgument1
,
697 IN PVOID SystemArgument2
)
699 PDEVICE_OBJECT FdoDevice
;
700 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
702 DPRINT("USBPORT_WorkerRequestDpc: ... \n");
704 FdoDevice
= DeferredContext
;
705 FdoExtension
= FdoDevice
->DeviceExtension
;
707 if (!InterlockedIncrement(&FdoExtension
->IsrDpcHandlerCounter
))
709 USBPORT_DpcHandler(FdoDevice
);
712 InterlockedDecrement(&FdoExtension
->IsrDpcHandlerCounter
);
717 USBPORT_DoneTransfer(IN PUSBPORT_TRANSFER Transfer
)
719 PUSBPORT_ENDPOINT Endpoint
;
720 PDEVICE_OBJECT FdoDevice
;
721 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
727 DPRINT_CORE("USBPORT_DoneTransfer: Transfer - %p\n", Transfer
);
729 Endpoint
= Transfer
->Endpoint
;
730 FdoDevice
= Endpoint
->FdoDevice
;
731 FdoExtension
= FdoDevice
->DeviceExtension
;
736 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
740 IoAcquireCancelSpinLock(&CancelIrql
);
741 IoSetCancelRoutine(Irp
, NULL
);
742 IoReleaseCancelSpinLock(CancelIrql
);
744 USBPORT_RemoveActiveTransferIrp(FdoDevice
, Irp
);
747 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
749 USBPORT_USBDStatusToNtStatus(Transfer
->Urb
, Transfer
->USBDStatus
);
750 USBPORT_CompleteTransfer(Urb
, Urb
->UrbHeader
.Status
);
752 DPRINT_CORE("USBPORT_DoneTransfer: exit\n");
757 USBPORT_FlushDoneTransfers(IN PDEVICE_OBJECT FdoDevice
)
759 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
760 PLIST_ENTRY DoneTransferList
;
761 PUSBPORT_TRANSFER Transfer
;
762 PUSBPORT_ENDPOINT Endpoint
;
765 BOOLEAN IsHasTransfers
;
767 DPRINT_CORE("USBPORT_FlushDoneTransfers: ... \n");
769 FdoExtension
= FdoDevice
->DeviceExtension
;
770 DoneTransferList
= &FdoExtension
->DoneTransferList
;
774 KeAcquireSpinLock(&FdoExtension
->DoneTransferSpinLock
, &OldIrql
);
776 if (IsListEmpty(DoneTransferList
))
779 Transfer
= CONTAINING_RECORD(DoneTransferList
->Flink
,
783 RemoveHeadList(DoneTransferList
);
784 KeReleaseSpinLock(&FdoExtension
->DoneTransferSpinLock
, OldIrql
);
788 Endpoint
= Transfer
->Endpoint
;
790 if ((Transfer
->Flags
& TRANSFER_FLAG_SPLITED
))
792 ASSERT(FALSE
);// USBPORT_DoneSplitTransfer(Transfer);
796 USBPORT_DoneTransfer(Transfer
);
799 IsHasTransfers
= USBPORT_EndpointHasQueuedTransfers(FdoDevice
,
803 if (IsHasTransfers
&& !TransferCount
)
805 USBPORT_InvalidateEndpointHandler(FdoDevice
,
807 INVALIDATE_ENDPOINT_WORKER_DPC
);
812 KeReleaseSpinLock(&FdoExtension
->DoneTransferSpinLock
, OldIrql
);
818 USBPORT_TransferFlushDpc(IN PRKDPC Dpc
,
819 IN PVOID DeferredContext
,
820 IN PVOID SystemArgument1
,
821 IN PVOID SystemArgument2
)
823 PDEVICE_OBJECT FdoDevice
;
825 DPRINT_CORE("USBPORT_TransferFlushDpc: ... \n");
826 FdoDevice
= DeferredContext
;
827 USBPORT_FlushDoneTransfers(FdoDevice
);
832 USBPORT_QueueDoneTransfer(IN PUSBPORT_TRANSFER Transfer
,
833 IN USBD_STATUS USBDStatus
)
835 PDEVICE_OBJECT FdoDevice
;
836 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
838 DPRINT_CORE("USBPORT_QueueDoneTransfer: Transfer - %p, USBDStatus - %p\n",
842 FdoDevice
= Transfer
->Endpoint
->FdoDevice
;
843 FdoExtension
= FdoDevice
->DeviceExtension
;
845 RemoveEntryList(&Transfer
->TransferLink
);
846 Transfer
->USBDStatus
= USBDStatus
;
848 ExInterlockedInsertTailList(&FdoExtension
->DoneTransferList
,
849 &Transfer
->TransferLink
,
850 &FdoExtension
->DoneTransferSpinLock
);
852 return KeInsertQueueDpc(&FdoExtension
->TransferFlushDpc
, NULL
, NULL
);
857 USBPORT_DpcHandler(IN PDEVICE_OBJECT FdoDevice
)
859 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
860 PUSBPORT_ENDPOINT Endpoint
;
865 DPRINT("USBPORT_DpcHandler: ... \n");
867 FdoExtension
= FdoDevice
->DeviceExtension
;
869 InitializeListHead(&List
);
871 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
872 Entry
= FdoExtension
->EndpointList
.Flink
;
874 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
876 Endpoint
= CONTAINING_RECORD(Entry
,
880 LockCounter
= InterlockedIncrement(&Endpoint
->LockCounter
);
882 if (USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_ACTIVE
||
884 Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
886 InterlockedDecrement(&Endpoint
->LockCounter
);
890 InsertTailList(&List
, &Endpoint
->DispatchLink
);
892 if (Endpoint
->WorkerLink
.Flink
&& Endpoint
->WorkerLink
.Blink
)
894 RemoveEntryList(&Endpoint
->WorkerLink
);
896 Endpoint
->WorkerLink
.Flink
= NULL
;
897 Endpoint
->WorkerLink
.Blink
= NULL
;
901 Entry
= Endpoint
->EndpointLink
.Flink
;
904 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
906 while (!IsListEmpty(&List
))
908 Endpoint
= CONTAINING_RECORD(List
.Flink
,
912 RemoveEntryList(List
.Flink
);
913 Endpoint
->DispatchLink
.Flink
= NULL
;
914 Endpoint
->DispatchLink
.Blink
= NULL
;
916 USBPORT_EndpointWorker(Endpoint
, TRUE
);
917 USBPORT_FlushPendingTransfers(Endpoint
);
920 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
922 if (!IsListEmpty(&FdoExtension
->WorkerList
))
924 USBPORT_SignalWorkerThread(FdoDevice
);
927 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
929 USBPORT_FlushDoneTransfers(FdoDevice
);
934 USBPORT_IsrDpcHandler(IN PDEVICE_OBJECT FdoDevice
,
935 IN BOOLEAN IsDpcHandler
)
937 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
938 PUSBPORT_REGISTRATION_PACKET Packet
;
939 PUSBPORT_ENDPOINT Endpoint
;
943 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
945 DPRINT_CORE("USBPORT_IsrDpcHandler: IsDpcHandler - %x\n", IsDpcHandler
);
947 FdoExtension
= FdoDevice
->DeviceExtension
;
948 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
950 if (InterlockedIncrement(&FdoExtension
->IsrDpcHandlerCounter
))
952 KeInsertQueueDpc(&FdoExtension
->IsrDpc
, NULL
, NULL
);
953 InterlockedDecrement(&FdoExtension
->IsrDpcHandlerCounter
);
957 for (List
= ExInterlockedRemoveHeadList(&FdoExtension
->EpStateChangeList
,
958 &FdoExtension
->EpStateChangeSpinLock
);
960 List
= ExInterlockedRemoveHeadList(&FdoExtension
->EpStateChangeList
,
961 &FdoExtension
->EpStateChangeSpinLock
))
963 Endpoint
= CONTAINING_RECORD(List
,
967 DPRINT_CORE("USBPORT_IsrDpcHandler: Endpoint - %p\n", Endpoint
);
969 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
971 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
972 FrameNumber
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
973 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
975 if (FrameNumber
<= Endpoint
->FrameNumber
&&
976 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
978 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
980 ExInterlockedInsertHeadList(&FdoExtension
->EpStateChangeList
,
981 &Endpoint
->StateChangeLink
,
982 &FdoExtension
->EpStateChangeSpinLock
);
984 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
985 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
986 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
991 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
993 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
994 Endpoint
->StateLast
= Endpoint
->StateNext
;
995 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
997 DPRINT_CORE("USBPORT_IsrDpcHandler: Endpoint->StateLast - %x\n",
998 Endpoint
->StateLast
);
1002 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1004 INVALIDATE_ENDPOINT_ONLY
);
1008 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1010 INVALIDATE_ENDPOINT_WORKER_THREAD
);
1016 USBPORT_DpcHandler(FdoDevice
);
1019 InterlockedDecrement(&FdoExtension
->IsrDpcHandlerCounter
);
1024 USBPORT_IsrDpc(IN PRKDPC Dpc
,
1025 IN PVOID DeferredContext
,
1026 IN PVOID SystemArgument1
,
1027 IN PVOID SystemArgument2
)
1029 PDEVICE_OBJECT FdoDevice
;
1030 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1031 PUSBPORT_REGISTRATION_PACKET Packet
;
1032 BOOLEAN InterruptEnable
;
1034 DPRINT_INT("USBPORT_IsrDpc: DeferredContext - %p, SystemArgument2 - %p\n",
1038 FdoDevice
= DeferredContext
;
1039 FdoExtension
= FdoDevice
->DeviceExtension
;
1040 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1042 if (SystemArgument2
)
1044 InterlockedDecrement(&FdoExtension
->IsrDpcCounter
);
1047 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportInterruptsSpinLock
);
1048 InterruptEnable
= (FdoExtension
->Flags
& USBPORT_FLAG_INTERRUPT_ENABLED
) ==
1049 USBPORT_FLAG_INTERRUPT_ENABLED
;
1051 Packet
->InterruptDpc(FdoExtension
->MiniPortExt
, InterruptEnable
);
1053 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportInterruptsSpinLock
);
1055 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
&&
1056 FdoExtension
->TimerFlags
& USBPORT_TMFLAG_WAKE
)
1058 USBPORT_CompletePdoWaitWake(FdoDevice
);
1062 USBPORT_IsrDpcHandler(FdoDevice
, TRUE
);
1065 DPRINT_INT("USBPORT_IsrDpc: exit\n");
1070 USBPORT_InterruptService(IN PKINTERRUPT Interrupt
,
1071 IN PVOID ServiceContext
)
1073 PDEVICE_OBJECT FdoDevice
;
1074 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1075 PUSBPORT_REGISTRATION_PACKET Packet
;
1076 BOOLEAN Result
= FALSE
;
1078 FdoDevice
= ServiceContext
;
1079 FdoExtension
= FdoDevice
->DeviceExtension
;
1080 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1082 DPRINT_INT("USBPORT_InterruptService: FdoExtension[%p]->Flags - %08X\n",
1084 FdoExtension
->Flags
);
1086 if (FdoExtension
->Flags
& USBPORT_FLAG_INTERRUPT_ENABLED
&&
1087 FdoExtension
->MiniPortFlags
& USBPORT_MPFLAG_INTERRUPTS_ENABLED
)
1089 Result
= Packet
->InterruptService(FdoExtension
->MiniPortExt
);
1093 KeInsertQueueDpc(&FdoExtension
->IsrDpc
, NULL
, NULL
);
1097 DPRINT_INT("USBPORT_InterruptService: return - %x\n", Result
);
1104 USBPORT_SignalWorkerThread(IN PDEVICE_OBJECT FdoDevice
)
1106 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1109 DPRINT_CORE("USBPORT_SignalWorkerThread ... \n");
1111 FdoExtension
= FdoDevice
->DeviceExtension
;
1113 KeAcquireSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, &OldIrql
);
1114 KeSetEvent(&FdoExtension
->WorkerThreadEvent
, EVENT_INCREMENT
, FALSE
);
1115 KeReleaseSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, OldIrql
);
1120 USBPORT_WorkerThreadHandler(IN PDEVICE_OBJECT FdoDevice
)
1122 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1123 PUSBPORT_REGISTRATION_PACKET Packet
;
1124 PLIST_ENTRY workerList
;
1126 PUSBPORT_ENDPOINT Endpoint
;
1130 DPRINT_CORE("USBPORT_WorkerThreadHandler: ... \n");
1132 FdoExtension
= FdoDevice
->DeviceExtension
;
1133 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1135 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1137 if (!(FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
))
1139 Packet
->CheckController(FdoExtension
->MiniPortExt
);
1142 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1144 InitializeListHead(&list
);
1146 USBPORT_FlushAllEndpoints(FdoDevice
);
1150 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1151 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1153 workerList
= &FdoExtension
->WorkerList
;
1155 if (IsListEmpty(workerList
))
1158 Endpoint
= CONTAINING_RECORD(workerList
->Flink
,
1162 DPRINT_CORE("USBPORT_WorkerThreadHandler: Endpoint - %p\n", Endpoint
);
1164 RemoveHeadList(workerList
);
1165 Endpoint
->WorkerLink
.Blink
= NULL
;
1166 Endpoint
->WorkerLink
.Flink
= NULL
;
1168 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1170 Result
= USBPORT_EndpointWorker(Endpoint
, FALSE
);
1171 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1175 if (Endpoint
->FlushAbortLink
.Flink
== NULL
||
1176 Endpoint
->FlushAbortLink
.Blink
== NULL
)
1178 InsertTailList(&list
, &Endpoint
->FlushAbortLink
);
1182 while (!IsListEmpty(&list
))
1184 Endpoint
= CONTAINING_RECORD(list
.Flink
,
1188 RemoveHeadList(&list
);
1190 Endpoint
->FlushAbortLink
.Flink
= NULL
;
1191 Endpoint
->FlushAbortLink
.Blink
= NULL
;
1193 if (Endpoint
->WorkerLink
.Flink
== NULL
||
1194 Endpoint
->WorkerLink
.Blink
== NULL
)
1196 InsertTailList(&FdoExtension
->WorkerList
,
1197 &Endpoint
->WorkerLink
);
1199 USBPORT_SignalWorkerThread(FdoDevice
);
1203 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1204 KeLowerIrql(OldIrql
);
1207 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1208 KeLowerIrql(OldIrql
);
1210 USBPORT_FlushClosedEndpointList(FdoDevice
);
1215 USBPORT_DoRootHubCallback(IN PDEVICE_OBJECT FdoDevice
)
1217 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1218 PDEVICE_OBJECT PdoDevice
;
1219 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1220 PRH_INIT_CALLBACK RootHubInitCallback
;
1221 PVOID RootHubInitContext
;
1223 FdoExtension
= FdoDevice
->DeviceExtension
;
1225 DPRINT("USBPORT_DoRootHubCallback: FdoDevice - %p\n", FdoDevice
);
1227 PdoDevice
= FdoExtension
->RootHubPdo
;
1231 PdoExtension
= PdoDevice
->DeviceExtension
;
1233 RootHubInitContext
= PdoExtension
->RootHubInitContext
;
1234 RootHubInitCallback
= PdoExtension
->RootHubInitCallback
;
1236 PdoExtension
->RootHubInitCallback
= NULL
;
1237 PdoExtension
->RootHubInitContext
= NULL
;
1239 if (RootHubInitCallback
)
1241 RootHubInitCallback(RootHubInitContext
);
1245 DPRINT("USBPORT_DoRootHubCallback: exit\n");
1250 USBPORT_SynchronizeRootHubCallback(IN PDEVICE_OBJECT FdoDevice
,
1251 IN PDEVICE_OBJECT Usb2FdoDevice
)
1253 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1254 PUSBPORT_REGISTRATION_PACKET Packet
;
1255 PUSBPORT_DEVICE_EXTENSION Usb2FdoExtension
;
1256 PDEVICE_RELATIONS CompanionControllersList
;
1257 PUSBPORT_DEVICE_EXTENSION CompanionFdoExtension
;
1258 PDEVICE_OBJECT
* Entry
;
1261 DPRINT("USBPORT_SynchronizeRootHubCallback: FdoDevice - %p, Usb2FdoDevice - %p\n",
1265 FdoExtension
= FdoDevice
->DeviceExtension
;
1266 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1268 if (Usb2FdoDevice
== NULL
&&
1269 !(Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
))
1271 /* Not Companion USB11 Controller */
1272 USBPORT_DoRootHubCallback(FdoDevice
);
1274 FdoExtension
->Flags
&= ~USBPORT_FLAG_RH_INIT_CALLBACK
;
1275 InterlockedCompareExchange(&FdoExtension
->RHInitCallBackLock
, 0, 1);
1277 DPRINT("USBPORT_SynchronizeRootHubCallback: exit \n");
1281 /* USB2 or Companion USB11 */
1283 DPRINT("USBPORT_SynchronizeRootHubCallback: FdoExtension->Flags - %p\n",
1284 FdoExtension
->Flags
);
1286 if (!(FdoExtension
->Flags
& USBPORT_FLAG_COMPANION_HC
))
1288 KeWaitForSingleObject(&FdoExtension
->ControllerSemaphore
,
1294 FdoExtension
->Flags
|= USBPORT_FLAG_PWR_AND_CHIRP_LOCK
;
1296 if (!(FdoExtension
->Flags
& (USBPORT_FLAG_HC_SUSPEND
|
1297 USBPORT_FLAG_POWER_AND_CHIRP_OK
)))
1299 USBPORT_RootHubPowerAndChirpAllCcPorts(FdoDevice
);
1300 FdoExtension
->Flags
|= USBPORT_FLAG_POWER_AND_CHIRP_OK
;
1303 FdoExtension
->Flags
&= ~USBPORT_FLAG_PWR_AND_CHIRP_LOCK
;
1305 KeReleaseSemaphore(&FdoExtension
->ControllerSemaphore
,
1306 LOW_REALTIME_PRIORITY
,
1310 CompanionControllersList
= USBPORT_FindCompanionControllers(FdoDevice
,
1314 if (CompanionControllersList
)
1316 Entry
= &CompanionControllersList
->Objects
[0];
1318 for (ix
= 0; ix
< CompanionControllersList
->Count
; ++ix
)
1320 CompanionFdoExtension
= ((*Entry
)->DeviceExtension
);
1322 InterlockedCompareExchange(&CompanionFdoExtension
->RHInitCallBackLock
,
1329 ExFreePoolWithTag(CompanionControllersList
, USB_PORT_TAG
);
1332 USBPORT_DoRootHubCallback(FdoDevice
);
1334 FdoExtension
->Flags
&= ~USBPORT_FLAG_RH_INIT_CALLBACK
;
1335 InterlockedCompareExchange(&FdoExtension
->RHInitCallBackLock
, 0, 1);
1339 Usb2FdoExtension
= Usb2FdoDevice
->DeviceExtension
;
1341 USBPORT_Wait(FdoDevice
, 50);
1343 while (FdoExtension
->RHInitCallBackLock
)
1345 USBPORT_Wait(FdoDevice
, 10);
1347 Usb2FdoExtension
->Flags
|= USBPORT_FLAG_RH_INIT_CALLBACK
;
1348 USBPORT_SignalWorkerThread(Usb2FdoDevice
);
1351 USBPORT_DoRootHubCallback(FdoDevice
);
1353 FdoExtension
->Flags
&= ~USBPORT_FLAG_RH_INIT_CALLBACK
;
1356 DPRINT("USBPORT_SynchronizeRootHubCallback: exit \n");
1361 USBPORT_WorkerThread(IN PVOID StartContext
)
1363 PDEVICE_OBJECT FdoDevice
;
1364 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1365 LARGE_INTEGER OldTime
;
1366 LARGE_INTEGER NewTime
;
1369 DPRINT_CORE("USBPORT_WorkerThread ... \n");
1371 FdoDevice
= StartContext
;
1372 FdoExtension
= FdoDevice
->DeviceExtension
;
1374 FdoExtension
->WorkerThread
= KeGetCurrentThread();
1378 KeQuerySystemTime(&OldTime
);
1380 KeWaitForSingleObject(&FdoExtension
->WorkerThreadEvent
,
1386 KeQuerySystemTime(&NewTime
);
1388 KeAcquireSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, &OldIrql
);
1389 KeResetEvent(&FdoExtension
->WorkerThreadEvent
);
1390 KeReleaseSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, OldIrql
);
1391 DPRINT_CORE("USBPORT_WorkerThread: run \n");
1393 if (FdoExtension
->MiniPortFlags
& USBPORT_MPFLAG_INTERRUPTS_ENABLED
)
1395 USBPORT_DoSetPowerD0(FdoDevice
);
1397 if (FdoExtension
->Flags
& USBPORT_FLAG_RH_INIT_CALLBACK
)
1399 PDEVICE_OBJECT USB2FdoDevice
= NULL
;
1401 USB2FdoDevice
= USBPORT_FindUSB2Controller(FdoDevice
);
1402 USBPORT_SynchronizeRootHubCallback(FdoDevice
, USB2FdoDevice
);
1406 USBPORT_WorkerThreadHandler(FdoDevice
);
1408 while (!(FdoExtension
->Flags
& USBPORT_FLAG_WORKER_THREAD_ON
));
1410 PsTerminateSystemThread(0);
1415 USBPORT_CreateWorkerThread(IN PDEVICE_OBJECT FdoDevice
)
1417 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1420 DPRINT("USBPORT_CreateWorkerThread ... \n");
1422 FdoExtension
= FdoDevice
->DeviceExtension
;
1424 FdoExtension
->Flags
&= ~USBPORT_FLAG_WORKER_THREAD_ON
;
1426 KeInitializeEvent(&FdoExtension
->WorkerThreadEvent
,
1430 Status
= PsCreateSystemThread(&FdoExtension
->WorkerThreadHandle
,
1435 USBPORT_WorkerThread
,
1443 USBPORT_SynchronizeControllersStart(IN PDEVICE_OBJECT FdoDevice
)
1445 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1446 PDEVICE_OBJECT PdoDevice
;
1447 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1448 PDEVICE_OBJECT USB2FdoDevice
= NULL
;
1449 PUSBPORT_DEVICE_EXTENSION USB2FdoExtension
;
1452 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: FdoDevice - %p\n",
1455 FdoExtension
= FdoDevice
->DeviceExtension
;
1457 PdoDevice
= FdoExtension
->RootHubPdo
;
1464 PdoExtension
= PdoDevice
->DeviceExtension
;
1466 if (PdoExtension
->RootHubInitCallback
== NULL
||
1467 FdoExtension
->Flags
& USBPORT_FLAG_RH_INIT_CALLBACK
)
1472 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: Flags - %p\n",
1473 FdoExtension
->Flags
);
1475 if (FdoExtension
->Flags
& USBPORT_FLAG_COMPANION_HC
)
1479 USB2FdoDevice
= USBPORT_FindUSB2Controller(FdoDevice
);
1481 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: USB2FdoDevice - %p\n",
1486 USB2FdoExtension
= USB2FdoDevice
->DeviceExtension
;
1488 if (USB2FdoExtension
->CommonExtension
.PnpStateFlags
&
1489 USBPORT_PNP_STATE_STARTED
)
1495 if (!(FdoExtension
->Flags
& USBPORT_FLAG_NO_HACTION
))
1500 USB2FdoDevice
= NULL
;
1508 !InterlockedCompareExchange(&FdoExtension
->RHInitCallBackLock
, 1, 0))
1510 FdoExtension
->Flags
|= USBPORT_FLAG_RH_INIT_CALLBACK
;
1511 USBPORT_SignalWorkerThread(FdoDevice
);
1515 USB2FdoExtension
= USB2FdoDevice
->DeviceExtension
;
1517 USB2FdoExtension
->Flags
|= USBPORT_FLAG_RH_INIT_CALLBACK
;
1518 USBPORT_SignalWorkerThread(USB2FdoDevice
);
1522 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: exit\n");
1527 USBPORT_TimerDpc(IN PRKDPC Dpc
,
1528 IN PVOID DeferredContext
,
1529 IN PVOID SystemArgument1
,
1530 IN PVOID SystemArgument2
)
1532 PDEVICE_OBJECT FdoDevice
;
1533 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1534 PUSBPORT_REGISTRATION_PACKET Packet
;
1535 LARGE_INTEGER DueTime
= {{0, 0}};
1537 PTIMER_WORK_QUEUE_ITEM IdleQueueItem
;
1541 DPRINT_TIMER("USBPORT_TimerDpc: Dpc - %p, DeferredContext - %p\n",
1545 FdoDevice
= DeferredContext
;
1546 FdoExtension
= FdoDevice
->DeviceExtension
;
1547 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1549 KeAcquireSpinLock(&FdoExtension
->TimerFlagsSpinLock
, &TimerOldIrql
);
1551 TimerFlags
= FdoExtension
->TimerFlags
;
1553 DPRINT_TIMER("USBPORT_TimerDpc: Flags - %p, TimerFlags - %p\n",
1554 FdoExtension
->Flags
,
1557 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
&&
1558 FdoExtension
->Flags
& USBPORT_FLAG_HC_WAKE_SUPPORT
&&
1559 !(TimerFlags
& USBPORT_TMFLAG_HC_RESUME
))
1561 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1562 Packet
->PollController(FdoExtension
->MiniPortExt
);
1563 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1566 USBPORT_SynchronizeControllersStart(FdoDevice
);
1568 if (TimerFlags
& USBPORT_TMFLAG_HC_SUSPENDED
)
1570 USBPORT_BadRequestFlush(FdoDevice
);
1574 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1576 if (!(FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
))
1578 Packet
->CheckController(FdoExtension
->MiniPortExt
);
1581 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1583 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_POLLING
)
1585 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1586 Packet
->PollController(FdoExtension
->MiniPortExt
);
1587 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1590 USBPORT_IsrDpcHandler(FdoDevice
, FALSE
);
1592 DPRINT_TIMER("USBPORT_TimerDpc: USBPORT_TimeoutAllEndpoints UNIMPLEMENTED.\n");
1593 //USBPORT_TimeoutAllEndpoints(FdoDevice);
1594 DPRINT_TIMER("USBPORT_TimerDpc: USBPORT_CheckIdleEndpoints UNIMPLEMENTED.\n");
1595 //USBPORT_CheckIdleEndpoints(FdoDevice);
1597 USBPORT_BadRequestFlush(FdoDevice
);
1599 if (FdoExtension
->IdleLockCounter
> -1 &&
1600 !(TimerFlags
& USBPORT_TMFLAG_IDLE_QUEUEITEM_ON
))
1602 IdleQueueItem
= ExAllocatePoolWithTag(NonPagedPool
,
1603 sizeof(TIMER_WORK_QUEUE_ITEM
),
1606 DPRINT("USBPORT_TimerDpc: IdleLockCounter - %x, IdleQueueItem - %p\n",
1607 FdoExtension
->IdleLockCounter
,
1612 RtlZeroMemory(IdleQueueItem
, sizeof(TIMER_WORK_QUEUE_ITEM
));
1614 IdleQueueItem
->WqItem
.List
.Flink
= NULL
;
1615 IdleQueueItem
->WqItem
.WorkerRoutine
= USBPORT_DoIdleNotificationCallback
;
1616 IdleQueueItem
->WqItem
.Parameter
= IdleQueueItem
;
1618 IdleQueueItem
->FdoDevice
= FdoDevice
;
1619 IdleQueueItem
->Context
= 0;
1621 FdoExtension
->TimerFlags
|= USBPORT_TMFLAG_IDLE_QUEUEITEM_ON
;
1623 ExQueueWorkItem(&IdleQueueItem
->WqItem
, CriticalWorkQueue
);
1629 KeReleaseSpinLock(&FdoExtension
->TimerFlagsSpinLock
, TimerOldIrql
);
1631 if (TimerFlags
& USBPORT_TMFLAG_TIMER_QUEUED
)
1633 DueTime
.QuadPart
-= FdoExtension
->TimerValue
* 10000 +
1634 (KeQueryTimeIncrement() - 1);
1636 KeSetTimer(&FdoExtension
->TimerObject
,
1638 &FdoExtension
->TimerDpc
);
1641 DPRINT_TIMER("USBPORT_TimerDpc: exit\n");
1646 USBPORT_StartTimer(IN PDEVICE_OBJECT FdoDevice
,
1649 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1650 LARGE_INTEGER DueTime
= {{0, 0}};
1651 ULONG TimeIncrement
;
1654 DPRINT_TIMER("USBPORT_StartTimer: FdoDevice - %p, Time - %x\n",
1658 FdoExtension
= FdoDevice
->DeviceExtension
;
1660 TimeIncrement
= KeQueryTimeIncrement();
1662 FdoExtension
->TimerFlags
|= USBPORT_TMFLAG_TIMER_QUEUED
;
1663 FdoExtension
->TimerValue
= Time
;
1665 KeInitializeTimer(&FdoExtension
->TimerObject
);
1666 KeInitializeDpc(&FdoExtension
->TimerDpc
, USBPORT_TimerDpc
, FdoDevice
);
1668 DueTime
.QuadPart
-= 10000 * Time
+ (TimeIncrement
- 1);
1670 Result
= KeSetTimer(&FdoExtension
->TimerObject
,
1672 &FdoExtension
->TimerDpc
);
1677 PUSBPORT_COMMON_BUFFER_HEADER
1679 USBPORT_AllocateCommonBuffer(IN PDEVICE_OBJECT FdoDevice
,
1680 IN SIZE_T BufferLength
)
1682 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
= NULL
;
1683 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1684 PDMA_ADAPTER DmaAdapter
;
1685 PDMA_OPERATIONS DmaOperations
;
1689 PHYSICAL_ADDRESS LogicalAddress
;
1691 ULONG_PTR StartBufferVA
;
1692 ULONG_PTR StartBufferPA
;
1694 DPRINT("USBPORT_AllocateCommonBuffer: FdoDevice - %p, BufferLength - %p\n",
1698 if (BufferLength
== 0)
1701 FdoExtension
= FdoDevice
->DeviceExtension
;
1703 DmaAdapter
= FdoExtension
->DmaAdapter
;
1704 DmaOperations
= DmaAdapter
->DmaOperations
;
1706 HeaderSize
= sizeof(USBPORT_COMMON_BUFFER_HEADER
);
1707 Length
= ROUND_TO_PAGES(BufferLength
+ HeaderSize
);
1708 LengthPadded
= Length
- (BufferLength
+ HeaderSize
);
1710 BaseVA
= (ULONG_PTR
)DmaOperations
->AllocateCommonBuffer(DmaAdapter
,
1718 StartBufferVA
= BaseVA
& ~(PAGE_SIZE
- 1);
1719 StartBufferPA
= LogicalAddress
.LowPart
& ~(PAGE_SIZE
- 1);
1721 HeaderBuffer
= (PUSBPORT_COMMON_BUFFER_HEADER
)(StartBufferVA
+
1725 HeaderBuffer
->Length
= Length
;
1726 HeaderBuffer
->BaseVA
= BaseVA
;
1727 HeaderBuffer
->LogicalAddress
= LogicalAddress
;
1729 HeaderBuffer
->BufferLength
= BufferLength
+ LengthPadded
;
1730 HeaderBuffer
->VirtualAddress
= StartBufferVA
;
1731 HeaderBuffer
->PhysicalAddress
= StartBufferPA
;
1733 RtlZeroMemory((PVOID
)StartBufferVA
, BufferLength
+ LengthPadded
);
1736 return HeaderBuffer
;
1741 USBPORT_FreeCommonBuffer(IN PDEVICE_OBJECT FdoDevice
,
1742 IN PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
)
1744 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1745 PDMA_ADAPTER DmaAdapter
;
1746 PDMA_OPERATIONS DmaOperations
;
1748 DPRINT("USBPORT_FreeCommonBuffer: ... \n");
1750 FdoExtension
= FdoDevice
->DeviceExtension
;
1752 DmaAdapter
= FdoExtension
->DmaAdapter
;
1753 DmaOperations
= DmaAdapter
->DmaOperations
;
1755 DmaOperations
->FreeCommonBuffer(FdoExtension
->DmaAdapter
,
1756 HeaderBuffer
->Length
,
1757 HeaderBuffer
->LogicalAddress
,
1758 (PVOID
)HeaderBuffer
->VirtualAddress
,
1762 PUSBPORT_MINIPORT_INTERFACE
1764 USBPORT_FindMiniPort(IN PDRIVER_OBJECT DriverObject
)
1768 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
1769 BOOLEAN IsFound
= FALSE
;
1771 DPRINT("USBPORT_FindMiniPort: ... \n");
1773 KeAcquireSpinLock(&USBPORT_SpinLock
, &OldIrql
);
1775 for (List
= USBPORT_MiniPortDrivers
.Flink
;
1776 List
!= &USBPORT_MiniPortDrivers
;
1779 MiniPortInterface
= CONTAINING_RECORD(List
,
1780 USBPORT_MINIPORT_INTERFACE
,
1783 if (MiniPortInterface
->DriverObject
== DriverObject
)
1785 DPRINT("USBPORT_FindMiniPort: find MiniPortInterface - %p\n",
1793 KeReleaseSpinLock(&USBPORT_SpinLock
, OldIrql
);
1796 return MiniPortInterface
;
1804 USBPORT_AddDevice(IN PDRIVER_OBJECT DriverObject
,
1805 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1808 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
1809 ULONG DeviceNumber
= 0;
1810 WCHAR CharDeviceName
[64];
1811 UNICODE_STRING DeviceName
;
1812 PDEVICE_OBJECT DeviceObject
;
1813 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1814 PUSBPORT_COMMON_DEVICE_EXTENSION FdoCommonExtension
;
1815 PDEVICE_OBJECT LowerDevice
;
1818 DPRINT("USBPORT_AddDevice: DriverObject - %p, PhysicalDeviceObject - %p\n",
1820 PhysicalDeviceObject
);
1822 MiniPortInterface
= USBPORT_FindMiniPort(DriverObject
);
1824 if (!MiniPortInterface
)
1826 DPRINT("USBPORT_AddDevice: USBPORT_FindMiniPort not found MiniPortInterface\n");
1827 return STATUS_UNSUCCESSFUL
;
1832 /* Construct device name */
1833 RtlStringCbPrintfW(CharDeviceName
,
1834 sizeof(CharDeviceName
),
1835 L
"\\Device\\USBFDO-%d",
1838 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
1840 Length
= sizeof(USBPORT_DEVICE_EXTENSION
) +
1841 MiniPortInterface
->Packet
.MiniPortExtensionSize
;
1844 Status
= IoCreateDevice(DriverObject
,
1847 FILE_DEVICE_CONTROLLER
,
1852 /* Check for success */
1853 if (NT_SUCCESS(Status
)) break;
1855 /* Is there a device object with that same name */
1856 if ((Status
== STATUS_OBJECT_NAME_EXISTS
) ||
1857 (Status
== STATUS_OBJECT_NAME_COLLISION
))
1859 /* Try the next name */
1864 /* Bail out on other errors */
1865 if (!NT_SUCCESS(Status
))
1867 DPRINT1("USBPORT_AddDevice: failed to create %wZ, Status %x\n",
1875 DPRINT("USBPORT_AddDevice: created device %p <%wZ>, Status %x\n",
1880 FdoExtension
= DeviceObject
->DeviceExtension
;
1881 FdoCommonExtension
= &FdoExtension
->CommonExtension
;
1883 RtlZeroMemory(FdoExtension
, sizeof(USBPORT_DEVICE_EXTENSION
));
1885 FdoCommonExtension
->SelfDevice
= DeviceObject
;
1886 FdoCommonExtension
->LowerPdoDevice
= PhysicalDeviceObject
;
1887 FdoCommonExtension
->IsPDO
= FALSE
;
1889 LowerDevice
= IoAttachDeviceToDeviceStack(DeviceObject
,
1890 PhysicalDeviceObject
);
1892 FdoCommonExtension
->LowerDevice
= LowerDevice
;
1894 FdoCommonExtension
->DevicePowerState
= PowerDeviceD3
;
1896 FdoExtension
->MiniPortExt
= (PVOID
)((ULONG_PTR
)FdoExtension
+
1897 sizeof(USBPORT_DEVICE_EXTENSION
));
1899 FdoExtension
->MiniPortInterface
= MiniPortInterface
;
1900 FdoExtension
->FdoNameNumber
= DeviceNumber
;
1902 KeInitializeSemaphore(&FdoExtension
->DeviceSemaphore
, 1, 1);
1903 KeInitializeSemaphore(&FdoExtension
->ControllerSemaphore
, 1, 1);
1905 InitializeListHead(&FdoExtension
->EndpointList
);
1906 InitializeListHead(&FdoExtension
->DoneTransferList
);
1907 InitializeListHead(&FdoExtension
->WorkerList
);
1908 InitializeListHead(&FdoExtension
->EpStateChangeList
);
1909 InitializeListHead(&FdoExtension
->MapTransferList
);
1910 InitializeListHead(&FdoExtension
->DeviceHandleList
);
1911 InitializeListHead(&FdoExtension
->IdleIrpList
);
1912 InitializeListHead(&FdoExtension
->BadRequestList
);
1913 InitializeListHead(&FdoExtension
->EndpointClosedList
);
1915 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1922 USBPORT_Unload(IN PDRIVER_OBJECT DriverObject
)
1924 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
1926 DPRINT1("USBPORT_Unload: FIXME!\n");
1928 MiniPortInterface
= USBPORT_FindMiniPort(DriverObject
);
1930 if (!MiniPortInterface
)
1932 DPRINT("USBPORT_Unload: CRITICAL ERROR!!! USBPORT_FindMiniPort not found MiniPortInterface\n");
1933 KeBugCheckEx(BUGCODE_USB_DRIVER
, 1, 0, 0, 0);
1936 DPRINT1("USBPORT_Unload: UNIMPLEMENTED. FIXME. \n");
1937 //MiniPortInterface->DriverUnload(DriverObject); // Call MiniPort _HCI_Unload
1942 USBPORT_MiniportCompleteTransfer(IN PVOID MiniPortExtension
,
1943 IN PVOID MiniPortEndpoint
,
1944 IN PVOID TransferParameters
,
1945 IN USBD_STATUS USBDStatus
,
1946 IN ULONG TransferLength
)
1948 PUSBPORT_TRANSFER Transfer
;
1949 PDEVICE_OBJECT FdoDevice
;
1950 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1952 DPRINT_CORE("USBPORT_MiniportCompleteTransfer: USBDStatus - %x, TransferLength - %x\n",
1956 Transfer
= CONTAINING_RECORD(TransferParameters
,
1958 TransferParameters
);
1960 FdoDevice
= Transfer
->Endpoint
->FdoDevice
;
1961 FdoExtension
= FdoDevice
->DeviceExtension
;
1963 Transfer
->CompletedTransferLen
= TransferLength
;
1965 RemoveEntryList(&Transfer
->TransferLink
);
1967 Transfer
->USBDStatus
= USBDStatus
;
1969 ExInterlockedInsertTailList(&FdoExtension
->DoneTransferList
,
1970 &Transfer
->TransferLink
,
1971 &FdoExtension
->DoneTransferSpinLock
);
1973 KeInsertQueueDpc(&FdoExtension
->TransferFlushDpc
, NULL
, NULL
);
1978 USBPORT_AsyncTimerDpc(IN PRKDPC Dpc
,
1979 IN PVOID DeferredContext
,
1980 IN PVOID SystemArgument1
,
1981 IN PVOID SystemArgument2
)
1983 PDEVICE_OBJECT FdoDevice
;
1984 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1985 PUSBPORT_ASYNC_CALLBACK_DATA AsyncCallbackData
;
1987 DPRINT("USBPORT_AsyncTimerDpc: ... \n");
1989 AsyncCallbackData
= DeferredContext
;
1990 FdoDevice
= AsyncCallbackData
->FdoDevice
;
1991 FdoExtension
= FdoDevice
->DeviceExtension
;
1993 (*AsyncCallbackData
->CallbackFunction
)(FdoExtension
->MiniPortExt
,
1994 &AsyncCallbackData
->CallbackContext
);
1996 ExFreePoolWithTag(AsyncCallbackData
, USB_PORT_TAG
);
2001 USBPORT_RequestAsyncCallback(IN PVOID MiniPortExtension
,
2002 IN ULONG TimerValue
,
2005 IN ASYNC_TIMER_CALLBACK
* Callback
)
2007 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2008 PDEVICE_OBJECT FdoDevice
;
2009 PUSBPORT_ASYNC_CALLBACK_DATA AsyncCallbackData
;
2010 LARGE_INTEGER DueTime
= {{0, 0}};
2012 DPRINT("USBPORT_RequestAsyncCallback: ... \n");
2014 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)MiniPortExtension
-
2015 sizeof(USBPORT_DEVICE_EXTENSION
));
2017 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
2019 AsyncCallbackData
= ExAllocatePoolWithTag(NonPagedPool
,
2020 sizeof(USBPORT_ASYNC_CALLBACK_DATA
) + Length
,
2023 if (!AsyncCallbackData
)
2025 DPRINT1("USBPORT_RequestAsyncCallback: Not allocated AsyncCallbackData!\n");
2029 RtlZeroMemory(AsyncCallbackData
,
2030 sizeof(USBPORT_ASYNC_CALLBACK_DATA
) + Length
);
2034 RtlCopyMemory(&AsyncCallbackData
->CallbackContext
, Buffer
, Length
);
2037 AsyncCallbackData
->FdoDevice
= FdoDevice
;
2038 AsyncCallbackData
->CallbackFunction
= Callback
;
2040 KeInitializeTimer(&AsyncCallbackData
->AsyncTimer
);
2042 KeInitializeDpc(&AsyncCallbackData
->AsyncTimerDpc
,
2043 USBPORT_AsyncTimerDpc
,
2046 DueTime
.QuadPart
-= (KeQueryTimeIncrement() - 1) + 10000 * TimerValue
;
2048 KeSetTimer(&AsyncCallbackData
->AsyncTimer
,
2050 &AsyncCallbackData
->AsyncTimerDpc
);
2057 USBPORT_GetMappedVirtualAddress(IN PVOID PhysicalAddress
,
2058 IN PVOID MiniPortExtension
,
2059 IN PVOID MiniPortEndpoint
)
2061 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
2062 PUSBPORT_ENDPOINT Endpoint
;
2064 ULONG_PTR VirtualAddress
;
2066 DPRINT_CORE("USBPORT_GetMappedVirtualAddress ... \n");
2068 Endpoint
= (PUSBPORT_ENDPOINT
)((ULONG_PTR
)MiniPortEndpoint
-
2069 sizeof(USBPORT_ENDPOINT
));
2076 HeaderBuffer
= Endpoint
->HeaderBuffer
;
2078 Offset
= (ULONG_PTR
)PhysicalAddress
- HeaderBuffer
->PhysicalAddress
;
2079 VirtualAddress
= HeaderBuffer
->VirtualAddress
+ Offset
;
2081 return (PVOID
)VirtualAddress
;
2086 USBPORT_InvalidateEndpoint(IN PVOID MiniPortExtension
,
2087 IN PVOID MiniPortEndpoint
)
2089 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2090 PDEVICE_OBJECT FdoDevice
;
2091 PUSBPORT_ENDPOINT Endpoint
;
2093 DPRINT_CORE("USBPORT_InvalidateEndpoint: ... \n");
2095 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)MiniPortExtension
-
2096 sizeof(USBPORT_DEVICE_EXTENSION
));
2098 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
2100 if (!MiniPortEndpoint
)
2102 USBPORT_InvalidateEndpointHandler(FdoDevice
,
2104 INVALIDATE_ENDPOINT_ONLY
);
2108 Endpoint
= (PUSBPORT_ENDPOINT
)((ULONG_PTR
)MiniPortEndpoint
-
2109 sizeof(USBPORT_ENDPOINT
));
2111 USBPORT_InvalidateEndpointHandler(FdoDevice
,
2113 INVALIDATE_ENDPOINT_ONLY
);
2120 USBPORT_CompleteTransfer(IN PURB Urb
,
2121 IN USBD_STATUS TransferStatus
)
2123 struct _URB_CONTROL_TRANSFER
*UrbTransfer
;
2124 PUSBPORT_TRANSFER Transfer
;
2129 BOOLEAN WriteToDevice
;
2130 BOOLEAN IsFlushSuccess
;
2132 ULONG_PTR CurrentVa
;
2133 SIZE_T TransferLength
;
2134 PUSBPORT_ENDPOINT Endpoint
;
2135 PDEVICE_OBJECT FdoDevice
;
2136 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2137 PDMA_OPERATIONS DmaOperations
;
2139 DPRINT("USBPORT_CompleteTransfer: Urb - %p, TransferStatus - %X\n",
2143 UrbTransfer
= &Urb
->UrbControlTransfer
;
2144 Transfer
= UrbTransfer
->hca
.Reserved8
[0];
2146 Transfer
->USBDStatus
= TransferStatus
;
2147 Status
= USBPORT_USBDStatusToNtStatus(Urb
, TransferStatus
);
2149 UrbTransfer
->TransferBufferLength
= Transfer
->CompletedTransferLen
;
2151 if (Transfer
->Flags
& TRANSFER_FLAG_DMA_MAPPED
)
2153 Endpoint
= Transfer
->Endpoint
;
2154 FdoDevice
= Endpoint
->FdoDevice
;
2155 FdoExtension
= FdoDevice
->DeviceExtension
;
2156 DmaOperations
= FdoExtension
->DmaAdapter
->DmaOperations
;
2158 WriteToDevice
= Transfer
->Direction
== USBPORT_DMA_DIRECTION_TO_DEVICE
;
2159 Mdl
= UrbTransfer
->TransferBufferMDL
;
2160 CurrentVa
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2161 TransferLength
= UrbTransfer
->TransferBufferLength
;
2163 IsFlushSuccess
= DmaOperations
->FlushAdapterBuffers(FdoExtension
->DmaAdapter
,
2165 Transfer
->MapRegisterBase
,
2170 if (!IsFlushSuccess
)
2172 DPRINT("USBPORT_CompleteTransfer: no FlushAdapterBuffers !!!\n");
2176 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
2178 DmaOperations
->FreeMapRegisters(FdoExtension
->DmaAdapter
,
2179 Transfer
->MapRegisterBase
,
2180 Transfer
->NumberOfMapRegisters
);
2182 KeLowerIrql(OldIrql
);
2185 if (Urb
->UrbHeader
.UsbdFlags
& USBD_FLAG_ALLOCATED_MDL
)
2187 IoFreeMdl(Transfer
->TransferBufferMDL
);
2188 Urb
->UrbHeader
.UsbdFlags
|= ~USBD_FLAG_ALLOCATED_MDL
;
2191 Urb
->UrbControlTransfer
.hca
.Reserved8
[0] = NULL
;
2192 Urb
->UrbHeader
.UsbdFlags
|= ~USBD_FLAG_ALLOCATED_TRANSFER
;
2194 Irp
= Transfer
->Irp
;
2198 if (!NT_SUCCESS(Status
))
2201 DPRINT1("USBPORT_CompleteTransfer: Irp - %p complete with Status - %lx\n",
2205 USBPORT_DumpingURB(Urb
);
2208 Irp
->IoStatus
.Status
= Status
;
2209 Irp
->IoStatus
.Information
= 0;
2211 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
2212 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2213 KeLowerIrql(OldIrql
);
2216 Event
= Transfer
->Event
;
2220 KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
2223 ExFreePoolWithTag(Transfer
, USB_PORT_TAG
);
2225 DPRINT_CORE("USBPORT_CompleteTransfer: exit\n");
2228 IO_ALLOCATION_ACTION
2230 USBPORT_MapTransfer(IN PDEVICE_OBJECT FdoDevice
,
2232 IN PVOID MapRegisterBase
,
2235 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2236 PDMA_ADAPTER DmaAdapter
;
2237 PUSBPORT_TRANSFER Transfer
;
2239 PUSBPORT_ENDPOINT Endpoint
;
2241 ULONG_PTR CurrentVa
;
2242 PUSBPORT_SCATTER_GATHER_LIST sgList
;
2243 SIZE_T CurrentLength
;
2245 BOOLEAN WriteToDevice
;
2246 PHYSICAL_ADDRESS PhAddr
= {{0, 0}};
2247 PHYSICAL_ADDRESS PhAddress
= {{0, 0}};
2248 SIZE_T TransferLength
;
2249 SIZE_T SgCurrentLength
;
2250 SIZE_T ElementLength
;
2251 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
2252 PDMA_OPERATIONS DmaOperations
;
2254 DPRINT_CORE("USBPORT_MapTransfer: ... \n");
2256 FdoExtension
= FdoDevice
->DeviceExtension
;
2257 DmaAdapter
= FdoExtension
->DmaAdapter
;
2258 DmaOperations
= DmaAdapter
->DmaOperations
;
2262 Urb
= Transfer
->Urb
;
2263 Endpoint
= Transfer
->Endpoint
;
2264 TransferLength
= Transfer
->TransferParameters
.TransferBufferLength
;
2266 Mdl
= Urb
->UrbControlTransfer
.TransferBufferMDL
;
2267 CurrentVa
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2269 Transfer
->SgList
.CurrentVa
= CurrentVa
;
2270 Transfer
->SgList
.MappedSystemVa
= MmGetSystemAddressForMdlSafe(Mdl
, NormalPagePriority
);
2272 sgList
= &Transfer
->SgList
;
2275 Transfer
->MapRegisterBase
= MapRegisterBase
;
2282 WriteToDevice
= Transfer
->Direction
== USBPORT_DMA_DIRECTION_TO_DEVICE
;
2283 ASSERT(Transfer
->Direction
!= 0);
2285 PhAddress
= DmaOperations
->MapTransfer(DmaAdapter
,
2292 DPRINT_CORE("USBPORT_MapTransfer: PhAddress.LowPart - %p, PhAddress.HighPart - %x, TransferLength - %x\n",
2297 PhAddress
.HighPart
= 0;
2298 SgCurrentLength
= TransferLength
;
2302 ElementLength
= PAGE_SIZE
- (PhAddress
.LowPart
& (PAGE_SIZE
- 1));
2304 if (ElementLength
> SgCurrentLength
)
2305 ElementLength
= SgCurrentLength
;
2307 DPRINT_CORE("USBPORT_MapTransfer: PhAddress.LowPart - %p, HighPart - %x, ElementLength - %x\n",
2312 sgList
->SgElement
[ix
].SgPhysicalAddress
= PhAddress
;
2313 sgList
->SgElement
[ix
].SgTransferLength
= ElementLength
;
2314 sgList
->SgElement
[ix
].SgOffset
= CurrentLength
+
2315 (TransferLength
- SgCurrentLength
);
2317 PhAddress
.LowPart
+= ElementLength
;
2318 SgCurrentLength
-= ElementLength
;
2322 while (SgCurrentLength
);
2324 if (PhAddr
.QuadPart
== PhAddress
.QuadPart
)
2326 DPRINT1("USBPORT_MapTransfer: PhAddr == PhAddress\n");
2332 CurrentLength
+= TransferLength
;
2333 CurrentVa
+= TransferLength
;
2335 TransferLength
= Transfer
->TransferParameters
.TransferBufferLength
-
2338 while (CurrentLength
!= Transfer
->TransferParameters
.TransferBufferLength
);
2340 Transfer
->SgList
.SgElementCount
= ix
;
2341 Transfer
->Flags
|= TRANSFER_FLAG_DMA_MAPPED
;
2343 ASSERT(Transfer
->TransferParameters
.TransferBufferLength
<=
2344 Endpoint
->EndpointProperties
.MaxTransferSize
);
2346 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
2347 InsertTailList(&Endpoint
->TransferList
, &Transfer
->TransferLink
);
2348 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
2350 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
2351 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
2353 if (USBPORT_EndpointWorker(Endpoint
, 0))
2355 USBPORT_InvalidateEndpointHandler(FdoDevice
,
2357 INVALIDATE_ENDPOINT_WORKER_THREAD
);
2360 return DeallocateObjectKeepRegisters
;
2365 USBPORT_FlushMapTransfers(IN PDEVICE_OBJECT FdoDevice
)
2367 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2368 PLIST_ENTRY MapTransferList
;
2369 PUSBPORT_TRANSFER Transfer
;
2370 ULONG NumMapRegisters
;
2372 SIZE_T TransferBufferLength
;
2373 ULONG_PTR VirtualAddr
;
2376 PDMA_OPERATIONS DmaOperations
;
2378 DPRINT_CORE("USBPORT_FlushMapTransfers: ... \n");
2380 FdoExtension
= FdoDevice
->DeviceExtension
;
2381 DmaOperations
= FdoExtension
->DmaAdapter
->DmaOperations
;
2383 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
2387 MapTransferList
= &FdoExtension
->MapTransferList
;
2389 if (IsListEmpty(&FdoExtension
->MapTransferList
))
2391 KeLowerIrql(OldIrql
);
2395 Transfer
= CONTAINING_RECORD(MapTransferList
->Flink
,
2399 RemoveHeadList(MapTransferList
);
2401 Mdl
= Transfer
->Urb
->UrbControlTransfer
.TransferBufferMDL
;
2402 TransferBufferLength
= Transfer
->TransferParameters
.TransferBufferLength
;
2403 VirtualAddr
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2405 NumMapRegisters
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddr
,
2406 TransferBufferLength
);
2408 Transfer
->NumberOfMapRegisters
= NumMapRegisters
;
2410 Status
= DmaOperations
->AllocateAdapterChannel(FdoExtension
->DmaAdapter
,
2413 USBPORT_MapTransfer
,
2416 if (!NT_SUCCESS(Status
))
2420 KeLowerIrql(OldIrql
);
2425 USBPORT_AllocateTransfer(IN PDEVICE_OBJECT FdoDevice
,
2427 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
2431 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2432 SIZE_T TransferLength
;
2434 ULONG_PTR VirtualAddr
;
2435 ULONG PagesNeed
= 0;
2436 SIZE_T PortTransferLength
;
2437 SIZE_T FullTransferLength
;
2438 PUSBPORT_TRANSFER Transfer
;
2439 PUSBPORT_PIPE_HANDLE PipeHandle
;
2440 USBD_STATUS USBDStatus
;
2442 DPRINT_CORE("USBPORT_AllocateTransfer: FdoDevice - %p, Urb - %p, DeviceHandle - %p, Irp - %p, Event - %p\n",
2449 FdoExtension
= FdoDevice
->DeviceExtension
;
2451 TransferLength
= Urb
->UrbControlTransfer
.TransferBufferLength
;
2452 PipeHandle
= Urb
->UrbControlTransfer
.PipeHandle
;
2456 Mdl
= Urb
->UrbControlTransfer
.TransferBufferMDL
;
2457 VirtualAddr
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2459 PagesNeed
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddr
,
2463 if (Urb
->UrbHeader
.Function
== URB_FUNCTION_ISOCH_TRANSFER
)
2465 DPRINT1("USBPORT_AllocateTransfer: ISOCH_TRANSFER UNIMPLEMENTED. FIXME.\n");
2468 PortTransferLength
= sizeof(USBPORT_TRANSFER
) +
2469 PagesNeed
* sizeof(USBPORT_SCATTER_GATHER_ELEMENT
);
2471 FullTransferLength
= PortTransferLength
+
2472 FdoExtension
->MiniPortInterface
->Packet
.MiniPortTransferSize
;
2474 Transfer
= ExAllocatePoolWithTag(NonPagedPool
,
2480 RtlZeroMemory(Transfer
, FullTransferLength
);
2482 Transfer
->Irp
= Irp
;
2483 Transfer
->Urb
= Urb
;
2484 Transfer
->Endpoint
= PipeHandle
->Endpoint
;
2485 Transfer
->Event
= Event
;
2486 Transfer
->PortTransferLength
= PortTransferLength
;
2487 Transfer
->FullTransferLength
= FullTransferLength
;
2489 Transfer
->MiniportTransfer
= (PVOID
)((ULONG_PTR
)Transfer
+
2490 PortTransferLength
);
2492 Urb
->UrbControlTransfer
.hca
.Reserved8
[0] = Transfer
;
2493 Urb
->UrbHeader
.UsbdFlags
|= USBD_FLAG_ALLOCATED_TRANSFER
;
2495 USBDStatus
= USBD_STATUS_SUCCESS
;
2499 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
2502 DPRINT_CORE("USBPORT_AllocateTransfer: return USBDStatus - %x\n",
2510 USBPORT_Dispatch(IN PDEVICE_OBJECT DeviceObject
,
2513 PUSBPORT_COMMON_DEVICE_EXTENSION DeviceExtension
;
2514 PIO_STACK_LOCATION IoStack
;
2515 NTSTATUS Status
= STATUS_SUCCESS
;
2517 DeviceExtension
= DeviceObject
->DeviceExtension
;
2518 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2520 if (DeviceExtension
->PnpStateFlags
& USBPORT_PNP_STATE_FAILED
)
2522 DPRINT1("USBPORT_Dispatch: USBPORT_PNP_STATE_FAILED\n");
2526 switch (IoStack
->MajorFunction
)
2528 case IRP_MJ_DEVICE_CONTROL
:
2529 if (DeviceExtension
->IsPDO
)
2531 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2532 IoStack
->MajorFunction
,
2533 IoStack
->MinorFunction
);
2535 Status
= USBPORT_PdoDeviceControl(DeviceObject
, Irp
);
2539 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2540 IoStack
->MajorFunction
,
2541 IoStack
->MinorFunction
);
2543 Status
= USBPORT_FdoDeviceControl(DeviceObject
, Irp
);
2548 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
2549 if (DeviceExtension
->IsPDO
)
2551 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_INTERNAL_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2552 IoStack
->MajorFunction
,
2553 IoStack
->MinorFunction
);
2555 Status
= USBPORT_PdoInternalDeviceControl(DeviceObject
, Irp
);
2559 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_INTERNAL_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2560 IoStack
->MajorFunction
,
2561 IoStack
->MinorFunction
);
2563 Status
= USBPORT_FdoInternalDeviceControl(DeviceObject
, Irp
);
2569 if (DeviceExtension
->IsPDO
)
2571 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_POWER. Major - %d, Minor - %d\n",
2572 IoStack
->MajorFunction
,
2573 IoStack
->MinorFunction
);
2575 Status
= USBPORT_PdoPower(DeviceObject
, Irp
);
2579 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_POWER. Major - %d, Minor - %d\n",
2580 IoStack
->MajorFunction
,
2581 IoStack
->MinorFunction
);
2583 Status
= USBPORT_FdoPower(DeviceObject
, Irp
);
2588 case IRP_MJ_SYSTEM_CONTROL
:
2589 if (DeviceExtension
->IsPDO
)
2591 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_SYSTEM_CONTROL. Major - %d, Minor - %d\n",
2592 IoStack
->MajorFunction
,
2593 IoStack
->MinorFunction
);
2595 Irp
->IoStatus
.Status
= Status
;
2596 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2600 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_SYSTEM_CONTROL. Major - %d, Minor - %d\n",
2601 IoStack
->MajorFunction
,
2602 IoStack
->MinorFunction
);
2604 IoSkipCurrentIrpStackLocation(Irp
);
2605 Status
= IoCallDriver(DeviceExtension
->LowerDevice
, Irp
);
2611 if (DeviceExtension
->IsPDO
)
2613 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_PNP. Major - %d, Minor - %d\n",
2614 IoStack
->MajorFunction
,
2615 IoStack
->MinorFunction
);
2617 Status
= USBPORT_PdoPnP(DeviceObject
, Irp
);
2621 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_PNP. Major - %d, Minor - %d\n",
2622 IoStack
->MajorFunction
,
2623 IoStack
->MinorFunction
);
2625 Status
= USBPORT_FdoPnP(DeviceObject
, Irp
);
2632 DPRINT("USBPORT_Dispatch: IRP_MJ_CREATE | IRP_MJ_CLOSE\n");
2633 Irp
->IoStatus
.Status
= Status
;
2634 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2638 if (DeviceExtension
->IsPDO
)
2640 DPRINT("USBPORT_Dispatch: PDO unhandled IRP_MJ_???. Major - %d, Minor - %d\n",
2641 IoStack
->MajorFunction
,
2642 IoStack
->MinorFunction
);
2646 DPRINT("USBPORT_Dispatch: FDO unhandled IRP_MJ_???. Major - %d, Minor - %d\n",
2647 IoStack
->MajorFunction
,
2648 IoStack
->MinorFunction
);
2651 Status
= STATUS_INVALID_DEVICE_REQUEST
;
2652 Irp
->IoStatus
.Status
= Status
;
2653 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2657 DPRINT("USBPORT_Dispatch: Status - %x\n", Status
);
2663 USBPORT_GetHciMn(VOID
)
2665 return USBPORT_HCI_MN
;
2670 USBPORT_RegisterUSBPortDriver(IN PDRIVER_OBJECT DriverObject
,
2672 IN PUSBPORT_REGISTRATION_PACKET RegPacket
)
2674 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
2676 DPRINT("USBPORT_RegisterUSBPortDriver: DriverObject - %p, Version - %p, RegPacket - %p\n",
2681 DPRINT("USBPORT_RegisterUSBPortDriver: sizeof(USBPORT_MINIPORT_INTERFACE) - %x\n",
2682 sizeof(USBPORT_MINIPORT_INTERFACE
));
2684 DPRINT("USBPORT_RegisterUSBPortDriver: sizeof(USBPORT_DEVICE_EXTENSION) - %x\n",
2685 sizeof(USBPORT_DEVICE_EXTENSION
));
2687 if (Version
< USB10_MINIPORT_INTERFACE_VERSION
)
2689 return STATUS_UNSUCCESSFUL
;
2692 if (!USBPORT_Initialized
)
2694 InitializeListHead(&USBPORT_MiniPortDrivers
);
2695 InitializeListHead(&USBPORT_USB1FdoList
);
2696 InitializeListHead(&USBPORT_USB2FdoList
);
2698 KeInitializeSpinLock(&USBPORT_SpinLock
);
2699 USBPORT_Initialized
= TRUE
;
2702 MiniPortInterface
= ExAllocatePoolWithTag(NonPagedPool
,
2703 sizeof(USBPORT_MINIPORT_INTERFACE
),
2705 if (!MiniPortInterface
)
2707 return STATUS_INSUFFICIENT_RESOURCES
;
2710 RtlZeroMemory(MiniPortInterface
, sizeof(USBPORT_MINIPORT_INTERFACE
));
2712 MiniPortInterface
->DriverObject
= DriverObject
;
2713 MiniPortInterface
->DriverUnload
= DriverObject
->DriverUnload
;
2714 MiniPortInterface
->Version
= Version
;
2716 ExInterlockedInsertTailList(&USBPORT_MiniPortDrivers
,
2717 &MiniPortInterface
->DriverLink
,
2720 DriverObject
->DriverExtension
->AddDevice
= USBPORT_AddDevice
;
2721 DriverObject
->DriverUnload
= USBPORT_Unload
;
2723 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = USBPORT_Dispatch
;
2724 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = USBPORT_Dispatch
;
2725 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = USBPORT_Dispatch
;
2726 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = USBPORT_Dispatch
;
2727 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = USBPORT_Dispatch
;
2728 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = USBPORT_Dispatch
;
2729 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = USBPORT_Dispatch
;
2731 RegPacket
->UsbPortDbgPrint
= USBPORT_DbgPrint
;
2732 RegPacket
->UsbPortTestDebugBreak
= USBPORT_TestDebugBreak
;
2733 RegPacket
->UsbPortAssertFailure
= USBPORT_AssertFailure
;
2734 RegPacket
->UsbPortGetMiniportRegistryKeyValue
= USBPORT_GetMiniportRegistryKeyValue
;
2735 RegPacket
->UsbPortInvalidateRootHub
= USBPORT_InvalidateRootHub
;
2736 RegPacket
->UsbPortInvalidateEndpoint
= USBPORT_InvalidateEndpoint
;
2737 RegPacket
->UsbPortCompleteTransfer
= USBPORT_MiniportCompleteTransfer
;
2738 RegPacket
->UsbPortCompleteIsoTransfer
= USBPORT_CompleteIsoTransfer
;
2739 RegPacket
->UsbPortLogEntry
= USBPORT_LogEntry
;
2740 RegPacket
->UsbPortGetMappedVirtualAddress
= USBPORT_GetMappedVirtualAddress
;
2741 RegPacket
->UsbPortRequestAsyncCallback
= USBPORT_RequestAsyncCallback
;
2742 RegPacket
->UsbPortReadWriteConfigSpace
= USBPORT_ReadWriteConfigSpace
;
2743 RegPacket
->UsbPortWait
= USBPORT_Wait
;
2744 RegPacket
->UsbPortInvalidateController
= USBPORT_InvalidateController
;
2745 RegPacket
->UsbPortBugCheck
= USBPORT_BugCheck
;
2746 RegPacket
->UsbPortNotifyDoubleBuffer
= USBPORT_NotifyDoubleBuffer
;
2748 RtlCopyMemory(&MiniPortInterface
->Packet
,
2750 sizeof(USBPORT_REGISTRATION_PACKET
));
2752 return STATUS_SUCCESS
;
2757 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
2758 IN PUNICODE_STRING RegistryPath
)
2760 return STATUS_SUCCESS
;