406 lines
8.8 KiB
C
406 lines
8.8 KiB
C
|
/*++
|
|||
|
|
|||
|
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);
|
|||
|
}
|