|
|
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993
/*++
Copyright (c) 1993 - Colorado Memory Systems, Inc.
All Rights Reserved
Module Name:
send.c
Abstract:
Sends a QIC117 command to the drive.
Revision History:
--*/
//
// include files
//
#include <ntddk.h> // various NT definitions
#include <ntdddisk.h> // disk device driver I/O control codes
#include <ntiologc.h>
#include "common.h"
#include "drvtask.h" // this driver's data declarations
#include "mt1defs.h" // this driver's data declarations
#include "mt1strc.h" // this driver's data declarations
#include "q117data.h" // this driver's data declarations
STATUS
Q117iSendByte(
IN PTAPE_EXTENSION TapeExtension,
IN FIRMWARE_CMD Command
)
/*++
Routine Description:
Transmit a command to the tape drive using step pulses generated by
the FDC.
Using the Present Cylinder Number (pcn) of the FDC calculate a New
Cylinder Number (ncn) that will make the FDC generate the number of
step pulses corresponding to the command byte.
Execute a Seek with the FDC.
Sense Interrupt Status of the FDC and make sure that the pcn concurs
with the ncn, which indicates that the correct number of step pulses
were issued.
Arguments:
TapeExtension -
Command -
Return Value:
--*/
{
STATUS retval = NoErr;
SHORT statLength;
struct seek_cmd seek;
struct fdc_result result;
#if DBG
BOOLEAN save;
// Lockout commands used to receive the status
save = TapeExtension->DbgLockout;
TapeExtension->DbgLockout = TRUE;
#endif
if (TapeExtension->QControllerData->AbortRequested) {
return(DAbort);
}
if (Command >= 128) {
return(InvalCmd);
}
if (TapeExtension->QControllerData->FDC_Pcn < 128) {
seek.NCN = TapeExtension->QControllerData->FDC_Pcn + Command;
} else {
seek.NCN = TapeExtension->QControllerData->FDC_Pcn - Command;
}
seek.cmd = 0x0f;
seek.drive = (UCHAR)TapeExtension->DriveParms.DriveSelect;
(VOID) Q117iResetInterruptEvent(TapeExtension);
if ((retval = Q117iProgramFDC(
TapeExtension,
(CHAR *)&seek,
sizeof(seek),
FALSE)) != NoErr) {
return(retval);
}
if (TapeExtension->QControllerData->StartFormatMode) {
TapeExtension->FmtOp.NCN = seek.NCN;
if (TapeExtension->XferRate.XferRate == SLOW) {
CheckedDump(QIC117INFO,( "Q117i: FmtOp L_SLOW timeout %ld (decimal)\n",
TapeExtension->TapeParms.TimeOut[L_SLOW]));
retval = Q117iSleep(TapeExtension, TapeExtension->TapeParms.TimeOut[L_SLOW], TRUE);
} else {
CheckedDump(QIC117INFO,( "Q117i: FmtOp L_FAST timeout %ld (decimal)\n",
TapeExtension->TapeParms.TimeOut[L_FAST]));
retval = Q117iSleep(TapeExtension, TapeExtension->TapeParms.TimeOut[L_FAST], TRUE);
}
if ((retval == TimeOut) && (TapeExtension->FmtOp.retval == NoErr)) {
TapeExtension->QControllerData->StartFormatMode = FALSE;
TapeExtension->QControllerData->EndFormatMode = FALSE;
IoFlushAdapterBuffers(
TapeExtension->QControllerData->AdapterObject,
TapeExtension->FmtOp.MdlAddress,
TapeExtension->QControllerData->MapRegisterBase,
(PVOID)( (ULONG) MmGetMdlVirtualAddress(TapeExtension->FmtOp.MdlAddress )
+ TapeExtension->RdWrOp.BytesTransferredSoFar ),
TapeExtension->RdWrOp.TotalBytesOfTransfer,
DMA_READ );
}
if (retval == NoErr) {
retval = TapeExtension->FmtOp.retval;
}
TapeExtension->QControllerData->StartFormatMode = FALSE;
} else {
Q117iSleep(TapeExtension, mt_wt001s, TRUE);
// For some unknown reason, we occasionally miss an interrupt.
// Despite the timeout, we still press on as if we received the interrupt.
// Therefore, we go ahead and perform the sense interrupt status. If
// status register 0 is bad, then we assume that we truly did miss the
// interrupt. Otherwise, we go on as if nothing happened.
//
if ((retval = Q117iReadFDC(TapeExtension, (CHAR *)&result, &statLength))
!= NoErr) {
return(retval);
} else {
//
// If the sense interrupt status is O.K., then proceed as if
// nothing happened. If, however, there is an error returned by
// status register 0, then return a NECFLT.
//
if (! (result.ST0 & ST0_IC)) {
//
// If we timed out, then we did the sense interrupt status
// without clearing the interrupt from the interrupt controller.
// Since the FDC did not indicate an error, we assume that we
// missed the interrupt and send the EOI. Only needed for an
// 82072.
//
if (TapeExtension->QControllerData->InterfaceType != MicroChannel) {
if (result.ST0 !=
(UCHAR)(TapeExtension->DriveParms.DriveSelect | ST0_SE)) {
return(NECFlt);
}
}
if (seek.NCN != result.PCN) {
return(CmdFlt);
}
TapeExtension->QControllerData->FDC_Pcn = result.PCN;
} else {
return(NECFlt);
}
}
#if DBG
TapeExtension->DbgLockout = save;
DbgAddEntry(0x1234567b);
DbgAddEntry((UCHAR)Command);
#endif
}
return(retval);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.