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