Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3676 lines
111 KiB

/*++
Copyright (c) 1994 Arcada Software Inc. - All rights reserved
Module Name:
4mmsony.c
Abstract:
This module contains device-specific routines for 4mm DAT drives:
SONY SDT-2000, SONY SDT-4000, SDT-5000, and SDT-5200.
Author:
Mike Colandreo (Arcada Software)
Environment:
kernel mode only
Revision History:
$Log$
--*/
#include "minitape.h"
#include "4mmdat.h"
//
// Internal (module wide) defines that symbolize
// the 4mm DAT drives supported by this module.
//
#define SONY_SDT2000 31
#define SONY_SDT4000 32
#define SONY_SDT5000 33
#define SONY_SDT5200 34
//
// Internal (module wide) defines that symbolize
// the 4mm DAT drives supported by this module.
//
#define AIWA_GD201 1
#define ARCHIVE_PYTHON 2
#define ARCHIVE_IBM4326 3
#define ARCHIVE_4326 4
#define ARCHIVE_4322 5
#define ARCHIVE_4586 6
#define DEC_TLZ06 7
#define DEC_TLZ07 8
#define EXABYTE_4200 9
#define EXABYTE_4200C 10
#define HP_35470A 11
#define HP_35480A 12
#define HP_C1533A 13
#define HP_C1553A 14
#define HP_IBM35480A 15
#define IOMEGA_DAT4000 16
#define WANGDAT_1300 17
#define WANGDAT_3100 18
#define WANGDAT_3200 19
#define WANGDAT_3300DX 20
#define WANGDAT_3400DX 21
//
// Internal (module wide) defines that symbolize
// various 4mm DAT "partitioned" states.
//
#define NOT_PARTITIONED 0 // must be zero -- != 0 means partitioned
#define SELECT_PARTITIONED 1
#define INITIATOR_PARTITIONED 2
#define FIXED_PARTITIONED 3
//
// Internal (module wide) define that symbolizes
// the 4mm DAT "no partitions" partition method.
//
#define NO_PARTITIONS 0xFFFFFFFF
//
// Function prototype(s) for internal function(s)
//
static ULONG WhichIsIt(IN PINQUIRYDATA InquiryData);
//
// Minitape extension definition.
//
typedef struct _MINITAPE_EXTENSION {
ULONG DriveID ;
ULONG CurrentPartition ;
} MINITAPE_EXTENSION, *PMINITAPE_EXTENSION ;
//
// Command extension definition.
//
typedef struct _COMMAND_EXTENSION {
ULONG CurrentState;
} COMMAND_EXTENSION, *PCOMMAND_EXTENSION;
BOOLEAN
LocalAllocatePartPage(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_MEDIUM_PARTITION_PAGE *MediumPartPage,
OUT PULONG bufferSize
);
VOID
LocalGetPartPageData(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_MEDIUM_PARTITION_PAGE *MediumPartPage,
OUT PULONG bufferSize
) ;
BOOLEAN
LocalAllocateConfigPage(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DEVICE_CONFIGURATION_PAGE *DeviceConfigPage,
OUT PULONG bufferSize
) ;
VOID
LocalGetConfigPageData(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DEVICE_CONFIGURATION_PAGE *DeviceConfigPage,
OUT PULONG bufferSize
) ;
BOOLEAN
LocalAllocateCompressPage(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DATA_COMPRESSION_PAGE *CompressPage,
OUT PULONG bufferSize
) ;
VOID
LocalGetCompressPageData(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DATA_COMPRESSION_PAGE *CompressPage,
OUT PULONG bufferSize
) ;
BOOLEAN
VerifyInquiry(
IN PINQUIRYDATA InquiryData,
IN PMODE_CAPABILITIES_PAGE ModeCapabilitiesPage
);
VOID
ExtensionInit(
OUT PVOID MinitapeExtension,
IN PINQUIRYDATA InquiryData,
IN PMODE_CAPABILITIES_PAGE ModeCapabilitiesPage
);
TAPE_STATUS
CreatePartition(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
Erase(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
GetDriveParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
GetMediaParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
GetPosition(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
GetStatus(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
Prepare(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
SetDriveParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
SetMediaParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
SetPosition(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
TAPE_STATUS
WriteMarks(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
);
VOID
TapeError(
IN OUT PVOID MinitapeExtension,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT TAPE_STATUS *LastError
);
ULONG
DriverEntry(
IN PVOID Argument1,
IN PVOID Argument2
)
/*++
Routine Description:
Driver entry point for tape minitape driver.
Arguments:
Argument1 - Supplies the first argument.
Argument2 - Supplies the second argument.
Return Value:
Status from TapeClassInitialize()
--*/
{
TAPE_INIT_DATA tapeInitData;
TapeClassZeroMemory( &tapeInitData, sizeof(TAPE_INIT_DATA));
tapeInitData.VerifyInquiry = VerifyInquiry;
tapeInitData.QueryModeCapabilitiesPage = FALSE ;
tapeInitData.MinitapeExtensionSize = sizeof(MINITAPE_EXTENSION);
tapeInitData.ExtensionInit = ExtensionInit;
tapeInitData.DefaultTimeOutValue = 360;
tapeInitData.TapeError = TapeError ;
tapeInitData.CommandExtensionSize = sizeof(COMMAND_EXTENSION);
tapeInitData.CreatePartition = CreatePartition;
tapeInitData.Erase = Erase;
tapeInitData.GetDriveParameters = GetDriveParameters;
tapeInitData.GetMediaParameters = GetMediaParameters;
tapeInitData.GetPosition = GetPosition;
tapeInitData.GetStatus = GetStatus;
tapeInitData.Prepare = Prepare;
tapeInitData.SetDriveParameters = SetDriveParameters;
tapeInitData.SetMediaParameters = SetMediaParameters;
tapeInitData.SetPosition = SetPosition;
tapeInitData.WriteMarks = WriteMarks;
return TapeClassInitialize(Argument1, Argument2, &tapeInitData);
}
BOOLEAN
VerifyInquiry(
IN PINQUIRYDATA InquiryData,
IN PMODE_CAPABILITIES_PAGE ModeCapabilitiesPage
)
/*++
Routine Description:
This routine examines the given inquiry data to determine whether
or not the given device is one that may be controller by this driver.
Arguments:
InquiryData - Supplies the SCSI inquiry data.
Return Value:
FALSE - This driver does not recognize the given device.
TRUE - This driver recognizes the given device.
--*/
{
return WhichIsIt(InquiryData) ? TRUE : FALSE;
}
VOID
ExtensionInit(
OUT PVOID MinitapeExtension,
IN PINQUIRYDATA InquiryData,
IN PMODE_CAPABILITIES_PAGE ModeCapabilitiesPage
)
/*++
Routine Description:
This routine is called at driver initialization time to
initialize the minitape extension.
Arguments:
MinitapeExtension - Supplies the minitape extension.
Return Value:
None.
--*/
{
PMINITAPE_EXTENSION extension = MinitapeExtension;
extension->DriveID = WhichIsIt(InquiryData);
extension->CurrentPartition = 0 ;
}
TAPE_STATUS
CreatePartition(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Create Partition requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PTAPE_CREATE_PARTITION tapeCreatePartition = CommandParameters;
PMODE_PARM_READ_WRITE_DATA modeBuffer;
PMINITAPE_EXTENSION tapeExtension = MinitapeExtension ;
PCOMMAND_EXTENSION tapeCmdExtension = CommandExtension ;
PCDB cdb = (PCDB)Srb->Cdb;
PMODE_DEVICE_CONFIG_PAGE deviceConfigModeSenseBuffer;
PMODE_MEDIUM_PART_PAGE modeSelectBuffer;
ULONG modeSelectLength;
ULONG partitionMethod;
ULONG partitionCount;
ULONG partition;
PMODE_PARAMETER_HEADER ParameterListHeader; // List Header Format
PMODE_PARAMETER_BLOCK ParameterListBlock; // List Block Descriptor
PMODE_MEDIUM_PARTITION_PAGE MediumPartPage;
PMODE_DEVICE_CONFIGURATION_PAGE DeviceConfigPage;
ULONG bufferSize ;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"CreatePartition: Enter routine\n"));
if (CallNumber == 0) {
return TAPE_STATUS_CHECK_TEST_UNIT_READY ;
}
if (CallNumber == 1) {
if (!LocalAllocatePartPage(Srb,
tapeExtension,
&ParameterListHeader,
&ParameterListBlock,
&MediumPartPage,
&bufferSize ) ) {
DebugPrint((1,"TapeCreatePartition: insufficient resources (ModeSel buffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.AllocationLength = (UCHAR)bufferSize;
cdb->MODE_SENSE.PageCode = MODE_PAGE_MEDIUM_PARTITION;
switch (tapeExtension->DriveID) {
//
// The Sony drives must return Block descriptors.
//
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
cdb->MODE_SENSE.Dbd = 0;
break;
default:
cdb->MODE_SENSE.Dbd = 1;
//
// Subtract off last partition size entry.
//
cdb->MODE_SENSE.AllocationLength -= 2;
break;
}
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeCreatePartition: SendSrb (mode sense)\n"));
Srb->DataTransferLength = cdb->MODE_SENSE.AllocationLength ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if ( CallNumber == 2 ) {
LocalGetPartPageData(Srb,
tapeExtension,
&ParameterListHeader,
&ParameterListBlock,
&MediumPartPage,
&bufferSize ) ;
partitionMethod = tapeCreatePartition->Method;
partitionCount = tapeCreatePartition->Count;
//
// Filter out invalid partition counts.
//
switch (partitionCount) {
case 0:
partitionMethod = NO_PARTITIONS;
break;
case 1:
case 2:
break;
default:
return TAPE_STATUS_INVALID_DEVICE_REQUEST;
break;
}
//
// Filter out partition methods that are
// not implemented on the various drives.
//
switch (partitionMethod) {
case TAPE_FIXED_PARTITIONS:
DebugPrint((3,"TapeCreatePartition: fixed partitions\n"));
switch (tapeExtension->DriveID) {
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
partitionCount = 1;
break;
default:
return TAPE_STATUS_NOT_IMPLEMENTED;
break;
}
break;
case TAPE_SELECT_PARTITIONS:
DebugPrint((3,"TapeCreatePartition: select partitions\n"));
switch (tapeExtension->DriveID) {
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
if (--partitionCount == 0) {
DebugPrint((3,"TapeCreatePartition: no partitions\n"));
partitionMethod = NO_PARTITIONS;
}
break;
default:
return TAPE_STATUS_NOT_IMPLEMENTED;
break;
}
break;
case TAPE_INITIATOR_PARTITIONS:
DebugPrint((3,"TapeCreatePartition: initiator partitions\n"));
if (--partitionCount == 0) {
DebugPrint((3,"TapeCreatePartition: no partitions\n"));
partitionMethod = NO_PARTITIONS;
}
break;
case NO_PARTITIONS:
DebugPrint((3,"TapeCreatePartition: no partitions\n"));
partitionCount = 0;
break;
default:
DebugPrint((1,"partitionMethod -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
break;
}
ParameterListHeader->ModeDataLength = 0;
ParameterListHeader->MediumType = 0;
ParameterListHeader->DeviceSpecificParameter = 0x10;
if (ParameterListBlock) {
ParameterListHeader->BlockDescriptorLength = 0x08;
} else {
ParameterListHeader->BlockDescriptorLength = 0;
}
MediumPartPage->PageCode = MODE_PAGE_MEDIUM_PARTITION;
MediumPartPage->PageLength = partitionCount? 8 : 6;
MediumPartPage->MaximumAdditionalPartitions = 0;
MediumPartPage->AdditionalPartitionDefined = (UCHAR)partitionCount;
MediumPartPage->MediumFormatRecognition = 3;
switch (partitionMethod) {
case TAPE_FIXED_PARTITIONS:
MediumPartPage->FDPBit = SETBITON;
switch (tapeExtension->DriveID) {
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
MediumPartPage->PageLength = 10;
break;
default:
// we already returned not implmented....
MediumPartPage->PageLength = 6;
break;
}
partition = FIXED_PARTITIONED;
break;
case TAPE_SELECT_PARTITIONS:
MediumPartPage->SDPBit = SETBITON;
switch (tapeExtension->DriveID) {
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
MediumPartPage->PageLength = 10;
break;
default:
// we already returned not implmented....
MediumPartPage->PageLength = 6;
break;
}
partition = SELECT_PARTITIONED;
break;
case TAPE_INITIATOR_PARTITIONS:
MediumPartPage->IDPBit = SETBITON;
MediumPartPage->PSUMBit = 2;
switch (tapeExtension->DriveID) {
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
MediumPartPage->PageLength = 10;
if (partitionCount) {
MediumPartPage->Partition1Size[0] = (UCHAR)((tapeCreatePartition->Size >> 8) & 0xFF);
MediumPartPage->Partition1Size[1] = (UCHAR)(tapeCreatePartition->Size & 0xFF);
}
break;
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
MediumPartPage->PageLength = 10;
if (partitionCount) {
MediumPartPage->Partition0Size[0] = 0;
MediumPartPage->Partition0Size[1] = 0;
}
// fall throuth
default:
//
// Subtract out Parition1Size
//
bufferSize -= 2;
if (partitionCount) {
MediumPartPage->Partition0Size[0] = (UCHAR)((tapeCreatePartition->Size >> 8) & 0xFF);
MediumPartPage->Partition0Size[1] = (UCHAR)(tapeCreatePartition->Size & 0xFF);
}
break;
}
partition = INITIATOR_PARTITIONED;
break;
case NO_PARTITIONS:
switch (tapeExtension->DriveID) {
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
switch (tapeCreatePartition->Method) {
case TAPE_FIXED_PARTITIONS:
MediumPartPage->FDPBit = SETBITON;
break;
case TAPE_SELECT_PARTITIONS:
MediumPartPage->SDPBit = SETBITON;
break;
case TAPE_INITIATOR_PARTITIONS:
MediumPartPage->IDPBit = SETBITON;
MediumPartPage->PSUMBit = 2;
break;
}
MediumPartPage->PageLength = 10;
break;
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
MediumPartPage->PageLength = 10;
MediumPartPage->MaximumAdditionalPartitions = 0;
// fall throuth
default:
MediumPartPage->IDPBit = SETBITON;
MediumPartPage->PSUMBit = 2;
break;
}
partition = NOT_PARTITIONED;
break;
}
Srb->CdbLength = CDB6GENERIC_LENGTH ;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
cdb->MODE_SELECT.PFBit = SETBITON;
cdb->MODE_SELECT.ParameterListLength = (UCHAR)bufferSize;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeCreatePartition: SendSrb (mode select)\n"));
Srb->TimeOutValue = 16500;
Srb->DataTransferLength = bufferSize;
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT ;
//
// save partition value for successful completion....
//
tapeCmdExtension->CurrentState = partition ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if ( CallNumber == 3 ) {
partition = tapeCmdExtension->CurrentState;
if (partition == NOT_PARTITIONED) {
tapeExtension->CurrentPartition = partition ;
return TAPE_STATUS_SUCCESS ;
}
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
if (!LocalAllocateConfigPage(Srb,
tapeExtension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ) {
DebugPrint((1,"TapeCreatePartition: insufficient resources (DevConfig buffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
cdb->MODE_SENSE.AllocationLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeCreatePartition: SendSrb (mode sense)\n"));
Srb->DataTransferLength = bufferSize ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if ( CallNumber == 4 ) {
LocalGetConfigPageData(Srb,
tapeExtension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ;
tapeExtension->CurrentPartition = DeviceConfigPage->ActivePartition + 1;
}
return TAPE_STATUS_SUCCESS;
} // end TapeCreatePartition()
TAPE_STATUS
Erase(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for an Erase requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PTAPE_ERASE tapeErase = CommandParameters;
PCDB cdb = (PCDB) Srb->Cdb;
PMINITAPE_EXTENSION tapeExtension = MinitapeExtension ;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"TapeErase: Enter routine\n"));
if ( CallNumber == 0 ) {
if (tapeErase->Immediate) {
switch (tapeErase->Type) {
case TAPE_ERASE_LONG:
case TAPE_ERASE_SHORT:
DebugPrint((3,"TapeErase: immediate\n"));
break;
default:
DebugPrint((1,"TapeErase: EraseType, immediate -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
}
switch (tapeErase->Type) {
case TAPE_ERASE_LONG:
switch (tapeExtension->DriveID) {
case AIWA_GD201:
case ARCHIVE_PYTHON:
case DEC_TLZ06:
case DEC_TLZ07:
case EXABYTE_4200:
case EXABYTE_4200C:
case HP_35470A:
case HP_35480A:
case HP_IBM35480A:
case IOMEGA_DAT4000:
case WANGDAT_1300:
DebugPrint((1,"TapeErase: long -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
DebugPrint((3,"TapeErase: long\n"));
break;
case TAPE_ERASE_SHORT:
switch (tapeExtension->DriveID) {
case HP_C1533A:
case HP_C1553A:
DebugPrint((1,"TapeErase: short -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
DebugPrint((3,"TapeErase: short\n"));
break;
default:
DebugPrint((1,"TapeErase: EraseType -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->ERASE.OperationCode = SCSIOP_ERASE;
cdb->ERASE.Immediate = tapeErase->Immediate;
if (tapeErase->Type == TAPE_ERASE_LONG) {
cdb->ERASE.Long = SETBITON;
} else {
cdb->ERASE.Long = SETBITOFF;
}
//
// Set timeout value.
//
if (tapeErase->Type == TAPE_ERASE_LONG) {
Srb->TimeOutValue = 16500;
}
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeErase: SendSrb (erase)\n"));
Srb->DataTransferLength = 0 ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
ASSERT( CallNumber == 1 ) ;
return TAPE_STATUS_SUCCESS ;
} // end TapeErase()
VOID
TapeError(
IN OUT PVOID MinitapeExtension,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN TAPE_STATUS *LastError
)
/*++
Routine Description:
This routine is called for tape requests, to handle tape
specific errors: it may/can update the status.
Arguments:
MinitapeExtension - Supplies the minitape extension.
Srb - Supplies the SCSI request block.
LastError - Status used to set the IRP's completion status.
Retry - Indicates that this request should be retried.
Return Value:
None.
--*/
{
PMINITAPE_EXTENSION tapeExtension = MinitapeExtension;
PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
UCHAR adsenseq = senseBuffer->AdditionalSenseCodeQualifier;
UCHAR adsense = senseBuffer->AdditionalSenseCode;
DebugPrint((3,"TapeError: Enter routine\n"));
DebugPrint((1,"TapeError: Status 0x%.8X\n", *LastError));
switch (*LastError) {
case TAPE_STATUS_IO_DEVICE_ERROR :
if ((senseBuffer->SenseKey & 0x0F) == SCSI_SENSE_ABORTED_COMMAND) {
*LastError = TAPE_STATUS_DEVICE_NOT_READY;
}
break ;
case TAPE_STATUS_BUS_RESET:
// if a manual eject during an operation occurs then this happens
if ((adsense == SCSI_ADSENSE_NO_MEDIA_IN_DEVICE) &&
(adsenseq == 0) ) {
*LastError = TAPE_STATUS_NO_MEDIA;
}
break;
}
DebugPrint((1,"TapeError: Status 0x%.8X \n", *LastError ));
return;
} // end TapeError()
GetDriveParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Get Drive Parameters requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PMINITAPE_EXTENSION extension = MinitapeExtension;
PCOMMAND_EXTENSION commandExtension = CommandExtension;
PTAPE_GET_DRIVE_PARAMETERS tapeGetDriveParams = CommandParameters;
PCDB cdb = (PCDB)Srb->Cdb;
PMODE_DATA_COMPRESS_PAGE compressionModeSenseBuffer;
PREAD_BLOCK_LIMITS_DATA blockLimits;
PMODE_PARAMETER_HEADER ParameterListHeader; // List Header Format
PMODE_PARAMETER_BLOCK ParameterListBlock; // List Block Descriptor
PMODE_DATA_COMPRESSION_PAGE DataCompressPage;
PMODE_DEVICE_CONFIGURATION_PAGE DeviceConfigPage;
ULONG bufferSize ;
DebugPrint((3,"TapeGetDriveParameters: Enter routine\n"));
if (CallNumber == 0) {
TapeClassZeroMemory(tapeGetDriveParams, sizeof(TAPE_GET_DRIVE_PARAMETERS));
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
if (!LocalAllocateConfigPage(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ) {
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (modeParmBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
cdb->MODE_SENSE.AllocationLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeGetDriveParameters: SendSrb (mode sense)\n"));
Srb->DataTransferLength = bufferSize ;
*RetryFlags = RETURN_ERRORS ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK;
}
if (CallNumber == 1) {
if ( ( LastError != TAPE_STATUS_NO_MEDIA ) &&
( LastError != TAPE_STATUS_SUCCESS ) ) {
return LastError ;
}
LocalGetConfigPageData(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ;
tapeGetDriveParams->ReportSetmarks =
(DeviceConfigPage->RSmk? 1 : 0 );
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
if (!LocalAllocateCompressPage(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DataCompressPage,
&bufferSize ) ) {
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (compressionModeSenseBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.PageCode = MODE_PAGE_DATA_COMPRESS;
cdb->MODE_SENSE.AllocationLength = (UCHAR)bufferSize ;
Srb->DataTransferLength = bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeGetDriveParameters: SendSrb (mode sense)\n"));
*RetryFlags = RETURN_ERRORS ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK;
}
if (CallNumber == 2) {
if ( LastError == TAPE_STATUS_INVALID_DEVICE_REQUEST ) {
return TAPE_STATUS_CALLBACK ;
}
if ( ( LastError != TAPE_STATUS_NO_MEDIA ) &&
( LastError != TAPE_STATUS_SUCCESS ) ) {
DebugPrint((1,"TapeGetDriveParameters: mode sense, SendSrb unsuccessful\n"));
return LastError ;
}
compressionModeSenseBuffer = Srb->DataBuffer;
LocalGetCompressPageData(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DataCompressPage,
&bufferSize ) ;
if (DataCompressPage->DCC) {
tapeGetDriveParams->FeaturesLow |= TAPE_DRIVE_COMPRESSION;
tapeGetDriveParams->FeaturesHigh |= TAPE_DRIVE_SET_COMPRESSION;
tapeGetDriveParams->Compression =
(DataCompressPage->DCE? TRUE : FALSE);
} else {
return TAPE_STATUS_CALLBACK ;
}
if ( LastError == TAPE_STATUS_NO_MEDIA ) {
return TAPE_STATUS_CALLBACK ;
}
if (compressionModeSenseBuffer->DataCompressPage.DDE) {
return TAPE_STATUS_CALLBACK ;
}
if (( extension->DriveID != SONY_SDT2000 ) &&
( extension->DriveID != SONY_SDT4000 ) &&
( extension->DriveID != SONY_SDT5000 ) &&
( extension->DriveID != SONY_SDT5200 ) ) {
return TAPE_STATUS_CALLBACK ;
}
ParameterListHeader->ModeDataLength = 0;
ParameterListHeader->MediumType = 0;
ParameterListHeader->DeviceSpecificParameter = 0x10;
if ( ParameterListBlock ) {
ParameterListBlock->DensityCode = 0x7F;
}
DataCompressPage->DDE = SETBITON;
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
cdb->MODE_SELECT.PFBit = SETBITON;
cdb->MODE_SELECT.ParameterListLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeGetDriveParameters: SendSrb (mode select)\n"));
Srb->DataTransferLength = bufferSize ;
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT ;
*RetryFlags = RETURN_ERRORS ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if ( CallNumber == 3 ) {
if ( ( LastError != TAPE_STATUS_NO_MEDIA ) &&
( LastError != TAPE_STATUS_CALLBACK ) &&
( LastError != TAPE_STATUS_SUCCESS ) ) {
DebugPrint((1,"TapeGetDriveParameters: mode sense, SendSrb unsuccessful\n"));
return LastError ;
}
//
// this time around lets make sure the DDE bit is on
//
if (!TapeClassAllocateSrbBuffer(Srb, sizeof(READ_BLOCK_LIMITS_DATA))) {
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (compressionModeSenseBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
blockLimits = Srb->DataBuffer;
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->CDB6GENERIC.OperationCode = SCSIOP_READ_BLOCK_LIMITS;
DebugPrint((3,"TapeGetDriveParameters: SendSrb (read block limits)\n"));
*RetryFlags = RETURN_ERRORS ;
Srb->DataTransferLength = sizeof(READ_BLOCK_LIMITS_DATA) ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK;
}
if (CallNumber == 4) {
blockLimits = Srb->DataBuffer;
if ( LastError == TAPE_STATUS_SUCCESS ) {
tapeGetDriveParams->MaximumBlockSize = blockLimits->BlockMaximumSize[2];
tapeGetDriveParams->MaximumBlockSize += (blockLimits->BlockMaximumSize[1] << 8);
tapeGetDriveParams->MaximumBlockSize += (blockLimits->BlockMaximumSize[0] << 16);
tapeGetDriveParams->MinimumBlockSize = blockLimits->BlockMinimumSize[1];
tapeGetDriveParams->MinimumBlockSize += (blockLimits->BlockMinimumSize[0] << 8);
} else {
if (LastError != TAPE_STATUS_NO_MEDIA ) {
return LastError ;
}
}
tapeGetDriveParams->DefaultBlockSize = 0x200;
tapeGetDriveParams->MaximumPartitionCount = 2;
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_INITIATOR |
TAPE_DRIVE_ERASE_SHORT |
TAPE_DRIVE_ERASE_IMMEDIATE |
TAPE_DRIVE_FIXED_BLOCK |
TAPE_DRIVE_VARIABLE_BLOCK |
TAPE_DRIVE_WRITE_PROTECT |
TAPE_DRIVE_REPORT_SMKS |
TAPE_DRIVE_GET_ABSOLUTE_BLK |
TAPE_DRIVE_GET_LOGICAL_BLK |
TAPE_DRIVE_EJECT_MEDIA;
tapeGetDriveParams->FeaturesHigh |=
TAPE_DRIVE_LOAD_UNLOAD |
TAPE_DRIVE_LOCK_UNLOCK |
TAPE_DRIVE_REWIND_IMMEDIATE |
TAPE_DRIVE_SET_BLOCK_SIZE |
TAPE_DRIVE_LOAD_UNLD_IMMED |
TAPE_DRIVE_SET_REPORT_SMKS |
TAPE_DRIVE_ABSOLUTE_BLK |
TAPE_DRIVE_LOGICAL_BLK |
TAPE_DRIVE_END_OF_DATA |
TAPE_DRIVE_RELATIVE_BLKS |
TAPE_DRIVE_FILEMARKS |
TAPE_DRIVE_SEQUENTIAL_FMKS |
TAPE_DRIVE_SETMARKS |
TAPE_DRIVE_REVERSE_POSITION |
TAPE_DRIVE_WRITE_SETMARKS |
TAPE_DRIVE_WRITE_FILEMARKS |
TAPE_DRIVE_WRITE_MARK_IMMED;
switch (extension->DriveID) {
case AIWA_GD201:
case IOMEGA_DAT4000:
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_TAPE_CAPACITY |
TAPE_DRIVE_TAPE_REMAINING;
tapeGetDriveParams->FeaturesHigh |=
TAPE_DRIVE_TENSION |
TAPE_DRIVE_TENSION_IMMED |
TAPE_DRIVE_ABS_BLK_IMMED |
TAPE_DRIVE_LOG_BLK_IMMED |
TAPE_DRIVE_SEQUENTIAL_SMKS;
break;
case ARCHIVE_PYTHON:
case ARCHIVE_4322:
case ARCHIVE_4326:
case ARCHIVE_4586:
case DEC_TLZ06:
case DEC_TLZ07:
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_TAPE_CAPACITY |
TAPE_DRIVE_TAPE_REMAINING;
break;
case ARCHIVE_IBM4326:
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_ERASE_LONG |
TAPE_DRIVE_TAPE_CAPACITY |
TAPE_DRIVE_TAPE_REMAINING;
break;
case EXABYTE_4200:
case EXABYTE_4200C:
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_TAPE_CAPACITY |
TAPE_DRIVE_TAPE_REMAINING;
tapeGetDriveParams->FeaturesHigh &=~TAPE_DRIVE_SEQUENTIAL_FMKS;
break;
case HP_35470A:
case HP_35480A:
case HP_IBM35480A:
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_TAPE_CAPACITY |
TAPE_DRIVE_TAPE_REMAINING;
tapeGetDriveParams->FeaturesHigh |=
TAPE_DRIVE_ABS_BLK_IMMED |
TAPE_DRIVE_LOG_BLK_IMMED |
TAPE_DRIVE_SEQUENTIAL_SMKS;
break;
case HP_C1533A:
case HP_C1553A:
//
// Bizarre implementation doesn't write EOD.
//
DebugPrint((1,"GetDriveParameters: Turning off erase short %x\n",
tapeGetDriveParams->FeaturesLow));
tapeGetDriveParams->FeaturesLow &= ~TAPE_DRIVE_ERASE_SHORT;
DebugPrint((1,"GetDriveParameters: Turned off erase short %x\n",
tapeGetDriveParams->FeaturesLow));
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_ERASE_LONG |
TAPE_DRIVE_TAPE_CAPACITY |
TAPE_DRIVE_TAPE_REMAINING;
tapeGetDriveParams->FeaturesHigh |=
TAPE_DRIVE_ABS_BLK_IMMED |
TAPE_DRIVE_LOG_BLK_IMMED |
TAPE_DRIVE_SEQUENTIAL_SMKS;
break;
case WANGDAT_1300:
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_FIXED |
TAPE_DRIVE_SELECT |
TAPE_DRIVE_TAPE_CAPACITY;
tapeGetDriveParams->FeaturesHigh |=
TAPE_DRIVE_ABS_BLK_IMMED |
TAPE_DRIVE_LOG_BLK_IMMED |
TAPE_DRIVE_SEQUENTIAL_SMKS;
break;
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_ERASE_LONG |
TAPE_DRIVE_TAPE_CAPACITY ;
tapeGetDriveParams->FeaturesHigh |=
TAPE_DRIVE_TENSION |
TAPE_DRIVE_TENSION_IMMED |
TAPE_DRIVE_ABS_BLK_IMMED |
//TAPE_DRIVE_LOG_BLK_IMMED |
TAPE_DRIVE_SEQUENTIAL_SMKS ;
break ;
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
tapeGetDriveParams->FeaturesLow |=
TAPE_DRIVE_FIXED |
TAPE_DRIVE_SELECT |
TAPE_DRIVE_ERASE_LONG |
TAPE_DRIVE_ERASE_BOP_ONLY |
TAPE_DRIVE_TAPE_CAPACITY;
tapeGetDriveParams->FeaturesHigh |=
TAPE_DRIVE_ABS_BLK_IMMED |
TAPE_DRIVE_LOG_BLK_IMMED |
TAPE_DRIVE_SEQUENTIAL_SMKS;
break;
}
tapeGetDriveParams->FeaturesHigh &= ~TAPE_DRIVE_HIGH_FEATURES;
DebugPrint((3,"TapeGetDriveParameters: FeaturesLow == 0x%.8X\n",
tapeGetDriveParams->FeaturesLow));
DebugPrint((3,"TapeGetDriveParameters: FeaturesHigh == 0x%.8X\n",
tapeGetDriveParams->FeaturesHigh));
return TAPE_STATUS_SUCCESS ;
}
ASSERT(FALSE) ;
} // end TapeGetDriveParameters()
TAPE_STATUS
GetMediaParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Get Media Parameters requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PMINITAPE_EXTENSION extension = MinitapeExtension;
PTAPE_GET_MEDIA_PARAMETERS tapeGetMediaParams = CommandParameters;
PMODE_TAPE_MEDIA_INFORMATION modeSenseBuffer;
PLOG_SENSE_PARAMETER_FORMAT logSenseBuffer;
LARGE_INTEGER partitionSize[2];
LARGE_INTEGER remaining[2];
LARGE_INTEGER capacity[2];
ULONG partitionCount;
PCDB cdb = (PCDB)Srb->Cdb;
PMODE_PARAMETER_HEADER ParameterListHeader; // List Header Format
PMODE_PARAMETER_BLOCK ParameterListBlock; // List Block Descriptor
PMODE_DATA_COMPRESSION_PAGE DataCompressPage;
PMODE_DEVICE_CONFIGURATION_PAGE DeviceConfigPage;
ULONG bufferSize ;
UNREFERENCED_PARAMETER(LastError) ;
TapeClassZeroMemory(partitionSize, 2*sizeof(LARGE_INTEGER));
TapeClassZeroMemory(remaining, 2*sizeof(LARGE_INTEGER));
TapeClassZeroMemory(capacity, 2*sizeof(LARGE_INTEGER));
DebugPrint((3,"TapeGetMediaParameters: Enter routine\n"));
if (CallNumber == 0) {
TapeClassZeroMemory(tapeGetMediaParams, sizeof(TAPE_GET_MEDIA_PARAMETERS));
return TAPE_STATUS_CHECK_TEST_UNIT_READY;
}
if (CallNumber == 1) {
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
if (!LocalAllocateConfigPage(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ) {
DebugPrint((1,"TapeGetMediaParameters: insufficient resources (deviceConfigModeSenseBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
cdb->MODE_SENSE.AllocationLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeGetMediaParameters: SendSrb (mode sense)\n"));
Srb->DataTransferLength = bufferSize ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if (CallNumber == 2) {
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
LocalGetConfigPageData(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ;
extension->CurrentPartition = DeviceConfigPage->ActivePartition + 1;
if (!TapeClassAllocateSrbBuffer(Srb, sizeof(MODE_TAPE_MEDIA_INFORMATION))) {
DebugPrint((1,"TapeGetMediaParameters: insufficient resources (deviceConfigModeSenseBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
modeSenseBuffer = Srb->DataBuffer;
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.PageCode = MODE_PAGE_MEDIUM_PARTITION;
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_TAPE_MEDIA_INFORMATION);
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeGetMediaParameters: SendSrb (mode sense)\n"));
Srb->DataTransferLength = sizeof(MODE_TAPE_MEDIA_INFORMATION) ;
*RetryFlags = RETURN_ERRORS ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if (CallNumber == 3) {
if ( ( LastError != TAPE_STATUS_DATA_OVERRUN ) &&
( LastError != TAPE_STATUS_SUCCESS ) ) {
return LastError ;
}
modeSenseBuffer = Srb->DataBuffer;
tapeGetMediaParams->BlockSize = modeSenseBuffer->ParameterListBlock.BlockLength[2];
tapeGetMediaParams->BlockSize += modeSenseBuffer->ParameterListBlock.BlockLength[1] << 8;
tapeGetMediaParams->BlockSize += modeSenseBuffer->ParameterListBlock.BlockLength[0] << 16;
partitionCount = modeSenseBuffer->MediumPartPage.AdditionalPartitionDefined;
tapeGetMediaParams->PartitionCount = partitionCount + 1;
tapeGetMediaParams->WriteProtected =
((modeSenseBuffer->ParameterListHeader.DeviceSpecificParameter >> 7) & 0x01);
partitionSize[0].LowPart = modeSenseBuffer->MediumPartPage.Partition0Size[1];
partitionSize[0].LowPart += modeSenseBuffer->MediumPartPage.Partition0Size[0] << 8;
partitionSize[0].HighPart = 0;
partitionSize[1].LowPart = modeSenseBuffer->MediumPartPage.Partition1Size[1];
partitionSize[1].LowPart += modeSenseBuffer->MediumPartPage.Partition1Size[0] << 8;
partitionSize[1].HighPart = 0;
switch (modeSenseBuffer->MediumPartPage.PSUMBit) {
case 1:
partitionSize[0].QuadPart <<= 10 ;
partitionSize[1].QuadPart <<= 10 ;
break;
case 2:
partitionSize[0].QuadPart <<= 20 ;
partitionSize[1].QuadPart <<= 20 ;
break;
}
switch (extension->DriveID) {
case AIWA_GD201:
case ARCHIVE_PYTHON:
case ARCHIVE_4322:
case ARCHIVE_4326:
case ARCHIVE_4586:
case ARCHIVE_IBM4326:
case DEC_TLZ06:
case DEC_TLZ07:
case EXABYTE_4200:
case EXABYTE_4200C:
case HP_35470A:
case HP_35480A:
case HP_C1533A:
case HP_C1553A:
case HP_IBM35480A:
case IOMEGA_DAT4000:
if (!TapeClassAllocateSrbBuffer(Srb, sizeof(LOG_SENSE_PARAMETER_FORMAT))) {
DebugPrint((1,"TapeGetMediaParameters: insufficient resources (LogSenseBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
logSenseBuffer = Srb->DataBuffer;
//
// Zero CDB in SRB on stack.
//
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB10GENERIC_LENGTH;
cdb->LOGSENSE.OperationCode = SCSIOP_LOG_SENSE;
cdb->LOGSENSE.PageCode = LOGSENSEPAGE31;
cdb->LOGSENSE.PCBit = 1;
cdb->LOGSENSE.AllocationLength[0] = 0;
cdb->LOGSENSE.AllocationLength[1] = 0x24;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeGetMediaParameters: SendSrb (log sense)\n"));
Srb->DataTransferLength = 0x24 ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5200 :
case SONY_SDT5000 :
capacity[0].QuadPart = partitionSize[0].QuadPart +
partitionSize[1].QuadPart ;
tapeGetMediaParams->Remaining = remaining[0];
tapeGetMediaParams->Capacity = capacity[0];
extension->CurrentPartition = partitionCount? extension->CurrentPartition : NOT_PARTITIONED;
return TAPE_STATUS_SUCCESS ;
}
}
if (CallNumber == 4) {
logSenseBuffer = Srb->DataBuffer;
capacity[0].LowPart = logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart0[3];
capacity[0].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart0[2] << 8;
capacity[0].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart0[1] << 16;
capacity[0].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart0[0] << 24;
capacity[0].HighPart = 0;
remaining[0].LowPart = logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart0[3];
remaining[0].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart0[2] << 8;
remaining[0].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart0[1] << 16;
remaining[0].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart0[0] << 24;
remaining[0].HighPart = 0;
capacity[1].LowPart = logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart1[3];
capacity[1].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart1[2] << 8;
capacity[1].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart1[1] << 16;
capacity[1].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.MaximumCapacityPart1[0] << 24;
capacity[1].HighPart = 0;
remaining[1].LowPart = logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart1[3];
remaining[1].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart1[2] << 8;
remaining[1].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart1[1] << 16;
remaining[1].LowPart += logSenseBuffer->LogSensePageInfo.LogSensePage.Page31.RemainingCapacityPart1[0] << 24;
remaining[1].HighPart = 0;
remaining[0].QuadPart = remaining[0].QuadPart << 10 ;
remaining[1].QuadPart = remaining[1].QuadPart << 10 ;
remaining[0].QuadPart = remaining[0].QuadPart + remaining[1].QuadPart ;
capacity[0].QuadPart <<= 10 ;
capacity[1].QuadPart <<= 10 ;
capacity[0].QuadPart += capacity[1].QuadPart ;
tapeGetMediaParams->Remaining = remaining[0];
tapeGetMediaParams->Capacity = capacity[0];
extension->CurrentPartition = partitionCount? extension->CurrentPartition : NOT_PARTITIONED;
return TAPE_STATUS_SUCCESS ;
}
ASSERT(FALSE) ;
} // end TapeGetMediaParameters()
TAPE_STATUS
GetPosition(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Get Position requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PMINITAPE_EXTENSION extension = MinitapeExtension;
PTAPE_GET_POSITION tapeGetPosition = CommandParameters;
PCDB cdb = (PCDB)Srb->Cdb;
PTAPE_POSITION_DATA positionBuffer;
ULONG type;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"TapeGetPosition: Enter routine\n"));
if (CallNumber == 0) {
type = tapeGetPosition->Type;
TapeClassZeroMemory(tapeGetPosition, sizeof(TAPE_GET_POSITION));
tapeGetPosition->Type = type;
return TAPE_STATUS_CHECK_TEST_UNIT_READY ;
}
if ( CallNumber == 1 ) {
switch (tapeGetPosition->Type) {
case TAPE_ABSOLUTE_POSITION:
DebugPrint((3,"TapeGetPosition: absolute\n"));
break;
case TAPE_LOGICAL_POSITION:
DebugPrint((3,"TapeGetPosition: logical\n"));
break;
default:
DebugPrint((1,"TapeGetPosition: PositionType -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(TAPE_POSITION_DATA) )) {
DebugPrint((1,"TapeGetPosition: insufficient resources (TapePositionData)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
positionBuffer = Srb->DataBuffer ;
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB10GENERIC_LENGTH;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->READ_POSITION.Operation = SCSIOP_READ_POSITION;
if (tapeGetPosition->Type == TAPE_ABSOLUTE_POSITION) {
switch (extension->DriveID) {
case ARCHIVE_PYTHON:
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
break;
default:
cdb->READ_POSITION.BlockType = SETBITON;
break;
}
}
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeGetPosition: SendSrb (read position)\n"));
Srb->DataTransferLength = sizeof(TAPE_POSITION_DATA) ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
ASSERT( CallNumber == 2) ;
positionBuffer = Srb->DataBuffer ;
if (positionBuffer->BlockPositionUnsupported) {
DebugPrint((1,"TapeGetPosition: read position -- block position unsupported\n"));
return TAPE_STATUS_INVALID_DEVICE_REQUEST;
}
if (tapeGetPosition->Type == TAPE_LOGICAL_POSITION) {
tapeGetPosition->Partition = positionBuffer->PartitionNumber + 1;
}
tapeGetPosition->Offset.HighPart = 0;
REVERSE_BYTES((PFOUR_BYTE)&tapeGetPosition->Offset.LowPart,
(PFOUR_BYTE)positionBuffer->FirstBlock);
return TAPE_STATUS_SUCCESS ;
} // end TapeGetPosition()
TAPE_STATUS
GetStatus(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Get Status requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PCDB cdb = (PCDB)Srb->Cdb;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"TapeGetStatus: Enter routine\n"));
if (CallNumber == 0) {
return TAPE_STATUS_CHECK_TEST_UNIT_READY ;
}
return TAPE_STATUS_SUCCESS ;
} // end TapeGetStatus()
TAPE_STATUS
Prepare(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Prepare requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PMINITAPE_EXTENSION extension = MinitapeExtension;
PTAPE_PREPARE tapePrepare = CommandParameters;
PCDB cdb = (PCDB)Srb->Cdb;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"TapePrepare: Enter routine\n"));
if (CallNumber == 0) {
switch (tapePrepare->Operation) {
case TAPE_LOAD:
DebugPrint((3,"TapePrepare: load\n"));
break;
case TAPE_UNLOAD:
DebugPrint((3,"TapePrepare: unload\n"));
break;
case TAPE_LOCK:
DebugPrint((3,"TapePrepare: lock\n"));
break;
case TAPE_UNLOCK:
DebugPrint((3,"TapePrepare: unlock\n"));
break;
case TAPE_TENSION:
DebugPrint((3,"TapePrepare: tension\n"));
switch (extension->DriveID) {
case ARCHIVE_PYTHON:
case ARCHIVE_IBM4326:
case ARCHIVE_4322:
case ARCHIVE_4326:
case ARCHIVE_4586:
case DEC_TLZ06:
case DEC_TLZ07:
case EXABYTE_4200:
case EXABYTE_4200C:
case HP_35470A:
case HP_35480A:
case HP_C1533A:
case HP_C1553A:
case HP_IBM35480A:
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
return TAPE_STATUS_NOT_IMPLEMENTED;
break;
}
break;
default:
return TAPE_STATUS_NOT_IMPLEMENTED;
break;
}
if (tapePrepare->Immediate) {
switch (tapePrepare->Operation) {
case TAPE_LOAD:
case TAPE_UNLOAD:
case TAPE_TENSION:
DebugPrint((3,"TapePrepare: immediate\n"));
break;
case TAPE_LOCK:
case TAPE_UNLOCK:
default:
DebugPrint((1,"TapePrepare: Operation, immediate -- not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
}
//
// Zero CDB in SRB on stack.
//
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->CDB6GENERIC.Immediate = tapePrepare->Immediate;
switch (tapePrepare->Operation) {
case TAPE_LOAD:
cdb->CDB6GENERIC.OperationCode = SCSIOP_LOAD_UNLOAD;
cdb->CDB6GENERIC.CommandUniqueBytes[2] = 0x01;
Srb->TimeOutValue = 390;
break;
case TAPE_UNLOAD:
cdb->CDB6GENERIC.OperationCode = SCSIOP_LOAD_UNLOAD;
Srb->TimeOutValue = 390;
break;
case TAPE_TENSION:
cdb->CDB6GENERIC.OperationCode = SCSIOP_LOAD_UNLOAD;
cdb->CDB6GENERIC.CommandUniqueBytes[2] = 0x03;
Srb->TimeOutValue = 390;
break;
case TAPE_LOCK:
cdb->CDB6GENERIC.OperationCode = SCSIOP_MEDIUM_REMOVAL;
cdb->CDB6GENERIC.CommandUniqueBytes[2] = 0x01;
Srb->TimeOutValue = 180;
break;
case TAPE_UNLOCK:
cdb->CDB6GENERIC.OperationCode = SCSIOP_MEDIUM_REMOVAL;
Srb->TimeOutValue = 180;
break;
}
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapePrepare: SendSrb (Operation)\n"));
Srb->DataTransferLength = 0 ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
ASSERT( CallNumber == 1) ;
return TAPE_STATUS_SUCCESS;
} // end TapePrepare()
TAPE_STATUS
SetDriveParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Set Drive Parameters requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PMINITAPE_EXTENSION extension = MinitapeExtension;
PCOMMAND_EXTENSION commandExtension = CommandExtension;
PTAPE_SET_DRIVE_PARAMETERS tapeSetDriveParams = CommandParameters;
PCDB cdb = (PCDB)Srb->Cdb;
PMODE_DATA_COMPRESS_PAGE compressionBuffer;
PMODE_PARAMETER_HEADER ParameterListHeader; // List Header Format
PMODE_PARAMETER_BLOCK ParameterListBlock; // List Block Descriptor
PMODE_MEDIUM_PARTITION_PAGE MediumPartPage;
PMODE_DEVICE_CONFIGURATION_PAGE DeviceConfigPage;
PMODE_DATA_COMPRESSION_PAGE DataCompressPage;
ULONG bufferSize ;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"TapeSetDriveParameters: Enter routine\n"));
if (CallNumber == 0) {
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
if (!LocalAllocateConfigPage(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ) {
DebugPrint((1,"TapeSetDriveParameters: insufficient resources (configBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
cdb->MODE_SENSE.AllocationLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode sense)\n"));
Srb->DataTransferLength = bufferSize ;
*RetryFlags = RETURN_ERRORS ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if ( CallNumber == 1 ) {
if ( LastError != TAPE_STATUS_SUCCESS ) {
return TAPE_STATUS_CALLBACK ;
}
LocalGetConfigPageData(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DeviceConfigPage,
&bufferSize ) ;
ParameterListHeader->ModeDataLength = 0;
ParameterListHeader->MediumType = 0;
ParameterListHeader->DeviceSpecificParameter = 0x10;
// ParameterListHeader->BlockDescriptorLength = 0;
if ( ParameterListBlock ) {
ParameterListBlock->DensityCode = 0x7f ;
}
DeviceConfigPage->PageCode = MODE_PAGE_DEVICE_CONFIG;
DeviceConfigPage->PageLength = 0x0E;
if (tapeSetDriveParams->ReportSetmarks) {
DeviceConfigPage->RSmk = SETBITON;
} else {
DeviceConfigPage->RSmk = SETBITOFF;
}
//
// Zero CDB in SRB on stack.
//
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
cdb->MODE_SELECT.PFBit = SETBITON;
cdb->MODE_SELECT.ParameterListLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode select)\n"));
Srb->DataTransferLength = bufferSize ;
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if ( CallNumber == 2 ) {
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
if (!LocalAllocateCompressPage(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DataCompressPage,
&bufferSize ) ) {
DebugPrint((1,"TapeSetDriveParameters: insufficient resources (compressionBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
cdb->MODE_SENSE.PageCode = MODE_PAGE_DATA_COMPRESS;
cdb->MODE_SENSE.AllocationLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode sense)\n"));
Srb->DataTransferLength = bufferSize ;
*RetryFlags = RETURN_ERRORS ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
if ( CallNumber == 3 ) {
if ( LastError == TAPE_STATUS_INVALID_DEVICE_REQUEST ) {
return TAPE_STATUS_SUCCESS ;
}
LocalGetCompressPageData(Srb,
extension,
&ParameterListHeader,
&ParameterListBlock,
&DataCompressPage,
&bufferSize ) ;
if ( !DataCompressPage->DCC) {
return TAPE_STATUS_SUCCESS ;
}
ParameterListHeader->ModeDataLength = 0;
ParameterListHeader->MediumType = 0;
ParameterListHeader->DeviceSpecificParameter = 0x10;
if ( ParameterListBlock ) {
ParameterListBlock->DensityCode = 0x7F;
} else {
ParameterListHeader->BlockDescriptorLength = 0;
}
DataCompressPage->PageCode = MODE_PAGE_DATA_COMPRESS;
DataCompressPage->PageLength = 0x0E;
if (tapeSetDriveParams->Compression) {
DataCompressPage->DCE = SETBITON;
DataCompressPage->CompressionAlgorithm[0] = 0;
DataCompressPage->CompressionAlgorithm[1] = 0;
DataCompressPage->CompressionAlgorithm[2] = 0;
DataCompressPage->CompressionAlgorithm[3] = 0x20;
DataCompressPage->DecompressionAlgorithm[0] = 0;
DataCompressPage->DecompressionAlgorithm[1] = 0;
DataCompressPage->DecompressionAlgorithm[2] = 0;
DataCompressPage->DecompressionAlgorithm[3] = 0;
} else {
DataCompressPage->DCE = SETBITOFF;
DataCompressPage->CompressionAlgorithm[0] = 0;
DataCompressPage->CompressionAlgorithm[1] = 0;
DataCompressPage->CompressionAlgorithm[2] = 0;
DataCompressPage->CompressionAlgorithm[3] = 0;
DataCompressPage->DecompressionAlgorithm[0] = 0;
DataCompressPage->DecompressionAlgorithm[1] = 0;
DataCompressPage->DecompressionAlgorithm[2] = 0;
DataCompressPage->DecompressionAlgorithm[3] = 0;
}
DataCompressPage->DDE = SETBITON;
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
cdb->MODE_SELECT.PFBit = SETBITON;
cdb->MODE_SELECT.ParameterListLength = (UCHAR)bufferSize ;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode select)\n"));
Srb->DataTransferLength = bufferSize ;
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
ASSERT( CallNumber == 4 ) ;
return TAPE_STATUS_SUCCESS ;
} // end TapeSetDriveParameters()
TAPE_STATUS
SetMediaParameters(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Set Media Parameters requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PTAPE_SET_MEDIA_PARAMETERS tapeSetMediaParams = CommandParameters;
PCDB cdb = (PCDB)Srb->Cdb;
PMODE_PARM_READ_WRITE_DATA modeBuffer;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"TapeSetMediaParameters: Enter routine\n"));
if (CallNumber == 0) {
return TAPE_STATUS_CHECK_TEST_UNIT_READY ;
}
if (CallNumber == 1) {
if (!TapeClassAllocateSrbBuffer(Srb, sizeof(MODE_PARM_READ_WRITE_DATA)) ) {
DebugPrint((1,"TapeSetMediaParameters: insufficient resources (modeBuffer)\n"));
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
}
modeBuffer = Srb->DataBuffer ;
modeBuffer->ParameterListHeader.ModeDataLength = 0;
modeBuffer->ParameterListHeader.MediumType = 0;
modeBuffer->ParameterListHeader.DeviceSpecificParameter = 0x10;
modeBuffer->ParameterListHeader.BlockDescriptorLength =
MODE_BLOCK_DESC_LENGTH;
modeBuffer->ParameterListBlock.DensityCode = 0x7F;
modeBuffer->ParameterListBlock.BlockLength[0] =
(UCHAR)((tapeSetMediaParams->BlockSize >> 16) & 0xFF);
modeBuffer->ParameterListBlock.BlockLength[1] =
(UCHAR)((tapeSetMediaParams->BlockSize >> 8) & 0xFF);
modeBuffer->ParameterListBlock.BlockLength[2] =
(UCHAR)(tapeSetMediaParams->BlockSize & 0xFF);
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
cdb->MODE_SELECT.ParameterListLength = sizeof(MODE_PARM_READ_WRITE_DATA);
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeSetMediaParameters: SendSrb (mode select)\n"));
Srb->DataTransferLength = sizeof(MODE_PARM_READ_WRITE_DATA) ;
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
ASSERT( CallNumber == 2 );
return TAPE_STATUS_SUCCESS ;
} // end TapeSetMediaParameters()
TAPE_STATUS
SetPosition(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Set Position requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PMINITAPE_EXTENSION tapeExtension = MinitapeExtension ;
PCOMMAND_EXTENSION tapeCmdExtension = CommandExtension ;
PTAPE_SET_POSITION tapeSetPosition = CommandParameters;
PCDB cdb = (PCDB)Srb->Cdb;
ULONG tapePositionVector;
ULONG method;
ULONG partition = 0;
UNREFERENCED_PARAMETER(LastError) ;
DebugPrint((3,"TapeSetPosition: Enter routine\n"));
if (CallNumber == 0) {
if (tapeSetPosition->Immediate) {
switch (tapeSetPosition->Method) {
case TAPE_REWIND:
DebugPrint((3,"TapeSetPosition: immediate\n"));
break;
case TAPE_ABSOLUTE_BLOCK:
switch (tapeExtension->DriveID) {
case ARCHIVE_PYTHON:
case ARCHIVE_IBM4326:
case ARCHIVE_4322:
case ARCHIVE_4326:
case ARCHIVE_4586:
DebugPrint((1,"TapeSetPosition: PositionMethod (absolute), immediate -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
break;
default:
DebugPrint((3,"TapeSetPosition: immediate\n"));
break;
}
break;
case TAPE_LOGICAL_BLOCK:
switch (tapeExtension->DriveID) {
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
case ARCHIVE_PYTHON:
case ARCHIVE_IBM4326:
case ARCHIVE_4322:
case ARCHIVE_4326:
case ARCHIVE_4586:
DebugPrint((1,"TapeSetPosition: PositionMethod (logical), immediate -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
break;
default:
DebugPrint((3,"TapeSetPosition: immediate\n"));
break;
}
break;
case TAPE_SPACE_END_OF_DATA:
case TAPE_SPACE_RELATIVE_BLOCKS:
case TAPE_SPACE_FILEMARKS:
case TAPE_SPACE_SEQUENTIAL_FMKS:
case TAPE_SPACE_SETMARKS:
case TAPE_SPACE_SEQUENTIAL_SMKS:
default:
DebugPrint((1,"TapeSetPosition: PositionMethod, immediate -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
}
//
// Zero CDB in SRB on stack.
//
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->CDB6GENERIC.Immediate = tapeSetPosition->Immediate;
switch (tapeSetPosition->Method) {
case TAPE_REWIND:
DebugPrint((3,"TapeSetPosition: method == rewind\n"));
cdb->CDB6GENERIC.OperationCode = SCSIOP_REWIND;
Srb->TimeOutValue = 360;
break;
case TAPE_ABSOLUTE_BLOCK:
switch (tapeExtension->DriveID) {
case ARCHIVE_PYTHON:
case WANGDAT_1300:
case WANGDAT_3100:
case WANGDAT_3200:
case WANGDAT_3300DX:
case WANGDAT_3400DX:
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
DebugPrint((3,"TapeSetPosition: method == locate, BT- (absolute)\n"));
break;
default:
DebugPrint((3,"TapeSetPosition: method == locate, BT+ (absolute)\n"));
cdb->LOCATE.BTBit = SETBITON;
break;
}
Srb->CdbLength = CDB10GENERIC_LENGTH;
cdb->LOCATE.OperationCode = SCSIOP_LOCATE;
cdb->LOCATE.LogicalBlockAddress[0] = (UCHAR)((tapeSetPosition->Offset.LowPart >> 24) & 0xFF);
cdb->LOCATE.LogicalBlockAddress[1] = (UCHAR)((tapeSetPosition->Offset.LowPart >> 16) & 0xFF);
cdb->LOCATE.LogicalBlockAddress[2] = (UCHAR)((tapeSetPosition->Offset.LowPart >> 8) & 0xFF);
cdb->LOCATE.LogicalBlockAddress[3] = (UCHAR)(tapeSetPosition->Offset.LowPart & 0xFF);
Srb->TimeOutValue = 480;
break;
case TAPE_LOGICAL_BLOCK:
DebugPrint((3,"TapeSetPosition: method == locate (logical)\n"));
Srb->CdbLength = CDB10GENERIC_LENGTH;
cdb->LOCATE.OperationCode = SCSIOP_LOCATE;
cdb->LOCATE.LogicalBlockAddress[0] = (UCHAR)((tapeSetPosition->Offset.LowPart >> 24) & 0xFF);
cdb->LOCATE.LogicalBlockAddress[1] = (UCHAR)((tapeSetPosition->Offset.LowPart >> 16) & 0xFF);
cdb->LOCATE.LogicalBlockAddress[2] = (UCHAR)((tapeSetPosition->Offset.LowPart >> 8) & 0xFF);
cdb->LOCATE.LogicalBlockAddress[3] = (UCHAR)(tapeSetPosition->Offset.LowPart & 0xFF);
if ((tapeSetPosition->Partition != 0) &&
(tapeExtension->CurrentPartition != NOT_PARTITIONED) &&
(tapeSetPosition->Partition != tapeExtension->CurrentPartition)) {
partition = tapeSetPosition->Partition;
cdb->LOCATE.Partition = (UCHAR)(partition - 1);
cdb->LOCATE.CPBit = SETBITON;
} else {
partition = tapeExtension->CurrentPartition;
}
Srb->TimeOutValue = 480;
break;
case TAPE_SPACE_END_OF_DATA:
DebugPrint((3,"TapeSetPosition: method == space to end-of-data\n"));
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
cdb->SPACE_TAPE_MARKS.Code = 3;
Srb->TimeOutValue = 480;
break;
case TAPE_SPACE_RELATIVE_BLOCKS:
DebugPrint((3,"TapeSetPosition: method == space blocks\n"));
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
cdb->SPACE_TAPE_MARKS.Code = 0;
cdb->SPACE_TAPE_MARKS.NumMarksMSB = (UCHAR)((tapeSetPosition->Offset.LowPart >> 16) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarks = (UCHAR)((tapeSetPosition->Offset.LowPart >> 8) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarksLSB = (UCHAR)(tapeSetPosition->Offset.LowPart & 0xFF);
Srb->TimeOutValue = 480;
break;
case TAPE_SPACE_FILEMARKS:
DebugPrint((3,"TapeSetPosition: method == space filemarks\n"));
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
cdb->SPACE_TAPE_MARKS.Code = 1;
cdb->SPACE_TAPE_MARKS.NumMarksMSB = (UCHAR)((tapeSetPosition->Offset.LowPart >> 16) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarks = (UCHAR)((tapeSetPosition->Offset.LowPart >> 8) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarksLSB = (UCHAR)(tapeSetPosition->Offset.LowPart & 0xFF);
Srb->TimeOutValue = 480;
break;
case TAPE_SPACE_SEQUENTIAL_FMKS:
DebugPrint((3,"TapeSetPosition: method == space sequential filemarks\n"));
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
cdb->SPACE_TAPE_MARKS.Code = 2;
cdb->SPACE_TAPE_MARKS.NumMarksMSB = (UCHAR)((tapeSetPosition->Offset.LowPart >> 16) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarks = (UCHAR)((tapeSetPosition->Offset.LowPart >> 8) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarksLSB = (UCHAR)(tapeSetPosition->Offset.LowPart & 0xFF);
Srb->TimeOutValue = 480;
break;
case TAPE_SPACE_SETMARKS:
DebugPrint((3,"TapeSetPosition: method == space setmarks\n"));
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
cdb->SPACE_TAPE_MARKS.Code = 4;
cdb->SPACE_TAPE_MARKS.NumMarksMSB = (UCHAR)((tapeSetPosition->Offset.LowPart >> 16) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarks = (UCHAR)((tapeSetPosition->Offset.LowPart >> 8) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarksLSB = (UCHAR)(tapeSetPosition->Offset.LowPart & 0xFF);
Srb->TimeOutValue = 480;
break;
case TAPE_SPACE_SEQUENTIAL_SMKS:
DebugPrint((3,"TapeSetPosition: method == space sequential setmarks\n"));
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
cdb->SPACE_TAPE_MARKS.Code = 5;
cdb->SPACE_TAPE_MARKS.NumMarksMSB = (UCHAR)(UCHAR)((tapeSetPosition->Offset.LowPart >> 16) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarks = (UCHAR)((tapeSetPosition->Offset.LowPart >> 8) & 0xFF);
cdb->SPACE_TAPE_MARKS.NumMarksLSB = (UCHAR)(tapeSetPosition->Offset.LowPart & 0xFF);
Srb->TimeOutValue = 480;
break;
default:
DebugPrint((1,"TapeSetPosition: PositionMethod -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeSetPosition: SendSrb (method)\n"));
Srb->DataTransferLength = 0 ;
tapeCmdExtension->CurrentState = partition ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
ASSERT( CallNumber == 1 ) ;
if (tapeSetPosition->Method == TAPE_LOGICAL_BLOCK) {
tapeExtension->CurrentPartition = tapeCmdExtension->CurrentState ;
}
return TAPE_STATUS_SUCCESS ;
} // end TapeSetPosition()
TAPE_STATUS
WriteMarks(
IN OUT PVOID MinitapeExtension,
IN OUT PVOID CommandExtension,
IN OUT PVOID CommandParameters,
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN ULONG CallNumber,
IN TAPE_STATUS LastError,
IN OUT PULONG RetryFlags
)
/*++
Routine Description:
This is the TAPE COMMAND routine for a Write Marks requests.
Arguments:
MinitapeExtension - Supplies the minitape extension.
CommandExtension - Supplies the ioctl extension.
CommandParameters - Supplies the command parameters.
Srb - Supplies the SCSI request block.
CallNumber - Supplies the call number.
RetryFlags - Supplies the retry flags.
Return Value:
TAPE_STATUS_SEND_SRB_AND_CALLBACK - The SRB is ready to be sent
(a callback is requested.)
TAPE_STATUS_SUCCESS - The command is complete and
successful.
Otherwise - An error occurred.
--*/
{
PTAPE_WRITE_MARKS tapeWriteMarks = CommandParameters;
PCDB cdb = (PCDB)Srb->Cdb;
DebugPrint((3,"TapeWriteMarks: Enter routine\n"));
if (CallNumber == 0) {
if (tapeWriteMarks->Immediate) {
switch (tapeWriteMarks->Type) {
case TAPE_SETMARKS:
case TAPE_FILEMARKS:
DebugPrint((3,"TapeWriteMarks: immediate\n"));
break;
case TAPE_SHORT_FILEMARKS:
case TAPE_LONG_FILEMARKS:
default:
DebugPrint((1,"TapeWriteMarks: TapemarkType, immediate -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
}
//
// Zero CDB in SRB on stack.
//
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
//
// Prepare SCSI command (CDB)
//
Srb->CdbLength = CDB6GENERIC_LENGTH;
cdb->WRITE_TAPE_MARKS.OperationCode = SCSIOP_WRITE_FILEMARKS;
cdb->WRITE_TAPE_MARKS.Immediate = tapeWriteMarks->Immediate;
switch (tapeWriteMarks->Type) {
case TAPE_SETMARKS:
DebugPrint((3,"TapeWriteMarks: TapemarkType == setmarks\n"));
cdb->WRITE_TAPE_MARKS.WriteSetMarks = SETBITON;
break;
case TAPE_FILEMARKS:
DebugPrint((3,"TapeWriteMarks: TapemarkType == filemarks\n"));
break;
case TAPE_SHORT_FILEMARKS:
case TAPE_LONG_FILEMARKS:
default:
DebugPrint((1,"TapeWriteMarks: TapemarkType -- operation not supported\n"));
return TAPE_STATUS_NOT_IMPLEMENTED;
}
cdb->WRITE_TAPE_MARKS.TransferLength[0] =
(UCHAR)((tapeWriteMarks->Count >> 16) & 0xFF);
cdb->WRITE_TAPE_MARKS.TransferLength[1] =
(UCHAR)((tapeWriteMarks->Count >> 8) & 0xFF);
cdb->WRITE_TAPE_MARKS.TransferLength[2] =
(UCHAR)(tapeWriteMarks->Count & 0xFF);
//
// Set timeout value.
//
Srb->TimeOutValue = 360;
//
// Send SCSI command (CDB) to device
//
DebugPrint((3,"TapeWriteMarks: SendSrb (TapemarkType)\n"));
Srb->DataTransferLength = 0 ;
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
}
ASSERT( CallNumber == 1 ) ;
return TAPE_STATUS_SUCCESS;
} // end TapeWriteMarks()
static
ULONG
WhichIsIt(
IN PINQUIRYDATA InquiryData
)
/*++
Routine Description:
This routine determines a drive's identity from the Product ID field
in its inquiry data.
Arguments:
InquiryData (from an Inquiry command)
Return Value:
driveID
--*/
{
if (TapeClassCompareMemory(InquiryData->VendorId,"AIWA ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"GD-201",6) == 6) {
return AIWA_GD201;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"ARCHIVE ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"Python",6) == 6) {
return ARCHIVE_PYTHON;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"IBM4326",7) == 7) {
return ARCHIVE_IBM4326;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"4322XX",6) == 6) {
return ARCHIVE_4322;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"4326XX",6) == 6) {
return ARCHIVE_4326;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"4586XX",6) == 6) {
return ARCHIVE_4586;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"DEC ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"TLZ06",5) == 5) {
return DEC_TLZ06;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"TLZ6",4) == 4) {
return DEC_TLZ06;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"TLZ07",5) == 5) {
return DEC_TLZ07;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"TLZ09",5) == 5) {
return SONY_SDT5000;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"TLZ7 ",5) == 5) {
return DEC_TLZ07;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"TLZ9 ",5) == 5) {
return SONY_SDT5000;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"EXABYTE ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"EXB-4200 ",9) == 9) {
return EXABYTE_4200;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"EXB-4200c",9) == 9) {
return EXABYTE_4200C;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"HP ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"HP35470A",8) == 8) {
return HP_35470A;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"HP35480A",8) == 8) {
return HP_35480A;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"IBM35480A",9) == 9) {
return HP_IBM35480A;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"C1533A",6) == 6) {
return HP_C1533A;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"C1553A",6) == 6) {
return HP_C1553A;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"C1537A",6) == 6) {
return HP_C1553A;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"IBM ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"HP35480A ",9) == 9) {
return HP_IBM35480A;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"IOMEGA ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"DAT4000",7) == 7) {
return IOMEGA_DAT4000;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"WangDAT ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"Model 1300",10) == 10) {
return WANGDAT_1300;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"Model 3100",10) == 10) {
return WANGDAT_3100;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"Model 3200",10) == 10) {
return WANGDAT_3200;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"Model 3300DX",12) == 12) {
return WANGDAT_3300DX;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"Model 3400DX",12) == 12) {
return WANGDAT_3400DX;
}
}
if (TapeClassCompareMemory(InquiryData->VendorId,"SONY ",8) == 8) {
if (TapeClassCompareMemory(InquiryData->ProductId,"SDT-2000",8) == 8) {
return SONY_SDT2000;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"SDT-4000",8) == 8) {
return SONY_SDT4000;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"SDT-5000",8) == 8) {
return SONY_SDT5000;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"SDT-5200",8) == 8) {
return SONY_SDT5200;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"SDT-7000",8) == 8) {
return SONY_SDT5000;
}
if (TapeClassCompareMemory(InquiryData->ProductId,"SDT-9000",8) == 8) {
return SONY_SDT5000;
}
}
return 0;
}
BOOLEAN
LocalAllocatePartPage(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_MEDIUM_PARTITION_PAGE *MediumPartPage,
OUT PULONG bufferSize
)
/*++
Routine Description:
This routine allocates and returns the pointers to the individule
members of the MODE_MEDIUM_PART_PAGE
Arguments:
Srb - Supplies the SCSI request block.
MinitapeExtension - Supplies the minitape extension.
ParameterListHeader - Return pointer to this portion of the page.
ParameterListBlock - Return pointer to this poriton of the page.
MediumPartPage - Return pointer to this portion of the page.
bufferSize - The size of the page.
Return Value:
TRUE if the allocation was successful
--*/
{
ULONG size ;
switch ( MinitapeExtension->DriveID ) {
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
size = sizeof(MODE_MEDIUM_PART_PAGE_PLUS) ;
break ;
default:
size = sizeof(MODE_MEDIUM_PART_PAGE);
break ;
}
if (!TapeClassAllocateSrbBuffer(Srb, size) ) {
DebugPrint((1,"TapeCreatePartition: insufficient resources (ModeSel buffer)\n"));
return FALSE ;
} else {
LocalGetPartPageData( Srb,
MinitapeExtension,
ParameterListHeader,
ParameterListBlock,
MediumPartPage,
bufferSize ) ;
}
return TRUE ;
}
VOID
LocalGetPartPageData(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_MEDIUM_PARTITION_PAGE *MediumPartPage,
OUT PULONG bufferSize
)
/*++
Routine Description:
This returns the pointers to the individule members of the
MODE_MEDIUM_PART_PAGE
Arguments:
Srb - Supplies the SCSI request block.
MinitapeExtension - Supplies the minitape extension.
ParameterListHeader - Return pointer to this portion of the page.
ParameterListBlock - Return pointer to this poriton of the page.
MediumPartPage - Return pointer to this portion of the page.
bufferSize - The size of the page.
Return Value:
none
--*/
{
PMODE_MEDIUM_PART_PAGE modePage = Srb->DataBuffer ;
PMODE_MEDIUM_PART_PAGE_PLUS modePagePlus = Srb->DataBuffer ;
switch ( MinitapeExtension->DriveID ) {
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
*ParameterListHeader = &modePagePlus->ParameterListHeader ;
*ParameterListBlock = &modePagePlus->ParameterListBlock ;
*MediumPartPage = &modePagePlus->MediumPartPage ;
*bufferSize = sizeof(MODE_MEDIUM_PART_PAGE_PLUS) ;
break ;
default:
*ParameterListHeader = &modePage->ParameterListHeader ;
*ParameterListBlock = NULL ;
*MediumPartPage = &modePage->MediumPartPage ;
*bufferSize = sizeof(MODE_MEDIUM_PART_PAGE);
break ;
}
return ;
}
BOOLEAN
LocalAllocateConfigPage(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DEVICE_CONFIGURATION_PAGE *DeviceConfigPage,
OUT PULONG bufferSize
)
/*++
Routine Description:
This routine allocates and returns the pointers to the individule
members of the MODE_DEVICE_CONFIG_PAGE
Arguments:
Srb - Supplies the SCSI request block.
MinitapeExtension - Supplies the minitape extension.
ParameterListHeader - Return pointer to this portion of the page.
ParameterListBlock - Return pointer to this poriton of the page.
DeviceConfigPage - Return pointer to this portion of the page.
bufferSize - The size of the page.
Return Value:
TRUE if the allocation was successful.
--*/
{
ULONG size ;
PCDB cdb = (PCDB)Srb->Cdb;
switch ( MinitapeExtension->DriveID ) {
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
size = sizeof(MODE_DEVICE_CONFIG_PAGE_PLUS) ;
break ;
default:
cdb->MODE_SENSE.Dbd = SETBITON;
size = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
break ;
}
if (!TapeClassAllocateSrbBuffer(Srb, size) ) {
DebugPrint((1,"TapeCreatePartition: insufficient resources (ModeSel buffer)\n"));
return FALSE ;
} else {
LocalGetConfigPageData( Srb,
MinitapeExtension,
ParameterListHeader,
ParameterListBlock,
DeviceConfigPage,
bufferSize ) ;
}
return TRUE ;
}
VOID
LocalGetConfigPageData(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DEVICE_CONFIGURATION_PAGE *DeviceConfigPage,
OUT PULONG bufferSize
)
/*++
Routine Description:
This returns the pointers to the individule members of the
MODE_DEVICE_CONFIG_PART_PAGE
Arguments:
Srb - Supplies the SCSI request block.
MinitapeExtension - Supplies the minitape extension.
ParameterListHeader - Return pointer to this portion of the page.
ParameterListBlock - Return pointer to this poriton of the page.
DeviceConfigPage - Return pointer to this portion of the page.
bufferSize - The size of the page.
Return Value:
none
--*/
{
PMODE_DEVICE_CONFIG_PAGE configPage = Srb->DataBuffer ;
PMODE_DEVICE_CONFIG_PAGE_PLUS configPagePlus = Srb->DataBuffer ;
switch ( MinitapeExtension->DriveID ) {
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
*ParameterListHeader = &configPagePlus->ParameterListHeader ;
*ParameterListBlock = &configPagePlus->ParameterListBlock ;
*DeviceConfigPage = &configPagePlus->DeviceConfigPage ;
*bufferSize = sizeof(MODE_DEVICE_CONFIG_PAGE_PLUS) ;
break ;
default:
*ParameterListHeader = &configPage->ParameterListHeader ;
*ParameterListBlock = NULL ;
*DeviceConfigPage = &configPage->DeviceConfigPage ;
*bufferSize = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
break ;
}
return ;
}
BOOLEAN
LocalAllocateCompressPage(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DATA_COMPRESSION_PAGE *CompressPage,
OUT PULONG bufferSize
)
/*++
Routine Description:
This routine allocates and returns the pointers to the individule
members of the MODE_DATA_COMPRESS_PAGE
Arguments:
Srb - Supplies the SCSI request block.
MinitapeExtension - Supplies the minitape extension.
ParameterListHeader - Return pointer to this portion of the page.
ParameterListBlock - Return pointer to this poriton of the page.
CompressPage - Return pointer to this portion of the page.
bufferSize - The size of the page.
Return Value:
TRUE if the allocation was successful.
--*/
{
ULONG size ;
PCDB cdb = (PCDB)Srb->Cdb;
switch ( MinitapeExtension->DriveID ) {
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
size = sizeof(MODE_DATA_COMPRESS_PAGE_PLUS) ;
break ;
default:
size = sizeof(MODE_DATA_COMPRESS_PAGE) ;
cdb->MODE_SENSE.Dbd = SETBITON;
break ;
}
if (!TapeClassAllocateSrbBuffer(Srb, size) ) {
DebugPrint((1,"TapeCreatePartition: insufficient resources (ModeSel buffer)\n"));
return FALSE ;
} else {
LocalGetCompressPageData( Srb,
MinitapeExtension,
ParameterListHeader,
ParameterListBlock,
CompressPage,
bufferSize ) ;
}
return TRUE ;
}
VOID
LocalGetCompressPageData(
IN OUT PSCSI_REQUEST_BLOCK Srb,
IN OUT PMINITAPE_EXTENSION MinitapeExtension,
OUT PMODE_PARAMETER_HEADER *ParameterListHeader,
OUT PMODE_PARAMETER_BLOCK *ParameterListBlock,
OUT PMODE_DATA_COMPRESSION_PAGE *CompressPage,
OUT PULONG bufferSize
)
/*++
Routine Description:
This returns the pointers to the individule members of the
MODE_DEVICE_CONFIG_PART_PAGE
Arguments:
Srb - Supplies the SCSI request block.
MinitapeExtension - Supplies the minitape extension.
ParameterListHeader - Return pointer to this portion of the page.
ParameterListBlock - Return pointer to this poriton of the page.
CompressPage - Return pointer to this portion of the page.
bufferSize - The size of the page.
Return Value:
none
--*/
{
PMODE_DATA_COMPRESS_PAGE compressPage = Srb->DataBuffer ;
PMODE_DATA_COMPRESS_PAGE_PLUS compressPagePlus = Srb->DataBuffer ;
switch ( MinitapeExtension->DriveID ) {
case SONY_SDT2000 :
case SONY_SDT4000 :
case SONY_SDT5000 :
case SONY_SDT5200 :
*ParameterListHeader = &compressPagePlus->ParameterListHeader ;
*ParameterListBlock = &compressPagePlus->ParameterListBlock ;
*CompressPage = &compressPagePlus->DataCompressPage ;
*bufferSize = sizeof(MODE_DATA_COMPRESS_PAGE_PLUS) ;
break ;
default:
*ParameterListHeader = &compressPage->ParameterListHeader ;
*ParameterListBlock = NULL ;
*CompressPage = &compressPage->DataCompressPage ;
*bufferSize = sizeof(MODE_DATA_COMPRESS_PAGE) ;
break ;
}
return ;
}