X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=drivers%2Fstorage%2Fatapi%2Fatapi.c;h=c42d750ba6061542321bf19c9f5ad80a0e992fdc;hp=e54042662ddf8fa7d2a8d43e31039e3f592b5056;hb=HEAD;hpb=7c0db166f81fbe8c8b913d7f26048e337d383605 diff --git a/drivers/storage/atapi/atapi.c b/drivers/storage/atapi/atapi.c index e540426..c42d750 100644 --- a/drivers/storage/atapi/atapi.c +++ b/drivers/storage/atapi/atapi.c @@ -74,12 +74,8 @@ typedef struct _ATAPI_MINIPORT_EXTENSION { IDE_DRIVE_IDENTIFY DeviceParams[2]; - BOOLEAN DevicePresent[2]; - BOOLEAN DeviceAtapi[2]; - ULONG TransferSize[2]; - BOOLEAN MultiSectorCommand[2]; - BOOLEAN DWordIo[2]; - + ULONG DeviceFlags[2]; + ULONG TransferSize[2]; ULONG CommandPortBase; ULONG ControlPortBase; @@ -93,6 +89,14 @@ typedef struct _ATAPI_MINIPORT_EXTENSION ULONG DataTransferLength; } ATAPI_MINIPORT_EXTENSION, *PATAPI_MINIPORT_EXTENSION; +/* DeviceFlags */ +#define DEVICE_PRESENT 0x00000001 +#define DEVICE_ATAPI 0x00000002 +#define DEVICE_MULTI_SECTOR_CMD 0x00000004 +#define DEVICE_DWORD_IO 0x00000008 +#define DEVICE_48BIT_ADDRESS 0x00000010 +#define DEVICE_MEDIA_STATUS 0x00000020 + typedef struct _UNIT_EXTENSION { @@ -237,10 +241,17 @@ static ULONG AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension, PSCSI_REQUEST_BLOCK Srb); +static ULONG +AtapiTestUnitReady(PATAPI_MINIPORT_EXTENSION DeviceExtension, + PSCSI_REQUEST_BLOCK Srb); + static UCHAR AtapiErrorToScsi(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb); +static VOID +AtapiScsiSrbToAtapi (PSCSI_REQUEST_BLOCK Srb); + // ---------------------------------------------------------------- Inlines void @@ -830,7 +841,7 @@ AtapiStartIo(IN PVOID DeviceExtension, { case SRB_FUNCTION_EXECUTE_SCSI: DevExt->CurrentSrb = Srb; - if (DevExt->DeviceAtapi[Srb->TargetId] == TRUE) + if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI) { Result = AtapiSendAtapiCommand(DevExt, Srb); @@ -842,6 +853,20 @@ AtapiStartIo(IN PVOID DeviceExtension, } break; + case SRB_FUNCTION_ABORT_COMMAND: + if (DevExt->CurrentSrb != NULL) + { + Result = SRB_STATUS_ABORT_FAILED; + } + else + { + Result = SRB_STATUS_SUCCESS; + } + break; + + default: + Result = SRB_STATUS_INVALID_REQUEST; + break; } Srb->SrbStatus = Result; @@ -877,13 +902,14 @@ AtapiInterrupt(IN PVOID DeviceExtension) PSCSI_REQUEST_BLOCK Srb; ULONG CommandPortBase; ULONG ControlPortBase; - UCHAR DeviceStatus; BOOLEAN IsLastBlock; BOOLEAN IsAtapi; ULONG Retries; PUCHAR TargetAddress; ULONG TransferSize; + ULONG JunkSize; + USHORT Junk; DPRINT("AtapiInterrupt() called!\n"); @@ -915,7 +941,7 @@ AtapiInterrupt(IN PVOID DeviceExtension) DPRINT("CommandPortBase: %lx ControlPortBase: %lx\n", CommandPortBase, ControlPortBase); - IsAtapi = DevExt->DeviceAtapi[Srb->TargetId]; + IsAtapi = (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI); DPRINT("IsAtapi == %s\n", (IsAtapi) ? "TRUE" : "FALSE"); IsLastBlock = FALSE; @@ -954,10 +980,16 @@ AtapiInterrupt(IN PVOID DeviceExtension) if (DevExt->DataTransferLength <= TransferSize) { - if (!IsAtapi) - { - TransferSize = DevExt->DataTransferLength; - } + JunkSize = TransferSize - DevExt->DataTransferLength; + TransferSize = DevExt->DataTransferLength; + +#ifndef NDEBUG + if (JunkSize > 0) + { + DPRINT1("Junk data: %lu bytes\n", JunkSize); + } +#endif + DevExt->DataTransferLength = 0; IsLastBlock = TRUE; } @@ -974,25 +1006,35 @@ AtapiInterrupt(IN PVOID DeviceExtension) !(IDEReadStatus(CommandPortBase) & IDE_SR_DRQ); Retries++) { - KeStallExecutionProcessor(10); + KeStallExecutionProcessor(10); } /* Copy the block of data */ - if (DevExt->DWordIo[Srb->TargetId]) - { - IDEReadBlock32(CommandPortBase, - TargetAddress, - TransferSize); - } + if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_DWORD_IO) + { + IDEReadBlock32(CommandPortBase, + TargetAddress, + TransferSize); + } else - { - IDEReadBlock(CommandPortBase, - TargetAddress, - TransferSize); - } + { + IDEReadBlock(CommandPortBase, + TargetAddress, + TransferSize); + } + /* check DRQ */ if (IsLastBlock) { + /* Read remaining junk from device */ + while (JunkSize > 0) + { + IDEReadBlock(CommandPortBase, + &Junk, + 2); + JunkSize -= 2; + } + for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES && (IDEReadStatus(CommandPortBase) & IDE_SR_BUSY); Retries++) @@ -1034,35 +1076,35 @@ AtapiInterrupt(IN PVOID DeviceExtension) /* Update DevExt data */ TransferSize = DevExt->TransferSize[Srb->TargetId]; if (DevExt->DataTransferLength < TransferSize) - { - TransferSize = DevExt->DataTransferLength; - } - + { + TransferSize = DevExt->DataTransferLength; + } + TargetAddress = DevExt->DataBuffer; DevExt->DataBuffer += TransferSize; DevExt->DataTransferLength -= TransferSize; /* Write the sector */ - if (DevExt->DWordIo[Srb->TargetId]) - { - IDEWriteBlock32(CommandPortBase, - TargetAddress, - TransferSize); - } + if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_DWORD_IO) + { + IDEWriteBlock32(CommandPortBase, + TargetAddress, + TransferSize); + } else - { - IDEWriteBlock(CommandPortBase, - TargetAddress, - TransferSize); - } + { + IDEWriteBlock(CommandPortBase, + TargetAddress, + TransferSize); + } } Srb->SrbStatus = SRB_STATUS_SUCCESS; } else { - DPRINT1("Unspecified transfer direction!\n"); - Srb->SrbStatus = SRB_STATUS_SUCCESS; // SRB_STATUS_ERROR; + DPRINT("Unspecified transfer direction!\n"); + Srb->SrbStatus = SRB_STATUS_SUCCESS; IsLastBlock = TRUE; } } @@ -1179,7 +1221,7 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension, if (Retries >= 20000) { DPRINT("Timeout on drive %lu\n", UnitNumber); - DeviceExtension->DevicePresent[UnitNumber] = FALSE; + DeviceExtension->DeviceFlags[UnitNumber] &= ~DEVICE_PRESENT; continue; } @@ -1200,11 +1242,10 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension, &DeviceExtension->DeviceParams[UnitNumber])) { DPRINT(" ATAPI drive found!\n"); - DeviceExtension->DevicePresent[UnitNumber] = TRUE; - DeviceExtension->DeviceAtapi[UnitNumber] = TRUE; - DeviceExtension->TransferSize[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].BytesPerSector; - DeviceExtension->MultiSectorCommand[UnitNumber] = FALSE; - DeviceExtension->DWordIo[UnitNumber] = FALSE; + DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_PRESENT; + DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_ATAPI; + DeviceExtension->TransferSize[UnitNumber] = + DeviceExtension->DeviceParams[UnitNumber].BytesPerSector; DeviceFound = TRUE; } else @@ -1221,22 +1262,22 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension, &DeviceExtension->DeviceParams[UnitNumber])) { DPRINT(" IDE drive found!\n"); - DeviceExtension->DevicePresent[UnitNumber] = TRUE; - DeviceExtension->DeviceAtapi[UnitNumber] = FALSE; + DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_PRESENT; DeviceExtension->TransferSize[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].BytesPerSector; if ((DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0x8000) && (DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0xff) && (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0x100) && (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff)) - { - DeviceExtension->TransferSize[UnitNumber] *= (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff); - DeviceExtension->MultiSectorCommand[UnitNumber] = TRUE; - } - else - { - DeviceExtension->MultiSectorCommand[UnitNumber] = FALSE; - } - DeviceExtension->DWordIo[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].DWordIo ? TRUE : FALSE; + { + DeviceExtension->TransferSize[UnitNumber] *= (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff); + DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_MULTI_SECTOR_CMD; + } + + if (DeviceExtension->DeviceParams[UnitNumber].DWordIo) + { + DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_DWORD_IO; + } + DeviceFound = TRUE; } else @@ -1677,7 +1718,7 @@ AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, return(SRB_STATUS_INVALID_LUN); } - if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE) + if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT)) { Srb->SrbStatus = SRB_STATUS_NO_DEVICE; return(SRB_STATUS_NO_DEVICE); @@ -1771,6 +1812,16 @@ AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, ScsiPortStallExecution(10); } + /* Convert special SCSI SRBs to ATAPI format */ + switch (Srb->Cdb[0]) + { + case SCSIOP_FORMAT_UNIT: + case SCSIOP_MODE_SELECT: + case SCSIOP_MODE_SENSE: + AtapiScsiSrbToAtapi (Srb); + break; + } + CdbSize = (DeviceExtension->DeviceParams[Srb->TargetId].ConfigBits & 0x3 == 1) ? 16 : 12; DPRINT("CdbSize: %lu\n", CdbSize); @@ -1800,6 +1851,30 @@ AtapiSendIdeCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, Srb->TargetId, Srb->Lun); + if (Srb->PathId != 0) + { + Srb->SrbStatus = SRB_STATUS_INVALID_PATH_ID; + return(SRB_STATUS_INVALID_PATH_ID); + } + + if (Srb->TargetId > 1) + { + Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; + return(SRB_STATUS_INVALID_TARGET_ID); + } + + if (Srb->Lun != 0) + { + Srb->SrbStatus = SRB_STATUS_INVALID_LUN; + return(SRB_STATUS_INVALID_LUN); + } + + if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT)) + { + Srb->SrbStatus = SRB_STATUS_NO_DEVICE; + return(SRB_STATUS_NO_DEVICE); + } + switch (Srb->Cdb[0]) { case SCSIOP_INQUIRY: @@ -1823,8 +1898,13 @@ AtapiSendIdeCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, Srb); break; - case SCSIOP_MODE_SENSE: case SCSIOP_TEST_UNIT_READY: + SrbStatus = AtapiTestUnitReady(DeviceExtension, + Srb); + break; + + case SCSIOP_MODE_SENSE: + case SCSIOP_VERIFY: case SCSIOP_START_STOP_UNIT: case SCSIOP_REQUEST_SENSE: @@ -1854,30 +1934,6 @@ AtapiInquiry(PATAPI_MINIPORT_EXTENSION DeviceExtension, DPRINT("SCSIOP_INQUIRY: DeviceExtension %p TargetId: %lu\n", DeviceExtension, Srb->TargetId); - if (Srb->PathId != 0) - { - Srb->SrbStatus = SRB_STATUS_INVALID_PATH_ID; - return(SRB_STATUS_INVALID_PATH_ID); - } - - if (Srb->TargetId > 1) - { - Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; - return(SRB_STATUS_INVALID_TARGET_ID); - } - - if (Srb->Lun != 0) - { - Srb->SrbStatus = SRB_STATUS_INVALID_LUN; - return(SRB_STATUS_INVALID_LUN); - } - - if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE) - { - Srb->SrbStatus = SRB_STATUS_NO_DEVICE; - return(SRB_STATUS_NO_DEVICE); - } - InquiryData = Srb->DataBuffer; DeviceParams = &DeviceExtension->DeviceParams[Srb->TargetId]; @@ -1888,17 +1944,17 @@ AtapiInquiry(PATAPI_MINIPORT_EXTENSION DeviceExtension, } /* set device class */ - if (DeviceExtension->DeviceAtapi[Srb->TargetId] == FALSE) - { - /* hard-disk */ - InquiryData->DeviceType = DIRECT_ACCESS_DEVICE; - } - else + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI) { /* get it from the ATAPI configuration word */ InquiryData->DeviceType = (DeviceParams->ConfigBits >> 8) & 0x1F; DPRINT("Device class: %u\n", InquiryData->DeviceType); } + else + { + /* hard-disk */ + InquiryData->DeviceType = DIRECT_ACCESS_DEVICE; + } DPRINT("ConfigBits: 0x%x\n", DeviceParams->ConfigBits); if (DeviceParams->ConfigBits & 0x80) @@ -1944,31 +2000,6 @@ AtapiReadCapacity(PATAPI_MINIPORT_EXTENSION DeviceExtension, ULONG LastSector; DPRINT("SCSIOP_READ_CAPACITY: TargetId: %lu\n", Srb->TargetId); - - if (Srb->PathId != 0) - { - Srb->SrbStatus = SRB_STATUS_INVALID_PATH_ID; - return(SRB_STATUS_INVALID_PATH_ID); - } - - if (Srb->TargetId > 1) - { - Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; - return(SRB_STATUS_INVALID_TARGET_ID); - } - - if (Srb->Lun != 0) - { - Srb->SrbStatus = SRB_STATUS_INVALID_LUN; - return(SRB_STATUS_INVALID_LUN); - } - - if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE) - { - Srb->SrbStatus = SRB_STATUS_NO_DEVICE; - return(SRB_STATUS_NO_DEVICE); - } - CapacityData = (PREAD_CAPACITY_DATA)Srb->DataBuffer; DeviceParams = &DeviceExtension->DeviceParams[Srb->TargetId]; @@ -2019,31 +2050,6 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, UCHAR Status; DPRINT("AtapiReadWrite() called!\n"); - - if (Srb->PathId != 0) - { - Srb->SrbStatus = SRB_STATUS_INVALID_PATH_ID; - return(SRB_STATUS_INVALID_PATH_ID); - } - - if (Srb->TargetId > 1) - { - Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; - return(SRB_STATUS_INVALID_TARGET_ID); - } - - if (Srb->Lun != 0) - { - Srb->SrbStatus = SRB_STATUS_INVALID_LUN; - return(SRB_STATUS_INVALID_LUN); - } - - if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE) - { - Srb->SrbStatus = SRB_STATUS_NO_DEVICE; - return(SRB_STATUS_NO_DEVICE); - } - DPRINT("SCSIOP_WRITE: TargetId: %lu\n", Srb->TargetId); @@ -2086,11 +2092,11 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) { - Command = DeviceExtension->MultiSectorCommand[Srb->TargetId] ? IDE_CMD_READ_MULTIPLE : IDE_CMD_READ; + Command = (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_MULTI_SECTOR_CMD) ? IDE_CMD_READ_MULTIPLE : IDE_CMD_READ; } else { - Command = DeviceExtension->MultiSectorCommand[Srb->TargetId] ? IDE_CMD_WRITE_MULTIPLE : IDE_CMD_WRITE; + Command = (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_MULTI_SECTOR_CMD) ? IDE_CMD_WRITE_MULTIPLE : IDE_CMD_WRITE; } if (DrvHead & IDE_DH_LBA) @@ -2205,27 +2211,27 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, /* Update DeviceExtension data */ TransferSize = DeviceExtension->TransferSize[Srb->TargetId]; if (DeviceExtension->DataTransferLength < TransferSize) - { - TransferSize = DeviceExtension->DataTransferLength; - } + { + TransferSize = DeviceExtension->DataTransferLength; + } TargetAddress = DeviceExtension->DataBuffer; DeviceExtension->DataBuffer += TransferSize; DeviceExtension->DataTransferLength -= TransferSize; /* Write data block */ - if (DeviceExtension->DWordIo[Srb->TargetId]) - { - IDEWriteBlock32(DeviceExtension->CommandPortBase, - TargetAddress, - TransferSize); - } + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_DWORD_IO) + { + IDEWriteBlock32(DeviceExtension->CommandPortBase, + TargetAddress, + TransferSize); + } else - { - IDEWriteBlock(DeviceExtension->CommandPortBase, - TargetAddress, - TransferSize); - } + { + IDEWriteBlock(DeviceExtension->CommandPortBase, + TargetAddress, + TransferSize); + } } DPRINT("AtapiReadWrite() done!\n"); @@ -2242,35 +2248,82 @@ AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension, ULONG Retries; UCHAR Status; - DPRINT1("AtapiFlushCache() called!\n"); + DPRINT("AtapiFlushCache() called!\n"); + DPRINT("SCSIOP_SYNCRONIZE_CACHE: TargetId: %lu\n", + Srb->TargetId); - if (Srb->PathId != 0) + /* Wait for BUSY to clear */ + for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++) { - Srb->SrbStatus = SRB_STATUS_INVALID_PATH_ID; - return(SRB_STATUS_INVALID_PATH_ID); + Status = IDEReadStatus(DeviceExtension->CommandPortBase); + if (!(Status & IDE_SR_BUSY)) + { + break; + } + ScsiPortStallExecution(10); } - - if (Srb->TargetId > 1) + DPRINT("Status=%02x\n", Status); + DPRINT("Waited %ld usecs for busy to clear\n", Retries * 10); + if (Retries >= IDE_MAX_BUSY_RETRIES) { - Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; - return(SRB_STATUS_INVALID_TARGET_ID); + DPRINT1("Drive is BUSY for too long\n"); + return(SRB_STATUS_BUSY); } - if (Srb->Lun != 0) + /* Select the desired drive */ + IDEWriteDriveHead(DeviceExtension->CommandPortBase, + IDE_DH_FIXED | (Srb->TargetId ? IDE_DH_DRV1 : 0)); + ScsiPortStallExecution(10); + + /* Issue command to drive */ + IDEWriteCommand(DeviceExtension->CommandPortBase, IDE_CMD_FLUSH_CACHE); + + /* Wait for controller ready */ + for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++) { - Srb->SrbStatus = SRB_STATUS_INVALID_LUN; - return(SRB_STATUS_INVALID_LUN); + BYTE Status = IDEReadStatus(DeviceExtension->CommandPortBase); + if (!(Status & IDE_SR_BUSY) || (Status & IDE_SR_ERR)) + { + break; + } + KeStallExecutionProcessor(10); } - - if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE) + if (Retries >= IDE_MAX_WRITE_RETRIES) { - Srb->SrbStatus = SRB_STATUS_NO_DEVICE; - return(SRB_STATUS_NO_DEVICE); + DPRINT1("Drive is BUSY for too long after sending write command\n"); + return(SRB_STATUS_BUSY); } - DPRINT1("SCSIOP_SYNCRONIZE_CACHE: TargetId: %lu\n", + /* Indicate expecting an interrupt. */ + DeviceExtension->ExpectingInterrupt = TRUE; + + DPRINT("AtapiFlushCache() done!\n"); + + /* Wait for interrupt. */ + return(SRB_STATUS_PENDING); +} + + +static ULONG +AtapiTestUnitReady(PATAPI_MINIPORT_EXTENSION DeviceExtension, + PSCSI_REQUEST_BLOCK Srb) +{ + ULONG Retries; + UCHAR Status; + UCHAR Error; + + DPRINT1("AtapiTestUnitReady() called!\n"); + + DPRINT1("SCSIOP_TEST_UNIT_READY: TargetId: %lu\n", Srb->TargetId); + /* Return success if media status is not supported */ + if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_MEDIA_STATUS)) + { + Srb->SrbStatus = SRB_STATUS_SUCCESS; + return(SRB_STATUS_SUCCESS); + } + /* Wait for BUSY to clear */ for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++) { @@ -2295,12 +2348,12 @@ AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension, ScsiPortStallExecution(10); /* Issue command to drive */ - IDEWriteCommand(DeviceExtension->CommandPortBase, IDE_CMD_FLUSH_CACHE); + IDEWriteCommand(DeviceExtension->CommandPortBase, IDE_CMD_GET_MEDIA_STATUS); /* Wait for controller ready */ for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++) { - BYTE Status = IDEReadStatus(DeviceExtension->CommandPortBase); + Status = IDEReadStatus(DeviceExtension->CommandPortBase); if (!(Status & IDE_SR_BUSY) || (Status & IDE_SR_ERR)) { break; @@ -2313,13 +2366,29 @@ AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension, return(SRB_STATUS_BUSY); } - /* Indicate expecting an interrupt. */ - DeviceExtension->ExpectingInterrupt = TRUE; + if (Status & IDE_SR_ERR) + { + Error = IDEReadError(DeviceExtension->CommandPortBase); + if (Error == IDE_ER_UNC) + { +CHECKPOINT1; + /* Handle write protection 'error' */ + Srb->SrbStatus = SRB_STATUS_SUCCESS; + return(SRB_STATUS_SUCCESS); + } + else + { +CHECKPOINT1; + /* Indicate expecting an interrupt. */ + DeviceExtension->ExpectingInterrupt = TRUE; + return(SRB_STATUS_PENDING); + } + } - DPRINT1("AtapiFlushCache() done!\n"); + DPRINT1("AtapiTestUnitReady() done!\n"); - /* Wait for interrupt. */ - return(SRB_STATUS_PENDING); + Srb->SrbStatus = SRB_STATUS_SUCCESS; + return(SRB_STATUS_SUCCESS); } @@ -2343,7 +2412,7 @@ AtapiErrorToScsi(PVOID DeviceExtension, ErrorReg = IDEReadError(CommandPortBase); - if (DevExt->DeviceAtapi[Srb->TargetId]) + if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI) { switch (ErrorReg >> 4) { @@ -2449,4 +2518,56 @@ AtapiErrorToScsi(PVOID DeviceExtension, return(SrbStatus); } + +static VOID +AtapiScsiSrbToAtapi (PSCSI_REQUEST_BLOCK Srb) +{ + DPRINT("AtapiConvertScsiToAtapi() called\n"); + + Srb->CdbLength = 12; + + switch (Srb->Cdb[0]) + { + case SCSIOP_FORMAT_UNIT: + Srb->Cdb[0] = ATAPI_FORMAT_UNIT; + break; + + case SCSIOP_MODE_SELECT: + { + PATAPI_MODE_SELECT12 AtapiModeSelect; + UCHAR Length; + + AtapiModeSelect = (PATAPI_MODE_SELECT12)Srb->Cdb; + Length = ((PCDB)Srb->Cdb)->MODE_SELECT.ParameterListLength; + + RtlZeroMemory (Srb->Cdb, + MAXIMUM_CDB_SIZE); + AtapiModeSelect->OperationCode = ATAPI_MODE_SELECT; + AtapiModeSelect->PFBit = 1; + AtapiModeSelect->ParameterListLengthMsb = 0; + AtapiModeSelect->ParameterListLengthLsb = Length; + } + break; + + case SCSIOP_MODE_SENSE: + { + PATAPI_MODE_SENSE12 AtapiModeSense; + UCHAR PageCode; + UCHAR Length; + + AtapiModeSense = (PATAPI_MODE_SENSE12)Srb->Cdb; + PageCode = ((PCDB)Srb->Cdb)->MODE_SENSE.PageCode; + Length = ((PCDB)Srb->Cdb)->MODE_SENSE.AllocationLength; + + RtlZeroMemory (Srb->Cdb, + MAXIMUM_CDB_SIZE); + AtapiModeSense->OperationCode = ATAPI_MODE_SENSE; + AtapiModeSense->PageCode = PageCode; + AtapiModeSense->ParameterListLengthMsb = 0; + AtapiModeSense->ParameterListLengthLsb = Length; + } + break; + } +} + /* EOF */