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.
288 lines
5.0 KiB
288 lines
5.0 KiB
/*++
|
|
|
|
Copyright (c) 1993 - Colorado Memory Systems, Inc.
|
|
All Rights Reserved
|
|
|
|
Module Name:
|
|
|
|
erase.c
|
|
|
|
Abstract:
|
|
|
|
Does a read pass over the entire tape to create the bad block map and
|
|
writes the bad block map to the tape and zeros the tape directory.
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
|
|
--*/
|
|
|
|
//
|
|
// include files
|
|
//
|
|
|
|
#include <ntddk.h>
|
|
#include <ntddtape.h>
|
|
#include "common.h"
|
|
#include "q117.h"
|
|
#include "protos.h"
|
|
|
|
#define FCT_ID 0x0106
|
|
|
|
dStatus
|
|
q117VerifyFormat(
|
|
IN OUT PQ117_CONTEXT Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
Context -
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
dStatus status;
|
|
|
|
Context->CurrentTape.CurBadListIndex = 0;
|
|
|
|
status = q117FillTapeBlocks(
|
|
CMD_READ_VERIFY,
|
|
0,
|
|
Context->CurrentTape.LastSegment,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL,
|
|
Context);
|
|
|
|
Context->CurrentTape.CurBadListIndex = 0;
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
dStatus
|
|
q117EraseQ (
|
|
IN OUT PQ117_CONTEXT Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Writes the bad sector map already in memory (put there either by a
|
|
call to Init() or Erase()) to the tape and stomps on each entry
|
|
in the tape directory.
|
|
|
|
Arguments:
|
|
|
|
Context -
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
dStatus ret; // Return value from other routines called.
|
|
LONG i; // generic loop index
|
|
PVOLUME_TABLE_ENTRY scrbuf;
|
|
PSEGMENT_BUFFER bufferInfo;
|
|
PIO_REQUEST ioreq;
|
|
|
|
if (!q117QueueEmpty(Context)) {
|
|
|
|
return ERROR_ENCODE(ERR_PROGRAM_FAILURE, FCT_ID, 1);
|
|
|
|
}
|
|
|
|
q117ClearVolume(Context);
|
|
|
|
scrbuf = (PVOLUME_TABLE_ENTRY)q117GetFreeBuffer(&bufferInfo,Context);
|
|
|
|
if (ret = q117IssIOReq(
|
|
scrbuf,
|
|
CMD_READ,
|
|
(LONG)Context->CurrentTape.VolumeSegment * BLOCKS_PER_SEGMENT,
|
|
bufferInfo,
|
|
Context)) {
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
ioreq = q117Dequeue(WaitForItem,Context);
|
|
ret = ioreq->x.adi_hdr.status;
|
|
|
|
if (ERROR_DECODE(ret) == ERR_BAD_BLOCK_DETECTED || ret == ERR_NO_ERR) {
|
|
|
|
//
|
|
// correct data segment with Reed-Solomon and Heroic retries
|
|
//
|
|
ret = q117ReconstructSegment(ioreq,Context);
|
|
|
|
}
|
|
|
|
if (ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
//
|
|
// stomp on the signatures only
|
|
//
|
|
|
|
for (i = 0;
|
|
i < ( ( DATA_BLOCKS_PER_SEGMENT * BYTES_PER_SECTOR ) /
|
|
sizeof(VOLUME_TABLE_ENTRY));
|
|
i++) {
|
|
|
|
RtlZeroMemory(&scrbuf[i].Signature, sizeof(scrbuf->Signature));
|
|
|
|
}
|
|
|
|
//
|
|
// now write it out again!
|
|
//
|
|
|
|
if (ret = q117IssIOReq(
|
|
scrbuf,
|
|
CMD_WRITE,
|
|
(LONG)Context->CurrentTape.VolumeSegment * BLOCKS_PER_SEGMENT,
|
|
bufferInfo,
|
|
Context)) {
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
ret = q117Dequeue(WaitForItem,Context)->x.adi_hdr.status;
|
|
|
|
q117ClearVolume(Context);
|
|
|
|
q117SetTpSt(Context);
|
|
|
|
return(ret);
|
|
}
|
|
|
|
dStatus
|
|
q117EraseS (
|
|
IN OUT PQ117_CONTEXT Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Init() must be called before calling this routine. Reads the tape
|
|
directory to find the ending block of the last backup on the tape
|
|
and writes 0's to every sector from the end of the tape directory
|
|
up to and including the ending block of the last backup, and then 0's
|
|
the tape directory and rewrites the bad sector map by calling
|
|
EraseQ().
|
|
|
|
Arguments:
|
|
|
|
Context -
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
dStatus ret; // Return value from other routines called.
|
|
PVOID scrbuf;
|
|
PSEGMENT_BUFFER bufferInfo;
|
|
|
|
scrbuf = q117GetFreeBuffer(&bufferInfo, Context);
|
|
|
|
RtlZeroMemory(scrbuf, BLOCKS_PER_SEGMENT * BYTES_PER_SECTOR);
|
|
|
|
ret = q117FillTapeBlocks(
|
|
CMD_WRITE,
|
|
Context->CurrentTape.VolumeSegment,
|
|
Context->CurrentTape.LastSegment,
|
|
scrbuf,
|
|
0,
|
|
0,
|
|
bufferInfo,
|
|
Context);
|
|
|
|
Context->CurrentOperation.EndOfUsedTape =
|
|
Context->CurrentTape.LastUsedSegment =
|
|
Context->CurrentTape.VolumeSegment;
|
|
|
|
q117ClearVolume(Context);
|
|
|
|
q117SetTpSt(Context);
|
|
|
|
return(ret);
|
|
}
|
|
|
|
VOID
|
|
q117ClearVolume (
|
|
IN OUT PQ117_CONTEXT Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Clear state information for any active volume.
|
|
|
|
Arguments:
|
|
|
|
Context -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
#ifndef NO_MARKS
|
|
// Clear the mark array
|
|
Context->MarkArray.TotalMarks = 0;
|
|
Context->CurrentMark = Context->MarkArray.TotalMarks;
|
|
Context->MarkArray.MarkEntry[Context->CurrentMark].Offset = 0xffffffff;
|
|
#endif
|
|
|
|
Context->CurrentOperation.Position = TAPE_REWIND;
|
|
|
|
//
|
|
// Destroy the active volume
|
|
//
|
|
|
|
RtlZeroMemory(&Context->ActiveVolume,sizeof(Context->ActiveVolume));
|
|
Context->ActiveVolumeNumber = 0;
|
|
|
|
//
|
|
// Set tape to all available
|
|
//
|
|
Context->CurrentOperation.EndOfUsedTape =
|
|
Context->CurrentTape.LastUsedSegment =
|
|
Context->CurrentTape.VolumeSegment;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|