windows-nt/Source/XPSP1/NT/base/busdrv/pci/busintrf.c
2020-09-26 16:20:57 +08:00

406 lines
8.8 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1997-2000 Microsoft Corporation
Module Name:
busintrf.c
Abstract:
This module implements the "bus handler" interfaces supported
by the PCI driver.
Author:
Peter Johnston (peterj) 6-Jun-1997
Revision History:
--*/
#include "pcip.h"
#define BUSINTRF_VERSION 1
//
// Prototypes for routines exposed only thru the "interface"
// mechanism.
//
NTSTATUS
busintrf_Constructor(
PVOID DeviceExtension,
PVOID PciInterface,
PVOID InterfaceSpecificData,
USHORT Version,
USHORT Size,
PINTERFACE InterfaceReturn
);
VOID
busintrf_Reference(
IN PVOID Context
);
VOID
busintrf_Dereference(
IN PVOID Context
);
NTSTATUS
busintrf_Initializer(
IN PPCI_ARBITER_INSTANCE Instance
);
BOOLEAN
PciPnpTranslateBusAddress(
IN PVOID Context,
IN PHYSICAL_ADDRESS BusAddress,
IN ULONG Length,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress
);
struct _DMA_ADAPTER *
PciPnpGetDmaAdapter(
IN PVOID Context,
IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
OUT PULONG NumberOfMapRegisters
);
ULONG
PciPnpReadConfig(
IN PVOID Context,
IN ULONG WhichSpace,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
);
ULONG
PciPnpWriteConfig(
IN PVOID Context,
IN ULONG WhichSpace,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
);
//
// Define the Bus Interface "Interface" structure.
//
PCI_INTERFACE BusHandlerInterface = {
&GUID_BUS_INTERFACE_STANDARD, // InterfaceType
sizeof(BUS_INTERFACE_STANDARD), // MinSize
BUSINTRF_VERSION, // MinVersion
BUSINTRF_VERSION, // MaxVersion
PCIIF_PDO, // Flags
0, // ReferenceCount
PciInterface_BusHandler, // Signature
busintrf_Constructor, // Constructor
busintrf_Initializer // Instance Initializer
};
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, busintrf_Constructor)
#pragma alloc_text(PAGE, busintrf_Dereference)
#pragma alloc_text(PAGE, busintrf_Initializer)
#pragma alloc_text(PAGE, busintrf_Reference)
#pragma alloc_text(PAGE, PciPnpTranslateBusAddress)
#pragma alloc_text(PAGE, PciPnpGetDmaAdapter)
#endif
VOID
busintrf_Reference(
IN PVOID Context
)
{
PPCI_PDO_EXTENSION pdoExtension = (PPCI_PDO_EXTENSION)Context;
ASSERT_PCI_PDO_EXTENSION(pdoExtension);
InterlockedIncrement(&pdoExtension->BusInterfaceReferenceCount);
}
VOID
busintrf_Dereference(
IN PVOID Context
)
{
PPCI_PDO_EXTENSION pdoExtension = (PPCI_PDO_EXTENSION)Context;
ASSERT_PCI_PDO_EXTENSION(pdoExtension);
InterlockedDecrement(&pdoExtension->BusInterfaceReferenceCount);
}
NTSTATUS
busintrf_Constructor(
PVOID DeviceExtension,
PVOID PciInterface,
PVOID InterfaceSpecificData,
USHORT Version,
USHORT Size,
PINTERFACE InterfaceReturn
)
/*++
Routine Description:
Initialize the BUS_INTERFACE_STANDARD fields.
Arguments:
PciInterface Pointer to the PciInterface record for this
interface type.
InterfaceSpecificData
A ULONG containing the resource type for which
arbitration is required.
InterfaceReturn
Return Value:
TRUE is this device is not known to cause problems, FALSE
if the device should be skipped altogether.
--*/
{
PBUS_INTERFACE_STANDARD standard = (PBUS_INTERFACE_STANDARD)InterfaceReturn;
standard->Size = sizeof( BUS_INTERFACE_STANDARD );
standard->Version = BUSINTRF_VERSION;
standard->Context = DeviceExtension;
standard->InterfaceReference = busintrf_Reference;
standard->InterfaceDereference = busintrf_Dereference;
standard->TranslateBusAddress = PciPnpTranslateBusAddress;
standard->GetDmaAdapter = PciPnpGetDmaAdapter;
standard->SetBusData = PciPnpWriteConfig;
standard->GetBusData = PciPnpReadConfig;
return STATUS_SUCCESS;
}
NTSTATUS
busintrf_Initializer(
IN PPCI_ARBITER_INSTANCE Instance
)
/*++
Routine Description:
For bus interface, does nothing, shouldn't actually be called.
Arguments:
Instance Pointer to the PDO extension.
Return Value:
Returns the status of this operation.
--*/
{
ASSERTMSG("PCI busintrf_Initializer, unexpected call.", 0);
return STATUS_UNSUCCESSFUL;
}
BOOLEAN
PciPnpTranslateBusAddress(
IN PVOID Context,
IN PHYSICAL_ADDRESS BusAddress,
IN ULONG Length,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress
)
/*++
Routine Description:
This function is used to translate bus addresses from legacy drivers.
Arguments:
Context - Supplies a pointer to the interface context. This is actually
the PDO for the root bus.
BusAddress - Supplies the orginal address to be translated.
Length - Supplies the length of the range to be translated.
AddressSpace - Points to the location of of the address space type such as
memory or I/O port. This value is updated by the translation.
TranslatedAddress - Returns the translated address.
Return Value:
Returns a boolean indicating if the operations was a success.
--*/
{
PPCI_PDO_EXTENSION pdoExtension = (PPCI_PDO_EXTENSION)Context;
PPCI_FDO_EXTENSION fdoExtension;
PAGED_CODE();
ASSERT_PCI_PDO_EXTENSION(pdoExtension);
return HalTranslateBusAddress(PCIBus,
PCI_PARENT_FDOX(pdoExtension)->BaseBus,
BusAddress,
AddressSpace,
TranslatedAddress);
}
ULONG
PciPnpReadConfig(
IN PVOID Context,
IN ULONG WhichSpace,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
)
/*++
Routine Description:
This function reads the PCI configuration space.
Arguments:
Context - Supplies a pointer to the interface context. This is actually
the PDO for the root bus.
Buffer - Supplies a pointer to where the data should be placed.
Offset - Indicates the offset into the data where the reading should begin.
Length - Indicates the count of bytes which should be read.
Return Value:
Returns the number of bytes read.
--*/
{
PPCI_PDO_EXTENSION pdoExtension = (PPCI_PDO_EXTENSION)Context;
ULONG lengthRead;
ASSERT_PCI_PDO_EXTENSION(pdoExtension);
PciReadDeviceSpace(pdoExtension,
WhichSpace,
Buffer,
Offset,
Length,
&lengthRead
);
return lengthRead;
}
ULONG
PciPnpWriteConfig(
IN PVOID Context,
IN ULONG WhichSpace,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
)
/*++
Routine Description:
This function writes the PCI configuration space.
Arguments:
Context - Supplies a pointer to the interface context. This is actually
the PDO for the root bus.
Buffer - Supplies a pointer to where the data to be written is.
Offset - Indicates the offset into the data where the writing should begin.
Length - Indicates the count of bytes which should be written.
Return Value:
Returns the number of bytes read.
--*/
{
PPCI_PDO_EXTENSION pdoExtension = (PPCI_PDO_EXTENSION)Context;
ULONG lengthWritten;
ASSERT_PCI_PDO_EXTENSION(pdoExtension);
PciWriteDeviceSpace(pdoExtension,
WhichSpace,
Buffer,
Offset,
Length,
&lengthWritten
);
return lengthWritten;
}
PDMA_ADAPTER
PciPnpGetDmaAdapter(
IN PVOID Context,
IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
OUT PULONG NumberOfMapRegisters
)
/*++
Routine Description:
This function writes the PCI configuration space.
Arguments:
Context - Supplies a pointer to the interface context. This is actually
the PDO for the root bus.
DeviceDescriptor - Supplies the device descriptor used to allocate the dma
adapter object.
NubmerOfMapRegisters - Returns the maximum number of map registers a device
can allocate at one time.
Return Value:
Returns a DMA adapter or NULL.
--*/
{
PPCI_PDO_EXTENSION pdoExtension = (PPCI_PDO_EXTENSION)Context;
PAGED_CODE();
ASSERT_PCI_PDO_EXTENSION(pdoExtension);
//
// If this is DMA on a PCI bus update the bus number, otherwise leave well
// alone
//
if (DeviceDescriptor->InterfaceType == PCIBus) {
DeviceDescriptor->BusNumber = PCI_PARENT_FDOX(pdoExtension)->BaseBus;
}
return IoGetDmaAdapter(
pdoExtension->ParentFdoExtension->PhysicalDeviceObject,
DeviceDescriptor,
NumberOfMapRegisters);
}