mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 22:55:05 +00:00
- 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
This commit is contained in:
parent
0dc6bcee53
commit
6010d1fd63
|
@ -1,459 +1,491 @@
|
||||||
/* $Id: fdo.c,v 1.4 2003/11/24 16:15:00 gvg Exp $
|
/* $Id: fdo.c,v 1.5 2003/12/12 21:54:42 ekohl Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS PCI bus driver
|
* PROJECT: ReactOS PCI bus driver
|
||||||
* FILE: fdo.c
|
* FILE: fdo.c
|
||||||
* PURPOSE: PCI device object dispatch routines
|
* PURPOSE: PCI device object dispatch routines
|
||||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* 10-09-2001 CSH Created
|
* 10-09-2001 CSH Created
|
||||||
*/
|
*/
|
||||||
#include <pci.h>
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
#define NDEBUG
|
|
||||||
#include <debug.h>
|
#include "pcidef.h"
|
||||||
|
#include "pci.h"
|
||||||
/*** PRIVATE *****************************************************************/
|
|
||||||
|
#define NDEBUG
|
||||||
NTSTATUS
|
#include <debug.h>
|
||||||
FdoLocateChildDevice(
|
|
||||||
PPCI_DEVICE *Device,
|
/*** PRIVATE *****************************************************************/
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension,
|
|
||||||
PPCI_COMMON_CONFIG PciConfig)
|
static NTSTATUS
|
||||||
{
|
FdoLocateChildDevice(
|
||||||
PLIST_ENTRY CurrentEntry;
|
PPCI_DEVICE *Device,
|
||||||
PPCI_DEVICE CurrentDevice;
|
PFDO_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
PCI_SLOT_NUMBER SlotNumber,
|
||||||
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
PPCI_COMMON_CONFIG PciConfig)
|
||||||
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
|
{
|
||||||
CurrentDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PPCI_DEVICE CurrentDevice;
|
||||||
/* If both vendor ID and device ID match, it is the same device */
|
|
||||||
if ((PciConfig->VendorID == CurrentDevice->PciConfig.VendorID) &&
|
DPRINT("Called\n");
|
||||||
(PciConfig->DeviceID == CurrentDevice->PciConfig.DeviceID)) {
|
|
||||||
*Device = CurrentDevice;
|
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||||
return STATUS_SUCCESS;
|
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
|
||||||
}
|
CurrentDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
||||||
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
/* 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 = NULL;
|
(SlotNumber.u.AsULONG == CurrentDevice->SlotNumber.u.AsULONG)) {
|
||||||
return STATUS_UNSUCCESSFUL;
|
*Device = CurrentDevice;
|
||||||
}
|
DPRINT("Done\n");
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
NTSTATUS
|
|
||||||
FdoEnumerateDevices(
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
PDEVICE_OBJECT DeviceObject)
|
}
|
||||||
{
|
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
*Device = NULL;
|
||||||
PCI_COMMON_CONFIG PciConfig;
|
DPRINT("Done\n");
|
||||||
PLIST_ENTRY CurrentEntry;
|
return STATUS_UNSUCCESSFUL;
|
||||||
PPCI_DEVICE Device;
|
}
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG Slot;
|
|
||||||
ULONG Size;
|
static NTSTATUS
|
||||||
|
FdoEnumerateDevices(
|
||||||
DPRINT("Called\n");
|
PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PCI_COMMON_CONFIG PciConfig;
|
||||||
/* Mark all devices to be removed. If we don't discover them again during
|
PLIST_ENTRY CurrentEntry;
|
||||||
enumeration, assume that they have been surprise removed */
|
PPCI_DEVICE Device;
|
||||||
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
PCI_SLOT_NUMBER SlotNumber;
|
||||||
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
|
ULONG DeviceNumber;
|
||||||
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
ULONG FunctionNumber;
|
||||||
Device->RemovePending = TRUE;
|
ULONG Size;
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
NTSTATUS Status;
|
||||||
}
|
|
||||||
|
DPRINT("Called\n");
|
||||||
DeviceExtension->DeviceListCount = 0;
|
|
||||||
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
/* Enumerate devices on the PCI bus */
|
|
||||||
for (Slot = 0; Slot < 256; Slot++)
|
/* Mark all devices to be removed. If we don't discover them again during
|
||||||
{
|
enumeration, assume that they have been surprise removed */
|
||||||
Size = PciGetBusData(
|
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||||
DeviceExtension->BusNumber,
|
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
|
||||||
Slot,
|
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
||||||
&PciConfig,
|
Device->RemovePending = TRUE;
|
||||||
0,
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
sizeof(PCI_COMMON_CONFIG));
|
}
|
||||||
if (Size != 0)
|
|
||||||
{
|
DeviceExtension->DeviceListCount = 0;
|
||||||
DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n",
|
|
||||||
DeviceExtension->BusNumber,
|
/* Enumerate devices on the PCI bus */
|
||||||
Slot>>3,
|
SlotNumber.u.AsULONG = 0;
|
||||||
Slot & 0x07,
|
for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
|
||||||
PciConfig.VendorID,
|
{
|
||||||
PciConfig.DeviceID);
|
SlotNumber.u.bits.DeviceNumber = DeviceNumber;
|
||||||
|
for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
|
||||||
Status = FdoLocateChildDevice(&Device, DeviceExtension, &PciConfig);
|
{
|
||||||
if (!NT_SUCCESS(Status)) {
|
SlotNumber.u.bits.FunctionNumber = FunctionNumber;
|
||||||
Device = (PPCI_DEVICE)ExAllocatePool(PagedPool, sizeof(PCI_DEVICE));
|
|
||||||
if (!Device)
|
Size= HalGetBusData(PCIConfiguration,
|
||||||
{
|
DeviceExtension->BusNumber,
|
||||||
/* FIXME: Cleanup resources for already discovered devices */
|
SlotNumber.u.AsULONG,
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
&PciConfig,
|
||||||
}
|
sizeof(PCI_COMMON_CONFIG));
|
||||||
|
DPRINT("Size %lu\n", Size);
|
||||||
RtlZeroMemory(Device, sizeof(PCI_DEVICE));
|
if (Size < sizeof(PCI_COMMON_CONFIG))
|
||||||
|
{
|
||||||
RtlMoveMemory(&Device->PciConfig, &PciConfig, sizeof(PCI_COMMON_CONFIG));
|
if (FunctionNumber == 0)
|
||||||
|
{
|
||||||
ExInterlockedInsertTailList(
|
break;
|
||||||
&DeviceExtension->DeviceListHead,
|
}
|
||||||
&Device->ListEntry,
|
else
|
||||||
&DeviceExtension->DeviceListLock);
|
{
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
/* Don't remove this device */
|
}
|
||||||
Device->RemovePending = FALSE;
|
|
||||||
|
DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n",
|
||||||
DeviceExtension->DeviceListCount++;
|
DeviceExtension->BusNumber,
|
||||||
}
|
DeviceNumber,
|
||||||
}
|
FunctionNumber,
|
||||||
|
PciConfig.VendorID,
|
||||||
return STATUS_SUCCESS;
|
PciConfig.DeviceID);
|
||||||
}
|
|
||||||
|
Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
NTSTATUS
|
{
|
||||||
FdoQueryBusRelations(
|
Device = (PPCI_DEVICE)ExAllocatePool(PagedPool, sizeof(PCI_DEVICE));
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
if (!Device)
|
||||||
IN PIRP Irp,
|
{
|
||||||
PIO_STACK_LOCATION IrpSp)
|
/* FIXME: Cleanup resources for already discovered devices */
|
||||||
{
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
}
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
PDEVICE_RELATIONS Relations;
|
RtlZeroMemory (Device,
|
||||||
PLIST_ENTRY CurrentEntry;
|
sizeof(PCI_DEVICE));
|
||||||
PPCI_DEVICE Device;
|
|
||||||
NTSTATUS Status;
|
RtlCopyMemory (&Device->SlotNumber,
|
||||||
BOOLEAN ErrorOccurred;
|
&SlotNumber,
|
||||||
NTSTATUS ErrorStatus;
|
sizeof(PCI_SLOT_NUMBER));
|
||||||
WCHAR Buffer[MAX_PATH];
|
|
||||||
ULONG Size;
|
RtlCopyMemory (&Device->PciConfig,
|
||||||
ULONG i;
|
&PciConfig,
|
||||||
|
sizeof(PCI_COMMON_CONFIG));
|
||||||
DPRINT("Called\n");
|
|
||||||
|
ExInterlockedInsertTailList(
|
||||||
ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
|
&DeviceExtension->DeviceListHead,
|
||||||
|
&Device->ListEntry,
|
||||||
Status = STATUS_SUCCESS;
|
&DeviceExtension->DeviceListLock);
|
||||||
|
}
|
||||||
ErrorOccurred = FALSE;
|
|
||||||
|
/* Don't remove this device */
|
||||||
FdoEnumerateDevices(DeviceObject);
|
Device->RemovePending = FALSE;
|
||||||
|
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension->DeviceListCount++;
|
||||||
|
}
|
||||||
if (Irp->IoStatus.Information) {
|
}
|
||||||
/* FIXME: Another bus driver has already created a DEVICE_RELATIONS
|
|
||||||
structure so we must merge this structure with our own */
|
DPRINT("Done\n");
|
||||||
}
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
|
}
|
||||||
(DeviceExtension->DeviceListCount - 1);
|
|
||||||
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
|
|
||||||
if (!Relations)
|
static NTSTATUS
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
FdoQueryBusRelations(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
Relations->Count = DeviceExtension->DeviceListCount;
|
IN PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp)
|
||||||
i = 0;
|
{
|
||||||
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||||
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
PDEVICE_RELATIONS Relations;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
PdoDeviceExtension = NULL;
|
PPCI_DEVICE Device;
|
||||||
|
NTSTATUS Status;
|
||||||
if (!Device->Pdo) {
|
BOOLEAN ErrorOccurred;
|
||||||
/* Create a physical device object for the
|
NTSTATUS ErrorStatus;
|
||||||
device as it does not already have one */
|
WCHAR Buffer[MAX_PATH];
|
||||||
Status = IoCreateDevice(
|
ULONG Size;
|
||||||
DeviceObject->DriverObject,
|
ULONG i;
|
||||||
sizeof(PDO_DEVICE_EXTENSION),
|
|
||||||
NULL,
|
DPRINT("Called\n");
|
||||||
FILE_DEVICE_CONTROLLER,
|
|
||||||
0,
|
ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
FALSE,
|
|
||||||
&Device->Pdo);
|
Status = STATUS_SUCCESS;
|
||||||
if (!NT_SUCCESS(Status)) {
|
|
||||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
ErrorOccurred = FALSE;
|
||||||
ErrorStatus = Status;
|
|
||||||
ErrorOccurred = TRUE;
|
FdoEnumerateDevices(DeviceObject);
|
||||||
break;
|
|
||||||
}
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
if (Irp->IoStatus.Information) {
|
||||||
|
/* FIXME: Another bus driver has already created a DEVICE_RELATIONS
|
||||||
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
structure so we must merge this structure with our own */
|
||||||
|
}
|
||||||
//Device->Pdo->Flags |= DO_POWER_PAGABLE;
|
|
||||||
|
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
|
||||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
|
(DeviceExtension->DeviceListCount - 1);
|
||||||
|
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
|
||||||
RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
|
if (!Relations)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
PdoDeviceExtension->Common.IsFDO = FALSE;
|
|
||||||
|
Relations->Count = DeviceExtension->DeviceListCount;
|
||||||
PdoDeviceExtension->Common.DeviceObject = Device->Pdo;
|
|
||||||
|
i = 0;
|
||||||
PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
|
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||||
|
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
|
||||||
/* FIXME: Get device properties (Hardware IDs, etc.) */
|
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
||||||
|
|
||||||
swprintf(
|
PdoDeviceExtension = NULL;
|
||||||
Buffer,
|
|
||||||
L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
|
if (!Device->Pdo) {
|
||||||
Device->PciConfig.VendorID,
|
/* Create a physical device object for the
|
||||||
Device->PciConfig.DeviceID,
|
device as it does not already have one */
|
||||||
(Device->PciConfig.u.type0.SubSystemID << 16) +
|
Status = IoCreateDevice(
|
||||||
Device->PciConfig.u.type0.SubVendorID,
|
DeviceObject->DriverObject,
|
||||||
Device->PciConfig.RevisionID);
|
sizeof(PDO_DEVICE_EXTENSION),
|
||||||
|
NULL,
|
||||||
if (!PciCreateUnicodeString(
|
FILE_DEVICE_CONTROLLER,
|
||||||
&PdoDeviceExtension->DeviceID,
|
0,
|
||||||
Buffer,
|
FALSE,
|
||||||
PagedPool)) {
|
&Device->Pdo);
|
||||||
ErrorOccurred = TRUE;
|
if (!NT_SUCCESS(Status)) {
|
||||||
break;
|
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||||
}
|
ErrorStatus = Status;
|
||||||
|
ErrorOccurred = TRUE;
|
||||||
DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Device->RemovePending) {
|
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||||
/* Reference the physical device object. The PnP manager
|
|
||||||
will dereference it again when it is no longer needed */
|
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
ObReferenceObject(Device->Pdo);
|
|
||||||
|
//Device->Pdo->Flags |= DO_POWER_PAGABLE;
|
||||||
Relations->Objects[i] = Device->Pdo;
|
|
||||||
|
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
|
||||||
i++;
|
|
||||||
}
|
RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
|
||||||
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
PdoDeviceExtension->Common.IsFDO = FALSE;
|
||||||
}
|
|
||||||
|
PdoDeviceExtension->Common.DeviceObject = Device->Pdo;
|
||||||
if (ErrorOccurred) {
|
|
||||||
/* FIXME: Cleanup all new PDOs created in this call. Please give me SEH!!! ;-) */
|
PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
|
||||||
/* FIXME: Should IoAttachDeviceToDeviceStack() be undone? */
|
|
||||||
if (PdoDeviceExtension) {
|
/* FIXME: Get device properties (Hardware IDs, etc.) */
|
||||||
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceID);
|
|
||||||
ExFreePool(PdoDeviceExtension);
|
swprintf(
|
||||||
}
|
Buffer,
|
||||||
|
L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
|
||||||
ExFreePool(Relations);
|
Device->PciConfig.VendorID,
|
||||||
return ErrorStatus;
|
Device->PciConfig.DeviceID,
|
||||||
}
|
(Device->PciConfig.u.type0.SubSystemID << 16) +
|
||||||
|
Device->PciConfig.u.type0.SubVendorID,
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)Relations;
|
Device->PciConfig.RevisionID);
|
||||||
|
|
||||||
return Status;
|
if (!PciCreateUnicodeString(
|
||||||
}
|
&PdoDeviceExtension->DeviceID,
|
||||||
|
Buffer,
|
||||||
|
PagedPool)) {
|
||||||
NTSTATUS
|
ErrorOccurred = TRUE;
|
||||||
FdoStartDevice(
|
break;
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
}
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer);
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
}
|
||||||
|
|
||||||
DPRINT("Called\n");
|
if (!Device->RemovePending) {
|
||||||
|
/* Reference the physical device object. The PnP manager
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
will dereference it again when it is no longer needed */
|
||||||
|
ObReferenceObject(Device->Pdo);
|
||||||
assert(DeviceExtension->State == dsStopped);
|
|
||||||
|
Relations->Objects[i] = Device->Pdo;
|
||||||
InitializeListHead(&DeviceExtension->DeviceListHead);
|
|
||||||
KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
|
i++;
|
||||||
DeviceExtension->DeviceListCount = 0;
|
}
|
||||||
|
|
||||||
PciBusConfigType = PciGetBusConfigType();
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
}
|
||||||
DPRINT("Bus configuration is %d\n", PciBusConfigType);
|
|
||||||
|
if (ErrorOccurred) {
|
||||||
if (PciBusConfigType != pbtUnknown) {
|
/* FIXME: Cleanup all new PDOs created in this call. Please give me SEH!!! ;-) */
|
||||||
/* At least one PCI bus is found */
|
/* FIXME: Should IoAttachDeviceToDeviceStack() be undone? */
|
||||||
}
|
if (PdoDeviceExtension) {
|
||||||
|
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceID);
|
||||||
/* FIXME: Find a way to get this information */
|
ExFreePool(PdoDeviceExtension);
|
||||||
DeviceExtension->BusNumber = 0;
|
}
|
||||||
|
|
||||||
DeviceExtension->State = dsStarted;
|
ExFreePool(Relations);
|
||||||
|
return ErrorStatus;
|
||||||
//Irp->IoStatus.Information = 0;
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
Irp->IoStatus.Information = (ULONG_PTR)Relations;
|
||||||
}
|
|
||||||
|
DPRINT("Done\n");
|
||||||
|
|
||||||
NTSTATUS
|
return Status;
|
||||||
FdoSetPower(
|
}
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp,
|
|
||||||
PIO_STACK_LOCATION IrpSp)
|
static NTSTATUS
|
||||||
{
|
FdoStartDevice(
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
NTSTATUS Status;
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
DPRINT("Called\n");
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DPRINT("Called\n");
|
||||||
|
|
||||||
if (IrpSp->Parameters.Power.Type == DevicePowerState) {
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
/* FIXME: Set device power state for the device */
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
assert(DeviceExtension->State == dsStopped);
|
||||||
} else {
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
InitializeListHead(&DeviceExtension->DeviceListHead);
|
||||||
}
|
KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
|
||||||
|
DeviceExtension->DeviceListCount = 0;
|
||||||
return Status;
|
|
||||||
}
|
/* FIXME: Find a way to get this information */
|
||||||
|
DeviceExtension->BusNumber = 0;
|
||||||
|
|
||||||
/*** PUBLIC ******************************************************************/
|
DeviceExtension->State = dsStarted;
|
||||||
|
|
||||||
NTSTATUS
|
//Irp->IoStatus.Information = 0;
|
||||||
FdoPnpControl(
|
|
||||||
PDEVICE_OBJECT DeviceObject,
|
return STATUS_SUCCESS;
|
||||||
PIRP Irp)
|
}
|
||||||
/*
|
|
||||||
* FUNCTION: Handle Plug and Play IRPs for the PCI device object
|
|
||||||
* ARGUMENTS:
|
static NTSTATUS
|
||||||
* DeviceObject = Pointer to functional device object of the PCI driver
|
FdoSetPower(
|
||||||
* Irp = Pointer to IRP that should be handled
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
* RETURNS:
|
IN PIRP Irp,
|
||||||
* Status
|
PIO_STACK_LOCATION IrpSp)
|
||||||
*/
|
{
|
||||||
{
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
NTSTATUS Status;
|
||||||
PIO_STACK_LOCATION IrpSp;
|
|
||||||
NTSTATUS Status;
|
DPRINT("Called\n");
|
||||||
|
|
||||||
DPRINT("Called\n");
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
if (IrpSp->Parameters.Power.Type == DevicePowerState) {
|
||||||
|
/* FIXME: Set device power state for the device */
|
||||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
switch (IrpSp->MinorFunction) {
|
} else {
|
||||||
#if 0
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
}
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
break;
|
return Status;
|
||||||
|
}
|
||||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
break;
|
/*** PUBLIC ******************************************************************/
|
||||||
|
|
||||||
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
|
NTSTATUS
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
FdoPnpControl(
|
||||||
break;
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
|
/*
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
* FUNCTION: Handle Plug and Play IRPs for the PCI device object
|
||||||
break;
|
* ARGUMENTS:
|
||||||
#endif
|
* DeviceObject = Pointer to functional device object of the PCI driver
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
* Irp = Pointer to IRP that should be handled
|
||||||
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
|
* RETURNS:
|
||||||
break;
|
* Status
|
||||||
#if 0
|
*/
|
||||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
{
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
break;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
|
NTSTATUS Status;
|
||||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
DPRINT("Called\n");
|
||||||
break;
|
|
||||||
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
case IRP_MN_QUERY_STOP_DEVICE:
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
break;
|
switch (IrpSp->MinorFunction) {
|
||||||
|
#if 0
|
||||||
case IRP_MN_REMOVE_DEVICE:
|
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||||
DPRINT("IRP_MN_START_DEVICE received\n");
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
Status = FdoStartDevice(DeviceObject, Irp);
|
break;
|
||||||
break;
|
|
||||||
case IRP_MN_STOP_DEVICE:
|
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
|
||||||
/* Currently not supported */
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
break;
|
||||||
break;
|
|
||||||
#if 0
|
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
|
||||||
case IRP_MN_SURPRISE_REMOVAL:
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
break;
|
||||||
break;
|
#endif
|
||||||
#endif
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
default:
|
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
|
||||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
break;
|
||||||
|
#if 0
|
||||||
/*
|
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||||
* Do NOT complete the IRP as it will be processed by the lower
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
* device object, which will complete the IRP
|
break;
|
||||||
*/
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||||
Status = IoCallDriver(DeviceExtension->Ldo, Irp);
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
return Status;
|
break;
|
||||||
break;
|
|
||||||
}
|
case IRP_MN_QUERY_STOP_DEVICE:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
if (Status != STATUS_PENDING) {
|
|
||||||
if (Status != STATUS_NOT_IMPLEMENTED)
|
case IRP_MN_REMOVE_DEVICE:
|
||||||
Irp->IoStatus.Status = Status;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
break;
|
||||||
}
|
#endif
|
||||||
|
case IRP_MN_START_DEVICE:
|
||||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
DPRINT("IRP_MN_START_DEVICE received\n");
|
||||||
|
Status = FdoStartDevice(DeviceObject, Irp);
|
||||||
return Status;
|
break;
|
||||||
}
|
case IRP_MN_STOP_DEVICE:
|
||||||
|
/* Currently not supported */
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
NTSTATUS
|
break;
|
||||||
FdoPowerControl(
|
#if 0
|
||||||
PDEVICE_OBJECT DeviceObject,
|
case IRP_MN_SURPRISE_REMOVAL:
|
||||||
PIRP Irp)
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
/*
|
break;
|
||||||
* FUNCTION: Handle power management IRPs for the PCI device object
|
#endif
|
||||||
* ARGUMENTS:
|
default:
|
||||||
* DeviceObject = Pointer to functional device object of the PCI driver
|
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||||
* Irp = Pointer to IRP that should be handled
|
|
||||||
* RETURNS:
|
/*
|
||||||
* Status
|
* Do NOT complete the IRP as it will be processed by the lower
|
||||||
*/
|
* device object, which will complete the IRP
|
||||||
{
|
*/
|
||||||
PIO_STACK_LOCATION IrpSp;
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
NTSTATUS Status;
|
Status = IoCallDriver(DeviceExtension->Ldo, Irp);
|
||||||
|
return Status;
|
||||||
DPRINT("Called\n");
|
break;
|
||||||
|
}
|
||||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
switch (IrpSp->MinorFunction) {
|
if (Status != STATUS_PENDING) {
|
||||||
case IRP_MN_SET_POWER:
|
if (Status != STATUS_NOT_IMPLEMENTED)
|
||||||
Status = FdoSetPower(DeviceObject, Irp, IrpSp);
|
Irp->IoStatus.Status = Status;
|
||||||
break;
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
}
|
||||||
default:
|
|
||||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
break;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status != STATUS_PENDING) {
|
|
||||||
Irp->IoStatus.Status = Status;
|
NTSTATUS
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
FdoPowerControl(
|
||||||
}
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
/*
|
||||||
|
* FUNCTION: Handle power management IRPs for the PCI device object
|
||||||
return Status;
|
* ARGUMENTS:
|
||||||
}
|
* DeviceObject = Pointer to functional device object of the PCI driver
|
||||||
|
* Irp = Pointer to IRP that should be handled
|
||||||
/* EOF */
|
* 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 */
|
||||||
|
|
|
@ -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
|
* PROJECT: ReactOS PCI Bus driver
|
||||||
* FILE: pci.c
|
* FILE: pci.c
|
||||||
|
@ -7,7 +7,11 @@
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* 10-09-2001 CSH Created
|
* 10-09-2001 CSH Created
|
||||||
*/
|
*/
|
||||||
#include <pci.h>
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
#include "pcidef.h"
|
||||||
|
#include "pci.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -24,420 +28,9 @@
|
||||||
|
|
||||||
/*** PUBLIC ******************************************************************/
|
/*** PUBLIC ******************************************************************/
|
||||||
|
|
||||||
PCI_BUS_TYPE PciBusConfigType = pbtUnknown;
|
|
||||||
|
|
||||||
|
|
||||||
/*** PRIVATE *****************************************************************/
|
/*** 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
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
PciDispatchDeviceControl(
|
PciDispatchDeviceControl(
|
||||||
|
|
|
@ -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
|
#ifndef __PCI_H
|
||||||
#define __PCI_H
|
#define __PCI_H
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
|
||||||
#include <pcidef.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
pbtUnknown = 0,
|
pbtUnknown = 0,
|
||||||
|
@ -20,6 +17,8 @@ typedef struct _PCI_DEVICE
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
// Physical Device Object of device
|
// Physical Device Object of device
|
||||||
PDEVICE_OBJECT Pdo;
|
PDEVICE_OBJECT Pdo;
|
||||||
|
/* PCI Slot number */
|
||||||
|
PCI_SLOT_NUMBER SlotNumber;
|
||||||
// PCI configuration data
|
// PCI configuration data
|
||||||
PCI_COMMON_CONFIG PciConfig;
|
PCI_COMMON_CONFIG PciConfig;
|
||||||
// Flag used during enumeration to locate removed devices
|
// Flag used during enumeration to locate removed devices
|
||||||
|
@ -103,21 +102,9 @@ FdoPowerControl(
|
||||||
|
|
||||||
/* pci.c */
|
/* 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
|
BOOLEAN
|
||||||
PciCreateUnicodeString(
|
PciCreateUnicodeString(
|
||||||
PUNICODE_STRING Destination,
|
PUNICODE_STRING Destination,
|
||||||
PWSTR Source,
|
PWSTR Source,
|
||||||
POOL_TYPE PoolType);
|
POOL_TYPE PoolType);
|
||||||
|
|
||||||
|
|
|
@ -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
|
* PCI defines and function prototypes
|
||||||
* Copyright 1994, Drew Eckhardt
|
* Copyright 1994, Drew Eckhardt
|
||||||
|
@ -298,18 +298,7 @@
|
||||||
#define PCI_ROM_RESOURCE 6
|
#define PCI_ROM_RESOURCE 6
|
||||||
#define PCI_BRIDGE_RESOURCES 7
|
#define PCI_BRIDGE_RESOURCES 7
|
||||||
#define PCI_NUM_RESOURCES 11
|
#define PCI_NUM_RESOURCES 11
|
||||||
|
|
||||||
#define PCI_REGION_FLAG_MASK 0x0f /* These bits of resource flags tell us the PCI region flags */
|
#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 */
|
#endif /* _PCIDEF_H */
|
||||||
|
|
|
@ -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
|
* PROJECT: ReactOS PCI bus driver
|
||||||
* FILE: pdo.c
|
* FILE: pdo.c
|
||||||
|
@ -7,7 +7,11 @@
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* 10-09-2001 CSH Created
|
* 10-09-2001 CSH Created
|
||||||
*/
|
*/
|
||||||
#include <pci.h>
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
#include "pcidef.h"
|
||||||
|
#include "pci.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
Loading…
Reference in a new issue