Updates to the disk driver stack.

svn path=/trunk/; revision=2595
This commit is contained in:
Eric Kohl 2002-02-03 20:21:59 +00:00
parent 95410deae9
commit 246369a31b
5 changed files with 635 additions and 289 deletions

View file

@ -1,4 +1,4 @@
/* $Id: atapi.c,v 1.5 2002/01/31 14:57:37 ekohl Exp $
/* $Id: atapi.c,v 1.6 2002/02/03 20:21:13 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS ATAPI miniport driver
@ -60,6 +60,7 @@ typedef struct _ATAPI_MINIPORT_EXTENSION
ULONG ControlPortBase;
BOOLEAN ExpectingInterrupt;
PSCSI_REQUEST_BLOCK CurrentSrb;
PUSHORT DataBuffer;
} ATAPI_MINIPORT_EXTENSION, *PATAPI_MINIPORT_EXTENSION;
@ -137,21 +138,19 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
PPORT_CONFIGURATION_INFORMATION ConfigInfo);
static BOOLEAN
AtapiIdentifyATADevice(IN ULONG CommandPort,
IN ULONG DriveNum,
OUT PIDE_DRIVE_IDENTIFY DrvParms);
static BOOLEAN
AtapiIdentifyATAPIDevice(IN ULONG CommandPort,
IN ULONG DriveNum,
OUT PIDE_DRIVE_IDENTIFY DrvParms);
AtapiIdentifyDevice(IN ULONG CommandPort,
IN ULONG ControlPort,
IN ULONG DriveNum,
IN BOOLEAN Atapi,
OUT PIDE_DRIVE_IDENTIFY DrvParms);
static BOOLEAN
IDEResetController(IN WORD CommandPort,
IN WORD ControlPort);
static int
AtapiPolledRead(IN WORD Address,
AtapiPolledRead(IN WORD CommandPort,
IN WORD ControlPort,
IN BYTE PreComp,
IN BYTE SectorCnt,
IN BYTE SectorNum,
@ -163,10 +162,13 @@ AtapiPolledRead(IN WORD Address,
static ULONG
AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb);
static ULONG
AtapiExecuteScsi(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb);
AtapiSendIdeCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb);
static ULONG
AtapiInquiry(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
@ -537,24 +539,49 @@ static BOOLEAN STDCALL
AtapiStartIo(IN PVOID DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb)
{
PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
PATAPI_MINIPORT_EXTENSION DevExt;
ULONG Result;
DPRINT("AtapiStartIo() called\n");
DPRINT1("AtapiStartIo() called\n");
DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
switch (Srb->Function)
{
case SRB_FUNCTION_EXECUTE_SCSI:
Result = AtapiExecuteScsi(DevExt,
Srb);
DevExt->CurrentSrb = Srb;
if (DevExt->DeviceAtapi[Srb->TargetId] == TRUE)
{
Result = AtapiSendAtapiCommand(DevExt,
Srb);
}
else
{
Result = AtapiSendIdeCommand(DevExt,
Srb);
}
break;
}
Srb->SrbStatus = Result;
if (Result != SRB_STATUS_PENDING)
{
DevExt->CurrentSrb = NULL;
Srb->SrbStatus = (UCHAR)Result;
#if 0
ScsiPortNotification(RequestComplete,
DeviceExtension,
Srb);
ScsiPortNotification(NextRequest,
DeviceExtension,
NULL);
#endif
}
return(TRUE);
}
@ -562,7 +589,192 @@ AtapiStartIo(IN PVOID DeviceExtension,
static BOOLEAN STDCALL
AtapiInterrupt(IN PVOID DeviceExtension)
{
DPRINT("AtapiInterrupt() called!\n");
PATAPI_MINIPORT_EXTENSION DevExt;
PSCSI_REQUEST_BLOCK Srb;
ULONG CommandPortBase;
ULONG ControlPortBase;
UCHAR DeviceStatus;
BOOLEAN IsLastBlock, AnErrorOccured, RequestIsComplete;
ULONG Retries;
NTSTATUS ErrorStatus;
ULONG ErrorInformation;
PUCHAR TargetAddress;
DPRINT1("AtapiInterrupt() called!\n");
DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
Srb = DevExt->CurrentSrb;
DPRINT1("Srb: %p\n", Srb);
CommandPortBase = DevExt->CommandPortBase;
ControlPortBase = DevExt->ControlPortBase;
DPRINT("CommandPortBase: %lx ControlPortBase: %lx\n", CommandPortBase, ControlPortBase);
IsLastBlock = FALSE;
AnErrorOccured = FALSE;
RequestIsComplete = FALSE;
ErrorStatus = STATUS_SUCCESS;
ErrorInformation = 0;
DeviceStatus = IDEReadStatus(CommandPortBase);
/* Handle error condition if it exists */
if (DeviceStatus & IDE_SR_ERR)
{
BYTE ErrorReg, SectorCount, SectorNum, CylinderLow, CylinderHigh;
BYTE DriveHead;
/* Log the error */
ErrorReg = IDEReadError(CommandPortBase);
CylinderLow = IDEReadCylinderLow(CommandPortBase);
CylinderHigh = IDEReadCylinderHigh(CommandPortBase);
DriveHead = IDEReadDriveHead(CommandPortBase);
SectorCount = IDEReadSectorCount(CommandPortBase);
SectorNum = IDEReadSectorNum(CommandPortBase);
/* FIXME: should use the NT error logging facility */
DbgPrint("ATAPT Error: OP:%02x STAT:%02x ERR:%02x CYLLO:%02x CYLHI:%02x SCNT:%02x SNUM:%02x\n",
0, //DeviceExtension->Operation,
DeviceStatus,
ErrorReg,
CylinderLow,
CylinderHigh,
SectorCount,
SectorNum);
/* FIXME: should retry the command and perhaps recalibrate the drive */
// Set error status information
AnErrorOccured = TRUE;
ErrorStatus = STATUS_DISK_OPERATION_FAILED;
#if 0
ErrorInformation =
(((((((CylinderHigh << 8) + CylinderLow) *
DeviceExtension->LogicalHeads) +
(DriveHead % DeviceExtension->LogicalHeads)) *
DeviceExtension->SectorsPerLogTrk) + SectorNum - 1) -
DeviceExtension->StartingSector) * DeviceExtension->BytesPerSector;
#endif
}
else
{
switch (Srb->Cdb[0])
{
case SCSIOP_READ:
DPRINT1("SCSIOP_READ\n");
/* Update controller/device state variables */
TargetAddress = Srb->DataBuffer;
Srb->DataBuffer += DevExt->DeviceParams[Srb->TargetId].BytesPerSector;
Srb->DataTransferLength -= DevExt->DeviceParams[Srb->TargetId].BytesPerSector;
// DevExt->SectorsTransferred++;
/* Remember whether DRQ should be low at end (last block read) */
IsLastBlock = Srb->DataTransferLength == 0;
/* Wait for DRQ assertion */
for (Retries = 0; Retries < IDE_MAX_DRQ_RETRIES &&
!(IDEReadStatus(CommandPortBase) & IDE_SR_DRQ);
Retries++)
{
KeStallExecutionProcessor(10);
}
/* Copy the block of data */
IDEReadBlock(CommandPortBase,
TargetAddress,
IDE_SECTOR_BUF_SZ);
/* check DRQ */
if (IsLastBlock)
{
for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES &&
(IDEReadStatus(CommandPortBase) & IDE_SR_BUSY);
Retries++)
{
KeStallExecutionProcessor(10);
}
/* Check for data overrun */
if (IDEReadStatus(CommandPortBase) & IDE_SR_DRQ)
{
AnErrorOccured = TRUE;
ErrorStatus = STATUS_DATA_OVERRUN;
ErrorInformation = 0;
}
else
{
#if 0
// Setup next transfer or set RequestIsComplete
if (DeviceExtension->BytesRequested >
DeviceExtension->BytesPerSector * IDE_MAX_SECTORS_PER_XFER)
{
DeviceExtension->StartingSector += DeviceExtension->SectorsTransferred;
DeviceExtension->SectorsTransferred = 0;
DeviceExtension->BytesToTransfer =
DeviceExtension->BytesPerSector * IDE_MAX_SECTORS_PER_XFER;
DeviceExtension->BytesRequested -= DeviceExtension->BytesToTransfer;
}
else if (DeviceExtension->BytesRequested > 0)
{
DeviceExtension->StartingSector += DeviceExtension->SectorsTransferred;
DeviceExtension->SectorsTransferred = 0;
DeviceExtension->BytesToTransfer = DeviceExtension->BytesRequested;
DeviceExtension->BytesRequested -= DeviceExtension->BytesToTransfer;
}
else
{
RequestIsComplete = TRUE;
}
#endif
RequestIsComplete = TRUE;
}
}
break;
case SCSIOP_WRITE:
DPRINT1("AtapiInterrupt(): SCSIOP_WRITE not implemented yet!\n");
RequestIsComplete = TRUE;
break;
}
}
/* If there was an error or the request is done, complete the packet */
if (AnErrorOccured || RequestIsComplete)
{
#if 0
/* Set the return status and info values */
Irp = ControllerExtension->CurrentIrp;
Irp->IoStatus.Status = ErrorStatus;
Irp->IoStatus.Information = ErrorInformation;
/* Clear out controller fields */
ControllerExtension->OperationInProgress = FALSE;
ControllerExtension->DeviceStatus = 0;
/* Queue the Dpc to finish up */
IoRequestDpc(DeviceExtension->DeviceObject,
Irp,
ControllerExtension);
#endif
}
else if (IsLastBlock)
{
#if 0
/* Else more data is needed, setup next device I/O */
IDEStartController((PVOID)DeviceExtension);
#endif
}
DPRINT1("AtapiInterrupt() done!\n");
return(TRUE);
}
@ -581,6 +793,7 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
{
BOOLEAN DeviceFound = FALSE;
ULONG CommandPortBase;
ULONG ControlPortBase;
ULONG UnitNumber;
ULONG Retries;
BYTE High, Low;
@ -589,9 +802,12 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
// CommandPortBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart);
CommandPortBase = ScsiPortConvertPhysicalAddressToUlong(ConfigInfo->AccessRanges[0].RangeStart);
DPRINT(" CommandPortBase: %x\n", CommandPortBase);
// ControlPortBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart);
ControlPortBase = ScsiPortConvertPhysicalAddressToUlong(ConfigInfo->AccessRanges[1].RangeStart);
DPRINT(" ControlPortBase: %x\n", ControlPortBase);
for (UnitNumber = 0; UnitNumber < 2; UnitNumber++)
{
/* disable interrupts */
@ -634,9 +850,11 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
if (High == 0xEB && Low == 0x14)
{
if (AtapiIdentifyATAPIDevice(CommandPortBase,
UnitNumber,
&DeviceExtension->DeviceParams[UnitNumber]))
if (AtapiIdentifyDevice(CommandPortBase,
ControlPortBase,
UnitNumber,
TRUE,
&DeviceExtension->DeviceParams[UnitNumber]))
{
DPRINT(" ATAPI drive found!\n");
DeviceExtension->DevicePresent[UnitNumber] = TRUE;
@ -650,9 +868,11 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
}
else
{
if (AtapiIdentifyATADevice(CommandPortBase,
UnitNumber,
&DeviceExtension->DeviceParams[UnitNumber]))
if (AtapiIdentifyDevice(CommandPortBase,
ControlPortBase,
UnitNumber,
FALSE,
&DeviceExtension->DeviceParams[UnitNumber]))
{
DPRINT(" IDE drive found!\n");
DeviceExtension->DevicePresent[UnitNumber] = TRUE;
@ -726,7 +946,7 @@ AtapiResetController(IN WORD CommandPort,
}
// AtapiIdentifyATADevice
// AtapiIdentifyDevice
//
// DESCRIPTION:
// Get the identification block from the drive
@ -744,82 +964,22 @@ AtapiResetController(IN WORD CommandPort,
//
static BOOLEAN
AtapiIdentifyATADevice(IN ULONG CommandPort,
IN ULONG DriveNum,
OUT PIDE_DRIVE_IDENTIFY DrvParms)
AtapiIdentifyDevice(IN ULONG CommandPort,
IN ULONG ControlPort,
IN ULONG DriveNum,
IN BOOLEAN Atapi,
OUT PIDE_DRIVE_IDENTIFY DrvParms)
{
/* Get the Drive Identify block from drive or die */
if (AtapiPolledRead((WORD)CommandPort,
(WORD)ControlPort,
0,
1,
0,
0,
0,
(DriveNum ? IDE_DH_DRV1 : 0),
IDE_CMD_IDENT_ATA_DRV,
(BYTE *)DrvParms) != 0)
{
return FALSE;
}
/* Report on drive parameters if debug mode */
IDESwapBytePairs(DrvParms->SerialNumber, 20);
IDESwapBytePairs(DrvParms->FirmwareRev, 8);
IDESwapBytePairs(DrvParms->ModelNumber, 40);
DPRINT("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);
DPRINT("Bytes/PLO:%3d Vendor Cnt:%2d Serial number:[%.20s]\n",
DrvParms->BytesInPLO,
DrvParms->VendorUniqueCnt,
DrvParms->SerialNumber);
DPRINT("Cntlr type:%2d BufSiz:%5d ECC bytes:%3d Firmware Rev:[%.8s]\n",
DrvParms->ControllerType,
DrvParms->BufferSize * IDE_SECTOR_BUF_SZ,
DrvParms->ECCByteCnt,
DrvParms->FirmwareRev);
DPRINT("Model:[%.40s]\n", DrvParms->ModelNumber);
DPRINT("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);
DPRINT("TM:Cyls:%d Heads:%d Sectors/Trk:%d Capacity:%ld\n",
DrvParms->TMCylinders,
DrvParms->TMHeads,
DrvParms->TMSectorsPerTrk,
(ULONG)(DrvParms->TMCapacityLo + (DrvParms->TMCapacityHi << 16)));
DPRINT("TM:SectorCount: 0x%04x%04x = %lu\n",
DrvParms->TMSectorCountHi,
DrvParms->TMSectorCountLo,
(ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo));
DPRINT("BytesPerSector %d\n", DrvParms->BytesPerSector);
if (DrvParms->BytesPerSector == 0)
DrvParms->BytesPerSector = 512;
return TRUE;
}
static BOOLEAN
AtapiIdentifyATAPIDevice(IN ULONG CommandPort,
IN ULONG DriveNum,
OUT PIDE_DRIVE_IDENTIFY DrvParms)
{
/* Get the Drive Identify block from drive or die */
if (AtapiPolledRead((WORD)CommandPort,
0,
1,
0,
0,
0,
(DriveNum ? IDE_DH_DRV1 : 0),
IDE_CMD_IDENT_ATAPI_DRV,
(Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
(BYTE *)DrvParms) != 0) /* atapi_identify */
{
DPRINT1("IDEPolledRead() failed\n");
@ -864,7 +1024,8 @@ AtapiIdentifyATAPIDevice(IN ULONG CommandPort,
(ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo));
DPRINT("BytesPerSector %d\n", DrvParms->BytesPerSector);
// DrvParms->BytesPerSector = 512; /* FIXME !!!*/
if (DrvParms->BytesPerSector == 0)
DrvParms->BytesPerSector = 512;
return TRUE;
}
@ -894,6 +1055,7 @@ AtapiIdentifyATAPIDevice(IN ULONG CommandPort,
static int
AtapiPolledRead(IN WORD Address,
IN WORD ControlPort,
IN BYTE PreComp,
IN BYTE SectorCnt,
IN BYTE SectorNum,
@ -907,6 +1069,11 @@ AtapiPolledRead(IN WORD Address,
ULONG RetryCount;
BOOLEAN Junk = FALSE;
UCHAR Status;
UCHAR Control;
/* Disable interrupts */
Control = IDEReadAltStatus(ControlPort);
IDEWriteDriveControl(ControlPort, Control | IDE_DC_nIEN);
/* Wait for STATUS.BUSY and STATUS.DRQ to clear */
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
@ -982,6 +1149,7 @@ AtapiPolledRead(IN WORD Address,
{
if (Status & IDE_SR_ERR)
{
IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN);
return(IDE_ER_ABRT);
}
if (Status & IDE_SR_DRQ)
@ -990,6 +1158,7 @@ AtapiPolledRead(IN WORD Address,
}
else
{
IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN);
return(IDE_ER_ABRT);
}
}
@ -999,6 +1168,7 @@ AtapiPolledRead(IN WORD Address,
/* timed out */
if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN);
return(IDE_ER_ABRT);
}
@ -1025,6 +1195,7 @@ AtapiPolledRead(IN WORD Address,
{
if (Status & IDE_SR_ERR)
{
IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN);
return(IDE_ER_ABRT);
}
if (Status & IDE_SR_DRQ)
@ -1043,6 +1214,7 @@ AtapiPolledRead(IN WORD Address,
DPRINT("Read %lu sectors of junk!\n",
SectorCount - SectorCnt);
}
IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN);
return(0);
}
}
@ -1053,19 +1225,28 @@ AtapiPolledRead(IN WORD Address,
// ------------------------------------------- Nondiscardable statics
static ULONG
AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb);
{
DPRINT1("AtapiSendAtapiComamnd() called!\n");
DPRINT1("Not implemented yet!\n");
return(SRB_STATUS_SELECTION_TIMEOUT);
}
static ULONG
AtapiExecuteScsi(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb)
AtapiSendIdeCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb)
{
ULONG SrbStatus = SRB_STATUS_SUCCESS;
DPRINT1("AtapiExecuteScsi() called!\n");
DPRINT("AtapiSendIdeCommand() called!\n");
DPRINT1("PathId: %lu TargetId: %lu Lun: %lu\n",
Srb->PathId,
Srb->TargetId,
Srb->Lun);
DPRINT("PathId: %lu TargetId: %lu Lun: %lu\n",
Srb->PathId,
Srb->TargetId,
Srb->Lun);
switch (Srb->Cdb[0])
{
@ -1093,13 +1274,13 @@ AtapiExecuteScsi(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
break;
default:
DPRINT1("AtapiExecuteScsi():unknown command %x\n",
DPRINT1("AtapiSendIdeCommand():unknown command %x\n",
Srb->Cdb[0]);
SrbStatus = SRB_STATUS_INVALID_REQUEST;
break;
}
DPRINT1("AtapiExecuteScsi() done!\n");
DPRINT("AtapiSendIdeCommand() done!\n");
return(SrbStatus);
}
@ -1246,7 +1427,7 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
UCHAR Status;
DPRINT1("AtapiReadWrite() called!\n");
DPRINT("AtapiReadWrite() called!\n");
if ((Srb->PathId != 0) ||
(Srb->TargetId > 1) ||
@ -1256,8 +1437,8 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
return(SRB_STATUS_SELECTION_TIMEOUT);
}
DPRINT1("SCSIOP_WRITE: TargetId: %lu\n",
Srb->TargetId);
DPRINT("SCSIOP_WRITE: TargetId: %lu\n",
Srb->TargetId);
DeviceParams = &DeviceExtension->DeviceParams[Srb->TargetId];
@ -1270,10 +1451,10 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
SectorCount = (Srb->DataTransferLength + DeviceParams->BytesPerSector - 1) /
DeviceParams->BytesPerSector;
DPRINT1("Starting sector %lu Number of bytes %lu Sectors %lu\n",
StartingSector,
Srb->DataTransferLength,
SectorCount);
DPRINT("Starting sector %lu Number of bytes %lu Sectors %lu\n",
StartingSector,
Srb->DataTransferLength,
SectorCount);
if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED)
{
@ -1308,13 +1489,13 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
if (DrvHead & IDE_DH_LBA)
{
DPRINT1("%s:BUS=%04x:DRV=%d:LBA=1:BLK=%08d:SC=%02x:CM=%02x\n",
(Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE",
DeviceExtension->CommandPortBase,
DrvHead & IDE_DH_DRV1 ? 1 : 0,
((DrvHead & 0x0f) << 24) +
(CylinderHigh << 16) + (CylinderLow << 8) + SectorNumber,
SectorCount,
Command);
(Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE",
DeviceExtension->CommandPortBase,
DrvHead & IDE_DH_DRV1 ? 1 : 0,
((DrvHead & 0x0f) << 24) +
(CylinderHigh << 16) + (CylinderLow << 8) + SectorNumber,
SectorCount,
Command);
}
else
{
@ -1333,6 +1514,8 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
/* Set pointer to data buffer. */
DeviceExtension->DataBuffer = (PUSHORT)Srb->DataBuffer;
DeviceExtension->CurrentSrb = Srb;
DeviceExtension->ExpectingInterrupt = TRUE;
@ -1411,6 +1594,12 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
#endif
}
if (Command == IDE_CMD_WRITE)
{
DPRINT1("Write not implemented yet!\n");
return(SRB_STATUS_SUCCESS);
}
/* Indicate expecting an interrupt. */
DeviceExtension->ExpectingInterrupt = TRUE;
@ -1428,13 +1617,10 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
// ControllerExtension->TimerCount = IDE_CMD_TIMEOUT;
/* FIXME: Write data here! */
if (Srb->SrbFlags & SRB_FLAGS_DATA_IN == 0)
{
DPRINT1("Write not implemented yet!\n");
}
DPRINT1("AtapiReadWrite() done!\n");
DPRINT("AtapiReadWrite() done!\n");
/* Wait for interrupt. */
return(SRB_STATUS_PENDING);

View file

@ -113,6 +113,8 @@ extern "C" {
// Access macros for control registers
// Each macro takes an address of the control port blank and data
//
#define IDEReadAltStatus(Address) \
(ScsiPortReadPortUchar((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
#define IDEWriteDriveControl(Address, Data) \
(ScsiPortWritePortUchar((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))

View file

@ -1,4 +1,4 @@
/* $Id: class2.c,v 1.4 2002/01/31 14:57:58 ekohl Exp $
/* $Id: class2.c,v 1.5 2002/02/03 20:21:29 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -126,9 +126,11 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
// logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
startingBlock.QuadPart = startingOffset.QuadPart >> deviceExtension->SectorShift;
startingBlock.QuadPart = startingOffset.QuadPart / 512; // >> deviceExtension->SectorShift;
logicalBlockAddress = (ULONG)startingBlock.u.LowPart;
DPRINT1("Logical block address: %lu\n", logicalBlockAddress);
//
// Allocate an Srb.
//
@ -222,7 +224,7 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
MAXIMUM_CDB_SIZE);
Cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
//
// Move little endian values into CDB in big endian format.
@ -319,7 +321,7 @@ ScsiClassClaimDevice(PDEVICE_OBJECT PortDeviceObject,
PIRP Irp;
NTSTATUS Status;
DPRINT1("ScsiClassClaimDevice() called\n");
DPRINT("ScsiClassClaimDevice() called\n");
if (NewPortDeviceObject != NULL)
*NewPortDeviceObject = NULL;
@ -406,7 +408,7 @@ ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
UNICODE_STRING DeviceName;
NTSTATUS Status;
DPRINT1("ScsiClassCreateDeviceObject() called\n");
DPRINT("ScsiClassCreateDeviceObject() called\n");
*DeviceObject = NULL;
@ -421,7 +423,7 @@ ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
return(Status);
}
DPRINT1("Device name: '%wZ'\n", &DeviceName);
DPRINT("Device name: '%wZ'\n", &DeviceName);
Status = IoCreateDevice(DriverObject,
InitializationData->DeviceExtensionSize,
@ -432,7 +434,7 @@ ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
&InternalDeviceObject);
if (NT_SUCCESS(Status))
{
PDEVICE_EXTENSION deviceExtension = InternalDeviceObject->DeviceExtension;
DeviceExtension = InternalDeviceObject->DeviceExtension;
DeviceExtension->ClassError = InitializationData->ClassError;
DeviceExtension->ClassReadWriteVerification = InitializationData->ClassReadWriteVerification;
@ -696,7 +698,7 @@ ScsiClassInitialize(PVOID Argument1,
DPRINT("Status 0x%08lX\n", Status);
if (NT_SUCCESS(Status))
{
DPRINT1("ScsiPort%lu found.\n", PortNumber);
DPRINT("ScsiPort%lu found.\n", PortNumber);
/* Check scsi port for attached disk drives */
if (InitializationData->ClassFindDevices(DriverObject,
@ -710,9 +712,9 @@ ScsiClassInitialize(PVOID Argument1,
}
}
DPRINT("ScsiClassInitialize() done!\n");
for(;;);
DPRINT1("ScsiClassInitialize() done!\n");
// DPRINT1("** System stopped! **\n");
//for(;;);
return((DiskFound == TRUE) ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE);
}
@ -750,7 +752,7 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
DPRINT1("ScsiClassIoComplete() called\n");
DPRINT("ScsiClassIoComplete() called\n");
if (Irp->PendingReturned)
{
@ -798,7 +800,7 @@ ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
ULONG LastSector;
ULONG SectorSize;
DPRINT1("ScsiClassReadDriveCapacity() called\n");
DPRINT("ScsiClassReadDriveCapacity() called\n");
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@ -903,7 +905,7 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
NTSTATUS Status;
DPRINT1("ScsiClassSendSrbSynchronous() called\n");
DPRINT("ScsiClassSendSrbSynchronous() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
@ -1042,6 +1044,10 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
DeviceExtension = DeviceObject->DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT1("Relative Offset: %I64u Length: %lu\n",
IrpStack->Parameters.Read.ByteOffset.QuadPart,
IrpStack->Parameters.Read.Length);
TransferLength = IrpStack->Parameters.Read.Length;
@ -1118,7 +1124,7 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
ScsiClassBuildRequest(DeviceObject,
Irp);
DPRINT1("ScsiClassReadWrite() done\n");
DPRINT("ScsiClassReadWrite() done\n");
/* Call the port driver */
return(IoCallDriver(DeviceExtension->PortDeviceObject,
@ -1144,13 +1150,20 @@ static NTSTATUS STDCALL
ScsiClassDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("ScsiClassDeviceDispatch() called\n");
PDEVICE_EXTENSION DeviceExtension;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
DPRINT("ScsiClassDeviceDispatch() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
if (DeviceExtension->ClassDeviceControl)
{
return(DeviceExtension->ClassDeviceControl(DeviceObject, Irp));
}
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
return(STATUS_INVALID_DEVICE_REQUEST);
}
@ -1158,13 +1171,20 @@ static NTSTATUS STDCALL
ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("ScsiClassShutdownFlush() called\n");
PDEVICE_EXTENSION DeviceExtension;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
DPRINT("ScsiClassShutdownFlush() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
if (DeviceExtension->ClassShutdownFlush)
{
return(DeviceExtension->ClassShutdownFlush(DeviceObject, Irp));
}
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
return(STATUS_INVALID_DEVICE_REQUEST);
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: disk.c,v 1.4 2002/01/31 14:58:12 ekohl Exp $
/* $Id: disk.c,v 1.5 2002/02/03 20:21:45 ekohl Exp $
*
*/
@ -163,7 +163,7 @@ DiskClassFindDevices(PDRIVER_OBJECT DriverObject,
BOOLEAN FoundDevice;
NTSTATUS Status;
DPRINT1("DiskClassFindDevices() called.\n");
DPRINT("DiskClassFindDevices() called.\n");
/* Get port capabilities */
Status = ScsiClassGetCapabilities(PortDeviceObject,
@ -174,7 +174,7 @@ DiskClassFindDevices(PDRIVER_OBJECT DriverObject,
return(FALSE);
}
DPRINT1("MaximumTransferLength: %lu\n", PortCapabilities->MaximumTransferLength);
DPRINT("MaximumTransferLength: %lu\n", PortCapabilities->MaximumTransferLength);
/* Get inquiry data */
Status = ScsiClassGetInquiryData(PortDeviceObject,
@ -244,7 +244,7 @@ DiskClassFindDevices(PDRIVER_OBJECT DriverObject,
ExFreePool(Buffer);
ExFreePool(PortCapabilities);
DPRINT1("DiskClassFindDevices() done\n");
DPRINT("DiskClassFindDevices() done\n");
return(FoundDevice);
}
@ -283,7 +283,7 @@ NTSTATUS STDCALL
DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("DiskClassCheckReadWrite() called\n");
DPRINT("DiskClassCheckReadWrite() called\n");
return(STATUS_SUCCESS);
}
@ -328,24 +328,26 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
WCHAR NameBuffer[80];
CHAR NameBuffer2[80];
PDEVICE_OBJECT DiskDeviceObject;
PDEVICE_OBJECT PartitionDeviceObject;
PDEVICE_EXTENSION DiskDeviceExtension; /* defined in class2.h */
PDEVICE_EXTENSION PartitionDeviceExtension; /* defined in class2.h */
PDRIVE_LAYOUT_INFORMATION PartitionList = NULL;
HANDLE Handle;
#if 0
IDE_DRIVE_IDENTIFY DrvParms;
PDEVICE_OBJECT PartitionDeviceObject;
ULONG SectorCount = 0;
#endif
PPARTITION_INFORMATION PartitionEntry;
PDISK_DEVICE_EXTENSION DiskData;
ULONG PartitionNumber;
NTSTATUS Status;
DPRINT1("DiskClassCreateDeviceObjects() called\n");
WCHAR ArcNameBuffer[120];
UNICODE_STRING ArcName;
ANSI_STRING DeviceNameA;
UNICODE_STRING DeviceName;
DPRINT1("DiskClassCreateDeviceObject() called\n");
/* Create the harddisk device directory */
swprintf(NameBuffer,
L"\\Device\\Harddisk%d",
L"\\Device\\Harddisk%lu",
DiskNumber);
RtlInitUnicodeString(&UnicodeDeviceDirName,
NameBuffer);
@ -380,7 +382,7 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
/* Create disk device (Partition 0) */
sprintf(NameBuffer2,
"\\Device\\Harddisk%d\\Partition0",
"\\Device\\Harddisk%lu\\Partition0",
DiskNumber);
Status = ScsiClassCreateDeviceObject(DriverObject,
@ -418,6 +420,7 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
}
DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
// DiskData = (PDISK_DEVICE_EXTENSION)((PUCHAR)DiskDeviceExtension + sizeof(DEVICE_EXTENSION));
DiskDeviceExtension->LockCount = 0;
DiskDeviceExtension->DeviceNumber = DiskNumber;
@ -471,6 +474,30 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
DPRINT1("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector);
/* assign arc name */
RtlInitAnsiString(&DeviceNameA,
NameBuffer2);
RtlAnsiStringToUnicodeString(&DeviceName,
&DeviceNameA,
TRUE);
swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
DiskNumber);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT1("ArcNameBuffer '%S'\n", ArcNameBuffer);
DPRINT1("%wZ ==> %wZ\n", &ArcName, &DeviceName);
Status = IoAssignArcName(&ArcName,
&DeviceName);
RtlFreeUnicodeString(&DeviceName);
if (!NT_SUCCESS(Status))
{
DbgPrint("IoAssignArcName (%wZ) failed (Status %x)\n", &ArcName, Status);
KeBugCheck(0);
}
/* Read partition table */
Status = IoReadPartitionTable(DiskDeviceObject,
DiskDeviceExtension->DiskGeometry->BytesPerSector,
@ -523,33 +550,82 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
PartitionEntry->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
PartitionEntry->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
#if 0
/* Create device for partition */
Status = IDECreateDevice(DriverObject,
&PartitionDeviceObject,
ControllerObject,
DriveIdx,
HarddiskIdx,
&DrvParms,
PartitionEntry->PartitionNumber,
PartitionEntry->StartingOffset.QuadPart / 512 /* DrvParms.BytesPerSector*/,
PartitionEntry->PartitionLength.QuadPart / 512 /*DrvParms.BytesPerSector*/);
if (!NT_SUCCESS(Status))
{
DbgPrint("IDECreateDevice() failed\n");
break;
}
/* Create partition device (Partition 0) */
sprintf(NameBuffer2,
"\\Device\\Harddisk%lu\\Partition%lu",
DiskNumber,
PartitionNumber + 1);
/* Initialize pointer to disk device extension */
PartitionDeviceExtension = (PIDE_DEVICE_EXTENSION)PartitionDeviceObject->DeviceExtension;
PartitionDeviceExtension->DiskExtension = (PVOID)DiskDeviceExtension;
#endif
Status = ScsiClassCreateDeviceObject(DriverObject,
NameBuffer2,
DiskDeviceObject,
&PartitionDeviceObject,
InitializationData);
DPRINT1("ScsiClassCreateDeviceObject(): Status %x\n", Status);
if (NT_SUCCESS(Status))
{
PartitionDeviceObject->Flags = DiskDeviceObject->Flags;
PartitionDeviceObject->Characteristics = DiskDeviceObject->Characteristics;
PartitionDeviceObject->StackSize = DiskDeviceObject->StackSize;
PartitionDeviceObject->AlignmentRequirement = DiskDeviceObject->AlignmentRequirement;
PartitionDeviceExtension = PartitionDeviceObject->DeviceExtension;
PartitionDeviceExtension->LockCount = 0;
PartitionDeviceExtension->DeviceNumber = DiskNumber;
PartitionDeviceExtension->PortDeviceObject = PortDeviceObject;
/* FIXME: Not yet! Will cause pointer corruption! */
// PartitionDeviceExtension->PortCapabilities = PortCapabilities;
PartitionDeviceExtension->StartingOffset.QuadPart =
PartitionEntry->StartingOffset.QuadPart;
PartitionDeviceExtension->PartitionLength.QuadPart =
PartitionEntry->PartitionLength.QuadPart;
PartitionDeviceExtension->PortNumber = (UCHAR)PortNumber;
PartitionDeviceExtension->PathId = InquiryData->PathId;
PartitionDeviceExtension->TargetId = InquiryData->TargetId;
PartitionDeviceExtension->Lun = InquiryData->Lun;
/* assign arc name */
RtlInitAnsiString(&DeviceNameA,
NameBuffer2);
RtlAnsiStringToUnicodeString(&DeviceName,
&DeviceNameA,
TRUE);
swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
DiskNumber,
PartitionNumber + 1);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT1("ArcNameBuffer '%S'\n", ArcNameBuffer);
DPRINT1("%wZ ==> %wZ\n", &ArcName, &DeviceName);
Status = IoAssignArcName(&ArcName,
&DeviceName);
RtlFreeUnicodeString(&DeviceName);
if (!NT_SUCCESS(Status))
{
DbgPrint("IoAssignArcName (%wZ) failed (Status %x)\n", &ArcName, Status);
KeBugCheck(0);
}
}
else
{
DPRINT1("ScsiClassCreateDeviceObject() failed (Status %x)\n", Status);
break;
}
}
ExFreePool(PartitionList);
}
if (PartitionList != NULL)
ExFreePool(PartitionList);
DPRINT1("DiskClassCreateDeviceObjects() done\n");
return(STATUS_SUCCESS);
@ -578,34 +654,43 @@ NTSTATUS STDCALL
DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("DiskClassDeviceControl() called!\n");
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpStack;
ULONG ControlCode, InputLength, OutputLength;
NTSTATUS Status;
#if 0
NTSTATUS RC;
ULONG ControlCode, InputLength, OutputLength;
PIO_STACK_LOCATION IrpStack;
PIDE_DEVICE_EXTENSION DeviceExtension;
DPRINT1("DiskClassDeviceControl() called!\n");
RC = STATUS_SUCCESS;
Status = STATUS_SUCCESS;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
DeviceExtension = (PIDE_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
// A huge switch statement in a Windows program?! who would have thought?
switch (ControlCode)
/* A huge switch statement in a Windows program?! who would have thought? */
switch (ControlCode)
{
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
else
{
PDISK_GEOMETRY Geometry;
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
}
else
{
PDISK_GEOMETRY Geometry;
Geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
Geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
RtlMoveMemory(Geometry,
DeviceExtension->DiskGeometry,
sizeof(DISK_GEOMETRY));
#if 0
RtlCopyMemory(DiskData->Geometry,
DiskDeviceExtension->DiskGeometry,
sizeof(DISK_GEOMETRY));
Geometry->MediaType = FixedMedia;
// FIXME: should report for RawDevice even on partition
Geometry->Cylinders.QuadPart = DeviceExtension->Size /
@ -614,46 +699,41 @@ DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject,
DeviceExtension->SectorsPerLogCyl;
Geometry->SectorsPerTrack = DeviceExtension->SectorsPerLogTrk;
Geometry->BytesPerSector = DeviceExtension->BytesPerSector;
#endif
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
}
break;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
}
break;
case IOCTL_DISK_GET_PARTITION_INFO:
case IOCTL_DISK_SET_PARTITION_INFO:
case IOCTL_DISK_GET_DRIVE_LAYOUT:
case IOCTL_DISK_SET_DRIVE_LAYOUT:
case IOCTL_DISK_VERIFY:
case IOCTL_DISK_FORMAT_TRACKS:
case IOCTL_DISK_PERFORMANCE:
case IOCTL_DISK_IS_WRITABLE:
case IOCTL_DISK_LOGGING:
case IOCTL_DISK_FORMAT_TRACKS_EX:
case IOCTL_DISK_HISTOGRAM_STRUCTURE:
case IOCTL_DISK_HISTOGRAM_DATA:
case IOCTL_DISK_HISTOGRAM_RESET:
case IOCTL_DISK_REQUEST_STRUCTURE:
case IOCTL_DISK_REQUEST_DATA:
case IOCTL_DISK_GET_PARTITION_INFO:
case IOCTL_DISK_SET_PARTITION_INFO:
case IOCTL_DISK_GET_DRIVE_LAYOUT:
case IOCTL_DISK_SET_DRIVE_LAYOUT:
case IOCTL_DISK_VERIFY:
case IOCTL_DISK_FORMAT_TRACKS:
case IOCTL_DISK_PERFORMANCE:
case IOCTL_DISK_IS_WRITABLE:
case IOCTL_DISK_LOGGING:
case IOCTL_DISK_FORMAT_TRACKS_EX:
case IOCTL_DISK_HISTOGRAM_STRUCTURE:
case IOCTL_DISK_HISTOGRAM_DATA:
case IOCTL_DISK_HISTOGRAM_RESET:
case IOCTL_DISK_REQUEST_STRUCTURE:
case IOCTL_DISK_REQUEST_DATA:
// If we get here, something went wrong. inform the requestor
default:
RC = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = 0;
break;
/* If we get here, something went wrong. inform the requestor */
default:
DPRINT1("Unhandled control code: %lx\n", ControlCode);
Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
break;
}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return RC;
#endif
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
return(Status);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: scsiport.c,v 1.4 2002/01/31 14:58:52 ekohl Exp $
/* $Id: scsiport.c,v 1.5 2002/02/03 20:21:59 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -58,6 +58,7 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
ULONG PortBusInfoSize;
PSCSI_ADAPTER_BUS_INFO PortBusInfo;
PDEVICE_OBJECT DeviceObject;
PCONTROLLER_OBJECT ControllerObject;
PHW_STARTIO HwStartIo;
@ -113,6 +114,7 @@ typedef struct _SCSI_PORT_CONTROLLER_EXTENSION
LONG TimerCount;
PDEVICE_OBJECT PortDeviceObject;
PCONTROLLER_OBJECT ControllerObject;
} SCSI_PORT_CONTROLLER_EXTENSION, *PSCSI_PORT_CONTROLLER_EXTENSION;
@ -168,6 +170,8 @@ static VOID STDCALL
ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject,
PVOID Context);
static VOID
ScsiPortFinishOperation(PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension);
/* FUNCTIONS *****************************************************************/
@ -589,7 +593,27 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
IN PVOID HwDeviceExtension,
...)
{
UNIMPLEMENTED;
PSCSI_PORT_DEVICE_EXTENSION DevExt;
PSCSI_PORT_CONTROLLER_EXTENSION ControllerExt;
DPRINT1("ScsiPortNotification() called\n");
DevExt = (PSCSI_PORT_DEVICE_EXTENSION)((PUCHAR)HwDeviceExtension - sizeof(SCSI_PORT_DEVICE_EXTENSION));
ControllerExt = (PSCSI_PORT_CONTROLLER_EXTENSION)DevExt->ControllerObject->ControllerExtension;
switch (NotificationType)
{
case RequestComplete:
IoCompleteRequest(ControllerExt->CurrentIrp, IO_NO_INCREMENT);
break;
case NextRequest:
IoStartNextPacket(DevExt->DeviceObject, FALSE);
break;
default:
break;
}
}
@ -692,7 +716,7 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
ULONG DataSize = 0;
DPRINT1("ScsiPortDispatchScsi()\n");
DPRINT("ScsiPortDispatchScsi()\n");
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
@ -701,19 +725,19 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
{
case IOCTL_SCSI_EXECUTE_IN:
{
DPRINT1(" IOCTL_SCSI_EXECUTE_IN\n");
DPRINT(" IOCTL_SCSI_EXECUTE_IN\n");
}
break;
case IOCTL_SCSI_EXECUTE_OUT:
{
DPRINT1(" IOCTL_SCSI_EXECUTE_OUT\n");
DPRINT(" IOCTL_SCSI_EXECUTE_OUT\n");
}
break;
case IOCTL_SCSI_EXECUTE_NONE:
{
DPRINT1(" IOCTL_SCSI_EXECUTE_NONE\n");
DPRINT(" IOCTL_SCSI_EXECUTE_NONE\n");
}
break;
}
@ -869,7 +893,7 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
PIO_STACK_LOCATION Stack;
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT1("ScsiPortDeviceControl()\n");
DPRINT("ScsiPortDeviceControl()\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
@ -885,7 +909,7 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
{
PIO_SCSI_CAPABILITIES Capabilities;
DPRINT1(" IOCTL_SCSI_GET_CAPABILITIES\n");
DPRINT(" IOCTL_SCSI_GET_CAPABILITIES\n");
Capabilities = (PIO_SCSI_CAPABILITIES)Irp->AssociatedIrp.SystemBuffer;
Capabilities->Length = sizeof(IO_SCSI_CAPABILITIES);
@ -1013,7 +1037,7 @@ ScsiPortReadWrite(IN PDEVICE_OBJECT DeviceObject,
{
NTSTATUS Status;
DPRINT1("ScsiPortReadWrite() called!\n");
DPRINT("ScsiPortReadWrite() called!\n");
Status = STATUS_SUCCESS;
@ -1036,7 +1060,7 @@ ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
PIO_STACK_LOCATION IrpStack;
KIRQL OldIrql;
DPRINT1("ScsiPortStartIo() called!\n");
DPRINT("ScsiPortStartIo() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
@ -1050,54 +1074,37 @@ ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
BOOLEAN Result;
PSCSI_REQUEST_BLOCK Srb;
DPRINT1("IRP_MJ_SCSI\n");
DPRINT("IRP_MJ_SCSI\n");
Srb = IrpStack->Parameters.Scsi.Srb;
// Result = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
// Srb);
/* FIXME: Needs error handling! */
// if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_EXECUTE_OUT)
// DataSize = Srb->DataTransferLength;
DPRINT("DeviceExtension %p\n", DeviceExtension);
DPRINT("DeviceExtension->ControllerObject %p\n", DeviceExtension->ControllerObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Srb->DataTransferLength;
IoMarkIrpPending(Irp);
CHECKPOINT1;
KeRaiseIrql(DISPATCH_LEVEL,
&OldIrql);
CHECKPOINT1;
IoAllocateController(DeviceExtension->ControllerObject,
DeviceObject,
ScsiPortAllocateController,
Irp);
CHECKPOINT1;
KeLowerIrql(OldIrql);
CHECKPOINT1;
#if 0
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Srb->DataTransferLength;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
IoStartNextPacket(DeviceObject,
FALSE);
#endif
}
break;
default:
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
IoStartNextPacket(DeviceObject,
FALSE);
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
break;
}
DPRINT1("ScsiPortStartIo() done\n");
DPRINT("ScsiPortStartIo() done\n");
}
@ -1110,7 +1117,7 @@ ScsiPortAllocateController(IN PDEVICE_OBJECT DeviceObject,
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension;
DPRINT1("ScsiPortAllocateController() called\n");
DPRINT("ScsiPortAllocateController() called\n");
DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)
@ -1133,7 +1140,7 @@ ScsiPortStartController(IN OUT PVOID Context)
PIO_STACK_LOCATION IrpStack;
PSCSI_REQUEST_BLOCK Srb;
DPRINT1("ScsiPortStartController() called\n");
DPRINT("ScsiPortStartController() called\n");
DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION) Context;
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)
@ -1204,6 +1211,7 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
PseudoDeviceExtension->PortConfig.BusInterruptLevel,
&Dirql,
&Affinity);
#endif
ControllerObject = IoCreateController(sizeof(SCSI_PORT_CONTROLLER_EXTENSION));
if (ControllerObject == NULL)
@ -1212,11 +1220,11 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
PortNumber);
return(STATUS_NO_SUCH_DEVICE);
}
#endif
/* Fill out Controller extension data */
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)
ControllerObject->ControllerExtension;
ControllerExtension->ControllerObject = ControllerObject;
ControllerExtension->Number = PortNumber;
ControllerExtension->Vector = PseudoDeviceExtension->PortConfig.BusInterruptVector;
ControllerExtension->DMASupported = FALSE;
@ -1278,8 +1286,24 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
PortDeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
PortDeviceExtension = PortDeviceObject->DeviceExtension;
PortDeviceExtension->ControllerObject = ControllerObject;
/* Copy pseudo device extension into the real device extension */
memcpy(PortDeviceExtension,
PseudoDeviceExtension,
PseudoDeviceExtension->Length);
/* Copy access ranges */
AccessRangeSize =
sizeof(ACCESS_RANGE) * PseudoDeviceExtension->PortConfig.NumberOfAccessRanges;
PortDeviceExtension->PortConfig.AccessRanges = ExAllocatePool(NonPagedPool,
AccessRangeSize);
memcpy(PortDeviceExtension->PortConfig.AccessRanges,
PseudoDeviceExtension->PortConfig.AccessRanges,
AccessRangeSize);
/* Store pointers to controller object and port device object */
PortDeviceExtension->ControllerObject = ControllerObject;
PortDeviceExtension->DeviceObject = PortDeviceObject;
ControllerExtension->PortDeviceObject = PortDeviceObject;
/* Initialize the DPC object here */
@ -1296,20 +1320,6 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
ScsiPortIoTimer,
ControllerExtension);
/* Copy port configuration in device extension */
memcpy(PortDeviceExtension,
PseudoDeviceExtension,
PseudoDeviceExtension->Length);
/* Copy access ranges */
AccessRangeSize =
sizeof(ACCESS_RANGE) * PseudoDeviceExtension->PortConfig.NumberOfAccessRanges;
PortDeviceExtension->PortConfig.AccessRanges = ExAllocatePool(NonPagedPool,
AccessRangeSize);
memcpy(PortDeviceExtension->PortConfig.AccessRanges,
PseudoDeviceExtension->PortConfig.AccessRanges,
AccessRangeSize);
/* Initialize inquiry data */
PortDeviceExtension->PortBusInfoSize = 0;
PortDeviceExtension->PortBusInfo = NULL;
@ -1336,14 +1346,22 @@ ScsiPortIsr(IN PKINTERRUPT Interrupt,
{
PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension;
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
BOOLEAN Result;
DPRINT1("ScsiPortIsr() called!\n");
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)ServiceContext;
DeviceExtension = ControllerExtension->DeviceForOperation;
Result = DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension);
if (Result == FALSE)
{
return(FALSE);
}
IoRequestDpc(ControllerExtension->PortDeviceObject,
ControllerExtension->CurrentIrp,
ControllerExtension);
return(TRUE);
}
@ -1366,8 +1384,8 @@ ScsiPortDpcForIsr(IN PKDPC Dpc,
IN PIRP DpcIrp,
IN PVOID DpcContext)
{
DPRINT("ScsiPortDpcForIsr()\n");
// IDEFinishOperation((PIDE_CONTROLLER_EXTENSION) DpcContext);
DPRINT1("ScsiPortDpcForIsr()\n");
ScsiPortFinishOperation((PSCSI_PORT_CONTROLLER_EXTENSION) DpcContext);
}
@ -1389,4 +1407,44 @@ ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject,
DPRINT("ScsiPortIoTimer()\n");
}
static VOID
ScsiPortFinishOperation(PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PIRP Irp;
ULONG Operation;
DPRINT1("ScsiPortFinishOperation()\n");
DeviceExtension = ControllerExtension->DeviceForOperation;
Irp = ControllerExtension->CurrentIrp;
// Operation = DeviceExtension->Operation;
ControllerExtension->OperationInProgress = FALSE;
ControllerExtension->DeviceForOperation = NULL;
ControllerExtension->CurrentIrp = NULL;
/* Deallocate the controller */
IoFreeController(DeviceExtension->ControllerObject);
/* Issue completion of the current packet */
IoCompleteRequest(Irp,
IO_DISK_INCREMENT);
/* Start the next packet */
IoStartNextPacket(DeviceExtension->DeviceObject,
FALSE);
#if 0
/* Flush cache if necessary */
if (Operation == IRP_MJ_READ)
{
KeFlushIoBuffers(Irp->MdlAddress,
TRUE,
FALSE);
}
#endif
}
/* EOF */