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