1 /* 2 * PROJECT: ReactOS USB Port Driver 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: USBPort queue implementation 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_QUEUE 15 #define NDEBUG_USBPORT_URB 16 #include "usbdebug.h" 17 18 VOID 19 NTAPI 20 USBPORT_InsertIdleIrp(IN PIO_CSQ Csq, 21 IN PIRP Irp) 22 { 23 PUSBPORT_DEVICE_EXTENSION FdoExtension; 24 25 DPRINT_QUEUE("USBPORT_InsertIdleIrp: Irp - %p\n", Irp); 26 27 FdoExtension = CONTAINING_RECORD(Csq, 28 USBPORT_DEVICE_EXTENSION, 29 IdleIoCsq); 30 31 InsertTailList(&FdoExtension->IdleIrpList, 32 &Irp->Tail.Overlay.ListEntry); 33 } 34 35 VOID 36 NTAPI 37 USBPORT_RemoveIdleIrp(IN PIO_CSQ Csq, 38 IN PIRP Irp) 39 { 40 DPRINT_QUEUE("USBPORT_RemoveIdleIrp: Irp - %p\n", Irp); 41 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 42 } 43 44 PIRP 45 NTAPI 46 USBPORT_PeekNextIdleIrp(IN PIO_CSQ Csq, 47 IN PIRP Irp, 48 IN PVOID PeekContext) 49 { 50 PUSBPORT_DEVICE_EXTENSION FdoExtension; 51 PLIST_ENTRY NextEntry; 52 PLIST_ENTRY ListHead; 53 PIRP NextIrp = NULL; 54 55 DPRINT_QUEUE("USBPORT_PeekNextIdleIrp: Irp - %p, PeekContext - %p\n", 56 Irp, 57 PeekContext); 58 59 FdoExtension = CONTAINING_RECORD(Csq, 60 USBPORT_DEVICE_EXTENSION, 61 IdleIoCsq); 62 63 ListHead = &FdoExtension->IdleIrpList; 64 65 if (Irp) 66 { 67 NextEntry = Irp->Tail.Overlay.ListEntry.Flink; 68 } 69 else 70 { 71 NextEntry = ListHead->Flink; 72 } 73 74 while (NextEntry != ListHead) 75 { 76 NextIrp = CONTAINING_RECORD(NextEntry, 77 IRP, 78 Tail.Overlay.ListEntry); 79 80 if (!PeekContext) 81 break; 82 83 NextEntry = NextEntry->Flink; 84 } 85 86 return NextIrp; 87 } 88 89 VOID 90 NTAPI 91 USBPORT_AcquireIdleLock(IN PIO_CSQ Csq, 92 IN PKIRQL Irql) 93 { 94 PUSBPORT_DEVICE_EXTENSION FdoExtension; 95 96 DPRINT_QUEUE("USBPORT_AcquireIdleLock: ... \n"); 97 98 FdoExtension = CONTAINING_RECORD(Csq, 99 USBPORT_DEVICE_EXTENSION, 100 IdleIoCsq); 101 102 KeAcquireSpinLock(&FdoExtension->IdleIoCsqSpinLock, Irql); 103 } 104 105 VOID 106 NTAPI 107 USBPORT_ReleaseIdleLock(IN PIO_CSQ Csq, 108 IN KIRQL Irql) 109 { 110 PUSBPORT_DEVICE_EXTENSION FdoExtension; 111 112 DPRINT_QUEUE("USBPORT_ReleaseIdleLock: ... \n"); 113 114 FdoExtension = CONTAINING_RECORD(Csq, 115 USBPORT_DEVICE_EXTENSION, 116 IdleIoCsq); 117 118 KeReleaseSpinLock(&FdoExtension->IdleIoCsqSpinLock, Irql); 119 } 120 121 VOID 122 NTAPI 123 USBPORT_CompleteCanceledIdleIrp(IN PIO_CSQ Csq, 124 IN PIRP Irp) 125 { 126 PUSBPORT_DEVICE_EXTENSION FdoExtension; 127 128 DPRINT_QUEUE("USBPORT_CompleteCanceledIdleIrp: ... \n"); 129 130 FdoExtension = CONTAINING_RECORD(Csq, 131 USBPORT_DEVICE_EXTENSION, 132 IdleIoCsq); 133 134 InterlockedDecrement(&FdoExtension->IdleLockCounter); 135 136 Irp->IoStatus.Status = STATUS_CANCELLED; 137 Irp->IoStatus.Information = 0; 138 IoCompleteRequest(Irp, IO_NO_INCREMENT); 139 } 140 141 VOID 142 NTAPI 143 USBPORT_InsertBadRequest(IN PIO_CSQ Csq, 144 IN PIRP Irp) 145 { 146 PUSBPORT_DEVICE_EXTENSION FdoExtension; 147 148 DPRINT_QUEUE("USBPORT_InsertBadRequest: Irp - %p\n", Irp); 149 150 FdoExtension = CONTAINING_RECORD(Csq, 151 USBPORT_DEVICE_EXTENSION, 152 BadRequestIoCsq); 153 154 InsertTailList(&FdoExtension->BadRequestList, 155 &Irp->Tail.Overlay.ListEntry); 156 } 157 158 VOID 159 NTAPI 160 USBPORT_RemoveBadRequest(IN PIO_CSQ Csq, 161 IN PIRP Irp) 162 { 163 DPRINT_QUEUE("USBPORT_RemoveBadRequest: Irp - %p\n", Irp); 164 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 165 } 166 167 PIRP 168 NTAPI 169 USBPORT_PeekNextBadRequest(IN PIO_CSQ Csq, 170 IN PIRP Irp, 171 IN PVOID PeekContext) 172 { 173 PUSBPORT_DEVICE_EXTENSION FdoExtension; 174 PLIST_ENTRY NextEntry; 175 PLIST_ENTRY ListHead; 176 PIRP NextIrp = NULL; 177 178 DPRINT_QUEUE("USBPORT_PeekNextBadRequest: Irp - %p, PeekContext - %p\n", 179 Irp, 180 PeekContext); 181 182 FdoExtension = CONTAINING_RECORD(Csq, 183 USBPORT_DEVICE_EXTENSION, 184 BadRequestIoCsq); 185 186 ListHead = &FdoExtension->BadRequestList; 187 188 if (Irp) 189 { 190 NextEntry = Irp->Tail.Overlay.ListEntry.Flink; 191 } 192 else 193 { 194 NextEntry = ListHead->Flink; 195 } 196 197 while (NextEntry != ListHead) 198 { 199 NextIrp = CONTAINING_RECORD(NextEntry, 200 IRP, 201 Tail.Overlay.ListEntry); 202 203 if (!PeekContext) 204 break; 205 206 NextEntry = NextEntry->Flink; 207 } 208 209 return NextIrp; 210 } 211 212 VOID 213 NTAPI 214 USBPORT_AcquireBadRequestLock(IN PIO_CSQ Csq, 215 IN PKIRQL Irql) 216 { 217 PUSBPORT_DEVICE_EXTENSION FdoExtension; 218 219 DPRINT_QUEUE("USBPORT_AcquireBadRequestLock: ... \n"); 220 221 FdoExtension = CONTAINING_RECORD(Csq, 222 USBPORT_DEVICE_EXTENSION, 223 BadRequestIoCsq); 224 225 KeAcquireSpinLock(&FdoExtension->BadRequestIoCsqSpinLock, Irql); 226 } 227 228 VOID 229 NTAPI 230 USBPORT_ReleaseBadRequestLock(IN PIO_CSQ Csq, 231 IN KIRQL Irql) 232 { 233 PUSBPORT_DEVICE_EXTENSION FdoExtension; 234 235 DPRINT_QUEUE("USBPORT_ReleaseBadRequestLock: ... \n"); 236 237 FdoExtension = CONTAINING_RECORD(Csq, 238 USBPORT_DEVICE_EXTENSION, 239 BadRequestIoCsq); 240 241 KeReleaseSpinLock(&FdoExtension->BadRequestIoCsqSpinLock, Irql); 242 } 243 244 VOID 245 NTAPI 246 USBPORT_CompleteCanceledBadRequest(IN PIO_CSQ Csq, 247 IN PIRP Irp) 248 { 249 PUSBPORT_DEVICE_EXTENSION FdoExtension; 250 251 DPRINT_QUEUE("USBPORT_CompleteCanceledBadRequest: Irp - %p\n", Irp); 252 253 FdoExtension = CONTAINING_RECORD(Csq, 254 USBPORT_DEVICE_EXTENSION, 255 BadRequestIoCsq); 256 257 InterlockedDecrement(&FdoExtension->BadRequestLockCounter); 258 259 Irp->IoStatus.Status = STATUS_CANCELLED; 260 Irp->IoStatus.Information = 0; 261 IoCompleteRequest(Irp, IO_NO_INCREMENT); 262 } 263 264 VOID 265 NTAPI 266 USBPORT_InsertIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable, 267 IN PIRP Irp) 268 { 269 ULONG ix; 270 271 DPRINT_CORE("USBPORT_InsertIrpInTable: IrpTable - %p, Irp - %p\n", 272 IrpTable, 273 Irp); 274 275 ASSERT(IrpTable != NULL); 276 277 while (TRUE) 278 { 279 for (ix = 0; ix < 0x200; ix++) 280 { 281 if (IrpTable->irp[ix] == NULL) 282 { 283 IrpTable->irp[ix] = Irp; 284 285 if (ix > 0) 286 { 287 DPRINT_CORE("USBPORT_InsertIrpInTable: ix - %x\n", ix); 288 } 289 290 return; 291 } 292 } 293 294 if (ix != 0x200) 295 { 296 KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0); 297 } 298 299 IrpTable->LinkNextTable = ExAllocatePoolWithTag(NonPagedPool, 300 sizeof(USBPORT_IRP_TABLE), 301 USB_PORT_TAG); 302 303 if (IrpTable->LinkNextTable == NULL) 304 { 305 KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0); 306 } 307 308 RtlZeroMemory(IrpTable->LinkNextTable, sizeof(USBPORT_IRP_TABLE)); 309 310 IrpTable = IrpTable->LinkNextTable; 311 } 312 } 313 314 PIRP 315 NTAPI 316 USBPORT_RemoveIrpFromTable(IN PUSBPORT_IRP_TABLE IrpTable, 317 IN PIRP Irp) 318 { 319 ULONG ix; 320 321 DPRINT_CORE("USBPORT_RemoveIrpFromTable: IrpTable - %p, Irp - %p\n", 322 IrpTable, 323 Irp); 324 325 ASSERT(IrpTable != NULL); 326 327 while (TRUE) 328 { 329 for (ix = 0; ix < 0x200; ix++) 330 { 331 if (IrpTable->irp[ix] == Irp) 332 { 333 IrpTable->irp[ix] = NULL; 334 335 if (ix > 0) 336 { 337 DPRINT_CORE("USBPORT_RemoveIrpFromTable: ix - %x\n", ix); 338 } 339 340 return Irp; 341 } 342 } 343 344 if (IrpTable->LinkNextTable == NULL) 345 break; 346 347 IrpTable = IrpTable->LinkNextTable; 348 continue; 349 } 350 351 DPRINT1("USBPORT_RemoveIrpFromTable: return NULL. ix - %x\n", ix); 352 return NULL; 353 } 354 355 PIRP 356 NTAPI 357 USBPORT_RemoveActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice, 358 IN PIRP Irp) 359 { 360 PUSBPORT_DEVICE_EXTENSION FdoExtension; 361 362 DPRINT_CORE("USBPORT_RemoveActiveTransferIrp: Irp - %p\n", Irp); 363 FdoExtension = FdoDevice->DeviceExtension; 364 return USBPORT_RemoveIrpFromTable(FdoExtension->ActiveIrpTable, Irp); 365 } 366 367 PIRP 368 NTAPI 369 USBPORT_RemovePendingTransferIrp(IN PDEVICE_OBJECT FdoDevice, 370 IN PIRP Irp) 371 { 372 PUSBPORT_DEVICE_EXTENSION FdoExtension; 373 374 DPRINT_CORE("USBPORT_RemovePendingTransferIrp: Irp - %p\n", Irp); 375 FdoExtension = FdoDevice->DeviceExtension; 376 return USBPORT_RemoveIrpFromTable(FdoExtension->PendingIrpTable, Irp); 377 } 378 379 VOID 380 NTAPI 381 USBPORT_FindUrbInIrpTable(IN PUSBPORT_IRP_TABLE IrpTable, 382 IN PURB Urb, 383 IN PIRP Irp) 384 { 385 ULONG ix; 386 PIRP irp; 387 PURB urbIn; 388 389 DPRINT_CORE("USBPORT_FindUrbInIrpTable: IrpTable - %p, Urb - %p, Irp - %p\n", 390 IrpTable, 391 Urb, 392 Irp); 393 394 ASSERT(IrpTable != NULL); 395 396 do 397 { 398 for (ix = 0; ix < 0x200; ix++) 399 { 400 irp = IrpTable->irp[ix]; 401 402 if (irp) 403 { 404 urbIn = URB_FROM_IRP(irp); 405 406 if (urbIn == Urb) 407 { 408 if (irp == Irp) 409 { 410 KeBugCheckEx(BUGCODE_USB_DRIVER, 411 4, 412 (ULONG_PTR)irp, 413 (ULONG_PTR)urbIn, 414 0); 415 } 416 417 KeBugCheckEx(BUGCODE_USB_DRIVER, 418 2, 419 (ULONG_PTR)irp, 420 (ULONG_PTR)Irp, 421 (ULONG_PTR)urbIn); 422 } 423 } 424 } 425 426 IrpTable = IrpTable->LinkNextTable; 427 } 428 while (IrpTable); 429 } 430 431 PIRP 432 NTAPI 433 USBPORT_FindIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable, 434 IN PIRP Irp) 435 { 436 ULONG ix; 437 PIRP irp; 438 439 DPRINT_CORE("USBPORT_FindIrpInTable: IrpTable - %p, Irp - %p\n", 440 IrpTable, 441 Irp); 442 443 ASSERT(IrpTable != NULL); 444 445 do 446 { 447 for (ix = 0; ix < 0x200; ix++) 448 { 449 irp = IrpTable->irp[ix]; 450 451 if (irp && irp == Irp) 452 { 453 return irp; 454 } 455 } 456 457 IrpTable = IrpTable->LinkNextTable; 458 } 459 while (IrpTable->LinkNextTable); 460 461 DPRINT_CORE("USBPORT_FindIrpInTable: Not found!!!\n"); 462 return NULL; 463 } 464 465 PIRP 466 NTAPI 467 USBPORT_FindActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice, 468 IN PIRP Irp) 469 { 470 PUSBPORT_DEVICE_EXTENSION FdoExtension; 471 472 DPRINT_CORE("USBPORT_FindActiveTransferIrp: Irp - %p\n", Irp); 473 FdoExtension = FdoDevice->DeviceExtension; 474 return USBPORT_FindIrpInTable(FdoExtension->ActiveIrpTable, Irp); 475 } 476 477 VOID 478 NTAPI 479 USBPORT_CancelPendingTransferIrp(IN PDEVICE_OBJECT DeviceObject, 480 IN PIRP Irp) 481 { 482 PURB Urb; 483 PUSBPORT_TRANSFER Transfer; 484 PUSBPORT_ENDPOINT Endpoint; 485 PDEVICE_OBJECT FdoDevice; 486 PUSBPORT_DEVICE_EXTENSION FdoExtension; 487 KIRQL OldIrql; 488 PIRP irp; 489 490 DPRINT_CORE("USBPORT_CancelPendingTransferIrp: DeviceObject - %p, Irp - %p\n", 491 DeviceObject, 492 Irp); 493 494 Urb = URB_FROM_IRP(Irp); 495 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0]; 496 Endpoint = Transfer->Endpoint; 497 498 FdoDevice = Endpoint->FdoDevice; 499 FdoExtension = DeviceObject->DeviceExtension; 500 501 IoReleaseCancelSpinLock(Irp->CancelIrql); 502 503 KeAcquireSpinLock(&FdoExtension->FlushPendingTransferSpinLock, &OldIrql); 504 505 irp = USBPORT_RemovePendingTransferIrp(FdoDevice, Irp); 506 507 if (!irp) 508 { 509 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, 510 OldIrql); 511 return; 512 } 513 514 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock); 515 516 RemoveEntryList(&Transfer->TransferLink); 517 518 Transfer->TransferLink.Flink = NULL; 519 Transfer->TransferLink.Blink = NULL; 520 521 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 522 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, OldIrql); 523 524 USBPORT_CompleteTransfer(Transfer->Urb, USBD_STATUS_CANCELED); 525 } 526 527 VOID 528 NTAPI 529 USBPORT_CancelActiveTransferIrp(IN PDEVICE_OBJECT DeviceObject, 530 IN PIRP Irp) 531 { 532 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 533 PDEVICE_OBJECT FdoDevice; 534 PUSBPORT_DEVICE_EXTENSION FdoExtension; 535 PURB Urb; 536 PUSBPORT_TRANSFER Transfer; 537 PUSBPORT_ENDPOINT Endpoint; 538 PIRP irp; 539 PUSBPORT_TRANSFER SplitTransfer; 540 PLIST_ENTRY Entry; 541 KIRQL OldIrql; 542 543 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: Irp - %p\n", Irp); 544 545 PdoExtension = DeviceObject->DeviceExtension; 546 FdoDevice = PdoExtension->FdoDevice; 547 FdoExtension = FdoDevice->DeviceExtension; 548 549 IoReleaseCancelSpinLock(Irp->CancelIrql); 550 551 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql); 552 553 irp = USBPORT_FindActiveTransferIrp(FdoDevice, Irp); 554 555 if (!irp) 556 { 557 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql); 558 return; 559 } 560 561 Urb = URB_FROM_IRP(irp); 562 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0]; 563 Endpoint = Transfer->Endpoint; 564 565 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: irp - %p, Urb - %p, Transfer - %p\n", 566 irp, 567 Urb, 568 Transfer); 569 570 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock); 571 572 Transfer->Flags |= TRANSFER_FLAG_CANCELED; 573 574 if (Transfer->Flags & TRANSFER_FLAG_PARENT) 575 { 576 KeAcquireSpinLockAtDpcLevel(&Transfer->TransferSpinLock); 577 578 Entry = Transfer->SplitTransfersList.Flink; 579 580 while (Entry && Entry != &Transfer->SplitTransfersList) 581 { 582 SplitTransfer = CONTAINING_RECORD(Entry, 583 USBPORT_TRANSFER, 584 SplitLink); 585 586 SplitTransfer->Flags |= TRANSFER_FLAG_CANCELED; 587 588 Entry = Entry->Flink; 589 } 590 591 KeReleaseSpinLockFromDpcLevel(&Transfer->TransferSpinLock); 592 } 593 594 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 595 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql); 596 597 USBPORT_InvalidateEndpointHandler(FdoDevice, 598 Endpoint, 599 INVALIDATE_ENDPOINT_WORKER_THREAD); 600 return; 601 } 602 603 VOID 604 NTAPI 605 USBPORT_FlushAbortList(IN PUSBPORT_ENDPOINT Endpoint) 606 { 607 PLIST_ENTRY Entry; 608 PUSBPORT_TRANSFER Transfer; 609 PLIST_ENTRY AbortList; 610 LIST_ENTRY List; 611 NTSTATUS Status; 612 PIRP Irp; 613 PURB Urb; 614 PUSBPORT_DEVICE_HANDLE DeviceHandle = NULL; 615 616 DPRINT_CORE("USBPORT_FlushAbortList: Endpoint - %p\n", Endpoint); 617 618 InitializeListHead(&List); 619 620 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql); 621 622 if (IsListEmpty(&Endpoint->AbortList)) 623 { 624 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 625 Endpoint->EndpointOldIrql); 626 return; 627 } 628 629 Entry = Endpoint->PendingTransferList.Flink; 630 631 while (Entry && Entry != &Endpoint->PendingTransferList) 632 { 633 Transfer = CONTAINING_RECORD(Entry, 634 USBPORT_TRANSFER, 635 TransferLink); 636 637 if (Transfer->Flags & TRANSFER_FLAG_ABORTED) 638 { 639 DPRINT_CORE("USBPORT_FlushAbortList: Aborted PendingTransfer - %p\n", 640 Transfer); 641 642 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 643 Endpoint->EndpointOldIrql); 644 return; 645 } 646 647 Entry = Transfer->TransferLink.Flink; 648 } 649 650 Entry = Endpoint->TransferList.Flink; 651 652 while (Entry && Entry != &Endpoint->TransferList) 653 { 654 Transfer = CONTAINING_RECORD(Entry, 655 USBPORT_TRANSFER, 656 TransferLink); 657 658 if (Transfer->Flags & TRANSFER_FLAG_ABORTED) 659 { 660 DPRINT_CORE("USBPORT_FlushAbortList: Aborted ActiveTransfer - %p\n", 661 Transfer); 662 663 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 664 Endpoint->EndpointOldIrql); 665 return; 666 } 667 668 Entry = Transfer->TransferLink.Flink; 669 } 670 671 AbortList = &Endpoint->AbortList; 672 673 while (!IsListEmpty(AbortList)) 674 { 675 //DbgBreakPoint(); 676 677 Irp = CONTAINING_RECORD(AbortList->Flink, 678 IRP, 679 Tail.Overlay.ListEntry); 680 681 RemoveHeadList(AbortList); 682 InsertTailList(&List, &Irp->Tail.Overlay.ListEntry); 683 } 684 685 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql); 686 687 while (!IsListEmpty(&List)) 688 { 689 //DbgBreakPoint(); 690 691 Irp = CONTAINING_RECORD(List.Flink, 692 IRP, 693 Tail.Overlay.ListEntry); 694 695 RemoveHeadList(&List); 696 697 Urb = URB_FROM_IRP(Irp); 698 699 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 700 InterlockedDecrement(&DeviceHandle->DeviceHandleLock); 701 702 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); 703 704 DPRINT_CORE("USBPORT_FlushAbortList: complete Irp - %p\n", Irp); 705 706 Irp->IoStatus.Status = Status; 707 Irp->IoStatus.Information = 0; 708 IoCompleteRequest(Irp, IO_NO_INCREMENT); 709 } 710 } 711 712 VOID 713 NTAPI 714 USBPORT_FlushCancelList(IN PUSBPORT_ENDPOINT Endpoint) 715 { 716 PDEVICE_OBJECT FdoDevice; 717 PUSBPORT_DEVICE_EXTENSION FdoExtension; 718 PUSBPORT_TRANSFER Transfer; 719 PIRP Irp; 720 KIRQL OldIrql; 721 KIRQL PrevIrql; 722 723 DPRINT_CORE("USBPORT_FlushCancelList: ... \n"); 724 725 FdoDevice = Endpoint->FdoDevice; 726 FdoExtension = FdoDevice->DeviceExtension; 727 728 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql); 729 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock); 730 731 while (!IsListEmpty(&Endpoint->CancelList)) 732 { 733 Transfer = CONTAINING_RECORD(Endpoint->CancelList.Flink, 734 USBPORT_TRANSFER, 735 TransferLink); 736 737 RemoveHeadList(&Endpoint->CancelList); 738 739 Irp = Transfer->Irp; 740 741 if (Irp) 742 { 743 DPRINT("USBPORT_FlushCancelList: Irp - %p\n", Irp); 744 745 IoAcquireCancelSpinLock(&PrevIrql); 746 IoSetCancelRoutine(Irp, NULL); 747 IoReleaseCancelSpinLock(PrevIrql); 748 749 USBPORT_RemoveActiveTransferIrp(FdoDevice, Irp); 750 } 751 752 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 753 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql); 754 755 if (Endpoint->Flags & ENDPOINT_FLAG_NUKE) 756 { 757 USBPORT_CompleteTransfer(Transfer->Urb, USBD_STATUS_DEVICE_GONE); 758 } 759 else 760 { 761 if (Transfer->Flags & TRANSFER_FLAG_DEVICE_GONE) 762 { 763 USBPORT_CompleteTransfer(Transfer->Urb, 764 USBD_STATUS_DEVICE_GONE); 765 } 766 else 767 { 768 USBPORT_CompleteTransfer(Transfer->Urb, 769 USBD_STATUS_CANCELED); 770 } 771 } 772 773 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql); 774 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock); 775 } 776 777 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 778 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql); 779 780 USBPORT_FlushAbortList(Endpoint); 781 } 782 783 VOID 784 NTAPI 785 USBPORT_FlushPendingTransfers(IN PUSBPORT_ENDPOINT Endpoint) 786 { 787 PDEVICE_OBJECT FdoDevice; 788 PUSBPORT_DEVICE_EXTENSION FdoExtension; 789 BOOLEAN IsMapTransfer; 790 BOOLEAN IsEnd = FALSE; 791 PLIST_ENTRY List; 792 PUSBPORT_TRANSFER Transfer; 793 PURB Urb; 794 PIRP Irp; 795 KIRQL OldIrql; 796 BOOLEAN Result; 797 798 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint - %p\n", Endpoint); 799 800 FdoDevice = Endpoint->FdoDevice; 801 FdoExtension = FdoDevice->DeviceExtension; 802 803 if (InterlockedCompareExchange(&Endpoint->FlushPendingLock, 1, 0)) 804 { 805 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Locked \n"); 806 return; 807 } 808 809 while (TRUE) 810 { 811 IsMapTransfer = 0; 812 813 KeAcquireSpinLock(&FdoExtension->FlushPendingTransferSpinLock, 814 &OldIrql); 815 816 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock); 817 818 if (FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND) 819 { 820 IsEnd = TRUE; 821 822 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 823 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, 824 OldIrql); 825 goto Next; 826 } 827 828 if (!(Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0)) 829 { 830 if (!IsListEmpty(&Endpoint->TransferList)) 831 { 832 List = Endpoint->TransferList.Flink; 833 834 while (List && List != &Endpoint->TransferList) 835 { 836 Transfer = CONTAINING_RECORD(List, 837 USBPORT_TRANSFER, 838 TransferLink); 839 840 if (!(Transfer->Flags & TRANSFER_FLAG_SUBMITED)) 841 { 842 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 843 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, 844 OldIrql); 845 846 IsEnd = TRUE; 847 goto Worker; 848 } 849 850 List = Transfer->TransferLink.Flink; 851 } 852 } 853 } 854 855 List = Endpoint->PendingTransferList.Flink; 856 857 if (List == NULL || IsListEmpty(&Endpoint->PendingTransferList)) 858 { 859 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 860 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, 861 OldIrql); 862 863 IsEnd = TRUE; 864 goto Worker; 865 } 866 867 Transfer = CONTAINING_RECORD(List, 868 USBPORT_TRANSFER, 869 TransferLink); 870 871 if (Transfer->Irp) 872 { 873 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp->CancelRoutine - %p\n", 874 Transfer->Irp->CancelRoutine); 875 } 876 877 if (Transfer->Irp && 878 (IoSetCancelRoutine(Transfer->Irp, NULL) == NULL)) 879 { 880 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp - %p\n", 881 Transfer->Irp); 882 883 Transfer = NULL; 884 IsEnd = TRUE; 885 } 886 887 if (!Transfer) 888 { 889 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 890 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, 891 OldIrql); 892 893 if (IsMapTransfer) 894 { 895 USBPORT_FlushMapTransfers(FdoDevice); 896 goto Next; 897 } 898 899 goto Worker; 900 } 901 902 Irp = Transfer->Irp; 903 Urb = Transfer->Urb; 904 905 RemoveEntryList(&Transfer->TransferLink); 906 Transfer->TransferLink.Flink = NULL; 907 Transfer->TransferLink.Blink = NULL; 908 909 if (Irp) 910 { 911 Irp = USBPORT_RemovePendingTransferIrp(FdoDevice, Irp); 912 } 913 914 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock); 915 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, 916 OldIrql); 917 918 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql); 919 920 if (Irp) 921 { 922 IoSetCancelRoutine(Irp, USBPORT_CancelActiveTransferIrp); 923 924 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL)) 925 { 926 DPRINT_CORE("USBPORT_FlushPendingTransfers: irp - %p\n", Irp); 927 928 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, 929 OldIrql); 930 931 USBPORT_CompleteTransfer(Transfer->Urb, USBD_STATUS_CANCELED); 932 goto Worker; 933 } 934 935 USBPORT_FindUrbInIrpTable(FdoExtension->ActiveIrpTable, Urb, Irp); 936 USBPORT_InsertIrpInTable(FdoExtension->ActiveIrpTable, Irp); 937 } 938 939 IsMapTransfer = USBPORT_QueueActiveUrbToEndpoint(Endpoint, Urb); 940 941 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql); 942 943 if (IsMapTransfer) 944 { 945 USBPORT_FlushMapTransfers(FdoDevice); 946 goto Next; 947 } 948 949 Worker: 950 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); 951 Result = USBPORT_EndpointWorker(Endpoint, FALSE); 952 KeLowerIrql(OldIrql); 953 954 if (Result) 955 USBPORT_InvalidateEndpointHandler(FdoDevice, 956 Endpoint, 957 INVALIDATE_ENDPOINT_WORKER_THREAD); 958 959 Next: 960 if (IsEnd) 961 { 962 InterlockedDecrement(&Endpoint->FlushPendingLock); 963 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Unlocked. Exit\n"); 964 return; 965 } 966 } 967 } 968 969 VOID 970 NTAPI 971 USBPORT_QueuePendingUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint, 972 IN PURB Urb) 973 { 974 PUSBPORT_TRANSFER Transfer; 975 976 DPRINT_CORE("USBPORT_QueuePendingUrbToEndpoint: Endpoint - %p, Urb - %p\n", 977 Endpoint, 978 Urb); 979 980 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0]; 981 //FIXME USBPORT_ResetEndpointIdle(); 982 InsertTailList(&Endpoint->PendingTransferList, &Transfer->TransferLink); 983 Urb->UrbHeader.Status = USBD_STATUS_PENDING; 984 } 985 986 BOOLEAN 987 NTAPI 988 USBPORT_QueueActiveUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint, 989 IN PURB Urb) 990 { 991 PUSBPORT_TRANSFER Transfer; 992 PDEVICE_OBJECT FdoDevice; 993 PUSBPORT_DEVICE_EXTENSION FdoExtension; 994 PUSBPORT_DEVICE_HANDLE DeviceHandle; 995 KIRQL OldIrql; 996 997 DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: Endpoint - %p, Urb - %p\n", 998 Endpoint, 999 Urb); 1000 1001 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0]; 1002 FdoDevice = Endpoint->FdoDevice; 1003 FdoExtension = FdoDevice->DeviceExtension; 1004 1005 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, 1006 &Endpoint->EndpointOldIrql); 1007 1008 if ((Endpoint->Flags & ENDPOINT_FLAG_NUKE) || 1009 (Transfer->Flags & TRANSFER_FLAG_ABORTED)) 1010 { 1011 InsertTailList(&Endpoint->CancelList, &Transfer->TransferLink); 1012 1013 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 1014 Endpoint->EndpointOldIrql); 1015 1016 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n"); 1017 return FALSE; 1018 } 1019 1020 if (Transfer->TransferParameters.TransferBufferLength == 0 || 1021 !(Endpoint->Flags & ENDPOINT_FLAG_DMA_TYPE)) 1022 { 1023 InsertTailList(&Endpoint->TransferList, &Transfer->TransferLink); 1024 1025 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 1026 Endpoint->EndpointOldIrql); 1027 1028 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n"); 1029 return FALSE; 1030 } 1031 1032 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql); 1033 1034 KeAcquireSpinLock(&FdoExtension->MapTransferSpinLock, &OldIrql); 1035 1036 InsertTailList(&FdoExtension->MapTransferList, &Transfer->TransferLink); 1037 1038 DeviceHandle = Transfer->Urb->UrbHeader.UsbdDeviceHandle; 1039 InterlockedIncrement(&DeviceHandle->DeviceHandleLock); 1040 1041 KeReleaseSpinLock(&FdoExtension->MapTransferSpinLock, OldIrql); 1042 1043 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return TRUE\n"); 1044 return TRUE; 1045 } 1046 1047 VOID 1048 NTAPI 1049 USBPORT_QueuePendingTransferIrp(IN PIRP Irp) 1050 { 1051 PURB Urb; 1052 PUSBPORT_TRANSFER Transfer; 1053 PUSBPORT_ENDPOINT Endpoint; 1054 PDEVICE_OBJECT FdoDevice; 1055 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1056 1057 DPRINT_CORE("USBPORT_QueuePendingTransferIrp: Irp - %p\n", Irp); 1058 1059 Urb = URB_FROM_IRP(Irp); 1060 1061 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0]; 1062 Endpoint = Transfer->Endpoint; 1063 1064 FdoDevice = Endpoint->FdoDevice; 1065 FdoExtension = FdoDevice->DeviceExtension; 1066 1067 Irp->IoStatus.Status = STATUS_PENDING; 1068 IoMarkIrpPending(Irp); 1069 1070 IoSetCancelRoutine(Irp, USBPORT_CancelPendingTransferIrp); 1071 1072 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL)) 1073 { 1074 USBPORT_CompleteTransfer(Urb, USBD_STATUS_CANCELED); 1075 } 1076 else 1077 { 1078 USBPORT_InsertIrpInTable(FdoExtension->PendingIrpTable, Irp); 1079 USBPORT_QueuePendingUrbToEndpoint(Endpoint, Urb); 1080 } 1081 } 1082 1083 VOID 1084 NTAPI 1085 USBPORT_QueueTransferUrb(IN PURB Urb) 1086 { 1087 PUSBPORT_TRANSFER Transfer; 1088 PUSBPORT_ENDPOINT Endpoint; 1089 PIRP Irp; 1090 PUSBPORT_DEVICE_HANDLE DeviceHandle; 1091 PUSBPORT_TRANSFER_PARAMETERS Parameters; 1092 1093 DPRINT_CORE("USBPORT_QueueTransferUrb: Urb - %p\n", Urb); 1094 1095 if (Urb->UrbControlTransfer.TransferFlags & USBD_DEFAULT_PIPE_TRANSFER) 1096 Urb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER; 1097 1098 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0]; 1099 Parameters = &Transfer->TransferParameters; 1100 1101 Endpoint = Transfer->Endpoint; 1102 Endpoint->Flags &= ~ENDPOINT_FLAG_QUEUENE_EMPTY; 1103 1104 Parameters->TransferBufferLength = Urb->UrbControlTransfer.TransferBufferLength; 1105 Parameters->TransferFlags = Urb->UrbControlTransfer.TransferFlags; 1106 1107 Transfer->TransferBufferMDL = Urb->UrbControlTransfer.TransferBufferMDL; 1108 1109 if (Urb->UrbControlTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN) 1110 { 1111 Transfer->Direction = USBPORT_DMA_DIRECTION_FROM_DEVICE; 1112 } 1113 else 1114 { 1115 Transfer->Direction = USBPORT_DMA_DIRECTION_TO_DEVICE; 1116 } 1117 1118 if (Endpoint->EndpointProperties.TransferType == USBPORT_TRANSFER_TYPE_CONTROL) 1119 { 1120 RtlCopyMemory(&Parameters->SetupPacket, 1121 Urb->UrbControlTransfer.SetupPacket, 1122 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1123 } 1124 1125 DPRINT_URB("... URB TransferBufferLength - %x\n", 1126 Urb->UrbControlTransfer.TransferBufferLength); 1127 1128 Urb->UrbControlTransfer.TransferBufferLength = 0; 1129 1130 Irp = Transfer->Irp; 1131 1132 if (Irp) 1133 { 1134 USBPORT_QueuePendingTransferIrp(Irp); 1135 } 1136 else 1137 { 1138 USBPORT_QueuePendingUrbToEndpoint(Endpoint, Urb); 1139 } 1140 1141 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 1142 InterlockedDecrement(&DeviceHandle->DeviceHandleLock); 1143 1144 USBPORT_FlushPendingTransfers(Endpoint); 1145 1146 DPRINT_URB("... URB TransferBufferLength - %x\n", 1147 Urb->UrbControlTransfer.TransferBufferLength); 1148 1149 if (Urb->UrbControlTransfer.TransferBufferLength) 1150 { 1151 PULONG Buffer; 1152 ULONG BufferLength; 1153 ULONG_PTR BufferEnd; 1154 ULONG ix; 1155 1156 Buffer = Urb->UrbControlTransfer.TransferBuffer; 1157 BufferLength = Urb->UrbControlTransfer.TransferBufferLength; 1158 BufferEnd = (ULONG_PTR)Buffer + BufferLength; 1159 1160 DPRINT_URB("URB TransferBuffer - %p\n", Buffer); 1161 1162 for (ix = 0; (ULONG_PTR)(Buffer + ix) < BufferEnd; ix++) 1163 { 1164 DPRINT_URB("Buffer[%02X] - %p\n", ix, Buffer[ix]); 1165 } 1166 } 1167 } 1168 1169 VOID 1170 NTAPI 1171 USBPORT_FlushAllEndpoints(IN PDEVICE_OBJECT FdoDevice) 1172 { 1173 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1174 PLIST_ENTRY Entry; 1175 PUSBPORT_ENDPOINT Endpoint; 1176 LIST_ENTRY List; 1177 KIRQL OldIrql; 1178 1179 DPRINT_CORE("USBPORT_FlushAllEndpoints: ... \n"); 1180 1181 FdoExtension = FdoDevice->DeviceExtension; 1182 1183 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql); 1184 1185 InitializeListHead(&List); 1186 1187 Entry = FdoExtension->EndpointList.Flink; 1188 1189 while (Entry && Entry != &FdoExtension->EndpointList) 1190 { 1191 Endpoint = CONTAINING_RECORD(Entry, 1192 USBPORT_ENDPOINT, 1193 EndpointLink); 1194 1195 if (USBPORT_GetEndpointState(Endpoint) != USBPORT_ENDPOINT_CLOSED) 1196 { 1197 InsertTailList(&List, &Endpoint->FlushLink); 1198 } 1199 1200 Entry = Endpoint->EndpointLink.Flink; 1201 } 1202 1203 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql); 1204 1205 while (!IsListEmpty(&List)) 1206 { 1207 Endpoint = CONTAINING_RECORD(List.Flink, 1208 USBPORT_ENDPOINT, 1209 FlushLink); 1210 1211 RemoveHeadList(&List); 1212 1213 Endpoint->FlushLink.Flink = NULL; 1214 Endpoint->FlushLink.Blink = NULL; 1215 1216 if (!IsListEmpty(&Endpoint->PendingTransferList)) 1217 { 1218 USBPORT_FlushPendingTransfers(Endpoint); 1219 } 1220 } 1221 1222 DPRINT_CORE("USBPORT_FlushAllEndpoints: exit\n"); 1223 } 1224 1225 ULONG 1226 NTAPI 1227 USBPORT_KillEndpointActiveTransfers(IN PDEVICE_OBJECT FdoDevice, 1228 IN PUSBPORT_ENDPOINT Endpoint) 1229 { 1230 PLIST_ENTRY ActiveList; 1231 PUSBPORT_TRANSFER Transfer; 1232 ULONG KilledTransfers = 0; 1233 1234 DPRINT_CORE("USBPORT_KillEndpointActiveTransfers \n"); 1235 1236 ActiveList = Endpoint->TransferList.Flink; 1237 1238 while (ActiveList && ActiveList != &Endpoint->TransferList) 1239 { 1240 ++KilledTransfers; 1241 1242 Transfer = CONTAINING_RECORD(ActiveList, 1243 USBPORT_TRANSFER, 1244 TransferLink); 1245 1246 Transfer->Flags |= TRANSFER_FLAG_ABORTED; 1247 1248 ActiveList = Transfer->TransferLink.Flink; 1249 } 1250 1251 USBPORT_FlushPendingTransfers(Endpoint); 1252 USBPORT_FlushCancelList(Endpoint); 1253 1254 return KilledTransfers; 1255 } 1256 1257 VOID 1258 NTAPI 1259 USBPORT_FlushController(IN PDEVICE_OBJECT FdoDevice) 1260 { 1261 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1262 PLIST_ENTRY Entry; 1263 PUSBPORT_ENDPOINT Endpoint; 1264 ULONG KilledTransfers; 1265 PLIST_ENTRY EndpointList; 1266 KIRQL OldIrql; 1267 LIST_ENTRY FlushList; 1268 1269 DPRINT_CORE("USBPORT_FlushController \n"); 1270 1271 FdoExtension = FdoDevice->DeviceExtension; 1272 1273 EndpointList = &FdoExtension->EndpointList; 1274 1275 while (TRUE) 1276 { 1277 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql); 1278 1279 InitializeListHead(&FlushList); 1280 1281 Entry = EndpointList->Flink; 1282 1283 if (!IsListEmpty(EndpointList)) 1284 { 1285 while (Entry && Entry != EndpointList) 1286 { 1287 Endpoint = CONTAINING_RECORD(Entry, 1288 USBPORT_ENDPOINT, 1289 EndpointLink); 1290 1291 if (Endpoint->StateLast != USBPORT_ENDPOINT_REMOVE && 1292 Endpoint->StateLast != USBPORT_ENDPOINT_CLOSED) 1293 { 1294 InterlockedIncrement(&Endpoint->LockCounter); 1295 InsertTailList(&FlushList, &Endpoint->FlushControllerLink); 1296 } 1297 1298 Entry = Endpoint->EndpointLink.Flink; 1299 } 1300 } 1301 1302 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql); 1303 1304 KilledTransfers = 0; 1305 while (!IsListEmpty(&FlushList)) 1306 { 1307 Endpoint = CONTAINING_RECORD(FlushList.Flink, 1308 USBPORT_ENDPOINT, 1309 FlushControllerLink); 1310 1311 RemoveHeadList(&FlushList); 1312 1313 KilledTransfers += USBPORT_KillEndpointActiveTransfers(FdoDevice, 1314 Endpoint); 1315 1316 InterlockedDecrement(&Endpoint->LockCounter); 1317 } 1318 1319 if (!KilledTransfers) 1320 break; 1321 1322 USBPORT_Wait(FdoDevice, 100); 1323 } 1324 } 1325 1326 VOID 1327 NTAPI 1328 USBPORT_BadRequestFlush(IN PDEVICE_OBJECT FdoDevice) 1329 { 1330 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1331 PIRP Irp; 1332 1333 DPRINT_QUEUE("USBPORT_BadRequestFlush: ... \n"); 1334 1335 FdoExtension = FdoDevice->DeviceExtension; 1336 1337 while (TRUE) 1338 { 1339 Irp = IoCsqRemoveNextIrp(&FdoExtension->BadRequestIoCsq, 0); 1340 1341 if (!Irp) 1342 break; 1343 1344 DPRINT1("USBPORT_BadRequestFlush: Irp - %p\n", Irp); 1345 1346 Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; 1347 Irp->IoStatus.Information = 0; 1348 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1349 } 1350 } 1351 1352 VOID 1353 NTAPI 1354 USBPORT_AbortEndpoint(IN PDEVICE_OBJECT FdoDevice, 1355 IN PUSBPORT_ENDPOINT Endpoint, 1356 IN PIRP Irp) 1357 { 1358 PLIST_ENTRY PendingList; 1359 PUSBPORT_TRANSFER PendingTransfer; 1360 PLIST_ENTRY ActiveList; 1361 PUSBPORT_TRANSFER ActiveTransfer; 1362 1363 DPRINT_CORE("USBPORT_AbortEndpoint: Irp - %p\n", Irp); 1364 1365 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql); 1366 1367 if (Irp) 1368 { 1369 InsertTailList(&Endpoint->AbortList, &Irp->Tail.Overlay.ListEntry); 1370 } 1371 1372 PendingList = Endpoint->PendingTransferList.Flink; 1373 1374 while (PendingList && PendingList != &Endpoint->PendingTransferList) 1375 { 1376 PendingTransfer = CONTAINING_RECORD(PendingList, 1377 USBPORT_TRANSFER, 1378 TransferLink); 1379 1380 DPRINT_CORE("USBPORT_AbortEndpoint: Abort PendingTransfer - %p\n", 1381 PendingTransfer); 1382 1383 PendingTransfer->Flags |= TRANSFER_FLAG_ABORTED; 1384 1385 PendingList = PendingTransfer->TransferLink.Flink; 1386 } 1387 1388 ActiveList = Endpoint->TransferList.Flink; 1389 1390 while (ActiveList && ActiveList != &Endpoint->TransferList) 1391 { 1392 ActiveTransfer = CONTAINING_RECORD(ActiveList, 1393 USBPORT_TRANSFER, 1394 TransferLink); 1395 1396 DPRINT_CORE("USBPORT_AbortEndpoint: Abort ActiveTransfer - %p\n", 1397 ActiveTransfer); 1398 1399 ActiveTransfer->Flags |= TRANSFER_FLAG_ABORTED; 1400 1401 if (Endpoint->Flags & ENDPOINT_FLAG_ABORTING) 1402 { 1403 ActiveTransfer->Flags |= TRANSFER_FLAG_DEVICE_GONE; 1404 } 1405 1406 ActiveList = ActiveTransfer->TransferLink.Flink; 1407 } 1408 1409 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql); 1410 1411 USBPORT_InvalidateEndpointHandler(FdoDevice, 1412 Endpoint, 1413 INVALIDATE_ENDPOINT_INT_NEXT_SOF); 1414 1415 USBPORT_FlushPendingTransfers(Endpoint); 1416 USBPORT_FlushCancelList(Endpoint); 1417 }