1 /* 2 * PROJECT: ReactOS USB Port Driver 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: USBPort device 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 NTSTATUS 14 NTAPI 15 USBPORT_SendSetupPacket(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, 16 IN PDEVICE_OBJECT FdoDevice, 17 IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, 18 IN PVOID Buffer, 19 IN ULONG Length, 20 IN OUT PULONG TransferedLen, 21 IN OUT PUSBD_STATUS pUSBDStatus) 22 { 23 PURB Urb; 24 PMDL Mdl; 25 USBD_STATUS USBDStatus; 26 KEVENT Event; 27 NTSTATUS Status; 28 29 DPRINT("USBPORT_SendSetupPacket: DeviceHandle - %p, FdoDevice - %p, SetupPacket - %p, Buffer - %p, Length - %x, TransferedLen - %x, pUSBDStatus - %x\n", 30 DeviceHandle, 31 FdoDevice, 32 SetupPacket, 33 Buffer, 34 Length, 35 TransferedLen, 36 pUSBDStatus); 37 38 KeInitializeEvent(&Event, NotificationEvent, FALSE); 39 40 Urb = ExAllocatePoolWithTag(NonPagedPool, 41 sizeof(struct _URB_CONTROL_TRANSFER), 42 USB_PORT_TAG); 43 44 if (Urb) 45 { 46 InterlockedIncrement(&DeviceHandle->DeviceHandleLock); 47 48 RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_TRANSFER)); 49 50 RtlCopyMemory(Urb->UrbControlTransfer.SetupPacket, 51 SetupPacket, 52 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 53 54 Urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_TRANSFER); 55 Urb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER; 56 Urb->UrbHeader.UsbdDeviceHandle = DeviceHandle; 57 Urb->UrbHeader.UsbdFlags = 0; 58 59 Urb->UrbControlTransfer.PipeHandle = &DeviceHandle->PipeHandle; 60 Urb->UrbControlTransfer.TransferBufferLength = Length; 61 Urb->UrbControlTransfer.TransferBuffer = Buffer; 62 Urb->UrbControlTransfer.TransferBufferMDL = NULL; 63 64 Urb->UrbControlTransfer.TransferFlags = USBD_SHORT_TRANSFER_OK | 65 USBD_TRANSFER_DIRECTION; 66 67 if (SetupPacket->bmRequestType.Dir != BMREQUEST_DEVICE_TO_HOST) 68 { 69 Urb->UrbControlTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN; 70 } 71 72 Status = STATUS_SUCCESS; 73 74 if (Length) 75 { 76 Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL); 77 78 Urb->UrbControlTransfer.TransferBufferMDL = Mdl; 79 80 if (Mdl) 81 { 82 Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_MDL; 83 MmBuildMdlForNonPagedPool(Mdl); 84 } 85 else 86 { 87 Status = USBPORT_USBDStatusToNtStatus(NULL, 88 USBD_STATUS_INSUFFICIENT_RESOURCES); 89 } 90 } 91 92 if (NT_SUCCESS(Status)) 93 { 94 USBDStatus = USBPORT_AllocateTransfer(FdoDevice, 95 Urb, 96 NULL, 97 NULL, 98 &Event); 99 100 if (USBD_SUCCESS(USBDStatus)) 101 { 102 InterlockedIncrement(&DeviceHandle->DeviceHandleLock); 103 104 USBPORT_QueueTransferUrb(Urb); 105 106 KeWaitForSingleObject(&Event, 107 Suspended, 108 KernelMode, 109 FALSE, 110 NULL); 111 112 USBDStatus = Urb->UrbHeader.Status; 113 } 114 115 Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 116 117 if (TransferedLen) 118 *TransferedLen = Urb->UrbControlTransfer.TransferBufferLength; 119 120 if (pUSBDStatus) 121 *pUSBDStatus = USBDStatus; 122 } 123 124 InterlockedDecrement(&DeviceHandle->DeviceHandleLock); 125 ExFreePoolWithTag(Urb, USB_PORT_TAG); 126 } 127 else 128 { 129 if (pUSBDStatus) 130 *pUSBDStatus = USBD_STATUS_INSUFFICIENT_RESOURCES; 131 132 Status = USBPORT_USBDStatusToNtStatus(NULL, 133 USBD_STATUS_INSUFFICIENT_RESOURCES); 134 } 135 136 DPRINT("USBPORT_SendSetupPacket: Status - %x\n", Status); 137 return Status; 138 } 139 140 ULONG 141 NTAPI 142 USBPORT_GetInterfaceLength(IN PUSB_INTERFACE_DESCRIPTOR iDescriptor, 143 IN ULONG_PTR EndDescriptors) 144 { 145 SIZE_T Length; 146 PUSB_ENDPOINT_DESCRIPTOR Descriptor; 147 ULONG ix; 148 149 DPRINT("USBPORT_GetInterfaceLength ... \n"); 150 151 Length = iDescriptor->bLength; 152 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)iDescriptor + Length); 153 154 if (iDescriptor->bNumEndpoints) 155 { 156 for (ix = 0; ix < iDescriptor->bNumEndpoints; ix++) 157 { 158 while ((Descriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE) && 159 (Descriptor->bLength > 0)) 160 { 161 Length += Descriptor->bLength; 162 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor + 163 Descriptor->bLength); 164 } 165 166 Length += Descriptor->bLength; 167 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor + 168 Descriptor->bLength); 169 } 170 } 171 172 while (((ULONG_PTR)Descriptor < EndDescriptors) && 173 (Descriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE) && 174 (Descriptor->bLength > 0)) 175 { 176 Length += Descriptor->bLength; 177 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor + 178 Descriptor->bLength); 179 } 180 181 return Length; 182 } 183 184 PUSB_INTERFACE_DESCRIPTOR 185 NTAPI 186 USBPORT_ParseConfigurationDescriptor(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor, 187 IN UCHAR InterfaceNumber, 188 IN UCHAR Alternate, 189 OUT PBOOLEAN HasAlternates) 190 { 191 PUSB_CONFIGURATION_DESCRIPTOR TmpDescriptor; 192 PUSB_INTERFACE_DESCRIPTOR iDescriptor; 193 PUSB_INTERFACE_DESCRIPTOR OutDescriptor = NULL; 194 ULONG_PTR Descriptor = (ULONG_PTR)ConfigDescriptor; 195 ULONG_PTR EndDescriptors; 196 ULONG ix; 197 198 DPRINT("USBPORT_ParseConfigurationDescriptor ... \n"); 199 200 if (HasAlternates) 201 *HasAlternates = FALSE; 202 203 for (TmpDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)ConfigDescriptor + ConfigDescriptor->bLength); 204 TmpDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE && TmpDescriptor->bLength > 0; 205 TmpDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)TmpDescriptor + TmpDescriptor->bLength)) 206 ; 207 208 iDescriptor = (PUSB_INTERFACE_DESCRIPTOR)TmpDescriptor; 209 210 EndDescriptors = (ULONG_PTR)ConfigDescriptor + 211 ConfigDescriptor->wTotalLength; 212 213 while ((Descriptor < EndDescriptors) && 214 (iDescriptor->bInterfaceNumber != InterfaceNumber)) 215 { 216 Descriptor = (ULONG_PTR)iDescriptor + 217 USBPORT_GetInterfaceLength(iDescriptor, EndDescriptors); 218 219 iDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Descriptor; 220 } 221 222 ix = 0; 223 224 while (Descriptor < EndDescriptors && 225 iDescriptor->bInterfaceNumber == InterfaceNumber) 226 { 227 if (iDescriptor->bAlternateSetting == Alternate) 228 OutDescriptor = iDescriptor; 229 230 Descriptor = (ULONG_PTR)iDescriptor + 231 USBPORT_GetInterfaceLength(iDescriptor, EndDescriptors); 232 233 iDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Descriptor; 234 235 ++ix; 236 } 237 238 if ((ix > 1) && HasAlternates) 239 *HasAlternates = TRUE; 240 241 return OutDescriptor; 242 } 243 244 USBD_STATUS 245 NTAPI 246 USBPORT_OpenInterface(IN PURB Urb, 247 IN PUSBPORT_DEVICE_HANDLE DeviceHandle, 248 IN PDEVICE_OBJECT FdoDevice, 249 IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle, 250 IN PUSBD_INTERFACE_INFORMATION InterfaceInfo, 251 IN OUT PUSBPORT_INTERFACE_HANDLE *iHandle, 252 IN BOOLEAN SendSetInterface) 253 { 254 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; 255 PUSBPORT_INTERFACE_HANDLE InterfaceHandle = NULL; 256 PUSBPORT_PIPE_HANDLE PipeHandle; 257 PUSB_ENDPOINT_DESCRIPTOR Descriptor; 258 PUSBD_PIPE_INFORMATION PipeInfo; 259 BOOLEAN HasAlternates; 260 ULONG NumEndpoints; 261 SIZE_T Length; 262 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 263 SIZE_T HandleLength; 264 BOOLEAN IsAllocated = FALSE; 265 USHORT MaxPacketSize; 266 USHORT wMaxPacketSize; 267 ULONG ix; 268 USBD_STATUS USBDStatus = USBD_STATUS_SUCCESS; 269 NTSTATUS Status; 270 271 DPRINT("USBPORT_OpenInterface: ...\n"); 272 273 InterfaceDescriptor = USBPORT_ParseConfigurationDescriptor(ConfigHandle->ConfigurationDescriptor, 274 InterfaceInfo->InterfaceNumber, 275 InterfaceInfo->AlternateSetting, 276 &HasAlternates); 277 278 NumEndpoints = InterfaceDescriptor->bNumEndpoints; 279 280 Length = FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes) + 281 NumEndpoints * sizeof(USBD_PIPE_INFORMATION); 282 283 if (HasAlternates && SendSetInterface) 284 { 285 RtlZeroMemory(&SetupPacket, sizeof(SetupPacket)); 286 287 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 288 SetupPacket.bmRequestType.Type = BMREQUEST_STANDARD; 289 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 290 SetupPacket.bRequest = USB_REQUEST_SET_INTERFACE; 291 SetupPacket.wValue.W = InterfaceInfo->AlternateSetting; 292 SetupPacket.wIndex.W = InterfaceInfo->InterfaceNumber; 293 SetupPacket.wLength = 0; 294 295 USBPORT_SendSetupPacket(DeviceHandle, 296 FdoDevice, 297 &SetupPacket, 298 NULL, 299 0, 300 NULL, 301 &USBDStatus); 302 if (!USBD_SUCCESS(USBDStatus)) 303 { 304 goto Exit; 305 } 306 } 307 308 if (*iHandle) 309 { 310 InterfaceHandle = *iHandle; 311 } 312 else 313 { 314 HandleLength = FIELD_OFFSET(USBPORT_INTERFACE_HANDLE, PipeHandle) + 315 NumEndpoints * sizeof(USBPORT_PIPE_HANDLE); 316 317 InterfaceHandle = ExAllocatePoolWithTag(NonPagedPool, 318 HandleLength, 319 USB_PORT_TAG); 320 321 if (!InterfaceHandle) 322 { 323 USBDStatus = USBD_STATUS_INSUFFICIENT_RESOURCES; 324 goto Exit; 325 } 326 327 RtlZeroMemory(InterfaceHandle, HandleLength); 328 329 for (ix = 0; ix < NumEndpoints; ++ix) 330 { 331 PipeHandle = &InterfaceHandle->PipeHandle[ix]; 332 333 PipeHandle->Flags = PIPE_HANDLE_FLAG_CLOSED; 334 PipeHandle->Endpoint = NULL; 335 } 336 337 IsAllocated = TRUE; 338 } 339 340 InterfaceHandle->AlternateSetting = InterfaceInfo->AlternateSetting; 341 342 RtlCopyMemory(&InterfaceHandle->InterfaceDescriptor, 343 InterfaceDescriptor, 344 sizeof(USB_INTERFACE_DESCRIPTOR)); 345 346 InterfaceInfo->Class = InterfaceDescriptor->bInterfaceClass; 347 InterfaceInfo->SubClass = InterfaceDescriptor->bInterfaceSubClass; 348 InterfaceInfo->Protocol = InterfaceDescriptor->bInterfaceProtocol; 349 InterfaceInfo->Reserved = 0; 350 InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints; 351 352 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + 353 InterfaceDescriptor->bLength); 354 355 for (ix = 0; ix < NumEndpoints; ++ix) 356 { 357 PipeHandle = &InterfaceHandle->PipeHandle[ix]; 358 359 while (Descriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE) 360 { 361 if (Descriptor->bLength == 0) 362 { 363 break; 364 } 365 else 366 { 367 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor + 368 Descriptor->bLength); 369 } 370 } 371 372 if (InterfaceInfo->Pipes[ix].PipeFlags & USBD_PF_CHANGE_MAX_PACKET) 373 { 374 Descriptor->wMaxPacketSize = InterfaceInfo->Pipes[ix].MaximumPacketSize; 375 } 376 377 RtlCopyMemory(&PipeHandle->EndpointDescriptor, 378 Descriptor, 379 sizeof(USB_ENDPOINT_DESCRIPTOR)); 380 381 PipeHandle->Flags = PIPE_HANDLE_FLAG_CLOSED; 382 PipeHandle->PipeFlags = InterfaceInfo->Pipes[ix].PipeFlags; 383 PipeHandle->Endpoint = NULL; 384 385 wMaxPacketSize = Descriptor->wMaxPacketSize; 386 387 /* USB 2.0 Specification, 5.9 High-Speed, High Bandwidth Endpoints */ 388 MaxPacketSize = (wMaxPacketSize & 0x7FF) * (((wMaxPacketSize >> 11) & 3) + 1); 389 390 InterfaceInfo->Pipes[ix].EndpointAddress = Descriptor->bEndpointAddress; 391 InterfaceInfo->Pipes[ix].PipeType = Descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK; 392 InterfaceInfo->Pipes[ix].MaximumPacketSize = MaxPacketSize; 393 InterfaceInfo->Pipes[ix].PipeHandle = (USBD_PIPE_HANDLE)-1; 394 InterfaceInfo->Pipes[ix].Interval = Descriptor->bInterval; 395 396 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor + 397 Descriptor->bLength); 398 } 399 400 if (USBD_SUCCESS(USBDStatus)) 401 { 402 for (ix = 0; ix < NumEndpoints; ++ix) 403 { 404 PipeInfo = &InterfaceInfo->Pipes[ix]; 405 PipeHandle = &InterfaceHandle->PipeHandle[ix]; 406 407 Status = USBPORT_OpenPipe(FdoDevice, 408 DeviceHandle, 409 PipeHandle, 410 &USBDStatus); 411 412 if (!NT_SUCCESS(Status)) 413 break; 414 415 PipeInfo->PipeHandle = PipeHandle; 416 } 417 418 if (NumEndpoints) 419 { 420 USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 421 } 422 } 423 424 Exit: 425 426 if (USBD_SUCCESS(USBDStatus)) 427 { 428 InterfaceInfo->InterfaceHandle = InterfaceHandle; 429 *iHandle = InterfaceHandle; 430 InterfaceInfo->Length = Length; 431 } 432 else 433 { 434 if (InterfaceHandle) 435 { 436 if (NumEndpoints) 437 { 438 DPRINT1("USBPORT_OpenInterface: USBDStatus - %lx\n", USBDStatus); 439 } 440 441 if (IsAllocated) 442 ExFreePoolWithTag(InterfaceHandle, USB_PORT_TAG); 443 } 444 } 445 446 return USBDStatus; 447 } 448 449 VOID 450 NTAPI 451 USBPORT_CloseConfiguration(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, 452 IN PDEVICE_OBJECT FdoDevice) 453 { 454 PUSBPORT_CONFIGURATION_HANDLE ConfigHandle; 455 PLIST_ENTRY iHandleList; 456 PUSBPORT_INTERFACE_HANDLE iHandle; 457 ULONG NumEndpoints; 458 PUSBPORT_PIPE_HANDLE PipeHandle; 459 460 DPRINT("USBPORT_CloseConfiguration: ... \n"); 461 462 ConfigHandle = DeviceHandle->ConfigHandle; 463 464 if (ConfigHandle) 465 { 466 iHandleList = &ConfigHandle->InterfaceHandleList; 467 468 while (!IsListEmpty(iHandleList)) 469 { 470 iHandle = CONTAINING_RECORD(iHandleList->Flink, 471 USBPORT_INTERFACE_HANDLE, 472 InterfaceLink); 473 474 DPRINT("USBPORT_CloseConfiguration: iHandle - %p\n", iHandle); 475 476 RemoveHeadList(iHandleList); 477 478 NumEndpoints = iHandle->InterfaceDescriptor.bNumEndpoints; 479 480 PipeHandle = &iHandle->PipeHandle[0]; 481 482 while (NumEndpoints > 0) 483 { 484 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle); 485 PipeHandle += 1; 486 --NumEndpoints; 487 } 488 489 ExFreePoolWithTag(iHandle, USB_PORT_TAG); 490 } 491 492 ExFreePoolWithTag(ConfigHandle, USB_PORT_TAG); 493 DeviceHandle->ConfigHandle = NULL; 494 } 495 } 496 497 NTSTATUS 498 NTAPI 499 USBPORT_InitInterfaceInfo(IN PUSBD_INTERFACE_INFORMATION InterfaceInfo, 500 IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle) 501 { 502 PUSB_INTERFACE_DESCRIPTOR Descriptor; 503 PUSBD_PIPE_INFORMATION Pipe; 504 SIZE_T Length; 505 ULONG PipeFlags; 506 ULONG NumberOfPipes; 507 USBD_STATUS USBDStatus = USBD_STATUS_SUCCESS; 508 509 DPRINT("USBPORT_InitInterfaceInfo: InterfaceInfo - %p, ConfigHandle - %p\n", 510 InterfaceInfo, 511 ConfigHandle); 512 513 Descriptor = USBPORT_ParseConfigurationDescriptor(ConfigHandle->ConfigurationDescriptor, 514 InterfaceInfo->InterfaceNumber, 515 InterfaceInfo->AlternateSetting, 516 NULL); 517 518 Length = sizeof(USBD_INTERFACE_INFORMATION) + 519 sizeof(USBD_PIPE_INFORMATION); 520 521 if (Descriptor) 522 { 523 NumberOfPipes = Descriptor->bNumEndpoints; 524 525 Length = FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes) + 526 NumberOfPipes * sizeof(USBD_PIPE_INFORMATION); 527 528 if (InterfaceInfo->Length >= Length) 529 { 530 InterfaceInfo->Class = 0; 531 InterfaceInfo->SubClass = 0; 532 InterfaceInfo->Protocol = 0; 533 InterfaceInfo->Reserved = 0; 534 InterfaceInfo->InterfaceHandle = 0; 535 InterfaceInfo->NumberOfPipes = NumberOfPipes; 536 537 Pipe = InterfaceInfo->Pipes; 538 539 while (NumberOfPipes > 0) 540 { 541 Pipe->EndpointAddress = 0; 542 Pipe->Interval = 0; 543 Pipe->PipeType = 0; 544 Pipe->PipeHandle = 0; 545 546 PipeFlags = Pipe->PipeFlags; 547 548 if (PipeFlags & ~USBD_PF_VALID_MASK) 549 USBDStatus = USBD_STATUS_INVALID_PIPE_FLAGS; 550 551 if (!(PipeFlags & USBD_PF_CHANGE_MAX_PACKET)) 552 Pipe->MaximumPacketSize = 0; 553 554 Pipe += 1; 555 --NumberOfPipes; 556 } 557 } 558 else 559 { 560 USBDStatus = USBD_STATUS_BUFFER_TOO_SMALL; 561 } 562 } 563 else 564 { 565 USBDStatus = USBD_STATUS_INTERFACE_NOT_FOUND; 566 } 567 568 InterfaceInfo->Length = Length; 569 return USBDStatus; 570 } 571 572 NTSTATUS 573 NTAPI 574 USBPORT_HandleSelectConfiguration(IN PDEVICE_OBJECT FdoDevice, 575 IN PIRP Irp, 576 IN PURB Urb) 577 { 578 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor; 579 PUSBPORT_DEVICE_HANDLE DeviceHandle; 580 PUSBPORT_CONFIGURATION_HANDLE ConfigHandle = NULL; 581 PUSBD_INTERFACE_INFORMATION InterfaceInfo; 582 PUSBPORT_INTERFACE_HANDLE InterfaceHandle; 583 ULONG iNumber; 584 ULONG ix; 585 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 586 NTSTATUS Status; 587 USBD_STATUS USBDStatus; 588 PUSBPORT_DEVICE_EXTENSION FdoExtension; 589 590 DPRINT("USBPORT_HandleSelectConfiguration: ConfigDescriptor %p\n", 591 Urb->UrbSelectConfiguration.ConfigurationDescriptor); 592 593 FdoExtension = FdoDevice->DeviceExtension; 594 595 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 596 Executive, 597 KernelMode, 598 FALSE, 599 NULL); 600 601 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 602 ConfigDescriptor = Urb->UrbSelectConfiguration.ConfigurationDescriptor; 603 604 if (!ConfigDescriptor) 605 { 606 DPRINT("USBPORT_HandleSelectConfiguration: ConfigDescriptor == NULL\n"); 607 608 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 609 610 SetupPacket.bmRequestType.B = 0; 611 SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION; 612 SetupPacket.wValue.W = 0; 613 SetupPacket.wIndex.W = 0; 614 SetupPacket.wLength = 0; 615 616 USBPORT_SendSetupPacket(DeviceHandle, 617 FdoDevice, 618 &SetupPacket, 619 NULL, 620 0, 621 NULL, 622 NULL); 623 624 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); 625 goto Exit; 626 } 627 628 USBPORT_DumpingConfiguration(ConfigDescriptor); 629 630 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; 631 632 iNumber = 0; 633 634 do 635 { 636 ++iNumber; 637 InterfaceInfo = (PUSBD_INTERFACE_INFORMATION) 638 ((ULONG_PTR)InterfaceInfo + 639 InterfaceInfo->Length); 640 } 641 while ((ULONG_PTR)InterfaceInfo < (ULONG_PTR)Urb + Urb->UrbHeader.Length); 642 643 if ((iNumber <= 0) || (iNumber != ConfigDescriptor->bNumInterfaces)) 644 { 645 Status = USBPORT_USBDStatusToNtStatus(Urb, 646 USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR); 647 goto Exit; 648 } 649 650 ConfigHandle = ExAllocatePoolWithTag(NonPagedPool, 651 ConfigDescriptor->wTotalLength + sizeof(USBPORT_CONFIGURATION_HANDLE), 652 USB_PORT_TAG); 653 654 if (!ConfigHandle) 655 { 656 Status = USBPORT_USBDStatusToNtStatus(Urb, 657 USBD_STATUS_INSUFFICIENT_RESOURCES); 658 goto Exit; 659 } 660 661 RtlZeroMemory(ConfigHandle, 662 ConfigDescriptor->wTotalLength + sizeof(USBPORT_CONFIGURATION_HANDLE)); 663 664 InitializeListHead(&ConfigHandle->InterfaceHandleList); 665 666 ConfigHandle->ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)(ConfigHandle + 1); 667 668 RtlCopyMemory(ConfigHandle->ConfigurationDescriptor, 669 ConfigDescriptor, 670 ConfigDescriptor->wTotalLength); 671 672 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 673 674 SetupPacket.bmRequestType.B = 0; 675 SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION; 676 SetupPacket.wValue.W = ConfigDescriptor->bConfigurationValue; 677 SetupPacket.wIndex.W = 0; 678 SetupPacket.wLength = 0; 679 680 USBPORT_SendSetupPacket(DeviceHandle, 681 FdoDevice, 682 &SetupPacket, 683 NULL, 684 0, 685 NULL, 686 &USBDStatus); 687 688 if (USBD_ERROR(USBDStatus)) 689 { 690 Status = USBPORT_USBDStatusToNtStatus(Urb, 691 USBD_STATUS_SET_CONFIG_FAILED); 692 goto Exit; 693 } 694 695 if (iNumber <= 0) 696 { 697 Status = USBPORT_USBDStatusToNtStatus(Urb, 698 USBD_STATUS_SUCCESS); 699 700 goto Exit; 701 } 702 703 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; 704 705 for (ix = 0; ix < iNumber; ++ix) 706 { 707 USBDStatus = USBPORT_InitInterfaceInfo(InterfaceInfo, 708 ConfigHandle); 709 710 InterfaceHandle = NULL; 711 712 if (USBD_SUCCESS(USBDStatus)) 713 { 714 USBDStatus = USBPORT_OpenInterface(Urb, 715 DeviceHandle, 716 FdoDevice, 717 ConfigHandle, 718 InterfaceInfo, 719 &InterfaceHandle, 720 TRUE); 721 } 722 723 if (InterfaceHandle) 724 { 725 InsertTailList(&ConfigHandle->InterfaceHandleList, 726 &InterfaceHandle->InterfaceLink); 727 } 728 729 if (USBD_ERROR(USBDStatus)) 730 break; 731 732 InterfaceInfo = (PUSBD_INTERFACE_INFORMATION) 733 ((ULONG_PTR)InterfaceInfo + 734 InterfaceInfo->Length); 735 } 736 737 if (ix >= iNumber) 738 { 739 Status = USBPORT_USBDStatusToNtStatus(Urb, 740 USBD_STATUS_SUCCESS); 741 } 742 else 743 { 744 Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 745 } 746 747 Exit: 748 749 if (NT_SUCCESS(Status)) 750 { 751 Urb->UrbSelectConfiguration.ConfigurationHandle = ConfigHandle; 752 DeviceHandle->ConfigHandle = ConfigHandle; 753 } 754 else 755 { 756 DPRINT1("USBPORT_HandleSelectConfiguration: Status %x\n", Status); 757 } 758 759 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 760 LOW_REALTIME_PRIORITY, 761 1, 762 FALSE); 763 764 return Status; 765 } 766 767 VOID 768 NTAPI 769 USBPORT_AddDeviceHandle(IN PDEVICE_OBJECT FdoDevice, 770 IN PUSBPORT_DEVICE_HANDLE DeviceHandle) 771 { 772 PUSBPORT_DEVICE_EXTENSION FdoExtension; 773 774 DPRINT("USBPORT_AddDeviceHandle: ... \n"); 775 776 FdoExtension = FdoDevice->DeviceExtension; 777 778 InsertTailList(&FdoExtension->DeviceHandleList, 779 &DeviceHandle->DeviceHandleLink); 780 } 781 782 VOID 783 NTAPI 784 USBPORT_RemoveDeviceHandle(IN PDEVICE_OBJECT FdoDevice, 785 IN PUSBPORT_DEVICE_HANDLE DeviceHandle) 786 { 787 PUSBPORT_DEVICE_EXTENSION FdoExtension; 788 KIRQL OldIrql; 789 790 DPRINT("USBPORT_RemoveDeviceHandle \n"); 791 792 FdoExtension = FdoDevice->DeviceExtension; 793 794 KeAcquireSpinLock(&FdoExtension->DeviceHandleSpinLock, &OldIrql); 795 RemoveEntryList(&DeviceHandle->DeviceHandleLink); 796 KeReleaseSpinLock(&FdoExtension->DeviceHandleSpinLock, OldIrql); 797 } 798 799 BOOLEAN 800 NTAPI 801 USBPORT_ValidateDeviceHandle(IN PDEVICE_OBJECT FdoDevice, 802 IN PUSBPORT_DEVICE_HANDLE DeviceHandle) 803 { 804 PUSBPORT_DEVICE_EXTENSION FdoExtension; 805 KIRQL OldIrql; 806 PLIST_ENTRY HandleList; 807 PUSBPORT_DEVICE_HANDLE CurrentHandle; 808 BOOLEAN Result = FALSE; 809 810 //DPRINT("USBPORT_ValidateDeviceHandle: DeviceHandle - %p\n", DeviceHandle \n"); 811 812 FdoExtension = FdoDevice->DeviceExtension; 813 814 KeAcquireSpinLock(&FdoExtension->DeviceHandleSpinLock, &OldIrql); 815 if (DeviceHandle) 816 { 817 HandleList = FdoExtension->DeviceHandleList.Flink; 818 819 while (HandleList != &FdoExtension->DeviceHandleList) 820 { 821 CurrentHandle = CONTAINING_RECORD(HandleList, 822 USBPORT_DEVICE_HANDLE, 823 DeviceHandleLink); 824 825 if (CurrentHandle == DeviceHandle) 826 { 827 Result = TRUE; 828 break; 829 } 830 831 HandleList = HandleList->Flink; 832 } 833 } 834 KeReleaseSpinLock(&FdoExtension->DeviceHandleSpinLock, OldIrql); 835 836 return Result; 837 } 838 839 BOOLEAN 840 NTAPI 841 USBPORT_DeviceHasTransfers(IN PDEVICE_OBJECT FdoDevice, 842 IN PUSBPORT_DEVICE_HANDLE DeviceHandle) 843 { 844 PLIST_ENTRY PipeHandleList; 845 PUSBPORT_PIPE_HANDLE PipeHandle; 846 847 DPRINT("USBPORT_DeviceHasTransfers: ... \n"); 848 849 PipeHandleList = DeviceHandle->PipeHandleList.Flink; 850 851 while (PipeHandleList != &DeviceHandle->PipeHandleList) 852 { 853 PipeHandle = CONTAINING_RECORD(PipeHandleList, 854 USBPORT_PIPE_HANDLE, 855 PipeLink); 856 857 PipeHandleList = PipeHandleList->Flink; 858 859 if (!(PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE) && 860 USBPORT_EndpointHasQueuedTransfers(FdoDevice, PipeHandle->Endpoint, NULL)) 861 { 862 return TRUE; 863 } 864 } 865 866 return FALSE; 867 } 868 869 VOID 870 NTAPI 871 USBPORT_AbortTransfers(IN PDEVICE_OBJECT FdoDevice, 872 IN PUSBPORT_DEVICE_HANDLE DeviceHandle) 873 { 874 PLIST_ENTRY HandleList; 875 PUSBPORT_PIPE_HANDLE PipeHandle; 876 BOOLEAN Result; 877 878 DPRINT("USBPORT_AbortAllTransfers: ... \n"); 879 880 HandleList = DeviceHandle->PipeHandleList.Flink; 881 882 while (HandleList != &DeviceHandle->PipeHandleList) 883 { 884 PipeHandle = CONTAINING_RECORD(HandleList, 885 USBPORT_PIPE_HANDLE, 886 PipeLink); 887 888 HandleList = HandleList->Flink; 889 890 if (!(PipeHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB)) 891 { 892 PipeHandle->Endpoint->Flags |= ENDPOINT_FLAG_ABORTING; 893 894 USBPORT_AbortEndpoint(FdoDevice, PipeHandle->Endpoint, NULL); 895 USBPORT_FlushMapTransfers(FdoDevice); 896 } 897 } 898 899 while (TRUE) 900 { 901 Result = USBPORT_DeviceHasTransfers(FdoDevice, DeviceHandle); 902 903 if (!Result) 904 break; 905 906 USBPORT_Wait(FdoDevice, 100); 907 } 908 } 909 910 PUSB2_TT_EXTENSION 911 NTAPI 912 USBPORT_GetTt(IN PDEVICE_OBJECT FdoDevice, 913 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, 914 OUT PUSHORT OutPort, 915 OUT PUSBPORT_DEVICE_HANDLE * OutHubDeviceHandle) 916 { 917 PUSBPORT_DEVICE_HANDLE DeviceHandle = HubDeviceHandle; 918 ULONG TtCount; 919 PLIST_ENTRY Entry; 920 PUSB2_TT_EXTENSION TtExtension = NULL; 921 922 DPRINT("USBPORT_GetTt: HubDeviceHandle - %p\n", HubDeviceHandle); 923 924 *OutHubDeviceHandle = NULL; 925 926 while (DeviceHandle->DeviceSpeed != UsbHighSpeed) 927 { 928 DPRINT("USBPORT_GetTt: DeviceHandle - %p, DeviceHandle->PortNumber - %X\n", 929 DeviceHandle, 930 DeviceHandle->PortNumber); 931 932 *OutPort = DeviceHandle->PortNumber; 933 934 DeviceHandle = DeviceHandle->HubDeviceHandle; 935 936 if (!DeviceHandle) 937 return NULL; 938 } 939 940 TtCount = DeviceHandle->TtCount; 941 942 if (!TtCount) 943 return NULL; 944 945 if (IsListEmpty(&DeviceHandle->TtList)) 946 return NULL; 947 948 Entry = DeviceHandle->TtList.Flink; 949 950 if (TtCount > 1) 951 { 952 while (Entry != &DeviceHandle->TtList) 953 { 954 ASSERT(Entry != NULL); 955 956 TtExtension = CONTAINING_RECORD(Entry, 957 USB2_TT_EXTENSION, 958 Link); 959 960 if (TtExtension->TtNumber == *OutPort) 961 break; 962 963 Entry = Entry->Flink; 964 965 TtExtension = NULL; 966 } 967 } 968 else 969 { 970 TtExtension = CONTAINING_RECORD(Entry, 971 USB2_TT_EXTENSION, 972 Link); 973 } 974 975 *OutHubDeviceHandle = DeviceHandle; 976 977 return TtExtension; 978 } 979 980 NTSTATUS 981 NTAPI 982 USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, 983 IN PDEVICE_OBJECT FdoDevice, 984 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, 985 IN USHORT PortStatus, 986 IN USHORT Port) 987 { 988 PUSBPORT_DEVICE_HANDLE TtDeviceHandle = NULL; 989 PUSB2_TT_EXTENSION TtExtension = NULL; 990 USHORT port; 991 PUSBPORT_DEVICE_HANDLE DeviceHandle; 992 PUSBPORT_PIPE_HANDLE PipeHandle; 993 BOOL IsOpenedPipe; 994 PVOID DeviceDescriptor; 995 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 996 ULONG TransferedLen; 997 ULONG DescriptorMinSize; 998 UCHAR MaxPacketSize; 999 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1000 PUSBPORT_REGISTRATION_PACKET Packet; 1001 NTSTATUS Status; 1002 1003 DPRINT("USBPORT_CreateDevice: PortStatus - %p, Port - %x\n", 1004 PortStatus, 1005 Port); 1006 1007 FdoExtension = FdoDevice->DeviceExtension; 1008 Packet = &FdoExtension->MiniPortInterface->Packet; 1009 1010 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1011 Executive, 1012 KernelMode, 1013 FALSE, 1014 NULL); 1015 1016 if (!USBPORT_ValidateDeviceHandle(FdoDevice, HubDeviceHandle)) 1017 { 1018 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1019 LOW_REALTIME_PRIORITY, 1020 1, 1021 FALSE); 1022 1023 DPRINT1("USBPORT_CreateDevice: Not valid hub DeviceHandle\n"); 1024 return STATUS_DEVICE_NOT_CONNECTED; 1025 } 1026 1027 port = Port; 1028 1029 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2 && 1030 !(PortStatus & USB_PORT_STATUS_HIGH_SPEED)) 1031 { 1032 DPRINT1("USBPORT_CreateDevice: USB1 device connected to USB2 port\n"); 1033 1034 TtExtension = USBPORT_GetTt(FdoDevice, 1035 HubDeviceHandle, 1036 &port, 1037 &TtDeviceHandle); 1038 1039 DPRINT("USBPORT_CreateDevice: TtDeviceHandle - %p, port - %x\n", 1040 TtDeviceHandle, 1041 port); 1042 } 1043 1044 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1045 LOW_REALTIME_PRIORITY, 1046 1, 1047 FALSE); 1048 1049 DeviceHandle = ExAllocatePoolWithTag(NonPagedPool, 1050 sizeof(USBPORT_DEVICE_HANDLE), 1051 USB_PORT_TAG); 1052 1053 if (!DeviceHandle) 1054 { 1055 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceHandle\n"); 1056 return STATUS_INSUFFICIENT_RESOURCES; 1057 } 1058 1059 RtlZeroMemory(DeviceHandle, sizeof(USBPORT_DEVICE_HANDLE)); 1060 1061 *pUsbdDeviceHandle = NULL; 1062 1063 DeviceHandle->TtExtension = TtExtension; 1064 DeviceHandle->PortNumber = Port; 1065 DeviceHandle->HubDeviceHandle = HubDeviceHandle; 1066 1067 if (PortStatus & USB_PORT_STATUS_LOW_SPEED) 1068 { 1069 DeviceHandle->DeviceSpeed = UsbLowSpeed; 1070 } 1071 else if (PortStatus & USB_PORT_STATUS_HIGH_SPEED) 1072 { 1073 DeviceHandle->DeviceSpeed = UsbHighSpeed; 1074 } 1075 else 1076 { 1077 DeviceHandle->DeviceSpeed = UsbFullSpeed; 1078 } 1079 1080 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1081 Executive, 1082 KernelMode, 1083 FALSE, 1084 NULL); 1085 1086 PipeHandle = &DeviceHandle->PipeHandle; 1087 1088 PipeHandle->Flags = PIPE_HANDLE_FLAG_CLOSED; 1089 1090 PipeHandle->EndpointDescriptor.bLength = sizeof(PipeHandle->EndpointDescriptor); 1091 PipeHandle->EndpointDescriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE; 1092 1093 if (DeviceHandle->DeviceSpeed == UsbLowSpeed) 1094 { 1095 PipeHandle->EndpointDescriptor.wMaxPacketSize = 8; 1096 } 1097 else 1098 { 1099 PipeHandle->EndpointDescriptor.wMaxPacketSize = USB_DEFAULT_MAX_PACKET; 1100 } 1101 1102 InitializeListHead(&DeviceHandle->PipeHandleList); 1103 InitializeListHead(&DeviceHandle->TtList); 1104 1105 Status = USBPORT_OpenPipe(FdoDevice, 1106 DeviceHandle, 1107 PipeHandle, 1108 NULL); 1109 1110 IsOpenedPipe = NT_SUCCESS(Status); 1111 1112 if (NT_ERROR(Status)) 1113 { 1114 DPRINT1("USBPORT_CreateDevice: USBPORT_OpenPipe return - %lx\n", Status); 1115 1116 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1117 LOW_REALTIME_PRIORITY, 1118 1, 1119 FALSE); 1120 1121 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG); 1122 1123 return Status; 1124 } 1125 1126 DeviceDescriptor = ExAllocatePoolWithTag(NonPagedPool, 1127 USB_DEFAULT_MAX_PACKET, 1128 USB_PORT_TAG); 1129 1130 if (!DeviceDescriptor) 1131 { 1132 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceDescriptor\n"); 1133 goto ErrorExit; 1134 } 1135 1136 RtlZeroMemory(DeviceDescriptor, USB_DEFAULT_MAX_PACKET); 1137 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1138 1139 SetupPacket.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 1140 SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; 1141 SetupPacket.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; 1142 SetupPacket.wLength = USB_DEFAULT_MAX_PACKET; 1143 1144 TransferedLen = 0; 1145 1146 Status = USBPORT_SendSetupPacket(DeviceHandle, 1147 FdoDevice, 1148 &SetupPacket, 1149 DeviceDescriptor, 1150 USB_DEFAULT_MAX_PACKET, 1151 &TransferedLen, 1152 NULL); 1153 1154 RtlCopyMemory(&DeviceHandle->DeviceDescriptor, 1155 DeviceDescriptor, 1156 sizeof(USB_DEVICE_DESCRIPTOR)); 1157 1158 ExFreePoolWithTag(DeviceDescriptor, USB_PORT_TAG); 1159 1160 DescriptorMinSize = RTL_SIZEOF_THROUGH_FIELD(USB_DEVICE_DESCRIPTOR, 1161 bMaxPacketSize0); 1162 1163 if ((TransferedLen == DescriptorMinSize) && !NT_SUCCESS(Status)) 1164 { 1165 Status = STATUS_SUCCESS; 1166 } 1167 1168 if (NT_SUCCESS(Status) && (TransferedLen >= DescriptorMinSize)) 1169 { 1170 if ((DeviceHandle->DeviceDescriptor.bLength >= sizeof(USB_DEVICE_DESCRIPTOR)) && 1171 (DeviceHandle->DeviceDescriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE)) 1172 { 1173 MaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0; 1174 1175 if (MaxPacketSize == 8 || 1176 MaxPacketSize == 16 || 1177 MaxPacketSize == 32 || 1178 MaxPacketSize == 64) 1179 { 1180 USBPORT_AddDeviceHandle(FdoDevice, DeviceHandle); 1181 1182 *pUsbdDeviceHandle = DeviceHandle; 1183 1184 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1185 LOW_REALTIME_PRIORITY, 1186 1, 1187 FALSE); 1188 1189 return Status; 1190 } 1191 } 1192 } 1193 1194 DPRINT1("USBPORT_CreateDevice: ERROR!!! TransferedLen - %x, Status - %lx\n", 1195 TransferedLen, 1196 Status); 1197 1198 ErrorExit: 1199 1200 if (TtExtension && TtDeviceHandle) 1201 { 1202 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_OTHER; 1203 SetupPacket.bmRequestType.Reserved = 0; 1204 SetupPacket.bmRequestType.Type = BMREQUEST_CLASS; 1205 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 1206 1207 /* Table 11-15. Hub Class Requests */ 1208 if (TtDeviceHandle == HubDeviceHandle) 1209 { 1210 SetupPacket.bRequest = USB_REQUEST_RESET_TT; 1211 } 1212 else 1213 { 1214 SetupPacket.bRequest = USB_REQUEST_CLEAR_TT_BUFFER; 1215 } 1216 1217 SetupPacket.wValue.LowByte = 0; 1218 SetupPacket.wValue.HiByte = 0; 1219 SetupPacket.wIndex.W = port; 1220 SetupPacket.wLength = 0; 1221 1222 USBPORT_SendSetupPacket(TtDeviceHandle, 1223 FdoDevice, 1224 &SetupPacket, 1225 NULL, 1226 0, 1227 NULL, 1228 NULL); 1229 } 1230 1231 Status = STATUS_DEVICE_DATA_ERROR; 1232 1233 if (IsOpenedPipe) 1234 { 1235 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle); 1236 } 1237 1238 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1239 LOW_REALTIME_PRIORITY, 1240 1, 1241 FALSE); 1242 1243 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG); 1244 1245 return Status; 1246 } 1247 1248 ULONG 1249 NTAPI 1250 USBPORT_AllocateUsbAddress(IN PDEVICE_OBJECT FdoDevice) 1251 { 1252 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1253 ULONG BitMapIdx; 1254 ULONG BitNumber; 1255 ULONG ix; 1256 1257 DPRINT("USBPORT_AllocateUsbAddress \n"); 1258 1259 FdoExtension = FdoDevice->DeviceExtension; 1260 1261 for (ix = 0; ix < 4; ++ix) 1262 { 1263 BitMapIdx = 1; 1264 1265 for (BitNumber = 0; BitNumber < 32; ++BitNumber) 1266 { 1267 if (!(FdoExtension->UsbAddressBitMap[ix] & BitMapIdx)) 1268 { 1269 FdoExtension->UsbAddressBitMap[ix] |= BitMapIdx; 1270 return 32 * ix + BitNumber; 1271 } 1272 1273 BitMapIdx <<= 2; 1274 } 1275 } 1276 1277 return 0; 1278 } 1279 1280 VOID 1281 NTAPI 1282 USBPORT_FreeUsbAddress(IN PDEVICE_OBJECT FdoDevice, 1283 IN USHORT DeviceAddress) 1284 { 1285 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1286 ULONG ix; 1287 ULONG BitMapIdx; 1288 ULONG BitNumber; 1289 USHORT CurrentAddress; 1290 1291 DPRINT("USBPORT_FreeUsbAddress: DeviceAddress - %x\n", DeviceAddress); 1292 1293 FdoExtension = FdoDevice->DeviceExtension; 1294 1295 for (ix = 0; ix < 4; ++ix) 1296 { 1297 BitMapIdx = 1; 1298 CurrentAddress = 32 * ix; 1299 1300 for (BitNumber = 0; BitNumber < 32; ++BitNumber) 1301 { 1302 if (CurrentAddress == DeviceAddress) 1303 { 1304 FdoExtension->UsbAddressBitMap[ix] &= ~BitMapIdx; 1305 return; 1306 } 1307 1308 BitMapIdx <<= 2; 1309 CurrentAddress++; 1310 } 1311 } 1312 } 1313 1314 NTSTATUS 1315 NTAPI 1316 USBPORT_InitializeDevice(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, 1317 IN PDEVICE_OBJECT FdoDevice) 1318 { 1319 PUSBPORT_ENDPOINT Endpoint; 1320 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; 1321 ULONG TransferedLen; 1322 USHORT DeviceAddress = 0; 1323 UCHAR MaxPacketSize; 1324 NTSTATUS Status; 1325 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1326 1327 DPRINT("USBPORT_InitializeDevice: ... \n"); 1328 1329 ASSERT(DeviceHandle != NULL); 1330 1331 FdoExtension = FdoDevice->DeviceExtension; 1332 1333 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1334 Executive, 1335 KernelMode, 1336 FALSE, 1337 NULL); 1338 1339 DeviceAddress = USBPORT_AllocateUsbAddress(FdoDevice); 1340 ASSERT(DeviceHandle->DeviceAddress == USB_DEFAULT_DEVICE_ADDRESS); 1341 1342 RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1343 1344 CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS; 1345 CtrlSetup.wValue.W = DeviceAddress; 1346 1347 Status = USBPORT_SendSetupPacket(DeviceHandle, 1348 FdoDevice, 1349 &CtrlSetup, 1350 NULL, 1351 0, 1352 NULL, 1353 NULL); 1354 1355 DPRINT("USBPORT_InitializeDevice: DeviceAddress - %x. SendSetupPacket Status - %x\n", 1356 DeviceAddress, 1357 Status); 1358 1359 if (!NT_SUCCESS(Status)) 1360 goto ExitError; 1361 1362 DeviceHandle->DeviceAddress = DeviceAddress; 1363 Endpoint = DeviceHandle->PipeHandle.Endpoint; 1364 1365 Endpoint->EndpointProperties.TotalMaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0; 1366 Endpoint->EndpointProperties.DeviceAddress = DeviceAddress; 1367 1368 Status = USBPORT_ReopenPipe(FdoDevice, Endpoint); 1369 1370 if (!NT_SUCCESS(Status)) 1371 goto ExitError; 1372 1373 USBPORT_Wait(FdoDevice, 10); 1374 1375 RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1376 1377 CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; 1378 CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; 1379 CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR); 1380 CtrlSetup.bmRequestType.B = 0x80; 1381 1382 Status = USBPORT_SendSetupPacket(DeviceHandle, 1383 FdoDevice, 1384 &CtrlSetup, 1385 &DeviceHandle->DeviceDescriptor, 1386 sizeof(USB_DEVICE_DESCRIPTOR), 1387 &TransferedLen, 1388 NULL); 1389 1390 if (NT_SUCCESS(Status)) 1391 { 1392 ASSERT(TransferedLen == sizeof(USB_DEVICE_DESCRIPTOR)); 1393 ASSERT(DeviceHandle->DeviceDescriptor.bLength >= sizeof(USB_DEVICE_DESCRIPTOR)); 1394 ASSERT(DeviceHandle->DeviceDescriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE); 1395 1396 MaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0; 1397 1398 ASSERT((MaxPacketSize == 8) || 1399 (MaxPacketSize == 16) || 1400 (MaxPacketSize == 32) || 1401 (MaxPacketSize == 64)); 1402 1403 if (DeviceHandle->DeviceSpeed == UsbHighSpeed && 1404 DeviceHandle->DeviceDescriptor.bDeviceClass == USB_DEVICE_CLASS_HUB) 1405 { 1406 DeviceHandle->Flags |= DEVICE_HANDLE_FLAG_USB2HUB; 1407 } 1408 } 1409 else 1410 { 1411 ExitError: 1412 DPRINT1("USBPORT_InitializeDevice: ExitError. Status - %x\n", Status); 1413 } 1414 1415 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1416 LOW_REALTIME_PRIORITY, 1417 1, 1418 FALSE); 1419 1420 return Status; 1421 } 1422 1423 NTSTATUS 1424 NTAPI 1425 USBPORT_GetUsbDescriptor(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, 1426 IN PDEVICE_OBJECT FdoDevice, 1427 IN UCHAR Type, 1428 IN PUCHAR ConfigDesc, 1429 IN PULONG ConfigDescSize) 1430 { 1431 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 1432 1433 DPRINT("USBPORT_GetUsbDescriptor: Type - %x\n"); 1434 1435 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1436 1437 SetupPacket.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 1438 SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; 1439 SetupPacket.wValue.HiByte = Type; 1440 SetupPacket.wLength = (USHORT)*ConfigDescSize; 1441 1442 return USBPORT_SendSetupPacket(DeviceHandle, 1443 FdoDevice, 1444 &SetupPacket, 1445 ConfigDesc, 1446 *ConfigDescSize, 1447 ConfigDescSize, 1448 NULL); 1449 } 1450 1451 PUSBPORT_INTERFACE_HANDLE 1452 NTAPI 1453 USBPORT_GetInterfaceHandle(IN PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle, 1454 IN UCHAR InterfaceNumber) 1455 { 1456 PUSBPORT_INTERFACE_HANDLE InterfaceHandle; 1457 PLIST_ENTRY iHandleList; 1458 UCHAR InterfaceNum; 1459 1460 DPRINT("USBPORT_GetInterfaceHandle: ConfigurationHandle - %p, InterfaceNumber - %p\n", 1461 ConfigurationHandle, 1462 InterfaceNumber); 1463 1464 iHandleList = ConfigurationHandle->InterfaceHandleList.Flink; 1465 1466 while (iHandleList && 1467 (iHandleList != &ConfigurationHandle->InterfaceHandleList)) 1468 { 1469 InterfaceHandle = CONTAINING_RECORD(iHandleList, 1470 USBPORT_INTERFACE_HANDLE, 1471 InterfaceLink); 1472 1473 InterfaceNum = InterfaceHandle->InterfaceDescriptor.bInterfaceNumber; 1474 1475 if (InterfaceNum == InterfaceNumber) 1476 return InterfaceHandle; 1477 1478 iHandleList = InterfaceHandle->InterfaceLink.Flink; 1479 } 1480 1481 return NULL; 1482 } 1483 1484 NTSTATUS 1485 NTAPI 1486 USBPORT_HandleSelectInterface(IN PDEVICE_OBJECT FdoDevice, 1487 IN PIRP Irp, 1488 IN PURB Urb) 1489 { 1490 PUSBPORT_DEVICE_HANDLE DeviceHandle; 1491 PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle; 1492 PUSBD_INTERFACE_INFORMATION Interface; 1493 PUSBPORT_INTERFACE_HANDLE InterfaceHandle; 1494 PUSBPORT_INTERFACE_HANDLE iHandle; 1495 PUSBPORT_PIPE_HANDLE PipeHandle; 1496 USBD_STATUS USBDStatus; 1497 USHORT Length; 1498 ULONG ix; 1499 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1500 1501 DPRINT("USBPORT_HandleSelectInterface: ... \n"); 1502 1503 FdoExtension = FdoDevice->DeviceExtension; 1504 1505 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1506 Executive, 1507 KernelMode, 1508 FALSE, 1509 NULL); 1510 1511 ConfigurationHandle = Urb->UrbSelectInterface.ConfigurationHandle; 1512 1513 Interface = &Urb->UrbSelectInterface.Interface; 1514 1515 Length = Interface->Length + sizeof(USBD_PIPE_INFORMATION); 1516 Urb->UrbHeader.Length = Length; 1517 1518 USBDStatus = USBPORT_InitInterfaceInfo(Interface, ConfigurationHandle); 1519 1520 if (USBDStatus) 1521 { 1522 Interface->InterfaceHandle = (USBD_INTERFACE_HANDLE)-1; 1523 return USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 1524 } 1525 1526 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 1527 1528 InterfaceHandle = USBPORT_GetInterfaceHandle(ConfigurationHandle, 1529 Interface->InterfaceNumber); 1530 1531 if (InterfaceHandle) 1532 { 1533 RemoveEntryList(&InterfaceHandle->InterfaceLink); 1534 1535 if (InterfaceHandle->InterfaceDescriptor.bNumEndpoints) 1536 { 1537 PipeHandle = &InterfaceHandle->PipeHandle[0]; 1538 1539 for (ix = 0; 1540 ix < InterfaceHandle->InterfaceDescriptor.bNumEndpoints; 1541 ix++) 1542 { 1543 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle); 1544 PipeHandle += 1; 1545 } 1546 } 1547 } 1548 1549 iHandle = 0; 1550 1551 USBDStatus = USBPORT_OpenInterface(Urb, 1552 DeviceHandle, 1553 FdoDevice, 1554 ConfigurationHandle, 1555 Interface, 1556 &iHandle, 1557 TRUE); 1558 1559 if (USBDStatus) 1560 { 1561 Interface->InterfaceHandle = (USBD_INTERFACE_HANDLE)-1; 1562 } 1563 else 1564 { 1565 if (InterfaceHandle) 1566 ExFreePoolWithTag(InterfaceHandle, USB_PORT_TAG); 1567 1568 Interface->InterfaceHandle = iHandle; 1569 1570 InsertTailList(&ConfigurationHandle->InterfaceHandleList, 1571 &iHandle->InterfaceLink); 1572 } 1573 1574 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1575 LOW_REALTIME_PRIORITY, 1576 1, 1577 FALSE); 1578 1579 return USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 1580 } 1581 1582 NTSTATUS 1583 NTAPI 1584 USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice, 1585 IN OUT PUSBPORT_DEVICE_HANDLE DeviceHandle, 1586 IN ULONG Flags) 1587 { 1588 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1589 PUSB2_TT_EXTENSION TtExtension; 1590 ULONG ix; 1591 KIRQL OldIrql; 1592 1593 DPRINT("USBPORT_RemoveDevice: DeviceHandle - %p, Flags - %x\n", 1594 DeviceHandle, 1595 Flags); 1596 1597 FdoExtension = FdoDevice->DeviceExtension; 1598 1599 if ((Flags & USBD_KEEP_DEVICE_DATA) || 1600 (Flags & USBD_MARK_DEVICE_BUSY)) 1601 { 1602 return STATUS_SUCCESS; 1603 } 1604 1605 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1606 Executive, 1607 KernelMode, 1608 FALSE, 1609 NULL); 1610 1611 if (!USBPORT_ValidateDeviceHandle(FdoDevice, DeviceHandle)) 1612 { 1613 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1614 LOW_REALTIME_PRIORITY, 1615 1, 1616 FALSE); 1617 1618 DPRINT1("USBPORT_RemoveDevice: Not valid device handle\n"); 1619 return STATUS_DEVICE_NOT_CONNECTED; 1620 } 1621 1622 USBPORT_RemoveDeviceHandle(FdoDevice, DeviceHandle); 1623 1624 DeviceHandle->Flags |= DEVICE_HANDLE_FLAG_REMOVED; 1625 1626 USBPORT_AbortTransfers(FdoDevice, DeviceHandle); 1627 1628 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock - %x\n", 1629 DeviceHandle->DeviceHandleLock); 1630 1631 while (InterlockedDecrement(&DeviceHandle->DeviceHandleLock) >= 0) 1632 { 1633 InterlockedIncrement(&DeviceHandle->DeviceHandleLock); 1634 USBPORT_Wait(FdoDevice, 100); 1635 } 1636 1637 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock ok\n"); 1638 1639 if (DeviceHandle->ConfigHandle) 1640 { 1641 USBPORT_CloseConfiguration(DeviceHandle, FdoDevice); 1642 } 1643 1644 USBPORT_ClosePipe(DeviceHandle, FdoDevice, &DeviceHandle->PipeHandle); 1645 1646 if (DeviceHandle->DeviceAddress) 1647 { 1648 USBPORT_FreeUsbAddress(FdoDevice, DeviceHandle->DeviceAddress); 1649 } 1650 1651 if (!IsListEmpty(&DeviceHandle->TtList)) 1652 { 1653 DPRINT1("USBPORT_RemoveDevice: DeviceHandle->TtList not empty\n"); 1654 } 1655 1656 while (!IsListEmpty(&DeviceHandle->TtList)) 1657 { 1658 TtExtension = CONTAINING_RECORD(DeviceHandle->TtList.Flink, 1659 USB2_TT_EXTENSION, 1660 Link); 1661 1662 RemoveHeadList(&DeviceHandle->TtList); 1663 1664 DPRINT("USBPORT_RemoveDevice: TtExtension - %p\n", TtExtension); 1665 1666 KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql); 1667 1668 TtExtension->Flags |= USB2_TT_EXTENSION_FLAG_DELETED; 1669 1670 if (IsListEmpty(&TtExtension->EndpointList)) 1671 { 1672 USBPORT_UpdateAllocatedBwTt(TtExtension); 1673 1674 for (ix = 0; ix < USB2_FRAMES; ix++) 1675 { 1676 FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth; 1677 } 1678 1679 DPRINT("USBPORT_RemoveDevice: ExFreePoolWithTag TtExtension - %p\n", TtExtension); 1680 ExFreePoolWithTag(TtExtension, USB_PORT_TAG); 1681 } 1682 1683 KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql); 1684 } 1685 1686 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1687 LOW_REALTIME_PRIORITY, 1688 1, 1689 FALSE); 1690 1691 if (!(DeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB)) 1692 { 1693 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG); 1694 } 1695 1696 return STATUS_SUCCESS; 1697 } 1698 1699 NTSTATUS 1700 NTAPI 1701 USBPORT_RestoreDevice(IN PDEVICE_OBJECT FdoDevice, 1702 IN OUT PUSBPORT_DEVICE_HANDLE OldDeviceHandle, 1703 IN OUT PUSBPORT_DEVICE_HANDLE NewDeviceHandle) 1704 { 1705 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1706 PLIST_ENTRY iHandleList; 1707 PUSBPORT_ENDPOINT Endpoint; 1708 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements = {0}; 1709 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 1710 NTSTATUS Status = STATUS_SUCCESS; 1711 USBD_STATUS USBDStatus; 1712 KIRQL OldIrql; 1713 PUSBPORT_INTERFACE_HANDLE InterfaceHandle; 1714 PUSBPORT_PIPE_HANDLE PipeHandle; 1715 PUSBPORT_REGISTRATION_PACKET Packet; 1716 1717 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle - %p, NewDeviceHandle - %p\n", 1718 OldDeviceHandle, 1719 NewDeviceHandle); 1720 1721 FdoExtension = FdoDevice->DeviceExtension; 1722 1723 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1724 Executive, 1725 KernelMode, 1726 FALSE, 1727 NULL); 1728 1729 if (!USBPORT_ValidateDeviceHandle(FdoDevice, OldDeviceHandle)) 1730 { 1731 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1732 LOW_REALTIME_PRIORITY, 1733 1, 1734 FALSE); 1735 1736 #ifndef NDEBUG 1737 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle not valid\n"); 1738 DbgBreakPoint(); 1739 #endif 1740 return STATUS_DEVICE_NOT_CONNECTED; 1741 } 1742 1743 if (!USBPORT_ValidateDeviceHandle(FdoDevice, NewDeviceHandle)) 1744 { 1745 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1746 LOW_REALTIME_PRIORITY, 1747 1, 1748 FALSE); 1749 #ifndef NDEBUG 1750 DPRINT("USBPORT_RestoreDevice: NewDeviceHandle not valid\n"); 1751 DbgBreakPoint(); 1752 #endif 1753 return STATUS_DEVICE_NOT_CONNECTED; 1754 } 1755 1756 USBPORT_RemoveDeviceHandle(FdoDevice, OldDeviceHandle); 1757 USBPORT_AbortTransfers(FdoDevice, OldDeviceHandle); 1758 1759 while (InterlockedDecrement(&OldDeviceHandle->DeviceHandleLock) >= 0) 1760 { 1761 InterlockedIncrement(&OldDeviceHandle->DeviceHandleLock); 1762 USBPORT_Wait(FdoDevice, 100); 1763 } 1764 1765 if (sizeof(USB_DEVICE_DESCRIPTOR) == RtlCompareMemory(&NewDeviceHandle->DeviceDescriptor, 1766 &OldDeviceHandle->DeviceDescriptor, 1767 sizeof(USB_DEVICE_DESCRIPTOR))) 1768 { 1769 NewDeviceHandle->ConfigHandle = OldDeviceHandle->ConfigHandle; 1770 1771 if (OldDeviceHandle->ConfigHandle) 1772 { 1773 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1774 1775 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 1776 SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION; 1777 SetupPacket.wValue.W = OldDeviceHandle->ConfigHandle->ConfigurationDescriptor->bConfigurationValue; 1778 SetupPacket.wIndex.W = 0; 1779 SetupPacket.wLength = 0; 1780 1781 USBPORT_SendSetupPacket(NewDeviceHandle, 1782 FdoDevice, 1783 &SetupPacket, 1784 NULL, 1785 0, 1786 NULL, 1787 &USBDStatus); 1788 1789 if (USBD_ERROR(USBDStatus)) 1790 Status = USBPORT_USBDStatusToNtStatus(NULL, USBDStatus); 1791 1792 if (NT_SUCCESS(Status)) 1793 { 1794 iHandleList = NewDeviceHandle->ConfigHandle->InterfaceHandleList.Flink; 1795 1796 while (iHandleList && 1797 iHandleList != &NewDeviceHandle->ConfigHandle->InterfaceHandleList) 1798 { 1799 InterfaceHandle = CONTAINING_RECORD(iHandleList, 1800 USBPORT_INTERFACE_HANDLE, 1801 InterfaceLink); 1802 1803 if (InterfaceHandle->AlternateSetting) 1804 { 1805 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1806 1807 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 1808 SetupPacket.bmRequestType.Type = BMREQUEST_STANDARD; 1809 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 1810 1811 SetupPacket.bRequest = USB_REQUEST_SET_INTERFACE; 1812 SetupPacket.wValue.W = InterfaceHandle->InterfaceDescriptor.bAlternateSetting; 1813 SetupPacket.wIndex.W = InterfaceHandle->InterfaceDescriptor.bInterfaceNumber; 1814 SetupPacket.wLength = 0; 1815 1816 USBPORT_SendSetupPacket(NewDeviceHandle, 1817 FdoDevice, 1818 &SetupPacket, 1819 NULL, 1820 0, 1821 NULL, 1822 &USBDStatus); 1823 } 1824 1825 iHandleList = iHandleList->Flink; 1826 } 1827 } 1828 } 1829 1830 if (NewDeviceHandle->Flags & DEVICE_HANDLE_FLAG_USB2HUB) 1831 { 1832 DPRINT1("USBPORT_RestoreDevice: FIXME Transaction Translator\n"); 1833 NewDeviceHandle->TtCount = OldDeviceHandle->TtCount; 1834 1835 #ifndef NDEBUG 1836 DbgBreakPoint(); 1837 #endif 1838 } 1839 1840 while (!IsListEmpty(&OldDeviceHandle->PipeHandleList)) 1841 { 1842 PipeHandle = CONTAINING_RECORD(OldDeviceHandle->PipeHandleList.Flink, 1843 USBPORT_PIPE_HANDLE, 1844 PipeLink); 1845 1846 DPRINT("USBPORT_RestoreDevice: PipeHandle - %p\n", PipeHandle); 1847 1848 USBPORT_RemovePipeHandle(OldDeviceHandle, PipeHandle); 1849 1850 if (PipeHandle != &OldDeviceHandle->PipeHandle) 1851 { 1852 USBPORT_AddPipeHandle(NewDeviceHandle, PipeHandle); 1853 1854 if (!(PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)) 1855 { 1856 Endpoint = PipeHandle->Endpoint; 1857 Endpoint->DeviceHandle = NewDeviceHandle; 1858 Endpoint->EndpointProperties.DeviceAddress = NewDeviceHandle->DeviceAddress; 1859 1860 Packet = &FdoExtension->MiniPortInterface->Packet; 1861 1862 if (!(Endpoint->Flags & ENDPOINT_FLAG_NUKE)) 1863 { 1864 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, 1865 &OldIrql); 1866 1867 Packet->ReopenEndpoint(FdoExtension->MiniPortExt, 1868 &Endpoint->EndpointProperties, 1869 Endpoint + 1); 1870 1871 Packet->SetEndpointDataToggle(FdoExtension->MiniPortExt, 1872 Endpoint + 1, 1873 0); 1874 1875 Packet->SetEndpointStatus(FdoExtension->MiniPortExt, 1876 Endpoint + 1, 1877 USBPORT_ENDPOINT_RUN); 1878 1879 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, 1880 OldIrql); 1881 } 1882 else 1883 { 1884 MiniportCloseEndpoint(FdoDevice, Endpoint); 1885 1886 RtlZeroMemory(Endpoint + 1, Packet->MiniPortEndpointSize); 1887 1888 RtlZeroMemory((PVOID)Endpoint->EndpointProperties.BufferVA, 1889 Endpoint->EndpointProperties.BufferLength); 1890 1891 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql); 1892 1893 Packet->QueryEndpointRequirements(FdoExtension->MiniPortExt, 1894 &Endpoint->EndpointProperties, 1895 &EndpointRequirements); 1896 1897 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, 1898 OldIrql); 1899 1900 MiniportOpenEndpoint(FdoDevice, Endpoint); 1901 1902 Endpoint->Flags &= ~(ENDPOINT_FLAG_NUKE | 1903 ENDPOINT_FLAG_ABORTING); 1904 1905 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, 1906 &Endpoint->EndpointOldIrql); 1907 1908 if (Endpoint->StateLast == USBPORT_ENDPOINT_ACTIVE) 1909 { 1910 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock); 1911 1912 Packet->SetEndpointState(FdoExtension->MiniPortExt, 1913 Endpoint + 1, 1914 USBPORT_ENDPOINT_ACTIVE); 1915 1916 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock); 1917 } 1918 1919 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 1920 Endpoint->EndpointOldIrql); 1921 } 1922 } 1923 } 1924 } 1925 1926 USBPORT_AddPipeHandle(OldDeviceHandle, &OldDeviceHandle->PipeHandle); 1927 } 1928 else 1929 { 1930 #ifndef NDEBUG 1931 DPRINT("USBPORT_RestoreDevice: New DeviceDescriptor != Old DeviceDescriptor\n"); 1932 DbgBreakPoint(); 1933 #endif 1934 Status = STATUS_UNSUCCESSFUL; 1935 } 1936 1937 USBPORT_ClosePipe(OldDeviceHandle, FdoDevice, &OldDeviceHandle->PipeHandle); 1938 1939 if (OldDeviceHandle->DeviceAddress != 0) 1940 USBPORT_FreeUsbAddress(FdoDevice, OldDeviceHandle->DeviceAddress); 1941 1942 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1943 LOW_REALTIME_PRIORITY, 1944 1, 1945 FALSE); 1946 1947 ExFreePoolWithTag(OldDeviceHandle, USB_PORT_TAG); 1948 1949 return Status; 1950 } 1951 1952 NTSTATUS 1953 NTAPI 1954 USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice, 1955 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, 1956 IN ULONG TtNumber) 1957 { 1958 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1959 PUSB2_TT_EXTENSION TtExtension; 1960 ULONG ix; 1961 1962 DPRINT("USBPORT_InitializeTT: HubDeviceHandle - %p, TtNumber - %X\n", 1963 HubDeviceHandle, 1964 TtNumber); 1965 1966 FdoExtension = FdoDevice->DeviceExtension; 1967 1968 TtExtension = ExAllocatePoolWithTag(NonPagedPool, 1969 sizeof(USB2_TT_EXTENSION), 1970 USB_PORT_TAG); 1971 1972 if (!TtExtension) 1973 { 1974 DPRINT1("USBPORT_InitializeTT: ExAllocatePoolWithTag return NULL\n"); 1975 return STATUS_INSUFFICIENT_RESOURCES; 1976 } 1977 1978 DPRINT("USBPORT_InitializeTT: TtExtension - %p\n", TtExtension); 1979 1980 RtlZeroMemory(TtExtension, sizeof(USB2_TT_EXTENSION)); 1981 1982 TtExtension->DeviceAddress = HubDeviceHandle->DeviceAddress; 1983 TtExtension->TtNumber = TtNumber; 1984 TtExtension->RootHubPdo = FdoExtension->RootHubPdo; 1985 TtExtension->BusBandwidth = TOTAL_USB11_BUS_BANDWIDTH; 1986 1987 InitializeListHead(&TtExtension->EndpointList); 1988 1989 /* 90% maximum allowed for periodic endpoints */ 1990 for (ix = 0; ix < USB2_FRAMES; ix++) 1991 { 1992 TtExtension->Bandwidth[ix] = TtExtension->BusBandwidth - 1993 TtExtension->BusBandwidth / 10; 1994 } 1995 1996 USBPORT_UpdateAllocatedBwTt(TtExtension); 1997 1998 for (ix = 0; ix < USB2_FRAMES; ix++) 1999 { 2000 FdoExtension->Bandwidth[ix] -= TtExtension->MaxBandwidth; 2001 } 2002 2003 USB2_InitTT(FdoExtension->Usb2Extension, &TtExtension->Tt); 2004 2005 InsertTailList(&HubDeviceHandle->TtList, &TtExtension->Link); 2006 2007 return STATUS_SUCCESS; 2008 } 2009 2010 NTSTATUS 2011 NTAPI 2012 USBPORT_Initialize20Hub(IN PDEVICE_OBJECT FdoDevice, 2013 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, 2014 IN ULONG TtCount) 2015 { 2016 NTSTATUS Status; 2017 ULONG ix; 2018 2019 DPRINT("USBPORT_Initialize20Hub: TtCount - %X\n", TtCount); 2020 2021 if (!HubDeviceHandle) 2022 { 2023 return STATUS_INVALID_PARAMETER; 2024 } 2025 2026 if (HubDeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB) 2027 { 2028 return STATUS_SUCCESS; 2029 } 2030 2031 if (TtCount == 0) 2032 { 2033 HubDeviceHandle->TtCount = 0; 2034 return STATUS_SUCCESS; 2035 } 2036 2037 for (ix = 0; ix < TtCount; ++ix) 2038 { 2039 Status = USBPORT_InitializeTT(FdoDevice, HubDeviceHandle, ix + 1); 2040 2041 if (!NT_SUCCESS(Status)) 2042 break; 2043 } 2044 2045 HubDeviceHandle->TtCount = TtCount; 2046 2047 return Status; 2048 }