mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Moved/added some declarations
Fixed atapi drive identification svn path=/trunk/; revision=2330
This commit is contained in:
parent
6d21eb028c
commit
998550e404
1 changed files with 293 additions and 86 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: atapi.c,v 1.1 2001/09/09 21:31:13 ekohl Exp $
|
||||
/* $Id: atapi.c,v 1.2 2001/11/01 00:30:29 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS ATAPI miniport driver
|
||||
|
@ -28,6 +28,8 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "../include/srb.h"
|
||||
|
||||
#include "atapi.h"
|
||||
#include "partitio.h"
|
||||
|
||||
|
@ -102,6 +104,14 @@ AtapiCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
|
|||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
IN ULONG ControllerNumber);
|
||||
|
||||
static BOOLEAN
|
||||
AtapiFindDrives(PIDE_CONTROLLER_EXTENSION ControllerExtension);
|
||||
|
||||
BOOLEAN
|
||||
AtapiIdentifyATAPIDrive(IN int CommandPort,
|
||||
IN int DriveNum,
|
||||
OUT PIDE_DRIVE_IDENTIFY DrvParms);
|
||||
|
||||
static BOOLEAN IDEResetController(IN WORD CommandPort, IN WORD ControlPort);
|
||||
static BOOLEAN IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
|
@ -132,7 +142,14 @@ static int IDEPolledRead(IN WORD Address,
|
|||
static NTSTATUS STDCALL IDEDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static NTSTATUS STDCALL IDEDispatchReadWrite(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static NTSTATUS STDCALL IDEDispatchDeviceControl(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static VOID STDCALL IDEStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
AtapiDispatchScsi(IN PDEVICE_OBJECT pDO,
|
||||
IN PIRP Irp);
|
||||
|
||||
static VOID STDCALL
|
||||
IDEStartIo(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
static IO_ALLOCATION_ACTION STDCALL
|
||||
IDEAllocateController(IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -157,47 +174,6 @@ static VOID IDEFinishOperation(PIDE_CONTROLLER_EXTENSION ControllerExtension);
|
|||
static VOID STDCALL IDEIoTimer(PDEVICE_OBJECT DeviceObject, PVOID Context);
|
||||
|
||||
|
||||
|
||||
|
||||
#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; /* read-only */
|
||||
UCHAR MaximumLatency; /* read-only */
|
||||
} type0;
|
||||
} u;
|
||||
UCHAR DeviceSpecific[192];
|
||||
} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------- Inlines
|
||||
|
||||
void
|
||||
|
@ -215,6 +191,28 @@ IDESwapBytePairs(char *Buf,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
IdeFindDrive(int Address,
|
||||
int DriveIdx)
|
||||
{
|
||||
ULONG Cyl;
|
||||
|
||||
DPRINT1("IdeFindDrive(Address %lx DriveIdx %lu) called!\n", Address, DriveIdx);
|
||||
|
||||
IDEWriteDriveHead(Address, IDE_DH_FIXED | (DriveIdx ? IDE_DH_DRV1 : 0));
|
||||
IDEWriteCylinderLow(Address, 0x30);
|
||||
|
||||
Cyl = IDEReadCylinderLow(Address);
|
||||
DPRINT1("Cylinder %lx\n", Cyl);
|
||||
|
||||
|
||||
DPRINT1("IdeFindDrive() done!\n");
|
||||
// for(;;);
|
||||
return(Cyl == 0x30);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------- Public Interface
|
||||
|
||||
// DriverEntry
|
||||
|
@ -244,15 +242,12 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
|||
|
||||
DbgPrint("ATAPI Driver %s\n", VERSION);
|
||||
|
||||
/* Export other driver entry points... */
|
||||
DriverObject->DriverStartIo = IDEStartIo;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = IDEDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IDEDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = IDEDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = IDEDispatchReadWrite;
|
||||
// DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = IDEDispatchQueryInformation;
|
||||
// DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = IDEDispatchSetInformation;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IDEDispatchDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_SCSI] = AtapiDispatchScsi;
|
||||
|
||||
Status = AtapiFindControllers(DriverObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
|
@ -397,6 +392,14 @@ AtapiFindControllers(IN PDRIVER_OBJECT DriverObject)
|
|||
DPRINT1("BaseAddress: 0x%08X\n", PciConfig.u.type0.BaseAddresses[i]);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if ((PciConfig.BaseClass == 0x01) &&
|
||||
(PciConfig.SubClass == 0x80))
|
||||
{
|
||||
/* found other mass storage controller */
|
||||
DPRINT1("Found other mass storage controller!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -535,6 +538,8 @@ AtapiCreateController(IN PDRIVER_OBJECT DriverObject,
|
|||
return(Status);
|
||||
}
|
||||
|
||||
AtapiFindDrives(ControllerExtension);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -605,6 +610,87 @@ AtapiCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
|
|||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
AtapiFindDrives(PIDE_CONTROLLER_EXTENSION ControllerExtension)
|
||||
{
|
||||
ULONG DriveIndex;
|
||||
ULONG Retries;
|
||||
BYTE High, Low;
|
||||
IDE_DRIVE_IDENTIFY DrvParms;
|
||||
|
||||
DPRINT1("AtapiFindDrives() called\n");
|
||||
|
||||
for (DriveIndex = 0; DriveIndex < 2; DriveIndex++)
|
||||
{
|
||||
/* disable interrupts */
|
||||
IDEWriteDriveControl(ControllerExtension->ControlPortBase, IDE_DC_nIEN);
|
||||
|
||||
/* select drive */
|
||||
IDEWriteDriveHead(ControllerExtension->CommandPortBase,
|
||||
IDE_DH_FIXED | (DriveIndex ? IDE_DH_DRV1 : 0));
|
||||
KeStallExecutionProcessor(500);
|
||||
IDEWriteCylinderHigh(ControllerExtension->CommandPortBase, 0);
|
||||
IDEWriteCylinderLow(ControllerExtension->CommandPortBase, 0);
|
||||
IDEWriteCommand(ControllerExtension->CommandPortBase, 0x08); /* IDE_COMMAND_ATAPI_RESET */
|
||||
// KeStallExecutionProcessor(1000*1000);
|
||||
// IDEWriteDriveHead(ControllerExtension->CommandPortBase,
|
||||
// IDE_DH_FIXED | (DriveIndex ? IDE_DH_DRV1 : 0));
|
||||
// IDE_DH_FIXED);
|
||||
|
||||
for (Retries = 0; Retries < 20000; Retries++)
|
||||
{
|
||||
if (!(IDEReadStatus(ControllerExtension->CommandPortBase) & IDE_SR_BUSY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
KeStallExecutionProcessor(150);
|
||||
}
|
||||
if (Retries >= IDE_RESET_BUSY_TIMEOUT * 1000)
|
||||
{
|
||||
DPRINT1("Timeout on drive %lu\n", DriveIndex);
|
||||
// return FALSE;
|
||||
}
|
||||
|
||||
High = IDEReadCylinderHigh(ControllerExtension->CommandPortBase);
|
||||
Low = IDEReadCylinderLow(ControllerExtension->CommandPortBase);
|
||||
|
||||
DPRINT1("Check drive %lu: High 0x%lx Low 0x%lx\n", DriveIndex, High, Low);
|
||||
if (High == 0xEB && Low == 0x14)
|
||||
{
|
||||
// DPRINT1("ATAPI drive found!\n");
|
||||
if (!AtapiIdentifyATAPIDrive(ControllerExtension->CommandPortBase, DriveIndex, &DrvParms))
|
||||
{
|
||||
DPRINT1("No drive found!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("ATAPI drive found!\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (!IDEGetDriveIdentification(ControllerExtension->CommandPortBase, DriveIndex, &DrvParms))
|
||||
{
|
||||
DPRINT1("No drive found!\n");
|
||||
// DPRINT1("Giving up on drive %d on controller %d...\n",
|
||||
// DriveIndex,
|
||||
// ControllerExtension->CommandPortBase);
|
||||
// return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("IDE drive found!\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// IDEResetController
|
||||
//
|
||||
// DESCRIPTION:
|
||||
|
@ -905,12 +991,70 @@ IDEGetDriveIdentification(IN int CommandPort,
|
|||
DrvParms->TMSectorCountLo,
|
||||
(ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo));
|
||||
|
||||
DPRINT("BytesPerSector %d\n", DrvParms->BytesPerSector);
|
||||
DPRINT1("BytesPerSector %d\n", DrvParms->BytesPerSector);
|
||||
if (DrvParms->BytesPerSector == 0)
|
||||
DrvParms->BytesPerSector = 512; /* FIXME !!!*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
AtapiIdentifyATAPIDrive(IN int CommandPort,
|
||||
IN int DriveNum,
|
||||
OUT PIDE_DRIVE_IDENTIFY DrvParms)
|
||||
{
|
||||
|
||||
// Get the Drive Identify block from drive or die
|
||||
if (IDEPolledRead(CommandPort, 0, 0, 0, 0, 0, (DriveNum ? IDE_DH_DRV1 : 0),
|
||||
0xA1 /*IDE_CMD_IDENT_DRV*/, (BYTE *)DrvParms) != 0) /* atapi_identify */
|
||||
{
|
||||
DPRINT1("IDEPolledRead() failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Report on drive parameters if debug mode
|
||||
IDESwapBytePairs(DrvParms->SerialNumber, 20);
|
||||
IDESwapBytePairs(DrvParms->FirmwareRev, 8);
|
||||
IDESwapBytePairs(DrvParms->ModelNumber, 40);
|
||||
DPRINT1("Config:%04x Cyls:%5d Heads:%2d Sectors/Track:%3d Gaps:%02d %02d\n",
|
||||
DrvParms->ConfigBits,
|
||||
DrvParms->LogicalCyls,
|
||||
DrvParms->LogicalHeads,
|
||||
DrvParms->SectorsPerTrack,
|
||||
DrvParms->InterSectorGap,
|
||||
DrvParms->InterSectorGapSize);
|
||||
DPRINT1("Bytes/PLO:%3d Vendor Cnt:%2d Serial number:[%.20s]\n",
|
||||
DrvParms->BytesInPLO,
|
||||
DrvParms->VendorUniqueCnt,
|
||||
DrvParms->SerialNumber);
|
||||
DPRINT1("Cntlr type:%2d BufSiz:%5d ECC bytes:%3d Firmware Rev:[%.8s]\n",
|
||||
DrvParms->ControllerType,
|
||||
DrvParms->BufferSize * IDE_SECTOR_BUF_SZ,
|
||||
DrvParms->ECCByteCnt,
|
||||
DrvParms->FirmwareRev);
|
||||
DPRINT1("Model:[%.40s]\n", DrvParms->ModelNumber);
|
||||
DPRINT1("RWMult?:%02x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n",
|
||||
(DrvParms->RWMultImplemented) & 0xff,
|
||||
(DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0,
|
||||
(DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0,
|
||||
DrvParms->MinPIOTransTime,
|
||||
DrvParms->MinDMATransTime);
|
||||
DPRINT1("TM:Cyls:%d Heads:%d Sectors/Trk:%d Capacity:%ld\n",
|
||||
DrvParms->TMCylinders,
|
||||
DrvParms->TMHeads,
|
||||
DrvParms->TMSectorsPerTrk,
|
||||
(ULONG)(DrvParms->TMCapacityLo + (DrvParms->TMCapacityHi << 16)));
|
||||
DPRINT1("TM:SectorCount: 0x%04x%04x = %lu\n",
|
||||
DrvParms->TMSectorCountHi,
|
||||
DrvParms->TMSectorCountLo,
|
||||
(ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo));
|
||||
|
||||
DPRINT1("BytesPerSector %d\n", DrvParms->BytesPerSector);
|
||||
// DrvParms->BytesPerSector = 512; /* FIXME !!!*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// IDECreateDevice
|
||||
//
|
||||
// DESCRIPTION:
|
||||
|
@ -1061,7 +1205,7 @@ static int
|
|||
IDEPolledRead(IN WORD Address,
|
||||
IN BYTE PreComp,
|
||||
IN BYTE SectorCnt,
|
||||
IN BYTE SectorNum ,
|
||||
IN BYTE SectorNum,
|
||||
IN BYTE CylinderLow,
|
||||
IN BYTE CylinderHigh,
|
||||
IN BYTE DrvHead,
|
||||
|
@ -1075,7 +1219,8 @@ IDEPolledRead(IN WORD Address,
|
|||
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
|
||||
{
|
||||
Status = IDEReadStatus(Address);
|
||||
if (!(Status & IDE_SR_BUSY))
|
||||
if (!(Status & IDE_SR_BUSY) && !(Status & IDE_SR_DRQ))
|
||||
// if (!(Status & IDE_SR_BUSY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -1083,24 +1228,27 @@ IDEPolledRead(IN WORD Address,
|
|||
}
|
||||
if (RetryCount == IDE_MAX_BUSY_RETRIES)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return IDE_ER_ABRT;
|
||||
}
|
||||
|
||||
/* Write Drive/Head to select drive */
|
||||
IDEWriteDriveHead(Address, IDE_DH_FIXED | DrvHead);
|
||||
|
||||
/* Wait for STATUS.BUSY to clear and STATUS.DRDY to assert */
|
||||
/* Wait for STATUS.BUSY to clear and STATUS.DRQ to clear */
|
||||
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
|
||||
{
|
||||
Status = IDEReadStatus(Address);
|
||||
if (!(Status & IDE_SR_BUSY) && (Status & IDE_SR_DRDY))
|
||||
// if (!(Status & IDE_SR_BUSY) && (Status & IDE_SR_DRDY))
|
||||
if (!(Status & IDE_SR_BUSY) && !(Status & IDE_SR_DRQ))
|
||||
{
|
||||
break;
|
||||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
if (RetryCount == IDE_MAX_BUSY_RETRIES)
|
||||
if (RetryCount >= IDE_MAX_BUSY_RETRIES)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return IDE_ER_ABRT;
|
||||
}
|
||||
|
||||
|
@ -1139,27 +1287,39 @@ IDEPolledRead(IN WORD Address,
|
|||
|
||||
while (1)
|
||||
{
|
||||
|
||||
// wait for DRQ or error
|
||||
for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
|
||||
{
|
||||
Status = IDEReadStatus(Address);
|
||||
if (!(Status & IDE_SR_BUSY))
|
||||
{
|
||||
/*
|
||||
if (Status & IDE_SR_ERR)
|
||||
{
|
||||
BYTE Err = IDEReadError(Address);
|
||||
CHECKPOINT1;
|
||||
return Err;
|
||||
}
|
||||
else if (Status & IDE_SR_DRQ)
|
||||
{
|
||||
break;
|
||||
}
|
||||
*/
|
||||
if (Status & IDE_SR_DRQ)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return IDE_ER_ABRT;
|
||||
}
|
||||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
if (RetryCount >= IDE_MAX_POLL_RETRIES)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return IDE_ER_ABRT;
|
||||
}
|
||||
|
||||
|
@ -1168,13 +1328,32 @@ IDEPolledRead(IN WORD Address,
|
|||
Buffer += IDE_SECTOR_BUF_SZ;
|
||||
|
||||
// Check for more sectors to read
|
||||
/*
|
||||
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES &&
|
||||
(IDEReadStatus(Address) & IDE_SR_DRQ); RetryCount++)
|
||||
;
|
||||
if (!(IDEReadStatus(Address) & IDE_SR_BUSY))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
|
||||
{
|
||||
Status = IDEReadStatus(Address);
|
||||
if (!(Status & IDE_SR_BUSY))
|
||||
{
|
||||
if (Status & IDE_SR_DRQ)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1458,6 +1637,34 @@ IDEDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
return RC;
|
||||
}
|
||||
|
||||
// AtapiDispatchScsi
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Answer requests for Scsi calls
|
||||
//
|
||||
// RUN LEVEL:
|
||||
// PASSIVE_LEVEL
|
||||
//
|
||||
// ARGUMENTS:
|
||||
// Standard dispatch arguments
|
||||
//
|
||||
// RETURNS:
|
||||
// NTSTATUS
|
||||
//
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
AtapiDispatchScsi(IN PDEVICE_OBJECT pDO,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT1("AtapiDispatchScsi()\n");
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = FILE_OPENED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// IDEStartIo
|
||||
//
|
||||
// DESCRIPTION:
|
||||
|
@ -1473,8 +1680,8 @@ IDEDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
// NTSTATUS
|
||||
//
|
||||
|
||||
static VOID
|
||||
STDCALL IDEStartIo(IN PDEVICE_OBJECT DeviceObject,
|
||||
static VOID STDCALL
|
||||
IDEStartIo(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
LARGE_INTEGER SectorLI;
|
||||
|
|
Loading…
Reference in a new issue