1 /* 2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: drivers/usb/usbccgp/fdo.c 5 * PURPOSE: USB device driver. 6 * PROGRAMMERS: 7 * Michael Martin (michael.martin@reactos.org) 8 * Johannes Anderwald (johannes.anderwald@reactos.org) 9 * Cameron Gutman 10 */ 11 12 #include "usbccgp.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 NTSTATUS 18 NTAPI 19 FDO_QueryCapabilitiesCompletionRoutine( 20 IN PDEVICE_OBJECT DeviceObject, 21 IN PIRP Irp, 22 IN PVOID Context) 23 { 24 /* Set event */ 25 KeSetEvent((PRKEVENT)Context, 0, FALSE); 26 27 /* Completion is done in the HidClassFDO_QueryCapabilities routine */ 28 return STATUS_MORE_PROCESSING_REQUIRED; 29 } 30 31 NTSTATUS 32 FDO_QueryCapabilities( 33 IN PDEVICE_OBJECT DeviceObject, 34 IN OUT PDEVICE_CAPABILITIES Capabilities) 35 { 36 PIRP Irp; 37 KEVENT Event; 38 NTSTATUS Status; 39 PIO_STACK_LOCATION IoStack; 40 PFDO_DEVICE_EXTENSION FDODeviceExtension; 41 42 /* Get device extension */ 43 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 44 ASSERT(FDODeviceExtension->Common.IsFDO); 45 46 /* Init event */ 47 KeInitializeEvent(&Event, NotificationEvent, FALSE); 48 49 /* Now allocate the irp */ 50 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); 51 if (!Irp) 52 { 53 /* No memory */ 54 return STATUS_INSUFFICIENT_RESOURCES; 55 } 56 57 /* Get next stack location */ 58 IoStack = IoGetNextIrpStackLocation(Irp); 59 60 /* Init stack location */ 61 IoStack->MajorFunction = IRP_MJ_PNP; 62 IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; 63 IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities; 64 65 /* Set completion routine */ 66 IoSetCompletionRoutine(Irp, 67 FDO_QueryCapabilitiesCompletionRoutine, 68 (PVOID)&Event, 69 TRUE, 70 TRUE, 71 TRUE); 72 73 /* Init capabilities */ 74 RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES)); 75 Capabilities->Size = sizeof(DEVICE_CAPABILITIES); 76 Capabilities->Version = 1; // FIXME hardcoded constant 77 Capabilities->Address = MAXULONG; 78 Capabilities->UINumber = MAXULONG; 79 80 /* Pnp irps have default completion code */ 81 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 82 83 /* Call lower device */ 84 Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 85 if (Status == STATUS_PENDING) 86 { 87 /* Wait for completion */ 88 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 89 } 90 91 /* Get status */ 92 Status = Irp->IoStatus.Status; 93 94 /* Complete request */ 95 IoFreeIrp(Irp); 96 97 /* Done */ 98 return Status; 99 } 100 101 NTSTATUS 102 FDO_DeviceRelations( 103 PDEVICE_OBJECT DeviceObject, 104 PIRP Irp) 105 { 106 ULONG DeviceCount = 0; 107 ULONG Index; 108 PDEVICE_RELATIONS DeviceRelations; 109 PIO_STACK_LOCATION IoStack; 110 PFDO_DEVICE_EXTENSION FDODeviceExtension; 111 112 /* Get device extension */ 113 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 114 115 /* Get current irp stack location */ 116 IoStack = IoGetCurrentIrpStackLocation(Irp); 117 118 /* Check if relation type is BusRelations */ 119 if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations) 120 { 121 /* FDO always only handles bus relations */ 122 return STATUS_SUCCESS; 123 } 124 125 /* Go through array and count device objects */ 126 for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++) 127 { 128 if (FDODeviceExtension->ChildPDO[Index]) 129 { 130 /* Child pdo */ 131 DeviceCount++; 132 } 133 } 134 135 /* Allocate device relations */ 136 DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, 137 sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0)); 138 if (!DeviceRelations) 139 { 140 /* No memory */ 141 return STATUS_INSUFFICIENT_RESOURCES; 142 } 143 144 /* Add device objects */ 145 for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++) 146 { 147 if (FDODeviceExtension->ChildPDO[Index]) 148 { 149 /* Store child pdo */ 150 DeviceRelations->Objects[DeviceRelations->Count] = FDODeviceExtension->ChildPDO[Index]; 151 152 /* Add reference */ 153 ObReferenceObject(FDODeviceExtension->ChildPDO[Index]); 154 155 /* Increment count */ 156 DeviceRelations->Count++; 157 } 158 } 159 160 /* Store result */ 161 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; 162 Irp->IoStatus.Status = STATUS_SUCCESS; 163 164 /* Request completed successfully */ 165 return STATUS_SUCCESS; 166 } 167 168 NTSTATUS 169 FDO_CreateChildPdo( 170 IN PDEVICE_OBJECT DeviceObject) 171 { 172 NTSTATUS Status; 173 PDEVICE_OBJECT PDODeviceObject; 174 PPDO_DEVICE_EXTENSION PDODeviceExtension; 175 PFDO_DEVICE_EXTENSION FDODeviceExtension; 176 ULONG Index; 177 178 /* Get device extension */ 179 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 180 ASSERT(FDODeviceExtension->Common.IsFDO); 181 182 /* Lets create array for the child PDO */ 183 FDODeviceExtension->ChildPDO = AllocateItem(NonPagedPool, 184 sizeof(PDEVICE_OBJECT) * FDODeviceExtension->FunctionDescriptorCount); 185 if (!FDODeviceExtension->ChildPDO) 186 { 187 /* No memory */ 188 return STATUS_INSUFFICIENT_RESOURCES; 189 } 190 191 /* Create pdo for each function */ 192 for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++) 193 { 194 /* Create the PDO */ 195 Status = IoCreateDevice(FDODeviceExtension->DriverObject, 196 sizeof(PDO_DEVICE_EXTENSION), 197 NULL, 198 FILE_DEVICE_USB, 199 FILE_AUTOGENERATED_DEVICE_NAME, 200 FALSE, 201 &PDODeviceObject); 202 if (!NT_SUCCESS(Status)) 203 { 204 /* Failed to create device object */ 205 DPRINT1("IoCreateDevice failed with %x\n", Status); 206 return Status; 207 } 208 209 /* Store in array */ 210 FDODeviceExtension->ChildPDO[Index] = PDODeviceObject; 211 212 /* Get device extension */ 213 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension; 214 RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION)); 215 216 /* Init device extension */ 217 PDODeviceExtension->Common.IsFDO = FALSE; 218 PDODeviceExtension->FunctionDescriptor = &FDODeviceExtension->FunctionDescriptor[Index]; 219 PDODeviceExtension->NextDeviceObject = DeviceObject; 220 PDODeviceExtension->FunctionIndex = Index; 221 PDODeviceExtension->FDODeviceExtension = FDODeviceExtension; 222 PDODeviceExtension->InterfaceList = FDODeviceExtension->InterfaceList; 223 PDODeviceExtension->InterfaceListCount = FDODeviceExtension->InterfaceListCount; 224 PDODeviceExtension->ConfigurationHandle = FDODeviceExtension->ConfigurationHandle; 225 PDODeviceExtension->ConfigurationDescriptor = FDODeviceExtension->ConfigurationDescriptor; 226 RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES)); 227 RtlCopyMemory(&PDODeviceExtension->DeviceDescriptor, FDODeviceExtension->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); 228 229 /* Patch the stack size */ 230 PDODeviceObject->StackSize = DeviceObject->StackSize + 1; 231 232 /* Set device flags */ 233 PDODeviceObject->Flags |= DO_DIRECT_IO | DO_MAP_IO_BUFFER; 234 235 /* Device is initialized */ 236 PDODeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 237 } 238 239 /* Done */ 240 return STATUS_SUCCESS; 241 } 242 243 NTSTATUS 244 FDO_StartDevice( 245 PDEVICE_OBJECT DeviceObject, 246 PIRP Irp) 247 { 248 NTSTATUS Status; 249 PFDO_DEVICE_EXTENSION FDODeviceExtension; 250 251 /* Get device extension */ 252 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 253 ASSERT(FDODeviceExtension->Common.IsFDO); 254 255 /* First start lower device */ 256 if (IoForwardIrpSynchronously(FDODeviceExtension->NextDeviceObject, Irp)) 257 { 258 Status = Irp->IoStatus.Status; 259 } 260 else 261 { 262 Status = STATUS_UNSUCCESSFUL; 263 } 264 265 if (!NT_SUCCESS(Status)) 266 { 267 /* Failed to start lower device */ 268 DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status); 269 return Status; 270 } 271 272 /* Get descriptors */ 273 Status = USBCCGP_GetDescriptors(DeviceObject); 274 if (!NT_SUCCESS(Status)) 275 { 276 /* Failed to start lower device */ 277 DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status); 278 return Status; 279 } 280 281 /* Get capabilities */ 282 Status = FDO_QueryCapabilities(DeviceObject, 283 &FDODeviceExtension->Capabilities); 284 if (!NT_SUCCESS(Status)) 285 { 286 /* Failed to start lower device */ 287 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status); 288 return Status; 289 } 290 291 /* Now select the configuration */ 292 Status = USBCCGP_SelectConfiguration(DeviceObject, FDODeviceExtension); 293 if (!NT_SUCCESS(Status)) 294 { 295 /* Failed to select interface */ 296 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status); 297 return Status; 298 } 299 300 /* Query bus interface */ 301 USBCCGP_QueryInterface(FDODeviceExtension->NextDeviceObject, 302 &FDODeviceExtension->BusInterface); 303 304 /* Now enumerate the functions */ 305 Status = USBCCGP_EnumerateFunctions(DeviceObject); 306 if (!NT_SUCCESS(Status)) 307 { 308 /* Failed to enumerate functions */ 309 DPRINT1("Failed to enumerate functions with %x\n", Status); 310 return Status; 311 } 312 313 /* Sanity checks */ 314 ASSERT(FDODeviceExtension->FunctionDescriptorCount); 315 ASSERT(FDODeviceExtension->FunctionDescriptor); 316 DumpFunctionDescriptor(FDODeviceExtension->FunctionDescriptor, 317 FDODeviceExtension->FunctionDescriptorCount); 318 319 /* Now create the pdo */ 320 Status = FDO_CreateChildPdo(DeviceObject); 321 if (!NT_SUCCESS(Status)) 322 { 323 /* Failed */ 324 DPRINT1("FDO_CreateChildPdo failed with %x\n", Status); 325 return Status; 326 } 327 328 /* Inform pnp manager of new device objects */ 329 IoInvalidateDeviceRelations(FDODeviceExtension->PhysicalDeviceObject, 330 BusRelations); 331 332 /* Done */ 333 DPRINT("[USBCCGP] FDO initialized successfully\n"); 334 return Status; 335 } 336 337 NTSTATUS 338 FDO_CloseConfiguration( 339 IN PDEVICE_OBJECT DeviceObject) 340 { 341 NTSTATUS Status; 342 PURB Urb; 343 PFDO_DEVICE_EXTENSION FDODeviceExtension; 344 345 /* Get device extension */ 346 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 347 ASSERT(FDODeviceExtension->Common.IsFDO); 348 349 /* Nothing to do if we're not configured */ 350 if (FDODeviceExtension->ConfigurationDescriptor == NULL || 351 FDODeviceExtension->InterfaceList == NULL) 352 { 353 return STATUS_SUCCESS; 354 } 355 356 /* Now allocate the urb */ 357 Urb = USBD_CreateConfigurationRequestEx(FDODeviceExtension->ConfigurationDescriptor, 358 FDODeviceExtension->InterfaceList); 359 if (!Urb) 360 { 361 /* No memory */ 362 return STATUS_INSUFFICIENT_RESOURCES; 363 } 364 365 /* Clear configuration descriptor to make it an unconfigure request */ 366 Urb->UrbSelectConfiguration.ConfigurationDescriptor = NULL; 367 368 /* Submit urb */ 369 Status = USBCCGP_SyncUrbRequest(FDODeviceExtension->NextDeviceObject, Urb); 370 if (!NT_SUCCESS(Status)) 371 { 372 /* Failed to set configuration */ 373 DPRINT1("USBCCGP_SyncUrbRequest failed to unconfigure device\n", Status); 374 } 375 376 ExFreePool(Urb); 377 return Status; 378 } 379 380 381 NTSTATUS 382 FDO_HandlePnp( 383 PDEVICE_OBJECT DeviceObject, 384 PIRP Irp) 385 { 386 PIO_STACK_LOCATION IoStack; 387 NTSTATUS Status; 388 PFDO_DEVICE_EXTENSION FDODeviceExtension; 389 390 /* Get device extension */ 391 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 392 ASSERT(FDODeviceExtension->Common.IsFDO); 393 394 395 /* Get stack location */ 396 IoStack = IoGetCurrentIrpStackLocation(Irp); 397 DPRINT("[USBCCGP] PnP Minor %x\n", IoStack->MinorFunction); 398 switch(IoStack->MinorFunction) 399 { 400 case IRP_MN_REMOVE_DEVICE: 401 { 402 // Unconfigure device */ 403 DPRINT1("[USBCCGP] FDO IRP_MN_REMOVE\n"); 404 FDO_CloseConfiguration(DeviceObject); 405 406 /* Send the IRP down the stack */ 407 Irp->IoStatus.Status = STATUS_SUCCESS; 408 IoSkipCurrentIrpStackLocation(Irp); 409 Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 410 411 /* Detach from the device stack */ 412 IoDetachDevice(FDODeviceExtension->NextDeviceObject); 413 414 /* Delete the device object */ 415 IoDeleteDevice(DeviceObject); 416 417 /* Request completed */ 418 break; 419 } 420 case IRP_MN_START_DEVICE: 421 { 422 /* Start the device */ 423 Status = FDO_StartDevice(DeviceObject, Irp); 424 break; 425 } 426 case IRP_MN_QUERY_DEVICE_RELATIONS: 427 { 428 /* Handle device relations */ 429 Status = FDO_DeviceRelations(DeviceObject, Irp); 430 if (!NT_SUCCESS(Status)) 431 { 432 break; 433 } 434 435 /* Forward irp to next device object */ 436 IoSkipCurrentIrpStackLocation(Irp); 437 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 438 } 439 case IRP_MN_QUERY_CAPABILITIES: 440 { 441 /* Copy capabilities */ 442 RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, 443 &FDODeviceExtension->Capabilities, 444 sizeof(DEVICE_CAPABILITIES)); 445 Status = STATUS_UNSUCCESSFUL; 446 447 if (IoForwardIrpSynchronously(FDODeviceExtension->NextDeviceObject, Irp)) 448 { 449 Status = Irp->IoStatus.Status; 450 if (NT_SUCCESS(Status)) 451 { 452 IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE; 453 } 454 } 455 break; 456 } 457 case IRP_MN_QUERY_REMOVE_DEVICE: 458 case IRP_MN_QUERY_STOP_DEVICE: 459 { 460 /* Sure */ 461 Irp->IoStatus.Status = STATUS_SUCCESS; 462 463 /* Forward irp to next device object */ 464 IoSkipCurrentIrpStackLocation(Irp); 465 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 466 } 467 default: 468 { 469 /* Forward irp to next device object */ 470 IoSkipCurrentIrpStackLocation(Irp); 471 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 472 } 473 474 } 475 476 /* Complete request */ 477 Irp->IoStatus.Status = Status; 478 IoCompleteRequest(Irp, IO_NO_INCREMENT); 479 return Status; 480 } 481 482 NTSTATUS 483 FDO_HandleResetCyclePort( 484 PDEVICE_OBJECT DeviceObject, 485 PIRP Irp) 486 { 487 PIO_STACK_LOCATION IoStack; 488 NTSTATUS Status; 489 PFDO_DEVICE_EXTENSION FDODeviceExtension; 490 PLIST_ENTRY ListHead, Entry; 491 LIST_ENTRY TempList; 492 PUCHAR ResetActive; 493 PIRP ListIrp; 494 KIRQL OldLevel; 495 496 /* Get device extension */ 497 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 498 ASSERT(FDODeviceExtension->Common.IsFDO); 499 500 /* Get stack location */ 501 IoStack = IoGetCurrentIrpStackLocation(Irp); 502 DPRINT("FDO_HandleResetCyclePort IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); 503 504 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT) 505 { 506 /* Use reset port list */ 507 ListHead = &FDODeviceExtension->ResetPortListHead; 508 ResetActive = &FDODeviceExtension->ResetPortActive; 509 } 510 else 511 { 512 /* Use cycle port list */ 513 ListHead = &FDODeviceExtension->CyclePortListHead; 514 ResetActive = &FDODeviceExtension->CyclePortActive; 515 } 516 517 /* Acquire lock */ 518 KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel); 519 520 if (*ResetActive) 521 { 522 /* Insert into pending list */ 523 InsertTailList(ListHead, &Irp->Tail.Overlay.ListEntry); 524 525 /* Mark irp pending */ 526 IoMarkIrpPending(Irp); 527 Status = STATUS_PENDING; 528 529 /* Release lock */ 530 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); 531 } 532 else 533 { 534 /* Mark reset active */ 535 *ResetActive = TRUE; 536 537 /* Release lock */ 538 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); 539 540 /* Forward request synchronized */ 541 NT_VERIFY(IoForwardIrpSynchronously(FDODeviceExtension->NextDeviceObject, Irp)); 542 543 /* Reacquire lock */ 544 KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel); 545 546 /* Mark reset as completed */ 547 *ResetActive = FALSE; 548 549 /* Move all requests into temporary list */ 550 InitializeListHead(&TempList); 551 while(!IsListEmpty(ListHead)) 552 { 553 Entry = RemoveHeadList(ListHead); 554 InsertTailList(&TempList, Entry); 555 } 556 557 /* Release lock */ 558 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); 559 560 /* Complete pending irps */ 561 while(!IsListEmpty(&TempList)) 562 { 563 Entry = RemoveHeadList(&TempList); 564 ListIrp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); 565 566 /* Complete request with status success */ 567 ListIrp->IoStatus.Status = STATUS_SUCCESS; 568 IoCompleteRequest(ListIrp, IO_NO_INCREMENT); 569 } 570 571 /* Status success */ 572 Status = STATUS_SUCCESS; 573 } 574 575 return Status; 576 } 577 578 579 580 NTSTATUS 581 FDO_HandleInternalDeviceControl( 582 PDEVICE_OBJECT DeviceObject, 583 PIRP Irp) 584 { 585 PIO_STACK_LOCATION IoStack; 586 NTSTATUS Status; 587 PFDO_DEVICE_EXTENSION FDODeviceExtension; 588 589 /* Get device extension */ 590 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 591 ASSERT(FDODeviceExtension->Common.IsFDO); 592 593 /* Get stack location */ 594 IoStack = IoGetCurrentIrpStackLocation(Irp); 595 596 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT || 597 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT) 598 { 599 /* Handle reset / cycle ports */ 600 Status = FDO_HandleResetCyclePort(DeviceObject, Irp); 601 DPRINT("FDO_HandleResetCyclePort Status %x\n", Status); 602 if (Status != STATUS_PENDING) 603 { 604 /* Complete request */ 605 Irp->IoStatus.Status = Status; 606 IoCompleteRequest(Irp, IO_NO_INCREMENT); 607 } 608 return Status; 609 } 610 611 /* Forward and forget request */ 612 IoSkipCurrentIrpStackLocation(Irp); 613 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 614 } 615 616 NTSTATUS 617 FDO_HandleSystemControl( 618 PDEVICE_OBJECT DeviceObject, 619 PIRP Irp) 620 { 621 PFDO_DEVICE_EXTENSION FDODeviceExtension; 622 623 /* Get device extension */ 624 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 625 ASSERT(FDODeviceExtension->Common.IsFDO); 626 627 /* Forward and forget request */ 628 IoSkipCurrentIrpStackLocation(Irp); 629 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 630 } 631 632 NTSTATUS 633 FDO_Dispatch( 634 PDEVICE_OBJECT DeviceObject, 635 PIRP Irp) 636 { 637 PIO_STACK_LOCATION IoStack; 638 NTSTATUS Status; 639 PFDO_DEVICE_EXTENSION FDODeviceExtension; 640 641 /* Get device extension */ 642 FDODeviceExtension = DeviceObject->DeviceExtension; 643 ASSERT(FDODeviceExtension->Common.IsFDO); 644 645 /* Get stack location */ 646 IoStack = IoGetCurrentIrpStackLocation(Irp); 647 648 switch(IoStack->MajorFunction) 649 { 650 case IRP_MJ_PNP: 651 return FDO_HandlePnp(DeviceObject, Irp); 652 case IRP_MJ_INTERNAL_DEVICE_CONTROL: 653 return FDO_HandleInternalDeviceControl(DeviceObject, Irp); 654 case IRP_MJ_POWER: 655 PoStartNextPowerIrp(Irp); 656 IoSkipCurrentIrpStackLocation(Irp); 657 return PoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 658 case IRP_MJ_SYSTEM_CONTROL: 659 return FDO_HandleSystemControl(DeviceObject, Irp); 660 default: 661 DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction); 662 ASSERT(FALSE); 663 Status = Irp->IoStatus.Status; 664 IoCompleteRequest(Irp, IO_NO_INCREMENT); 665 return Status; 666 } 667 668 } 669