diff --git a/reactos/drivers/storage/atapi/atapi.c b/reactos/drivers/storage/atapi/atapi.c index 4713cdd8193..2148f42696e 100644 --- a/reactos/drivers/storage/atapi/atapi.c +++ b/reactos/drivers/storage/atapi/atapi.c @@ -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); diff --git a/reactos/drivers/storage/atapi/atapi.h b/reactos/drivers/storage/atapi/atapi.h index 2886ae74f1e..a1fb47be6de 100644 --- a/reactos/drivers/storage/atapi/atapi.h +++ b/reactos/drivers/storage/atapi/atapi.h @@ -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))) diff --git a/reactos/drivers/storage/class2/class2.c b/reactos/drivers/storage/class2/class2.c index 0ea7816f151..b2cd6cf0e78 100644 --- a/reactos/drivers/storage/class2/class2.c +++ b/reactos/drivers/storage/class2/class2.c @@ -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 */ diff --git a/reactos/drivers/storage/disk/disk.c b/reactos/drivers/storage/disk/disk.c index 9c44fb4769f..425b68d07a9 100644 --- a/reactos/drivers/storage/disk/disk.c +++ b/reactos/drivers/storage/disk/disk.c @@ -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); } diff --git a/reactos/drivers/storage/scsiport/scsiport.c b/reactos/drivers/storage/scsiport/scsiport.c index 85439173f07..78b552690bb 100644 --- a/reactos/drivers/storage/scsiport/scsiport.c +++ b/reactos/drivers/storage/scsiport/scsiport.c @@ -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 */