From 6010d1fd63134767216bcccb4e982220efb74ce6 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 12 Dec 2003 21:54:42 +0000 Subject: [PATCH] - Fix Unix line breaks. - Use HAL PCI bus routines in order avoid race conditions. - Use slot number to distinguish multiple device of the same kind. svn path=/trunk/; revision=6980 --- reactos/drivers/bus/pci/fdo.c | 950 ++++++++++++++++--------------- reactos/drivers/bus/pci/pci.c | 419 +------------- reactos/drivers/bus/pci/pci.h | 21 +- reactos/drivers/bus/pci/pcidef.h | 15 +- reactos/drivers/bus/pci/pdo.c | 8 +- 5 files changed, 509 insertions(+), 904 deletions(-) diff --git a/reactos/drivers/bus/pci/fdo.c b/reactos/drivers/bus/pci/fdo.c index 5a4baf558a1..b57dbb7a90d 100644 --- a/reactos/drivers/bus/pci/fdo.c +++ b/reactos/drivers/bus/pci/fdo.c @@ -1,459 +1,491 @@ -/* $Id: fdo.c,v 1.4 2003/11/24 16:15:00 gvg Exp $ - * - * PROJECT: ReactOS PCI bus driver - * FILE: fdo.c - * PURPOSE: PCI device object dispatch routines - * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) - * UPDATE HISTORY: - * 10-09-2001 CSH Created - */ -#include - -#define NDEBUG -#include - -/*** PRIVATE *****************************************************************/ - -NTSTATUS -FdoLocateChildDevice( - PPCI_DEVICE *Device, - PFDO_DEVICE_EXTENSION DeviceExtension, - PPCI_COMMON_CONFIG PciConfig) -{ - PLIST_ENTRY CurrentEntry; - PPCI_DEVICE CurrentDevice; - - CurrentEntry = DeviceExtension->DeviceListHead.Flink; - while (CurrentEntry != &DeviceExtension->DeviceListHead) { - CurrentDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry); - - /* If both vendor ID and device ID match, it is the same device */ - if ((PciConfig->VendorID == CurrentDevice->PciConfig.VendorID) && - (PciConfig->DeviceID == CurrentDevice->PciConfig.DeviceID)) { - *Device = CurrentDevice; - return STATUS_SUCCESS; - } - - CurrentEntry = CurrentEntry->Flink; - } - - *Device = NULL; - return STATUS_UNSUCCESSFUL; -} - - -NTSTATUS -FdoEnumerateDevices( - PDEVICE_OBJECT DeviceObject) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - PCI_COMMON_CONFIG PciConfig; - PLIST_ENTRY CurrentEntry; - PPCI_DEVICE Device; - NTSTATUS Status; - ULONG Slot; - ULONG Size; - - DPRINT("Called\n"); - - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - /* Mark all devices to be removed. If we don't discover them again during - enumeration, assume that they have been surprise removed */ - CurrentEntry = DeviceExtension->DeviceListHead.Flink; - while (CurrentEntry != &DeviceExtension->DeviceListHead) { - Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry); - Device->RemovePending = TRUE; - CurrentEntry = CurrentEntry->Flink; - } - - DeviceExtension->DeviceListCount = 0; - - /* Enumerate devices on the PCI bus */ - for (Slot = 0; Slot < 256; Slot++) - { - Size = PciGetBusData( - DeviceExtension->BusNumber, - Slot, - &PciConfig, - 0, - sizeof(PCI_COMMON_CONFIG)); - if (Size != 0) - { - DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n", - DeviceExtension->BusNumber, - Slot>>3, - Slot & 0x07, - PciConfig.VendorID, - PciConfig.DeviceID); - - Status = FdoLocateChildDevice(&Device, DeviceExtension, &PciConfig); - if (!NT_SUCCESS(Status)) { - Device = (PPCI_DEVICE)ExAllocatePool(PagedPool, sizeof(PCI_DEVICE)); - if (!Device) - { - /* FIXME: Cleanup resources for already discovered devices */ - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlZeroMemory(Device, sizeof(PCI_DEVICE)); - - RtlMoveMemory(&Device->PciConfig, &PciConfig, sizeof(PCI_COMMON_CONFIG)); - - ExInterlockedInsertTailList( - &DeviceExtension->DeviceListHead, - &Device->ListEntry, - &DeviceExtension->DeviceListLock); - } - - /* Don't remove this device */ - Device->RemovePending = FALSE; - - DeviceExtension->DeviceListCount++; - } - } - - return STATUS_SUCCESS; -} - - -NTSTATUS -FdoQueryBusRelations( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - PIO_STACK_LOCATION IrpSp) -{ - PPDO_DEVICE_EXTENSION PdoDeviceExtension; - PFDO_DEVICE_EXTENSION DeviceExtension; - PDEVICE_RELATIONS Relations; - PLIST_ENTRY CurrentEntry; - PPCI_DEVICE Device; - NTSTATUS Status; - BOOLEAN ErrorOccurred; - NTSTATUS ErrorStatus; - WCHAR Buffer[MAX_PATH]; - ULONG Size; - ULONG i; - - DPRINT("Called\n"); - - ErrorStatus = STATUS_INSUFFICIENT_RESOURCES; - - Status = STATUS_SUCCESS; - - ErrorOccurred = FALSE; - - FdoEnumerateDevices(DeviceObject); - - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - if (Irp->IoStatus.Information) { - /* FIXME: Another bus driver has already created a DEVICE_RELATIONS - structure so we must merge this structure with our own */ - } - - Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) * - (DeviceExtension->DeviceListCount - 1); - Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size); - if (!Relations) - return STATUS_INSUFFICIENT_RESOURCES; - - Relations->Count = DeviceExtension->DeviceListCount; - - i = 0; - CurrentEntry = DeviceExtension->DeviceListHead.Flink; - while (CurrentEntry != &DeviceExtension->DeviceListHead) { - Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry); - - PdoDeviceExtension = NULL; - - if (!Device->Pdo) { - /* Create a physical device object for the - device as it does not already have one */ - Status = IoCreateDevice( - DeviceObject->DriverObject, - sizeof(PDO_DEVICE_EXTENSION), - NULL, - FILE_DEVICE_CONTROLLER, - 0, - FALSE, - &Device->Pdo); - if (!NT_SUCCESS(Status)) { - DPRINT("IoCreateDevice() failed with status 0x%X\n", Status); - ErrorStatus = Status; - ErrorOccurred = TRUE; - break; - } - - Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; - - Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING; - - //Device->Pdo->Flags |= DO_POWER_PAGABLE; - - PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension; - - RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION)); - - PdoDeviceExtension->Common.IsFDO = FALSE; - - PdoDeviceExtension->Common.DeviceObject = Device->Pdo; - - PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0; - - /* FIXME: Get device properties (Hardware IDs, etc.) */ - - swprintf( - Buffer, - L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X", - Device->PciConfig.VendorID, - Device->PciConfig.DeviceID, - (Device->PciConfig.u.type0.SubSystemID << 16) + - Device->PciConfig.u.type0.SubVendorID, - Device->PciConfig.RevisionID); - - if (!PciCreateUnicodeString( - &PdoDeviceExtension->DeviceID, - Buffer, - PagedPool)) { - ErrorOccurred = TRUE; - break; - } - - DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer); - } - - if (!Device->RemovePending) { - /* Reference the physical device object. The PnP manager - will dereference it again when it is no longer needed */ - ObReferenceObject(Device->Pdo); - - Relations->Objects[i] = Device->Pdo; - - i++; - } - - CurrentEntry = CurrentEntry->Flink; - } - - if (ErrorOccurred) { - /* FIXME: Cleanup all new PDOs created in this call. Please give me SEH!!! ;-) */ - /* FIXME: Should IoAttachDeviceToDeviceStack() be undone? */ - if (PdoDeviceExtension) { - RtlFreeUnicodeString(&PdoDeviceExtension->DeviceID); - ExFreePool(PdoDeviceExtension); - } - - ExFreePool(Relations); - return ErrorStatus; - } - - Irp->IoStatus.Information = (ULONG_PTR)Relations; - - return Status; -} - - -NTSTATUS -FdoStartDevice( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - - DPRINT("Called\n"); - - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - assert(DeviceExtension->State == dsStopped); - - InitializeListHead(&DeviceExtension->DeviceListHead); - KeInitializeSpinLock(&DeviceExtension->DeviceListLock); - DeviceExtension->DeviceListCount = 0; - - PciBusConfigType = PciGetBusConfigType(); - - DPRINT("Bus configuration is %d\n", PciBusConfigType); - - if (PciBusConfigType != pbtUnknown) { - /* At least one PCI bus is found */ - } - - /* FIXME: Find a way to get this information */ - DeviceExtension->BusNumber = 0; - - DeviceExtension->State = dsStarted; - - //Irp->IoStatus.Information = 0; - - return STATUS_SUCCESS; -} - - -NTSTATUS -FdoSetPower( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - PIO_STACK_LOCATION IrpSp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; - - DPRINT("Called\n"); - - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - if (IrpSp->Parameters.Power.Type == DevicePowerState) { - /* FIXME: Set device power state for the device */ - Status = STATUS_UNSUCCESSFUL; - } else { - Status = STATUS_UNSUCCESSFUL; - } - - return Status; -} - - -/*** PUBLIC ******************************************************************/ - -NTSTATUS -FdoPnpControl( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -/* - * FUNCTION: Handle Plug and Play IRPs for the PCI device object - * ARGUMENTS: - * DeviceObject = Pointer to functional device object of the PCI driver - * Irp = Pointer to IRP that should be handled - * RETURNS: - * Status - */ -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; - - DPRINT("Called\n"); - - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - switch (IrpSp->MinorFunction) { -#if 0 - case IRP_MN_CANCEL_REMOVE_DEVICE: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case IRP_MN_CANCEL_STOP_DEVICE: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case IRP_MN_DEVICE_USAGE_NOTIFICATION: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: - Status = STATUS_NOT_IMPLEMENTED; - break; -#endif - case IRP_MN_QUERY_DEVICE_RELATIONS: - Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp); - break; -#if 0 - case IRP_MN_QUERY_PNP_DEVICE_STATE: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case IRP_MN_QUERY_REMOVE_DEVICE: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case IRP_MN_QUERY_STOP_DEVICE: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case IRP_MN_REMOVE_DEVICE: - Status = STATUS_NOT_IMPLEMENTED; - break; -#endif - case IRP_MN_START_DEVICE: - DPRINT("IRP_MN_START_DEVICE received\n"); - Status = FdoStartDevice(DeviceObject, Irp); - break; - case IRP_MN_STOP_DEVICE: - /* Currently not supported */ - Status = STATUS_UNSUCCESSFUL; - break; -#if 0 - case IRP_MN_SURPRISE_REMOVAL: - Status = STATUS_NOT_IMPLEMENTED; - break; -#endif - default: - DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); - - /* - * 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); - } - - DPRINT("Leaving. Status 0x%X\n", Status); - - return Status; -} - - -NTSTATUS -FdoPowerControl( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -/* - * FUNCTION: Handle power management IRPs for the PCI device object - * ARGUMENTS: - * DeviceObject = Pointer to functional device object of the PCI driver - * Irp = Pointer to IRP that should be handled - * RETURNS: - * Status - */ -{ - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; - - DPRINT("Called\n"); - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - switch (IrpSp->MinorFunction) { - case IRP_MN_SET_POWER: - Status = FdoSetPower(DeviceObject, Irp, IrpSp); - break; - - default: - DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - - if (Status != STATUS_PENDING) { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - DPRINT("Leaving. Status 0x%X\n", Status); - - return Status; -} - -/* EOF */ +/* $Id: fdo.c,v 1.5 2003/12/12 21:54:42 ekohl Exp $ + * + * PROJECT: ReactOS PCI bus driver + * FILE: fdo.c + * PURPOSE: PCI device object dispatch routines + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * UPDATE HISTORY: + * 10-09-2001 CSH Created + */ + +#include + +#include "pcidef.h" +#include "pci.h" + +#define NDEBUG +#include + +/*** PRIVATE *****************************************************************/ + +static NTSTATUS +FdoLocateChildDevice( + PPCI_DEVICE *Device, + PFDO_DEVICE_EXTENSION DeviceExtension, + PCI_SLOT_NUMBER SlotNumber, + PPCI_COMMON_CONFIG PciConfig) +{ + PLIST_ENTRY CurrentEntry; + PPCI_DEVICE CurrentDevice; + + DPRINT("Called\n"); + + CurrentEntry = DeviceExtension->DeviceListHead.Flink; + while (CurrentEntry != &DeviceExtension->DeviceListHead) { + CurrentDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry); + + /* If both vendor ID and device ID match, it is the same device */ + if ((PciConfig->VendorID == CurrentDevice->PciConfig.VendorID) && + (PciConfig->DeviceID == CurrentDevice->PciConfig.DeviceID) && + (SlotNumber.u.AsULONG == CurrentDevice->SlotNumber.u.AsULONG)) { + *Device = CurrentDevice; + DPRINT("Done\n"); + return STATUS_SUCCESS; + } + + CurrentEntry = CurrentEntry->Flink; + } + + *Device = NULL; + DPRINT("Done\n"); + return STATUS_UNSUCCESSFUL; +} + + +static NTSTATUS +FdoEnumerateDevices( + PDEVICE_OBJECT DeviceObject) +{ + PFDO_DEVICE_EXTENSION DeviceExtension; + PCI_COMMON_CONFIG PciConfig; + PLIST_ENTRY CurrentEntry; + PPCI_DEVICE Device; + PCI_SLOT_NUMBER SlotNumber; + ULONG DeviceNumber; + ULONG FunctionNumber; + ULONG Size; + NTSTATUS Status; + + DPRINT("Called\n"); + + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* Mark all devices to be removed. If we don't discover them again during + enumeration, assume that they have been surprise removed */ + CurrentEntry = DeviceExtension->DeviceListHead.Flink; + while (CurrentEntry != &DeviceExtension->DeviceListHead) { + Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry); + Device->RemovePending = TRUE; + CurrentEntry = CurrentEntry->Flink; + } + + DeviceExtension->DeviceListCount = 0; + + /* Enumerate devices on the PCI bus */ + SlotNumber.u.AsULONG = 0; + for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++) + { + SlotNumber.u.bits.DeviceNumber = DeviceNumber; + for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++) + { + SlotNumber.u.bits.FunctionNumber = FunctionNumber; + + Size= HalGetBusData(PCIConfiguration, + DeviceExtension->BusNumber, + SlotNumber.u.AsULONG, + &PciConfig, + sizeof(PCI_COMMON_CONFIG)); + DPRINT("Size %lu\n", Size); + if (Size < sizeof(PCI_COMMON_CONFIG)) + { + if (FunctionNumber == 0) + { + break; + } + else + { + continue; + } + } + + DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n", + DeviceExtension->BusNumber, + DeviceNumber, + FunctionNumber, + PciConfig.VendorID, + PciConfig.DeviceID); + + Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig); + if (!NT_SUCCESS(Status)) + { + Device = (PPCI_DEVICE)ExAllocatePool(PagedPool, sizeof(PCI_DEVICE)); + if (!Device) + { + /* FIXME: Cleanup resources for already discovered devices */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory (Device, + sizeof(PCI_DEVICE)); + + RtlCopyMemory (&Device->SlotNumber, + &SlotNumber, + sizeof(PCI_SLOT_NUMBER)); + + RtlCopyMemory (&Device->PciConfig, + &PciConfig, + sizeof(PCI_COMMON_CONFIG)); + + ExInterlockedInsertTailList( + &DeviceExtension->DeviceListHead, + &Device->ListEntry, + &DeviceExtension->DeviceListLock); + } + + /* Don't remove this device */ + Device->RemovePending = FALSE; + + DeviceExtension->DeviceListCount++; + } + } + + DPRINT("Done\n"); + + return STATUS_SUCCESS; +} + + +static NTSTATUS +FdoQueryBusRelations( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PPDO_DEVICE_EXTENSION PdoDeviceExtension; + PFDO_DEVICE_EXTENSION DeviceExtension; + PDEVICE_RELATIONS Relations; + PLIST_ENTRY CurrentEntry; + PPCI_DEVICE Device; + NTSTATUS Status; + BOOLEAN ErrorOccurred; + NTSTATUS ErrorStatus; + WCHAR Buffer[MAX_PATH]; + ULONG Size; + ULONG i; + + DPRINT("Called\n"); + + ErrorStatus = STATUS_INSUFFICIENT_RESOURCES; + + Status = STATUS_SUCCESS; + + ErrorOccurred = FALSE; + + FdoEnumerateDevices(DeviceObject); + + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (Irp->IoStatus.Information) { + /* FIXME: Another bus driver has already created a DEVICE_RELATIONS + structure so we must merge this structure with our own */ + } + + Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) * + (DeviceExtension->DeviceListCount - 1); + Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size); + if (!Relations) + return STATUS_INSUFFICIENT_RESOURCES; + + Relations->Count = DeviceExtension->DeviceListCount; + + i = 0; + CurrentEntry = DeviceExtension->DeviceListHead.Flink; + while (CurrentEntry != &DeviceExtension->DeviceListHead) { + Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry); + + PdoDeviceExtension = NULL; + + if (!Device->Pdo) { + /* Create a physical device object for the + device as it does not already have one */ + Status = IoCreateDevice( + DeviceObject->DriverObject, + sizeof(PDO_DEVICE_EXTENSION), + NULL, + FILE_DEVICE_CONTROLLER, + 0, + FALSE, + &Device->Pdo); + if (!NT_SUCCESS(Status)) { + DPRINT("IoCreateDevice() failed with status 0x%X\n", Status); + ErrorStatus = Status; + ErrorOccurred = TRUE; + break; + } + + Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; + + Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING; + + //Device->Pdo->Flags |= DO_POWER_PAGABLE; + + PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension; + + RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION)); + + PdoDeviceExtension->Common.IsFDO = FALSE; + + PdoDeviceExtension->Common.DeviceObject = Device->Pdo; + + PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0; + + /* FIXME: Get device properties (Hardware IDs, etc.) */ + + swprintf( + Buffer, + L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X", + Device->PciConfig.VendorID, + Device->PciConfig.DeviceID, + (Device->PciConfig.u.type0.SubSystemID << 16) + + Device->PciConfig.u.type0.SubVendorID, + Device->PciConfig.RevisionID); + + if (!PciCreateUnicodeString( + &PdoDeviceExtension->DeviceID, + Buffer, + PagedPool)) { + ErrorOccurred = TRUE; + break; + } + + DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer); + } + + if (!Device->RemovePending) { + /* Reference the physical device object. The PnP manager + will dereference it again when it is no longer needed */ + ObReferenceObject(Device->Pdo); + + Relations->Objects[i] = Device->Pdo; + + i++; + } + + CurrentEntry = CurrentEntry->Flink; + } + + if (ErrorOccurred) { + /* FIXME: Cleanup all new PDOs created in this call. Please give me SEH!!! ;-) */ + /* FIXME: Should IoAttachDeviceToDeviceStack() be undone? */ + if (PdoDeviceExtension) { + RtlFreeUnicodeString(&PdoDeviceExtension->DeviceID); + ExFreePool(PdoDeviceExtension); + } + + ExFreePool(Relations); + return ErrorStatus; + } + + Irp->IoStatus.Information = (ULONG_PTR)Relations; + + DPRINT("Done\n"); + + return Status; +} + + +static NTSTATUS +FdoStartDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDO_DEVICE_EXTENSION DeviceExtension; + + DPRINT("Called\n"); + + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + assert(DeviceExtension->State == dsStopped); + + InitializeListHead(&DeviceExtension->DeviceListHead); + KeInitializeSpinLock(&DeviceExtension->DeviceListLock); + DeviceExtension->DeviceListCount = 0; + + /* FIXME: Find a way to get this information */ + DeviceExtension->BusNumber = 0; + + DeviceExtension->State = dsStarted; + + //Irp->IoStatus.Information = 0; + + return STATUS_SUCCESS; +} + + +static NTSTATUS +FdoSetPower( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PFDO_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + + DPRINT("Called\n"); + + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (IrpSp->Parameters.Power.Type == DevicePowerState) { + /* FIXME: Set device power state for the device */ + Status = STATUS_UNSUCCESSFUL; + } else { + Status = STATUS_UNSUCCESSFUL; + } + + return Status; +} + + +/*** PUBLIC ******************************************************************/ + +NTSTATUS +FdoPnpControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +/* + * FUNCTION: Handle Plug and Play IRPs for the PCI device object + * ARGUMENTS: + * DeviceObject = Pointer to functional device object of the PCI driver + * Irp = Pointer to IRP that should be handled + * RETURNS: + * Status + */ +{ + PFDO_DEVICE_EXTENSION DeviceExtension; + PIO_STACK_LOCATION IrpSp; + NTSTATUS Status; + + DPRINT("Called\n"); + + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + switch (IrpSp->MinorFunction) { +#if 0 + case IRP_MN_CANCEL_REMOVE_DEVICE: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case IRP_MN_CANCEL_STOP_DEVICE: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case IRP_MN_DEVICE_USAGE_NOTIFICATION: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: + Status = STATUS_NOT_IMPLEMENTED; + break; +#endif + case IRP_MN_QUERY_DEVICE_RELATIONS: + Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp); + break; +#if 0 + case IRP_MN_QUERY_PNP_DEVICE_STATE: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case IRP_MN_QUERY_REMOVE_DEVICE: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case IRP_MN_QUERY_STOP_DEVICE: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case IRP_MN_REMOVE_DEVICE: + Status = STATUS_NOT_IMPLEMENTED; + break; +#endif + case IRP_MN_START_DEVICE: + DPRINT("IRP_MN_START_DEVICE received\n"); + Status = FdoStartDevice(DeviceObject, Irp); + break; + case IRP_MN_STOP_DEVICE: + /* Currently not supported */ + Status = STATUS_UNSUCCESSFUL; + break; +#if 0 + case IRP_MN_SURPRISE_REMOVAL: + Status = STATUS_NOT_IMPLEMENTED; + break; +#endif + default: + DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); + + /* + * 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); + } + + DPRINT("Leaving. Status 0x%X\n", Status); + + return Status; +} + + +NTSTATUS +FdoPowerControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +/* + * FUNCTION: Handle power management IRPs for the PCI device object + * ARGUMENTS: + * DeviceObject = Pointer to functional device object of the PCI driver + * Irp = Pointer to IRP that should be handled + * RETURNS: + * Status + */ +{ + PIO_STACK_LOCATION IrpSp; + NTSTATUS Status; + + DPRINT("Called\n"); + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + switch (IrpSp->MinorFunction) { + case IRP_MN_SET_POWER: + Status = FdoSetPower(DeviceObject, Irp, IrpSp); + break; + + default: + DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + + if (Status != STATUS_PENDING) { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + DPRINT("Leaving. Status 0x%X\n", Status); + + return Status; +} + +/* EOF */ diff --git a/reactos/drivers/bus/pci/pci.c b/reactos/drivers/bus/pci/pci.c index 8918fe6dd57..58b2f2d6c6d 100644 --- a/reactos/drivers/bus/pci/pci.c +++ b/reactos/drivers/bus/pci/pci.c @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.4 2003/11/14 17:13:24 weiden Exp $ +/* $Id: pci.c,v 1.5 2003/12/12 21:54:42 ekohl Exp $ * * PROJECT: ReactOS PCI Bus driver * FILE: pci.c @@ -7,7 +7,11 @@ * UPDATE HISTORY: * 10-09-2001 CSH Created */ -#include + +#include + +#include "pcidef.h" +#include "pci.h" #define NDEBUG #include @@ -24,420 +28,9 @@ /*** PUBLIC ******************************************************************/ -PCI_BUS_TYPE PciBusConfigType = pbtUnknown; - /*** PRIVATE *****************************************************************/ -static NTSTATUS -PciReadConfigUchar(UCHAR Bus, - UCHAR Slot, - UCHAR Offset, - PUCHAR Value) -{ - switch (PciBusConfigType) - { - case pbtType1: - WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3)); - return STATUS_SUCCESS; - - case pbtType2: - WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot)); - WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); - *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset))); - WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); - return STATUS_SUCCESS; - case pbtUnknown: - break; - } - return STATUS_UNSUCCESSFUL; -} - - -static NTSTATUS -PciReadConfigUshort(UCHAR Bus, - UCHAR Slot, - UCHAR Offset, - PUSHORT Value) -{ - if ((Offset & 1) != 0) - { - return STATUS_INVALID_PARAMETER; - } - - switch (PciBusConfigType) - { - case pbtType1: - WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2)); - return STATUS_SUCCESS; - - case pbtType2: - WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot)); - WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); - *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset))); - WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); - return STATUS_SUCCESS; - case pbtUnknown: - break; - } - return STATUS_UNSUCCESSFUL; -} - - -static NTSTATUS -PciReadConfigUlong(UCHAR Bus, - UCHAR Slot, - UCHAR Offset, - PULONG Value) -{ - if ((Offset & 3) != 0) - { - return STATUS_INVALID_PARAMETER; - } - - switch (PciBusConfigType) - { - case pbtType1: - WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - *Value = READ_PORT_ULONG((PULONG)0xCFC); - return STATUS_SUCCESS; - - case pbtType2: - WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot)); - WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); - *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset))); - WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); - return STATUS_SUCCESS; - case pbtUnknown: - break; - } - return STATUS_UNSUCCESSFUL; -} - - -static NTSTATUS -PciWriteConfigUchar(UCHAR Bus, - UCHAR Slot, - UCHAR Offset, - UCHAR Value) -{ - switch (PciBusConfigType) - { - case pbtType1: - WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value); - return STATUS_SUCCESS; - - case pbtType2: - WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot)); - WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); - WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value); - WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); - return STATUS_SUCCESS; - case pbtUnknown: - break; - } - return STATUS_UNSUCCESSFUL; -} - - -static NTSTATUS -PciWriteConfigUshort(UCHAR Bus, - UCHAR Slot, - UCHAR Offset, - USHORT Value) -{ - if ((Offset & 1) != 0) - { - return STATUS_INVALID_PARAMETER; - } - - switch (PciBusConfigType) - { - case pbtType1: - WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value); - return STATUS_SUCCESS; - - case pbtType2: - WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot)); - WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); - WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value); - WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); - return STATUS_SUCCESS; - case pbtUnknown: - break; - } - return STATUS_UNSUCCESSFUL; -} - - -static NTSTATUS -PciWriteConfigUlong(UCHAR Bus, - UCHAR Slot, - UCHAR Offset, - ULONG Value) -{ - if ((Offset & 3) != 0) - { - return STATUS_INVALID_PARAMETER; - } - - switch (PciBusConfigType) - { - case pbtType1: - WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - WRITE_PORT_ULONG((PULONG)0xCFC, Value); - return STATUS_SUCCESS; - - case pbtType2: - WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot)); - WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); - WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value); - WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); - return STATUS_SUCCESS; - case pbtUnknown: - break; - } - return STATUS_UNSUCCESSFUL; -} - - -ULONG -PciGetBusData(ULONG BusNumber, - ULONG SlotNumber, - PVOID Buffer, - ULONG Offset, - ULONG Length) -{ - PVOID Ptr = Buffer; - ULONG Address = Offset; - ULONG Len = Length; - ULONG Vendor; - UCHAR HeaderType; - -#if 0 - DPRINT(" BusNumber %lu\n", BusNumber); - DPRINT(" SlotNumber %lu\n", SlotNumber); - DPRINT(" Offset 0x%lx\n", Offset); - DPRINT(" Length 0x%lx\n", Length); -#endif - - if ((Length == 0) || (PciBusConfigType == 0)) - return 0; - - /* 0E=PCI_HEADER_TYPE */ - PciReadConfigUchar(BusNumber, - SlotNumber & 0xF8, - 0x0E, - &HeaderType); - if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0)) - return 0; - - PciReadConfigUlong(BusNumber, - SlotNumber, - 0x00, - &Vendor); - /* some broken boards return 0 if a slot is empty: */ - if (Vendor == 0xFFFFFFFF || Vendor == 0) - return 0; - - if ((Address & 1) && (Len >= 1)) - { - PciReadConfigUchar(BusNumber, - SlotNumber, - Address, - Ptr); - Ptr = Ptr + 1; - Address++; - Len--; - } - - if ((Address & 2) && (Len >= 2)) - { - PciReadConfigUshort(BusNumber, - SlotNumber, - Address, - Ptr); - Ptr = Ptr + 2; - Address += 2; - Len -= 2; - } - - while (Len >= 4) - { - PciReadConfigUlong(BusNumber, - SlotNumber, - Address, - Ptr); - Ptr = Ptr + 4; - Address += 4; - Len -= 4; - } - - if (Len >= 2) - { - PciReadConfigUshort(BusNumber, - SlotNumber, - Address, - Ptr); - Ptr = Ptr + 2; - Address += 2; - Len -= 2; - } - - if (Len >= 1) - { - PciReadConfigUchar(BusNumber, - SlotNumber, - Address, - Ptr); - Ptr = Ptr + 1; - Address++; - Len--; - } - - return Length - Len; -} - - -ULONG -PciSetBusData(ULONG BusNumber, - ULONG SlotNumber, - PVOID Buffer, - ULONG Offset, - ULONG Length) -{ - PVOID Ptr = Buffer; - ULONG Address = Offset; - ULONG Len = Length; - ULONG Vendor; - UCHAR HeaderType; - -#if 0 - DPRINT(" BusNumber %lu\n", BusNumber); - DPRINT(" SlotNumber %lu\n", SlotNumber); - DPRINT(" Offset 0x%lx\n", Offset); - DPRINT(" Length 0x%lx\n", Length); -#endif - - if ((Length == 0) || (PciBusConfigType == 0)) - return 0; - - /* 0E=PCI_HEADER_TYPE */ - PciReadConfigUchar(BusNumber, - SlotNumber & 0xF8, - 0x0E, - &HeaderType); - if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0)) - return 0; - - PciReadConfigUlong(BusNumber, - SlotNumber, - 0x00, - &Vendor); - /* some broken boards return 0 if a slot is empty: */ - if (Vendor == 0xFFFFFFFF || Vendor == 0) - return 0; - - if ((Address & 1) && (Len >= 1)) - { - PciWriteConfigUchar(BusNumber, - SlotNumber, - Address, - *(PUCHAR)Ptr); - Ptr = Ptr + 1; - Address++; - Len--; - } - - if ((Address & 2) && (Len >= 2)) - { - PciWriteConfigUshort(BusNumber, - SlotNumber, - Address, - *(PUSHORT)Ptr); - Ptr = Ptr + 2; - Address += 2; - Len -= 2; - } - - while (Len >= 4) - { - PciWriteConfigUlong(BusNumber, - SlotNumber, - Address, - *(PULONG)Ptr); - Ptr = Ptr + 4; - Address += 4; - Len -= 4; - } - - if (Len >= 2) - { - PciWriteConfigUshort(BusNumber, - SlotNumber, - Address, - *(PUSHORT)Ptr); - Ptr = Ptr + 2; - Address += 2; - Len -= 2; - } - - if (Len >= 1) - { - PciWriteConfigUchar(BusNumber, - SlotNumber, - Address, - *(PUCHAR)Ptr); - Ptr = Ptr + 1; - Address++; - Len--; - } - - return Length - Len; -} - - -PCI_BUS_TYPE -PciGetBusConfigType(VOID) -{ - ULONG Value; - - DPRINT("Called\n"); - - DPRINT("Checking configuration type 1:\n"); - WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01); - Value = READ_PORT_ULONG((PULONG)0xCF8); - WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000); - if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000) - { - WRITE_PORT_ULONG((PULONG)0xCF8, Value); - DPRINT(" Success!\n"); - return pbtType1; - } - WRITE_PORT_ULONG((PULONG)0xCF8, Value); - DPRINT(" Unsuccessful!\n"); - - DPRINT("Checking configuration type 2:\n"); - WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00); - WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00); - WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00); - if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 && - READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00) - { - DPRINT(" Success!\n"); - return pbtType2; - } - DPRINT(" Unsuccessful!\n"); - - DPRINT("No pci bus found!\n"); - return pbtUnknown; -} - - NTSTATUS STDCALL PciDispatchDeviceControl( diff --git a/reactos/drivers/bus/pci/pci.h b/reactos/drivers/bus/pci/pci.h index e8d5b36083e..c447a042300 100644 --- a/reactos/drivers/bus/pci/pci.h +++ b/reactos/drivers/bus/pci/pci.h @@ -1,11 +1,8 @@ -/* $Id: pci.h,v 1.3 2003/11/14 17:13:24 weiden Exp $ */ +/* $Id: pci.h,v 1.4 2003/12/12 21:54:42 ekohl Exp $ */ #ifndef __PCI_H #define __PCI_H -#include -#include - typedef enum { pbtUnknown = 0, @@ -20,6 +17,8 @@ typedef struct _PCI_DEVICE LIST_ENTRY ListEntry; // Physical Device Object of device PDEVICE_OBJECT Pdo; + /* PCI Slot number */ + PCI_SLOT_NUMBER SlotNumber; // PCI configuration data PCI_COMMON_CONFIG PciConfig; // Flag used during enumeration to locate removed devices @@ -103,21 +102,9 @@ FdoPowerControl( /* pci.c */ -extern PCI_BUS_TYPE PciBusConfigType; - -PCI_BUS_TYPE -PciGetBusConfigType(VOID); - -ULONG -PciGetBusData(ULONG BusNumber, - ULONG SlotNumber, - PVOID Buffer, - ULONG Offset, - ULONG Length); - BOOLEAN PciCreateUnicodeString( - PUNICODE_STRING Destination, + PUNICODE_STRING Destination, PWSTR Source, POOL_TYPE PoolType); diff --git a/reactos/drivers/bus/pci/pcidef.h b/reactos/drivers/bus/pci/pcidef.h index dcce92698e0..310fd2c84f7 100644 --- a/reactos/drivers/bus/pci/pcidef.h +++ b/reactos/drivers/bus/pci/pcidef.h @@ -1,5 +1,5 @@ /* - * $Id: pcidef.h,v 1.2 2001/11/01 23:17:10 ekohl Exp $ + * $Id: pcidef.h,v 1.3 2003/12/12 21:54:42 ekohl Exp $ * * PCI defines and function prototypes * Copyright 1994, Drew Eckhardt @@ -298,18 +298,7 @@ #define PCI_ROM_RESOURCE 6 #define PCI_BRIDGE_RESOURCES 7 #define PCI_NUM_RESOURCES 11 - + #define PCI_REGION_FLAG_MASK 0x0f /* These bits of resource flags tell us the PCI region flags */ - - -#define CONFIG_CMD(bus, device_fn, where) \ - (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3)) - -#define IOADDR(devfn, where) \ - ((0xC000 | ((devfn & 0x78) << 5)) + where) - -#define FUNC(devfn) \ - (((devfn & 7) << 1) | 0xf0) - #endif /* _PCIDEF_H */ diff --git a/reactos/drivers/bus/pci/pdo.c b/reactos/drivers/bus/pci/pdo.c index 560a58a4ac2..bbe68e7a54e 100644 --- a/reactos/drivers/bus/pci/pdo.c +++ b/reactos/drivers/bus/pci/pdo.c @@ -1,4 +1,4 @@ -/* $Id: pdo.c,v 1.1 2001/09/16 13:18:24 chorns Exp $ +/* $Id: pdo.c,v 1.2 2003/12/12 21:54:42 ekohl Exp $ * * PROJECT: ReactOS PCI bus driver * FILE: pdo.c @@ -7,7 +7,11 @@ * UPDATE HISTORY: * 10-09-2001 CSH Created */ -#include + +#include + +#include "pcidef.h" +#include "pci.h" #define NDEBUG #include