mirror of
https://github.com/marciot/mac-tip.git
synced 2025-01-15 07:33:13 +00:00
Major enhancements for Jaz drives
- Added command to spin down cartridges to command line - Improved console diagnostics - Report SCSI short reads - Report last error - Report media change - Report disk at speed - Report spare sectors - Report detailed testing steps - Supress unsuported commands on Jaz drive while: - Enabling early recovery - Reading defects list - Fix short reads on Jaz drives during: - Cartridge status - Set error recovery
This commit is contained in:
parent
dcfa0958a6
commit
c719c8d7dd
@ -47,6 +47,7 @@ bool process_command() {
|
|||||||
case 'h': print_help(); break;
|
case 'h': print_help(); break;
|
||||||
case 'l': scan_bus(); break;
|
case 'l': scan_bus(); break;
|
||||||
case 's': iomega_spin_up_cartridge(arg_val); break;
|
case 's': iomega_spin_up_cartridge(arg_val); break;
|
||||||
|
case 'p': iomega_spin_down_cartridge(arg_val); break;
|
||||||
case 'r': scsi_reset(); break;
|
case 'r': scsi_reset(); break;
|
||||||
case 'e': mac_eject(arg_val); break;
|
case 'e': mac_eject(arg_val); break;
|
||||||
case 'i': dev_info(arg_val); break;
|
case 'i': dev_info(arg_val); break;
|
||||||
@ -83,6 +84,7 @@ void print_help() {
|
|||||||
|
|
||||||
"\nIomega device operations on SCSI device:\n"
|
"\nIomega device operations on SCSI device:\n"
|
||||||
" spin [n] : spin up a cartridge\n"
|
" spin [n] : spin up a cartridge\n"
|
||||||
|
" pause [n] : spin down a cartridge\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,19 @@ OSErr iomega_spin_down_and_eject( int id ) {
|
|||||||
return scsi_cmd(id, cmd, sizeof(cmd), 0, 0, 0, 0);
|
return scsi_cmd(id, cmd, sizeof(cmd), 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OSErr iomega_spin_down_cartridge( int id ) {
|
||||||
|
// issue an Asynchronous STOP command to induce spindown
|
||||||
|
char cmd[6] = {
|
||||||
|
SCSI_Cmd_StartStopUnit,
|
||||||
|
1, // set the IMMED bit for offline
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
return scsi_cmd(id, cmd, sizeof(cmd), 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
OSErr iomega_set_prevent_removal( int id, bool lock) {
|
OSErr iomega_set_prevent_removal( int id, bool lock) {
|
||||||
OSErr err;
|
OSErr err;
|
||||||
char cmd[6] = {
|
char cmd[6] = {
|
||||||
|
@ -4,5 +4,6 @@ typedef Boolean bool;
|
|||||||
|
|
||||||
OSErr iomega_spin_up_cartridge(int id);
|
OSErr iomega_spin_up_cartridge(int id);
|
||||||
OSErr iomega_spin_down_and_eject(int id);
|
OSErr iomega_spin_down_and_eject(int id);
|
||||||
|
OSErr iomega_spin_down_cartridge(int id);
|
||||||
OSErr iomega_set_prevent_removal(int id, bool lock);
|
OSErr iomega_set_prevent_removal(int id, bool lock);
|
||||||
OSErr iomega_eject_cartridge(int id);
|
OSErr iomega_eject_cartridge(int id);
|
||||||
|
@ -61,8 +61,11 @@ OSErr scsi_cmd(int id, void *cmd, size_t clen, void *buff, size_t siz, size_t cn
|
|||||||
case SCSI_READ: io_err = SCSIRead( (Ptr) TIB ); break;
|
case SCSI_READ: io_err = SCSIRead( (Ptr) TIB ); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
if (io_err != noErr) {
|
if (io_err == scPhaseErr && flags & SCSI_READ) {
|
||||||
printf("SCSI Read/Write Error: %d\n", io_err);
|
printf("\nSCSI phase error; less data delivered than requested\n");
|
||||||
|
}
|
||||||
|
else if (io_err != noErr) {
|
||||||
|
printf("\nSCSI Read/Write Error: %d\n", io_err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("SCSICmd Error: %d\n", err);
|
printf("SCSICmd Error: %d\n", err);
|
||||||
|
@ -161,7 +161,7 @@ void WndProc(long iMessage, uint16_t wParam) {
|
|||||||
SpinUpIomegaCartridge(CurrentDevice);
|
SpinUpIomegaCartridge(CurrentDevice);
|
||||||
break;
|
break;
|
||||||
case DISK_AT_SPEED:
|
case DISK_AT_SPEED:
|
||||||
printf("Testing the disk\n");
|
printf("\nTesting the disk\n");
|
||||||
if(TestingPhase != READY_TO_TEST) {
|
if(TestingPhase != READY_TO_TEST) {
|
||||||
PrepareToBeginTesting();
|
PrepareToBeginTesting();
|
||||||
}
|
}
|
||||||
@ -339,6 +339,15 @@ void PaintCenteredValue(int Xleft, int Ytop, int XWidth, int YHeight, long value
|
|||||||
*
|
*
|
||||||
* This paints the two columns of testing statistics on the test minitor window.
|
* This paints the two columns of testing statistics on the test minitor window.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
char *FindErrorString(long error) {
|
||||||
|
char *errStr = 0;
|
||||||
|
for (int i = 0; errorTypeList[i].str; i++) {
|
||||||
|
errStr = errorTypeList[i].str;
|
||||||
|
if (errorTypeList[i].code == error) break;
|
||||||
|
}
|
||||||
|
return errStr;
|
||||||
|
}
|
||||||
|
|
||||||
void PaintTestStatistics(bool Active) {
|
void PaintTestStatistics(bool Active) {
|
||||||
char szString[40];
|
char szString[40];
|
||||||
// assemble and paint the sector testing range
|
// assemble and paint the sector testing range
|
||||||
@ -361,12 +370,7 @@ void PaintTestStatistics(bool Active) {
|
|||||||
PaintCenteredString(76, 155, 126, 14, szString, Active);
|
PaintCenteredString(76, 155, 126, 14, szString, Active);
|
||||||
|
|
||||||
// show the LastError
|
// show the LastError
|
||||||
char *errStr = 0;
|
PaintCenteredString(76, 172, 126, 14, FindErrorString(LastError), Active);
|
||||||
for (int i = 0; errorTypeList[i].str; i++) {
|
|
||||||
errStr = errorTypeList[i].str;
|
|
||||||
if (errorTypeList[i].code == LastError) break;
|
|
||||||
}
|
|
||||||
PaintCenteredString(76, 172, 126, 14, errStr, Active);
|
|
||||||
|
|
||||||
// show the elapsed time
|
// show the elapsed time
|
||||||
CvrtSecondsToHMSstring(szString, SecondsElapsed);
|
CvrtSecondsToHMSstring(szString, SecondsElapsed);
|
||||||
|
@ -282,6 +282,8 @@ void PaintTheBarGraphs(bool Active);
|
|||||||
void PaintTestStatistics(bool Active);
|
void PaintTestStatistics(bool Active);
|
||||||
void CvrtSecondsToHMSstring(char *szString, long seconds);
|
void CvrtSecondsToHMSstring(char *szString, long seconds);
|
||||||
|
|
||||||
|
char *FindErrorString(long error);
|
||||||
|
|
||||||
void UpdateCurrentSector();
|
void UpdateCurrentSector();
|
||||||
void UpdateRunTimeDisplay();
|
void UpdateRunTimeDisplay();
|
||||||
void UpdateRunPhaseDisplay();
|
void UpdateRunPhaseDisplay();
|
||||||
@ -301,9 +303,9 @@ void GetCommandDetails(char command, char &cmd_flags, char &cmd_length);
|
|||||||
long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, size_t IoBufLen);
|
long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, size_t IoBufLen);
|
||||||
long EnumerateIomegaDevices(uint8_t *DrivesSkipped);
|
long EnumerateIomegaDevices(uint8_t *DrivesSkipped);
|
||||||
long GetModePage(short Device, short PageToGet, void *pBuffer, short BufLen);
|
long GetModePage(short Device, short PageToGet, void *pBuffer, short BufLen);
|
||||||
long SetModePage(short Device, void *pBuffer);
|
long SetModePage(short Device, void *pBuffer, short BufLen);
|
||||||
void ModifyModePage(char *PageBuff, char eec, char retries);
|
void ModifyModePage(char *PageBuff, char eec, char retries);
|
||||||
void SetErrorRecovery(bool Retries, bool ECC, bool Testing);
|
long SetErrorRecovery(bool Retries, bool ECC, bool Testing);
|
||||||
long GetNonSenseData(short Device, short DataPage, void *Buffer, short BufLen);
|
long GetNonSenseData(short Device, short DataPage, void *Buffer, short BufLen);
|
||||||
long LockCurrentDrive();
|
long LockCurrentDrive();
|
||||||
long UnlockCurrentDrive();
|
long UnlockCurrentDrive();
|
||||||
|
@ -6,8 +6,28 @@
|
|||||||
#include "tip.h"
|
#include "tip.h"
|
||||||
|
|
||||||
//#define DEMO
|
//#define DEMO
|
||||||
|
|
||||||
|
/* The original TIP seems to request more data than is supplied by
|
||||||
|
* certain commands. While this appears to be allowed, it causes
|
||||||
|
* SCSI phase errors to be reported. Setting NO_EXCESS_READS will
|
||||||
|
* adjust the reads to to the max size before such errors occur.
|
||||||
|
*/
|
||||||
#define NO_EXCESS_READS
|
#define NO_EXCESS_READS
|
||||||
|
|
||||||
|
/* The original TIP will always try to enable Early Recovery. This
|
||||||
|
* fails on certain Jaz drives. While the original TIP will then
|
||||||
|
* retry without Early Recovery, this will cause many errors to be
|
||||||
|
* reported. Enable SUPRESS_ER_ERRORS to prevent this from problem
|
||||||
|
* from happening as frequently
|
||||||
|
*/
|
||||||
|
#define SUPRESS_ER_ERRORS
|
||||||
|
|
||||||
|
/* The original TIP will always try to read the defects list, but
|
||||||
|
* not all drives support this, causing many errors to be shown.
|
||||||
|
* Setting SUPPRESS_DEFECTS_ERROR will silence these errors.
|
||||||
|
*/
|
||||||
|
#define SUPPRESS_DEFECTS_ERROR
|
||||||
|
|
||||||
#define MAKE_LITTLE_ENDIAN(a) a // Don't do anything on 68000
|
#define MAKE_LITTLE_ENDIAN(a) a // Don't do anything on 68000
|
||||||
#define MAKE_BIG_ENDIAN(a) a // Don't do anything on 68000
|
#define MAKE_BIG_ENDIAN(a) a // Don't do anything on 68000
|
||||||
|
|
||||||
@ -96,6 +116,13 @@ long DriveCount = 0;
|
|||||||
long JazDrive = 0; // true if the current drive
|
long JazDrive = 0; // true if the current drive
|
||||||
long CartridgeStatus = DISK_NOT_PRESENT;
|
long CartridgeStatus = DISK_NOT_PRESENT;
|
||||||
|
|
||||||
|
#ifdef SUPRESS_ER_ERRORS
|
||||||
|
Boolean SupressEarlyRecovery = false;
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPRESS_DEFECTS_ERROR
|
||||||
|
Boolean SupressDefectsError = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long StartingInstant;
|
unsigned long StartingInstant;
|
||||||
|
|
||||||
// ----------------------------- Run Time Variables ------------------------------
|
// ----------------------------- Run Time Variables ------------------------------
|
||||||
@ -215,6 +242,7 @@ long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, size_t IoBufLen) {
|
|||||||
(long(sense_data.ascq) << 8) |
|
(long(sense_data.ascq) << 8) |
|
||||||
(long(sense_data.key) );
|
(long(sense_data.key) );
|
||||||
if(res == MEDIA_CHANGE_CODE) {
|
if(res == MEDIA_CHANGE_CODE) {
|
||||||
|
printf("Media change signalled. Most recent error can be ignored\n\n");
|
||||||
int index = GetDriveEntryOffset(Device);
|
int index = GetDriveEntryOffset(Device);
|
||||||
DriveArray[index].flags |= MEDIA_CHANGED;
|
DriveArray[index].flags |= MEDIA_CHANGED;
|
||||||
return 0;
|
return 0;
|
||||||
@ -312,13 +340,18 @@ long GetModePage(short Device, short PageToGet, void *pBuffer, short BufLen) {
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SET MODE PAGE
|
* SET MODE PAGE
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
long SetModePage(short Device, void *pBuffer) {
|
long SetModePage(short Device, void *pBuffer, short BufLen) {
|
||||||
char* ebx = (char*) pBuffer; // get a pointer to the top of buffer
|
unsigned char* ebx = (unsigned char*) pBuffer; // get a pointer to the top of buffer
|
||||||
char ecx = ebx[0] + 1; // adjust it up by one
|
unsigned char ecx = ebx[0] + 1; // adjust it up by one
|
||||||
|
|
||||||
ebx[0] = 0; // now clear the two reserved bytes
|
ebx[0] = 0; // now clear the two reserved bytes
|
||||||
ebx[2] = 0;
|
ebx[2] = 0;
|
||||||
|
|
||||||
|
if(ecx != BufLen) {
|
||||||
|
printf("Length error in SetModePage %d != %d\n\n", BufLen, (int) ecx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char Scsi[6] = {0}; // init the SCSI parameter block
|
char Scsi[6] = {0}; // init the SCSI parameter block
|
||||||
Scsi[0] = SCSI_Cmd_ModeSelect; // set the command
|
Scsi[0] = SCSI_Cmd_ModeSelect; // set the command
|
||||||
Scsi[1] = 0x10; // set the Page Format bit
|
Scsi[1] = 0x10; // set the Page Format bit
|
||||||
@ -343,16 +376,21 @@ void ModifyModePage(char *PageBuff, char ecc, char retries) {
|
|||||||
ebx[8] = retries; // then set the write count too
|
ebx[8] = retries; // then set the write count too
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
|
long SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
|
||||||
char PageBuff[40];
|
char PageBuff[40];
|
||||||
|
|
||||||
#ifdef NO_EXCESS_READS
|
#ifdef NO_EXCESS_READS
|
||||||
// Limit reads to 20 bytes on Zip to prevent controller errors
|
// Limit reads to 20 bytes on Zip (24 bytes on Jaz) to prevent controller errors
|
||||||
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, JazDrive ? sizeof(PageBuff) : 20);
|
const short pageBuffLen = JazDrive ? 24 : 20;
|
||||||
#else
|
#else
|
||||||
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, sizeof(PageBuff));
|
const short pageBuffLen = sizeof(PageBuff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
long eax = GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, pageBuffLen);
|
||||||
|
if(eax) {
|
||||||
|
printf("SetErrorRecovery failed\n");
|
||||||
|
return eax;
|
||||||
|
}
|
||||||
|
|
||||||
#define EARLY_RECOVERY 0x08
|
#define EARLY_RECOVERY 0x08
|
||||||
#define PER 0x04
|
#define PER 0x04
|
||||||
#define SUPPRESS_ECC 0x01
|
#define SUPPRESS_ECC 0x01
|
||||||
@ -360,6 +398,9 @@ void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
|
|||||||
// set the ECC fields
|
// set the ECC fields
|
||||||
char ecc = SUPPRESS_ECC; // presume ECC suppression
|
char ecc = SUPPRESS_ECC; // presume ECC suppression
|
||||||
if(ECC) {
|
if(ECC) {
|
||||||
|
#ifdef SUPRESS_ER_ERRORS
|
||||||
|
if(!SupressEarlyRecovery)
|
||||||
|
#endif
|
||||||
ecc = EARLY_RECOVERY; // enable ECC and Early Recovery
|
ecc = EARLY_RECOVERY; // enable ECC and Early Recovery
|
||||||
if(Testing) {
|
if(Testing) {
|
||||||
ecc = EARLY_RECOVERY | PER; // we're testing, so EER & PER
|
ecc = EARLY_RECOVERY | PER; // we're testing, so EER & PER
|
||||||
@ -374,14 +415,22 @@ void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
|
|||||||
retries = 0;
|
retries = 0;
|
||||||
|
|
||||||
ModifyModePage(PageBuff, ecc, retries);
|
ModifyModePage(PageBuff, ecc, retries);
|
||||||
const long eax = SetModePage(CurrentDevice, PageBuff);
|
|
||||||
|
eax = SetModePage(CurrentDevice, PageBuff, pageBuffLen);
|
||||||
// if we had an invalid field in the CDB (the EER bit was on)
|
// if we had an invalid field in the CDB (the EER bit was on)
|
||||||
if (eax == 0x00260005) {
|
if (eax == 0x00260005) {
|
||||||
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, sizeof(PageBuff));
|
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, pageBuffLen);
|
||||||
ecc &= ~0x08; // same, *BUT*NOT* Early Recovery
|
ecc &= ~EARLY_RECOVERY; // same, *BUT*NOT* Early Recovery
|
||||||
ModifyModePage(PageBuff, ecc, retries);
|
ModifyModePage(PageBuff, ecc, retries);
|
||||||
SetModePage(CurrentDevice, PageBuff);
|
eax = SetModePage(CurrentDevice, PageBuff, pageBuffLen);
|
||||||
|
#ifdef SUPRESS_ER_ERRORS
|
||||||
|
if(!eax) {
|
||||||
|
printf(" Early recovery not supported on this drive. Ignoring.\n\n");
|
||||||
|
SupressEarlyRecovery = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
return eax;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -468,7 +517,18 @@ long GetSpareSectorCounts(char checkPassword) {
|
|||||||
Scsi[0] = SCSI_Cmd_ReadDefectData;
|
Scsi[0] = SCSI_Cmd_ReadDefectData;
|
||||||
Scsi[2] = 0x1e; // 0b00011110 defect format, G/P bits
|
Scsi[2] = 0x1e; // 0b00011110 defect format, G/P bits
|
||||||
Scsi[8] = 4; // ask for only FOUR bytes
|
Scsi[8] = 4; // ask for only FOUR bytes
|
||||||
|
#ifdef SUPPRESS_DEFECTS_ERROR
|
||||||
|
if(SupressDefectsError)
|
||||||
|
eax = INCOMPATIBLE_MEDIA;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
eax = SCSICommand(CurrentDevice, Scsi, &DefectHeader, sizeof(DefectHeader));
|
eax = SCSICommand(CurrentDevice, Scsi, &DefectHeader, sizeof(DefectHeader));
|
||||||
|
#ifdef SUPPRESS_DEFECTS_ERROR
|
||||||
|
if(!SupressDefectsError && eax == INCOMPATIBLE_MEDIA) {
|
||||||
|
printf("Defects list not supported on this drive. Ignoring.\n\n");
|
||||||
|
SupressDefectsError = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if ((!eax) || (eax == INCOMPATIBLE_MEDIA)) {
|
if ((!eax) || (eax == INCOMPATIBLE_MEDIA)) {
|
||||||
// we could read its defect list ... so show it!
|
// we could read its defect list ... so show it!
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -635,7 +695,7 @@ uint8_t GetCartridgeStatus(long Device, uint8_t flags) {
|
|||||||
long eax;
|
long eax;
|
||||||
char DiskStat[72];
|
char DiskStat[72];
|
||||||
#ifdef NO_EXCESS_READS
|
#ifdef NO_EXCESS_READS
|
||||||
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, (flags & JAZ_DRIVE) ? sizeof(DiskStat) : 63);
|
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, 4);
|
||||||
if (eax) return DISK_STATUS_UNKNOWN;
|
if (eax) return DISK_STATUS_UNKNOWN;
|
||||||
#else
|
#else
|
||||||
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, sizeof(DiskStat));
|
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, sizeof(DiskStat));
|
||||||
@ -674,6 +734,7 @@ void SetCartridgeStatusToEAX(long eax, uint8_t flags) {
|
|||||||
SetRichEditText(szNotRunning);
|
SetRichEditText(szNotRunning);
|
||||||
goto DisableActions;
|
goto DisableActions;
|
||||||
case DISK_AT_SPEED:
|
case DISK_AT_SPEED:
|
||||||
|
printf("Disk at speed\n");
|
||||||
eax = GetSpareSectorCounts(true); // update the Cart Condition
|
eax = GetSpareSectorCounts(true); // update the Cart Condition
|
||||||
if(eax == MEDIA_NOT_PRESENT) {
|
if(eax == MEDIA_NOT_PRESENT) {
|
||||||
goto DisableActions;
|
goto DisableActions;
|
||||||
@ -686,10 +747,14 @@ void SetCartridgeStatusToEAX(long eax, uint8_t flags) {
|
|||||||
FirmErrors = 0;
|
FirmErrors = 0;
|
||||||
// check to see if we have enough spares to start
|
// check to see if we have enough spares to start
|
||||||
if(JazDrive) {
|
if(JazDrive) {
|
||||||
|
printf("Spare Sectors: %ld/%d\n", Side_0_SparesCount, MAXIMUM_JAZ_SPARES);
|
||||||
if(Side_0_SparesCount < MINIMUM_JAZ_SPARES)
|
if(Side_0_SparesCount < MINIMUM_JAZ_SPARES)
|
||||||
goto InsufficientSpares;
|
goto InsufficientSpares;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
printf("Spare Sectors:\n");
|
||||||
|
printf(" Side 1: %ld/%d\n", Side_0_SparesCount, MAXIMUM_ZIP_SPARES);
|
||||||
|
printf(" Side 2: %ld/%d\n", Side_1_SparesCount, MAXIMUM_ZIP_SPARES);
|
||||||
if(Side_0_SparesCount < MINIMUM_ZIP_SPARES) {
|
if(Side_0_SparesCount < MINIMUM_ZIP_SPARES) {
|
||||||
goto InsufficientSpares;
|
goto InsufficientSpares;
|
||||||
}
|
}
|
||||||
@ -761,6 +826,12 @@ void PrepareToBeginTesting() {
|
|||||||
HardErrors = 0;
|
HardErrors = 0;
|
||||||
UserInterrupt = 0;
|
UserInterrupt = 0;
|
||||||
LastError = 0;
|
LastError = 0;
|
||||||
|
#ifdef SUPRESS_ER_ERRORS
|
||||||
|
SupressEarlyRecovery = false;
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPRESS_DEFECTS_ERROR
|
||||||
|
SupressDefectsError = false;
|
||||||
|
#endif
|
||||||
#ifdef DEMO
|
#ifdef DEMO
|
||||||
LastLBAOnCartridge = 99999;
|
LastLBAOnCartridge = 99999;
|
||||||
SoftErrors = 6;
|
SoftErrors = 6;
|
||||||
@ -820,12 +891,12 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
char Scsi[10] = {0}; // clear out the SCSI CDB
|
char Scsi[10] = {0}; // clear out the SCSI CDB
|
||||||
const long InitialHardErrors = HardErrors;
|
const long InitialHardErrors = HardErrors;
|
||||||
|
|
||||||
SetErrorRecovery(false, false, true); // disable Retries & ECC
|
long eax = SetErrorRecovery(false, false, true); // disable Retries & ECC
|
||||||
|
|
||||||
Scsi[0] = XferCmd;
|
Scsi[0] = XferCmd;
|
||||||
SET_DWORD_AT(Scsi, 2, MAKE_BIG_ENDIAN(FirstLBASector)); // WHICH LBA's to read, BIG endian
|
SET_DWORD_AT(Scsi, 2, MAKE_BIG_ENDIAN(FirstLBASector)); // WHICH LBA's to read, BIG endian
|
||||||
SET_WORD_AT (Scsi, 7, MAKE_BIG_ENDIAN(NumberOfLBAs)); // HOW MANY to read, BIG endian
|
SET_WORD_AT (Scsi, 7, MAKE_BIG_ENDIAN(NumberOfLBAs)); // HOW MANY to read, BIG endian
|
||||||
long eax = SCSICommand(CurrentDevice, Scsi, pBuffer, NumberOfLBAs * BYTES_PER_SECTOR);
|
eax = SCSICommand(CurrentDevice, Scsi, pBuffer, NumberOfLBAs * BYTES_PER_SECTOR);
|
||||||
// if we failed somewhere during our transfer ... let's zero in on it
|
// if we failed somewhere during our transfer ... let's zero in on it
|
||||||
if (eax) {
|
if (eax) {
|
||||||
if ( eax == SS_ERR || // if it's a CONTROLLER ERROR, skip!
|
if ( eax == SS_ERR || // if it's a CONTROLLER ERROR, skip!
|
||||||
@ -834,6 +905,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Starting detailed search...\n");
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Save error and current Soft + Hard Error count to see if we do FIND the glitch ...
|
// Save error and current Soft + Hard Error count to see if we do FIND the glitch ...
|
||||||
const long GlitchError = eax; // save the error which stopped us!
|
const long GlitchError = eax; // save the error which stopped us!
|
||||||
@ -863,6 +936,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
||||||
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
|
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
|
||||||
|
|
||||||
|
printf(" Found error, retesting with retries\n");
|
||||||
SetErrorRecovery(true, false, true); // enable retries
|
SetErrorRecovery(true, false, true); // enable retries
|
||||||
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
|
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
|
||||||
if (eax) {
|
if (eax) {
|
||||||
@ -870,7 +944,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
||||||
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
|
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
|
||||||
|
|
||||||
SetErrorRecovery(true, true, true); // enable retries AND EEC
|
printf(" Found error, retesting with retries & ECC\n");
|
||||||
|
eax = SetErrorRecovery(true, true, true); // enable retries AND EEC
|
||||||
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
|
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
|
||||||
if (eax) {
|
if (eax) {
|
||||||
// failed with retries and EEC
|
// failed with retries and EEC
|
||||||
@ -888,6 +963,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PostTheError:
|
PostTheError:
|
||||||
|
printf(" %s (Sector %ld)\n", FindErrorString(eax), SingleTransferLBA);
|
||||||
|
printf("--------------------------------------------\n");
|
||||||
BumpErrorCounts(eax); // given eax, count the errors
|
BumpErrorCounts(eax); // given eax, count the errors
|
||||||
GetSpareSectorCounts(false); // update the Cart's Condition
|
GetSpareSectorCounts(false); // update the Cart's Condition
|
||||||
UpdateRunTimeDisplay();
|
UpdateRunTimeDisplay();
|
||||||
@ -897,6 +974,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
ProcessPendingMessages();
|
ProcessPendingMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("... detailed search finished\n");
|
||||||
// now see whether we *did* found something to complain about ...
|
// now see whether we *did* found something to complain about ...
|
||||||
eax = SoftErrors + HardErrors;
|
eax = SoftErrors + HardErrors;
|
||||||
if (eax == GlitchCount) {
|
if (eax == GlitchCount) {
|
||||||
@ -907,6 +985,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
long ebx = eax & 0x00FF00FF; // strip the ASCQ byte
|
long ebx = eax & 0x00FF00FF; // strip the ASCQ byte
|
||||||
if(ebx == 0x00110003) // if we're about to say "unrecovered read"
|
if(ebx == 0x00110003) // if we're about to say "unrecovered read"
|
||||||
eax = 0x170101; // change it to: "Read with Retries"
|
eax = 0x170101; // change it to: "Read with Retries"
|
||||||
|
printf("%s\n", FindErrorString(eax));
|
||||||
BumpErrorCounts(eax); // given eax, count the errors
|
BumpErrorCounts(eax); // given eax, count the errors
|
||||||
HardErrors = SavedHardErrors; // restore the counts
|
HardErrors = SavedHardErrors; // restore the counts
|
||||||
SoftErrors = SavedSoftErrors;
|
SoftErrors = SavedSoftErrors;
|
||||||
@ -917,6 +996,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
|||||||
eax = 0; // now let's return happiness to our caller
|
eax = 0; // now let's return happiness to our caller
|
||||||
if (HardErrors != InitialHardErrors) // UNRECOVERABLE errors!
|
if (HardErrors != InitialHardErrors) // UNRECOVERABLE errors!
|
||||||
eax = -1;
|
eax = -1;
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user