/*
* This file is part of the QPxTool project.
* Copyright (C) 2005-2006 Gennady "ShultZ" Kozlov <qpxtool@mail.ru>
*
*
* Some Plextor commands got from PxScan and CDVDlib (C) Alexander Noe`
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file "COPYING" for the exact licensing terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <common_functions.h>
//#include <qthread.h>
#include <qpx_transport.h>
#include <qpx_mmc.h>
//#include "test_threads.h"
#include "plextor_qcheck.h"
//#include "qpx_const.h"
#define DEBUG 1
//#define _debug_cx
//#define _debug_pi
//#define _debug_jb
//*********************************//
//
// commands to start tests
//
//*********************************//
const char PLEX_QCHECK_START = 0x15;
const char PLEX_QCHECK_READOUT = 0x16;
const char PLEX_QCHECK_END = 0x17;
int plextor_start_cx(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_START; //0x15;
drive->cmd[2] = 0x00;
drive->cmd[3] = 0x01;
if ((drive->err=drive->cmd.transport(NONE, NULL, 0) ))
{sperror ("PLEXTOR_START_CX",drive->err); return drive->err;}
#ifdef _debug_cx
printf("00 18 01 01 00 4B | LBA | BLER E31 E21 E11 ??? E32 E22 E12 | C1| C2| CU\n");
#endif
return 0;
}
int plextor_start_pie(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_START; //0x15;
drive->cmd[2] = 0x00;
drive->cmd[3] = 0x00;
drive->cmd[8] = 0x08; // scan interval (ECC blocks)
drive->cmd[9] = 0x10;
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_START_PISUM8",drive->err);return drive->err;}
return 0;
}
int plextor_start_pie_poe(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_START; //0x15;
drive->cmd[2] = 0x00;
drive->cmd[3] = 0x00;
drive->cmd[8] = 0x08; // scan interval (ECC blocks)
drive->cmd[9] = 0x11;
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_START_PISUM8_POE",drive->err);return drive->err;}
return 0;
}
int plextor_start_pif(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_START; //0x15;
drive->cmd[2] = 0x00;
drive->cmd[3] = 0x00;
drive->cmd[8] = 0x01; // scan interval (ECC blocks)
drive->cmd[9] = 0x12;
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_START_PIF",drive->err); return drive->err;}
return 0;
}
int plextor_start_jb_DVD(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_START; //0x15;
drive->cmd[2] = 0x10;
drive->cmd[3] = 0x00; // DVD
drive->cmd[8] = 0x10; // scan interval (ECC blocks)
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_START_JB_DVD",drive->err);return drive->err;}
return 0;
}
int plextor_start_jb_CD(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_START; //0x15;
drive->cmd[2] = 0x10;
drive->cmd[3] = 0x01; // CD
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_START_JB_CD",drive->err);return drive->err;}
return 0;
}
int plextor_start_fete(drive_info* drive) {
drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3;
drive->cmd[1] = 0x1F;
drive->cmd[2] = 0x03;
drive->cmd[3] = 0x01;
if (drive->media.disc_type & DISC_CD) {
int sect;
msf sect_msf;
// start address
drive->cmd[4] = 0x00;
drive->cmd[5] = 0x00;
drive->cmd[6] = 0x00;
// end address
sect = drive->media.capacity_total-1;
lba2msf(§,§_msf);
drive->cmd[7] = sect_msf.m;
drive->cmd[8] = sect_msf.s;
drive->cmd[9] = sect_msf.f;
} else {
// start address
drive->cmd[4] = 0x00;
drive->cmd[5] = 0x00;
drive->cmd[6] = 0x00;
// end address
drive->cmd[7] = ((drive->media.capacity_total-1) >> 16) & 0xFF;
drive->cmd[8] = ((drive->media.capacity_total-1) >> 8) & 0xFF;
drive->cmd[9] = (drive->media.capacity_total-1) & 0xFF;
}
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_START_FETE",drive->err);return drive->err;}
return 0;
}
//*********************************//
//
// end scan commands
//
//*********************************//
int plextor_end_scan(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_END; //0x17;
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_END_SCAN",drive->err); return drive->err;}
return 0;
}
int plextor_end_fete(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3;
drive->cmd[1] = 0x1F;
drive->cmd[2] = 0x04;
if ((drive->err=drive->cmd.transport(NONE, NULL, 0)))
{sperror ("PLEXTOR_END_FETE",drive->err); return drive->err;}
return 0;
}
//*********************************//
//
// test data readout commands
//
//*********************************//
int plextor_read_cd_error_info(drive_info* drive, int* BLER,
int* E11, int* E21, int* E31, int* E12, int* E22, int* E32)
{
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16;
drive->cmd[2] = 0x01;
drive->cmd[10]= 0x1A;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x1A)))
{sperror ("PLEXTOR_READ_CD_ERROR_INFO", drive->err);return drive->err;}
// int E11, E21, E31, E12, E22, E32, BLER;
*BLER = swap2(drive->rd_buf+10);
*E31 = swap2(drive->rd_buf+12);
*E21 = swap2(drive->rd_buf+14);
*E11 = swap2(drive->rd_buf+16);
// ??? swap2(drive->rd_buf+18);
*E32 = swap2(drive->rd_buf+20);
*E22 = swap2(drive->rd_buf+22);
*E12 = swap2(drive->rd_buf+24);
int C1,C2,CU;
C1 = *BLER;
C2 = *E22;
CU = *E32;
#ifdef _debug_cx
int i;
for (i=0x00; i<0x06; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("| ");
for (i=0x06; i<0x0A; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("| ");
for (i=0x0A; i<0x1A; i+=2) { if (swap2(drive->rd_buf+i)) printf("%5d ", swap2(drive->rd_buf+i)); else printf("_____ "); }
printf("| ");
printf("%3d C1| %3d C2| %3d CU\n", C1, C2, CU);
#endif
return 0;
}
int plextor_read_pi_info(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16;
drive->cmd[2] = 0x00;
drive->cmd[10]= 0x34;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x34)))
{sperror ("PLEXTOR_READ_PI",drive->err); return drive->err;}
/*
printf("READ PI:");
for (int i=0; i<0x34; i++) {
if (!(i%0x10)) printf("\n");
printf(" %02X",drive->rd_buf[i] & 0xFF);
}
printf("\n");
*/
#ifdef _debug_pi
int i;
/*
// printf("\n| ");
for (i=0x00; i<0x34; i++) {
if (!(i%0x20))printf("\n| ");
printf("%02X ", drive->rd_buf[i] & 0xFF);
}
*/
for (i=0x00; i<0x06; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("|");
printf(" %6X |", swap4(drive->rd_buf+0x06) - 0x030000);
printf(" %4X |", swap2(drive->rd_buf+0x0A));
printf(" %4X", swap2(drive->rd_buf+0x0C));
for (i=0x20; i<0x34; i+=4) {
if (!(i%0x10))printf(" |");
if (swap4(drive->rd_buf+i))
printf(" %8d", swap4(drive->rd_buf+i));
else
printf(" ________");
}
// printf("\n");
#endif
return 0;
}
int plextor_read_jb_info(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16;
drive->cmd[2] = 0x10;
drive->cmd[10] = 0x10;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x10)))
{sperror ("PLEXTOR_READ_JB",drive->err); return drive->err;}
#ifdef _debug_jb
int i;
printf("\n| J/B data: | ");
for (i=0x00; i<0x10; i++) printf("%02X ", drive->rd_buf[i] & 0xFF);
printf("|\n");
#endif
return 0;
}
int plextor_cx_do_one_interval(drive_info* drive, int* lba, int* BLER,
int* E11, int* E21, int* E31, int* E12, int* E22, int* E32)
{
for (int i=0; (i<5) && *lba<drive->media.capacity; i++) {
if (*lba + 15 < drive->media.capacity)
read_cd(drive, *lba, 15, 0xFA);
else
read_cd(drive, *lba, drive->media.capacity - *lba, 0xFA);
*lba+=15;
}
plextor_read_cd_error_info(drive, BLER, E11, E21, E31, E12, E22, E32);
// *lba =
return 0;
}
int plextor_pif_do_one_ecc_block(drive_info* drive, int* lba, int* pif) {
read_one_ecc_block(drive, *lba);
*lba+= 0x10;
plextor_read_pi_info(drive);
// *lba = swap4(drive->rd_buf+0x06) - 0x00030000;
*pif = swap4(drive->rd_buf+0x24);
#ifdef _debug_pi
printf(" * %4d\n", *pif);
#endif
return 0;
}
int plextor_pisum8_do_eight_ecc_blocks(drive_info* drive, int* lba, int* pie, int* pof) {
for (int i=0;i<8;i++) {
if ((drive->err = read_one_ecc_block(drive, *lba)));// i = 8;
*lba+= 0x10;
}
plextor_read_pi_info(drive);
// *lba = swap4(drive->rd_buf+0x06) - 0x00030000;
*pie = swap4(drive->rd_buf+0x24);
*pof = swap4(drive->rd_buf+0x10);
// *poe = swap4(drive->rd_buf+0x28);
// *pif = 0;
#ifdef _debug_pi
printf(" * %4d\n", *pie);
#endif
return 0;
}
int plextor_burst_do_eight_ecc_blocks(drive_info* drive, int* lba, int* pie, int* poe, int* pof) {
for (int i=0;i<8;i++) {
if ((drive->err = read_one_ecc_block(drive, *lba)));// i = 8;
*lba+= 0x10;
}
plextor_read_pi_info(drive);
// *lba = swap4(drive->rd_buf+0x06) - 0x00030000;
*pie = swap4(drive->rd_buf+0x24);
//*
if (swap2(drive->rd_buf+0x0C) > swap2(drive->rd_buf+0x0A))
*poe = swap4(drive->rd_buf+0x28) >> 1;
else
*poe = 0;
*pof = swap4(drive->rd_buf+0x10);
#ifdef _debug_pi
printf(" * %4d * %4d\n", *pie, *poe);
#endif
return 0;
}
int plextor_jitterbeta_DVD_do_16_ecc_blocks(drive_info* drive, int* lba, int* jitter, short int* beta) {
short int* i16_beta;
char c;
for (int i=0;i<16;i++) {
int j = read_one_ecc_block(drive, *lba);
if (j == COMMAND_FAILED) i=16;
*lba+= 0x10;
}
plextor_read_jb_info(drive);
c = drive->rd_buf[10]; drive->rd_buf[10] = drive->rd_buf[11]; drive->rd_buf[11] = c;
i16_beta = (short int*)(drive->rd_buf+10);
if (drive->dev_ID > PLEXTOR_716) {
*beta = *i16_beta;
*jitter = 3200 - 2*swap2(drive->rd_buf+12);
} else {
*beta = *i16_beta;
// *jitter = 3000 - 2*swap2(drive->rd_buf+12);
*jitter = 3200 - (int)(2.4*swap2(drive->rd_buf+12));
}
return (!(drive->rd_buf[2]));
}
int plextor_jitterbeta_do_one_cd_interval(drive_info* drive, int* lba, int* jitter, short int* beta, int int_len) {
short int* i16_beta;
char c;
int blocks = int_len / 15;
int rest = int_len % 15;
for (int i=0;i<blocks;i++) {
int j = read_cd(drive, *lba, 15, 0xFA);
*lba+= 0x0F;
if (j == COMMAND_FAILED) i++;
}
if (rest) {
read_cd(drive, *lba, rest, 0xFA);
}
plextor_read_jb_info(drive);
c = drive->rd_buf[10]; drive->rd_buf[10] = drive->rd_buf[11]; drive->rd_buf[11] = c;
i16_beta = (short int*)(drive->rd_buf+10);
if (drive->dev_ID > PLEXTOR_716) {
*beta = *i16_beta;
*jitter = 4800 - 2*swap2(drive->rd_buf+12);
} else {
*beta = *i16_beta;
// *jitter = 3200 - 2*swap2(drive->rd_buf+12);
*jitter = 3600 - (int)(2.4*swap2(drive->rd_buf+12));
}
return (!(drive->rd_buf[2]));
}
int plextor_read_fete(drive_info* drive) {
drive->cmd_clear();
drive->cmd[0] = CMD_PLEX_FETE_READOUT; // 0xF5;
drive->cmd[3] = 0x0C;
drive->cmd[9] = 0xCE;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0xCE)))
{sperror ("PLEXTOR_FETE_READOUT",drive->err); return drive->err;}
/*
for (int i=0; i<0xCE; i++) {
if (!(i % 0x20)) printf("\n");
printf("%02X ",drive->rd_buf[i] & 0xFF);
}
printf("\n");
*/
return 0;
}
scan_commands commands_plextor_list = {
plextor_start_cx, plextor_cx_do_one_interval, plextor_end_scan,
plextor_start_jb_CD, plextor_jitterbeta_do_one_cd_interval, plextor_end_scan,
plextor_start_pie, plextor_pisum8_do_eight_ecc_blocks, plextor_end_scan,
plextor_start_pif, plextor_pif_do_one_ecc_block, plextor_end_scan,
plextor_start_pie_poe, plextor_burst_do_eight_ecc_blocks, plextor_end_scan,
NULL, NULL, NULL,
plextor_start_jb_DVD, plextor_jitterbeta_DVD_do_16_ecc_blocks, plextor_end_scan,
};
scan_commands commands_plextor() { return commands_plextor_list; }
syntax highlighted by Code2HTML, v. 0.9.1