mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Added pci bus scanner to find ide controllers. Hardware reset is used when no controller was found.
svn path=/trunk/; revision=2251
This commit is contained in:
parent
c4cd9be8de
commit
dcc3b51487
1 changed files with 266 additions and 61 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: ide.c,v 1.44 2001/08/27 01:26:38 ekohl Exp $
|
/* $Id: ide.c,v 1.45 2001/09/09 21:28:05 ekohl Exp $
|
||||||
*
|
*
|
||||||
* IDE.C - IDE Disk driver
|
* IDE.C - IDE Disk driver
|
||||||
* written by Rex Jolliff
|
* written by Rex Jolliff
|
||||||
|
@ -81,6 +81,49 @@
|
||||||
|
|
||||||
// ------------------------------------------------------- File Static Data
|
// ------------------------------------------------------- File Static Data
|
||||||
|
|
||||||
|
#define PCI_TYPE0_ADDRESSES 6
|
||||||
|
#define PCI_TYPE1_ADDRESSES 2
|
||||||
|
|
||||||
|
typedef struct _PCI_COMMON_CONFIG
|
||||||
|
{
|
||||||
|
USHORT VendorID; // (ro)
|
||||||
|
USHORT DeviceID; // (ro)
|
||||||
|
USHORT Command; // Device control
|
||||||
|
USHORT Status;
|
||||||
|
UCHAR RevisionID; // (ro)
|
||||||
|
UCHAR ProgIf; // (ro)
|
||||||
|
UCHAR SubClass; // (ro)
|
||||||
|
UCHAR BaseClass; // (ro)
|
||||||
|
UCHAR CacheLineSize; // (ro+)
|
||||||
|
UCHAR LatencyTimer; // (ro+)
|
||||||
|
UCHAR HeaderType; // (ro)
|
||||||
|
UCHAR BIST; // Built in self test
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct _PCI_HEADER_TYPE_0
|
||||||
|
{
|
||||||
|
ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
|
||||||
|
ULONG CIS;
|
||||||
|
USHORT SubVendorID;
|
||||||
|
USHORT SubSystemID;
|
||||||
|
ULONG ROMBaseAddress;
|
||||||
|
ULONG Reserved2[2];
|
||||||
|
|
||||||
|
UCHAR InterruptLine; //
|
||||||
|
UCHAR InterruptPin; // (ro)
|
||||||
|
UCHAR MinimumGrant; // (ro)
|
||||||
|
UCHAR MaximumLatency; // (ro)
|
||||||
|
} type0;
|
||||||
|
|
||||||
|
|
||||||
|
} u;
|
||||||
|
|
||||||
|
UCHAR DeviceSpecific[192];
|
||||||
|
|
||||||
|
} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _IDE_CONTROLLER_PARAMETERS
|
typedef struct _IDE_CONTROLLER_PARAMETERS
|
||||||
{
|
{
|
||||||
int CommandPortBase;
|
int CommandPortBase;
|
||||||
|
@ -98,12 +141,12 @@ typedef struct _IDE_CONTROLLER_PARAMETERS
|
||||||
|
|
||||||
#define IDE_MAX_DRIVES 2
|
#define IDE_MAX_DRIVES 2
|
||||||
|
|
||||||
#define IDE_MAX_CONTROLLERS 1
|
#define IDE_MAX_CONTROLLERS 2
|
||||||
IDE_CONTROLLER_PARAMETERS Controllers[IDE_MAX_CONTROLLERS] =
|
IDE_CONTROLLER_PARAMETERS Controllers[IDE_MAX_CONTROLLERS] =
|
||||||
{
|
{
|
||||||
{0x01f0, 8, 0x03f6, 1, 14, 14, 15, LevelSensitive, 0xffff}
|
{0x01f0, 8, 0x03f6, 1, 14, 14, 15, LevelSensitive, 0xffff},
|
||||||
/*{0x0170, 8, 0x0376, 1, 15, 15, 15, LevelSensitive, 0xffff},
|
{0x0170, 8, 0x0376, 1, 15, 15, 15, LevelSensitive, 0xffff}
|
||||||
{0x01E8, 8, 0x03ee, 1, 11, 11, 15, LevelSensitive, 0xffff},
|
/* {0x01E8, 8, 0x03ee, 1, 11, 11, 15, LevelSensitive, 0xffff},
|
||||||
{0x0168, 8, 0x036e, 1, 10, 10, 15, LevelSensitive, 0xffff}*/
|
{0x0168, 8, 0x036e, 1, 10, 10, 15, LevelSensitive, 0xffff}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,9 +177,14 @@ static BOOLEAN IDEInitialized = FALSE;
|
||||||
|
|
||||||
// ---------------------------------------------------- Forward Declarations
|
// ---------------------------------------------------- Forward Declarations
|
||||||
|
|
||||||
static BOOLEAN IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
static NTSTATUS
|
||||||
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
IdeFindControllers(IN PDRIVER_OBJECT DriverObject);
|
||||||
IN int ControllerIdx);
|
|
||||||
|
static NTSTATUS
|
||||||
|
IdeCreateController(IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
||||||
|
IN int ControllerIdx);
|
||||||
|
|
||||||
static BOOLEAN IDEResetController(IN WORD CommandPort, IN WORD ControlPort);
|
static BOOLEAN IDEResetController(IN WORD CommandPort, IN WORD ControlPort);
|
||||||
static BOOLEAN IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
static BOOLEAN IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PCONTROLLER_OBJECT ControllerObject,
|
IN PCONTROLLER_OBJECT ControllerObject,
|
||||||
|
@ -161,9 +209,6 @@ static NTSTATUS IDECreatePartitionDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN ULONG DiskNumber,
|
IN ULONG DiskNumber,
|
||||||
IN PIDE_DRIVE_IDENTIFY DrvParms,
|
IN PIDE_DRIVE_IDENTIFY DrvParms,
|
||||||
IN PPARTITION_INFORMATION PartitionInfo);
|
IN PPARTITION_INFORMATION PartitionInfo);
|
||||||
// IN ULONG PartitionIdx,
|
|
||||||
// IN ULONGLONG Offset,
|
|
||||||
// IN ULONGLONG Size);
|
|
||||||
static int IDEPolledRead(IN WORD Address,
|
static int IDEPolledRead(IN WORD Address,
|
||||||
IN BYTE PreComp,
|
IN BYTE PreComp,
|
||||||
IN BYTE SectorCnt,
|
IN BYTE SectorCnt,
|
||||||
|
@ -231,12 +276,11 @@ IDESwapBytePairs(char *Buf,
|
||||||
// RETURNS:
|
// RETURNS:
|
||||||
// NTSTATUS
|
// NTSTATUS
|
||||||
|
|
||||||
STDCALL NTSTATUS
|
STDCALL NTSTATUS
|
||||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PUNICODE_STRING RegistryPath)
|
IN PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
BOOLEAN WeGotSomeDisks;
|
NTSTATUS Status;
|
||||||
int ControllerIdx;
|
|
||||||
|
|
||||||
DbgPrint("IDE Driver %s\n", VERSION);
|
DbgPrint("IDE Driver %s\n", VERSION);
|
||||||
|
|
||||||
|
@ -250,29 +294,199 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
// DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = IDEDispatchSetInformation;
|
// DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = IDEDispatchSetInformation;
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IDEDispatchDeviceControl;
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IDEDispatchDeviceControl;
|
||||||
|
|
||||||
WeGotSomeDisks = FALSE;
|
Status = IdeFindControllers(DriverObject);
|
||||||
for (ControllerIdx = 0; ControllerIdx < IDE_MAX_CONTROLLERS; ControllerIdx++)
|
if (NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
if (IDECreateController(DriverObject,
|
|
||||||
&Controllers[ControllerIdx],
|
|
||||||
ControllerIdx))
|
|
||||||
{
|
|
||||||
WeGotSomeDisks = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WeGotSomeDisks)
|
|
||||||
{
|
{
|
||||||
IDEInitialized = TRUE;
|
IDEInitialized = TRUE;
|
||||||
}
|
}
|
||||||
|
return Status;
|
||||||
DPRINT( "Returning from DriverEntry\n" );
|
|
||||||
return WeGotSomeDisks ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------- Discardable statics
|
// ---------------------------------------------------- Discardable statics
|
||||||
|
|
||||||
// IDECreateController
|
static NTSTATUS
|
||||||
|
IdeFindControllers(IN PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
PCI_COMMON_CONFIG PciConfig;
|
||||||
|
ULONG Bus;
|
||||||
|
ULONG Slot;
|
||||||
|
ULONG Size;
|
||||||
|
ULONG i;
|
||||||
|
NTSTATUS ReturnedStatus = STATUS_NO_SUCH_DEVICE;
|
||||||
|
NTSTATUS Status;
|
||||||
|
INT ControllerIdx = 0;
|
||||||
|
PCONFIGURATION_INFORMATION ConfigInfo;
|
||||||
|
|
||||||
|
DPRINT("IdeFindControllers() called!\n");
|
||||||
|
|
||||||
|
ConfigInfo = IoGetConfigurationInformation();
|
||||||
|
|
||||||
|
/* Search PCI busses for IDE controllers */
|
||||||
|
for (Bus = 0; Bus < 8; Bus++)
|
||||||
|
{
|
||||||
|
for (Slot = 0; Slot < 256; Slot++)
|
||||||
|
{
|
||||||
|
Size = HalGetBusData(PCIConfiguration,
|
||||||
|
Bus,
|
||||||
|
Slot,
|
||||||
|
&PciConfig,
|
||||||
|
sizeof(PCI_COMMON_CONFIG));
|
||||||
|
if (Size != 0)
|
||||||
|
{
|
||||||
|
if ((PciConfig.BaseClass == 0x01) &&
|
||||||
|
(PciConfig.SubClass == 0x01))
|
||||||
|
{
|
||||||
|
DPRINT("IDE controller found!\n");
|
||||||
|
|
||||||
|
DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n",
|
||||||
|
Bus,
|
||||||
|
Slot>>3,
|
||||||
|
Slot & 0x07,
|
||||||
|
PciConfig.VendorID,
|
||||||
|
PciConfig.DeviceID);
|
||||||
|
if ((PciConfig.HeaderType & 0x7FFFFFFF) == 0)
|
||||||
|
{
|
||||||
|
DPRINT(" IPR 0x%X ILR 0x%X\n",
|
||||||
|
PciConfig.u.type0.InterruptPin,
|
||||||
|
PciConfig.u.type0.InterruptLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PciConfig.ProgIf & 0x01)
|
||||||
|
{
|
||||||
|
DPRINT("Primary channel: PCI native mode\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Primary channel: Compatibility mode\n");
|
||||||
|
if (ConfigInfo->AtDiskPrimaryAddressClaimed == FALSE)
|
||||||
|
{
|
||||||
|
Status = IdeCreateController(DriverObject,
|
||||||
|
&Controllers[0],
|
||||||
|
ControllerIdx);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ControllerIdx++;
|
||||||
|
ConfigInfo->AtDiskPrimaryAddressClaimed = TRUE;
|
||||||
|
ConfigInfo->ScsiPortCount++;
|
||||||
|
ReturnedStatus = Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* FIXME: Switch controller to native pci mode
|
||||||
|
* if it is programmable.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (PciConfig.ProgIf & 0x02)
|
||||||
|
{
|
||||||
|
DPRINT("Primary channel: programmable\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Primary channel: not programmable\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PciConfig.ProgIf & 0x04)
|
||||||
|
{
|
||||||
|
DPRINT("Secondary channel: PCI native mode\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Secondary channel: Compatibility mode\n");
|
||||||
|
#if 0
|
||||||
|
Status = IdeCreateController(DriverObject,
|
||||||
|
&Controllers[1],
|
||||||
|
ControllerIdx);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ControllerIdx++;
|
||||||
|
ConfigInfo->AtDiskSecondaryAddressClaimed = TRUE;
|
||||||
|
ConfigInfo->ScsiPortCount++;
|
||||||
|
ReturnedStatus = Status;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (PciConfig.ProgIf & 0x08)
|
||||||
|
{
|
||||||
|
DPRINT("Secondary channel: programmable\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Secondary channel: not programmable\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PciConfig.ProgIf & 0x80)
|
||||||
|
{
|
||||||
|
DPRINT("Master IDE device: 1\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Master IDE device: 0\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
|
||||||
|
{
|
||||||
|
DPRINT("BaseAddress: 0x%08X\n", PciConfig.u.type0.BaseAddresses[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search for ISA IDE controller if no primary controller was found */
|
||||||
|
if (ConfigInfo->AtDiskPrimaryAddressClaimed == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT("Searching for primary ISA IDE controller!\n");
|
||||||
|
|
||||||
|
if (IDEResetController(Controllers[0].CommandPortBase,
|
||||||
|
Controllers[0].ControlPortBase))
|
||||||
|
{
|
||||||
|
Status = IdeCreateController(DriverObject,
|
||||||
|
&Controllers[0],
|
||||||
|
ControllerIdx);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT(" Found primary ISA IDE controller!\n");
|
||||||
|
ControllerIdx++;
|
||||||
|
ConfigInfo->AtDiskPrimaryAddressClaimed = TRUE;
|
||||||
|
ConfigInfo->ScsiPortCount++;
|
||||||
|
ReturnedStatus = Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (ConfigInfo->AtDiskSecondaryAddressClaimed == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT("Searching for secondary ISA IDE controller!\n");
|
||||||
|
|
||||||
|
if (IDEResetController(Controllers[1].CommandPortBase,
|
||||||
|
Controllers[1].ControlPortBase))
|
||||||
|
{
|
||||||
|
Status = IdeCreateController(DriverObject,
|
||||||
|
&Controllers[1],
|
||||||
|
ControllerIdx);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT(" Found secondary ISA IDE controller!\n");
|
||||||
|
ControllerIdx++;
|
||||||
|
ConfigInfo->AtDiskSecondaryAddressClaimed = TRUE;
|
||||||
|
ConfigInfo->ScsiPortCount++;
|
||||||
|
ReturnedStatus = Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DPRINT("IdeFindControllers() done!\n");
|
||||||
|
|
||||||
|
return(ReturnedStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// IdeCreateController
|
||||||
//
|
//
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
// Creates a controller object and a device object for each valid
|
// Creates a controller object and a device object for each valid
|
||||||
|
@ -292,10 +506,10 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
// FALSE The controller does not respond or there are no devices on it
|
// FALSE The controller does not respond or there are no devices on it
|
||||||
//
|
//
|
||||||
|
|
||||||
BOOLEAN
|
static NTSTATUS
|
||||||
IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
IdeCreateController(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
||||||
IN int ControllerIdx)
|
IN int ControllerIdx)
|
||||||
{
|
{
|
||||||
BOOLEAN CreatedDevices, ThisDriveExists;
|
BOOLEAN CreatedDevices, ThisDriveExists;
|
||||||
int DriveIdx;
|
int DriveIdx;
|
||||||
|
@ -303,22 +517,12 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||||
PCONTROLLER_OBJECT ControllerObject;
|
PCONTROLLER_OBJECT ControllerObject;
|
||||||
PIDE_CONTROLLER_EXTENSION ControllerExtension;
|
PIDE_CONTROLLER_EXTENSION ControllerExtension;
|
||||||
|
|
||||||
// Try to reset the controller and return FALSE if it fails
|
|
||||||
if (!IDEResetController(ControllerParams->CommandPortBase,
|
|
||||||
ControllerParams->ControlPortBase))
|
|
||||||
{
|
|
||||||
DbgPrint ("Could not find controller %d at %04lx\n",
|
|
||||||
ControllerIdx,
|
|
||||||
ControllerParams->CommandPortBase);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerObject = IoCreateController(sizeof(IDE_CONTROLLER_EXTENSION));
|
ControllerObject = IoCreateController(sizeof(IDE_CONTROLLER_EXTENSION));
|
||||||
if (ControllerObject == NULL)
|
if (ControllerObject == NULL)
|
||||||
{
|
{
|
||||||
DbgPrint ("Could not create controller object for controller %d\n",
|
DbgPrint ("Could not create controller object for controller %d\n",
|
||||||
ControllerIdx);
|
ControllerIdx);
|
||||||
return FALSE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill out Controller extension data
|
// Fill out Controller extension data
|
||||||
|
@ -337,22 +541,22 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||||
|
|
||||||
// Register an interrupt handler for this controller
|
// Register an interrupt handler for this controller
|
||||||
RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
|
RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
|
||||||
IDEIsr,
|
IDEIsr,
|
||||||
ControllerExtension,
|
ControllerExtension,
|
||||||
&ControllerExtension->SpinLock,
|
&ControllerExtension->SpinLock,
|
||||||
ControllerExtension->Vector,
|
ControllerExtension->Vector,
|
||||||
ControllerParams->IrqL,
|
ControllerParams->IrqL,
|
||||||
ControllerParams->SynchronizeIrqL,
|
ControllerParams->SynchronizeIrqL,
|
||||||
ControllerParams->InterruptMode,
|
ControllerParams->InterruptMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
ControllerParams->Affinity,
|
ControllerParams->Affinity,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!NT_SUCCESS(RC))
|
if (!NT_SUCCESS(RC))
|
||||||
{
|
{
|
||||||
DbgPrint ("Could not Connect Interrupt %d\n",
|
DbgPrint ("Could not Connect Interrupt %d\n",
|
||||||
ControllerExtension->Vector);
|
ControllerExtension->Vector);
|
||||||
IoDeleteController (ControllerObject);
|
IoDeleteController (ControllerObject);
|
||||||
return FALSE;
|
return RC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEST */
|
/* TEST */
|
||||||
|
@ -373,7 +577,7 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreatedDevices)
|
if (!CreatedDevices)
|
||||||
{
|
{
|
||||||
DbgPrint ("Did not find any devices for controller %d\n",
|
DbgPrint ("Did not find any devices for controller %d\n",
|
||||||
ControllerIdx);
|
ControllerIdx);
|
||||||
|
@ -387,9 +591,10 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||||
IoStartTimer(ControllerExtension->TimerDevice);
|
IoStartTimer(ControllerExtension->TimerDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreatedDevices;
|
return((CreatedDevices == TRUE)?STATUS_SUCCESS:STATUS_NO_SUCH_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// IDEResetController
|
// IDEResetController
|
||||||
//
|
//
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
|
|
Loading…
Reference in a new issue