1 /* 2 * PROJECT: ReactOS USB Port Driver 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: USBPort URB functions 5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru> 6 */ 7 8 #include "usbport.h" 9 10 #define NDEBUG 11 #include <debug.h> 12 13 #define NDEBUG_USBPORT_URB 14 #include "usbdebug.h" 15 16 NTSTATUS 17 NTAPI 18 USBPORT_HandleGetConfiguration(IN PURB Urb) 19 { 20 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 21 22 DPRINT_URB("USBPORT_HandleGetConfiguration: Urb - %p\n", Urb); 23 24 SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET) 25 &Urb->UrbControlGetConfigurationRequest.Reserved1; 26 27 SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 28 SetupPacket->bRequest = USB_REQUEST_GET_CONFIGURATION; 29 SetupPacket->wValue.W = 0; 30 SetupPacket->wIndex.W = 0; 31 SetupPacket->wLength = Urb->UrbControlGetConfigurationRequest.TransferBufferLength; 32 33 Urb->UrbControlGetConfigurationRequest.Reserved0 |= USBD_TRANSFER_DIRECTION_IN; // 1; 34 Urb->UrbControlGetConfigurationRequest.Reserved0 |= USBD_SHORT_TRANSFER_OK; // 2 35 36 USBPORT_DumpingSetupPacket(SetupPacket); 37 38 USBPORT_QueueTransferUrb(Urb); 39 40 return STATUS_PENDING; 41 } 42 43 NTSTATUS 44 NTAPI 45 USBPORT_HandleGetCurrentFrame(IN PDEVICE_OBJECT FdoDevice, 46 IN PIRP Irp, 47 IN PURB Urb) 48 { 49 PUSBPORT_DEVICE_EXTENSION FdoExtension; 50 PUSBPORT_REGISTRATION_PACKET Packet; 51 ULONG FrameNumber; 52 KIRQL OldIrql; 53 54 FdoExtension = FdoDevice->DeviceExtension; 55 Packet = &FdoExtension->MiniPortInterface->Packet; 56 57 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql); 58 FrameNumber = Packet->Get32BitFrameNumber(FdoExtension->MiniPortExt); 59 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql); 60 61 Urb->UrbGetCurrentFrameNumber.FrameNumber = FrameNumber; 62 63 DPRINT_URB("USBPORT_HandleGetCurrentFrame: FrameNumber - %p\n", 64 FrameNumber); 65 66 return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); 67 } 68 69 NTSTATUS 70 NTAPI 71 USBPORT_AbortPipe(IN PDEVICE_OBJECT FdoDevice, 72 IN PIRP Irp, 73 IN PURB Urb) 74 { 75 PUSBPORT_ENDPOINT Endpoint; 76 PUSBPORT_PIPE_HANDLE PipeHandle; 77 PUSBPORT_DEVICE_HANDLE DeviceHandle; 78 NTSTATUS Status; 79 80 DPRINT_URB("USBPORT_AbortPipe: ... \n"); 81 82 PipeHandle = Urb->UrbPipeRequest.PipeHandle; 83 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 84 85 if (USBPORT_ValidatePipeHandle(DeviceHandle, PipeHandle)) 86 { 87 if (!(PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)) 88 { 89 Endpoint = PipeHandle->Endpoint; 90 91 Status = STATUS_PENDING; 92 93 Irp->IoStatus.Status = Status; 94 IoMarkIrpPending(Irp); 95 96 USBPORT_AbortEndpoint(FdoDevice, Endpoint, Irp); 97 98 return Status; 99 } 100 101 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); 102 } 103 else 104 { 105 Status = USBPORT_USBDStatusToNtStatus(Urb, 106 USBD_STATUS_INVALID_PIPE_HANDLE); 107 } 108 109 return Status; 110 } 111 112 NTSTATUS 113 NTAPI 114 USBPORT_ResetPipe(IN PDEVICE_OBJECT FdoDevice, 115 IN PIRP Irp, 116 IN PURB Urb) 117 { 118 PUSBPORT_DEVICE_EXTENSION FdoExtension; 119 PUSBPORT_REGISTRATION_PACKET Packet; 120 PUSBPORT_PIPE_HANDLE PipeHandle; 121 PUSBPORT_ENDPOINT Endpoint; 122 NTSTATUS Status; 123 124 DPRINT_URB("USBPORT_ResetPipe: ... \n"); 125 126 FdoExtension = FdoDevice->DeviceExtension; 127 Packet = &FdoExtension->MiniPortInterface->Packet; 128 129 PipeHandle = Urb->UrbPipeRequest.PipeHandle; 130 131 if (!USBPORT_ValidatePipeHandle((PUSBPORT_DEVICE_HANDLE)Urb->UrbHeader.UsbdDeviceHandle, 132 PipeHandle)) 133 { 134 return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_INVALID_PIPE_HANDLE); 135 } 136 137 Endpoint = PipeHandle->Endpoint; 138 139 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql); 140 141 if (IsListEmpty(&Endpoint->TransferList)) 142 { 143 if (Urb->UrbHeader.UsbdFlags & USBD_FLAG_NOT_ISO_TRANSFER) 144 { 145 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock); 146 147 Packet->SetEndpointDataToggle(FdoExtension->MiniPortExt, 148 Endpoint + 1, 149 0); 150 151 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock); 152 } 153 154 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); 155 } 156 else 157 { 158 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_ERROR_BUSY); 159 } 160 161 Endpoint->Flags |= ENDPOINT_FLAG_QUEUENE_EMPTY; 162 163 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock); 164 165 Packet->SetEndpointStatus(FdoExtension->MiniPortExt, 166 Endpoint + 1, 167 USBPORT_ENDPOINT_RUN); 168 169 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock); 170 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql); 171 172 return Status; 173 } 174 175 NTSTATUS 176 NTAPI 177 USBPORT_ClearStall(IN PDEVICE_OBJECT FdoDevice, 178 IN PIRP Irp, 179 IN PURB Urb) 180 { 181 PUSBPORT_DEVICE_HANDLE DeviceHandle; 182 PUSBPORT_PIPE_HANDLE PipeHandle; 183 USBD_STATUS USBDStatus; 184 PUSBPORT_ENDPOINT Endpoint; 185 NTSTATUS Status; 186 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 187 188 DPRINT_URB("USBPORT_ClearStall: ... \n"); 189 190 PipeHandle = Urb->UrbPipeRequest.PipeHandle; 191 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 192 193 if (!USBPORT_ValidatePipeHandle(DeviceHandle, PipeHandle)) 194 { 195 return USBPORT_USBDStatusToNtStatus(Urb, 196 USBD_STATUS_INVALID_PIPE_HANDLE); 197 } 198 199 Endpoint = PipeHandle->Endpoint; 200 201 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); 202 203 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 204 SetupPacket.bRequest = USB_REQUEST_CLEAR_FEATURE; 205 SetupPacket.wValue.W = 0; 206 SetupPacket.wIndex.W = Endpoint->EndpointProperties.EndpointAddress; 207 SetupPacket.wLength = 0; 208 209 USBPORT_SendSetupPacket(DeviceHandle, 210 FdoDevice, 211 &SetupPacket, 212 NULL, 213 0, 214 NULL, 215 &USBDStatus); 216 217 Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 218 219 return Status; 220 } 221 222 NTSTATUS 223 NTAPI 224 USBPORT_SyncResetPipeAndClearStall(IN PDEVICE_OBJECT FdoDevice, 225 IN PIRP Irp, 226 IN PURB Urb) 227 { 228 PUSBPORT_DEVICE_HANDLE DeviceHandle; 229 PUSBPORT_PIPE_HANDLE PipeHandle; 230 PUSBPORT_ENDPOINT Endpoint; 231 ULONG EndpointState; 232 NTSTATUS Status; 233 234 DPRINT_URB("USBPORT_SyncResetPipeAndClearStall: ... \n"); 235 236 ASSERT(Urb->UrbHeader.UsbdDeviceHandle); 237 ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); 238 ASSERT(Urb->UrbPipeRequest.PipeHandle); 239 240 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 241 PipeHandle = Urb->UrbPipeRequest.PipeHandle; 242 243 if (!USBPORT_ValidatePipeHandle(DeviceHandle, PipeHandle)) 244 { 245 return USBPORT_USBDStatusToNtStatus(Urb, 246 USBD_STATUS_INVALID_PIPE_HANDLE); 247 } 248 249 if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE) 250 { 251 return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); 252 } 253 254 Endpoint = PipeHandle->Endpoint; 255 InterlockedIncrement(&DeviceHandle->DeviceHandleLock); 256 257 if (Endpoint->EndpointProperties.TransferType != USBPORT_TRANSFER_TYPE_ISOCHRONOUS) 258 { 259 Urb->UrbHeader.UsbdFlags |= USBD_FLAG_NOT_ISO_TRANSFER; 260 Status = USBPORT_ClearStall(FdoDevice, Irp, Urb); 261 } 262 else 263 { 264 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); 265 } 266 267 if (NT_SUCCESS(Status)) 268 { 269 Status = USBPORT_ResetPipe(FdoDevice, Irp, Urb); 270 271 if (Endpoint->EndpointProperties.TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) 272 { 273 while (TRUE) 274 { 275 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, 276 &Endpoint->EndpointOldIrql); 277 278 EndpointState = USBPORT_GetEndpointState(Endpoint); 279 280 if (EndpointState == USBPORT_ENDPOINT_PAUSED && 281 IsListEmpty(&Endpoint->TransferList)) 282 { 283 USBPORT_SetEndpointState(Endpoint, 284 USBPORT_ENDPOINT_ACTIVE); 285 } 286 287 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, 288 Endpoint->EndpointOldIrql); 289 290 if (EndpointState == USBPORT_ENDPOINT_ACTIVE) 291 { 292 break; 293 } 294 295 USBPORT_Wait(FdoDevice, 1); 296 } 297 } 298 } 299 300 InterlockedDecrement(&DeviceHandle->DeviceHandleLock); 301 302 return Status; 303 } 304 305 NTSTATUS 306 NTAPI 307 USBPORT_HandleSetOrClearFeature(IN PURB Urb) 308 { 309 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 310 311 DPRINT_URB("USBPORT_HandleSetOrClearFeature: Urb - %p\n", Urb); 312 313 SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET) 314 &Urb->UrbControlFeatureRequest.Reserved0; 315 316 SetupPacket->wLength = 0; 317 Urb->UrbControlFeatureRequest.Reserved3 = 0; // TransferBufferLength 318 319 SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 320 321 switch (Urb->UrbHeader.Function) 322 { 323 case URB_FUNCTION_SET_FEATURE_TO_DEVICE: 324 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n"); 325 SetupPacket->bRequest = USB_REQUEST_SET_FEATURE; 326 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE; 327 break; 328 329 case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: 330 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE\n"); 331 SetupPacket->bRequest = USB_REQUEST_SET_FEATURE; 332 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 333 break; 334 335 case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: 336 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE\n"); 337 SetupPacket->bRequest = USB_REQUEST_SET_FEATURE; 338 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 339 break; 340 341 case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: 342 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT\n"); 343 SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE; 344 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE; 345 break; 346 347 case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: 348 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT\n"); 349 SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE; 350 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 351 break; 352 353 case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: 354 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n"); 355 SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE; 356 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 357 break; 358 359 case URB_FUNCTION_CLEAR_FEATURE_TO_OTHER: 360 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE\n"); 361 SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE; 362 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER; 363 break; 364 365 case URB_FUNCTION_SET_FEATURE_TO_OTHER: 366 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE\n"); 367 SetupPacket->bRequest = USB_REQUEST_SET_FEATURE; 368 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER; 369 break; 370 } 371 372 Urb->UrbControlFeatureRequest.Reserved2 &= ~USBD_TRANSFER_DIRECTION_IN; 373 Urb->UrbControlFeatureRequest.Reserved2 |= USBD_SHORT_TRANSFER_OK; 374 375 USBPORT_DumpingSetupPacket(SetupPacket); 376 377 USBPORT_QueueTransferUrb(Urb); 378 379 return STATUS_PENDING; 380 } 381 382 NTSTATUS 383 NTAPI 384 USBPORT_HandleDataTransfers(IN PURB Urb) 385 { 386 PUSBPORT_ENDPOINT Endpoint; 387 388 DPRINT_URB("USBPORT_HandleDataTransfers: Urb - %p\n", Urb); 389 390 Endpoint = ((PUSBPORT_PIPE_HANDLE) 391 (Urb->UrbBulkOrInterruptTransfer.PipeHandle))->Endpoint; 392 393 if (Endpoint->EndpointProperties.TransferType != USBPORT_TRANSFER_TYPE_CONTROL) 394 { 395 if (Endpoint->EndpointProperties.Direction == USBPORT_TRANSFER_DIRECTION_OUT) 396 { 397 Urb->UrbBulkOrInterruptTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN; 398 } 399 else 400 { 401 Urb->UrbBulkOrInterruptTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; 402 } 403 } 404 405 USBPORT_QueueTransferUrb(Urb); 406 407 return STATUS_PENDING; 408 } 409 410 NTSTATUS 411 NTAPI 412 USBPORT_HandleGetStatus(IN PIRP Irp, 413 IN PURB Urb) 414 { 415 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 416 NTSTATUS Status; 417 418 SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET) 419 &Urb->UrbControlDescriptorRequest.Reserved1; 420 421 SetupPacket->bmRequestType.B = 0; 422 SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 423 SetupPacket->bRequest = USB_REQUEST_GET_STATUS; 424 SetupPacket->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; 425 SetupPacket->wValue.W = 0; 426 427 switch (Urb->UrbHeader.Function) 428 { 429 case URB_FUNCTION_GET_STATUS_FROM_DEVICE: 430 DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_DEVICE\n"); 431 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE; 432 break; 433 434 case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: 435 DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_INTERFACE\n"); 436 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 437 break; 438 439 case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: 440 DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_ENDPOINT\n"); 441 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 442 break; 443 444 case URB_FUNCTION_GET_STATUS_FROM_OTHER: 445 DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_OTHER\n"); 446 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER; 447 break; 448 } 449 450 if (SetupPacket->wLength == 2) 451 { 452 Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK; 453 454 if (SetupPacket->bmRequestType.Dir) 455 Urb->UrbControlTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; 456 else 457 Urb->UrbControlTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN; 458 459 //USBPORT_DumpingSetupPacket(SetupPacket); 460 461 USBPORT_QueueTransferUrb(Urb); 462 463 Status = STATUS_PENDING; 464 } 465 else 466 { 467 Status = USBPORT_USBDStatusToNtStatus(Urb, 468 USBD_STATUS_INVALID_PARAMETER); 469 470 DPRINT1("USBPORT_HandleGetStatus: Bad wLength\n"); 471 USBPORT_DumpingSetupPacket(SetupPacket); 472 } 473 474 return Status; 475 } 476 477 NTSTATUS 478 NTAPI 479 USBPORT_HandleVendorOrClass(IN PIRP Irp, 480 IN PURB Urb) 481 { 482 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 483 484 /* 485 Specifies a value, from 4 to 31 inclusive, 486 that becomes part of the request type code in the USB-defined setup packet. 487 This value is defined by USB for a class request or the vendor for a vendor request. 488 */ 489 490 SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET) 491 &Urb->UrbControlDescriptorRequest.Reserved1; 492 493 SetupPacket->bmRequestType.Dir = USBD_TRANSFER_DIRECTION_FLAG 494 (Urb->UrbControlTransfer.TransferFlags); 495 496 SetupPacket->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; 497 498 Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK; 499 500 switch (Urb->UrbHeader.Function) 501 { 502 case URB_FUNCTION_VENDOR_DEVICE: 503 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_DEVICE\n"); 504 SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR; 505 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE; 506 break; 507 508 case URB_FUNCTION_VENDOR_INTERFACE: 509 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_INTERFACE\n"); 510 SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR; 511 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 512 break; 513 514 case URB_FUNCTION_VENDOR_ENDPOINT: 515 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_ENDPOINT\n"); 516 SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR; 517 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 518 break; 519 520 case URB_FUNCTION_CLASS_DEVICE: 521 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_DEVICE\n"); 522 SetupPacket->bmRequestType.Type = BMREQUEST_CLASS; 523 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE; 524 break; 525 526 case URB_FUNCTION_CLASS_INTERFACE: 527 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_INTERFACE\n"); 528 SetupPacket->bmRequestType.Type = BMREQUEST_CLASS; 529 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 530 break; 531 532 case URB_FUNCTION_CLASS_ENDPOINT: 533 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_ENDPOINT\n"); 534 SetupPacket->bmRequestType.Type = BMREQUEST_CLASS; 535 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 536 break; 537 538 case URB_FUNCTION_CLASS_OTHER: 539 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_OTHER\n"); 540 SetupPacket->bmRequestType.Type = BMREQUEST_CLASS; 541 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER; 542 break; 543 544 case URB_FUNCTION_VENDOR_OTHER: 545 DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_OTHER\n"); 546 SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR; 547 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER; 548 break; 549 } 550 551 USBPORT_DumpingSetupPacket(SetupPacket); 552 553 USBPORT_QueueTransferUrb(Urb); 554 555 return STATUS_PENDING; 556 } 557 558 NTSTATUS 559 NTAPI 560 USBPORT_HandleGetSetDescriptor(IN PIRP Irp, 561 IN PURB Urb) 562 { 563 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket; 564 565 SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET) 566 &Urb->UrbControlDescriptorRequest.Reserved1; 567 568 SetupPacket->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; 569 SetupPacket->bmRequestType.B = 0; // Clear bmRequestType 570 SetupPacket->bmRequestType.Type = BMREQUEST_STANDARD; 571 572 switch (Urb->UrbHeader.Function) 573 { 574 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: 575 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n"); 576 SetupPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR; 577 SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 578 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE; 579 break; 580 581 case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE: 582 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE\n"); 583 SetupPacket->bRequest = USB_REQUEST_SET_DESCRIPTOR; 584 SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 585 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE; 586 break; 587 588 case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT: 589 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT\n"); 590 SetupPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR; 591 SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 592 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 593 break; 594 595 case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT: 596 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT\n"); 597 SetupPacket->bRequest = USB_REQUEST_SET_DESCRIPTOR; 598 SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 599 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT; 600 break; 601 602 case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE: 603 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n"); 604 SetupPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR; 605 SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST; 606 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 607 break; 608 609 case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE: 610 DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE\n"); 611 SetupPacket->bRequest = USB_REQUEST_SET_DESCRIPTOR; 612 SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; 613 SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE; 614 break; 615 } 616 617 Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK; 618 619 if (SetupPacket->bmRequestType.Dir) 620 Urb->UrbControlTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; 621 else 622 Urb->UrbControlTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN; 623 624 USBPORT_DumpingSetupPacket(SetupPacket); 625 626 USBPORT_QueueTransferUrb(Urb); 627 628 return STATUS_PENDING; 629 } 630 631 NTSTATUS 632 NTAPI 633 USBPORT_ValidateTransferParametersURB(IN PURB Urb) 634 { 635 struct _URB_CONTROL_TRANSFER *UrbRequest; 636 PMDL Mdl; 637 638 DPRINT_URB("USBPORT_ValidateTransferParametersURB: Urb - %p\n", Urb); 639 640 UrbRequest = &Urb->UrbControlTransfer; 641 642 if (UrbRequest->TransferBuffer == NULL && 643 UrbRequest->TransferBufferMDL == NULL && 644 UrbRequest->TransferBufferLength > 0) 645 { 646 DPRINT1("USBPORT_ValidateTransferParametersURB: Not valid parameter\n"); 647 USBPORT_DumpingURB(Urb); 648 return STATUS_INVALID_PARAMETER; 649 } 650 651 if ((UrbRequest->TransferBuffer != NULL) && 652 (UrbRequest->TransferBufferMDL != NULL) && 653 UrbRequest->TransferBufferLength == 0) 654 { 655 DPRINT1("USBPORT_ValidateTransferParametersURB: Not valid parameter\n"); 656 USBPORT_DumpingURB(Urb); 657 return STATUS_INVALID_PARAMETER; 658 } 659 660 if (UrbRequest->TransferBuffer != NULL && 661 UrbRequest->TransferBufferMDL == NULL && 662 UrbRequest->TransferBufferLength != 0) 663 { 664 DPRINT_URB("USBPORT_ValidateTransferParametersURB: TransferBuffer - %p, TransferBufferLength - %x\n", 665 UrbRequest->TransferBuffer, 666 UrbRequest->TransferBufferLength); 667 668 Mdl = IoAllocateMdl(UrbRequest->TransferBuffer, 669 UrbRequest->TransferBufferLength, 670 FALSE, 671 FALSE, 672 NULL); 673 674 if (!Mdl) 675 { 676 DPRINT1("USBPORT_ValidateTransferParametersURB: Not allocated Mdl\n"); 677 return STATUS_INSUFFICIENT_RESOURCES; 678 } 679 680 MmBuildMdlForNonPagedPool(Mdl); 681 682 UrbRequest->TransferBufferMDL = Mdl; 683 Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_MDL; 684 685 DPRINT_URB("USBPORT_ValidateTransferParametersURB: Mdl - %p\n", Mdl); 686 } 687 688 return STATUS_SUCCESS; 689 } 690 691 NTSTATUS 692 NTAPI 693 USBPORT_ValidateURB(IN PDEVICE_OBJECT FdoDevice, 694 IN PIRP Irp, 695 IN PURB Urb, 696 IN BOOLEAN IsControlTransfer, 697 IN BOOLEAN IsNullTransfer) 698 { 699 struct _URB_CONTROL_TRANSFER *UrbRequest; 700 PUSBPORT_DEVICE_HANDLE DeviceHandle; 701 NTSTATUS Status; 702 USBD_STATUS USBDStatus; 703 704 UrbRequest = &Urb->UrbControlTransfer; 705 706 if (UrbRequest->UrbLink) 707 { 708 Status = USBPORT_USBDStatusToNtStatus(Urb, 709 USBD_STATUS_INVALID_PARAMETER); 710 711 DPRINT1("USBPORT_ValidateURB: Not valid parameter\n"); 712 713 USBPORT_DumpingURB(Urb); 714 return Status; 715 } 716 717 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 718 719 if (IsControlTransfer) 720 { 721 UrbRequest->TransferFlags |= USBD_DEFAULT_PIPE_TRANSFER; 722 UrbRequest->PipeHandle = &DeviceHandle->PipeHandle; 723 } 724 725 if (UrbRequest->TransferFlags & USBD_DEFAULT_PIPE_TRANSFER) 726 { 727 if (UrbRequest->TransferBufferLength > 0x1000) 728 { 729 Status = USBPORT_USBDStatusToNtStatus(Urb, 730 USBD_STATUS_INVALID_PARAMETER); 731 732 DPRINT1("USBPORT_ValidateURB: Not valid parameter\n"); 733 734 USBPORT_DumpingURB(Urb); 735 return Status; 736 } 737 738 if (Urb->UrbHeader.Function == URB_FUNCTION_CONTROL_TRANSFER) 739 { 740 UrbRequest->PipeHandle = &DeviceHandle->PipeHandle; 741 } 742 } 743 744 if (!USBPORT_ValidatePipeHandle(DeviceHandle, UrbRequest->PipeHandle)) 745 { 746 Status = USBPORT_USBDStatusToNtStatus(Urb, 747 USBD_STATUS_INVALID_PIPE_HANDLE); 748 749 DPRINT1("USBPORT_ValidateURB: Not valid pipe handle\n"); 750 751 USBPORT_DumpingURB(Urb); 752 return Status; 753 } 754 755 UrbRequest->hca.Reserved8[0] = NULL; // Transfer 756 757 if (IsNullTransfer) 758 { 759 UrbRequest->TransferBuffer = 0; 760 UrbRequest->TransferBufferMDL = NULL; 761 UrbRequest->TransferBufferLength = 0; 762 } 763 else 764 { 765 Status = USBPORT_ValidateTransferParametersURB(Urb); 766 767 if (!NT_SUCCESS(Status)) 768 { 769 return Status; 770 } 771 } 772 773 USBDStatus = USBPORT_AllocateTransfer(FdoDevice, 774 Urb, 775 DeviceHandle, 776 Irp, 777 NULL); 778 779 Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus); 780 781 if (!NT_SUCCESS(Status)) 782 { 783 DPRINT1("USBPORT_ValidateURB: Not allocated transfer\n"); 784 } 785 786 return Status; 787 } 788 789 NTSTATUS 790 NTAPI 791 USBPORT_HandleSubmitURB(IN PDEVICE_OBJECT PdoDevice, 792 IN PIRP Irp, 793 IN PURB Urb) 794 { 795 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 796 PDEVICE_OBJECT FdoDevice; 797 PUSBPORT_DEVICE_EXTENSION FdoExtension; 798 USHORT Function; 799 PUSBPORT_DEVICE_HANDLE DeviceHandle; 800 NTSTATUS Status = STATUS_NOT_IMPLEMENTED; 801 802 ASSERT(Urb); 803 804 PdoExtension = PdoDevice->DeviceExtension; 805 FdoDevice = PdoExtension->FdoDevice; 806 FdoExtension = FdoDevice->DeviceExtension; 807 808 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS; 809 Urb->UrbHeader.UsbdFlags = 0; 810 811 Function = Urb->UrbHeader.Function; 812 813 if (Function > URB_FUNCTION_MAX) 814 { 815 Status = USBPORT_USBDStatusToNtStatus(Urb, 816 USBD_STATUS_INVALID_URB_FUNCTION); 817 818 DPRINT1("USBPORT_HandleSubmitURB: Unknown URB function - %x !!!\n", 819 Function); 820 821 return Status; 822 } 823 824 if (FdoExtension->TimerFlags & USBPORT_TMFLAG_RH_SUSPENDED) 825 { 826 DPRINT1("USBPORT_HandleSubmitURB: Bad Request\n"); 827 828 USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_DEVICE_GONE); 829 830 Irp->IoStatus.Status = STATUS_PENDING; 831 IoMarkIrpPending(Irp); 832 IoCsqInsertIrp(&FdoExtension->BadRequestIoCsq, Irp, NULL); 833 834 return STATUS_PENDING; 835 } 836 837 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; 838 839 if (!DeviceHandle) 840 { 841 DeviceHandle = &PdoExtension->DeviceHandle; 842 Urb->UrbHeader.UsbdDeviceHandle = DeviceHandle; 843 } 844 845 if (!USBPORT_ValidateDeviceHandle(PdoExtension->FdoDevice, 846 DeviceHandle)) 847 { 848 DPRINT1("USBPORT_HandleSubmitURB: Not valid device handle\n"); 849 850 Irp->IoStatus.Status = STATUS_PENDING; 851 IoMarkIrpPending(Irp); 852 IoCsqInsertIrp(&FdoExtension->BadRequestIoCsq, Irp, NULL); 853 854 return STATUS_PENDING; 855 } 856 857 InterlockedIncrement(&DeviceHandle->DeviceHandleLock); 858 859 DPRINT_URB("USBPORT_HandleSubmitURB: Function - 0x%02X, DeviceHandle - %p\n", 860 Function, 861 Urb->UrbHeader.UsbdDeviceHandle); 862 863 switch (Function) 864 { 865 case URB_FUNCTION_ISOCH_TRANSFER: 866 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_ISOCH_TRANSFER UNIMPLEMENTED. FIXME. \n"); 867 break; 868 869 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: 870 case URB_FUNCTION_CONTROL_TRANSFER: 871 Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, FALSE, FALSE); 872 873 if (!NT_SUCCESS(Status)) 874 { 875 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n"); 876 break; 877 } 878 879 Status = USBPORT_HandleDataTransfers(Urb); 880 break; 881 882 case URB_FUNCTION_VENDOR_DEVICE: 883 case URB_FUNCTION_VENDOR_INTERFACE: 884 case URB_FUNCTION_VENDOR_ENDPOINT: 885 case URB_FUNCTION_CLASS_DEVICE: 886 case URB_FUNCTION_CLASS_INTERFACE: 887 case URB_FUNCTION_CLASS_ENDPOINT: 888 case URB_FUNCTION_CLASS_OTHER: 889 case URB_FUNCTION_VENDOR_OTHER: 890 Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE); 891 892 if (!NT_SUCCESS(Status)) 893 { 894 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n"); 895 break; 896 } 897 898 Status = USBPORT_HandleVendorOrClass(Irp, Urb); 899 break; 900 901 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: 902 case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE: 903 case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT: 904 case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT: 905 case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE: 906 case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE: 907 Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE); 908 909 if (!NT_SUCCESS(Status)) 910 { 911 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n"); 912 break; 913 } 914 915 Status = USBPORT_HandleGetSetDescriptor(Irp, Urb); 916 break; 917 918 case URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR: 919 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR (0x2A) NOT_SUPPORTED\n"); 920 return USBPORT_USBDStatusToNtStatus(Urb, 921 USBD_STATUS_INVALID_URB_FUNCTION); 922 923 case URB_FUNCTION_GET_STATUS_FROM_DEVICE: 924 case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: 925 case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: 926 case URB_FUNCTION_GET_STATUS_FROM_OTHER: 927 Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE); 928 929 if (!NT_SUCCESS(Status)) 930 { 931 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n"); 932 break; 933 } 934 935 Status = USBPORT_HandleGetStatus(Irp, Urb); 936 break; 937 938 case URB_FUNCTION_SELECT_CONFIGURATION: 939 Status = USBPORT_HandleSelectConfiguration(PdoExtension->FdoDevice, 940 Irp, 941 Urb); 942 break; 943 944 case URB_FUNCTION_SELECT_INTERFACE: 945 Status = USBPORT_HandleSelectInterface(PdoExtension->FdoDevice, 946 Irp, 947 Urb); 948 break; 949 950 case URB_FUNCTION_GET_CONFIGURATION: 951 Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE); 952 953 if (!NT_SUCCESS(Status)) 954 { 955 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n"); 956 break; 957 } 958 959 Status = USBPORT_HandleGetConfiguration(Urb); 960 break; 961 962 case URB_FUNCTION_GET_INTERFACE: 963 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_INTERFACE (0x27) NOT_SUPPORTED\n"); 964 return USBPORT_USBDStatusToNtStatus(Urb, 965 USBD_STATUS_INVALID_URB_FUNCTION); 966 967 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: 968 Status = USBPORT_SyncResetPipeAndClearStall(PdoExtension->FdoDevice, 969 Irp, 970 Urb); 971 break; 972 973 case URB_FUNCTION_SYNC_RESET_PIPE: 974 Status = USBPORT_ResetPipe(PdoExtension->FdoDevice, 975 Irp, 976 Urb); 977 break; 978 979 case URB_FUNCTION_SYNC_CLEAR_STALL: 980 Status = USBPORT_ClearStall(PdoExtension->FdoDevice, 981 Irp, 982 Urb); 983 break; 984 985 case URB_FUNCTION_ABORT_PIPE: 986 Status = USBPORT_AbortPipe(PdoExtension->FdoDevice, 987 Irp, 988 Urb); 989 break; 990 991 case URB_FUNCTION_SET_FEATURE_TO_DEVICE: 992 case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: 993 case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: 994 case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: 995 case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: 996 case URB_FUNCTION_CLEAR_FEATURE_TO_OTHER: 997 case URB_FUNCTION_SET_FEATURE_TO_OTHER: 998 Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, TRUE); 999 1000 if (!NT_SUCCESS(Status)) 1001 { 1002 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n"); 1003 break; 1004 } 1005 1006 Status = USBPORT_HandleSetOrClearFeature(Urb); 1007 break; 1008 1009 case URB_FUNCTION_GET_CURRENT_FRAME_NUMBER: 1010 Status = USBPORT_HandleGetCurrentFrame(PdoExtension->FdoDevice, 1011 Irp, 1012 Urb); 1013 break; 1014 1015 case URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL: 1016 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL (0x03) NOT_SUPPORTED\n"); 1017 return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED); 1018 1019 case URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL: 1020 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL (0x04) NOT_SUPPORTED\n"); 1021 return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED); 1022 1023 case URB_FUNCTION_GET_FRAME_LENGTH: 1024 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_FRAME_LENGTH (0x05) NOT_SUPPORTED\n"); 1025 return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED); 1026 1027 case URB_FUNCTION_SET_FRAME_LENGTH: 1028 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_SET_FRAME_LENGTH (0x06) NOT_SUPPORTED\n"); 1029 return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED); 1030 1031 default: 1032 DPRINT1("USBPORT_HandleSubmitURB: Unknown URB Function - %x\n", 1033 Function); 1034 //URB_FUNCTION_RESERVED_0X0016 1035 //URB_FUNCTION_RESERVE_0X001D 1036 //URB_FUNCTION_RESERVE_0X002B 1037 //URB_FUNCTION_RESERVE_0X002C 1038 //URB_FUNCTION_RESERVE_0X002D 1039 //URB_FUNCTION_RESERVE_0X002E 1040 //URB_FUNCTION_RESERVE_0X002F 1041 break; 1042 } 1043 1044 if (Status == STATUS_PENDING) 1045 { 1046 return Status; 1047 } 1048 1049 if (Urb->UrbHeader.UsbdFlags & USBD_FLAG_ALLOCATED_TRANSFER) 1050 { 1051 PUSBPORT_TRANSFER Transfer; 1052 1053 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0]; 1054 Urb->UrbControlTransfer.hca.Reserved8[0] = NULL; 1055 Urb->UrbHeader.UsbdFlags |= ~USBD_FLAG_ALLOCATED_TRANSFER; 1056 ExFreePoolWithTag(Transfer, USB_PORT_TAG); 1057 } 1058 1059 InterlockedDecrement(&DeviceHandle->DeviceHandleLock); 1060 1061 Irp->IoStatus.Status = Status; 1062 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1063 1064 return Status; 1065 } 1066