You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
4.9 KiB
213 lines
4.9 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997 - 1999
|
|
//
|
|
// File: sync.c
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pciidex.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, PciIdeCreateSyncChildAccess)
|
|
#pragma alloc_text(PAGE, PciIdeDeleteSyncChildAccess)
|
|
#pragma alloc_text(PAGE, PciIdeQuerySyncAccessInterface)
|
|
#pragma alloc_text(PAGE, PciIdeSyncAccessRequired)
|
|
|
|
#pragma alloc_text(NONPAGE, PciIdeAllocateAccessToken)
|
|
#pragma alloc_text(NONPAGE, PciIdeFreeAccessToken)
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
|
|
//
|
|
// Must match mshdc.inf
|
|
//
|
|
static PWCHAR SyncAccess = L"SyncAccess";
|
|
|
|
NTSTATUS
|
|
PciIdeCreateSyncChildAccess (
|
|
PCTRLFDO_EXTENSION FdoExtension
|
|
)
|
|
{
|
|
BOOLEAN syncAccessNeeded;
|
|
|
|
PAGED_CODE();
|
|
|
|
syncAccessNeeded = FALSE;
|
|
|
|
if (FdoExtension->TranslatedBusMasterBaseAddress) {
|
|
|
|
UCHAR bmRawStatus;
|
|
|
|
bmRawStatus = READ_PORT_UCHAR (&FdoExtension->TranslatedBusMasterBaseAddress->Status);
|
|
|
|
if (bmRawStatus & BUSMASTER_DMA_SIMPLEX_BIT) {
|
|
|
|
syncAccessNeeded = TRUE;
|
|
}
|
|
}
|
|
|
|
if (syncAccessNeeded == FALSE) {
|
|
|
|
syncAccessNeeded = PciIdeSyncAccessRequired (
|
|
FdoExtension
|
|
);
|
|
}
|
|
|
|
if (syncAccessNeeded) {
|
|
|
|
DebugPrint ((1, "PCIIDEX: Serialize access to both channels\n"));
|
|
|
|
FdoExtension->ControllerObject = IoCreateController (0);
|
|
|
|
ASSERT (FdoExtension->ControllerObject);
|
|
|
|
if (FdoExtension->ControllerObject) {
|
|
|
|
return STATUS_SUCCESS;
|
|
} else {
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
} // PciIdeCreateSyncChildAccess
|
|
|
|
VOID
|
|
PciIdeDeleteSyncChildAccess (
|
|
PCTRLFDO_EXTENSION FdoExtension
|
|
)
|
|
{
|
|
PAGED_CODE();
|
|
|
|
if (FdoExtension->ControllerObject) {
|
|
|
|
IoDeleteController (FdoExtension->ControllerObject);
|
|
|
|
FdoExtension->ControllerObject = NULL;
|
|
}
|
|
return;
|
|
} // PciIdeDeleteSyncChildAccess
|
|
|
|
NTSTATUS
|
|
PciIdeQuerySyncAccessInterface (
|
|
PCHANPDO_EXTENSION PdoExtension,
|
|
PPCIIDE_SYNC_ACCESS_INTERFACE SyncAccessInterface
|
|
)
|
|
{
|
|
PAGED_CODE();
|
|
|
|
if (SyncAccessInterface == NULL) {
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
if (!PdoExtension->ParentDeviceExtension->ControllerObject) {
|
|
|
|
SyncAccessInterface->AllocateAccessToken = NULL;
|
|
SyncAccessInterface->FreeAccessToken = NULL;
|
|
SyncAccessInterface->Token = NULL;
|
|
|
|
} else {
|
|
|
|
SyncAccessInterface->AllocateAccessToken = PciIdeAllocateAccessToken;
|
|
SyncAccessInterface->FreeAccessToken = PciIdeFreeAccessToken;
|
|
SyncAccessInterface->Token = PdoExtension;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
} // PciIdeQuerySyncAccessInterface
|
|
|
|
|
|
static ULONG tokenAccessCount=0;
|
|
|
|
//
|
|
// IRQL must be DISPATCH_LEVEL;
|
|
//
|
|
NTSTATUS
|
|
PciIdeAllocateAccessToken (
|
|
PVOID Token,
|
|
PDRIVER_CONTROL Callback,
|
|
PVOID CallbackContext
|
|
)
|
|
{
|
|
PCHANPDO_EXTENSION pdoExtension = Token;
|
|
PCTRLFDO_EXTENSION FdoExtension;
|
|
|
|
ASSERT (Token);
|
|
ASSERT (KeGetCurrentIrql() == DISPATCH_LEVEL);
|
|
|
|
FdoExtension = pdoExtension->ParentDeviceExtension;
|
|
|
|
tokenAccessCount++;
|
|
|
|
IoAllocateController (
|
|
FdoExtension->ControllerObject,
|
|
FdoExtension->DeviceObject,
|
|
Callback,
|
|
CallbackContext
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
} // PciIdeAllocateAccessToken
|
|
|
|
NTSTATUS
|
|
PciIdeFreeAccessToken (
|
|
PVOID Token
|
|
)
|
|
{
|
|
PCHANPDO_EXTENSION pdoExtension = Token;
|
|
PCTRLFDO_EXTENSION FdoExtension;
|
|
|
|
FdoExtension = pdoExtension->ParentDeviceExtension;
|
|
|
|
tokenAccessCount--;
|
|
|
|
IoFreeController (
|
|
FdoExtension->ControllerObject
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
} // PciIdeFreeAccessToken
|
|
|
|
|
|
BOOLEAN
|
|
PciIdeSyncAccessRequired (
|
|
IN PCTRLFDO_EXTENSION FdoExtension
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
ULONG syncAccess;
|
|
|
|
PAGED_CODE();
|
|
|
|
syncAccess = 0;
|
|
status = PciIdeXGetDeviceParameter (
|
|
FdoExtension->AttacheePdo,
|
|
SyncAccess,
|
|
&syncAccess
|
|
);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
return (syncAccess != 0);
|
|
|
|
} else {
|
|
|
|
DebugPrint ((1, "PciIdeX: Unable to get SyncAccess flag from the registry\n"));
|
|
}
|
|
|
|
if (FdoExtension->ControllerProperties.PciIdeSyncAccessRequired) {
|
|
|
|
return FdoExtension->ControllerProperties.PciIdeSyncAccessRequired (
|
|
FdoExtension->VendorSpecificDeviceEntension
|
|
);
|
|
}
|
|
|
|
DebugPrint ((1, "PciIdeX: assume sync access not required\n"));
|
|
return FALSE;
|
|
} // PciIdeSyncAccessRequired
|
|
|