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 Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp); 257 258 if (!NT_SUCCESS(Status)) 259 { 260 /* Failed to start lower device */ 261 DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status); 262 return Status; 263 } 264 265 /* Get descriptors */ 266 Status = USBCCGP_GetDescriptors(DeviceObject); 267 if (!NT_SUCCESS(Status)) 268 { 269 /* Failed to start lower device */ 270 DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status); 271 return Status; 272 } 273 274 /* Get capabilities */ 275 Status = FDO_QueryCapabilities(DeviceObject, 276 &FDODeviceExtension->Capabilities); 277 if (!NT_SUCCESS(Status)) 278 { 279 /* Failed to start lower device */ 280 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status); 281 return Status; 282 } 283 284 /* Now select the configuration */ 285 Status = USBCCGP_SelectConfiguration(DeviceObject, FDODeviceExtension); 286 if (!NT_SUCCESS(Status)) 287 { 288 /* Failed to select interface */ 289 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status); 290 return Status; 291 } 292 293 /* Query bus interface */ 294 USBCCGP_QueryInterface(FDODeviceExtension->NextDeviceObject, 295 &FDODeviceExtension->BusInterface); 296 297 /* Now enumerate the functions */ 298 Status = USBCCGP_EnumerateFunctions(DeviceObject); 299 if (!NT_SUCCESS(Status)) 300 { 301 /* Failed to enumerate functions */ 302 DPRINT1("Failed to enumerate functions with %x\n", Status); 303 return Status; 304 } 305 306 /* Sanity checks */ 307 ASSERT(FDODeviceExtension->FunctionDescriptorCount); 308 ASSERT(FDODeviceExtension->FunctionDescriptor); 309 DumpFunctionDescriptor(FDODeviceExtension->FunctionDescriptor, 310 FDODeviceExtension->FunctionDescriptorCount); 311 312 /* Now create the pdo */ 313 Status = FDO_CreateChildPdo(DeviceObject); 314 if (!NT_SUCCESS(Status)) 315 { 316 /* Failed */ 317 DPRINT1("FDO_CreateChildPdo failed with %x\n", Status); 318 return Status; 319 } 320 321 /* Inform pnp manager of new device objects */ 322 IoInvalidateDeviceRelations(FDODeviceExtension->PhysicalDeviceObject, 323 BusRelations); 324 325 /* Done */ 326 DPRINT("[USBCCGP] FDO initialized successfully\n"); 327 return Status; 328 } 329 330 NTSTATUS 331 FDO_CloseConfiguration( 332 IN PDEVICE_OBJECT DeviceObject) 333 { 334 NTSTATUS Status; 335 PURB Urb; 336 PFDO_DEVICE_EXTENSION FDODeviceExtension; 337 338 /* Get device extension */ 339 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 340 ASSERT(FDODeviceExtension->Common.IsFDO); 341 342 /* Nothing to do if we're not configured */ 343 if (FDODeviceExtension->ConfigurationDescriptor == NULL || 344 FDODeviceExtension->InterfaceList == NULL) 345 { 346 return STATUS_SUCCESS; 347 } 348 349 /* Now allocate the urb */ 350 Urb = USBD_CreateConfigurationRequestEx(FDODeviceExtension->ConfigurationDescriptor, 351 FDODeviceExtension->InterfaceList); 352 if (!Urb) 353 { 354 /* No memory */ 355 return STATUS_INSUFFICIENT_RESOURCES; 356 } 357 358 /* Clear configuration descriptor to make it an unconfigure request */ 359 Urb->UrbSelectConfiguration.ConfigurationDescriptor = NULL; 360 361 /* Submit urb */ 362 Status = USBCCGP_SyncUrbRequest(FDODeviceExtension->NextDeviceObject, Urb); 363 if (!NT_SUCCESS(Status)) 364 { 365 /* Failed to set configuration */ 366 DPRINT1("USBCCGP_SyncUrbRequest failed to unconfigure device\n", Status); 367 } 368 369 ExFreePool(Urb); 370 return Status; 371 } 372 373 374 NTSTATUS 375 FDO_HandlePnp( 376 PDEVICE_OBJECT DeviceObject, 377 PIRP Irp) 378 { 379 PIO_STACK_LOCATION IoStack; 380 NTSTATUS Status; 381 PFDO_DEVICE_EXTENSION FDODeviceExtension; 382 383 /* Get device extension */ 384 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 385 ASSERT(FDODeviceExtension->Common.IsFDO); 386 387 388 /* Get stack location */ 389 IoStack = IoGetCurrentIrpStackLocation(Irp); 390 DPRINT("[USBCCGP] PnP Minor %x\n", IoStack->MinorFunction); 391 switch(IoStack->MinorFunction) 392 { 393 case IRP_MN_REMOVE_DEVICE: 394 { 395 // Unconfigure device */ 396 DPRINT1("[USBCCGP] FDO IRP_MN_REMOVE\n"); 397 FDO_CloseConfiguration(DeviceObject); 398 399 /* Send the IRP down the stack */ 400 Irp->IoStatus.Status = STATUS_SUCCESS; 401 IoSkipCurrentIrpStackLocation(Irp); 402 Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 403 404 /* Detach from the device stack */ 405 IoDetachDevice(FDODeviceExtension->NextDeviceObject); 406 407 /* Delete the device object */ 408 IoDeleteDevice(DeviceObject); 409 410 /* Request completed */ 411 break; 412 } 413 case IRP_MN_START_DEVICE: 414 { 415 /* Start the device */ 416 Status = FDO_StartDevice(DeviceObject, Irp); 417 break; 418 } 419 case IRP_MN_QUERY_DEVICE_RELATIONS: 420 { 421 /* Handle device relations */ 422 Status = FDO_DeviceRelations(DeviceObject, Irp); 423 if (!NT_SUCCESS(Status)) 424 { 425 break; 426 } 427 428 /* Forward irp to next device object */ 429 IoSkipCurrentIrpStackLocation(Irp); 430 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 431 } 432 case IRP_MN_QUERY_CAPABILITIES: 433 { 434 /* Copy capabilities */ 435 RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, 436 &FDODeviceExtension->Capabilities, 437 sizeof(DEVICE_CAPABILITIES)); 438 Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp); 439 if (NT_SUCCESS(Status)) 440 { 441 /* Surprise removal ok */ 442 IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE; 443 } 444 break; 445 } 446 case IRP_MN_QUERY_REMOVE_DEVICE: 447 case IRP_MN_QUERY_STOP_DEVICE: 448 { 449 /* Sure */ 450 Irp->IoStatus.Status = STATUS_SUCCESS; 451 452 /* Forward irp to next device object */ 453 IoSkipCurrentIrpStackLocation(Irp); 454 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 455 } 456 default: 457 { 458 /* Forward irp to next device object */ 459 IoSkipCurrentIrpStackLocation(Irp); 460 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 461 } 462 463 } 464 465 /* Complete request */ 466 Irp->IoStatus.Status = Status; 467 IoCompleteRequest(Irp, IO_NO_INCREMENT); 468 return Status; 469 } 470 471 NTSTATUS 472 FDO_HandleResetCyclePort( 473 PDEVICE_OBJECT DeviceObject, 474 PIRP Irp) 475 { 476 PIO_STACK_LOCATION IoStack; 477 NTSTATUS Status; 478 PFDO_DEVICE_EXTENSION FDODeviceExtension; 479 PLIST_ENTRY ListHead, Entry; 480 LIST_ENTRY TempList; 481 PUCHAR ResetActive; 482 PIRP ListIrp; 483 KIRQL OldLevel; 484 485 /* Get device extension */ 486 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 487 ASSERT(FDODeviceExtension->Common.IsFDO); 488 489 /* Get stack location */ 490 IoStack = IoGetCurrentIrpStackLocation(Irp); 491 DPRINT("FDO_HandleResetCyclePort IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); 492 493 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT) 494 { 495 /* Use reset port list */ 496 ListHead = &FDODeviceExtension->ResetPortListHead; 497 ResetActive = &FDODeviceExtension->ResetPortActive; 498 } 499 else 500 { 501 /* Use cycle port list */ 502 ListHead = &FDODeviceExtension->CyclePortListHead; 503 ResetActive = &FDODeviceExtension->CyclePortActive; 504 } 505 506 /* Acquire lock */ 507 KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel); 508 509 if (*ResetActive) 510 { 511 /* Insert into pending list */ 512 InsertTailList(ListHead, &Irp->Tail.Overlay.ListEntry); 513 514 /* Mark irp pending */ 515 IoMarkIrpPending(Irp); 516 Status = STATUS_PENDING; 517 518 /* Release lock */ 519 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); 520 } 521 else 522 { 523 /* Mark reset active */ 524 *ResetActive = TRUE; 525 526 /* Release lock */ 527 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); 528 529 /* Forward request synchronized */ 530 USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp); 531 532 /* Reacquire lock */ 533 KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel); 534 535 /* Mark reset as completed */ 536 *ResetActive = FALSE; 537 538 /* Move all requests into temporary list */ 539 InitializeListHead(&TempList); 540 while(!IsListEmpty(ListHead)) 541 { 542 Entry = RemoveHeadList(ListHead); 543 InsertTailList(&TempList, Entry); 544 } 545 546 /* Release lock */ 547 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); 548 549 /* Complete pending irps */ 550 while(!IsListEmpty(&TempList)) 551 { 552 Entry = RemoveHeadList(&TempList); 553 ListIrp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); 554 555 /* Complete request with status success */ 556 ListIrp->IoStatus.Status = STATUS_SUCCESS; 557 IoCompleteRequest(ListIrp, IO_NO_INCREMENT); 558 } 559 560 /* Status success */ 561 Status = STATUS_SUCCESS; 562 } 563 564 return Status; 565 } 566 567 568 569 NTSTATUS 570 FDO_HandleInternalDeviceControl( 571 PDEVICE_OBJECT DeviceObject, 572 PIRP Irp) 573 { 574 PIO_STACK_LOCATION IoStack; 575 NTSTATUS Status; 576 PFDO_DEVICE_EXTENSION FDODeviceExtension; 577 578 /* Get device extension */ 579 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 580 ASSERT(FDODeviceExtension->Common.IsFDO); 581 582 /* Get stack location */ 583 IoStack = IoGetCurrentIrpStackLocation(Irp); 584 585 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT || 586 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT) 587 { 588 /* Handle reset / cycle ports */ 589 Status = FDO_HandleResetCyclePort(DeviceObject, Irp); 590 DPRINT("FDO_HandleResetCyclePort Status %x\n", Status); 591 if (Status != STATUS_PENDING) 592 { 593 /* Complete request */ 594 Irp->IoStatus.Status = Status; 595 IoCompleteRequest(Irp, IO_NO_INCREMENT); 596 } 597 return Status; 598 } 599 600 /* Forward and forget request */ 601 IoSkipCurrentIrpStackLocation(Irp); 602 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 603 } 604 605 NTSTATUS 606 FDO_HandleSystemControl( 607 PDEVICE_OBJECT DeviceObject, 608 PIRP Irp) 609 { 610 PFDO_DEVICE_EXTENSION FDODeviceExtension; 611 612 /* Get device extension */ 613 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 614 ASSERT(FDODeviceExtension->Common.IsFDO); 615 616 /* Forward and forget request */ 617 IoSkipCurrentIrpStackLocation(Irp); 618 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 619 } 620 621 NTSTATUS 622 FDO_Dispatch( 623 PDEVICE_OBJECT DeviceObject, 624 PIRP Irp) 625 { 626 PIO_STACK_LOCATION IoStack; 627 NTSTATUS Status; 628 PFDO_DEVICE_EXTENSION FDODeviceExtension; 629 630 /* Get device extension */ 631 FDODeviceExtension = DeviceObject->DeviceExtension; 632 ASSERT(FDODeviceExtension->Common.IsFDO); 633 634 /* Get stack location */ 635 IoStack = IoGetCurrentIrpStackLocation(Irp); 636 637 switch(IoStack->MajorFunction) 638 { 639 case IRP_MJ_PNP: 640 return FDO_HandlePnp(DeviceObject, Irp); 641 case IRP_MJ_INTERNAL_DEVICE_CONTROL: 642 return FDO_HandleInternalDeviceControl(DeviceObject, Irp); 643 case IRP_MJ_POWER: 644 PoStartNextPowerIrp(Irp); 645 IoSkipCurrentIrpStackLocation(Irp); 646 return PoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); 647 case IRP_MJ_SYSTEM_CONTROL: 648 return FDO_HandleSystemControl(DeviceObject, Irp); 649 default: 650 DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction); 651 ASSERT(FALSE); 652 Status = Irp->IoStatus.Status; 653 IoCompleteRequest(Irp, IO_NO_INCREMENT); 654 return Status; 655 } 656 657 } 658