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.
427 lines
11 KiB
427 lines
11 KiB
/*****************************************************************************
|
|
*
|
|
* 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;
|
|
}
|