NT4/private/ntos/dd/qic117/endback.c
2020-09-30 17:12:29 +02:00

162 lines
4.0 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1993 - Colorado Memory Systems, Inc.
All Rights Reserved
Module Name:
endback.c
Abstract:
High level end write operations. Flushes buffers and zero-fills
to the end of a segment.
Revision History:
--*/
//
// include files
//
#include <ntddk.h>
#include <ntddtape.h>
#include "common.h"
#include "q117.h"
#include "protos.h"
#define FCT_ID 0x0104
dStatus
q117EndBack(
IN OUT PQ117_CONTEXT Context
)
/*++
Routine Description:
This routine finishes writing all information to the tape for pending
update.
Uses global variable CurrentOperation.SegmentBytesRemaining, the number of bytes left in last
segment on the tape.
Arguments:
Context -
Return Value:
Possible return values: ERR_NO_ERR, any Driver error,
--*/
{
USHORT end_fill,remainder;
dStatus ret; // Return value from other routines called.
PIO_REQUEST ioreq;
//
// clear the end of the last segment buffer
//
if (Context->CurrentOperation.SegmentBytesRemaining) {
//
// clear the rest of the data
//
RtlZeroMemory(Context->CurrentOperation.SegmentPointer,Context->CurrentOperation.SegmentBytesRemaining);
end_fill = Context->CurrentOperation.SegmentBytesRemaining;
} else {
end_fill = 0;
}
//
// Set fill bytes (so bad sector re-mapping knows how much of this segment
// is zeros)
//
Context->CurrentOperation.BytesZeroFilled = end_fill;
//
// write out last block
//
if (!(ret = q117IssIOReq(
(PVOID)NULL,
CMD_WRITE,
(LONG)Context->CurrentOperation.CurrentSegment * BLOCKS_PER_SEGMENT,
NULL,
Context))) {
++Context->CurrentOperation.CurrentSegment;
//
// wait for all blocks to be written
//
while (!ret && !q117QueueEmpty(Context)) {
ioreq = q117Dequeue(WaitForItem, Context);
if (ioreq->x.adi_hdr.status && ERROR_DECODE(ioreq->x.adi_hdr.status) != ERR_BAD_BLOCK_DETECTED) {
ret = ioreq->x.adi_hdr.status;
} else {
if (ioreq->x.ioDeviceIO.crc ||
ERROR_DECODE(ioreq->x.adi_hdr.status) == ERR_BAD_BLOCK_DETECTED) {
if (!(ret = q117MapBadBlock(
ioreq,
&Context->CurrentOperation.SegmentPointer,
&Context->CurrentOperation.SegmentBytesRemaining,
&Context->CurrentOperation.CurrentSegment,
&remainder,
Context))) {
if (remainder) {
if (Context->CurrentOperation.SegmentBytesRemaining) {
//
// clear the rest of the data
//
RtlZeroMemory(Context->CurrentOperation.SegmentPointer,Context->CurrentOperation.SegmentBytesRemaining);
Context->CurrentOperation.BytesZeroFilled = Context->CurrentOperation.SegmentBytesRemaining;
}
//
// write out overflow data
//
if (!(ret=q117IssIOReq(
(PVOID)NULL,
CMD_WRITE,
(LONG)Context->CurrentOperation.CurrentSegment *
BLOCKS_PER_SEGMENT,
NULL,
Context))) {
++Context->CurrentOperation.CurrentSegment;
}
}
}
}
}
}
}
return(ret);
}