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

428 lines
11 KiB
C
Raw Permalink 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 1993 - COLORADO MEMORY SYSTEMS, INC.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* FILE: \SE\DRIVER\DEVICE\JUMBO\SRC\0X1102A.C
*
* FUNCTION: cqd_HighSpeedSeek
*
* PURPOSE: Execute a High Speed Seek. There are two methods of doing
* this now. First, if the Skip commands are not implemented,
* the high speed seek is accomplished by calculating the
* approximate amount of time needed at high speed to reach the
* target position and allowing the tape drive to go at 90 ips
* for that amount of time. If the Skip commands are implemented,
* the high speed seek is merely the proper command with
* a calculated offset.
*
* The Seeking is done by using either the Skip_N_Segments command
* or by using the time seeking algorithm provided by cqd_WaitSeek.
* The Skip_N_Segments commands are not reliable in all versions of
* the firmware. Only in versions for JUMBO_B and greater are the
* commands available at all and only in versions of 65 and greater
* are the Skip_N_Segment commands reliable for skipping past the
* DC erased gap.
*
* HISTORY:
* $Log: J:\se.vcs\driver\q117cd\src\0x1102a.c $
*
* Rev 1.13 15 May 1995 10:47:28 GaryKiwi
* Phoenix merge from CBW95s
*
* Rev 1.12.1.0 11 Apr 1995 18:04:06 garykiwi
* PHOENIX pass #1
*
* Rev 1.13 30 Jan 1995 14:25:08 BOBLEHMA
* Changed device_descriptor.version to cqd_context->firmware_version.
*
* Rev 1.12 14 Apr 1994 11:50:40 KEVINKES
* Changed seek slop back to previous rev and added rev seek slop if
* the drive is a Jumbo B.
*
* Rev 1.11 12 Apr 1994 14:49:52 KEVINKES
* Changed eot seek slop to 5% and rev seek slop to double the fwd seek slop.
*
* Rev 1.10 09 Mar 1994 09:48:08 KEVINKES
* Modified the setting of the reverse seek slop to be 1 if
* the firmware is greater than or equal to fw 88.
*
* Rev 1.9 17 Feb 1994 11:42:42 KEVINKES
* Added an extra parameter to WaitCC.
*
* Rev 1.8 01 Feb 1994 12:30:38 KEVINKES
* Added seek debug code.
*
* Rev 1.7 27 Jan 1994 15:58:42 KEVINKES
* Added debug code.
*
* Rev 1.6 18 Jan 1994 16:21:10 KEVINKES
* Updated debug code.
*
* Rev 1.5 14 Jan 1994 10:26:26 KEVINKES
* Modified EOT, BOT reverse seeking to only add 1 for cms drives
* with FW greater than 110.
*
* Rev 1.4 11 Jan 1994 14:39:22 KEVINKES
* Removed magic numbers.
*
* Rev 1.3 23 Nov 1993 18:49:48 KEVINKES
* Modified CHECKED_DUMP calls for debugging over the serial port.
*
* Rev 1.2 08 Nov 1993 14:04:28 KEVINKES
* Removed all bit-field structures, removed all enumerated types, changed
* all defines to uppercase, and removed all signed data types wherever
* possible.
*
* Rev 1.1 25 Oct 1993 14:38:46 KEVINKES
* Changed kdi_wt2ticks to kdi_wt004ms.
*
* Rev 1.0 18 Oct 1993 17:18:44 KEVINKES
* Initial Revision.
*
*****************************************************************************/
#define FCT_ID 0x1102a
#include "include\public\adi_api.h"
#include "include\public\frb_api.h"
#include "include\public\vendor.h"
#include "include\private\kdi_pub.h"
#include "include\private\cqd_pub.h"
#include "q117cd\include\cqd_defs.h"
#include "q117cd\include\cqd_strc.h"
#include "q117cd\include\cqd_hdr.h"
/*endinclude*/
dStatus cqd_HighSpeedSeek
(
/* INPUT PARAMETERS: */
CqdContextPtr cqd_context
/* UPDATE PARAMETERS: */
/* OUTPUT PARAMETERS: */
)
/* COMMENTS: *****************************************************************
*
* DEFINITIONS: *************************************************************/
{
/* DATA: ********************************************************************/
dStatus status=DONT_PANIC; /* dStatus or error condition.*/
dSDWord seek_offset=0l;
dUWord i;
dUByte seek_dir;
dUByte skip_n_segs;
dUWord skip;
/* CODE: ********************************************************************/
/* Determine the logical direction that the tape needs to be moved */
seek_offset = (dSDWord)((cqd_context->rd_wr_op.d_segment - 1l) -
cqd_context->operation_status.current_segment);
if (seek_offset >= 0l) {
seek_dir = FWD;
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, DBG_SEEK_FWD);
} else {
seek_dir = REV;
seek_offset = 0l - seek_offset;
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, DBG_SEEK_REV);
}
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, seek_offset);
if (seek_dir == REV || seek_offset > STOP_LEN) {
if ((status = cqd_StopTape(cqd_context)) != DONT_PANIC) {
return status;
}
if (seek_dir == FWD) {
if (cqd_context->drive_parms.seek_mode == SEEK_TIMED) {
seek_offset -= SEEK_SLOP;
} else {
seek_offset -= 1l;
}
} else {
/* seek direction is reverse */
if (cqd_context->rd_wr_op.bot ||
cqd_context->rd_wr_op.eot) {
if ((cqd_context->device_descriptor.vendor == VENDOR_CMS) &&
(cqd_context->firmware_version >= FIRM_VERSION_88)) {
seek_offset += 1l;
} else {
seek_offset += (cqd_context->tape_cfg.seg_tape_track * 45l)/1000l;
}
} else {
if ((cqd_context->drive_parms.seek_mode == SEEK_TIMED) ||
((cqd_context->device_descriptor.vendor == VENDOR_CMS) &&
(cqd_context->firmware_version >= FIRM_VERSION_60) &&
(cqd_context->firmware_version < FIRM_VERSION_80))) {
seek_offset += SEEK_SLOP;
} else {
seek_offset += 1l;
}
}
}
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, seek_offset);
switch (cqd_context->drive_parms.seek_mode) {
case SEEK_SKIP:
/* Determine the offset to be used for the Skip_N_Segment commands */
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, DBG_SEEK_PHASE);
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, 2);
if (seek_dir == FWD) {
skip_n_segs = FW_CMD_SKIP_N_FWD;
} else {
skip_n_segs = FW_CMD_SKIP_N_REV;
}
/* Skip the first bytes worth of segments */
if ((status = cqd_SendByte(
cqd_context,
skip_n_segs)) != DONT_PANIC) {
return status;
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
if ((status = cqd_SendByte(
cqd_context,
(dUByte)((seek_offset & NIBBLE_MASK) + CMD_OFFSET))) != DONT_PANIC) {
return status;
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
seek_offset >>= NIBBLE_SHIFT;
if ((status = cqd_SendByte(
cqd_context,
(dUByte)((seek_offset & NIBBLE_MASK) + CMD_OFFSET))) != DONT_PANIC) {
return status;
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
if ((status = cqd_WaitCommandComplete(
cqd_context,
cqd_context->floppy_tape_parms.time_out[PHYSICAL],
dTRUE)) != DONT_PANIC) {
return status;
}
seek_offset >>= NIBBLE_SHIFT;
for (;seek_offset != 0; --seek_offset) {
/* Skip the second bytes worth of segments */
for (i=0; i<2; ++i) {
if (i) {
skip = 1;
} else {
skip = MAX_SKIP;
}
if ((status = cqd_SendByte(
cqd_context,
skip_n_segs)) != DONT_PANIC) {
return status;
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
if ((status = cqd_SendByte(
cqd_context,
(dUByte)((skip & NIBBLE_MASK) + CMD_OFFSET))) != DONT_PANIC) {
return status;
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
if ((status = cqd_SendByte(
cqd_context,
(dUByte)((skip >> NIBBLE_SHIFT) + CMD_OFFSET))) != DONT_PANIC) {
return status;
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
if ((status = cqd_WaitCommandComplete(
cqd_context,
cqd_context->floppy_tape_parms.time_out[PHYSICAL],
dTRUE)) != DONT_PANIC) {
return status;
}
}
}
break;
case SEEK_SKIP_EXTENDED:
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, DBG_SEEK_PHASE);
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, 3);
if (seek_dir == FWD) {
if ((status = cqd_SendByte(
cqd_context,
FW_CMD_SKIP_N_FWD_EXT)) != DONT_PANIC) {
return status;
}
} else {
if ((status = cqd_SendByte(
cqd_context,
FW_CMD_SKIP_N_REV_EXT)) != DONT_PANIC) {
return status;
}
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
for (i = 0; i < MAX_SEEK_NIBBLES; i++) {
if ((status = cqd_SendByte(
cqd_context,
(dUByte)((seek_offset & NIBBLE_MASK) + CMD_OFFSET))) != DONT_PANIC) {
return status;
}
kdi_Sleep(cqd_context->kdi_context, INTERVAL_CMD, dFALSE);
seek_offset >>= NIBBLE_SHIFT;
}
if ((status = cqd_WaitCommandComplete(
cqd_context,
cqd_context->floppy_tape_parms.time_out[PHYSICAL],
dTRUE)) != DONT_PANIC) {
return status;
}
break;
default: /* SEEK_TIMED */
/* Skip segments commands are not available */
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, DBG_SEEK_PHASE);
DBG_ADD_ENTRY(QIC117DBGSEEK, cqd_context, 4);
if (((seek_dir == FWD) &&
((cqd_context->operation_status.current_track & 1) == 0)) ||
((seek_dir == REV) &&
((cqd_context->operation_status.current_track & 1) == 1))) {
if ((status = cqd_SendByte(cqd_context, FW_CMD_PHYSICAL_FWD)) !=
DONT_PANIC) {
return status;
}
} else {
if ((status = cqd_SendByte(cqd_context, FW_CMD_PHYSICAL_REV)) !=
DONT_PANIC) {
return status;
}
}
if ((status = cqd_WaitSeek(cqd_context, seek_offset)) != DONT_PANIC) {
return status;
}
if ((status = cqd_StopTape(cqd_context)) != DONT_PANIC) {
return status;
}
}
}
return status;
}