mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:32:57 +00:00
Added more stuff to the IDENTIFY data block.
Added support for the TEST UNIT READY command. Combined various booleans in a flags variable. svn path=/trunk/; revision=4957
This commit is contained in:
parent
b6b732c937
commit
1b854f5f2a
2 changed files with 224 additions and 83 deletions
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: atapi.c,v 1.38 2003/04/06 10:45:15 chorns Exp $
|
/* $Id: atapi.c,v 1.39 2003/06/24 12:29:02 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS ATAPI miniport driver
|
* PROJECT: ReactOS ATAPI miniport driver
|
||||||
|
@ -74,12 +74,8 @@
|
||||||
typedef struct _ATAPI_MINIPORT_EXTENSION
|
typedef struct _ATAPI_MINIPORT_EXTENSION
|
||||||
{
|
{
|
||||||
IDE_DRIVE_IDENTIFY DeviceParams[2];
|
IDE_DRIVE_IDENTIFY DeviceParams[2];
|
||||||
BOOLEAN DevicePresent[2];
|
ULONG DeviceFlags[2];
|
||||||
BOOLEAN DeviceAtapi[2];
|
|
||||||
ULONG TransferSize[2];
|
ULONG TransferSize[2];
|
||||||
BOOLEAN MultiSectorCommand[2];
|
|
||||||
BOOLEAN DWordIo[2];
|
|
||||||
|
|
||||||
|
|
||||||
ULONG CommandPortBase;
|
ULONG CommandPortBase;
|
||||||
ULONG ControlPortBase;
|
ULONG ControlPortBase;
|
||||||
|
@ -93,6 +89,14 @@ typedef struct _ATAPI_MINIPORT_EXTENSION
|
||||||
ULONG DataTransferLength;
|
ULONG DataTransferLength;
|
||||||
} ATAPI_MINIPORT_EXTENSION, *PATAPI_MINIPORT_EXTENSION;
|
} 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
|
typedef struct _UNIT_EXTENSION
|
||||||
{
|
{
|
||||||
|
@ -237,6 +241,10 @@ static ULONG
|
||||||
AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
PSCSI_REQUEST_BLOCK Srb);
|
PSCSI_REQUEST_BLOCK Srb);
|
||||||
|
|
||||||
|
static ULONG
|
||||||
|
AtapiTestUnitReady(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
|
PSCSI_REQUEST_BLOCK Srb);
|
||||||
|
|
||||||
static UCHAR
|
static UCHAR
|
||||||
AtapiErrorToScsi(PVOID DeviceExtension,
|
AtapiErrorToScsi(PVOID DeviceExtension,
|
||||||
PSCSI_REQUEST_BLOCK Srb);
|
PSCSI_REQUEST_BLOCK Srb);
|
||||||
|
@ -830,7 +838,7 @@ AtapiStartIo(IN PVOID DeviceExtension,
|
||||||
{
|
{
|
||||||
case SRB_FUNCTION_EXECUTE_SCSI:
|
case SRB_FUNCTION_EXECUTE_SCSI:
|
||||||
DevExt->CurrentSrb = Srb;
|
DevExt->CurrentSrb = Srb;
|
||||||
if (DevExt->DeviceAtapi[Srb->TargetId] == TRUE)
|
if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI)
|
||||||
{
|
{
|
||||||
Result = AtapiSendAtapiCommand(DevExt,
|
Result = AtapiSendAtapiCommand(DevExt,
|
||||||
Srb);
|
Srb);
|
||||||
|
@ -915,7 +923,7 @@ AtapiInterrupt(IN PVOID DeviceExtension)
|
||||||
|
|
||||||
DPRINT("CommandPortBase: %lx ControlPortBase: %lx\n", CommandPortBase, ControlPortBase);
|
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");
|
DPRINT("IsAtapi == %s\n", (IsAtapi) ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
IsLastBlock = FALSE;
|
IsLastBlock = FALSE;
|
||||||
|
@ -978,7 +986,7 @@ AtapiInterrupt(IN PVOID DeviceExtension)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the block of data */
|
/* Copy the block of data */
|
||||||
if (DevExt->DWordIo[Srb->TargetId])
|
if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_DWORD_IO)
|
||||||
{
|
{
|
||||||
IDEReadBlock32(CommandPortBase,
|
IDEReadBlock32(CommandPortBase,
|
||||||
TargetAddress,
|
TargetAddress,
|
||||||
|
@ -990,6 +998,7 @@ AtapiInterrupt(IN PVOID DeviceExtension)
|
||||||
TargetAddress,
|
TargetAddress,
|
||||||
TransferSize);
|
TransferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check DRQ */
|
/* check DRQ */
|
||||||
if (IsLastBlock)
|
if (IsLastBlock)
|
||||||
{
|
{
|
||||||
|
@ -1043,7 +1052,7 @@ AtapiInterrupt(IN PVOID DeviceExtension)
|
||||||
DevExt->DataTransferLength -= TransferSize;
|
DevExt->DataTransferLength -= TransferSize;
|
||||||
|
|
||||||
/* Write the sector */
|
/* Write the sector */
|
||||||
if (DevExt->DWordIo[Srb->TargetId])
|
if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_DWORD_IO)
|
||||||
{
|
{
|
||||||
IDEWriteBlock32(CommandPortBase,
|
IDEWriteBlock32(CommandPortBase,
|
||||||
TargetAddress,
|
TargetAddress,
|
||||||
|
@ -1179,7 +1188,7 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
if (Retries >= 20000)
|
if (Retries >= 20000)
|
||||||
{
|
{
|
||||||
DPRINT("Timeout on drive %lu\n", UnitNumber);
|
DPRINT("Timeout on drive %lu\n", UnitNumber);
|
||||||
DeviceExtension->DevicePresent[UnitNumber] = FALSE;
|
DeviceExtension->DeviceFlags[UnitNumber] &= ~DEVICE_PRESENT;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,11 +1209,10 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
&DeviceExtension->DeviceParams[UnitNumber]))
|
&DeviceExtension->DeviceParams[UnitNumber]))
|
||||||
{
|
{
|
||||||
DPRINT(" ATAPI drive found!\n");
|
DPRINT(" ATAPI drive found!\n");
|
||||||
DeviceExtension->DevicePresent[UnitNumber] = TRUE;
|
DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_PRESENT;
|
||||||
DeviceExtension->DeviceAtapi[UnitNumber] = TRUE;
|
DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_ATAPI;
|
||||||
DeviceExtension->TransferSize[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].BytesPerSector;
|
DeviceExtension->TransferSize[UnitNumber] =
|
||||||
DeviceExtension->MultiSectorCommand[UnitNumber] = FALSE;
|
DeviceExtension->DeviceParams[UnitNumber].BytesPerSector;
|
||||||
DeviceExtension->DWordIo[UnitNumber] = FALSE;
|
|
||||||
DeviceFound = TRUE;
|
DeviceFound = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1221,8 +1229,7 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
&DeviceExtension->DeviceParams[UnitNumber]))
|
&DeviceExtension->DeviceParams[UnitNumber]))
|
||||||
{
|
{
|
||||||
DPRINT(" IDE drive found!\n");
|
DPRINT(" IDE drive found!\n");
|
||||||
DeviceExtension->DevicePresent[UnitNumber] = TRUE;
|
DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_PRESENT;
|
||||||
DeviceExtension->DeviceAtapi[UnitNumber] = FALSE;
|
|
||||||
DeviceExtension->TransferSize[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].BytesPerSector;
|
DeviceExtension->TransferSize[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].BytesPerSector;
|
||||||
if ((DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0x8000) &&
|
if ((DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0x8000) &&
|
||||||
(DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0xff) &&
|
(DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0xff) &&
|
||||||
|
@ -1230,13 +1237,14 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
(DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff))
|
(DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff))
|
||||||
{
|
{
|
||||||
DeviceExtension->TransferSize[UnitNumber] *= (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff);
|
DeviceExtension->TransferSize[UnitNumber] *= (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff);
|
||||||
DeviceExtension->MultiSectorCommand[UnitNumber] = TRUE;
|
DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_MULTI_SECTOR_CMD;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (DeviceExtension->DeviceParams[UnitNumber].DWordIo)
|
||||||
{
|
{
|
||||||
DeviceExtension->MultiSectorCommand[UnitNumber] = FALSE;
|
DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_DWORD_IO;
|
||||||
}
|
}
|
||||||
DeviceExtension->DWordIo[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].DWordIo ? TRUE : FALSE;
|
|
||||||
DeviceFound = TRUE;
|
DeviceFound = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1677,7 +1685,7 @@ AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
return(SRB_STATUS_INVALID_LUN);
|
return(SRB_STATUS_INVALID_LUN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE)
|
if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT))
|
||||||
{
|
{
|
||||||
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
||||||
return(SRB_STATUS_NO_DEVICE);
|
return(SRB_STATUS_NO_DEVICE);
|
||||||
|
@ -1823,8 +1831,12 @@ AtapiSendIdeCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
Srb);
|
Srb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSIOP_MODE_SENSE:
|
|
||||||
case SCSIOP_TEST_UNIT_READY:
|
case SCSIOP_TEST_UNIT_READY:
|
||||||
|
SrbStatus = AtapiTestUnitReady(DeviceExtension,
|
||||||
|
Srb);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSIOP_MODE_SENSE:
|
||||||
case SCSIOP_VERIFY:
|
case SCSIOP_VERIFY:
|
||||||
case SCSIOP_START_STOP_UNIT:
|
case SCSIOP_START_STOP_UNIT:
|
||||||
case SCSIOP_REQUEST_SENSE:
|
case SCSIOP_REQUEST_SENSE:
|
||||||
|
@ -1872,7 +1884,7 @@ AtapiInquiry(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
return(SRB_STATUS_INVALID_LUN);
|
return(SRB_STATUS_INVALID_LUN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE)
|
if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT))
|
||||||
{
|
{
|
||||||
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
||||||
return(SRB_STATUS_NO_DEVICE);
|
return(SRB_STATUS_NO_DEVICE);
|
||||||
|
@ -1888,17 +1900,17 @@ AtapiInquiry(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set device class */
|
/* set device class */
|
||||||
if (DeviceExtension->DeviceAtapi[Srb->TargetId] == FALSE)
|
if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI)
|
||||||
{
|
|
||||||
/* hard-disk */
|
|
||||||
InquiryData->DeviceType = DIRECT_ACCESS_DEVICE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* get it from the ATAPI configuration word */
|
/* get it from the ATAPI configuration word */
|
||||||
InquiryData->DeviceType = (DeviceParams->ConfigBits >> 8) & 0x1F;
|
InquiryData->DeviceType = (DeviceParams->ConfigBits >> 8) & 0x1F;
|
||||||
DPRINT("Device class: %u\n", InquiryData->DeviceType);
|
DPRINT("Device class: %u\n", InquiryData->DeviceType);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* hard-disk */
|
||||||
|
InquiryData->DeviceType = DIRECT_ACCESS_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("ConfigBits: 0x%x\n", DeviceParams->ConfigBits);
|
DPRINT("ConfigBits: 0x%x\n", DeviceParams->ConfigBits);
|
||||||
if (DeviceParams->ConfigBits & 0x80)
|
if (DeviceParams->ConfigBits & 0x80)
|
||||||
|
@ -1963,7 +1975,7 @@ AtapiReadCapacity(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
return(SRB_STATUS_INVALID_LUN);
|
return(SRB_STATUS_INVALID_LUN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE)
|
if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT))
|
||||||
{
|
{
|
||||||
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
||||||
return(SRB_STATUS_NO_DEVICE);
|
return(SRB_STATUS_NO_DEVICE);
|
||||||
|
@ -2038,7 +2050,7 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
return(SRB_STATUS_INVALID_LUN);
|
return(SRB_STATUS_INVALID_LUN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE)
|
if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT))
|
||||||
{
|
{
|
||||||
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
||||||
return(SRB_STATUS_NO_DEVICE);
|
return(SRB_STATUS_NO_DEVICE);
|
||||||
|
@ -2086,11 +2098,11 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
|
|
||||||
if (Srb->SrbFlags & SRB_FLAGS_DATA_IN)
|
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
|
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)
|
if (DrvHead & IDE_DH_LBA)
|
||||||
|
@ -2214,7 +2226,7 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
DeviceExtension->DataTransferLength -= TransferSize;
|
DeviceExtension->DataTransferLength -= TransferSize;
|
||||||
|
|
||||||
/* Write data block */
|
/* Write data block */
|
||||||
if (DeviceExtension->DWordIo[Srb->TargetId])
|
if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_DWORD_IO)
|
||||||
{
|
{
|
||||||
IDEWriteBlock32(DeviceExtension->CommandPortBase,
|
IDEWriteBlock32(DeviceExtension->CommandPortBase,
|
||||||
TargetAddress,
|
TargetAddress,
|
||||||
|
@ -2262,7 +2274,7 @@ AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
return(SRB_STATUS_INVALID_LUN);
|
return(SRB_STATUS_INVALID_LUN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE)
|
if (!(DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT))
|
||||||
{
|
{
|
||||||
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
||||||
return(SRB_STATUS_NO_DEVICE);
|
return(SRB_STATUS_NO_DEVICE);
|
||||||
|
@ -2323,6 +2335,116 @@ AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ULONG
|
||||||
|
AtapiTestUnitReady(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
||||||
|
PSCSI_REQUEST_BLOCK Srb)
|
||||||
|
{
|
||||||
|
ULONG Retries;
|
||||||
|
UCHAR Status;
|
||||||
|
UCHAR Error;
|
||||||
|
|
||||||
|
DPRINT1("AtapiTestUnitReady() 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->DeviceFlags[Srb->TargetId] & DEVICE_PRESENT))
|
||||||
|
{
|
||||||
|
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
||||||
|
return(SRB_STATUS_NO_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
Status = IDEReadStatus(DeviceExtension->CommandPortBase);
|
||||||
|
if (!(Status & IDE_SR_BUSY))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ScsiPortStallExecution(10);
|
||||||
|
}
|
||||||
|
DPRINT1("Status=%02x\n", Status);
|
||||||
|
DPRINT1("Waited %ld usecs for busy to clear\n", Retries * 10);
|
||||||
|
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||||
|
{
|
||||||
|
DPRINT1("Drive is BUSY for too long\n");
|
||||||
|
return(SRB_STATUS_BUSY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_GET_MEDIA_STATUS);
|
||||||
|
|
||||||
|
/* Wait for controller ready */
|
||||||
|
for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++)
|
||||||
|
{
|
||||||
|
Status = IDEReadStatus(DeviceExtension->CommandPortBase);
|
||||||
|
if (!(Status & IDE_SR_BUSY) || (Status & IDE_SR_ERR))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
KeStallExecutionProcessor(10);
|
||||||
|
}
|
||||||
|
if (Retries >= IDE_MAX_WRITE_RETRIES)
|
||||||
|
{
|
||||||
|
DPRINT1("Drive is BUSY for too long after sending write command\n");
|
||||||
|
return(SRB_STATUS_BUSY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status & IDE_SR_ERR)
|
||||||
|
{
|
||||||
|
Error = IDEReadError(DeviceExtension->CommandPortBase);
|
||||||
|
if (Error == IDE_ER_UNC)
|
||||||
|
{
|
||||||
|
/* Handle write protection 'error' */
|
||||||
|
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||||
|
return(SRB_STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Indicate expecting an interrupt. */
|
||||||
|
DeviceExtension->ExpectingInterrupt = TRUE;
|
||||||
|
return(SRB_STATUS_PENDING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("AtapiTestUnitReady() done!\n");
|
||||||
|
|
||||||
|
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||||
|
return(SRB_STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static UCHAR
|
static UCHAR
|
||||||
AtapiErrorToScsi(PVOID DeviceExtension,
|
AtapiErrorToScsi(PVOID DeviceExtension,
|
||||||
PSCSI_REQUEST_BLOCK Srb)
|
PSCSI_REQUEST_BLOCK Srb)
|
||||||
|
@ -2343,7 +2465,7 @@ AtapiErrorToScsi(PVOID DeviceExtension,
|
||||||
|
|
||||||
ErrorReg = IDEReadError(CommandPortBase);
|
ErrorReg = IDEReadError(CommandPortBase);
|
||||||
|
|
||||||
if (DevExt->DeviceAtapi[Srb->TargetId])
|
if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI)
|
||||||
{
|
{
|
||||||
switch (ErrorReg >> 4)
|
switch (ErrorReg >> 4)
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,6 +75,7 @@ extern "C" {
|
||||||
#define IDE_CMD_FLUSH_CACHE_EXT 0xEA
|
#define IDE_CMD_FLUSH_CACHE_EXT 0xEA
|
||||||
#define IDE_CMD_IDENT_ATA_DRV 0xEC
|
#define IDE_CMD_IDENT_ATA_DRV 0xEC
|
||||||
#define IDE_CMD_IDENT_ATAPI_DRV 0xA1
|
#define IDE_CMD_IDENT_ATAPI_DRV 0xA1
|
||||||
|
#define IDE_CMD_GET_MEDIA_STATUS 0xDA
|
||||||
|
|
||||||
//
|
//
|
||||||
// Access macros for command registers
|
// Access macros for command registers
|
||||||
|
@ -179,7 +180,25 @@ typedef struct _IDE_DRIVE_IDENTIFY
|
||||||
WORD RWMultCurrent; /*59*/
|
WORD RWMultCurrent; /*59*/
|
||||||
WORD TMSectorCountLo; /*60*/
|
WORD TMSectorCountLo; /*60*/
|
||||||
WORD TMSectorCountHi; /*61*/
|
WORD TMSectorCountHi; /*61*/
|
||||||
WORD Reserved62[193]; /*62*/
|
WORD DmaModes; /*62*/
|
||||||
|
WORD MultiDmaModes; /*63*/
|
||||||
|
WORD Reserved64[5]; /*64*/
|
||||||
|
WORD Reserved69[2]; /*69*/
|
||||||
|
WORD Reserved71[4]; /*71*/
|
||||||
|
WORD MaxQueueDepth; /*75*/
|
||||||
|
WORD Reserved76[4]; /*79*/
|
||||||
|
WORD MajorRevision; /*80*/
|
||||||
|
WORD MinorRevision; /*81*/
|
||||||
|
WORD SupportedFeatures82; /*82*/
|
||||||
|
WORD SupportedFeatures83; /*83*/
|
||||||
|
WORD SupportedFeatures84; /*84*/
|
||||||
|
WORD EnabledFeatures85; /*85*/
|
||||||
|
WORD EnabledFeatures86; /*86*/
|
||||||
|
WORD EnabledFeatures87; /*87*/
|
||||||
|
WORD UltraDmaModes; /*88*/
|
||||||
|
WORD Reserved89[11]; /*89*/
|
||||||
|
WORD Max48BitAddress[4]; /*100*/
|
||||||
|
WORD Reserved104[151]; /*104*/
|
||||||
WORD Checksum; /*255*/
|
WORD Checksum; /*255*/
|
||||||
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
|
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue