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 USHORT 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 NTSTATUS 889 NTAPI 890 USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, 891 IN PDEVICE_OBJECT FdoDevice, 892 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, 893 IN USHORT PortStatus, 894 IN USHORT Port) 895 { 896 PUSBPORT_DEVICE_HANDLE DeviceHandle; 897 PUSBPORT_PIPE_HANDLE PipeHandle; 898 BOOL IsOpenedPipe; 899 PVOID DeviceDescriptor; 900 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 901 SIZE_T TransferedLen; 902 SIZE_T DescriptorMinSize; 903 UCHAR MaxPacketSize; 904 PUSBPORT_DEVICE_EXTENSION FdoExtension; 905 906 NTSTATUS Status; 907 908 DPRINT("USBPORT_CreateDevice: PortStatus - %p, Port - %x\n", 909 PortStatus, 910 Port); 911 912 FdoExtension = FdoDevice->DeviceExtension; 913 914 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 915 Executive, 916 KernelMode, 917 FALSE, 918 NULL); 919 920 if (!USBPORT_ValidateDeviceHandle(FdoDevice, HubDeviceHandle)) 921 { 922 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 923 LOW_REALTIME_PRIORITY, 924 1, 925 FALSE); 926 927 DPRINT1("USBPORT_CreateDevice: Not valid hub DeviceHandle\n"); 928 return STATUS_DEVICE_NOT_CONNECTED; 929 } 930 931 if (FdoExtension->MiniPortInterface->Packet.MiniPortFlags & USB_MINIPORT_FLAGS_USB2 && 932 !(PortStatus & USB_PORT_STATUS_HIGH_SPEED)) 933 { 934 DPRINT1("USBPORT_CreateDevice: USB1 device connected to USB2 port. FIXME: Transaction Translator.\n"); 935 DbgBreakPoint(); 936 } 937 938 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 939 LOW_REALTIME_PRIORITY, 940 1, 941 FALSE); 942 943 DeviceHandle = ExAllocatePoolWithTag(NonPagedPool, 944 sizeof(USBPORT_DEVICE_HANDLE), 945 USB_PORT_TAG); 946 947 if (!DeviceHandle) 948 { 949 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceHandle\n"); 950 return STATUS_INSUFFICIENT_RESOURCES; 951 } 952 953 RtlZeroMemory(DeviceHandle, sizeof(USBPORT_DEVICE_HANDLE)); 954 955 *pUsbdDeviceHandle = NULL; 956 957 DeviceHandle->PortNumber = Port; 958 DeviceHandle->HubDeviceHandle = HubDeviceHandle; 959 960 if (PortStatus & USB_PORT_STATUS_LOW_SPEED) 961 { 962 DeviceHandle->DeviceSpeed = UsbLowSpeed; 963 } 964 else if (PortStatus & USB_PORT_STATUS_HIGH_SPEED) 965 { 966 DeviceHandle->DeviceSpeed = UsbHighSpeed; 967 } 968 else 969 { 970 DeviceHandle->DeviceSpeed = UsbFullSpeed; 971 } 972 973 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 974 Executive, 975 KernelMode, 976 FALSE, 977 NULL); 978 979 PipeHandle = &DeviceHandle->PipeHandle; 980 981 PipeHandle->Flags = PIPE_HANDLE_FLAG_CLOSED; 982 983 PipeHandle->EndpointDescriptor.bLength = sizeof(PipeHandle->EndpointDescriptor); 984 PipeHandle->EndpointDescriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE; 985 986 if (DeviceHandle->DeviceSpeed == UsbLowSpeed) 987 { 988 PipeHandle->EndpointDescriptor.wMaxPacketSize = 8; 989 } 990 else 991 { 992 PipeHandle->EndpointDescriptor.wMaxPacketSize = USB_DEFAULT_MAX_PACKET; 993 } 994 995 InitializeListHead(&DeviceHandle->PipeHandleList); 996 997 Status = USBPORT_OpenPipe(FdoDevice, 998 DeviceHandle, 999 PipeHandle, 1000 NULL); 1001 1002 IsOpenedPipe = NT_SUCCESS(Status); 1003 1004 if (NT_ERROR(Status)) 1005 { 1006 DPRINT1("USBPORT_CreateDevice: USBPORT_OpenPipe return - %lx\n", Status); 1007 1008 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1009 LOW_REALTIME_PRIORITY, 1010 1, 1011 FALSE); 1012 1013 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG); 1014 1015 return Status; 1016 } 1017 1018 DeviceDescriptor = ExAllocatePoolWithTag(NonPagedPool, 1019 USB_DEFAULT_MAX_PACKET, 1020 USB_PORT_TAG); 1021 1022 if (!DeviceDescriptor) 1023 { 1024 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceDescriptor\n"); 1025 goto ErrorExit; 1026 } 1027 1028 RtlZeroMemory(DeviceDescriptor, USB_DEFAULT_MAX_PACKET); 1029 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1030 1031 SetupPacket.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 1032 SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; 1033 SetupPacket.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; 1034 SetupPacket.wLength = USB_DEFAULT_MAX_PACKET; 1035 1036 TransferedLen = 0; 1037 1038 Status = USBPORT_SendSetupPacket(DeviceHandle, 1039 FdoDevice, 1040 &SetupPacket, 1041 DeviceDescriptor, 1042 USB_DEFAULT_MAX_PACKET, 1043 &TransferedLen, 1044 NULL); 1045 1046 RtlCopyMemory(&DeviceHandle->DeviceDescriptor, 1047 DeviceDescriptor, 1048 sizeof(USB_DEVICE_DESCRIPTOR)); 1049 1050 ExFreePoolWithTag(DeviceDescriptor, USB_PORT_TAG); 1051 1052 DescriptorMinSize = RTL_SIZEOF_THROUGH_FIELD(USB_DEVICE_DESCRIPTOR, 1053 bMaxPacketSize0); 1054 1055 if ((TransferedLen == DescriptorMinSize) && !NT_SUCCESS(Status)) 1056 { 1057 Status = STATUS_SUCCESS; 1058 } 1059 1060 if (NT_SUCCESS(Status) && (TransferedLen >= DescriptorMinSize)) 1061 { 1062 if ((DeviceHandle->DeviceDescriptor.bLength >= sizeof(USB_DEVICE_DESCRIPTOR)) && 1063 (DeviceHandle->DeviceDescriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE)) 1064 { 1065 MaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0; 1066 1067 if (MaxPacketSize == 8 || 1068 MaxPacketSize == 16 || 1069 MaxPacketSize == 32 || 1070 MaxPacketSize == 64) 1071 { 1072 USBPORT_AddDeviceHandle(FdoDevice, DeviceHandle); 1073 1074 *pUsbdDeviceHandle = DeviceHandle; 1075 1076 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1077 LOW_REALTIME_PRIORITY, 1078 1, 1079 FALSE); 1080 1081 return Status; 1082 } 1083 } 1084 } 1085 1086 DPRINT1("USBPORT_CreateDevice: ERROR!!! TransferedLen - %x, Status - %lx\n", 1087 TransferedLen, 1088 Status); 1089 1090 ErrorExit: 1091 1092 // FIXME: if Transaction Translator 1093 1094 Status = STATUS_DEVICE_DATA_ERROR; 1095 1096 if (IsOpenedPipe) 1097 { 1098 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle); 1099 } 1100 1101 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1102 LOW_REALTIME_PRIORITY, 1103 1, 1104 FALSE); 1105 1106 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG); 1107 1108 return Status; 1109 } 1110 1111 ULONG 1112 NTAPI 1113 USBPORT_AllocateUsbAddress(IN PDEVICE_OBJECT FdoDevice) 1114 { 1115 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1116 ULONG BitMapIdx; 1117 ULONG BitNumber; 1118 ULONG ix; 1119 1120 DPRINT("USBPORT_AllocateUsbAddress \n"); 1121 1122 FdoExtension = FdoDevice->DeviceExtension; 1123 1124 for (ix = 0; ix < 4; ++ix) 1125 { 1126 BitMapIdx = 1; 1127 1128 for (BitNumber = 0; BitNumber < 32; ++BitNumber) 1129 { 1130 if (!(FdoExtension->UsbAddressBitMap[ix] & BitMapIdx)) 1131 { 1132 FdoExtension->UsbAddressBitMap[ix] |= BitMapIdx; 1133 return 32 * ix + BitNumber; 1134 } 1135 1136 BitMapIdx <<= 2; 1137 } 1138 } 1139 1140 return 0; 1141 } 1142 1143 VOID 1144 NTAPI 1145 USBPORT_FreeUsbAddress(IN PDEVICE_OBJECT FdoDevice, 1146 IN USHORT DeviceAddress) 1147 { 1148 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1149 ULONG ix; 1150 ULONG BitMapIdx; 1151 ULONG BitNumber; 1152 USHORT CurrentAddress; 1153 1154 DPRINT("USBPORT_FreeUsbAddress: DeviceAddress - %x\n", DeviceAddress); 1155 1156 FdoExtension = FdoDevice->DeviceExtension; 1157 1158 for (ix = 0; ix < 4; ++ix) 1159 { 1160 BitMapIdx = 1; 1161 CurrentAddress = 32 * ix; 1162 1163 for (BitNumber = 0; BitNumber < 32; ++BitNumber) 1164 { 1165 if (CurrentAddress == DeviceAddress) 1166 { 1167 FdoExtension->UsbAddressBitMap[ix] &= ~BitMapIdx; 1168 return; 1169 } 1170 1171 BitMapIdx <<= 2; 1172 CurrentAddress++; 1173 } 1174 } 1175 } 1176 1177 NTSTATUS 1178 NTAPI 1179 USBPORT_InitializeDevice(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, 1180 IN PDEVICE_OBJECT FdoDevice) 1181 { 1182 PUSBPORT_ENDPOINT Endpoint; 1183 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; 1184 ULONG TransferedLen; 1185 USHORT DeviceAddress = 0; 1186 UCHAR MaxPacketSize; 1187 NTSTATUS Status; 1188 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1189 1190 DPRINT("USBPORT_InitializeDevice: ... \n"); 1191 1192 ASSERT(DeviceHandle != NULL); 1193 1194 FdoExtension = FdoDevice->DeviceExtension; 1195 1196 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1197 Executive, 1198 KernelMode, 1199 FALSE, 1200 NULL); 1201 1202 DeviceAddress = USBPORT_AllocateUsbAddress(FdoDevice); 1203 ASSERT(DeviceHandle->DeviceAddress == USB_DEFAULT_DEVICE_ADDRESS); 1204 1205 RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1206 1207 CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS; 1208 CtrlSetup.wValue.W = DeviceAddress; 1209 1210 Status = USBPORT_SendSetupPacket(DeviceHandle, 1211 FdoDevice, 1212 &CtrlSetup, 1213 NULL, 1214 0, 1215 NULL, 1216 NULL); 1217 1218 DPRINT("USBPORT_InitializeDevice: DeviceAddress - %x. SendSetupPacket Status - %x\n", 1219 DeviceAddress, 1220 Status); 1221 1222 if (!NT_SUCCESS(Status)) 1223 goto ExitError; 1224 1225 DeviceHandle->DeviceAddress = DeviceAddress; 1226 Endpoint = DeviceHandle->PipeHandle.Endpoint; 1227 1228 Endpoint->EndpointProperties.TotalMaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0; 1229 Endpoint->EndpointProperties.DeviceAddress = DeviceAddress; 1230 1231 Status = USBPORT_ReopenPipe(FdoDevice, Endpoint); 1232 1233 if (!NT_SUCCESS(Status)) 1234 goto ExitError; 1235 1236 USBPORT_Wait(FdoDevice, 10); 1237 1238 RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1239 1240 CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; 1241 CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; 1242 CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR); 1243 CtrlSetup.bmRequestType.B = 0x80; 1244 1245 Status = USBPORT_SendSetupPacket(DeviceHandle, 1246 FdoDevice, 1247 &CtrlSetup, 1248 &DeviceHandle->DeviceDescriptor, 1249 sizeof(USB_DEVICE_DESCRIPTOR), 1250 &TransferedLen, 1251 NULL); 1252 1253 if (NT_SUCCESS(Status)) 1254 { 1255 ASSERT(TransferedLen == sizeof(USB_DEVICE_DESCRIPTOR)); 1256 ASSERT(DeviceHandle->DeviceDescriptor.bLength >= sizeof(USB_DEVICE_DESCRIPTOR)); 1257 ASSERT(DeviceHandle->DeviceDescriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE); 1258 1259 MaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0; 1260 1261 ASSERT((MaxPacketSize == 8) || 1262 (MaxPacketSize == 16) || 1263 (MaxPacketSize == 32) || 1264 (MaxPacketSize == 64)); 1265 } 1266 else 1267 { 1268 ExitError: 1269 DPRINT1("USBPORT_InitializeDevice: ExitError. Status - %x\n", Status); 1270 } 1271 1272 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1273 LOW_REALTIME_PRIORITY, 1274 1, 1275 FALSE); 1276 1277 return Status; 1278 } 1279 1280 NTSTATUS 1281 NTAPI 1282 USBPORT_GetUsbDescriptor(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, 1283 IN PDEVICE_OBJECT FdoDevice, 1284 IN UCHAR Type, 1285 IN PUCHAR ConfigDesc, 1286 IN PULONG ConfigDescSize) 1287 { 1288 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 1289 1290 DPRINT("USBPORT_GetUsbDescriptor: Type - %x\n"); 1291 1292 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1293 1294 SetupPacket.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 1295 SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; 1296 SetupPacket.wValue.HiByte = Type; 1297 SetupPacket.wLength = (USHORT)*ConfigDescSize; 1298 1299 return USBPORT_SendSetupPacket(DeviceHandle, 1300 FdoDevice, 1301 &SetupPacket, 1302 ConfigDesc, 1303 *ConfigDescSize, 1304 ConfigDescSize, 1305 NULL); 1306 } 1307 1308 PUSBPORT_INTERFACE_HANDLE 1309 NTAPI 1310 USBPORT_GetInterfaceHandle(IN PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle, 1311 IN UCHAR InterfaceNumber) 1312 { 1313 PUSBPORT_INTERFACE_HANDLE InterfaceHandle; 1314 PLIST_ENTRY iHandleList; 1315 UCHAR InterfaceNum; 1316 1317 DPRINT("USBPORT_GetInterfaceHandle: ConfigurationHandle - %p, InterfaceNumber - %p\n", 1318 ConfigurationHandle, 1319 InterfaceNumber); 1320 1321 iHandleList = ConfigurationHandle->InterfaceHandleList.Flink; 1322 1323 while (iHandleList && 1324 (iHandleList != &ConfigurationHandle->InterfaceHandleList)) 1325 { 1326 InterfaceHandle = CONTAINING_RECORD(iHandleList, 1327 USBPORT_INTERFACE_HANDLE, 1328 InterfaceLink); 1329 1330 InterfaceNum = InterfaceHandle->InterfaceDescriptor.bInterfaceNumber; 1331 1332 if (InterfaceNum == InterfaceNumber) 1333 return InterfaceHandle; 1334 1335 iHandleList = InterfaceHandle->InterfaceLink.Flink; 1336 } 1337 1338 return NULL; 1339 } 1340 1341 NTSTATUS 1342 NTAPI 1343 USBPORT_HandleSelectInterface(IN PDEVICE_OBJECT FdoDevice, 1344 IN PIRP Irp, 1345 IN PURB Urb) 1346 { 1347 PUSBPORT_DEVICE_HANDLE DeviceHandle; 1348 PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle; 1349 PUSBD_INTERFACE_INFORMATION Interface; 1350 PUSBPORT_INTERFACE_HANDLE InterfaceHandle; 1351 PUSBPORT_INTERFACE_HANDLE iHandle; 1352 PUSBPORT_PIPE_HANDLE PipeHandle; 1353 USBD_STATUS USBDStatus; 1354 USHORT Length; 1355 ULONG ix; 1356 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1357 1358 DPRINT("USBPORT_HandleSelectInterface: ... \n"); 1359 1360 FdoExtension = FdoDevice->DeviceExtension; 1361 1362 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1363 Executive, 1364 KernelMode, 1365 FALSE, 1366 NULL); 1367 1368 ConfigurationHandle = Urb->UrbSelectInterface.ConfigurationHandle; 1369 1370 Interface = &Urb->UrbSelectInterface.Interface; 1371 1372 Length = Interface->Length + sizeof(USBD_PIPE_INFORMATION); 1373 Urb->UrbHeader.Length = Length; 1374 1375 USBDStatus = USBPORT_InitInterfaceInfo(Interface, ConfigurationHandle); 1376 1377 if (USBDStatus) 1378 { 1379 Interface->InterfaceHandle = (USBD_INTERFACE_HANDLE)-1; 1380 return USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 1381 } 1382 1383 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 1384 1385 InterfaceHandle = USBPORT_GetInterfaceHandle(ConfigurationHandle, 1386 Interface->InterfaceNumber); 1387 1388 if (InterfaceHandle) 1389 { 1390 RemoveEntryList(&InterfaceHandle->InterfaceLink); 1391 1392 if (InterfaceHandle->InterfaceDescriptor.bNumEndpoints) 1393 { 1394 PipeHandle = &InterfaceHandle->PipeHandle[0]; 1395 1396 for (ix = 0; 1397 ix < InterfaceHandle->InterfaceDescriptor.bNumEndpoints; 1398 ix++) 1399 { 1400 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle); 1401 PipeHandle += 1; 1402 } 1403 } 1404 } 1405 1406 iHandle = 0; 1407 1408 USBDStatus = USBPORT_OpenInterface(Urb, 1409 DeviceHandle, 1410 FdoDevice, 1411 ConfigurationHandle, 1412 Interface, 1413 &iHandle, 1414 1); 1415 1416 if (USBDStatus) 1417 { 1418 Interface->InterfaceHandle = (USBD_INTERFACE_HANDLE)-1; 1419 } 1420 else 1421 { 1422 if (InterfaceHandle) 1423 ExFreePoolWithTag(InterfaceHandle, USB_PORT_TAG); 1424 1425 Interface->InterfaceHandle = iHandle; 1426 1427 InsertTailList(&ConfigurationHandle->InterfaceHandleList, 1428 &iHandle->InterfaceLink); 1429 } 1430 1431 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1432 LOW_REALTIME_PRIORITY, 1433 1, 1434 FALSE); 1435 1436 return USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 1437 } 1438 1439 NTSTATUS 1440 NTAPI 1441 USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice, 1442 IN OUT PUSBPORT_DEVICE_HANDLE DeviceHandle, 1443 IN ULONG Flags) 1444 { 1445 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1446 1447 DPRINT("USBPORT_RemoveDevice: DeviceHandle - %p, Flags - %x\n", 1448 DeviceHandle, 1449 Flags); 1450 1451 FdoExtension = FdoDevice->DeviceExtension; 1452 1453 if ((Flags & USBD_KEEP_DEVICE_DATA) || 1454 (Flags & USBD_MARK_DEVICE_BUSY)) 1455 { 1456 return STATUS_SUCCESS; 1457 } 1458 1459 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1460 Executive, 1461 KernelMode, 1462 FALSE, 1463 NULL); 1464 1465 if (!USBPORT_ValidateDeviceHandle(FdoDevice, DeviceHandle)) 1466 { 1467 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1468 LOW_REALTIME_PRIORITY, 1469 1, 1470 FALSE); 1471 1472 DPRINT1("USBPORT_RemoveDevice: Not valid device handle\n"); 1473 return STATUS_DEVICE_NOT_CONNECTED; 1474 } 1475 1476 USBPORT_RemoveDeviceHandle(FdoDevice, DeviceHandle); 1477 1478 DeviceHandle->Flags |= DEVICE_HANDLE_FLAG_REMOVED; 1479 1480 USBPORT_AbortTransfers(FdoDevice, DeviceHandle); 1481 1482 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock - %x\n", 1483 DeviceHandle->DeviceHandleLock); 1484 1485 while (InterlockedDecrement(&DeviceHandle->DeviceHandleLock) >= 0) 1486 { 1487 InterlockedIncrement(&DeviceHandle->DeviceHandleLock); 1488 USBPORT_Wait(FdoDevice, 100); 1489 } 1490 1491 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock ok\n"); 1492 1493 if (DeviceHandle->ConfigHandle) 1494 { 1495 USBPORT_CloseConfiguration(DeviceHandle, FdoDevice); 1496 } 1497 1498 USBPORT_ClosePipe(DeviceHandle, FdoDevice, &DeviceHandle->PipeHandle); 1499 1500 if (DeviceHandle->DeviceAddress) 1501 { 1502 USBPORT_FreeUsbAddress(FdoDevice, DeviceHandle->DeviceAddress); 1503 } 1504 1505 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1506 LOW_REALTIME_PRIORITY, 1507 1, 1508 FALSE); 1509 1510 if (!(DeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB)) 1511 { 1512 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG); 1513 } 1514 1515 return STATUS_SUCCESS; 1516 } 1517 1518 NTSTATUS 1519 NTAPI 1520 USBPORT_RestoreDevice(IN PDEVICE_OBJECT FdoDevice, 1521 IN OUT PUSBPORT_DEVICE_HANDLE OldDeviceHandle, 1522 IN OUT PUSBPORT_DEVICE_HANDLE NewDeviceHandle) 1523 { 1524 PUSBPORT_DEVICE_EXTENSION FdoExtension; 1525 PLIST_ENTRY iHandleList; 1526 PUSBPORT_ENDPOINT Endpoint; 1527 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements = {0}; 1528 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 1529 NTSTATUS Status = STATUS_SUCCESS; 1530 USBD_STATUS USBDStatus; 1531 KIRQL OldIrql; 1532 PUSBPORT_INTERFACE_HANDLE InterfaceHandle; 1533 PUSBPORT_PIPE_HANDLE PipeHandle; 1534 PUSBPORT_REGISTRATION_PACKET Packet; 1535 1536 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle - %p, NewDeviceHandle - %p\n", 1537 OldDeviceHandle, 1538 NewDeviceHandle); 1539 1540 FdoExtension = FdoDevice->DeviceExtension; 1541 1542 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, 1543 Executive, 1544 KernelMode, 1545 FALSE, 1546 NULL); 1547 1548 if (!USBPORT_ValidateDeviceHandle(FdoDevice, OldDeviceHandle)) 1549 { 1550 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1551 LOW_REALTIME_PRIORITY, 1552 1, 1553 FALSE); 1554 1555 #ifndef NDEBUG 1556 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle not valid\n"); 1557 DbgBreakPoint(); 1558 #endif 1559 return STATUS_DEVICE_NOT_CONNECTED; 1560 } 1561 1562 if (!USBPORT_ValidateDeviceHandle(FdoDevice, NewDeviceHandle)) 1563 { 1564 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1565 LOW_REALTIME_PRIORITY, 1566 1, 1567 FALSE); 1568 #ifndef NDEBUG 1569 DPRINT("USBPORT_RestoreDevice: NewDeviceHandle not valid\n"); 1570 DbgBreakPoint(); 1571 #endif 1572 return STATUS_DEVICE_NOT_CONNECTED; 1573 } 1574 1575 USBPORT_RemoveDeviceHandle(FdoDevice, OldDeviceHandle); 1576 USBPORT_AbortTransfers(FdoDevice, OldDeviceHandle); 1577 1578 while (InterlockedDecrement(&OldDeviceHandle->DeviceHandleLock) >= 0) 1579 { 1580 InterlockedIncrement(&OldDeviceHandle->DeviceHandleLock); 1581 USBPORT_Wait(FdoDevice, 100); 1582 } 1583 1584 if (sizeof(USB_DEVICE_DESCRIPTOR) == RtlCompareMemory(&NewDeviceHandle->DeviceDescriptor, 1585 &OldDeviceHandle->DeviceDescriptor, 1586 sizeof(USB_DEVICE_DESCRIPTOR))) 1587 { 1588 NewDeviceHandle->ConfigHandle = OldDeviceHandle->ConfigHandle; 1589 1590 if (OldDeviceHandle->ConfigHandle) 1591 { 1592 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1593 1594 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 1595 SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION; 1596 SetupPacket.wValue.W = OldDeviceHandle->ConfigHandle->ConfigurationDescriptor->bConfigurationValue; 1597 SetupPacket.wIndex.W = 0; 1598 SetupPacket.wLength = 0; 1599 1600 USBPORT_SendSetupPacket(NewDeviceHandle, 1601 FdoDevice, 1602 &SetupPacket, 1603 NULL, 1604 0, 1605 NULL, 1606 &USBDStatus); 1607 1608 if (USBD_ERROR(USBDStatus)) 1609 Status = USBPORT_USBDStatusToNtStatus(NULL, USBDStatus); 1610 1611 if (NT_SUCCESS(Status)) 1612 { 1613 iHandleList = NewDeviceHandle->ConfigHandle->InterfaceHandleList.Flink; 1614 1615 while (iHandleList && 1616 iHandleList != &NewDeviceHandle->ConfigHandle->InterfaceHandleList) 1617 { 1618 InterfaceHandle = CONTAINING_RECORD(iHandleList, 1619 USBPORT_INTERFACE_HANDLE, 1620 InterfaceLink); 1621 1622 if (InterfaceHandle->AlternateSetting) 1623 { 1624 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 1625 1626 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 1627 SetupPacket.bmRequestType.Type = BMREQUEST_STANDARD; 1628 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 1629 1630 SetupPacket.bRequest = USB_REQUEST_SET_INTERFACE; 1631 SetupPacket.wValue.W = InterfaceHandle->InterfaceDescriptor.bAlternateSetting; 1632 SetupPacket.wIndex.W = InterfaceHandle->InterfaceDescriptor.bInterfaceNumber; 1633 SetupPacket.wLength = 0; 1634 1635 USBPORT_SendSetupPacket(NewDeviceHandle, 1636 FdoDevice, 1637 &SetupPacket, 1638 NULL, 1639 0, 1640 NULL, 1641 &USBDStatus); 1642 } 1643 1644 iHandleList = iHandleList->Flink; 1645 } 1646 } 1647 } 1648 1649 if (NewDeviceHandle->Flags & DEVICE_HANDLE_FLAG_INITIALIZED) 1650 { 1651 DPRINT1("USBPORT_RestoreDevice: FIXME Transaction Translator\n"); 1652 NewDeviceHandle->TtCount = OldDeviceHandle->TtCount; 1653 } 1654 1655 while (!IsListEmpty(&OldDeviceHandle->PipeHandleList)) 1656 { 1657 PipeHandle = CONTAINING_RECORD(OldDeviceHandle->PipeHandleList.Flink, 1658 USBPORT_PIPE_HANDLE, 1659 PipeLink); 1660 1661 DPRINT("USBPORT_RestoreDevice: PipeHandle - %p\n", PipeHandle); 1662 1663 USBPORT_RemovePipeHandle(OldDeviceHandle, PipeHandle); 1664 1665 if (PipeHandle != &OldDeviceHandle->PipeHandle) 1666 { 1667 USBPORT_AddPipeHandle(NewDeviceHandle, PipeHandle); 1668 1669 if (!(PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)) 1670 { 1671 Endpoint = PipeHandle->Endpoint; 1672 Endpoint->DeviceHandle = NewDeviceHandle; 1673 Endpoint->EndpointProperties.DeviceAddress = NewDeviceHandle->DeviceAddress; 1674 1675 Packet = &FdoExtension->MiniPortInterface->Packet; 1676 1677 if (!(Endpoint->Flags & ENDPOINT_FLAG_NUKE)) 1678 { 1679 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, 1680 &OldIrql); 1681 1682 Packet->ReopenEndpoint(FdoExtension->MiniPortExt, 1683 &Endpoint->EndpointProperties, 1684 Endpoint + 1); 1685 1686 Packet->SetEndpointDataToggle(FdoExtension->MiniPortExt, 1687 Endpoint + 1, 1688 0); 1689 1690 Packet->SetEndpointStatus(FdoExtension->MiniPortExt, 1691 Endpoint + 1, 1692 USBPORT_ENDPOINT_RUN); 1693 1694 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, 1695 OldIrql); 1696 } 1697 else 1698 { 1699 MiniportCloseEndpoint(FdoDevice, Endpoint); 1700 1701 RtlZeroMemory(Endpoint + 1, Packet->MiniPortEndpointSize); 1702 1703 RtlZeroMemory((PVOID)Endpoint->EndpointProperties.BufferVA, 1704 Endpoint->EndpointProperties.BufferLength); 1705 1706 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql); 1707 1708 Packet->QueryEndpointRequirements(FdoExtension->MiniPortExt, 1709 &Endpoint->EndpointProperties, 1710 &EndpointRequirements); 1711 1712 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, 1713 OldIrql); 1714 1715 MiniportOpenEndpoint(FdoDevice, Endpoint); 1716 1717 Endpoint->Flags &= ~(ENDPOINT_FLAG_NUKE | 1718 ENDPOINT_FLAG_ABORTING); 1719 1720 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, 1721 &Endpoint->EndpointOldIrql); 1722 1723 if (Endpoint->StateLast == USBPORT_ENDPOINT_ACTIVE) 1724 { 1725 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock); 1726 1727 Packet->SetEndpointState(FdoExtension->MiniPortExt, 1728 Endpoint + 1, 1729 USBPORT_ENDPOINT_ACTIVE); 1730 1731 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock); 1732 } 1733 1734 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 1735 Endpoint->EndpointOldIrql); 1736 } 1737 } 1738 } 1739 } 1740 1741 USBPORT_AddPipeHandle(OldDeviceHandle, &OldDeviceHandle->PipeHandle); 1742 } 1743 else 1744 { 1745 #ifndef NDEBUG 1746 DPRINT("USBPORT_RestoreDevice: New DeviceDescriptor != Old DeviceDescriptor\n"); 1747 DbgBreakPoint(); 1748 #endif 1749 Status = STATUS_UNSUCCESSFUL; 1750 } 1751 1752 USBPORT_ClosePipe(OldDeviceHandle, FdoDevice, &OldDeviceHandle->PipeHandle); 1753 1754 if (OldDeviceHandle->DeviceAddress != 0) 1755 USBPORT_FreeUsbAddress(FdoDevice, OldDeviceHandle->DeviceAddress); 1756 1757 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, 1758 LOW_REALTIME_PRIORITY, 1759 1, 1760 FALSE); 1761 1762 ExFreePoolWithTag(OldDeviceHandle, USB_PORT_TAG); 1763 1764 return Status; 1765 } 1766 1767 NTSTATUS 1768 NTAPI 1769 USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice, 1770 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, 1771 IN ULONG TtNumber) 1772 { 1773 DPRINT1("USBPORT_InitializeTT: UNIMPLEMENTED. FIXME. \n"); 1774 return STATUS_SUCCESS; 1775 } 1776 1777 NTSTATUS 1778 NTAPI 1779 USBPORT_Initialize20Hub(IN PDEVICE_OBJECT FdoDevice, 1780 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, 1781 IN ULONG TtCount) 1782 { 1783 NTSTATUS Status; 1784 ULONG ix; 1785 1786 DPRINT("USBPORT_Initialize20Hub \n"); 1787 1788 if (!HubDeviceHandle) 1789 { 1790 return STATUS_INVALID_PARAMETER; 1791 } 1792 1793 if (HubDeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB) 1794 { 1795 return STATUS_SUCCESS; 1796 } 1797 1798 if (TtCount == 0) 1799 { 1800 HubDeviceHandle->TtCount = 0; 1801 return STATUS_SUCCESS; 1802 } 1803 1804 for (ix = 0; ix < TtCount; ++ix) 1805 { 1806 Status = USBPORT_InitializeTT(FdoDevice, HubDeviceHandle, ix + 1); 1807 1808 if (!NT_SUCCESS(Status)) 1809 break; 1810 } 1811 1812 HubDeviceHandle->TtCount = TtCount; 1813 1814 return Status; 1815 }