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 Context
,
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: Context - %p, UseDriverKey - %x, SourceString - %S, LengthStr - %x, Buffer - %p, BufferLength - %x\n",
387 //FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION));
388 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)Context
-
389 sizeof(USBPORT_DEVICE_EXTENSION
));
391 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
393 Status
= USBPORT_GetRegistryKeyValueFullInfo(FdoDevice
,
394 FdoExtension
->CommonExtension
.LowerPdoDevice
,
401 return USBPORT_NtStatusToMpStatus(Status
);
406 USBPORT_GetSetConfigSpaceData(IN PDEVICE_OBJECT FdoDevice
,
407 IN BOOLEAN IsReadData
,
412 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
413 ULONG BytesReadWrite
;
415 DPRINT("USBPORT_GetSetConfigSpaceData ... \n");
417 FdoExtension
= FdoDevice
->DeviceExtension
;
419 BytesReadWrite
= Length
;
423 RtlZeroMemory(Buffer
, Length
);
425 BytesReadWrite
= (*FdoExtension
->BusInterface
.GetBusData
)
426 (FdoExtension
->BusInterface
.Context
,
427 PCI_WHICHSPACE_CONFIG
,
434 BytesReadWrite
= (*FdoExtension
->BusInterface
.SetBusData
)
435 (FdoExtension
->BusInterface
.Context
,
436 PCI_WHICHSPACE_CONFIG
,
442 if (BytesReadWrite
== Length
)
444 return STATUS_SUCCESS
;
447 return STATUS_UNSUCCESSFUL
;
452 USBPORT_ReadWriteConfigSpace(IN PVOID Context
,
453 IN BOOLEAN IsReadData
,
459 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
460 PDEVICE_OBJECT FdoDevice
;
462 DPRINT("USBPORT_ReadWriteConfigSpace: ... \n");
464 //FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION));
465 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)Context
-
466 sizeof(USBPORT_DEVICE_EXTENSION
));
468 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
470 Status
= USBPORT_GetSetConfigSpaceData(FdoDevice
,
476 return USBPORT_NtStatusToMpStatus(Status
);
481 USBPORT_USBDStatusToNtStatus(IN PURB Urb
,
482 IN USBD_STATUS USBDStatus
)
486 if (USBD_ERROR(USBDStatus
))
488 DPRINT1("USBPORT_USBDStatusToNtStatus: Urb - %p, USBDStatus - %x\n",
494 Urb
->UrbHeader
.Status
= USBDStatus
;
498 case USBD_STATUS_SUCCESS
:
499 Status
= STATUS_SUCCESS
;
502 case USBD_STATUS_INSUFFICIENT_RESOURCES
:
503 Status
= STATUS_INSUFFICIENT_RESOURCES
;
506 case USBD_STATUS_DEVICE_GONE
:
507 Status
= STATUS_DEVICE_NOT_CONNECTED
;
510 case USBD_STATUS_CANCELED
:
511 Status
= STATUS_CANCELLED
;
514 case USBD_STATUS_NOT_SUPPORTED
:
515 Status
= STATUS_NOT_SUPPORTED
;
518 case USBD_STATUS_INVALID_URB_FUNCTION
:
519 case USBD_STATUS_INVALID_PARAMETER
:
520 case USBD_STATUS_INVALID_PIPE_HANDLE
:
521 case USBD_STATUS_BAD_START_FRAME
:
522 Status
= STATUS_INVALID_PARAMETER
;
526 if (USBD_ERROR(USBDStatus
))
527 Status
= STATUS_UNSUCCESSFUL
;
529 Status
= STATUS_SUCCESS
;
539 USBPORT_Wait(IN PVOID Context
,
540 IN ULONG Milliseconds
)
542 LARGE_INTEGER Interval
= {{0, 0}};
544 DPRINT("USBPORT_Wait: Milliseconds - %x\n", Milliseconds
);
545 Interval
.QuadPart
-= 10000 * Milliseconds
+ (KeQueryTimeIncrement() - 1);
546 return KeDelayExecutionThread(KernelMode
, FALSE
, &Interval
);
551 USBPORT_MiniportInterrupts(IN PDEVICE_OBJECT FdoDevice
,
554 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
555 PUSBPORT_REGISTRATION_PACKET Packet
;
559 DPRINT_INT("USBPORT_MiniportInterrupts: IsEnable - %p\n", IsEnable
);
561 FdoExtension
= FdoDevice
->DeviceExtension
;
562 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
564 IsLock
= (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_NOT_LOCK_INT
) == 0;
567 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
571 FdoExtension
->Flags
|= USBPORT_FLAG_INTERRUPT_ENABLED
;
572 Packet
->EnableInterrupts(FdoExtension
->MiniPortExt
);
576 Packet
->DisableInterrupts(FdoExtension
->MiniPortExt
);
577 FdoExtension
->Flags
&= ~USBPORT_FLAG_INTERRUPT_ENABLED
;
581 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
586 USBPORT_SoftInterruptDpc(IN PRKDPC Dpc
,
587 IN PVOID DeferredContext
,
588 IN PVOID SystemArgument1
,
589 IN PVOID SystemArgument2
)
591 PDEVICE_OBJECT FdoDevice
;
592 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
594 DPRINT("USBPORT_SoftInterruptDpc: ... \n");
596 FdoDevice
= DeferredContext
;
597 FdoExtension
= FdoDevice
->DeviceExtension
;
599 if (!KeInsertQueueDpc(&FdoExtension
->IsrDpc
, NULL
, (PVOID
)1))
601 InterlockedDecrement(&FdoExtension
->IsrDpcCounter
);
607 USBPORT_SoftInterrupt(IN PDEVICE_OBJECT FdoDevice
)
609 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
610 LARGE_INTEGER DueTime
= {{0, 0}};
612 DPRINT("USBPORT_SoftInterrupt: ... \n");
614 FdoExtension
= FdoDevice
->DeviceExtension
;
616 KeInitializeTimer(&FdoExtension
->TimerSoftInterrupt
);
618 KeInitializeDpc(&FdoExtension
->SoftInterruptDpc
,
619 USBPORT_SoftInterruptDpc
,
622 DueTime
.QuadPart
-= 10000 + (KeQueryTimeIncrement() - 1);
624 KeSetTimer(&FdoExtension
->TimerSoftInterrupt
,
626 &FdoExtension
->SoftInterruptDpc
);
631 USBPORT_InvalidateControllerHandler(IN PDEVICE_OBJECT FdoDevice
,
634 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
636 DPRINT("USBPORT_InvalidateControllerHandler: Invalidate Type - %x\n",
639 FdoExtension
= FdoDevice
->DeviceExtension
;
643 case INVALIDATE_CONTROLLER_RESET
:
644 DPRINT1("USBPORT_InvalidateControllerHandler: INVALIDATE_CONTROLLER_RESET UNIMPLEMENTED. FIXME. \n");
647 case INVALIDATE_CONTROLLER_SURPRISE_REMOVE
:
648 DPRINT1("USBPORT_InvalidateControllerHandler: INVALIDATE_CONTROLLER_SURPRISE_REMOVE UNIMPLEMENTED. FIXME. \n");
651 case INVALIDATE_CONTROLLER_SOFT_INTERRUPT
:
652 if (InterlockedIncrement(&FdoExtension
->IsrDpcCounter
))
654 InterlockedDecrement(&FdoExtension
->IsrDpcCounter
);
658 USBPORT_SoftInterrupt(FdoDevice
);
666 USBPORT_InvalidateController(IN PVOID Context
,
669 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
670 PDEVICE_OBJECT FdoDevice
;
672 DPRINT("USBPORT_InvalidateController: Invalidate Type - %x\n", Type
);
674 //FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION));
675 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)Context
-
676 sizeof(USBPORT_DEVICE_EXTENSION
));
677 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
679 USBPORT_InvalidateControllerHandler(FdoDevice
, Type
);
686 USBPORT_NotifyDoubleBuffer(IN PVOID Context1
,
691 DPRINT1("USBPORT_NotifyDoubleBuffer: UNIMPLEMENTED. FIXME. \n");
697 USBPORT_WorkerRequestDpc(IN PRKDPC Dpc
,
698 IN PVOID DeferredContext
,
699 IN PVOID SystemArgument1
,
700 IN PVOID SystemArgument2
)
702 PDEVICE_OBJECT FdoDevice
;
703 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
705 DPRINT("USBPORT_WorkerRequestDpc: ... \n");
707 FdoDevice
= DeferredContext
;
708 FdoExtension
= FdoDevice
->DeviceExtension
;
710 if (!InterlockedIncrement(&FdoExtension
->IsrDpcHandlerCounter
))
712 USBPORT_DpcHandler(FdoDevice
);
715 InterlockedDecrement(&FdoExtension
->IsrDpcHandlerCounter
);
720 USBPORT_DoneTransfer(IN PUSBPORT_TRANSFER Transfer
)
722 PUSBPORT_ENDPOINT Endpoint
;
723 PDEVICE_OBJECT FdoDevice
;
724 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
730 DPRINT_CORE("USBPORT_DoneTransfer: Transfer - %p\n", Transfer
);
732 Endpoint
= Transfer
->Endpoint
;
733 FdoDevice
= Endpoint
->FdoDevice
;
734 FdoExtension
= FdoDevice
->DeviceExtension
;
739 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
743 IoAcquireCancelSpinLock(&CancelIrql
);
744 IoSetCancelRoutine(Irp
, NULL
);
745 IoReleaseCancelSpinLock(CancelIrql
);
747 USBPORT_RemoveActiveTransferIrp(FdoDevice
, Irp
);
750 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
752 USBPORT_USBDStatusToNtStatus(Transfer
->Urb
, Transfer
->USBDStatus
);
753 USBPORT_CompleteTransfer(Urb
, Urb
->UrbHeader
.Status
);
755 DPRINT_CORE("USBPORT_DoneTransfer: exit\n");
760 USBPORT_FlushDoneTransfers(IN PDEVICE_OBJECT FdoDevice
)
762 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
763 PLIST_ENTRY DoneTransferList
;
764 PUSBPORT_TRANSFER Transfer
;
765 PUSBPORT_ENDPOINT Endpoint
;
768 BOOLEAN IsHasTransfers
;
770 DPRINT_CORE("USBPORT_FlushDoneTransfers: ... \n");
772 FdoExtension
= FdoDevice
->DeviceExtension
;
773 DoneTransferList
= &FdoExtension
->DoneTransferList
;
777 KeAcquireSpinLock(&FdoExtension
->DoneTransferSpinLock
, &OldIrql
);
779 if (IsListEmpty(DoneTransferList
))
782 Transfer
= CONTAINING_RECORD(DoneTransferList
->Flink
,
786 RemoveHeadList(DoneTransferList
);
787 KeReleaseSpinLock(&FdoExtension
->DoneTransferSpinLock
, OldIrql
);
791 Endpoint
= Transfer
->Endpoint
;
793 if ((Transfer
->Flags
& TRANSFER_FLAG_SPLITED
))
795 ASSERT(FALSE
);// USBPORT_DoneSplitTransfer(Transfer);
799 USBPORT_DoneTransfer(Transfer
);
802 IsHasTransfers
= USBPORT_EndpointHasQueuedTransfers(FdoDevice
,
806 if (IsHasTransfers
&& !TransferCount
)
808 USBPORT_InvalidateEndpointHandler(FdoDevice
,
810 INVALIDATE_ENDPOINT_WORKER_DPC
);
815 KeReleaseSpinLock(&FdoExtension
->DoneTransferSpinLock
, OldIrql
);
821 USBPORT_TransferFlushDpc(IN PRKDPC Dpc
,
822 IN PVOID DeferredContext
,
823 IN PVOID SystemArgument1
,
824 IN PVOID SystemArgument2
)
826 PDEVICE_OBJECT FdoDevice
;
828 DPRINT_CORE("USBPORT_TransferFlushDpc: ... \n");
829 FdoDevice
= DeferredContext
;
830 USBPORT_FlushDoneTransfers(FdoDevice
);
835 USBPORT_QueueDoneTransfer(IN PUSBPORT_TRANSFER Transfer
,
836 IN USBD_STATUS USBDStatus
)
838 PDEVICE_OBJECT FdoDevice
;
839 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
841 DPRINT_CORE("USBPORT_QueueDoneTransfer: Transfer - %p, USBDStatus - %p\n",
845 FdoDevice
= Transfer
->Endpoint
->FdoDevice
;
846 FdoExtension
= FdoDevice
->DeviceExtension
;
848 RemoveEntryList(&Transfer
->TransferLink
);
849 Transfer
->USBDStatus
= USBDStatus
;
851 ExInterlockedInsertTailList(&FdoExtension
->DoneTransferList
,
852 &Transfer
->TransferLink
,
853 &FdoExtension
->DoneTransferSpinLock
);
855 return KeInsertQueueDpc(&FdoExtension
->TransferFlushDpc
, NULL
, NULL
);
860 USBPORT_DpcHandler(IN PDEVICE_OBJECT FdoDevice
)
862 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
863 PUSBPORT_ENDPOINT Endpoint
;
868 DPRINT("USBPORT_DpcHandler: ... \n");
870 FdoExtension
= FdoDevice
->DeviceExtension
;
872 InitializeListHead(&List
);
874 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
875 Entry
= FdoExtension
->EndpointList
.Flink
;
877 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
879 Endpoint
= CONTAINING_RECORD(Entry
,
883 LockCounter
= InterlockedIncrement(&Endpoint
->LockCounter
);
885 if (USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_ACTIVE
||
887 Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
889 InterlockedDecrement(&Endpoint
->LockCounter
);
893 InsertTailList(&List
, &Endpoint
->DispatchLink
);
895 if (Endpoint
->WorkerLink
.Flink
&& Endpoint
->WorkerLink
.Blink
)
897 RemoveEntryList(&Endpoint
->WorkerLink
);
899 Endpoint
->WorkerLink
.Flink
= NULL
;
900 Endpoint
->WorkerLink
.Blink
= NULL
;
904 Entry
= Endpoint
->EndpointLink
.Flink
;
907 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
909 while (!IsListEmpty(&List
))
911 Endpoint
= CONTAINING_RECORD(List
.Flink
,
915 RemoveEntryList(List
.Flink
);
916 Endpoint
->DispatchLink
.Flink
= NULL
;
917 Endpoint
->DispatchLink
.Blink
= NULL
;
919 USBPORT_EndpointWorker(Endpoint
, TRUE
);
920 USBPORT_FlushPendingTransfers(Endpoint
);
923 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
925 if (!IsListEmpty(&FdoExtension
->WorkerList
))
927 USBPORT_SignalWorkerThread(FdoDevice
);
930 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
932 USBPORT_FlushDoneTransfers(FdoDevice
);
937 USBPORT_IsrDpcHandler(IN PDEVICE_OBJECT FdoDevice
,
938 IN BOOLEAN IsDpcHandler
)
940 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
941 PUSBPORT_REGISTRATION_PACKET Packet
;
942 PUSBPORT_ENDPOINT Endpoint
;
946 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
948 DPRINT_CORE("USBPORT_IsrDpcHandler: IsDpcHandler - %x\n", IsDpcHandler
);
950 FdoExtension
= FdoDevice
->DeviceExtension
;
951 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
953 if (InterlockedIncrement(&FdoExtension
->IsrDpcHandlerCounter
))
955 KeInsertQueueDpc(&FdoExtension
->IsrDpc
, NULL
, NULL
);
956 InterlockedDecrement(&FdoExtension
->IsrDpcHandlerCounter
);
960 for (List
= ExInterlockedRemoveHeadList(&FdoExtension
->EpStateChangeList
,
961 &FdoExtension
->EpStateChangeSpinLock
);
963 List
= ExInterlockedRemoveHeadList(&FdoExtension
->EpStateChangeList
,
964 &FdoExtension
->EpStateChangeSpinLock
))
966 Endpoint
= CONTAINING_RECORD(List
,
970 DPRINT_CORE("USBPORT_IsrDpcHandler: Endpoint - %p\n", Endpoint
);
972 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
974 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
975 FrameNumber
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
976 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
978 if (FrameNumber
<= Endpoint
->FrameNumber
&&
979 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
981 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
983 ExInterlockedInsertHeadList(&FdoExtension
->EpStateChangeList
,
984 &Endpoint
->StateChangeLink
,
985 &FdoExtension
->EpStateChangeSpinLock
);
987 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
988 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
989 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
994 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
996 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
997 Endpoint
->StateLast
= Endpoint
->StateNext
;
998 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1000 DPRINT_CORE("USBPORT_IsrDpcHandler: Endpoint->StateLast - %x\n",
1001 Endpoint
->StateLast
);
1005 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1007 INVALIDATE_ENDPOINT_ONLY
);
1011 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1013 INVALIDATE_ENDPOINT_WORKER_THREAD
);
1019 USBPORT_DpcHandler(FdoDevice
);
1022 InterlockedDecrement(&FdoExtension
->IsrDpcHandlerCounter
);
1027 USBPORT_IsrDpc(IN PRKDPC Dpc
,
1028 IN PVOID DeferredContext
,
1029 IN PVOID SystemArgument1
,
1030 IN PVOID SystemArgument2
)
1032 PDEVICE_OBJECT FdoDevice
;
1033 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1034 PUSBPORT_REGISTRATION_PACKET Packet
;
1035 BOOLEAN InterruptEnable
;
1037 DPRINT_INT("USBPORT_IsrDpc: DeferredContext - %p, SystemArgument2 - %p\n",
1041 FdoDevice
= DeferredContext
;
1042 FdoExtension
= FdoDevice
->DeviceExtension
;
1043 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1045 if (SystemArgument2
)
1047 InterlockedDecrement(&FdoExtension
->IsrDpcCounter
);
1050 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportInterruptsSpinLock
);
1051 InterruptEnable
= (FdoExtension
->Flags
& USBPORT_FLAG_INTERRUPT_ENABLED
) ==
1052 USBPORT_FLAG_INTERRUPT_ENABLED
;
1054 Packet
->InterruptDpc(FdoExtension
->MiniPortExt
, InterruptEnable
);
1056 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportInterruptsSpinLock
);
1058 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
&&
1059 FdoExtension
->TimerFlags
& USBPORT_TMFLAG_WAKE
)
1061 USBPORT_CompletePdoWaitWake(FdoDevice
);
1065 USBPORT_IsrDpcHandler(FdoDevice
, TRUE
);
1068 DPRINT_INT("USBPORT_IsrDpc: exit\n");
1073 USBPORT_InterruptService(IN PKINTERRUPT Interrupt
,
1074 IN PVOID ServiceContext
)
1076 PDEVICE_OBJECT FdoDevice
;
1077 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1078 PUSBPORT_REGISTRATION_PACKET Packet
;
1079 BOOLEAN Result
= FALSE
;
1081 FdoDevice
= ServiceContext
;
1082 FdoExtension
= FdoDevice
->DeviceExtension
;
1083 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1085 DPRINT_INT("USBPORT_InterruptService: FdoExtension->Flags - %lx\n",
1086 FdoExtension
->Flags
);
1088 if (FdoExtension
->Flags
& USBPORT_FLAG_INTERRUPT_ENABLED
&&
1089 FdoExtension
->MiniPortFlags
& USBPORT_MPFLAG_INTERRUPTS_ENABLED
)
1091 Result
= Packet
->InterruptService(FdoExtension
->MiniPortExt
);
1095 KeInsertQueueDpc(&FdoExtension
->IsrDpc
, NULL
, NULL
);
1099 DPRINT_INT("USBPORT_InterruptService: return - %x\n", Result
);
1106 USBPORT_SignalWorkerThread(IN PDEVICE_OBJECT FdoDevice
)
1108 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1111 DPRINT_CORE("USBPORT_SignalWorkerThread ... \n");
1113 FdoExtension
= FdoDevice
->DeviceExtension
;
1115 KeAcquireSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, &OldIrql
);
1116 KeSetEvent(&FdoExtension
->WorkerThreadEvent
, EVENT_INCREMENT
, FALSE
);
1117 KeReleaseSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, OldIrql
);
1122 USBPORT_WorkerThreadHandler(IN PDEVICE_OBJECT FdoDevice
)
1124 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1125 PUSBPORT_REGISTRATION_PACKET Packet
;
1126 PLIST_ENTRY workerList
;
1128 PUSBPORT_ENDPOINT Endpoint
;
1132 DPRINT_CORE("USBPORT_WorkerThreadHandler: ... \n");
1134 FdoExtension
= FdoDevice
->DeviceExtension
;
1135 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1137 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1139 if (!(FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
))
1141 Packet
->CheckController(FdoExtension
->MiniPortExt
);
1144 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1146 InitializeListHead(&list
);
1148 USBPORT_FlushAllEndpoints(FdoDevice
);
1152 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1153 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1155 workerList
= &FdoExtension
->WorkerList
;
1157 if (IsListEmpty(workerList
))
1160 Endpoint
= CONTAINING_RECORD(workerList
->Flink
,
1164 DPRINT_CORE("USBPORT_WorkerThreadHandler: Endpoint - %p\n", Endpoint
);
1166 RemoveHeadList(workerList
);
1167 Endpoint
->WorkerLink
.Blink
= NULL
;
1168 Endpoint
->WorkerLink
.Flink
= NULL
;
1170 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1172 Result
= USBPORT_EndpointWorker(Endpoint
, FALSE
);
1173 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1177 if (Endpoint
->FlushAbortLink
.Flink
== NULL
||
1178 Endpoint
->FlushAbortLink
.Blink
== NULL
)
1180 InsertTailList(&list
, &Endpoint
->FlushAbortLink
);
1184 while (!IsListEmpty(&list
))
1186 Endpoint
= CONTAINING_RECORD(list
.Flink
,
1190 RemoveHeadList(&list
);
1192 Endpoint
->FlushAbortLink
.Flink
= NULL
;
1193 Endpoint
->FlushAbortLink
.Blink
= NULL
;
1195 if (Endpoint
->WorkerLink
.Flink
== NULL
||
1196 Endpoint
->WorkerLink
.Blink
== NULL
)
1198 InsertTailList(&FdoExtension
->WorkerList
,
1199 &Endpoint
->WorkerLink
);
1201 USBPORT_SignalWorkerThread(FdoDevice
);
1205 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1206 KeLowerIrql(OldIrql
);
1209 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1210 KeLowerIrql(OldIrql
);
1212 USBPORT_FlushClosedEndpointList(FdoDevice
);
1217 USBPORT_DoRootHubCallback(IN PDEVICE_OBJECT FdoDevice
)
1219 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1220 PDEVICE_OBJECT PdoDevice
;
1221 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1222 PRH_INIT_CALLBACK RootHubInitCallback
;
1223 PVOID RootHubInitContext
;
1225 FdoExtension
= FdoDevice
->DeviceExtension
;
1227 DPRINT("USBPORT_DoRootHubCallback: FdoDevice - %p\n", FdoDevice
);
1229 PdoDevice
= FdoExtension
->RootHubPdo
;
1233 PdoExtension
= PdoDevice
->DeviceExtension
;
1235 RootHubInitContext
= PdoExtension
->RootHubInitContext
;
1236 RootHubInitCallback
= PdoExtension
->RootHubInitCallback
;
1238 PdoExtension
->RootHubInitCallback
= NULL
;
1239 PdoExtension
->RootHubInitContext
= NULL
;
1241 if (RootHubInitCallback
)
1243 RootHubInitCallback(RootHubInitContext
);
1247 DPRINT("USBPORT_DoRootHubCallback: exit\n");
1252 USBPORT_SynchronizeRootHubCallback(IN PDEVICE_OBJECT FdoDevice
,
1253 IN PDEVICE_OBJECT Usb2FdoDevice
)
1255 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1256 PUSBPORT_REGISTRATION_PACKET Packet
;
1257 PUSBPORT_DEVICE_EXTENSION Usb2FdoExtension
;
1258 PDEVICE_RELATIONS CompanionControllersList
;
1259 PUSBPORT_DEVICE_EXTENSION CompanionFdoExtension
;
1260 PDEVICE_OBJECT
* Entry
;
1263 DPRINT("USBPORT_SynchronizeRootHubCallback: FdoDevice - %p, Usb2FdoDevice - %p\n",
1267 FdoExtension
= FdoDevice
->DeviceExtension
;
1268 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1270 if (Usb2FdoDevice
== NULL
&&
1271 !(Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
))
1273 /* Not Companion USB11 Controller */
1274 USBPORT_DoRootHubCallback(FdoDevice
);
1276 FdoExtension
->Flags
&= ~USBPORT_FLAG_RH_INIT_CALLBACK
;
1277 InterlockedCompareExchange(&FdoExtension
->RHInitCallBackLock
, 0, 1);
1279 DPRINT("USBPORT_SynchronizeRootHubCallback: exit \n");
1283 /* USB2 or Companion USB11 */
1285 DPRINT("USBPORT_SynchronizeRootHubCallback: FdoExtension->Flags - %p\n",
1286 FdoExtension
->Flags
);
1288 if (!(FdoExtension
->Flags
& USBPORT_FLAG_COMPANION_HC
))
1290 KeWaitForSingleObject(&FdoExtension
->ControllerSemaphore
,
1296 FdoExtension
->Flags
|= USBPORT_FLAG_PWR_AND_CHIRP_LOCK
;
1298 if (!(FdoExtension
->Flags
& (USBPORT_FLAG_HC_SUSPEND
|
1299 USBPORT_FLAG_POWER_AND_CHIRP_OK
)))
1301 USBPORT_RootHubPowerAndChirpAllCcPorts(FdoDevice
);
1302 FdoExtension
->Flags
|= USBPORT_FLAG_POWER_AND_CHIRP_OK
;
1305 FdoExtension
->Flags
&= ~USBPORT_FLAG_PWR_AND_CHIRP_LOCK
;
1307 KeReleaseSemaphore(&FdoExtension
->ControllerSemaphore
,
1308 LOW_REALTIME_PRIORITY
,
1312 CompanionControllersList
= USBPORT_FindCompanionControllers(FdoDevice
,
1316 if (CompanionControllersList
)
1318 Entry
= &CompanionControllersList
->Objects
[0];
1320 for (ix
= 0; ix
< CompanionControllersList
->Count
; ++ix
)
1322 CompanionFdoExtension
= ((*Entry
)->DeviceExtension
);
1324 InterlockedCompareExchange(&CompanionFdoExtension
->RHInitCallBackLock
,
1331 ExFreePoolWithTag(CompanionControllersList
, USB_PORT_TAG
);
1334 USBPORT_DoRootHubCallback(FdoDevice
);
1336 FdoExtension
->Flags
&= ~USBPORT_FLAG_RH_INIT_CALLBACK
;
1337 InterlockedCompareExchange(&FdoExtension
->RHInitCallBackLock
, 0, 1);
1341 Usb2FdoExtension
= Usb2FdoDevice
->DeviceExtension
;
1343 USBPORT_Wait(FdoDevice
, 50);
1345 while (FdoExtension
->RHInitCallBackLock
)
1347 USBPORT_Wait(FdoDevice
, 10);
1349 Usb2FdoExtension
->Flags
|= USBPORT_FLAG_RH_INIT_CALLBACK
;
1350 USBPORT_SignalWorkerThread(Usb2FdoDevice
);
1353 USBPORT_DoRootHubCallback(FdoDevice
);
1355 FdoExtension
->Flags
&= ~USBPORT_FLAG_RH_INIT_CALLBACK
;
1358 DPRINT("USBPORT_SynchronizeRootHubCallback: exit \n");
1363 USBPORT_WorkerThread(IN PVOID StartContext
)
1365 PDEVICE_OBJECT FdoDevice
;
1366 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1367 LARGE_INTEGER OldTime
;
1368 LARGE_INTEGER NewTime
;
1371 DPRINT_CORE("USBPORT_WorkerThread ... \n");
1373 FdoDevice
= StartContext
;
1374 FdoExtension
= FdoDevice
->DeviceExtension
;
1376 FdoExtension
->WorkerThread
= KeGetCurrentThread();
1380 KeQuerySystemTime(&OldTime
);
1382 KeWaitForSingleObject(&FdoExtension
->WorkerThreadEvent
,
1388 KeQuerySystemTime(&NewTime
);
1390 KeAcquireSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, &OldIrql
);
1391 KeResetEvent(&FdoExtension
->WorkerThreadEvent
);
1392 KeReleaseSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
, OldIrql
);
1393 DPRINT_CORE("USBPORT_WorkerThread: run \n");
1395 if (FdoExtension
->MiniPortFlags
& USBPORT_MPFLAG_INTERRUPTS_ENABLED
)
1397 USBPORT_DoSetPowerD0(FdoDevice
);
1399 if (FdoExtension
->Flags
& USBPORT_FLAG_RH_INIT_CALLBACK
)
1401 PDEVICE_OBJECT USB2FdoDevice
= NULL
;
1403 USB2FdoDevice
= USBPORT_FindUSB2Controller(FdoDevice
);
1404 USBPORT_SynchronizeRootHubCallback(FdoDevice
, USB2FdoDevice
);
1408 USBPORT_WorkerThreadHandler(FdoDevice
);
1410 while (!(FdoExtension
->Flags
& USBPORT_FLAG_WORKER_THREAD_ON
));
1412 PsTerminateSystemThread(0);
1417 USBPORT_CreateWorkerThread(IN PDEVICE_OBJECT FdoDevice
)
1419 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1422 DPRINT("USBPORT_CreateWorkerThread ... \n");
1424 FdoExtension
= FdoDevice
->DeviceExtension
;
1426 FdoExtension
->Flags
&= ~USBPORT_FLAG_WORKER_THREAD_ON
;
1428 KeInitializeEvent(&FdoExtension
->WorkerThreadEvent
,
1432 Status
= PsCreateSystemThread(&FdoExtension
->WorkerThreadHandle
,
1437 USBPORT_WorkerThread
,
1445 USBPORT_SynchronizeControllersStart(IN PDEVICE_OBJECT FdoDevice
)
1447 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1448 PDEVICE_OBJECT PdoDevice
;
1449 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1450 PDEVICE_OBJECT USB2FdoDevice
= NULL
;
1451 PUSBPORT_DEVICE_EXTENSION USB2FdoExtension
;
1454 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: FdoDevice - %p\n",
1457 FdoExtension
= FdoDevice
->DeviceExtension
;
1459 PdoDevice
= FdoExtension
->RootHubPdo
;
1466 PdoExtension
= PdoDevice
->DeviceExtension
;
1468 if (PdoExtension
->RootHubInitCallback
== NULL
||
1469 FdoExtension
->Flags
& USBPORT_FLAG_RH_INIT_CALLBACK
)
1474 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: Flags - %p\n",
1475 FdoExtension
->Flags
);
1477 if (FdoExtension
->Flags
& USBPORT_FLAG_COMPANION_HC
)
1481 USB2FdoDevice
= USBPORT_FindUSB2Controller(FdoDevice
);
1483 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: USB2FdoDevice - %p\n",
1488 USB2FdoExtension
= USB2FdoDevice
->DeviceExtension
;
1490 if (USB2FdoExtension
->CommonExtension
.PnpStateFlags
&
1491 USBPORT_PNP_STATE_STARTED
)
1497 if (!(FdoExtension
->Flags
& USBPORT_FLAG_NO_HACTION
))
1502 USB2FdoDevice
= NULL
;
1510 !InterlockedCompareExchange(&FdoExtension
->RHInitCallBackLock
, 1, 0))
1512 FdoExtension
->Flags
|= USBPORT_FLAG_RH_INIT_CALLBACK
;
1513 USBPORT_SignalWorkerThread(FdoDevice
);
1517 USB2FdoExtension
= USB2FdoDevice
->DeviceExtension
;
1519 USB2FdoExtension
->Flags
|= USBPORT_FLAG_RH_INIT_CALLBACK
;
1520 USBPORT_SignalWorkerThread(USB2FdoDevice
);
1524 DPRINT_TIMER("USBPORT_SynchronizeControllersStart: exit\n");
1529 USBPORT_TimerDpc(IN PRKDPC Dpc
,
1530 IN PVOID DeferredContext
,
1531 IN PVOID SystemArgument1
,
1532 IN PVOID SystemArgument2
)
1534 PDEVICE_OBJECT FdoDevice
;
1535 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1536 PUSBPORT_REGISTRATION_PACKET Packet
;
1537 LARGE_INTEGER DueTime
= {{0, 0}};
1539 PTIMER_WORK_QUEUE_ITEM IdleQueueItem
;
1543 DPRINT_TIMER("USBPORT_TimerDpc: Dpc - %p, DeferredContext - %p\n",
1547 FdoDevice
= DeferredContext
;
1548 FdoExtension
= FdoDevice
->DeviceExtension
;
1549 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1551 KeAcquireSpinLock(&FdoExtension
->TimerFlagsSpinLock
, &TimerOldIrql
);
1553 TimerFlags
= FdoExtension
->TimerFlags
;
1555 DPRINT_TIMER("USBPORT_TimerDpc: Flags - %p, TimerFlags - %p\n",
1556 FdoExtension
->Flags
,
1559 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
&&
1560 FdoExtension
->Flags
& USBPORT_FLAG_HC_WAKE_SUPPORT
&&
1561 !(TimerFlags
& USBPORT_TMFLAG_HC_RESUME
))
1563 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1564 Packet
->PollController(FdoExtension
->MiniPortExt
);
1565 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1568 USBPORT_SynchronizeControllersStart(FdoDevice
);
1570 if (TimerFlags
& USBPORT_TMFLAG_HC_SUSPENDED
)
1572 USBPORT_BadRequestFlush(FdoDevice
);
1576 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1578 if (!(FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
))
1580 Packet
->CheckController(FdoExtension
->MiniPortExt
);
1583 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1585 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_POLLING
)
1587 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1588 Packet
->PollController(FdoExtension
->MiniPortExt
);
1589 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1592 USBPORT_IsrDpcHandler(FdoDevice
, FALSE
);
1594 DPRINT_TIMER("USBPORT_TimerDpc: USBPORT_TimeoutAllEndpoints UNIMPLEMENTED.\n");
1595 //USBPORT_TimeoutAllEndpoints(FdoDevice);
1596 DPRINT_TIMER("USBPORT_TimerDpc: USBPORT_CheckIdleEndpoints UNIMPLEMENTED.\n");
1597 //USBPORT_CheckIdleEndpoints(FdoDevice);
1599 USBPORT_BadRequestFlush(FdoDevice
);
1601 if (FdoExtension
->IdleLockCounter
> -1 &&
1602 !(TimerFlags
& USBPORT_TMFLAG_IDLE_QUEUEITEM_ON
))
1604 IdleQueueItem
= ExAllocatePoolWithTag(NonPagedPool
,
1605 sizeof(TIMER_WORK_QUEUE_ITEM
),
1608 DPRINT("USBPORT_TimerDpc: IdleLockCounter - %x, IdleQueueItem - %p\n",
1609 FdoExtension
->IdleLockCounter
,
1614 RtlZeroMemory(IdleQueueItem
, sizeof(TIMER_WORK_QUEUE_ITEM
));
1616 IdleQueueItem
->WqItem
.List
.Flink
= NULL
;
1617 IdleQueueItem
->WqItem
.WorkerRoutine
= USBPORT_DoIdleNotificationCallback
;
1618 IdleQueueItem
->WqItem
.Parameter
= IdleQueueItem
;
1620 IdleQueueItem
->FdoDevice
= FdoDevice
;
1621 IdleQueueItem
->Context
= 0;
1623 FdoExtension
->TimerFlags
|= USBPORT_TMFLAG_IDLE_QUEUEITEM_ON
;
1625 ExQueueWorkItem(&IdleQueueItem
->WqItem
, CriticalWorkQueue
);
1631 KeReleaseSpinLock(&FdoExtension
->TimerFlagsSpinLock
, TimerOldIrql
);
1633 if (TimerFlags
& USBPORT_TMFLAG_TIMER_QUEUED
)
1635 DueTime
.QuadPart
-= FdoExtension
->TimerValue
* 10000 +
1636 (KeQueryTimeIncrement() - 1);
1638 KeSetTimer(&FdoExtension
->TimerObject
,
1640 &FdoExtension
->TimerDpc
);
1643 DPRINT_TIMER("USBPORT_TimerDpc: exit\n");
1648 USBPORT_StartTimer(IN PDEVICE_OBJECT FdoDevice
,
1651 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1652 LARGE_INTEGER DueTime
= {{0, 0}};
1653 ULONG TimeIncrement
;
1656 DPRINT_TIMER("USBPORT_StartTimer: FdoDevice - %p, Time - %x\n",
1660 FdoExtension
= FdoDevice
->DeviceExtension
;
1662 TimeIncrement
= KeQueryTimeIncrement();
1664 FdoExtension
->TimerFlags
|= USBPORT_TMFLAG_TIMER_QUEUED
;
1665 FdoExtension
->TimerValue
= Time
;
1667 KeInitializeTimer(&FdoExtension
->TimerObject
);
1668 KeInitializeDpc(&FdoExtension
->TimerDpc
, USBPORT_TimerDpc
, FdoDevice
);
1670 DueTime
.QuadPart
-= 10000 * Time
+ (TimeIncrement
- 1);
1672 Result
= KeSetTimer(&FdoExtension
->TimerObject
,
1674 &FdoExtension
->TimerDpc
);
1679 PUSBPORT_COMMON_BUFFER_HEADER
1681 USBPORT_AllocateCommonBuffer(IN PDEVICE_OBJECT FdoDevice
,
1682 IN SIZE_T BufferLength
)
1684 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
= NULL
;
1685 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1686 PDMA_ADAPTER DmaAdapter
;
1687 PDMA_OPERATIONS DmaOperations
;
1691 PHYSICAL_ADDRESS LogicalAddress
;
1693 ULONG_PTR StartBufferVA
;
1694 ULONG_PTR StartBufferPA
;
1696 DPRINT("USBPORT_AllocateCommonBuffer: FdoDevice - %p, BufferLength - %p\n",
1700 if (BufferLength
== 0)
1703 FdoExtension
= FdoDevice
->DeviceExtension
;
1705 DmaAdapter
= FdoExtension
->DmaAdapter
;
1706 DmaOperations
= DmaAdapter
->DmaOperations
;
1708 HeaderSize
= sizeof(USBPORT_COMMON_BUFFER_HEADER
);
1709 Length
= ROUND_TO_PAGES(BufferLength
+ HeaderSize
);
1710 LengthPadded
= Length
- (BufferLength
+ HeaderSize
);
1712 BaseVA
= (ULONG_PTR
)DmaOperations
->AllocateCommonBuffer(DmaAdapter
,
1720 StartBufferVA
= BaseVA
& ~(PAGE_SIZE
- 1);
1721 StartBufferPA
= LogicalAddress
.LowPart
& ~(PAGE_SIZE
- 1);
1723 HeaderBuffer
= (PUSBPORT_COMMON_BUFFER_HEADER
)(StartBufferVA
+
1727 HeaderBuffer
->Length
= Length
;
1728 HeaderBuffer
->BaseVA
= BaseVA
;
1729 HeaderBuffer
->LogicalAddress
= LogicalAddress
;
1731 HeaderBuffer
->BufferLength
= BufferLength
+ LengthPadded
;
1732 HeaderBuffer
->VirtualAddress
= StartBufferVA
;
1733 HeaderBuffer
->PhysicalAddress
= StartBufferPA
;
1735 RtlZeroMemory((PVOID
)StartBufferVA
, BufferLength
+ LengthPadded
);
1738 return HeaderBuffer
;
1743 USBPORT_FreeCommonBuffer(IN PDEVICE_OBJECT FdoDevice
,
1744 IN PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
)
1746 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1747 PDMA_ADAPTER DmaAdapter
;
1748 PDMA_OPERATIONS DmaOperations
;
1750 DPRINT("USBPORT_FreeCommonBuffer: ... \n");
1752 FdoExtension
= FdoDevice
->DeviceExtension
;
1754 DmaAdapter
= FdoExtension
->DmaAdapter
;
1755 DmaOperations
= DmaAdapter
->DmaOperations
;
1757 DmaOperations
->FreeCommonBuffer(FdoExtension
->DmaAdapter
,
1758 HeaderBuffer
->Length
,
1759 HeaderBuffer
->LogicalAddress
,
1760 (PVOID
)HeaderBuffer
->VirtualAddress
,
1764 PUSBPORT_MINIPORT_INTERFACE
1766 USBPORT_FindMiniPort(IN PDRIVER_OBJECT DriverObject
)
1770 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
1771 BOOLEAN IsFound
= FALSE
;
1773 DPRINT("USBPORT_FindMiniPort: ... \n");
1775 KeAcquireSpinLock(&USBPORT_SpinLock
, &OldIrql
);
1777 for (List
= USBPORT_MiniPortDrivers
.Flink
;
1778 List
!= &USBPORT_MiniPortDrivers
;
1781 MiniPortInterface
= CONTAINING_RECORD(List
,
1782 USBPORT_MINIPORT_INTERFACE
,
1785 if (MiniPortInterface
->DriverObject
== DriverObject
)
1787 DPRINT("USBPORT_FindMiniPort: find MiniPortInterface - %p\n",
1795 KeReleaseSpinLock(&USBPORT_SpinLock
, OldIrql
);
1798 return MiniPortInterface
;
1806 USBPORT_AddDevice(IN PDRIVER_OBJECT DriverObject
,
1807 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1810 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
1811 ULONG DeviceNumber
= 0;
1812 WCHAR CharDeviceName
[64];
1813 UNICODE_STRING DeviceName
;
1814 PDEVICE_OBJECT DeviceObject
;
1815 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1816 PUSBPORT_COMMON_DEVICE_EXTENSION FdoCommonExtension
;
1817 PDEVICE_OBJECT LowerDevice
;
1820 DPRINT("USBPORT_AddDevice: DriverObject - %p, PhysicalDeviceObject - %p\n",
1822 PhysicalDeviceObject
);
1824 MiniPortInterface
= USBPORT_FindMiniPort(DriverObject
);
1826 if (!MiniPortInterface
)
1828 DPRINT("USBPORT_AddDevice: USBPORT_FindMiniPort not found MiniPortInterface\n");
1829 return STATUS_UNSUCCESSFUL
;
1834 /* Construct device name */
1835 RtlStringCbPrintfW(CharDeviceName
,
1836 sizeof(CharDeviceName
),
1837 L
"\\Device\\USBFDO-%d",
1840 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
1842 Length
= sizeof(USBPORT_DEVICE_EXTENSION
) +
1843 MiniPortInterface
->Packet
.MiniPortExtensionSize
;
1846 Status
= IoCreateDevice(DriverObject
,
1849 FILE_DEVICE_CONTROLLER
,
1854 /* Check for success */
1855 if (NT_SUCCESS(Status
)) break;
1857 /* Is there a device object with that same name */
1858 if ((Status
== STATUS_OBJECT_NAME_EXISTS
) ||
1859 (Status
== STATUS_OBJECT_NAME_COLLISION
))
1861 /* Try the next name */
1866 /* Bail out on other errors */
1867 if (!NT_SUCCESS(Status
))
1869 DPRINT1("USBPORT_AddDevice: failed to create %wZ, Status %x\n",
1877 DPRINT("USBPORT_AddDevice: created device %p <%wZ>, Status %x\n",
1882 FdoExtension
= DeviceObject
->DeviceExtension
;
1883 FdoCommonExtension
= &FdoExtension
->CommonExtension
;
1885 RtlZeroMemory(FdoExtension
, sizeof(USBPORT_DEVICE_EXTENSION
));
1887 FdoCommonExtension
->SelfDevice
= DeviceObject
;
1888 FdoCommonExtension
->LowerPdoDevice
= PhysicalDeviceObject
;
1889 FdoCommonExtension
->IsPDO
= FALSE
;
1891 LowerDevice
= IoAttachDeviceToDeviceStack(DeviceObject
,
1892 PhysicalDeviceObject
);
1894 FdoCommonExtension
->LowerDevice
= LowerDevice
;
1896 FdoCommonExtension
->DevicePowerState
= PowerDeviceD3
;
1898 FdoExtension
->MiniPortExt
= (PVOID
)((ULONG_PTR
)FdoExtension
+
1899 sizeof(USBPORT_DEVICE_EXTENSION
));
1901 FdoExtension
->MiniPortInterface
= MiniPortInterface
;
1902 FdoExtension
->FdoNameNumber
= DeviceNumber
;
1904 KeInitializeSemaphore(&FdoExtension
->DeviceSemaphore
, 1, 1);
1905 KeInitializeSemaphore(&FdoExtension
->ControllerSemaphore
, 1, 1);
1907 InitializeListHead(&FdoExtension
->EndpointList
);
1908 InitializeListHead(&FdoExtension
->DoneTransferList
);
1909 InitializeListHead(&FdoExtension
->WorkerList
);
1910 InitializeListHead(&FdoExtension
->EpStateChangeList
);
1911 InitializeListHead(&FdoExtension
->MapTransferList
);
1912 InitializeListHead(&FdoExtension
->DeviceHandleList
);
1913 InitializeListHead(&FdoExtension
->IdleIrpList
);
1914 InitializeListHead(&FdoExtension
->BadRequestList
);
1915 InitializeListHead(&FdoExtension
->EndpointClosedList
);
1917 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1924 USBPORT_Unload(IN PDRIVER_OBJECT DriverObject
)
1926 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
1928 DPRINT1("USBPORT_Unload: FIXME!\n");
1930 MiniPortInterface
= USBPORT_FindMiniPort(DriverObject
);
1932 if (!MiniPortInterface
)
1934 DPRINT("USBPORT_Unload: CRITICAL ERROR!!! USBPORT_FindMiniPort not found MiniPortInterface\n");
1935 KeBugCheckEx(BUGCODE_USB_DRIVER
, 1, 0, 0, 0);
1938 DPRINT1("USBPORT_Unload: UNIMPLEMENTED. FIXME. \n");
1939 //MiniPortInterface->DriverUnload(DriverObject); // Call MiniPort _HCI_Unload
1944 USBPORT_MiniportCompleteTransfer(IN PVOID MiniPortExtension
,
1945 IN PVOID MiniPortEndpoint
,
1946 IN PVOID TransferParameters
,
1947 IN USBD_STATUS USBDStatus
,
1948 IN ULONG TransferLength
)
1950 PUSBPORT_TRANSFER Transfer
;
1951 PDEVICE_OBJECT FdoDevice
;
1952 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1954 DPRINT_CORE("USBPORT_MiniportCompleteTransfer: USBDStatus - %x, TransferLength - %x\n",
1958 Transfer
= CONTAINING_RECORD(TransferParameters
,
1960 TransferParameters
);
1962 FdoDevice
= Transfer
->Endpoint
->FdoDevice
;
1963 FdoExtension
= FdoDevice
->DeviceExtension
;
1965 Transfer
->CompletedTransferLen
= TransferLength
;
1967 RemoveEntryList(&Transfer
->TransferLink
);
1969 Transfer
->USBDStatus
= USBDStatus
;
1971 ExInterlockedInsertTailList(&FdoExtension
->DoneTransferList
,
1972 &Transfer
->TransferLink
,
1973 &FdoExtension
->DoneTransferSpinLock
);
1975 return KeInsertQueueDpc(&FdoExtension
->TransferFlushDpc
, NULL
, NULL
);
1980 USBPORT_CompleteIsoTransfer(IN PVOID MiniPortExtension
,
1981 IN PVOID MiniPortEndpoint
,
1982 IN PVOID TransferParameters
,
1983 IN ULONG TransferLength
)
1985 DPRINT1("USBPORT_CompleteIsoTransfer: UNIMPLEMENTED. FIXME.\n");
1991 USBPORT_AsyncTimerDpc(IN PRKDPC Dpc
,
1992 IN PVOID DeferredContext
,
1993 IN PVOID SystemArgument1
,
1994 IN PVOID SystemArgument2
)
1996 PDEVICE_OBJECT FdoDevice
;
1997 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1998 PUSBPORT_ASYNC_CALLBACK_DATA AsyncCallbackData
;
2000 DPRINT("USBPORT_AsyncTimerDpc: ... \n");
2002 AsyncCallbackData
= DeferredContext
;
2003 FdoDevice
= AsyncCallbackData
->FdoDevice
;
2004 FdoExtension
= FdoDevice
->DeviceExtension
;
2006 (*AsyncCallbackData
->CallbackFunction
)(FdoExtension
->MiniPortExt
,
2007 &AsyncCallbackData
->CallbackContext
);
2009 ExFreePoolWithTag(AsyncCallbackData
, USB_PORT_TAG
);
2014 USBPORT_RequestAsyncCallback(IN PVOID Context
,
2015 IN ULONG TimerValue
,
2018 IN ASYNC_TIMER_CALLBACK
* Callback
)
2020 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2021 PDEVICE_OBJECT FdoDevice
;
2022 PUSBPORT_ASYNC_CALLBACK_DATA AsyncCallbackData
;
2023 LARGE_INTEGER DueTime
= {{0, 0}};
2025 DPRINT("USBPORT_RequestAsyncCallback: ... \n");
2027 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)Context
-
2028 sizeof(USBPORT_DEVICE_EXTENSION
));
2030 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
2032 AsyncCallbackData
= ExAllocatePoolWithTag(NonPagedPool
,
2033 sizeof(USBPORT_ASYNC_CALLBACK_DATA
) + Length
,
2036 if (!AsyncCallbackData
)
2038 DPRINT1("USBPORT_RequestAsyncCallback: Not allocated AsyncCallbackData!\n");
2042 RtlZeroMemory(AsyncCallbackData
,
2043 sizeof(USBPORT_ASYNC_CALLBACK_DATA
) + Length
);
2047 RtlCopyMemory(&AsyncCallbackData
->CallbackContext
, Buffer
, Length
);
2050 AsyncCallbackData
->FdoDevice
= FdoDevice
;
2051 AsyncCallbackData
->CallbackFunction
= Callback
;
2053 KeInitializeTimer(&AsyncCallbackData
->AsyncTimer
);
2055 KeInitializeDpc(&AsyncCallbackData
->AsyncTimerDpc
,
2056 USBPORT_AsyncTimerDpc
,
2059 DueTime
.QuadPart
-= (KeQueryTimeIncrement() - 1) + 10000 * TimerValue
;
2061 KeSetTimer(&AsyncCallbackData
->AsyncTimer
,
2063 &AsyncCallbackData
->AsyncTimerDpc
);
2070 USBPORT_GetMappedVirtualAddress(IN PVOID PhysicalAddress
,
2071 IN PVOID MiniPortExtension
,
2072 IN PVOID MiniPortEndpoint
)
2074 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
2075 PUSBPORT_ENDPOINT Endpoint
;
2077 ULONG_PTR VirtualAddress
;
2079 DPRINT_CORE("USBPORT_GetMappedVirtualAddress ... \n");
2081 Endpoint
= (PUSBPORT_ENDPOINT
)((ULONG_PTR
)MiniPortEndpoint
-
2082 sizeof(USBPORT_ENDPOINT
));
2089 HeaderBuffer
= Endpoint
->HeaderBuffer
;
2091 Offset
= (ULONG_PTR
)PhysicalAddress
- HeaderBuffer
->PhysicalAddress
;
2092 VirtualAddress
= HeaderBuffer
->VirtualAddress
+ Offset
;
2094 return (PVOID
)VirtualAddress
;
2099 USBPORT_InvalidateEndpoint(IN PVOID Context1
,
2102 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2103 PDEVICE_OBJECT FdoDevice
;
2104 PUSBPORT_ENDPOINT Endpoint
;
2106 DPRINT_CORE("USBPORT_InvalidateEndpoint: ... \n");
2108 FdoExtension
= (PUSBPORT_DEVICE_EXTENSION
)((ULONG_PTR
)Context1
-
2109 sizeof(USBPORT_DEVICE_EXTENSION
));
2111 FdoDevice
= FdoExtension
->CommonExtension
.SelfDevice
;
2113 Endpoint
= (PUSBPORT_ENDPOINT
)((ULONG_PTR
)Context2
-
2114 sizeof(USBPORT_ENDPOINT
));
2118 USBPORT_InvalidateEndpointHandler(FdoDevice
,
2120 INVALIDATE_ENDPOINT_ONLY
);
2124 USBPORT_InvalidateEndpointHandler(FdoDevice
,
2126 INVALIDATE_ENDPOINT_ONLY
);
2134 USBPORT_CompleteTransfer(IN PURB Urb
,
2135 IN USBD_STATUS TransferStatus
)
2137 struct _URB_CONTROL_TRANSFER
*UrbTransfer
;
2138 PUSBPORT_TRANSFER Transfer
;
2143 BOOLEAN WriteToDevice
;
2144 BOOLEAN IsFlushSuccess
;
2146 ULONG_PTR CurrentVa
;
2147 SIZE_T TransferLength
;
2148 PUSBPORT_ENDPOINT Endpoint
;
2149 PDEVICE_OBJECT FdoDevice
;
2150 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2151 PDMA_OPERATIONS DmaOperations
;
2153 DPRINT("USBPORT_CompleteTransfer: Urb - %p, TransferStatus - %X\n",
2157 UrbTransfer
= &Urb
->UrbControlTransfer
;
2158 Transfer
= UrbTransfer
->hca
.Reserved8
[0];
2160 Transfer
->USBDStatus
= TransferStatus
;
2161 Status
= USBPORT_USBDStatusToNtStatus(Urb
, TransferStatus
);
2163 UrbTransfer
->TransferBufferLength
= Transfer
->CompletedTransferLen
;
2165 if (Transfer
->Flags
& TRANSFER_FLAG_DMA_MAPPED
)
2167 Endpoint
= Transfer
->Endpoint
;
2168 FdoDevice
= Endpoint
->FdoDevice
;
2169 FdoExtension
= FdoDevice
->DeviceExtension
;
2170 DmaOperations
= FdoExtension
->DmaAdapter
->DmaOperations
;
2172 WriteToDevice
= Transfer
->Direction
== USBPORT_DMA_DIRECTION_TO_DEVICE
;
2173 Mdl
= UrbTransfer
->TransferBufferMDL
;
2174 CurrentVa
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2175 TransferLength
= UrbTransfer
->TransferBufferLength
;
2177 IsFlushSuccess
= DmaOperations
->FlushAdapterBuffers(FdoExtension
->DmaAdapter
,
2179 Transfer
->MapRegisterBase
,
2184 if (!IsFlushSuccess
)
2186 DPRINT("USBPORT_CompleteTransfer: no FlushAdapterBuffers !!!\n");
2190 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
2192 DmaOperations
->FreeMapRegisters(FdoExtension
->DmaAdapter
,
2193 Transfer
->MapRegisterBase
,
2194 Transfer
->NumberOfMapRegisters
);
2196 KeLowerIrql(OldIrql
);
2199 if (Urb
->UrbHeader
.UsbdFlags
& USBD_FLAG_ALLOCATED_MDL
)
2201 IoFreeMdl(Transfer
->TransferBufferMDL
);
2202 Urb
->UrbHeader
.UsbdFlags
|= ~USBD_FLAG_ALLOCATED_MDL
;
2205 Urb
->UrbControlTransfer
.hca
.Reserved8
[0] = NULL
;
2206 Urb
->UrbHeader
.UsbdFlags
|= ~USBD_FLAG_ALLOCATED_TRANSFER
;
2208 Irp
= Transfer
->Irp
;
2212 if (!NT_SUCCESS(Status
))
2215 DPRINT1("USBPORT_CompleteTransfer: Irp - %p complete with Status - %lx\n",
2219 USBPORT_DumpingURB(Urb
);
2222 Irp
->IoStatus
.Status
= Status
;
2223 Irp
->IoStatus
.Information
= 0;
2225 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
2226 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2227 KeLowerIrql(OldIrql
);
2230 Event
= Transfer
->Event
;
2234 KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
2237 ExFreePoolWithTag(Transfer
, USB_PORT_TAG
);
2239 DPRINT_CORE("USBPORT_CompleteTransfer: exit\n");
2242 IO_ALLOCATION_ACTION
2244 USBPORT_MapTransfer(IN PDEVICE_OBJECT FdoDevice
,
2246 IN PVOID MapRegisterBase
,
2249 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2250 PDMA_ADAPTER DmaAdapter
;
2251 PUSBPORT_TRANSFER Transfer
;
2253 PUSBPORT_ENDPOINT Endpoint
;
2255 ULONG_PTR CurrentVa
;
2256 PUSBPORT_SCATTER_GATHER_LIST sgList
;
2257 SIZE_T CurrentLength
;
2259 BOOLEAN WriteToDevice
;
2260 PHYSICAL_ADDRESS PhAddr
= {{0, 0}};
2261 PHYSICAL_ADDRESS PhAddress
= {{0, 0}};
2262 SIZE_T TransferLength
;
2263 SIZE_T SgCurrentLength
;
2264 SIZE_T ElementLength
;
2265 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
2266 PDMA_OPERATIONS DmaOperations
;
2268 DPRINT_CORE("USBPORT_MapTransfer: ... \n");
2270 FdoExtension
= FdoDevice
->DeviceExtension
;
2271 DmaAdapter
= FdoExtension
->DmaAdapter
;
2272 DmaOperations
= DmaAdapter
->DmaOperations
;
2276 Urb
= Transfer
->Urb
;
2277 Endpoint
= Transfer
->Endpoint
;
2278 TransferLength
= Transfer
->TransferParameters
.TransferBufferLength
;
2280 Mdl
= Urb
->UrbControlTransfer
.TransferBufferMDL
;
2281 CurrentVa
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2283 Transfer
->SgList
.CurrentVa
= CurrentVa
;
2284 Transfer
->SgList
.MappedSystemVa
= MmGetSystemAddressForMdlSafe(Mdl
, NormalPagePriority
);
2286 sgList
= &Transfer
->SgList
;
2289 Transfer
->MapRegisterBase
= MapRegisterBase
;
2296 WriteToDevice
= Transfer
->Direction
== USBPORT_DMA_DIRECTION_TO_DEVICE
;
2297 ASSERT(Transfer
->Direction
!= 0);
2299 PhAddress
= DmaOperations
->MapTransfer(DmaAdapter
,
2306 DPRINT_CORE("USBPORT_MapTransfer: PhAddress.LowPart - %p, PhAddress.HighPart - %x, TransferLength - %x\n",
2311 PhAddress
.HighPart
= 0;
2312 SgCurrentLength
= TransferLength
;
2316 ElementLength
= 0x1000 - (PhAddress
.LowPart
& 0xFFF);
2318 if (ElementLength
> SgCurrentLength
)
2319 ElementLength
= SgCurrentLength
;
2321 DPRINT_CORE("USBPORT_MapTransfer: PhAddress.LowPart - %p, HighPart - %x, ElementLength - %x\n",
2326 sgList
->SgElement
[ix
].SgPhysicalAddress
= PhAddress
;
2327 sgList
->SgElement
[ix
].SgTransferLength
= ElementLength
;
2328 sgList
->SgElement
[ix
].SgOffset
= CurrentLength
+
2329 (TransferLength
- SgCurrentLength
);
2331 PhAddress
.LowPart
+= ElementLength
;
2332 SgCurrentLength
-= ElementLength
;
2336 while (SgCurrentLength
);
2338 if ((PhAddr
.LowPart
== PhAddress
.LowPart
) &&
2339 (PhAddr
.HighPart
== PhAddress
.HighPart
))
2346 CurrentLength
+= TransferLength
;
2347 CurrentVa
+= TransferLength
;
2349 TransferLength
= Transfer
->TransferParameters
.TransferBufferLength
-
2352 while (CurrentLength
!= Transfer
->TransferParameters
.TransferBufferLength
);
2354 Transfer
->SgList
.SgElementCount
= ix
;
2355 Transfer
->Flags
|= TRANSFER_FLAG_DMA_MAPPED
;
2357 ASSERT(Transfer
->TransferParameters
.TransferBufferLength
<=
2358 Endpoint
->EndpointProperties
.MaxTransferSize
);
2360 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
2361 InsertTailList(&Endpoint
->TransferList
, &Transfer
->TransferLink
);
2362 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
2364 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
2365 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
2367 if (USBPORT_EndpointWorker(Endpoint
, 0))
2369 USBPORT_InvalidateEndpointHandler(FdoDevice
,
2371 INVALIDATE_ENDPOINT_WORKER_THREAD
);
2374 return DeallocateObjectKeepRegisters
;
2379 USBPORT_FlushMapTransfers(IN PDEVICE_OBJECT FdoDevice
)
2381 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2382 PLIST_ENTRY MapTransferList
;
2383 PUSBPORT_TRANSFER Transfer
;
2384 ULONG NumMapRegisters
;
2386 SIZE_T TransferBufferLength
;
2387 ULONG_PTR VirtualAddr
;
2390 PDMA_OPERATIONS DmaOperations
;
2392 DPRINT_CORE("USBPORT_FlushMapTransfers: ... \n");
2394 FdoExtension
= FdoDevice
->DeviceExtension
;
2395 DmaOperations
= FdoExtension
->DmaAdapter
->DmaOperations
;
2397 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
2401 MapTransferList
= &FdoExtension
->MapTransferList
;
2403 if (IsListEmpty(&FdoExtension
->MapTransferList
))
2405 KeLowerIrql(OldIrql
);
2409 Transfer
= CONTAINING_RECORD(MapTransferList
->Flink
,
2413 RemoveHeadList(MapTransferList
);
2415 Mdl
= Transfer
->Urb
->UrbControlTransfer
.TransferBufferMDL
;
2416 TransferBufferLength
= Transfer
->TransferParameters
.TransferBufferLength
;
2417 VirtualAddr
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2419 NumMapRegisters
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddr
,
2420 TransferBufferLength
);
2422 Transfer
->NumberOfMapRegisters
= NumMapRegisters
;
2424 Status
= DmaOperations
->AllocateAdapterChannel(FdoExtension
->DmaAdapter
,
2427 USBPORT_MapTransfer
,
2430 if (!NT_SUCCESS(Status
))
2434 KeLowerIrql(OldIrql
);
2439 USBPORT_AllocateTransfer(IN PDEVICE_OBJECT FdoDevice
,
2441 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
2445 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2446 SIZE_T TransferLength
;
2448 ULONG_PTR VirtualAddr
;
2449 ULONG PagesNeed
= 0;
2450 SIZE_T PortTransferLength
;
2451 SIZE_T FullTransferLength
;
2452 PUSBPORT_TRANSFER Transfer
;
2453 PUSBPORT_PIPE_HANDLE PipeHandle
;
2454 USBD_STATUS USBDStatus
;
2456 DPRINT_CORE("USBPORT_AllocateTransfer: FdoDevice - %p, Urb - %p, DeviceHandle - %p, Irp - %p, Event - %p\n",
2463 FdoExtension
= FdoDevice
->DeviceExtension
;
2465 TransferLength
= Urb
->UrbControlTransfer
.TransferBufferLength
;
2466 PipeHandle
= Urb
->UrbControlTransfer
.PipeHandle
;
2470 Mdl
= Urb
->UrbControlTransfer
.TransferBufferMDL
;
2471 VirtualAddr
= (ULONG_PTR
)MmGetMdlVirtualAddress(Mdl
);
2473 PagesNeed
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddr
,
2477 if (Urb
->UrbHeader
.Function
== URB_FUNCTION_ISOCH_TRANSFER
)
2479 DPRINT1("USBPORT_AllocateTransfer: ISOCH_TRANSFER UNIMPLEMENTED. FIXME.\n");
2482 PortTransferLength
= sizeof(USBPORT_TRANSFER
) +
2483 PagesNeed
* sizeof(USBPORT_SCATTER_GATHER_ELEMENT
);
2485 FullTransferLength
= PortTransferLength
+
2486 FdoExtension
->MiniPortInterface
->Packet
.MiniPortTransferSize
;
2488 Transfer
= ExAllocatePoolWithTag(NonPagedPool
,
2494 RtlZeroMemory(Transfer
, FullTransferLength
);
2496 Transfer
->Irp
= Irp
;
2497 Transfer
->Urb
= Urb
;
2498 Transfer
->Endpoint
= PipeHandle
->Endpoint
;
2499 Transfer
->Event
= Event
;
2500 Transfer
->PortTransferLength
= PortTransferLength
;
2501 Transfer
->FullTransferLength
= FullTransferLength
;
2503 Transfer
->MiniportTransfer
= (PVOID
)((ULONG_PTR
)Transfer
+
2504 PortTransferLength
);
2506 Urb
->UrbControlTransfer
.hca
.Reserved8
[0] = Transfer
;
2507 Urb
->UrbHeader
.UsbdFlags
|= USBD_FLAG_ALLOCATED_TRANSFER
;
2509 USBDStatus
= USBD_STATUS_SUCCESS
;
2513 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
2516 DPRINT_CORE("USBPORT_AllocateTransfer: return USBDStatus - %x\n",
2524 USBPORT_Dispatch(IN PDEVICE_OBJECT DeviceObject
,
2527 PUSBPORT_COMMON_DEVICE_EXTENSION DeviceExtension
;
2528 PIO_STACK_LOCATION IoStack
;
2529 NTSTATUS Status
= STATUS_SUCCESS
;
2531 DeviceExtension
= DeviceObject
->DeviceExtension
;
2532 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2534 if (DeviceExtension
->PnpStateFlags
& USBPORT_PNP_STATE_FAILED
)
2536 DPRINT1("USBPORT_Dispatch: USBPORT_PNP_STATE_FAILED\n");
2540 switch (IoStack
->MajorFunction
)
2542 case IRP_MJ_DEVICE_CONTROL
:
2543 if (DeviceExtension
->IsPDO
)
2545 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2546 IoStack
->MajorFunction
,
2547 IoStack
->MinorFunction
);
2549 Status
= USBPORT_PdoDeviceControl(DeviceObject
, Irp
);
2553 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2554 IoStack
->MajorFunction
,
2555 IoStack
->MinorFunction
);
2557 Status
= USBPORT_FdoDeviceControl(DeviceObject
, Irp
);
2562 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
2563 if (DeviceExtension
->IsPDO
)
2565 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_INTERNAL_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2566 IoStack
->MajorFunction
,
2567 IoStack
->MinorFunction
);
2569 Status
= USBPORT_PdoInternalDeviceControl(DeviceObject
, Irp
);
2573 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_INTERNAL_DEVICE_CONTROL. Major - %d, Minor - %d\n",
2574 IoStack
->MajorFunction
,
2575 IoStack
->MinorFunction
);
2577 Status
= USBPORT_FdoInternalDeviceControl(DeviceObject
, Irp
);
2583 if (DeviceExtension
->IsPDO
)
2585 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_POWER. Major - %d, Minor - %d\n",
2586 IoStack
->MajorFunction
,
2587 IoStack
->MinorFunction
);
2589 Status
= USBPORT_PdoPower(DeviceObject
, Irp
);
2593 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_POWER. Major - %d, Minor - %d\n",
2594 IoStack
->MajorFunction
,
2595 IoStack
->MinorFunction
);
2597 Status
= USBPORT_FdoPower(DeviceObject
, Irp
);
2602 case IRP_MJ_SYSTEM_CONTROL
:
2603 if (DeviceExtension
->IsPDO
)
2605 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_SYSTEM_CONTROL. Major - %d, Minor - %d\n",
2606 IoStack
->MajorFunction
,
2607 IoStack
->MinorFunction
);
2609 Irp
->IoStatus
.Status
= Status
;
2610 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2614 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_SYSTEM_CONTROL. Major - %d, Minor - %d\n",
2615 IoStack
->MajorFunction
,
2616 IoStack
->MinorFunction
);
2618 IoSkipCurrentIrpStackLocation(Irp
);
2619 Status
= IoCallDriver(DeviceExtension
->LowerDevice
, Irp
);
2625 if (DeviceExtension
->IsPDO
)
2627 DPRINT("USBPORT_Dispatch: PDO IRP_MJ_PNP. Major - %d, Minor - %d\n",
2628 IoStack
->MajorFunction
,
2629 IoStack
->MinorFunction
);
2631 Status
= USBPORT_PdoPnP(DeviceObject
, Irp
);
2635 DPRINT("USBPORT_Dispatch: FDO IRP_MJ_PNP. Major - %d, Minor - %d\n",
2636 IoStack
->MajorFunction
,
2637 IoStack
->MinorFunction
);
2639 Status
= USBPORT_FdoPnP(DeviceObject
, Irp
);
2646 DPRINT("USBPORT_Dispatch: IRP_MJ_CREATE | IRP_MJ_CLOSE\n");
2647 Irp
->IoStatus
.Status
= Status
;
2648 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2652 if (DeviceExtension
->IsPDO
)
2654 DPRINT("USBPORT_Dispatch: PDO unhandled IRP_MJ_???. Major - %d, Minor - %d\n",
2655 IoStack
->MajorFunction
,
2656 IoStack
->MinorFunction
);
2660 DPRINT("USBPORT_Dispatch: FDO unhandled IRP_MJ_???. Major - %d, Minor - %d\n",
2661 IoStack
->MajorFunction
,
2662 IoStack
->MinorFunction
);
2665 Status
= STATUS_INVALID_DEVICE_REQUEST
;
2666 Irp
->IoStatus
.Status
= Status
;
2667 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2671 DPRINT("USBPORT_Dispatch: Status - %x\n", Status
);
2677 USBPORT_GetHciMn(VOID
)
2679 return USBPORT_HCI_MN
;
2684 USBPORT_RegisterUSBPortDriver(IN PDRIVER_OBJECT DriverObject
,
2686 IN PUSBPORT_REGISTRATION_PACKET RegPacket
)
2688 PUSBPORT_MINIPORT_INTERFACE MiniPortInterface
;
2690 DPRINT("USBPORT_RegisterUSBPortDriver: DriverObject - %p, Version - %p, RegPacket - %p\n",
2695 DPRINT("USBPORT_RegisterUSBPortDriver: sizeof(USBPORT_MINIPORT_INTERFACE) - %x\n",
2696 sizeof(USBPORT_MINIPORT_INTERFACE
));
2698 DPRINT("USBPORT_RegisterUSBPortDriver: sizeof(USBPORT_DEVICE_EXTENSION) - %x\n",
2699 sizeof(USBPORT_DEVICE_EXTENSION
));
2701 if (Version
< 100) // 100 - USB1.1; 200 - USB2.0
2703 return STATUS_UNSUCCESSFUL
;
2706 if (!USBPORT_Initialized
)
2708 InitializeListHead(&USBPORT_MiniPortDrivers
);
2709 InitializeListHead(&USBPORT_USB1FdoList
);
2710 InitializeListHead(&USBPORT_USB2FdoList
);
2712 KeInitializeSpinLock(&USBPORT_SpinLock
);
2713 USBPORT_Initialized
= TRUE
;
2716 MiniPortInterface
= ExAllocatePoolWithTag(NonPagedPool
,
2717 sizeof(USBPORT_MINIPORT_INTERFACE
),
2719 if (!MiniPortInterface
)
2721 return STATUS_INSUFFICIENT_RESOURCES
;
2724 RtlZeroMemory(MiniPortInterface
, sizeof(USBPORT_MINIPORT_INTERFACE
));
2726 MiniPortInterface
->DriverObject
= DriverObject
;
2727 MiniPortInterface
->DriverUnload
= DriverObject
->DriverUnload
;
2728 MiniPortInterface
->Version
= Version
;
2730 ExInterlockedInsertTailList(&USBPORT_MiniPortDrivers
,
2731 &MiniPortInterface
->DriverLink
,
2734 DriverObject
->DriverExtension
->AddDevice
= USBPORT_AddDevice
;
2735 DriverObject
->DriverUnload
= USBPORT_Unload
;
2737 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = USBPORT_Dispatch
;
2738 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = USBPORT_Dispatch
;
2739 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = USBPORT_Dispatch
;
2740 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = USBPORT_Dispatch
;
2741 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = USBPORT_Dispatch
;
2742 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = USBPORT_Dispatch
;
2743 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = USBPORT_Dispatch
;
2745 RegPacket
->UsbPortDbgPrint
= USBPORT_DbgPrint
;
2746 RegPacket
->UsbPortTestDebugBreak
= USBPORT_TestDebugBreak
;
2747 RegPacket
->UsbPortAssertFailure
= USBPORT_AssertFailure
;
2748 RegPacket
->UsbPortGetMiniportRegistryKeyValue
= USBPORT_GetMiniportRegistryKeyValue
;
2749 RegPacket
->UsbPortInvalidateRootHub
= USBPORT_InvalidateRootHub
;
2750 RegPacket
->UsbPortInvalidateEndpoint
= USBPORT_InvalidateEndpoint
;
2751 RegPacket
->UsbPortCompleteTransfer
= USBPORT_MiniportCompleteTransfer
;
2752 RegPacket
->UsbPortCompleteIsoTransfer
= USBPORT_CompleteIsoTransfer
;
2753 RegPacket
->UsbPortLogEntry
= USBPORT_LogEntry
;
2754 RegPacket
->UsbPortGetMappedVirtualAddress
= USBPORT_GetMappedVirtualAddress
;
2755 RegPacket
->UsbPortRequestAsyncCallback
= USBPORT_RequestAsyncCallback
;
2756 RegPacket
->UsbPortReadWriteConfigSpace
= USBPORT_ReadWriteConfigSpace
;
2757 RegPacket
->UsbPortWait
= USBPORT_Wait
;
2758 RegPacket
->UsbPortInvalidateController
= USBPORT_InvalidateController
;
2759 RegPacket
->UsbPortBugCheck
= USBPORT_BugCheck
;
2760 RegPacket
->UsbPortNotifyDoubleBuffer
= USBPORT_NotifyDoubleBuffer
;
2762 RtlCopyMemory(&MiniPortInterface
->Packet
,
2764 sizeof(USBPORT_REGISTRATION_PACKET
));
2766 return STATUS_SUCCESS
;
2771 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
2772 IN PUNICODE_STRING RegistryPath
)
2774 return STATUS_SUCCESS
;