Leaked source code of windows server 2003
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.
 
 
 
 
 
 

443 lines
12 KiB

/*++
Copyright (C) Microsoft Corporation, 1999 - 1999
Module Name:
init.c
Abstract:
Generic PCI IDE mini driver
Revision History:
--*/
#include "pciide.h"
//
// Driver Entry Point
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
//
// call system pci ide driver (pciidex)
// for initializeation
//
return PciIdeXInitialize (
DriverObject,
RegistryPath,
GenericIdeGetControllerProperties,
sizeof (DEVICE_EXTENSION)
);
}
//
// Called on every I/O. Returns 1 if DMA is allowed.
// Returns 0 if DMA is not allowed.
//
ULONG
GenericIdeUseDma(
IN PVOID DeviceExtension,
IN PVOID cdbcmd,
IN UCHAR slave)
/**++
* Arguments : DeviceExtension
Cdb
Slave =1, if slave
=0, if master
--**/
{
PDEVICE_EXTENSION deviceExtension = DeviceExtension;
PUCHAR cdb= cdbcmd;
return 1;
}
//
// Query controller properties
//
NTSTATUS
GenericIdeGetControllerProperties (
IN PVOID DeviceExtension,
IN PIDE_CONTROLLER_PROPERTIES ControllerProperties
)
{
PDEVICE_EXTENSION deviceExtension = DeviceExtension;
NTSTATUS status;
ULONG i;
ULONG j;
ULONG xferMode;
//
// make sure we are in sync
//
if (ControllerProperties->Size != sizeof (IDE_CONTROLLER_PROPERTIES)) {
return STATUS_REVISION_MISMATCH;
}
//
// see what kind of PCI IDE controller we have
//
status = PciIdeXGetBusData (
deviceExtension,
&deviceExtension->pciConfigData,
0,
sizeof (PCIIDE_CONFIG_HEADER)
);
if (!NT_SUCCESS(status)) {
return status;
}
//
// assume we support all DMA mode if PCI master bit is set
//
xferMode = PIO_SUPPORT;
if ((deviceExtension->pciConfigData.MasterIde) &&
(deviceExtension->pciConfigData.Command.b.MasterEnable)) {
xferMode |= SWDMA_SUPPORT | MWDMA_SUPPORT | UDMA_SUPPORT;
}
// @@BEGIN_DDKSPLIT
//
// Run PIO by default for the Sis Chipset
//
if ((deviceExtension->pciConfigData.VendorID == 0x1039) &&
(deviceExtension->pciConfigData.DeviceID == 0x5513)) {
ControllerProperties->DefaultPIO = 1;
}
//
// Run PIO by default for the Rcc Chipset
//
if ((deviceExtension->pciConfigData.VendorID == 0x1166) &&
(deviceExtension->pciConfigData.DeviceID == 0x0211)) {
ControllerProperties->DefaultPIO = 1;
}
//
// continuous status register polling causes some ALI
// controller to corrupt data if the controller internal
// FIFO is enabled
//
// to play safe, we will always disable the FIFO
// see the ALi IDE controller programming spec for details
//
if ((deviceExtension->pciConfigData.VendorID == 0x10b9) &&
(deviceExtension->pciConfigData.DeviceID == 0x5229)) {
USHORT pciData;
USHORT pciDataMask;
pciData = 0;
pciDataMask = 0xcccc;
status = PciIdeXSetBusData(
DeviceExtension,
&pciData,
&pciDataMask,
0x54,
0x2);
if (!NT_SUCCESS(status)) {
return status;
}
}
//
// ALi IDE controllers have lots of busmaster problems
// some versions of them can't do busmaster with ATAPI devices
// and some other versions of them return bogus busmaster status values
// (the busmaster active bit doesn't get cleared when it should be
// during an end of busmaster interrupt)
//
if ((deviceExtension->pciConfigData.VendorID == 0x10b9) &&
(deviceExtension->pciConfigData.DeviceID == 0x5229) &&
((deviceExtension->pciConfigData.RevisionID == 0x20) ||
(deviceExtension->pciConfigData.RevisionID == 0xc1))) {
PciIdeXDebugPrint ((0, "pciide: overcome the sticky BM active bit problem in ALi controller\n"));
ControllerProperties->IgnoreActiveBitForAtaDevice = TRUE;
}
if ((deviceExtension->pciConfigData.VendorID == 0x0e11) &&
(deviceExtension->pciConfigData.DeviceID == 0xae33) &&
(deviceExtension->pciConfigData.Chan0OpMode ||
deviceExtension->pciConfigData.Chan1OpMode)) {
PciIdeXDebugPrint ((0, "pciide: overcome the bogus busmaster interrupt in CPQ controller\n"));
ControllerProperties->AlwaysClearBusMasterInterrupt = TRUE;
}
// @@END_DDKSPLIT
//
// fill in the controller properties
//
for (i=0; i< MAX_IDE_CHANNEL; i++) {
for (j=0; j< MAX_IDE_DEVICE; j++) {
ControllerProperties->SupportedTransferMode[i][j] =
deviceExtension->SupportedTransferMode[i][j] = xferMode;
}
}
ControllerProperties->PciIdeChannelEnabled = GenericIdeChannelEnabled;
ControllerProperties->PciIdeSyncAccessRequired = GenericIdeSyncAccessRequired;
ControllerProperties->PciIdeTransferModeSelect = NULL;
ControllerProperties->PciIdeUdmaModesSupported = GenericIdeUdmaModesSupported;
ControllerProperties->PciIdeUseDma = GenericIdeUseDma;
ControllerProperties->AlignmentRequirement=1;
return STATUS_SUCCESS;
}
IDE_CHANNEL_STATE
GenericIdeChannelEnabled (
IN PDEVICE_EXTENSION DeviceExtension,
IN ULONG Channel
)
{
// @@BEGIN_DDKSPLIT
NTSTATUS status;
PCI_COMMON_CONFIG pciHeader;
ULONG pciDataByte;
UCHAR maskByte = 0;
status = PciIdeXGetBusData (
DeviceExtension,
&pciHeader,
0,
sizeof (pciHeader)
);
if (NT_SUCCESS(status)) {
if ((pciHeader.VendorID == 0x0e11) &&
(pciHeader.DeviceID == 0xae33)) {
//
// Compaq
//
status = PciIdeXGetBusData (
DeviceExtension,
&pciDataByte,
0x80,
sizeof (pciDataByte)
);
if (NT_SUCCESS(status)) {
if (pciDataByte & (1 << Channel)) {
return ChannelEnabled;
} else {
return ChannelDisabled;
}
}
} else if ((pciHeader.VendorID == 0x1095) &&
((pciHeader.DeviceID == 0x0646) || (pciHeader.DeviceID == 0x0643))) {
//
// CMD
//
status = PciIdeXGetBusData (
DeviceExtension,
&pciDataByte,
0x51,
sizeof (pciDataByte)
);
if (NT_SUCCESS(status)) {
if (pciHeader.RevisionID < 0x3) {
//
// early revision doesn't have a
// bit to enable/disable primary
// channel since it is always enabled
// newer version does have a bit defined
// for this purpose. to make the check
// easier later. we will set primary enable bit
// for the early revision
pciDataByte |= 0x4;
}
if (Channel == 0) {
maskByte = 0x4;
} else {
maskByte = 0x8;
}
if (pciDataByte & maskByte) {
return ChannelEnabled;
} else {
return ChannelDisabled;
}
}
} else if ((pciHeader.VendorID == 0x1039) &&
(pciHeader.DeviceID == 0x5513)) {
//
// SiS
//
status = PciIdeXGetBusData (
DeviceExtension,
&pciDataByte,
0x4a,
sizeof (pciDataByte)
);
if (Channel == 0) {
maskByte = 0x2;
} else {
maskByte = 0x4;
}
if (pciDataByte & maskByte) {
return ChannelEnabled;
} else {
return ChannelDisabled;
}
} else if ((pciHeader.VendorID == 0x110A) &&
(pciHeader.DeviceID == 0x0002)) {
//
// Siemens
//
ULONG configOffset = (Channel == 0)?0x41:0x49;
status = PciIdeXGetBusData (
DeviceExtension,
&pciDataByte,
configOffset,
sizeof (pciDataByte)
);
if (NT_SUCCESS(status)) {
maskByte = 0x08;
if (pciDataByte & maskByte) {
return ChannelEnabled;
} else {
return ChannelDisabled;
}
}
} else if ((pciHeader.VendorID == 0x1106) &&
(pciHeader.DeviceID == 0x0571)) {
//
// VIA
//
status = PciIdeXGetBusData (
DeviceExtension,
&pciDataByte,
0x40,
sizeof (pciDataByte)
);
if (NT_SUCCESS(status)) {
maskByte = (Channel == 0)? 0x02:0x01;
if (pciDataByte & maskByte) {
return ChannelEnabled;
} else {
return ChannelDisabled;
}
}
}
}
// @@END_DDKSPLIT
//
// Can't tell if a channel is enabled or not.
//
return ChannelStateUnknown;
}
// @@BEGIN_DDKSPLIT
VENDOR_ID_DEVICE_ID SingleFifoController[] = {
{0x1095, 0x0640}, // CMD 640
{0x1039, 0x0601} // SiS ????
};
#define NUMBER_OF_SINGLE_FIFO_CONTROLLER (sizeof(SingleFifoController) / sizeof(VENDOR_ID_DEVICE_ID))
// @@END_DDKSPLIT
BOOLEAN
GenericIdeSyncAccessRequired (
IN PDEVICE_EXTENSION DeviceExtension
)
{
ULONG i;
// @@BEGIN_DDKSPLIT
for (i=0; i<NUMBER_OF_SINGLE_FIFO_CONTROLLER; i++) {
if ((DeviceExtension->pciConfigData.VendorID == SingleFifoController[i].VendorId) &&
(DeviceExtension->pciConfigData.DeviceID == SingleFifoController[i].DeviceId)) {
return TRUE;
}
}
// @@END_DDKSPLIT
return FALSE;
}
NTSTATUS
GenericIdeUdmaModesSupported (
IN IDENTIFY_DATA IdentifyData,
IN OUT PULONG BestXferMode,
IN OUT PULONG CurrentMode
)
{
ULONG bestXferMode =0;
ULONG currentMode = 0;
if (IdentifyData.TranslationFieldsValid & (1 << 2)) {
if (IdentifyData.UltraDMASupport) {
GetHighestTransferMode( IdentifyData.UltraDMASupport,
bestXferMode);
*BestXferMode = bestXferMode;
}
if (IdentifyData.UltraDMAActive) {
GetHighestTransferMode( IdentifyData.UltraDMAActive,
currentMode);
*CurrentMode = currentMode;
}
}
return STATUS_SUCCESS;
}