Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

631 lines
17 KiB

/*****************************************************************************
Copyright (c) 1993 Media Vision Inc. All Rights Reserved
Module Name:
config.c
Abstract:
This module contains code configuration code for the initialization phase
of the MVAUDIO device driver.
Author:
EPA 03-09-93
Environment:
Kernel mode
Revision History:
*****************************************************************************/
#include "sound.h"
//
// Internal routines
//
NTSTATUS
SoundInitIoPort(
IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PPAS_CONFIG_DATA ConfigData
);
NTSTATUS
SoundPortValid(
IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PULONG Port
);
NTSTATUS
SoundInitDmaChannel(
IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PULONG DmaChannel,
IN ULONG DmaBufferSize
);
NTSTATUS
SoundDmaChannelValid(
IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PULONG DmaChannel
);
NTSTATUS
SoundInitInterrupt(
IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PULONG Interrupt
);
NTSTATUS
SoundInterruptValid(
IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PULONG Interrupt
);
VOID
SoundSetVersion(
IN PGLOBAL_DEVICE_INFO pGlobalInfo,
IN ULONG DSPVersion
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,SoundSetVersion)
#pragma alloc_text(INIT,SoundInitHardwareConfig)
#pragma alloc_text(INIT,SoundInitIoPort)
#pragma alloc_text(INIT,SoundInitDmaChannel)
#pragma alloc_text(INIT,SoundInitInterrupt)
#pragma alloc_text(INIT,SoundSaveConfig)
#pragma alloc_text(INIT,SoundReadConfiguration)
#endif
#if 0
/*****************************************************************************
NOT USED ANYMORE
Routine Description :
Sets a version DWORD into the registry as a pseudo return code
to sndblst.drv
As a side effect the key to the registry entry is closed.
Arguments :
pGlobalInfo - Our driver global info
DSPVersion - the version number we want to set
Return Value :
None
*****************************************************************************/
VOID SoundSetVersion( IN PGLOBAL_DEVICE_INFO pGlobalInfo,
IN ULONG DSPVersion )
{
/***** Local Variables *****/
UNICODE_STRING VersionString;
/***** Start *****/
RtlInitUnicodeString(&VersionString,
L"DSP Version");
if ( pGlobalInfo->RegistryPathName )
{
NTSTATUS SetStatus;
SetStatus = SoundWriteRegistryDWORD( pGlobalInfo->RegistryPathName,
L"DSP Version",
DSPVersion );
if (!NT_SUCCESS(SetStatus))
{
dprintf1(("ERROR: SoundSetVersion(): Failed to write version - status %XH", SetStatus));
}
} // End IF (pGlobalInfo->RegistryPathName)
}
#endif // 0
/*****************************************************************************
SoundInitHardwareConfig()
*****************************************************************************/
NTSTATUS SoundInitHardwareConfig( IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN PPAS_CONFIG_DATA ConfigData )
{
/***** Local Variables *****/
NTSTATUS Status;
/***** Start *****/
dprintf4(("SoundInitHardwareConfig(): Start"));
//
// Check the input source
//
if ( ConfigData->InputSource > INPUT_OUTPUT)
{
dprintf1(("ERROR: SoundInitHardwareConfig(): Invalid Input Source = %u",
ConfigData->InputSource));
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
pGDI->Hw.InputSource = (UCHAR) ConfigData->InputSource;
//
// Find the Base Port and Wake up the PAS Hardware
//
Status = SoundInitIoPort( pGDI,
ConfigData );
if (!NT_SUCCESS(Status))
{
dprintf1(("ERROR: SoundInitHardwareConfig(): SoundInitIoPort() Failed with Status = %u",
Status));
SoundWriteRegistryDWORD( pGDI->RegistryPathName,
REG_VALUENAME_DRIVER_STATUS,
ERROR_NO_HW_FOUND );
return Status;
} // End IF (!NT_SUCCESS(Status))
//
// Find interrupt
//
Status = SoundInitInterrupt( pGDI,
&ConfigData->InterruptNumber );
if (!NT_SUCCESS(Status))
{
dprintf1(("ERROR: SoundInitHardwareConfig(): SoundInitInterrupt() Failed with Status = %u",
Status));
SoundWriteRegistryDWORD( pGDI->RegistryPathName,
REG_VALUENAME_DRIVER_STATUS,
ERROR_INT_CONFLICT );
return Status;
} // End IF (!NT_SUCCESS(Status))
//
// Find DMA channel
//
Status = SoundInitDmaChannel( pGDI,
&ConfigData->DmaChannel,
ConfigData->DmaBufferSize);
if (!NT_SUCCESS(Status))
{
dprintf1(("ERROR: SoundInitHardwareConfig(): SoundInitDmaChannel() Failed with Status = %u",
Status));
SoundWriteRegistryDWORD( pGDI->RegistryPathName,
REG_VALUENAME_DRIVER_STATUS,
ERROR_DMA_CONFLICT );
return Status;
} // End IF (!NT_SUCCESS(Status))
//
// Initialize the ProAudio hardware registers
//
HwInitPAS( pGDI );
return STATUS_SUCCESS;
} // End SoundInitHardwareConfig()
/*****************************************************************************
SoundInitIoPort()
*****************************************************************************/
NTSTATUS SoundInitIoPort( IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PPAS_CONFIG_DATA ConfigData )
{
/***** Local Variables *****/
// NTSTATUS Status;
NTSTATUS PasStatus;
/***** Start *****/
//
// Find where our device is mapped
//
dprintf4(("SoundInitIoPort(): Start"));
#if 0
// Do this in FindPasHardware instead!!
pGDI->Hw.PortBase = SoundMapPortAddress( pGDI->BusType,
pGDI->BusNumber,
ConfigData->Port,
NUMBER_OF_PAS_PORTS,
&pGDI->MemType);
#else
pGDI->Hw.PortBase = (PUCHAR) &pGDI->PASInfo.ProPort;
#endif // 0
//
// Try to Locate any ProAudio Spectrums
//
PasStatus = FindPasHardware( pGDI,
ConfigData );
if ( !NT_SUCCESS(PasStatus) )
{
dprintf1(("ERROR: SoundInitIoPort(): FindPasHardware() Failed with Status = %XH",
PasStatus));
return STATUS_DEVICE_CONFIGURATION_ERROR;
} // End IF (!NT_SUCCESS(PasStatus))
pGDI->ProAudioSpectrum = TRUE;
pGDI->Hw.ThunderBoard = FALSE;
InitPasAndMixer( pGDI,
&pGDI->PASInfo,
ConfigData );
//
// Setup Min & Max values
//
pGDI->MinHz = MIN_SAMPLE_RATE;
pGDI->MaxInHz = MAX_SAMPLE_RATE;
pGDI->MaxOutHz = MAX_SAMPLE_RATE;
return STATUS_SUCCESS;
} // End SoundInitIoPort()
/*****************************************************************************
SoundInitDmaChannel()
*****************************************************************************/
NTSTATUS SoundInitDmaChannel( IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PULONG DmaChannel,
IN ULONG DmaBufferSize )
{
/***** Local Variables *****/
DEVICE_DESCRIPTION DeviceDescription; // DMA adapter object
/***** Start *****/
dprintf3(("SoundInitDmaChannel(): Start"));
dprintf4((" SoundInitDmaChannel(): DMA Channel = %u", *DmaChannel));
dprintf4((" SoundInitDmaChannel(): DMA Buffer Size = %XH", DmaBufferSize));
//
// See if we can get this channel
//
//
// Zero the device description structure.
//
RtlZeroMemory(&DeviceDescription,
sizeof(DEVICE_DESCRIPTION));
//
// Get the adapter object for this card.
//
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
DeviceDescription.AutoInitialize = TRUE;
DeviceDescription.ScatterGather = FALSE;
DeviceDescription.DmaChannel = *DmaChannel;
DeviceDescription.InterfaceType = Isa; // Must use Isa DMA
DeviceDescription.DmaSpeed = Compatible;
DeviceDescription.MaximumLength = DmaBufferSize;
DeviceDescription.BusNumber = pGDI->BusNumber;
//
// Check the DMA Channel to set the DMA width
//
if ( *DmaChannel > 4 )
{
// 16 Bit DMA
DeviceDescription.DmaWidth = Width16Bits;
}
else
{
// 8 Bit DMA
DeviceDescription.DmaWidth = Width8Bits;
}
return SoundGetCommonBuffer(&DeviceDescription, &pGDI->WaveInfo.DMABuf);
} // End SoundInitDmaChannel()
/*****************************************************************************
SoundInitInterrupt()
*****************************************************************************/
NTSTATUS SoundInitInterrupt( IN OUT PGLOBAL_DEVICE_INFO pGDI,
IN OUT PULONG Interrupt )
{
/***** Local Variables *****/
NTSTATUS Status;
/***** Start *****/
dprintf4(("SoundInitInterrupt(): Start"));
//
// See if we can get this interrupt
//
Status = SoundConnectInterrupt(*Interrupt,
pGDI->BusType,
pGDI->BusNumber,
SoundISR,
(PVOID)pGDI,
INTERRUPT_MODE,
IRQ_SHARABLE,
&pGDI->WaveInfo.Interrupt );
if (!NT_SUCCESS(Status))
{
dprintf1(("ERROR: SoundInitInterrupt(): SoundConnectInterrupt() Failed with Status = %XH",
Status));
return Status;
} // End IF (!NT_SUCCESS(Status))
return STATUS_SUCCESS;
} // End SoundInitInterrupt()
/*****************************************************************************
Routine Description :
Saves the drivers configuration information for our device
Arguments :
Registry Key values
Return Value :
NT status code - STATUS_SUCCESS if no problems
*****************************************************************************/
NTSTATUS SoundSaveConfig( IN PWSTR DeviceKey,
IN ULONG Port,
IN ULONG DmaChannel,
IN ULONG Interrupt,
IN ULONG InputSource )
{
/***** Local Variables *****/
NTSTATUS Status;
/***** Start *****/
dprintf4(("SoundSaveConfig(): Start"));
//
// Port
//
Status = SoundWriteRegistryDWORD( DeviceKey,
SOUND_REG_PORT,
Port );
if (!NT_SUCCESS(Status))
{
return Status;
}
//
// DmaChannel
//
Status = SoundWriteRegistryDWORD( DeviceKey,
SOUND_REG_DMACHANNEL,
DmaChannel );
if (!NT_SUCCESS(Status))
{
return Status;
}
//
// Interrupt
//
Status = SoundWriteRegistryDWORD( DeviceKey,
SOUND_REG_INTERRUPT,
Interrupt );
if (!NT_SUCCESS(Status))
{
return Status;
}
//
// Input Source
//
Status = SoundWriteRegistryDWORD( DeviceKey,
SOUND_REG_INPUTSOURCE,
InputSource );
if (!NT_SUCCESS(Status))
{
return Status;
}
//
// Make sure the config routine sees the data
//
return STATUS_SUCCESS;
} // End SoundSaveConfig()
/*****************************************************************************
Routine Description :
Saves the drivers Volume configuration information for our device
Arguments :
PGLOBAL_DEVICE_INFO pGDI
Return Value :
NT status code - STATUS_SUCCESS if no problems
*****************************************************************************/
VOID SoundSaveVolume( PGLOBAL_DEVICE_INFO pGDI )
{
/***** Local Variables *****/
int i;
PLOCAL_DEVICE_INFO pLDI;
/***** Start *****/
dprintf4(("SoundSaveVolume(): Start"));
//
// Write out left and right volume settings for each device
//
for (i = 0; i < NumberOfDevices; i++) {
if ( pGDI->DeviceObject[i] ) {
pLDI = (PLOCAL_DEVICE_INFO)pGDI->DeviceObject[i]->DeviceExtension;
SoundSaveDeviceVolume( pLDI, pGDI->RegistryPathName );
}
} // End FOR (i < NumberOfDevices)
} // End SoundSaveVolume()
/*****************************************************************************
Routine Description :
Return configuration information for our device
Arguments :
ConfigData - where to store the result
Return Value :
NT status code - STATUS_SUCCESS if no problems
*****************************************************************************/
NTSTATUS SoundReadConfiguration( IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext )
{
/***** Local Variables *****/
PPAS_CONFIG_DATA ConfigData;
/***** Start *****/
dprintf4(("SoundReadConfiguration(): Start"));
ConfigData = Context;
if ( ValueType == REG_DWORD )
{
// Base I/O Port
if ( _wcsicmp(ValueName, SOUND_REG_PORT) == 0 )
{
ConfigData->Port = *(PULONG)ValueData;
dprintf3((" SoundReadConfiguration(): Read Port Base = %XH",
ConfigData->Port));
}
// Interrupt
else if ( _wcsicmp(ValueName, SOUND_REG_INTERRUPT) == 0 )
{
ConfigData->InterruptNumber = *(PULONG)ValueData;
dprintf3((" SoundReadConfiguration(): Read Interrupt = %u",
ConfigData->InterruptNumber));
}
// DMA Channel
else if ( _wcsicmp(ValueName, SOUND_REG_DMACHANNEL) == 0 )
{
ConfigData->DmaChannel = *(PULONG)ValueData;
dprintf3((" SoundReadConfiguration(): Read DMA Channel = %u",
ConfigData->DmaChannel));
}
// DMA Buffer Size
else if ( _wcsicmp(ValueName, SOUND_REG_DMABUFFERSIZE ) == 0 )
{
ConfigData->DmaBufferSize = *(PULONG)ValueData;
dprintf3((" SoundReadConfiguration(): Read DMA Buffer Size = %XH",
ConfigData->DmaBufferSize));
}
// FM Clock Override
else if ( _wcsicmp(ValueName, SOUND_REG_FM_CLK_OVRID) == 0 )
{
ConfigData->FMClockOverride = *(PULONG)ValueData;
dprintf3((" SoundReadConfiguration(): Read FMClockOverride = %u",
ConfigData->FMClockOverride));
}
else if ( _wcsicmp(ValueName, SOUND_REG_ALLOWMICLINEINTOLINEOUT) == 0 )
{
ConfigData->AllowMicOrLineInToLineOut = (BOOLEAN)(*(PULONG)ValueData != 0);
dprintf3((" SoundReadConfiguration(): Read FMClockOverride = %u",
ConfigData->FMClockOverride));
}
// Input Source
else if ( _wcsicmp(ValueName, SOUND_REG_INPUTSOURCE) == 0 )
{
ConfigData->InputSource = *(PULONG)ValueData;
dprintf3((" SoundReadConfiguration() Read Input Source = %s",
ConfigData->InputSource == INPUT_LINEIN ? "Line in" :
ConfigData->InputSource == INPUT_AUX ? "Aux" :
ConfigData->InputSource == INPUT_MIC ? "Microphone" :
ConfigData->InputSource == INPUT_OUTPUT ? "Output" :
"Invalid input source" ));
}
} // End IF (ValueType == REG_DWORD)
else {
if (ValueType == REG_BINARY &&
_wcsicmp(ValueName, SOUND_MIXER_SETTINGS_NAME) == 0) {
ASSERTMSG("Mixer data wrong length!",
ValueLength == sizeof(ConfigData->MixerSettings));
dprintf3(("Mixer settings"));
RtlCopyMemory((PVOID)ConfigData->MixerSettings,
ValueData,
ValueLength);
ConfigData->MixerSettingsFound = TRUE;
}
}
return STATUS_SUCCESS;
}
/************************************ END ***********************************/