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;
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
{
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
{
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);
}
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;
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");
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;
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;
}
!(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++)
/* 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;
}
}
if (Retries >= 20000)
{
DPRINT("Timeout on drive %lu\n", UnitNumber);
- DeviceExtension->DevicePresent[UnitNumber] = FALSE;
+ DeviceExtension->DeviceFlags[UnitNumber] &= ~DEVICE_PRESENT;
continue;
}
&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
&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
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);
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);
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:
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:
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];
}
/* 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)
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];
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);
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)
/* 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");
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++)
{
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;
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);
}
ErrorReg = IDEReadError(CommandPortBase);
- if (DevExt->DeviceAtapi[Srb->TargetId])
+ if (DevExt->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI)
{
switch (ErrorReg >> 4)
{
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 */