/*** PRIVATE *****************************************************************/
+static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion;
+
+static NTSTATUS NTAPI
+ForwardIrpAndWaitCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+ if (Irp->PendingReturned)
+ KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS NTAPI
+ForwardIrpAndWait(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ KEVENT Event;
+ NTSTATUS Status;
+ PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Ldo;
+ ASSERT(LowerDevice);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+
+ IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
+
+ Status = IoCallDriver(LowerDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ if (NT_SUCCESS(Status))
+ Status = Irp->IoStatus.Status;
+ }
+
+ return Status;
+}
+
static NTSTATUS
FdoLocateChildDevice(
PPCI_DEVICE *Device,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
- PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+ PPDO_DEVICE_EXTENSION PdoDeviceExtension = NULL;
PFDO_DEVICE_EXTENSION DeviceExtension;
PDEVICE_RELATIONS Relations;
PLIST_ENTRY CurrentEntry;
ULONG Size;
ULONG i;
+ UNREFERENCED_PARAMETER(IrpSp);
+
DPRINT("Called\n");
ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
(DeviceExtension->DeviceListCount - 1);
- Relations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(PagedPool, Size, TAG_PCI);
+ Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
if (!Relations)
return STATUS_INSUFFICIENT_RESOURCES;
break;
}
- Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
//Device->Pdo->Flags |= DO_POWER_PAGABLE;
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- static BOOLEAN FoundBuggyAllocatedResourcesList = FALSE;
PFDO_DEVICE_EXTENSION DeviceExtension;
PCM_RESOURCE_LIST AllocatedResources;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
AllocatedResources = IoGetCurrentIrpStackLocation(Irp)->Parameters.StartDevice.AllocatedResources;
- /* HACK due to a bug in ACPI driver, which doesn't report the bus number */
- if (!FoundBuggyAllocatedResourcesList &&
- (!AllocatedResources || AllocatedResources->Count == 0))
- {
- FoundBuggyAllocatedResourcesList = TRUE;
- DPRINT1("No bus number resource found (bug in acpi.sys?), assuming bus number #0\n");
- DeviceExtension->BusNumber = 0;
- goto next;
- }
- /* END HACK */
if (!AllocatedResources)
{
DPRINT("No allocated resources sent to driver\n");
ASSERT(DeviceExtension->State == dsStopped);
+ /* By default, use the bus number in the resource list header */
+ DeviceExtension->BusNumber = AllocatedResources->List[0].BusNumber;
+
for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++)
{
ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
{
if (FoundBusNumber || ResourceDescriptor->u.BusNumber.Length != 1)
return STATUS_INVALID_PARAMETER;
+ /* Use this one instead */
+ ASSERT(AllocatedResources->List[0].BusNumber == ResourceDescriptor->u.BusNumber.Start);
DeviceExtension->BusNumber = ResourceDescriptor->u.BusNumber.Start;
DPRINT("Found bus number resource: %lu\n", DeviceExtension->BusNumber);
FoundBusNumber = TRUE;
break;
}
default:
- DPRINT1("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type);
+ DPRINT("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type);
}
}
- if (!FoundBusNumber)
- {
- DPRINT("Some required resources were not found in allocated resources list\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-next:
InitializeListHead(&DeviceExtension->DeviceListHead);
KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
DeviceExtension->DeviceListCount = 0;
PFDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
+ UNREFERENCED_PARAMETER(Irp);
+
DPRINT("Called\n");
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
{
PFDO_DEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
+ NTSTATUS Status = Irp->IoStatus.Status;
DPRINT("Called\n");
break;
#endif
case IRP_MN_QUERY_DEVICE_RELATIONS:
+ if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
+ break;
+
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
- break;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
#if 0
case IRP_MN_QUERY_PNP_DEVICE_STATE:
Status = STATUS_NOT_IMPLEMENTED;
#endif
case IRP_MN_START_DEVICE:
DPRINT("IRP_MN_START_DEVICE received\n");
- Status = FdoStartDevice(DeviceObject, Irp);
- break;
+ Status = ForwardIrpAndWait(DeviceObject, Irp);
+ if (NT_SUCCESS(Status))
+ Status = FdoStartDevice(DeviceObject, Irp);
+
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
case IRP_MN_STOP_DEVICE:
/* Currently not supported */
Status = STATUS_UNSUCCESSFUL;
- break;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
#if 0
case IRP_MN_SURPRISE_REMOVAL:
Status = STATUS_NOT_IMPLEMENTED;
break;
#endif
+ case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+ break;
+ case IRP_MN_REMOVE_DEVICE:
+ DPRINT1("IRP_MN_REMOVE_DEVICE is UNIMPLEMENTED!\n");
+ break;
default:
DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
- /* fall through */
-
- case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
- /*
- * Do NOT complete the IRP as it will be processed by the lower
- * device object, which will complete the IRP
- */
- IoSkipCurrentIrpStackLocation(Irp);
- Status = IoCallDriver(DeviceExtension->Ldo, Irp);
- return Status;
break;
}
-
- if (Status != STATUS_PENDING) {
- if (Status != STATUS_NOT_IMPLEMENTED)
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
+ Irp->IoStatus.Status = Status;
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(DeviceExtension->Ldo, Irp);
DPRINT("Leaving. Status 0x%X\n", Status);