File:  [WindowsNT SDKs] / ntddk / src / scsi / qic117 / send.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:31:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntddk-nov-1993, HEAD
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);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.