mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +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
|
||||
* written by Rex Jolliff
|
||||
|
@ -81,6 +81,49 @@
|
|||
|
||||
// ------------------------------------------------------- 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
|
||||
{
|
||||
int CommandPortBase;
|
||||
|
@ -98,12 +141,12 @@ typedef struct _IDE_CONTROLLER_PARAMETERS
|
|||
|
||||
#define IDE_MAX_DRIVES 2
|
||||
|
||||
#define IDE_MAX_CONTROLLERS 1
|
||||
#define IDE_MAX_CONTROLLERS 2
|
||||
IDE_CONTROLLER_PARAMETERS Controllers[IDE_MAX_CONTROLLERS] =
|
||||
{
|
||||
{0x01f0, 8, 0x03f6, 1, 14, 14, 15, LevelSensitive, 0xffff}
|
||||
/*{0x0170, 8, 0x0376, 1, 15, 15, 15, LevelSensitive, 0xffff},
|
||||
{0x01E8, 8, 0x03ee, 1, 11, 11, 15, LevelSensitive, 0xffff},
|
||||
{0x01f0, 8, 0x03f6, 1, 14, 14, 15, LevelSensitive, 0xffff},
|
||||
{0x0170, 8, 0x0376, 1, 15, 15, 15, LevelSensitive, 0xffff}
|
||||
/* {0x01E8, 8, 0x03ee, 1, 11, 11, 15, LevelSensitive, 0xffff},
|
||||
{0x0168, 8, 0x036e, 1, 10, 10, 15, LevelSensitive, 0xffff}*/
|
||||
};
|
||||
|
||||
|
@ -134,9 +177,14 @@ static BOOLEAN IDEInitialized = FALSE;
|
|||
|
||||
// ---------------------------------------------------- Forward Declarations
|
||||
|
||||
static BOOLEAN IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
||||
IN int ControllerIdx);
|
||||
static NTSTATUS
|
||||
IdeFindControllers(IN PDRIVER_OBJECT DriverObject);
|
||||
|
||||
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 IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
|
@ -161,9 +209,6 @@ static NTSTATUS IDECreatePartitionDevice(IN PDRIVER_OBJECT DriverObject,
|
|||
IN ULONG DiskNumber,
|
||||
IN PIDE_DRIVE_IDENTIFY DrvParms,
|
||||
IN PPARTITION_INFORMATION PartitionInfo);
|
||||
// IN ULONG PartitionIdx,
|
||||
// IN ULONGLONG Offset,
|
||||
// IN ULONGLONG Size);
|
||||
static int IDEPolledRead(IN WORD Address,
|
||||
IN BYTE PreComp,
|
||||
IN BYTE SectorCnt,
|
||||
|
@ -231,12 +276,11 @@ IDESwapBytePairs(char *Buf,
|
|||
// RETURNS:
|
||||
// NTSTATUS
|
||||
|
||||
STDCALL NTSTATUS
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
STDCALL NTSTATUS
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
BOOLEAN WeGotSomeDisks;
|
||||
int ControllerIdx;
|
||||
NTSTATUS Status;
|
||||
|
||||
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_DEVICE_CONTROL] = IDEDispatchDeviceControl;
|
||||
|
||||
WeGotSomeDisks = FALSE;
|
||||
for (ControllerIdx = 0; ControllerIdx < IDE_MAX_CONTROLLERS; ControllerIdx++)
|
||||
{
|
||||
if (IDECreateController(DriverObject,
|
||||
&Controllers[ControllerIdx],
|
||||
ControllerIdx))
|
||||
{
|
||||
WeGotSomeDisks = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (WeGotSomeDisks)
|
||||
Status = IdeFindControllers(DriverObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
IDEInitialized = TRUE;
|
||||
}
|
||||
|
||||
DPRINT( "Returning from DriverEntry\n" );
|
||||
return WeGotSomeDisks ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------- 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:
|
||||
// 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
|
||||
//
|
||||
|
||||
BOOLEAN
|
||||
IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
||||
IN int ControllerIdx)
|
||||
static NTSTATUS
|
||||
IdeCreateController(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
||||
IN int ControllerIdx)
|
||||
{
|
||||
BOOLEAN CreatedDevices, ThisDriveExists;
|
||||
int DriveIdx;
|
||||
|
@ -303,22 +517,12 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
|||
PCONTROLLER_OBJECT ControllerObject;
|
||||
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));
|
||||
if (ControllerObject == NULL)
|
||||
if (ControllerObject == NULL)
|
||||
{
|
||||
DbgPrint ("Could not create controller object for controller %d\n",
|
||||
ControllerIdx);
|
||||
return FALSE;
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
// Fill out Controller extension data
|
||||
|
@ -337,22 +541,22 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
|||
|
||||
// Register an interrupt handler for this controller
|
||||
RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
|
||||
IDEIsr,
|
||||
ControllerExtension,
|
||||
&ControllerExtension->SpinLock,
|
||||
ControllerExtension->Vector,
|
||||
ControllerParams->IrqL,
|
||||
ControllerParams->SynchronizeIrqL,
|
||||
ControllerParams->InterruptMode,
|
||||
FALSE,
|
||||
ControllerParams->Affinity,
|
||||
IDEIsr,
|
||||
ControllerExtension,
|
||||
&ControllerExtension->SpinLock,
|
||||
ControllerExtension->Vector,
|
||||
ControllerParams->IrqL,
|
||||
ControllerParams->SynchronizeIrqL,
|
||||
ControllerParams->InterruptMode,
|
||||
FALSE,
|
||||
ControllerParams->Affinity,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(RC))
|
||||
if (!NT_SUCCESS(RC))
|
||||
{
|
||||
DbgPrint ("Could not Connect Interrupt %d\n",
|
||||
ControllerExtension->Vector);
|
||||
IoDeleteController (ControllerObject);
|
||||
return FALSE;
|
||||
return RC;
|
||||
}
|
||||
|
||||
/* TEST */
|
||||
|
@ -373,7 +577,7 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
|||
}
|
||||
}
|
||||
|
||||
if (!CreatedDevices)
|
||||
if (!CreatedDevices)
|
||||
{
|
||||
DbgPrint ("Did not find any devices for controller %d\n",
|
||||
ControllerIdx);
|
||||
|
@ -387,9 +591,10 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
|||
IoStartTimer(ControllerExtension->TimerDevice);
|
||||
}
|
||||
|
||||
return CreatedDevices;
|
||||
return((CreatedDevices == TRUE)?STATUS_SUCCESS:STATUS_NO_SUCH_DEVICE);
|
||||
}
|
||||
|
||||
|
||||
// IDEResetController
|
||||
//
|
||||
// DESCRIPTION:
|
||||
|
|
Loading…
Reference in a new issue