mirror of https://github.com/lianthony/NT4.0
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.
3428 lines
108 KiB
3428 lines
108 KiB
/*++
|
|
|
|
Copyright (c) 1994 - Arcada Software Inc. - All rights reserved
|
|
|
|
Module Name:
|
|
|
|
wangqic.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the device-specific routines for Wangtek QIC
|
|
drives.
|
|
|
|
Author:
|
|
|
|
Mike Colandreo (Arcada)
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "minitape.h"
|
|
|
|
#undef DebugPrint
|
|
#define DebugPrint(foo)
|
|
|
|
//
|
|
// Internal (module wide) defines that symbolize
|
|
// non-QFA mode and the two QFA mode partitions.
|
|
//
|
|
#define NOT_PARTITIONED 0 // non-QFA mode
|
|
#define DIRECTORY_PARTITION 1 // QFA mode, directory partition #
|
|
#define DATA_PARTITION 2 // QFA mode, data partition #
|
|
|
|
//
|
|
// Internal (module wide) defines that symbolize
|
|
// the Wangtek QIC drives supported by this module.
|
|
//
|
|
#define WANGTEK_5150 1 // aka the Wangtek 150
|
|
#define WANGTEK_5525 2 // aka the Wangtek 525
|
|
#define WANGTEK_5360 3 // aka the Tecmar 720
|
|
#define WANGTEK_9500 4
|
|
#define WANGTEK_9500DC 5
|
|
#define WANGTEK_5100 6 // aka the Wangtek 525
|
|
|
|
//
|
|
// Minitape extension definition.
|
|
//
|
|
typedef struct _MINITAPE_EXTENSION {
|
|
ULONG DriveID ;
|
|
ULONG CurrentPartition ;
|
|
BOOLEAN CompressionOn ;
|
|
} MINITAPE_EXTENSION, *PMINITAPE_EXTENSION ;
|
|
|
|
//
|
|
// Command extension definition.
|
|
//
|
|
|
|
typedef struct _COMMAND_EXTENSION {
|
|
|
|
ULONG CurrentState;
|
|
UCHAR densityCode;
|
|
UCHAR mediumType;
|
|
ULONG tapeBlockLength;
|
|
BOOLEAN changePartition ;
|
|
BOOLEAN final9500call ;
|
|
ULONG psudo_space_count ;
|
|
ULONG pos_type ;
|
|
|
|
} COMMAND_EXTENSION, *PCOMMAND_EXTENSION;
|
|
|
|
//
|
|
// Function Prototype(s) for internal function(s)
|
|
//
|
|
static ULONG WhichIsIt(IN PINQUIRYDATA InquiryData);
|
|
|
|
|
|
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 ;
|
|
extension->CompressionOn = FALSE ;
|
|
}
|
|
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
PMINITAPE_EXTENSION extension = MinitapeExtension;
|
|
PCOMMAND_EXTENSION tapeCmdExtension = CommandExtension ;
|
|
PTAPE_CREATE_PARTITION tapePartition = CommandParameters;
|
|
PMODE_MEDIUM_PART_PAGE modeSelectBuffer;
|
|
PCDB cdb = (PCDB) Srb->Cdb;
|
|
|
|
//
|
|
// Only support 2 partitions, QFA mode
|
|
// Partition 1 = Used as directory
|
|
// Partition 0 = used as data
|
|
//
|
|
// Note that 0 & 1 are partition numbers used
|
|
// by the drive -- they are not tape API partition
|
|
// numbers.
|
|
//
|
|
|
|
DebugPrint((3,"TapeCreatePartition: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
|
|
//
|
|
// Filter out invalid partition methods.
|
|
//
|
|
|
|
switch (tapePartition->Method) {
|
|
case TAPE_FIXED_PARTITIONS:
|
|
DebugPrint((3,"TapeCreatePartition: fixed partitions\n"));
|
|
break;
|
|
|
|
case TAPE_SELECT_PARTITIONS:
|
|
case TAPE_INITIATOR_PARTITIONS:
|
|
default:
|
|
DebugPrint((1,"TapeCreatePartition: "));
|
|
DebugPrint((1,"PartitionMethod -- operation not supported\n"));
|
|
return TAPE_STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
//
|
|
// Must rewind to BOT before one can enable/disable QFA mode.
|
|
// Changing the state of QFA mode is only valid at BOT.
|
|
//
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_REWIND;
|
|
|
|
//
|
|
// Set timeout value.
|
|
//
|
|
|
|
Srb->TimeOutValue = 480;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeCreatePartition: SendSrb (rewind)\n"));
|
|
Srb->DataTransferLength = 0 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if ( CallNumber == 1 ) {
|
|
|
|
//
|
|
// A successful rewind also confirms that there is a tape in the drive.
|
|
//
|
|
|
|
//
|
|
// Now enable/disable QFA mode in either SCSI-2 fashion or SCSI-1
|
|
// fashion depending on what sort of drive this is.
|
|
//
|
|
|
|
switch (extension->DriveID) {
|
|
case WANGTEK_9500:
|
|
case WANGTEK_9500DC:
|
|
//
|
|
// Performing mode select command, medium partition parameters page,
|
|
// to enable/disable QFA mode: set the FDP bit accordingly.
|
|
//
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_MEDIUM_PART_PAGE)) ) {
|
|
DebugPrint((1,"TapeCreatePartition: insufficient resources (modeSelectBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
modeSelectBuffer = Srb->DataBuffer ;
|
|
|
|
modeSelectBuffer->ParameterListHeader.DeviceSpecificParameter = 0x10;
|
|
|
|
modeSelectBuffer->MediumPartPage.PageCode = MODE_PAGE_MEDIUM_PARTITION;
|
|
modeSelectBuffer->MediumPartPage.PageLength = 0x06;
|
|
modeSelectBuffer->MediumPartPage.MaximumAdditionalPartitions = 1;
|
|
|
|
//
|
|
// Setup FDP bit to enable/disable "additional partition".
|
|
//
|
|
|
|
if (tapePartition->Count == 0) {
|
|
modeSelectBuffer->MediumPartPage.FDPBit = SETBITOFF;
|
|
} else {
|
|
modeSelectBuffer->MediumPartPage.FDPBit = SETBITON;
|
|
}
|
|
|
|
//
|
|
// 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 = sizeof(MODE_MEDIUM_PART_PAGE) - 4;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeCreatePartition: SendSrb (mode select)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_MEDIUM_PART_PAGE) - 4 ;
|
|
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
|
|
default:
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->PARTITION.OperationCode = SCSIOP_PARTITION;
|
|
cdb->PARTITION.Sel = 1;
|
|
cdb->PARTITION.PartitionSelect =
|
|
tapePartition->Count? DATA_PARTITION : NOT_PARTITIONED;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeCreatePartition: SendSrb (partition)\n"));
|
|
Srb->DataTransferLength = 0 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
|
|
}
|
|
}
|
|
|
|
ASSERT( CallNumber == 2 ) ;
|
|
|
|
if (tapePartition->Count == 0) {
|
|
extension->CurrentPartition = NOT_PARTITIONED;
|
|
DebugPrint((3,"TapeCreatePartition: QFA disabled\n"));
|
|
} else {
|
|
extension->CurrentPartition = DATA_PARTITION;
|
|
DebugPrint((3,"TapeCreatePartition: QFA enabled\n"));
|
|
}
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
PMINITAPE_EXTENSION extension = MinitapeExtension;
|
|
PTAPE_ERASE tapeErase = CommandParameters;
|
|
PCDB cdb = (PCDB) Srb->Cdb;
|
|
|
|
DebugPrint((3,"TapeErase: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
|
|
if (tapeErase->Immediate) {
|
|
switch (extension->DriveID) {
|
|
case WANGTEK_5150:
|
|
case WANGTEK_5360:
|
|
DebugPrint((1,"TapeErase: EraseType, immediate -- operation not supported\n"));
|
|
return TAPE_STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
DebugPrint((3,"TapeErase: immediate\n"));
|
|
}
|
|
|
|
switch (tapeErase->Type) {
|
|
case TAPE_ERASE_LONG:
|
|
DebugPrint((3,"TapeErase: long\n"));
|
|
break;
|
|
|
|
case TAPE_ERASE_SHORT:
|
|
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;
|
|
cdb->ERASE.Long = SETBITON;
|
|
|
|
//
|
|
// Set timeout value.
|
|
//
|
|
|
|
Srb->TimeOutValue = 480;
|
|
|
|
//
|
|
// 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.
|
|
|
|
--*/
|
|
|
|
{
|
|
PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
|
|
UCHAR senseKey = senseBuffer->SenseKey & 0x0F;
|
|
UCHAR adsenseq = senseBuffer->AdditionalSenseCodeQualifier;
|
|
UCHAR adsense = senseBuffer->AdditionalSenseCode;
|
|
|
|
DebugPrint((3,"TapeError: Enter routine\n"));
|
|
DebugPrint((1,"TapeError: Status 0x%.8X\n", *LastError));
|
|
|
|
if (*LastError == TAPE_STATUS_IO_DEVICE_ERROR) {
|
|
if ((senseKey == SCSI_SENSE_ABORTED_COMMAND) &&
|
|
(adsense == 0x5A) &&
|
|
(adsenseq == 0x01) ){ //operator medium removal request
|
|
|
|
*LastError = TAPE_STATUS_NO_MEDIA;
|
|
|
|
}
|
|
}
|
|
|
|
DebugPrint((1,"TapeError: Status 0x%.8X \n", *LastError));
|
|
|
|
return;
|
|
|
|
} // end TapeError()
|
|
|
|
|
|
|
|
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
|
|
)
|
|
|
|
/*++
|
|
|
|
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 cmdExtension = CommandExtension;
|
|
PTAPE_GET_DRIVE_PARAMETERS tapeGetDriveParams = CommandParameters;
|
|
PCDB cdb = (PCDB)Srb->Cdb;
|
|
PINQUIRYDATA inquiryBuffer;
|
|
PMODE_DEVICE_CONFIG_PAGE deviceConfigModeSenseBuffer;
|
|
PMODE_DATA_COMPRESS_PAGE compressionModeSenseBuffer;
|
|
PREAD_BLOCK_LIMITS_DATA blockLimitsBuffer;
|
|
PMODE_PARM_READ_WRITE_DATA blockDescripterModeSenseBuffer;
|
|
|
|
DebugPrint((3,"TapeGetDriveParameters: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
|
|
TapeClassZeroMemory(tapeGetDriveParams, sizeof(TAPE_GET_DRIVE_PARAMETERS));
|
|
|
|
if(!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_PARM_READ_WRITE_DATA)) ) {
|
|
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (blockDescripterModeSenseBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
blockDescripterModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_PARM_READ_WRITE_DATA);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetDriveParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_PARM_READ_WRITE_DATA) ;
|
|
*RetryFlags |= RETURN_ERRORS;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
if (CallNumber == 1 ) {
|
|
blockDescripterModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
if (LastError == TAPE_STATUS_SUCCESS) {
|
|
|
|
cmdExtension->mediumType = blockDescripterModeSenseBuffer->ParameterListHeader.MediumType;
|
|
cmdExtension->densityCode = blockDescripterModeSenseBuffer->ParameterListBlock.DensityCode;
|
|
cmdExtension->tapeBlockLength = blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[2];
|
|
cmdExtension->tapeBlockLength += (blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[1] << 8);
|
|
cmdExtension->tapeBlockLength += (blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[0] << 16);
|
|
|
|
} else {
|
|
|
|
cmdExtension->mediumType = DC6150;
|
|
cmdExtension->densityCode = QIC_XX;
|
|
cmdExtension->tapeBlockLength = 512;
|
|
|
|
|
|
if (((extension->DriveID == WANGTEK_5150) || (extension->DriveID == WANGTEK_5360))
|
|
&& (LastError == TAPE_STATUS_DEVICE_NOT_READY)) {
|
|
|
|
LastError = TAPE_STATUS_SUCCESS;
|
|
|
|
} else {
|
|
|
|
DebugPrint((1,"TapeGetDriveParameters: mode sense, SendSrb unsuccessful\n"));
|
|
return LastError;
|
|
|
|
}
|
|
|
|
}
|
|
if ( !TapeClassAllocateSrbBuffer( Srb, sizeof(READ_BLOCK_LIMITS_DATA)) ) {
|
|
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (blockLimitsBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
blockLimitsBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_READ_BLOCK_LIMITS;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetDriveParameters: SendSrb (read block limits)\n"));
|
|
Srb->DataTransferLength = sizeof(READ_BLOCK_LIMITS_DATA) ;
|
|
*RetryFlags |= RETURN_ERRORS;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
if (CallNumber == 2) {
|
|
blockLimitsBuffer = Srb->DataBuffer ;
|
|
|
|
if (LastError == TAPE_STATUS_SUCCESS) {
|
|
tapeGetDriveParams->MaximumBlockSize = blockLimitsBuffer->BlockMaximumSize[2];
|
|
tapeGetDriveParams->MaximumBlockSize += (blockLimitsBuffer->BlockMaximumSize[1] << 8);
|
|
tapeGetDriveParams->MaximumBlockSize += (blockLimitsBuffer->BlockMaximumSize[0] << 16);
|
|
|
|
tapeGetDriveParams->MinimumBlockSize = blockLimitsBuffer->BlockMinimumSize[1];
|
|
tapeGetDriveParams->MinimumBlockSize += (blockLimitsBuffer->BlockMinimumSize[0] << 8);
|
|
} else {
|
|
tapeGetDriveParams->MaximumBlockSize = 512;
|
|
tapeGetDriveParams->MinimumBlockSize = 512;
|
|
|
|
if (((extension->DriveID == WANGTEK_5150)||(extension->DriveID == WANGTEK_5360)) &&
|
|
(LastError == TAPE_STATUS_DEVICE_NOT_READY)) {
|
|
|
|
LastError = TAPE_STATUS_SUCCESS;
|
|
|
|
} else {
|
|
|
|
DebugPrint((1,"TapeGetDriveParameters: read block limits, SendSrb unsuccessful\n"));
|
|
return LastError;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((extension->DriveID != WANGTEK_9500) && (extension->DriveID != WANGTEK_9500DC)) {
|
|
return TAPE_STATUS_CALLBACK ;
|
|
}
|
|
//
|
|
// wangtek 9500 only
|
|
//
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DEVICE_CONFIG_PAGE)) ) {
|
|
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (deviceConfigModeSenseBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
deviceConfigModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DEVICE_CONFIG_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetDriveParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
if (CallNumber == 3 ) {
|
|
if ((extension->DriveID != WANGTEK_9500) && (extension->DriveID != WANGTEK_9500DC)) {
|
|
return TAPE_STATUS_CALLBACK ;
|
|
}
|
|
//
|
|
// wangtek 9500 only
|
|
//
|
|
|
|
deviceConfigModeSenseBuffer = Srb->DataBuffer ;
|
|
if (deviceConfigModeSenseBuffer->DeviceConfigPage.RSmk) {
|
|
|
|
tapeGetDriveParams->ReportSetmarks = TRUE;
|
|
|
|
}
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DATA_COMPRESS_PAGE)) ) {
|
|
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (compressionModeSenseBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
compressionModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DATA_COMPRESS;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DATA_COMPRESS_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetDriveParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DATA_COMPRESS_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
ASSERT(CallNumber == 4 ) ;
|
|
if ((extension->DriveID != WANGTEK_9500) && (extension->DriveID != WANGTEK_9500DC)) {
|
|
//
|
|
// wangtek 9500 only
|
|
//
|
|
compressionModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
if (compressionModeSenseBuffer->DataCompressPage.DCC) {
|
|
|
|
tapeGetDriveParams->FeaturesLow |= TAPE_DRIVE_COMPRESSION;
|
|
tapeGetDriveParams->FeaturesHigh |= TAPE_DRIVE_SET_COMPRESSION;
|
|
tapeGetDriveParams->Compression =
|
|
(compressionModeSenseBuffer->DataCompressPage.DCE? TRUE : FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (extension->DriveID) {
|
|
case WANGTEK_9500:
|
|
case WANGTEK_9500DC:
|
|
tapeGetDriveParams->ECC = 0;
|
|
tapeGetDriveParams->DataPadding = 0;
|
|
tapeGetDriveParams->MaximumPartitionCount = 2;
|
|
|
|
switch (cmdExtension->densityCode) {
|
|
case QIC_XX:
|
|
switch (cmdExtension->mediumType) {
|
|
case DC6320:
|
|
case DC6525:
|
|
case DC9100:
|
|
case DC9120:
|
|
case DC9120SL:
|
|
case DC9120XL:
|
|
case DC9200SL:
|
|
case DC9200:
|
|
case DC9200XL:
|
|
case DC9500:
|
|
case DC9500SL:
|
|
tapeGetDriveParams->DefaultBlockSize = cmdExtension->tapeBlockLength;
|
|
|
|
tapeGetDriveParams->FeaturesLow |=
|
|
TAPE_DRIVE_GET_LOGICAL_BLK;
|
|
tapeGetDriveParams->FeaturesHigh |=
|
|
TAPE_DRIVE_LOGICAL_BLK ;
|
|
break;
|
|
|
|
default:
|
|
tapeGetDriveParams->DefaultBlockSize = 512;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case QIC_525:
|
|
case QIC_1000:
|
|
case QIC_1000C:
|
|
case QIC_2GB:
|
|
// case QIC_5GB:
|
|
tapeGetDriveParams->FeaturesLow |=
|
|
TAPE_DRIVE_GET_LOGICAL_BLK;
|
|
tapeGetDriveParams->FeaturesHigh |=
|
|
TAPE_DRIVE_LOGICAL_BLK ;
|
|
|
|
tapeGetDriveParams->DefaultBlockSize = cmdExtension->tapeBlockLength;
|
|
break;
|
|
|
|
default:
|
|
tapeGetDriveParams->DefaultBlockSize = 512;
|
|
break;
|
|
}
|
|
|
|
tapeGetDriveParams->FeaturesLow |=
|
|
TAPE_DRIVE_FIXED |
|
|
TAPE_DRIVE_ERASE_LONG |
|
|
TAPE_DRIVE_ERASE_BOP_ONLY |
|
|
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 ;
|
|
|
|
tapeGetDriveParams->FeaturesHigh |=
|
|
TAPE_DRIVE_LOAD_UNLOAD |
|
|
TAPE_DRIVE_TENSION |
|
|
TAPE_DRIVE_LOCK_UNLOCK |
|
|
TAPE_DRIVE_REWIND_IMMEDIATE |
|
|
TAPE_DRIVE_SET_BLOCK_SIZE |
|
|
TAPE_DRIVE_LOAD_UNLD_IMMED |
|
|
TAPE_DRIVE_TENSION_IMMED |
|
|
TAPE_DRIVE_SET_REPORT_SMKS |
|
|
TAPE_DRIVE_ABSOLUTE_BLK |
|
|
TAPE_DRIVE_END_OF_DATA |
|
|
TAPE_DRIVE_RELATIVE_BLKS |
|
|
TAPE_DRIVE_FILEMARKS |
|
|
TAPE_DRIVE_SEQUENTIAL_FMKS |
|
|
TAPE_DRIVE_REVERSE_POSITION |
|
|
TAPE_DRIVE_WRITE_FILEMARKS |
|
|
TAPE_DRIVE_WRITE_SETMARKS |
|
|
TAPE_DRIVE_WRITE_MARK_IMMED;
|
|
break;
|
|
|
|
default:
|
|
tapeGetDriveParams->ECC = 0;
|
|
tapeGetDriveParams->Compression = 0;
|
|
tapeGetDriveParams->DataPadding = 0;
|
|
tapeGetDriveParams->ReportSetmarks = 0;
|
|
tapeGetDriveParams->MaximumPartitionCount = 2;
|
|
|
|
switch (cmdExtension->densityCode) {
|
|
case QIC_XX:
|
|
switch (cmdExtension->mediumType) {
|
|
case DC6320:
|
|
case DC6525:
|
|
tapeGetDriveParams->DefaultBlockSize = 1024;
|
|
break;
|
|
|
|
default:
|
|
tapeGetDriveParams->DefaultBlockSize = 512;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case QIC_525:
|
|
case QIC_1000:
|
|
tapeGetDriveParams->DefaultBlockSize = 1024;
|
|
break;
|
|
|
|
default:
|
|
tapeGetDriveParams->DefaultBlockSize = 512;
|
|
break;
|
|
}
|
|
|
|
if ( (extension->DriveID == WANGTEK_5525) ||
|
|
(extension->DriveID == WANGTEK_5100) ) {
|
|
|
|
tapeGetDriveParams->FeaturesLow |=
|
|
TAPE_DRIVE_ERASE_IMMEDIATE |
|
|
TAPE_DRIVE_VARIABLE_BLOCK;
|
|
|
|
tapeGetDriveParams->FeaturesHigh |=
|
|
TAPE_DRIVE_SET_BLOCK_SIZE;
|
|
|
|
} else if ((extension->DriveID == WANGTEK_9500) || (extension->DriveID == WANGTEK_9500DC)) {
|
|
tapeGetDriveParams->FeaturesLow |= TAPE_DRIVE_EJECT_MEDIA;
|
|
}
|
|
|
|
|
|
tapeGetDriveParams->FeaturesLow |=
|
|
TAPE_DRIVE_FIXED |
|
|
TAPE_DRIVE_ERASE_LONG |
|
|
TAPE_DRIVE_ERASE_BOP_ONLY |
|
|
TAPE_DRIVE_FIXED_BLOCK |
|
|
TAPE_DRIVE_WRITE_PROTECT |
|
|
TAPE_DRIVE_GET_ABSOLUTE_BLK ;
|
|
|
|
if ( extension->DriveID != WANGTEK_5360 ) {
|
|
tapeGetDriveParams->FeaturesLow |= TAPE_DRIVE_GET_LOGICAL_BLK;
|
|
}
|
|
|
|
tapeGetDriveParams->FeaturesHigh |=
|
|
TAPE_DRIVE_LOAD_UNLOAD |
|
|
TAPE_DRIVE_TENSION |
|
|
TAPE_DRIVE_LOCK_UNLOCK |
|
|
TAPE_DRIVE_REWIND_IMMEDIATE |
|
|
TAPE_DRIVE_LOAD_UNLD_IMMED |
|
|
TAPE_DRIVE_TENSION_IMMED |
|
|
TAPE_DRIVE_ABSOLUTE_BLK |
|
|
TAPE_DRIVE_END_OF_DATA |
|
|
TAPE_DRIVE_RELATIVE_BLKS |
|
|
TAPE_DRIVE_FILEMARKS |
|
|
TAPE_DRIVE_SEQUENTIAL_FMKS |
|
|
TAPE_DRIVE_REVERSE_POSITION |
|
|
TAPE_DRIVE_WRITE_FILEMARKS ;
|
|
TAPE_DRIVE_WRITE_MARK_IMMED;
|
|
|
|
if ( extension->DriveID != WANGTEK_5360 ) {
|
|
tapeGetDriveParams->FeaturesHigh |= TAPE_DRIVE_LOGICAL_BLK ;
|
|
}
|
|
|
|
if ( extension->DriveID != WANGTEK_5100 ) {
|
|
tapeGetDriveParams->FeaturesHigh |= TAPE_DRIVE_WRITE_MARK_IMMED;
|
|
}
|
|
|
|
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;
|
|
|
|
} // 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 mediaInfoBuffer;
|
|
PMODE_DEVICE_CONFIG_PAGE deviceConfigBuffer;
|
|
PMODE_PARM_READ_WRITE_DATA modeBuffer;
|
|
PUCHAR partitionBuffer;
|
|
PCDB cdb = (PCDB)Srb->Cdb;
|
|
|
|
DebugPrint((3,"TapeGetMediaParameters: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
|
|
TapeClassZeroMemory(tapeGetMediaParams, sizeof(TAPE_GET_MEDIA_PARAMETERS));
|
|
|
|
return TAPE_STATUS_CHECK_TEST_UNIT_READY;
|
|
}
|
|
|
|
if ( (extension->DriveID == WANGTEK_9500)||(extension->DriveID == WANGTEK_9500DC) ) {
|
|
|
|
if (CallNumber == 1) {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_TAPE_MEDIA_INFORMATION)) ) {
|
|
DebugPrint((1,"TapeGetMediaParameters: insufficient resources (mediaInfoBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
mediaInfoBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_MEDIUM_PARTITION;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_TAPE_MEDIA_INFORMATION) - 4;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetMediaParameters: SendSrb (mode sense #1)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_TAPE_MEDIA_INFORMATION) - 4 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (CallNumber == 2 ) {
|
|
mediaInfoBuffer = Srb->DataBuffer ;
|
|
|
|
tapeGetMediaParams->BlockSize = mediaInfoBuffer->ParameterListBlock.BlockLength[2];
|
|
tapeGetMediaParams->BlockSize += (mediaInfoBuffer->ParameterListBlock.BlockLength[1] << 8);
|
|
tapeGetMediaParams->BlockSize += (mediaInfoBuffer->ParameterListBlock.BlockLength[0] << 16);
|
|
|
|
tapeGetMediaParams->WriteProtected =
|
|
((mediaInfoBuffer->ParameterListHeader.DeviceSpecificParameter >> 7) & 0x01);
|
|
|
|
if (mediaInfoBuffer->MediumPartPage.FDPBit) {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DEVICE_CONFIG_PAGE)) ) {
|
|
DebugPrint((1,"TapeGetMediaParameters: insufficient resources (deviceConfigBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
deviceConfigBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DEVICE_CONFIG_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetMediaParameters: SendSrb (mode sense #2)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
|
|
} else {
|
|
return TAPE_STATUS_CALLBACK ;
|
|
}
|
|
|
|
}
|
|
|
|
ASSERT(CallNumber == 3) ;
|
|
|
|
if (LastError == TAPE_STATUS_CALLBACK ) {
|
|
|
|
tapeGetMediaParams->PartitionCount = 1 ;
|
|
extension->CurrentPartition = NOT_PARTITIONED;
|
|
|
|
} else {
|
|
|
|
deviceConfigBuffer = Srb->DataBuffer ;
|
|
|
|
extension->CurrentPartition =
|
|
deviceConfigBuffer->DeviceConfigPage.ActivePartition?
|
|
DIRECTORY_PARTITION : DATA_PARTITION;
|
|
|
|
tapeGetMediaParams->PartitionCount = 2;
|
|
|
|
}
|
|
|
|
} else { // non 9500 drives
|
|
|
|
if (CallNumber == 1) {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_PARM_READ_WRITE_DATA)) ) {
|
|
DebugPrint((1,"TapeGetMediaParameters: insufficient resources (modeBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
modeBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_PARM_READ_WRITE_DATA);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetMediaParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_PARM_READ_WRITE_DATA) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
ASSERT(CallNumber == 2) ;
|
|
|
|
modeBuffer = Srb->DataBuffer ;
|
|
|
|
tapeGetMediaParams->BlockSize = modeBuffer->ParameterListBlock.BlockLength[2];
|
|
tapeGetMediaParams->BlockSize += (modeBuffer->ParameterListBlock.BlockLength[1] << 8);
|
|
tapeGetMediaParams->BlockSize += (modeBuffer->ParameterListBlock.BlockLength[0] << 16);
|
|
|
|
|
|
tapeGetMediaParams->WriteProtected =
|
|
((modeBuffer->ParameterListHeader.DeviceSpecificParameter >> 7) & 0x01);
|
|
|
|
|
|
tapeGetMediaParams->PartitionCount = extension->CurrentPartition? 2 : 1 ;
|
|
|
|
}
|
|
|
|
return TAPE_STATUS_SUCCESS;
|
|
|
|
} // 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;
|
|
PCOMMAND_EXTENSION cmdExtension = CommandExtension;
|
|
PTAPE_GET_POSITION tapeGetPosition = CommandParameters;
|
|
PCDB cdb = (PCDB)Srb->Cdb;
|
|
PMODE_DATA_COMPRESS_PAGE compressionModeSenseBuffer;
|
|
PMODE_DEVICE_CONFIG_PAGE deviceConfigBuffer;
|
|
PTAPE_POSITION_DATA readPositionBuffer;
|
|
PMODE_TAPE_MEDIA_INFORMATION mediaInfoBuffer;
|
|
PMODE_PARM_READ_WRITE_DATA modeBuffer;
|
|
PUCHAR partitionBuffer;
|
|
PUCHAR absoluteBuffer;
|
|
ULONG type;
|
|
ULONG tapeBlockAddress;
|
|
|
|
DebugPrint((3,"TapeGetPosition: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
|
|
cmdExtension->pos_type = tapeGetPosition->Type;
|
|
type = tapeGetPosition->Type;
|
|
TapeClassZeroMemory(tapeGetPosition, sizeof(TAPE_GET_POSITION));
|
|
tapeGetPosition->Type = type;
|
|
cmdExtension->pos_type = type ;
|
|
cmdExtension->final9500call = FALSE ;
|
|
|
|
return TAPE_STATUS_CHECK_TEST_UNIT_READY;
|
|
}
|
|
|
|
if (!cmdExtension->final9500call &&
|
|
((extension->DriveID == WANGTEK_9500)||(extension->DriveID == WANGTEK_9500DC)) ) {
|
|
|
|
if (tapeGetPosition->Type == TAPE_LOGICAL_POSITION) {
|
|
|
|
if ( CallNumber == 1 ) {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_TAPE_MEDIA_INFORMATION)) ) {
|
|
DebugPrint((1,"TapeGetPosition: insufficient resources (mediaInfoBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
mediaInfoBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_MEDIUM_PARTITION;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_TAPE_MEDIA_INFORMATION) - 4;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetPosition: SendSrb (mode sense #1)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_TAPE_MEDIA_INFORMATION) - 4 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (CallNumber == 2 ) {
|
|
|
|
mediaInfoBuffer = Srb->DataBuffer ;
|
|
|
|
cmdExtension->densityCode = mediaInfoBuffer->ParameterListBlock.DensityCode;
|
|
cmdExtension->tapeBlockLength = mediaInfoBuffer->ParameterListBlock.BlockLength[2];
|
|
cmdExtension->tapeBlockLength += (mediaInfoBuffer->ParameterListBlock.BlockLength[1] << 8);
|
|
cmdExtension->tapeBlockLength += (mediaInfoBuffer->ParameterListBlock.BlockLength[0] << 16);
|
|
|
|
if (!mediaInfoBuffer->MediumPartPage.FDPBit) {
|
|
return TAPE_STATUS_CALLBACK ;
|
|
|
|
} else {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DEVICE_CONFIG_PAGE)) ) {
|
|
DebugPrint((1,"TapeGetPosition: insufficient resources (deviceConfigBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
deviceConfigBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DEVICE_CONFIG_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetPosition: SendSrb (mode sense #2)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
|
|
if (CallNumber == 3 ) {
|
|
if (LastError != TAPE_STATUS_CALLBACK ) {
|
|
|
|
deviceConfigBuffer = Srb->DataBuffer ;
|
|
|
|
extension->CurrentPartition =
|
|
deviceConfigBuffer->DeviceConfigPage.ActivePartition?
|
|
DIRECTORY_PARTITION : DATA_PARTITION;
|
|
|
|
} else {
|
|
|
|
extension->CurrentPartition = NOT_PARTITIONED;
|
|
|
|
}
|
|
|
|
if (cmdExtension->densityCode != QIC_2GB) {
|
|
return TAPE_STATUS_CALLBACK ;
|
|
|
|
} else {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DATA_COMPRESS_PAGE)) ) {
|
|
DebugPrint((1,"TapeGetDriveParameters: insufficient resources (compressionModeSenseBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
compressionModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DATA_COMPRESS;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DATA_COMPRESS_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetDriveParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DATA_COMPRESS_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
ASSERT (CallNumber == 4) ;
|
|
if (LastError != TAPE_STATUS_CALLBACK ) {
|
|
compressionModeSenseBuffer = Srb->DataBuffer ;
|
|
if (!compressionModeSenseBuffer->DataCompressPage.DCE) {
|
|
cmdExtension->pos_type = TAPE_PSEUDO_LOGICAL_POSITION;
|
|
}
|
|
}
|
|
|
|
if (cmdExtension->densityCode != QIC_5GB) {
|
|
|
|
cmdExtension->pos_type = TAPE_PSEUDO_LOGICAL_POSITION;
|
|
}
|
|
}
|
|
|
|
switch (cmdExtension->pos_type) {
|
|
case TAPE_ABSOLUTE_POSITION:
|
|
DebugPrint((3,"TapeGetPosition: absolute\n"));
|
|
if (cmdExtension->densityCode == QIC_5GB) {
|
|
cmdExtension->pos_type = TAPE_LOGICAL_POSITION;
|
|
}
|
|
break;
|
|
|
|
case TAPE_LOGICAL_POSITION:
|
|
DebugPrint((3,"TapeGetPosition: logical\n"));
|
|
break;
|
|
|
|
case TAPE_PSEUDO_LOGICAL_POSITION:
|
|
DebugPrint((3,"TapeGetPosition: pseudo 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 (readPositionBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
|
|
readPositionBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB10GENERIC_LENGTH;
|
|
|
|
cdb->READ_POSITION.Operation = SCSIOP_READ_POSITION;
|
|
cdb->READ_POSITION.BlockType = (cmdExtension->pos_type == TAPE_LOGICAL_POSITION)?
|
|
SETBITOFF : SETBITON;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetPosition: SendSrb (read position)\n"));
|
|
Srb->DataTransferLength = sizeof(TAPE_POSITION_DATA) ;
|
|
|
|
cmdExtension->final9500call = TRUE ;
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (cmdExtension->final9500call) {
|
|
cmdExtension->final9500call = FALSE ;
|
|
|
|
readPositionBuffer = Srb->DataBuffer ;
|
|
|
|
REVERSE_BYTES((PFOUR_BYTE)&tapeBlockAddress,
|
|
(PFOUR_BYTE)readPositionBuffer->FirstBlock);
|
|
|
|
|
|
if (cmdExtension->pos_type == TAPE_PSEUDO_LOGICAL_POSITION) {
|
|
tapeBlockAddress =
|
|
TapeClassPhysicalBlockToLogicalBlock(
|
|
cmdExtension->densityCode,
|
|
tapeBlockAddress,
|
|
cmdExtension->tapeBlockLength,
|
|
(BOOLEAN)(
|
|
(extension->CurrentPartition
|
|
== DIRECTORY_PARTITION)?
|
|
NOT_FROM_BOT : FROM_BOT
|
|
)
|
|
);
|
|
}
|
|
|
|
tapeGetPosition->Offset.HighPart = 0;
|
|
tapeGetPosition->Offset.LowPart = tapeBlockAddress;
|
|
|
|
if (cmdExtension->pos_type != TAPE_ABSOLUTE_POSITION) {
|
|
tapeGetPosition->Partition = extension->CurrentPartition;
|
|
}
|
|
}
|
|
if ((extension->DriveID != WANGTEK_9500)&&(extension->DriveID != WANGTEK_9500DC) ) {
|
|
|
|
if (CallNumber == 1 ) {
|
|
if (cmdExtension->pos_type != TAPE_LOGICAL_POSITION) {
|
|
return TAPE_STATUS_CALLBACK ;
|
|
} else {
|
|
|
|
DebugPrint((3,"TapeGetPosition: pseudo logical\n"));
|
|
|
|
cmdExtension->pos_type = TAPE_PSEUDO_LOGICAL_POSITION;
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(UCHAR)*2) ) {
|
|
DebugPrint((1,"TapeGetPosition: insufficient resources (partitionBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
partitionBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->PARTITION.OperationCode = SCSIOP_PARTITION;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetPosition: SendSrb (partition)\n"));
|
|
Srb->DataTransferLength = sizeof(UCHAR) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
if (CallNumber == 2 ) {
|
|
|
|
if ( LastError == TAPE_STATUS_CALLBACK ) {
|
|
return TAPE_STATUS_CALLBACK ;
|
|
}
|
|
|
|
partitionBuffer = Srb->DataBuffer ;
|
|
|
|
extension->CurrentPartition = *partitionBuffer;
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_PARM_READ_WRITE_DATA)) ) {
|
|
DebugPrint((1,"TapeGetPosition: insufficient resources (modeBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
modeBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_PARM_READ_WRITE_DATA);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetPosition: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_PARM_READ_WRITE_DATA) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
if (CallNumber == 3 ) {
|
|
|
|
if ( LastError != TAPE_STATUS_CALLBACK ) {
|
|
|
|
modeBuffer = Srb->DataBuffer ;
|
|
|
|
cmdExtension->densityCode = modeBuffer->ParameterListBlock.DensityCode;
|
|
cmdExtension->tapeBlockLength = modeBuffer->ParameterListBlock.BlockLength[2];
|
|
cmdExtension->tapeBlockLength += (modeBuffer->ParameterListBlock.BlockLength[1] << 8);
|
|
cmdExtension->tapeBlockLength += (modeBuffer->ParameterListBlock.BlockLength[0] << 16);
|
|
}
|
|
|
|
|
|
if ( (cmdExtension->pos_type!=TAPE_PSEUDO_LOGICAL_POSITION)&&
|
|
(cmdExtension->pos_type!=TAPE_ABSOLUTE_POSITION) ){
|
|
|
|
DebugPrint((1,"TapeGetPosition: PositionType -- operation not supported\n"));
|
|
return TAPE_STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(UCHAR)*3) ) {
|
|
DebugPrint((1,"TapeGetPosition: insufficient resources (absoluteBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
absoluteBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->REQUEST_BLOCK_ADDRESS.OperationCode = SCSIOP_REQUEST_BLOCK_ADDR;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeGetPosition: SendSrb (request block address)\n"));
|
|
Srb->DataTransferLength = sizeof(UCHAR)*3 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
ASSERT (CallNumber == 4) ;
|
|
absoluteBuffer = Srb->DataBuffer ;
|
|
|
|
tapeBlockAddress = absoluteBuffer[2];
|
|
tapeBlockAddress += (absoluteBuffer[1] << 8);
|
|
tapeBlockAddress += (absoluteBuffer[0] << 16);
|
|
|
|
if (cmdExtension->pos_type == TAPE_ABSOLUTE_POSITION) {
|
|
tapeGetPosition->Partition = 0;
|
|
tapeGetPosition->Offset.HighPart = 0;
|
|
tapeGetPosition->Offset.LowPart = tapeBlockAddress;
|
|
|
|
} else {
|
|
|
|
tapeBlockAddress =
|
|
TapeClassPhysicalBlockToLogicalBlock(
|
|
cmdExtension->densityCode,
|
|
tapeBlockAddress,
|
|
cmdExtension->tapeBlockLength,
|
|
(BOOLEAN)(
|
|
(extension->CurrentPartition
|
|
== DIRECTORY_PARTITION)?
|
|
NOT_FROM_BOT : FROM_BOT
|
|
)
|
|
);
|
|
|
|
tapeGetPosition->Offset.HighPart = 0;
|
|
tapeGetPosition->Offset.LowPart = tapeBlockAddress;
|
|
tapeGetPosition->Partition = extension->CurrentPartition;
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
DebugPrint((3,"TapeGetStatus: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
return TAPE_STATUS_CHECK_TEST_UNIT_READY;
|
|
}
|
|
|
|
ASSERT(CallNumber == 1);
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
PTAPE_PREPARE tapePrepare = CommandParameters;
|
|
PCDB cdb = (PCDB)Srb->Cdb;
|
|
|
|
DebugPrint((3,"TapePrepare: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
|
|
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 -- operation not supported\n"));
|
|
return TAPE_STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->CDB6GENERIC.Immediate = tapePrepare->Immediate;
|
|
Srb->TimeOutValue = 480;
|
|
|
|
switch (tapePrepare->Operation) {
|
|
case TAPE_LOAD:
|
|
DebugPrint((3,"TapePrepare: Operation == load\n"));
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_LOAD_UNLOAD;
|
|
cdb->CDB6GENERIC.CommandUniqueBytes[2] = 0x01;
|
|
break;
|
|
|
|
case TAPE_UNLOAD:
|
|
DebugPrint((3,"TapePrepare: Operation == unload\n"));
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_LOAD_UNLOAD;
|
|
break;
|
|
|
|
case TAPE_TENSION:
|
|
DebugPrint((3,"TapePrepare: Operation == tension\n"));
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_LOAD_UNLOAD;
|
|
cdb->CDB6GENERIC.CommandUniqueBytes[2] = 0x03;
|
|
break;
|
|
|
|
case TAPE_LOCK:
|
|
DebugPrint((3,"TapePrepare: Operation == lock\n"));
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_MEDIUM_REMOVAL;
|
|
cdb->CDB6GENERIC.CommandUniqueBytes[2] = 0x01;
|
|
break;
|
|
|
|
case TAPE_UNLOCK:
|
|
DebugPrint((3,"TapePrepare: Operation == unlock\n"));
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_MEDIUM_REMOVAL;
|
|
break;
|
|
|
|
default:
|
|
DebugPrint((1,"TapePrepare: Operation -- operation not supported\n"));
|
|
return TAPE_STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
//
|
|
// 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 cmdExtension = CommandExtension;
|
|
PTAPE_SET_DRIVE_PARAMETERS tapeSetDriveParams = CommandParameters;
|
|
PCDB cdb = (PCDB)Srb->Cdb;
|
|
PMODE_DATA_COMPRESS_PAGE compressionBuffer;
|
|
PMODE_DEVICE_CONFIG_PAGE configBuffer;
|
|
|
|
DebugPrint((3,"TapeSetDriveParameters: Enter routine\n"));
|
|
|
|
if (CallNumber == 0 ) {
|
|
|
|
if ((extension->DriveID != WANGTEK_9500) && (extension->DriveID != WANGTEK_9500DC) ){
|
|
return TAPE_STATUS_NOT_IMPLEMENTED ;
|
|
}
|
|
|
|
if (!TapeClassAllocateSrbBuffer(Srb, sizeof(MODE_DEVICE_CONFIG_PAGE)) ) {
|
|
DebugPrint((1,"TapeSetDriveParameters: insufficient resources (configBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
configBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DEVICE_CONFIG_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (CallNumber == 1 ) {
|
|
|
|
configBuffer = Srb->DataBuffer ;
|
|
|
|
configBuffer->ParameterListHeader.ModeDataLength = 0;
|
|
configBuffer->ParameterListHeader.MediumType = 0;
|
|
configBuffer->ParameterListHeader.DeviceSpecificParameter = 0x10;
|
|
configBuffer->ParameterListHeader.BlockDescriptorLength = 0;
|
|
|
|
configBuffer->DeviceConfigPage.PS = SETBITOFF;
|
|
configBuffer->DeviceConfigPage.PageCode = MODE_PAGE_DEVICE_CONFIG;
|
|
configBuffer->DeviceConfigPage.PageLength = 0x0E;
|
|
|
|
if (tapeSetDriveParams->ReportSetmarks) {
|
|
configBuffer->DeviceConfigPage.RSmk = SETBITON;
|
|
} else {
|
|
configBuffer->DeviceConfigPage.RSmk = SETBITOFF;
|
|
}
|
|
|
|
//
|
|
// 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 = sizeof(MODE_DEVICE_CONFIG_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode select)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
|
|
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
if (CallNumber == 2 ) {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DATA_COMPRESS_PAGE)) ) {
|
|
DebugPrint((1,"TapeSetDriveParameters: insufficient resources (compressionBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
compressionBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DATA_COMPRESS;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DATA_COMPRESS_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DATA_COMPRESS_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (CallNumber == 3 ) {
|
|
|
|
compressionBuffer = Srb->DataBuffer ;
|
|
|
|
if (compressionBuffer->DataCompressPage.DCC) {
|
|
|
|
compressionBuffer->ParameterListHeader.ModeDataLength = 0;
|
|
compressionBuffer->ParameterListHeader.MediumType = 0;
|
|
compressionBuffer->ParameterListHeader.DeviceSpecificParameter = 0x10;
|
|
compressionBuffer->ParameterListHeader.BlockDescriptorLength = 0;
|
|
|
|
compressionBuffer->DataCompressPage.Reserved1 = 0;
|
|
compressionBuffer->DataCompressPage.PageCode = MODE_PAGE_DATA_COMPRESS;
|
|
compressionBuffer->DataCompressPage.PageLength = 0x0E;
|
|
|
|
if (tapeSetDriveParams->Compression) {
|
|
compressionBuffer->DataCompressPage.DCE = SETBITON;
|
|
compressionBuffer->DataCompressPage.CompressionAlgorithm[3]= 3;
|
|
} else {
|
|
compressionBuffer->DataCompressPage.DCE = SETBITOFF;
|
|
}
|
|
|
|
compressionBuffer->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 = sizeof(MODE_DATA_COMPRESS_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode select)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DATA_COMPRESS_PAGE) ;
|
|
*RetryFlags |= RETURN_ERRORS;
|
|
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
} else {
|
|
|
|
return TAPE_STATUS_CALLBACK ;
|
|
}
|
|
}
|
|
ASSERT(CallNumber == 4 ) ;
|
|
|
|
if (LastError == TAPE_STATUS_INVALID_DEVICE_REQUEST) {
|
|
LastError = TAPE_STATUS_SUCCESS;
|
|
}
|
|
if (LastError == TAPE_STATUS_CALLBACK) {
|
|
LastError = TAPE_STATUS_SUCCESS;
|
|
}
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
PMINITAPE_EXTENSION extension = MinitapeExtension;
|
|
PCOMMAND_EXTENSION cmdExtension = CommandExtension;
|
|
PTAPE_SET_MEDIA_PARAMETERS tapeSetMediaParams = CommandParameters;
|
|
PMODE_PARM_READ_WRITE_DATA blockDescripterModeSenseBuffer;
|
|
PCDB cdb = (PCDB)Srb->Cdb;
|
|
PMODE_PARM_READ_WRITE_DATA modeBuffer;
|
|
|
|
DebugPrint((3,"TapeSetMediaParameters: Enter routine\n"));
|
|
|
|
if ((extension->DriveID == WANGTEK_9500) || (extension->DriveID == WANGTEK_9500DC)) {
|
|
|
|
if (CallNumber == 0) {
|
|
return TAPE_STATUS_CHECK_TEST_UNIT_READY ;
|
|
}
|
|
if (CallNumber == 1) {
|
|
|
|
if( !TapeClassAllocateSrbBuffer(Srb, sizeof(MODE_PARM_READ_WRITE_DATA)) ) {
|
|
DebugPrint((1,"TapeSetDriveParameters: insufficient resources (blockDescripterModeSenseBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
blockDescripterModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_PARM_READ_WRITE_DATA);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetDriveParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_PARM_READ_WRITE_DATA) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (CallNumber == 2 ) {
|
|
|
|
blockDescripterModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
if (cmdExtension->tapeBlockLength != tapeSetMediaParams->BlockSize) {
|
|
|
|
TapeClassZeroMemory(blockDescripterModeSenseBuffer, sizeof(MODE_PARM_READ_WRITE_DATA));
|
|
|
|
blockDescripterModeSenseBuffer->ParameterListHeader.DeviceSpecificParameter = 0x10;
|
|
blockDescripterModeSenseBuffer->ParameterListHeader.BlockDescriptorLength = MODE_BLOCK_DESC_LENGTH;
|
|
|
|
blockDescripterModeSenseBuffer->ParameterListBlock.DensityCode = 0x7F;
|
|
blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[0] =
|
|
(UCHAR)((tapeSetMediaParams->BlockSize >> 16) & 0xFF);
|
|
blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[1] =
|
|
(UCHAR)((tapeSetMediaParams->BlockSize >> 8) & 0xFF);
|
|
blockDescripterModeSenseBuffer->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 ;
|
|
} else {
|
|
return TAPE_STATUS_SUCCESS ;
|
|
}
|
|
}
|
|
return TAPE_STATUS_SUCCESS ;
|
|
|
|
} else { //non 9500
|
|
|
|
if ( CallNumber == 0 ) {
|
|
if ((extension->DriveID == WANGTEK_5150) || (extension->DriveID == WANGTEK_5360) ) {
|
|
DebugPrint((1,"TapeSetMediaParameters: driveID -- operation not supported\n"));
|
|
return TAPE_STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetMediaParameters: SendSrb (test unit ready)\n"));
|
|
Srb->DataTransferLength = 0 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if ( CallNumber == 1 ) {
|
|
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_PARM_READ_WRITE_DATA)) ) {
|
|
DebugPrint((1,"TapeSetMediaParameters: insufficient resources (blockDescripterModeSenseBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
blockDescripterModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_PARM_READ_WRITE_DATA);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetMediaParameters: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_PARM_READ_WRITE_DATA) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (CallNumber == 2 ) {
|
|
blockDescripterModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
|
|
if (tapeSetMediaParams->BlockSize) {
|
|
blockDescripterModeSenseBuffer->ParameterListHeader.ModeDataLength = 0;
|
|
blockDescripterModeSenseBuffer->ParameterListHeader.MediumType = 0;
|
|
blockDescripterModeSenseBuffer->ParameterListHeader.DeviceSpecificParameter = 0x10;
|
|
blockDescripterModeSenseBuffer->ParameterListHeader.BlockDescriptorLength = MODE_BLOCK_DESC_LENGTH;
|
|
|
|
blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[0] =
|
|
(UCHAR)((tapeSetMediaParams->BlockSize >> 16) & 0xFF);
|
|
blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[1] =
|
|
(UCHAR)((tapeSetMediaParams->BlockSize >> 8) & 0xFF);
|
|
blockDescripterModeSenseBuffer->ParameterListBlock.BlockLength[2] =
|
|
(UCHAR)(tapeSetMediaParams->BlockSize & 0xFF);
|
|
} else {
|
|
DebugPrint((1,
|
|
"SetMediaParameters: Tried to set variable block size\n"));
|
|
return TAPE_STATUS_INVALID_DEVICE_REQUEST;
|
|
}
|
|
|
|
//
|
|
// 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 == 3 );
|
|
|
|
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 extension = MinitapeExtension;
|
|
PCOMMAND_EXTENSION cmdExtension = CommandExtension ;
|
|
PTAPE_SET_POSITION tapeSetPosition = CommandParameters;
|
|
PMODE_DATA_COMPRESS_PAGE compressionModeSenseBuffer;
|
|
PMODE_DEVICE_CONFIG_PAGE deviceConfigBuffer;
|
|
PMODE_TAPE_MEDIA_INFORMATION mediaInfoBuffer;
|
|
PMODE_PARM_READ_WRITE_DATA modeBuffer;
|
|
PINQUIRYDATA inquiryBuffer;
|
|
TAPE_PHYS_POSITION physPosition;
|
|
PUCHAR partitionBuffer;
|
|
ULONG tapePositionVector;
|
|
ULONG tapeBlockLength;
|
|
ULONG driveID;
|
|
PCDB cdb = (PCDB)Srb->Cdb;
|
|
|
|
DebugPrint((3,"TapeSetPosition: Enter routine\n"));
|
|
|
|
if (CallNumber == 0) {
|
|
|
|
cmdExtension->changePartition = FALSE;
|
|
cmdExtension->pos_type = tapeSetPosition->Method ;
|
|
|
|
if (tapeSetPosition->Immediate) {
|
|
switch (tapeSetPosition->Method) {
|
|
case TAPE_REWIND:
|
|
DebugPrint((3,"TapeSetPosition: immediate\n"));
|
|
break;
|
|
|
|
case TAPE_LOGICAL_BLOCK:
|
|
case TAPE_ABSOLUTE_BLOCK:
|
|
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;
|
|
}
|
|
}
|
|
|
|
tapePositionVector = tapeSetPosition->Offset.LowPart;
|
|
cmdExtension->CurrentState = 0 ;
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 0 ) {
|
|
|
|
if ( (extension->DriveID != WANGTEK_9500) && (extension->DriveID != WANGTEK_9500) ) {
|
|
cmdExtension->CurrentState = 50 ;
|
|
|
|
} else {
|
|
|
|
if (cmdExtension->pos_type != TAPE_LOGICAL_BLOCK) {
|
|
cmdExtension->CurrentState = 10 ;
|
|
|
|
} else {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_TAPE_MEDIA_INFORMATION)) ) {
|
|
DebugPrint((1,"TapeSetPosition: insufficient resources (mediaInfoBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
mediaInfoBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_MEDIUM_PARTITION;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_TAPE_MEDIA_INFORMATION) - 4;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetPosition: SendSrb (mode sense #1)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_TAPE_MEDIA_INFORMATION) - 4 ;
|
|
|
|
cmdExtension->CurrentState = 1 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
}
|
|
if (cmdExtension->CurrentState == 1) {
|
|
mediaInfoBuffer = Srb->DataBuffer ;
|
|
|
|
cmdExtension->densityCode = mediaInfoBuffer->ParameterListBlock.DensityCode;
|
|
cmdExtension->tapeBlockLength = mediaInfoBuffer->ParameterListBlock.BlockLength[2];
|
|
cmdExtension->tapeBlockLength += (mediaInfoBuffer->ParameterListBlock.BlockLength[1] << 8);
|
|
cmdExtension->tapeBlockLength += (mediaInfoBuffer->ParameterListBlock.BlockLength[0] << 16);
|
|
|
|
if (!mediaInfoBuffer->MediumPartPage.FDPBit) {
|
|
extension->CurrentPartition = NOT_PARTITIONED;
|
|
cmdExtension->CurrentState = 3 ;
|
|
|
|
} else {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DEVICE_CONFIG_PAGE)) ) {
|
|
DebugPrint((1,"TapeSetPosition: insufficient resources (deviceConfigBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
deviceConfigBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DEVICE_CONFIG;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DEVICE_CONFIG_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetPosition: SendSrb (mode sense #2)\n"));
|
|
cmdExtension->CurrentState = 2 ;
|
|
Srb->DataTransferLength = sizeof(MODE_DEVICE_CONFIG_PAGE) ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
if (cmdExtension->CurrentState == 2) {
|
|
|
|
deviceConfigBuffer = Srb->DataBuffer ;
|
|
|
|
extension->CurrentPartition =
|
|
deviceConfigBuffer->DeviceConfigPage.ActivePartition?
|
|
DIRECTORY_PARTITION : DATA_PARTITION;
|
|
|
|
cmdExtension->CurrentState = 3 ;
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 3) {
|
|
|
|
if ( (cmdExtension->densityCode != QIC_2GB) &&
|
|
(cmdExtension->densityCode != QIC_5GB) ) {
|
|
|
|
cmdExtension->pos_type = TAPE_PSEUDO_LOGICAL_BLOCK;
|
|
cmdExtension->CurrentState = 10 ;
|
|
|
|
} else if (cmdExtension->densityCode != QIC_2GB) {
|
|
|
|
cmdExtension->CurrentState = 10 ;
|
|
|
|
} else {
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_DATA_COMPRESS_PAGE)) ) {
|
|
DebugPrint((1,"TapeSetPosition: insufficient resources (compressionModeSenseBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
compressionModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.Dbd = SETBITON;
|
|
cdb->MODE_SENSE.PageCode = MODE_PAGE_DATA_COMPRESS;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_DATA_COMPRESS_PAGE);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetPosition: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_DATA_COMPRESS_PAGE) ;
|
|
|
|
cmdExtension->CurrentState = 4 ;
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 4) {
|
|
|
|
compressionModeSenseBuffer = Srb->DataBuffer ;
|
|
|
|
if (!compressionModeSenseBuffer->DataCompressPage.DCE) {
|
|
cmdExtension->pos_type = TAPE_PSEUDO_LOGICAL_BLOCK;
|
|
}
|
|
|
|
cmdExtension->CurrentState = 10 ;
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 10 ) {
|
|
|
|
switch (tapeSetPosition->Partition) {
|
|
case 0:
|
|
break;
|
|
|
|
case DIRECTORY_PARTITION:
|
|
case DATA_PARTITION:
|
|
if (extension->CurrentPartition != NOT_PARTITIONED) {
|
|
if (tapeSetPosition->Partition != extension->CurrentPartition) {
|
|
cmdExtension->changePartition = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
// else: fall through to next case
|
|
|
|
default:
|
|
DebugPrint((1,"TapeSetPosition: Partition -- invalid parameter\n"));
|
|
return TAPE_STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
tapePositionVector = tapeSetPosition->Offset.LowPart;
|
|
|
|
if( cmdExtension->pos_type == TAPE_PSEUDO_LOGICAL_BLOCK) {
|
|
|
|
physPosition =
|
|
TapeClassLogicalBlockToPhysicalBlock(
|
|
cmdExtension->densityCode,
|
|
tapePositionVector,
|
|
cmdExtension->tapeBlockLength,
|
|
(BOOLEAN)(
|
|
(extension->CurrentPartition
|
|
== DIRECTORY_PARTITION)?
|
|
NOT_FROM_BOT : FROM_BOT
|
|
)
|
|
);
|
|
|
|
tapePositionVector = physPosition.SeekBlockAddress;
|
|
|
|
DebugPrint((3,"TapeSetPosition: pseudo logical\n"));
|
|
|
|
}
|
|
|
|
//
|
|
// 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 (cmdExtension->pos_type) {
|
|
case TAPE_ABSOLUTE_BLOCK:
|
|
DebugPrint((3,"TapeSetPosition: method == locate (absolute)\n"));
|
|
if (cmdExtension->densityCode == QIC_5GB) {
|
|
cmdExtension->pos_type = TAPE_LOGICAL_BLOCK;
|
|
DebugPrint((3,"TapeSetPosition: method == locate (logical absolute, 5GB)\n"));
|
|
}
|
|
break;
|
|
|
|
case TAPE_LOGICAL_BLOCK:
|
|
DebugPrint((3,"TapeSetPosition: method == locate (logical)\n"));
|
|
break;
|
|
|
|
case TAPE_PSEUDO_LOGICAL_BLOCK:
|
|
DebugPrint((3,"TapeSetPosition: method == locate (pseudo logical)\n"));
|
|
break;
|
|
}
|
|
|
|
Srb->TimeOutValue = 480;
|
|
cmdExtension->CurrentState = 12 ;
|
|
|
|
cmdExtension->psudo_space_count = 0 ;
|
|
|
|
switch (cmdExtension->pos_type) {
|
|
case TAPE_REWIND:
|
|
DebugPrint((3,"TapeSetPosition: method == rewind\n"));
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_REWIND;
|
|
break;
|
|
|
|
case TAPE_PSEUDO_LOGICAL_BLOCK:
|
|
if ( physPosition.SpaceBlockCount != 0 ) {
|
|
cmdExtension->psudo_space_count = physPosition.SpaceBlockCount ;
|
|
cmdExtension->CurrentState = 11 ;
|
|
}
|
|
/* fall through */
|
|
|
|
case TAPE_ABSOLUTE_BLOCK:
|
|
case TAPE_LOGICAL_BLOCK:
|
|
Srb->CdbLength = CDB10GENERIC_LENGTH;
|
|
cdb->LOCATE.OperationCode = SCSIOP_LOCATE;
|
|
cdb->LOCATE.CPBit = cmdExtension->changePartition? SETBITON : SETBITOFF;
|
|
cdb->LOCATE.BTBit = (cmdExtension->pos_type == TAPE_LOGICAL_BLOCK)?
|
|
SETBITOFF : SETBITON;
|
|
cdb->LOCATE.LogicalBlockAddress[1] =
|
|
(UCHAR)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->LOCATE.LogicalBlockAddress[2] =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->LOCATE.LogicalBlockAddress[3] =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
if (cmdExtension->changePartition &&
|
|
(tapeSetPosition->Partition == DIRECTORY_PARTITION)) {
|
|
cdb->LOCATE.Partition = 1;
|
|
}
|
|
break;
|
|
|
|
case TAPE_SPACE_END_OF_DATA:
|
|
DebugPrint((3,"TapeSetPosition: method == space to end-of-data\n"));
|
|
|
|
|
|
Srb->TimeOutValue = 9600;
|
|
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
|
|
cdb->SPACE_TAPE_MARKS.Code = 3;
|
|
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)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
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)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
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)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
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 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
|
|
if (cmdExtension->CurrentState == 11 ) {
|
|
|
|
//
|
|
// Zero CDB in SRB on stack.
|
|
//
|
|
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
|
|
DebugPrint((3,"TapeSetPosition: method == locate (pseudo logical) + space block(s)\n"));
|
|
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
|
|
cdb->SPACE_TAPE_MARKS.Code = 0;
|
|
cdb->SPACE_TAPE_MARKS.NumMarksMSB =
|
|
(UCHAR)((cmdExtension->psudo_space_count >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((cmdExtension->psudo_space_count >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(cmdExtension->psudo_space_count & 0xFF);
|
|
Srb->TimeOutValue = 480;
|
|
|
|
Srb->DataTransferLength = 0 ;
|
|
|
|
cmdExtension->CurrentState = 12 ;
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 12 ) {
|
|
|
|
if (cmdExtension->changePartition ) {
|
|
extension->CurrentPartition = tapeSetPosition->Partition;
|
|
}
|
|
return TAPE_STATUS_SUCCESS ;
|
|
}
|
|
|
|
//
|
|
// NON 9500 drives
|
|
//
|
|
|
|
if (cmdExtension->CurrentState == 50 ) {
|
|
|
|
if (cmdExtension->pos_type != TAPE_LOGICAL_BLOCK) {
|
|
|
|
cmdExtension->CurrentState = 60 ;
|
|
|
|
} else {
|
|
|
|
DebugPrint((3,"TapeSetPosition: pseudo logical\n"));
|
|
|
|
cmdExtension->pos_type = TAPE_PSEUDO_LOGICAL_BLOCK;
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(UCHAR)*2) ) {
|
|
DebugPrint((1,"TapeSetPosition: insufficient resources (partitionBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
partitionBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->PARTITION.OperationCode = SCSIOP_PARTITION;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetPosition: SendSrb (partition)\n"));
|
|
Srb->DataTransferLength = sizeof(UCHAR) ;
|
|
|
|
cmdExtension->CurrentState = 51 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
if (cmdExtension->CurrentState == 51 ) {
|
|
|
|
partitionBuffer = Srb->DataBuffer ;
|
|
extension->CurrentPartition = *partitionBuffer;
|
|
|
|
if ((tapeSetPosition->Partition != 0) &&
|
|
(extension->CurrentPartition == NOT_PARTITIONED)) {
|
|
DebugPrint((1,"TapeSetPosition: Partition -- invalid parameter\n"));
|
|
return TAPE_STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!TapeClassAllocateSrbBuffer( Srb, sizeof(MODE_PARM_READ_WRITE_DATA)) ) {
|
|
DebugPrint((1,"TapeSetPosition: insufficient resources (modeBuffer)\n"));
|
|
return TAPE_STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
modeBuffer = Srb->DataBuffer ;
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
|
|
cdb->MODE_SENSE.AllocationLength = sizeof(MODE_PARM_READ_WRITE_DATA);
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetPosition: SendSrb (mode sense)\n"));
|
|
Srb->DataTransferLength = sizeof(MODE_PARM_READ_WRITE_DATA) ;
|
|
|
|
cmdExtension->CurrentState = 52 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 52 ) {
|
|
modeBuffer = Srb->DataBuffer ;
|
|
|
|
cmdExtension->densityCode = modeBuffer->ParameterListBlock.DensityCode;
|
|
cmdExtension->tapeBlockLength = modeBuffer->ParameterListBlock.BlockLength[2];
|
|
cmdExtension->tapeBlockLength += (modeBuffer->ParameterListBlock.BlockLength[1] << 8);
|
|
cmdExtension->tapeBlockLength += (modeBuffer->ParameterListBlock.BlockLength[0] << 16);
|
|
|
|
if (tapeSetPosition->Partition == 0) {
|
|
cmdExtension->CurrentState = 54 ;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->PARTITION.OperationCode = SCSIOP_PARTITION;
|
|
cdb->PARTITION.Sel = 1;
|
|
cdb->PARTITION.PartitionSelect = (UCHAR)tapeSetPosition->Partition;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetPosition: SendSrb (partition)\n"));
|
|
Srb->DataTransferLength = 0 ;
|
|
|
|
cmdExtension->CurrentState = 53 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
}
|
|
if (cmdExtension->CurrentState == 53 ) {
|
|
|
|
extension->CurrentPartition = tapeSetPosition->Partition;
|
|
cmdExtension->CurrentState = 54 ;
|
|
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 54 ) {
|
|
|
|
cmdExtension->CurrentState = 55 ;
|
|
|
|
if ((cmdExtension->pos_type == TAPE_SPACE_END_OF_DATA) &&
|
|
((extension->DriveID == WANGTEK_5150) || (extension->DriveID == WANGTEK_5360)) ) {
|
|
|
|
DebugPrint((1,"TapeSetPosition: method == rewind before space EOD\n"));
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_REWIND;
|
|
|
|
//
|
|
// Set timeout value.
|
|
//
|
|
|
|
Srb->TimeOutValue = 180;
|
|
|
|
//
|
|
// Send SCSI command (CDB) to device
|
|
//
|
|
|
|
DebugPrint((3,"TapeSetPosition: method == rewind before space EOD\n"));
|
|
Srb->DataTransferLength = 0 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 55 ) {
|
|
tapePositionVector = tapeSetPosition->Offset.LowPart;
|
|
|
|
physPosition =
|
|
TapeClassLogicalBlockToPhysicalBlock(
|
|
cmdExtension->densityCode,
|
|
tapePositionVector,
|
|
cmdExtension->tapeBlockLength,
|
|
(BOOLEAN)(
|
|
(extension->CurrentPartition
|
|
== DIRECTORY_PARTITION)?
|
|
NOT_FROM_BOT : FROM_BOT
|
|
)
|
|
);
|
|
|
|
tapePositionVector = physPosition.SeekBlockAddress;
|
|
cmdExtension->CurrentState = 60 ;
|
|
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 60 ) {
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
cdb->CDB6GENERIC.Immediate = tapeSetPosition->Immediate;
|
|
|
|
cmdExtension->CurrentState = 62 ;
|
|
|
|
switch (cmdExtension->pos_type) {
|
|
case TAPE_REWIND:
|
|
DebugPrint((3,"TapeSetPosition: method == rewind\n"));
|
|
cdb->CDB6GENERIC.OperationCode = SCSIOP_REWIND;
|
|
Srb->TimeOutValue = 180;
|
|
break;
|
|
|
|
case TAPE_PSEUDO_LOGICAL_BLOCK:
|
|
if ( physPosition.SpaceBlockCount != 0 ) {
|
|
cmdExtension->psudo_space_count = physPosition.SpaceBlockCount ;
|
|
cmdExtension->CurrentState = 61 ;
|
|
}
|
|
/* fall through */
|
|
|
|
case TAPE_ABSOLUTE_BLOCK:
|
|
DebugPrint((3,"TapeSetPosition: method == seek block (absolute)\n"));
|
|
cdb->SEEK_BLOCK.OperationCode = SCSIOP_SEEK_BLOCK;
|
|
cdb->SEEK_BLOCK.BlockAddress[0] =
|
|
(UCHAR)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->SEEK_BLOCK.BlockAddress[1] =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->SEEK_BLOCK.BlockAddress[2] =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
Srb->TimeOutValue = 480;
|
|
|
|
break;
|
|
|
|
case TAPE_SPACE_END_OF_DATA:
|
|
|
|
DebugPrint((1,"TapeSetPosition: method == space to end-of-data\n"));
|
|
|
|
cdb->CDB6GENERIC.Immediate = tapeSetPosition->Immediate;
|
|
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
|
|
cdb->SPACE_TAPE_MARKS.Code = 3;
|
|
|
|
Srb->TimeOutValue = 960;
|
|
|
|
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)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
Srb->TimeOutValue = 4100;
|
|
break;
|
|
|
|
case TAPE_SPACE_FILEMARKS:
|
|
DebugPrint((3,"TapeSetPosition: method == space blocks\n"));
|
|
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
|
|
cdb->SPACE_TAPE_MARKS.Code = 1;
|
|
cdb->SPACE_TAPE_MARKS.NumMarksMSB =
|
|
(UCHAR)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
Srb->TimeOutValue = 4100;
|
|
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)((tapePositionVector >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((tapePositionVector >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(tapePositionVector & 0xFF);
|
|
Srb->TimeOutValue = 4100;
|
|
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 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
if (cmdExtension->CurrentState == 61 ) {
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
DebugPrint((3,"TapeSetPosition: method == space block(s)\n"));
|
|
cdb->SPACE_TAPE_MARKS.OperationCode = SCSIOP_SPACE;
|
|
cdb->SPACE_TAPE_MARKS.Code = 0;
|
|
cdb->SPACE_TAPE_MARKS.NumMarksMSB =
|
|
(UCHAR)((cmdExtension->psudo_space_count >> 16) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarks =
|
|
(UCHAR)((cmdExtension->psudo_space_count >> 8) & 0xFF);
|
|
cdb->SPACE_TAPE_MARKS.NumMarksLSB =
|
|
(UCHAR)(cmdExtension->psudo_space_count & 0xFF);
|
|
|
|
cmdExtension->CurrentState = 62 ;
|
|
|
|
return TAPE_STATUS_SEND_SRB_AND_CALLBACK ;
|
|
}
|
|
|
|
ASSERT(cmdExtension->CurrentState == 62 ) ;
|
|
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;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Prepare SCSI command (CDB)
|
|
//
|
|
|
|
Srb->CdbLength = CDB6GENERIC_LENGTH;
|
|
TapeClassZeroMemory(cdb, MAXIMUM_CDB_SIZE);
|
|
|
|
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);
|
|
|
|
//
|
|
// 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,"WANGTEK ",8) == 8) {
|
|
|
|
if (TapeClassCompareMemory(InquiryData->ProductId,"51000 SCSI ",12) == 12) {
|
|
return WANGTEK_5525;
|
|
}
|
|
|
|
if (TapeClassCompareMemory(InquiryData->ProductId,"51000HTSCSI ",12) == 12) {
|
|
return WANGTEK_5100;
|
|
}
|
|
|
|
if (TapeClassCompareMemory(InquiryData->ProductId,"5525ES SCSI ",12) == 12) {
|
|
return WANGTEK_5525;
|
|
}
|
|
|
|
if (TapeClassCompareMemory(InquiryData->ProductId,"5360ES SCSI ",12) == 12) {
|
|
return WANGTEK_5360;
|
|
}
|
|
|
|
if (TapeClassCompareMemory(InquiryData->ProductId,"5150ES SCSI ",12) == 12) {
|
|
return WANGTEK_5150;
|
|
}
|
|
|
|
if (TapeClassCompareMemory(InquiryData->ProductId,"9500 ",7) == 7) {
|
|
return WANGTEK_9500;
|
|
}
|
|
|
|
if (TapeClassCompareMemory(InquiryData->ProductId,"9500 DC",7) == 7) {
|
|
return WANGTEK_9500DC;
|
|
}
|
|
|
|
}
|
|
return 0;
|
|
}
|